{
context.out(
`${
typeof leftKey === 'string' ? escapeHTML(leftKey) : leftKey
- }
`,
+ }:`,
);
}
diff --git a/src/view/panel.vue b/src/view/panel.vue
index 8865768..0a0b752 100644
--- a/src/view/panel.vue
+++ b/src/view/panel.vue
@@ -189,6 +189,16 @@ a {
word-break: break-all;
}
+ .jsondiffpatch-property-name::after {
+ content: unset;
+ }
+ .jsondiffpatch-child-node-type-array,
+ .jsondiffpatch-child-node-type-object {
+ & > .jsondiffpatch-property-name::after {
+ content: ' [';
+ }
+ }
+
.jsondiffpatch-added .jsondiffpatch-property-name,
.jsondiffpatch-added .jsondiffpatch-value pre,
.jsondiffpatch-modified .jsondiffpatch-right-value pre,
From 76b9a79888263f9d717fc043f6fca471b1aba92c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=F0=9F=95=B7=EF=B8=8F?=
<3756473+zendive@users.noreply.github.com>
Date: Tue, 10 Feb 2026 18:24:53 +0200
Subject: [PATCH 05/23] update objectHash of jsondiffpatch
---
deno.lock | 50 ++++++++++++++++++++++------------------------
package.json | 3 +--
src/api/clone.ts | 2 +-
src/api/diffApi.ts | 29 ++++++++++++++-------------
4 files changed, 41 insertions(+), 43 deletions(-)
diff --git a/deno.lock b/deno.lock
index fd1b61e..9e4aa83 100644
--- a/deno.lock
+++ b/deno.lock
@@ -11,7 +11,6 @@
"jsr:@std/internal@^1.0.12": "1.0.12",
"jsr:@std/path@^1.1.4": "1.1.4",
"jsr:@std/testing@1.0.17": "1.0.17",
- "npm:@dmsnell/diff-match-patch@1.1.0": "1.1.0",
"npm:@noble/hashes@2.0.1": "2.0.1",
"npm:@types/chrome@*": "0.1.36",
"npm:@types/chrome@0.1.36": "0.1.36",
@@ -20,10 +19,10 @@
"npm:esbuild-plugin-vue-iii@0.5.0": "0.5.0_esbuild@0.27.3_typescript@5.9.3",
"npm:esbuild@0.27.3": "0.27.3",
"npm:jsondiffpatch@0.7.3": "0.7.3",
- "npm:pinia@3.0.4": "3.0.4_typescript@5.9.3_vue@3.5.27__typescript@5.9.3",
+ "npm:pinia@3.0.4": "3.0.4_typescript@5.9.3_vue@3.5.28__typescript@5.9.3",
"npm:typescript@5.9.3": "5.9.3",
"npm:vue-loader@17.4.2": "17.4.2_webpack@5.105.0__acorn@8.15.0",
- "npm:vue@3.5.27": "3.5.27_typescript@5.9.3"
+ "npm:vue@3.5.28": "3.5.28_typescript@5.9.3"
},
"jsr": {
"@std/assert@1.0.18": {
@@ -343,8 +342,8 @@
"eslint-visitor-keys"
]
},
- "@vue/compiler-core@3.5.27": {
- "integrity": "sha512-gnSBQjZA+//qDZen+6a2EdHqJ68Z7uybrMf3SPjEGgG4dicklwDVmMC1AeIHxtLVPT7sn6sH1KOO+tS6gwOUeQ==",
+ "@vue/compiler-core@3.5.28": {
+ "integrity": "sha512-kviccYxTgoE8n6OCw96BNdYlBg2GOWfBuOW4Vqwrt7mSKWKwFVvI8egdTltqRgITGPsTFYtKYfxIG8ptX2PJHQ==",
"dependencies": [
"@babel/parser",
"@vue/shared",
@@ -353,15 +352,15 @@
"source-map-js"
]
},
- "@vue/compiler-dom@3.5.27": {
- "integrity": "sha512-oAFea8dZgCtVVVTEC7fv3T5CbZW9BxpFzGGxC79xakTr6ooeEqmRuvQydIiDAkglZEAd09LgVf1RoDnL54fu5w==",
+ "@vue/compiler-dom@3.5.28": {
+ "integrity": "sha512-/1ZepxAb159jKR1btkefDP+J2xuWL5V3WtleRmxaT+K2Aqiek/Ab/+Ebrw2pPj0sdHO8ViAyyJWfhXXOP/+LQA==",
"dependencies": [
"@vue/compiler-core",
"@vue/shared"
]
},
- "@vue/compiler-sfc@3.5.27": {
- "integrity": "sha512-sHZu9QyDPeDmN/MRoshhggVOWE5WlGFStKFwu8G52swATgSny27hJRWteKDSUUzUH+wp+bmeNbhJnEAel/auUQ==",
+ "@vue/compiler-sfc@3.5.28": {
+ "integrity": "sha512-6TnKMiNkd6u6VeVDhZn/07KhEZuBSn43Wd2No5zaP5s3xm8IqFTHBj84HJah4UepSUJTro5SoqqlOY22FKY96g==",
"dependencies": [
"@babel/parser",
"@vue/compiler-core",
@@ -374,8 +373,8 @@
"source-map-js"
]
},
- "@vue/compiler-ssr@3.5.27": {
- "integrity": "sha512-Sj7h+JHt512fV1cTxKlYhg7qxBvack+BGncSpH+8vnN+KN95iPIcqB5rsbblX40XorP+ilO7VIKlkuu3Xq2vjw==",
+ "@vue/compiler-ssr@3.5.28": {
+ "integrity": "sha512-JCq//9w1qmC6UGLWJX7RXzrGpKkroubey/ZFqTpvEIDJEKGgntuDMqkuWiZvzTzTA5h2qZvFBFHY7fAAa9475g==",
"dependencies": [
"@vue/compiler-dom",
"@vue/shared"
@@ -405,21 +404,21 @@
"rfdc"
]
},
- "@vue/reactivity@3.5.27": {
- "integrity": "sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==",
+ "@vue/reactivity@3.5.28": {
+ "integrity": "sha512-gr5hEsxvn+RNyu9/9o1WtdYdwDjg5FgjUSBEkZWqgTKlo/fvwZ2+8W6AfKsc9YN2k/+iHYdS9vZYAhpi10kNaw==",
"dependencies": [
"@vue/shared"
]
},
- "@vue/runtime-core@3.5.27": {
- "integrity": "sha512-fxVuX/fzgzeMPn/CLQecWeDIFNt3gQVhxM0rW02Tvp/YmZfXQgcTXlakq7IMutuZ/+Ogbn+K0oct9J3JZfyk3A==",
+ "@vue/runtime-core@3.5.28": {
+ "integrity": "sha512-POVHTdbgnrBBIpnbYU4y7pOMNlPn2QVxVzkvEA2pEgvzbelQq4ZOUxbp2oiyo+BOtiYlm8Q44wShHJoBvDPAjQ==",
"dependencies": [
"@vue/reactivity",
"@vue/shared"
]
},
- "@vue/runtime-dom@3.5.27": {
- "integrity": "sha512-/QnLslQgYqSJ5aUmb5F0z0caZPGHRB8LEAQ1s81vHFM5CBfnun63rxhvE/scVb/j3TbBuoZwkJyiLCkBluMpeg==",
+ "@vue/runtime-dom@3.5.28": {
+ "integrity": "sha512-4SXxSF8SXYMuhAIkT+eBRqOkWEfPu6nhccrzrkioA6l0boiq7sp18HCOov9qWJA5HML61kW8p/cB4MmBiG9dSA==",
"dependencies": [
"@vue/reactivity",
"@vue/runtime-core",
@@ -427,16 +426,16 @@
"csstype"
]
},
- "@vue/server-renderer@3.5.27_vue@3.5.27__typescript@5.9.3_typescript@5.9.3": {
- "integrity": "sha512-qOz/5thjeP1vAFc4+BY3Nr6wxyLhpeQgAE/8dDtKo6a6xdk+L4W46HDZgNmLOBUDEkFXV3G7pRiUqxjX0/2zWA==",
+ "@vue/server-renderer@3.5.28_vue@3.5.28__typescript@5.9.3_typescript@5.9.3": {
+ "integrity": "sha512-pf+5ECKGj8fX95bNincbzJ6yp6nyzuLDhYZCeFxUNp8EBrQpPpQaLX3nNCp49+UbgbPun3CeVE+5CXVV1Xydfg==",
"dependencies": [
"@vue/compiler-ssr",
"@vue/shared",
"vue"
]
},
- "@vue/shared@3.5.27": {
- "integrity": "sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ=="
+ "@vue/shared@3.5.28": {
+ "integrity": "sha512-cfWa1fCGBxrvaHRhvV3Is0MgmrbSCxYTXCSCau2I0a1Xw1N1pHAvkWCiXPRAqjvToILvguNyEwjevUqAuBQWvQ=="
},
"@webassemblyjs/ast@1.14.1": {
"integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
@@ -910,7 +909,7 @@
"picomatch@2.3.1": {
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
},
- "pinia@3.0.4_typescript@5.9.3_vue@3.5.27__typescript@5.9.3": {
+ "pinia@3.0.4_typescript@5.9.3_vue@3.5.28__typescript@5.9.3": {
"integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==",
"dependencies": [
"@vue/devtools-api",
@@ -1081,8 +1080,8 @@
"webpack"
]
},
- "vue@3.5.27_typescript@5.9.3": {
- "integrity": "sha512-aJ/UtoEyFySPBGarREmN4z6qNKpbEguYHMmXSiOGk69czc+zhs0NF6tEFrY8TZKAl8N/LYAkd4JHVd5E/AsSmw==",
+ "vue@3.5.28_typescript@5.9.3": {
+ "integrity": "sha512-BRdrNfeoccSoIZeIhyPBfvWSLFP4q8J3u8Ju8Ug5vu3LdD+yTM13Sg4sKtljxozbnuMu1NB1X5HBHRYUzFocKg==",
"dependencies": [
"@vue/compiler-dom",
"@vue/compiler-sfc",
@@ -1148,7 +1147,6 @@
],
"packageJson": {
"dependencies": [
- "npm:@dmsnell/diff-match-patch@1.1.0",
"npm:@noble/hashes@2.0.1",
"npm:@types/chrome@0.1.36",
"npm:@types/firefox-webext-browser@143.0.0",
@@ -1156,7 +1154,7 @@
"npm:pinia@3.0.4",
"npm:typescript@5.9.3",
"npm:vue-loader@17.4.2",
- "npm:vue@3.5.27"
+ "npm:vue@3.5.28"
]
}
}
diff --git a/package.json b/package.json
index 8ea0d12..67532f4 100644
--- a/package.json
+++ b/package.json
@@ -1,14 +1,13 @@
{
"type": "module",
"devDependencies": {
- "@dmsnell/diff-match-patch": "1.1.0",
"@noble/hashes": "2.0.1",
"@types/chrome": "0.1.36",
"@types/firefox-webext-browser": "143.0.0",
"jsondiffpatch": "0.7.3",
"pinia": "3.0.4",
"typescript": "5.9.3",
- "vue": "3.5.27",
+ "vue": "3.5.28",
"vue-loader": "17.4.2"
}
}
diff --git a/src/api/clone.ts b/src/api/clone.ts
index 26982a6..5e2c7cc 100644
--- a/src/api/clone.ts
+++ b/src/api/clone.ts
@@ -22,7 +22,7 @@ import {
UniqueLookupCatalog,
} from './cloneCatalog.ts';
-interface ISerializableObject {
+export interface ISerializableObject {
[key: string | symbol]: unknown;
}
interface IFunction {
diff --git a/src/api/diffApi.ts b/src/api/diffApi.ts
index 41a5d60..5bd46f9 100644
--- a/src/api/diffApi.ts
+++ b/src/api/diffApi.ts
@@ -1,19 +1,22 @@
import { hasValue } from './toolkit.ts';
-import { diff_match_patch } from '@dmsnell/diff-match-patch';
-import { create } from 'jsondiffpatch';
+import { create } from 'jsondiffpatch/with-text-diffs';
+import { ISerializableObject } from './clone.ts';
export type { Delta } from 'jsondiffpatch';
+const OBJECT_ID_IN_ARRAY = ['id', '_id', 'uuid', 'name', 'key', 'version'];
+
const patcher = create({
// used to match objects when diffing arrays, by default only === operator is used
- objectHash(obj, index) {
- // this function is used only to when objects are not equal by ref
- const rv = hasValue(obj)
- ? 'id' in obj && hasValue(obj.id)
- ? obj.id
- : '_id' in obj && hasValue(obj._id)
- ? obj._id
- : index
- : index;
+ objectHash(item: object, index?: number) {
+ const obj = item;
+ let rv: unknown = index;
+
+ for (const prop of OBJECT_ID_IN_ARRAY) {
+ if (hasValue(obj[prop])) {
+ rv = obj[prop];
+ break;
+ }
+ }
return hasValue(rv) ? String(rv) : undefined;
},
@@ -26,9 +29,7 @@ const patcher = create({
},
textDiff: {
- diffMatchPatch: diff_match_patch,
- // default 60, minimum string length (left and right sides) to use text diff algorythm: google-diff-match-patch
- minLength: 120,
+ minLength: 120, // default 60
},
});
From 7e447cc7ca9a47e438095584ca4237fef23ea68f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=F0=9F=95=B7=EF=B8=8F?=
<3756473+zendive@users.noreply.github.com>
Date: Tue, 10 Feb 2026 19:42:25 +0200
Subject: [PATCH 06/23] use light-dark CSS function instead of relaying on
theme class
---
src/view/panel.header.vue | 2 +-
src/view/panel.search.vue | 2 +-
src/view/panel.vue | 43 +++++++++++++--------------------------
3 files changed, 16 insertions(+), 31 deletions(-)
diff --git a/src/view/panel.header.vue b/src/view/panel.header.vue
index e6d3398..347e2bb 100644
--- a/src/view/panel.header.vue
+++ b/src/view/panel.header.vue
@@ -73,7 +73,7 @@ const onClearResults = () => {
flex-shrink: 0;
width: 100%;
background-color: var(--header-background);
- border-bottom: var(--header-border);
+ border-bottom: 1px solid var(--header-border);
display: flex;
align-items: center;
height: var(--header-height);
diff --git a/src/view/panel.search.vue b/src/view/panel.search.vue
index 7ca7ba8..ecf53a3 100644
--- a/src/view/panel.search.vue
+++ b/src/view/panel.search.vue
@@ -121,7 +121,7 @@ const onNextSearch = () => {
display: flex;
align-items: center;
margin-left: 10px;
- color: rgb(var(--colour-found-this-background));
+ color: var(--colour-found-this-background);
font-size: 12px;
font-weight: bold;
diff --git a/src/view/panel.vue b/src/view/panel.vue
index 0a0b752..f80f018 100644
--- a/src/view/panel.vue
+++ b/src/view/panel.vue
@@ -85,45 +85,30 @@ onUnmounted(() => {