Skip to content

Commit 05a56fe

Browse files
authored
v3.0.7 (#30)
- support new types of serialization: `URL`, `RegExp` ( #28 ) - fix #29 - spread usage of catalogs between Symbol, DOM and the rest, to reduce "noise" in comparison results --------- Signed-off-by: 🕷️ <[email protected]>
1 parent b5527b6 commit 05a56fe

20 files changed

+1209
-1512
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,5 @@ node_modules/
1414
*.crx
1515
manifest.json
1616
bundle/js
17+
*.log
18+

.vscode/settings.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,7 @@
77
"url": "https://json.schemastore.org/chrome-manifest.json"
88
}
99
],
10-
"typescript.tsdk": "node_modules/typescript/lib"
10+
"typescript.tsdk": "node_modules/typescript/lib",
11+
"spellright.language": ["en-US-10-1."],
12+
"spellright.documentTypes": ["latex", "plaintext", "markdown"]
1113
}

Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ all:
1919
make lint
2020
make test
2121
make prod
22-
make zip_chrome
2322
make zip_firefox
23+
make zip_chrome
2424

2525
lint:
2626
pnpm exec prettier . --write
@@ -30,6 +30,7 @@ test:
3030
pnpm exec tsx --test
3131

3232
dev:
33+
rm -rf ./bundle/js/
3334
NODE_OPTIONS="--import=tsx --trace-deprecation" \
3435
pnpm exec webpack --progress --watch --mode=development
3536

README.md

+76-70
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,53 @@
11
### ![](./bundle/img/panel-icon28.png) JSDiff
22

3-
An extension for developers that enhances the console API by incorporating the ability to compare objects and adds a JSDiff tab (parallel to Elements, Network panels) within your dev-tools for viewing the results.
3+
An extension for developers that enhances the console API by incorporating the ability to compare objects and adds a `JSDiff` tab (parallel to Elements, Network panels) within your dev-tools for viewing the results.
44

55
- Available in Chrome Web Store as [console.diff()](https://chromewebstore.google.com/detail/consolediff/iefeamoljhdcpigpnpggeiiabpnpgonb)
66
- Available in Firefox Add-ons as [jsdiff.diff()](https://addons.mozilla.org/addon/jsdiff-diff/)
77

88
<details>
9-
<summary> <strong>Examples</strong> </summary>
9+
<summary> <strong>Screenshots</strong> </summary>
1010

1111
- Comparing two objects
1212
![screenshot](./doc/screenshot-01.png)
1313

14-
- Tracking changes in localStorage (unchanged are hidden)
14+
- Tracking changes in `localStorage` (unchanged are hidden)
1515
![screenshot](./doc/screenshot-02.png)
1616

1717
</details>
18-
<details>
19-
<summary> <strong>How it works</strong> </summary>
2018

21-
- Chrome mv3
22-
![screenshot](./doc/design.chrome.png)
23-
- Firefox
24-
![screenshot](./doc/design.firefox.png)
25-
26-
</details>
19+
### Motivation
2720

28-
### Based on
29-
30-
- [jsondiffpatch](https://github.com/benjamine/jsondiffpatch) by Benjamín Eidelman
31-
- [vuejs](https://github.com/vuejs) by Evan You
21+
- Track object mutations during runtime and/or while debugging with intention to find expected or unexpected changes.
3222

3323
### Features
3424

35-
- Symple user interface:
25+
- User interface:
3626

37-
- Button to hide/show unchanged properties.
38-
- Button to copy changed properties in format of `jsondiffpatch` Delta object.
39-
- Button to clear current result.
40-
- Search input to highlight patterns
27+
- Hide / show unchanged properties.
28+
- Copy changed properties in format of `jsondiffpatch` Delta object.
29+
- Clear current result.
30+
- Search input to highlight patterns.
31+
- If search query contains at least one upper-case letter - the search will be case-sensitive.
4132
- Indicator of the last update time.
4233
- Indicator of a fatal error (out of storage memory).
43-
- Devtools light/dark colour scheme support.
44-
45-
- Compare objects between multiple [sub]domains, chrome tabs, or single page reloads.
46-
47-
- JSDiff devtools panel reflects current state of comparison, regardless the tab[s] it was opened from.
48-
49-
- Internal search inside comparison results
34+
- DevTools light/dark color scheme support.
5035

51-
- If search query contains at least one upper-case letter - the search will be case-sensitive.
36+
- Compare objects between multiple [sub]domains, Chrome tabs, or single page reloads.
5237

53-
- Using `console.diff` functions from within online code editors like: [codesandbox.io](https://codesandbox.io), [coderpad.io](https://coderpad.io), [flems.io](https://flems.io), [codepen.io](https://codepen.io), [jsfiddle.net](https://jsfiddle.net).
38+
- `JSDiff` DevTools panel reflects current state of comparison, regardless the tab[s] it was opened from.
5439

55-
- Functions are included in comparison result in order to detect possible alterations, in form of a string combined from a function name (if present) and a SHA-256 hash of a `function.toString()` body. Native functions are shown as `ƒ⟪native⟫`.
40+
- Fail-safe serialization of objects having security issues while accessing their properties or objects having `toJSON()` function; when instead of serialization of all object properties, - only `toJSON()` return value is serialized, like `JSON.strigify()` does.
5641

57-
- Some DOM objects like Document or Element are not worth to be shown entirely, since that is not the purpose of this extension. So if they are present anywhere, they are serialized as `0x####: ⟪unserializable⟫`.
42+
- Can be used from within online code editors like: [codesandbox.io](https://codesandbox.io), [coderpad.io](https://coderpad.io), [flems.io](https://flems.io), [codepen.io](https://codepen.io), [jsfiddle.net](https://jsfiddle.net), [mdn playground](https://developer.mozilla.org/play).
5843

59-
- Object, Array, Map, Set - serialized only once and the rest of their ocurrances are mentioned with unique reference like: `0x####: {♻️}`, `0x####: [♻️]`, `0x####: Map{♻️}`, `0x####: Set[♻️]` respectivly.
44+
#### Limitations
6045

61-
- Map keys, unless they are primitive types, serialized by their pseudo ids.
46+
- Map keys like `0` and `'0'` would be merged due to `Map to Object` conversion.
6247

63-
- Symbols serialized with his pseudo id like: `0x####: Symbol(name)`.
48+
- While paused in debug mode, `JSDiff` panel won't reflect the result until runtime is resumed (see [#10](https://github.com/zendive/jsdiff/issues/10)).
6449

65-
- Serialization of numerics like `+/-Infinity`, `NaN`, `BigInt`, or `undefined` serialized like: `Number⟪Infinity⟫`, `Number⟪NaN⟫`, `BigInt⟪#⟫`, `⟪undefined⟫` respectivly.
66-
67-
- Failsafe serialization of objects having security issues while accessing their properties.
68-
69-
- Failsefe serialization of objects having `toJSON()` function (when instead of serialization of all object properties, - only toJSON() return value is serialized, similar to the way native `JSON.strigify()` works).
70-
71-
### Legend
72-
73-
- Pseudo id, assigned to non-primitive data types, used in order to detect reference recurrences and, in case of Symbols - symbol uniqueness. Id for an object shown in the output only if it seen more than once. It being assigned in the scope of serialization of a high level argument instance, while comparing left or right side; that means if some object, having id 0x0001 on the left side, is not guarantied to have same id on the right side.
74-
75-
### Limitations
76-
77-
- While paused in debug mode, JSDiff panel won't reflect the result until runtime is resumed (see [#10][i10]).
78-
79-
[i10]: https://github.com/zendive/jsdiff/issues/10
80-
81-
- Compared objects, after being serialized, stored in `chrome.storage.local` wich has 10MB limit (before chrome v114 was 5MB).
50+
- Compared objects, after being serialized, stored in `chrome.storage.local` which has 10 MB limit.
8251

8352
- In Firefox the API is under `jsdiff` object for now, cause extension API's not fully compatible.
8453

@@ -114,7 +83,7 @@ console.diffLeft(Date.now());
11483
console.diffRight(Date.now());
11584
```
11685

117-
### Typescript
86+
#### Typescript
11887

11988
Global Console interface declaration for quick copy/paste when used from typescript:
12089

@@ -129,41 +98,78 @@ declare global {
12998
}
13099
```
131100

132-
### Usage basics
133-
134-
Historically, left side represents the old state and right side the new state.
101+
### Serialization by types
135102

136-
- Things that are present on the left side but missing on the right side are colour-coded as red (old).
103+
| Input | Output |
104+
| ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
105+
| XMLHttpRequest<sup>[1]</sup> | ƒ XMLHttpRequest⟪native⟫ |
106+
| function test(){}<sup>[1]</sup> | ƒ test⟪1374b28d22b674e53a044425556a9cd48b82fd5aba3bf19e3545d51704227b10⟫ |
107+
| document.body | {0001}<sup>[2,3]</sup> DOM⟪BODY⟫ |
108+
| ±Infinity | Number⟪±Infinity⟫ |
109+
| NaN | Number⟪NaN⟫ |
110+
| 98765432109876543210n | BigInt⟪98765432109876543210⟫ |
111+
| void 0 | ⟪undefined⟫ |
112+
| /example/i | RegExp⟪/example/i⟫ |
113+
| new URL('https:\//example.com/') | URL⟪https:\//example.com/⟫ |
114+
| Symbol('example') | {0001}<sup>[3]</sup> Symbol(example) |
115+
| Symbol.for('global') | Symbol(global) |
116+
| (obj = {key: 1}, {first: obj, second: obj}) | {"first": {"key": 1}, "second": "[0002]<sup>[4]</sup> Object⟪♻️⟫"} |
117+
| (key2= {}, map = new Map(\[['key1', 1], [key2, 2]]), {first: map, second: map}) | {"first": {"[0003]<sup>[4,5]</sup> Object⟪♻️⟫": 2, "key1": 1}, "second": "[0002]<sup>[4]</sup> Map⟪♻️⟫"} |
118+
| (arr = [1], {first: arr, second: arr}) | {"first": [1], "second": "[0002]<sup>[4]</sup> Array⟪♻️⟫"} |
119+
| (set = new Set([1]), {first: set, second: set}) | {"first: [1], "second": "[0002]<sup>[4]</sup> Set⟪♻️⟫"} |
137120

138-
- Things that are missing on the left side but present on the right side are colour-coded as green (new).
121+
<sup>1</sup> Functions included in comparison result in order to detect possible alterations, in form of a string combined from a function name (if present) and a hash of a `function.toString()` body.
139122

140-
- To track changes of the same variable in timed manner you can push it with `diffPush` or `diff` with a single argument, - that will shift objects from right to left, showing differences with previous push state.
123+
<sup>2</sup> DOM element serialized by pseudo `id` and `nodeName`.
141124

142-
### How to build
125+
<sup>3</sup> Notation `{}` denotes pseudo `id` from a Set of unique instances, which is assigned during serialization of compared sides and remains inside internal `WeakMap` lookup catalog until its garbage collected or page is reloaded.
143126

144-
Requires
127+
<sup>4</sup> Notation `[]` denotes pseudo `id` from a [Multiset](https://en.wikipedia.org/wiki/Multiset) of recurring instances, which is assigned in the scope of serialization of a high level argument instance, while comparing left or right side; that means - if some object, having `id` of `[0001]` on the left side, is not guarantied to have same `id` on the right side.
145128

146-
- Linux
147-
- node 22.11 (LTS)
148-
149-
```sh
150-
make install # to install dependencies
151-
make all # build for prod and make extension.${browser}.zip
152-
make tune2chrome # or tune2firefox for relevant manifest.json file
153-
make dev # local development
154-
```
129+
<sup>5</sup> `Map` key, unless it's a primitive type, serialized by his pseudo `id`.
155130

156131
### Protection
157132

158133
- How to protect your site from this extension:
159-
- Well, tests on chrome show that even `Content-Security-Policy: default-src 'none';` header won't prevent injection of extension content-scripts...
134+
135+
- Tests in Chrome show that even `Content-Security-Policy: default-src 'none';` header won't prevent injection of extension content-scripts...
136+
160137
- Avoid assigning to `window` or `globalThis` any application object.
161138
See also [accidental global variables and memory leaks](https://www.tutorialspoint.com/explain-in-detail-about-memory-leaks-in-javascript).
139+
162140
- In general, you can incapacitate console functions:
141+
163142
```js
164143
for (const prop in console) {
165144
if (typeof console[prop] === 'function' && prop !== 'error') {
166145
console[prop] = function noop() {};
167146
}
168147
}
169148
```
149+
150+
### Build instructions
151+
152+
- Linux
153+
- node 22.14 (LTS)
154+
155+
```sh
156+
make install # install dependencies
157+
make all # build for prod and make extension.${browser}.zip
158+
make tune2chrome # or tune2firefox for relevant manifest.json file
159+
make dev # local development
160+
```
161+
162+
#### Based on
163+
164+
- [jsondiffpatch](https://github.com/benjamine/jsondiffpatch) by Benjamín Eidelman
165+
- [vuejs](https://github.com/vuejs) by Evan You
166+
167+
<details>
168+
<summary> <strong>Communication schemes between Content-script and DevTools panel</strong> </summary>
169+
170+
- Chrome mv3
171+
![screenshot](./doc/design.chrome.png)
172+
- Firefox
173+
![screenshot](./doc/design.firefox.png)
174+
175+
</details>

manifest.chrome.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "console.diff(...)",
4-
"version": "3.0.6",
4+
"version": "3.0.7",
55
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlCx2Bl0li+3idvfrH9cQL/MzphafGFqMUA2P+0vbyhwxsxWl0llOaGQbkirX5qCoAVHoUCPqu3hCjpVCv35igPbfqDs5bdLZZmXt2F0HjEQnWI/eZKd9IKcKYMplEeL2BodmpU02VrP1UnUzQHZeeMWk9ybgWOqCimkwliILVubRj5dxNB9AidLwO4Z5iGq/OvW9AJMYdxKxrLP2lF6/GGNcCBg+iCJZwlQOhFB9LbUjytT4ws3bIEX4b5zmWLqGKR1NiZfGug2eCWXt9oEKg2WkbXmBBzFKqxnM/bBUrVR29N9qNgx0f42qnyhsW3Bo4kPzE3d0asXCV5nofLTLEwIDAQAB",
66
"description": "Compare objects in memory with console.diff(old, new) devtools function",
77
"minimum_chrome_version": "100.0",

package.json

+18-15
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
{
22
"type": "module",
33
"devDependencies": {
4-
"@types/chrome": "0.0.280",
4+
"@noble/hashes": "1.7.1",
5+
"@types/chrome": "0.0.307",
56
"@types/diff-match-patch": "1.0.36",
67
"@types/firefox-webext-browser": "120.0.4",
78
"@types/webpack-bundle-analyzer": "4.7.0",
8-
"@vue/compiler-sfc": "3.5.12",
9-
"clean-webpack-plugin": "4.0.0",
9+
"@vue/compiler-sfc": "3.5.13",
1010
"css-loader": "7.1.2",
1111
"diff-match-patch": "1.0.5",
12-
"esbuild": "0.24.0",
13-
"esbuild-loader": "4.2.2",
12+
"esbuild": "0.25.0",
13+
"esbuild-loader": "4.3.0",
1414
"jsondiffpatch": "0.6.0",
15-
"pinia": "2.2.6",
16-
"prettier": "3.3.3",
17-
"sass": "1.80.6",
18-
"sass-loader": "16.0.3",
15+
"pinia": "3.0.1",
16+
"prettier": "3.5.3",
17+
"sass": "1.85.1",
18+
"sass-loader": "16.0.5",
1919
"style-loader": "4.0.0",
20-
"tsx": "4.19.2",
21-
"typescript": "5.6.3",
22-
"vue": "3.5.12",
20+
"tsx": "4.19.3",
21+
"typescript": "5.8.2",
22+
"vue": "3.5.13",
2323
"vue-loader": "17.4.2",
24-
"webpack": "5.96.1",
24+
"webpack": "5.98.0",
2525
"webpack-bundle-analyzer": "4.10.2",
26-
"webpack-cli": "5.1.4"
26+
"webpack-cli": "6.0.1"
2727
},
2828
"pnpm": {
29-
"overrides": {}
29+
"overrides": {},
30+
"onlyBuiltDependencies": [
31+
"sass"
32+
]
3033
}
3134
}

0 commit comments

Comments
 (0)