@arcanejs/diff 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +57 -24
  2. package/package.json +8 -8
package/README.md CHANGED
@@ -2,42 +2,75 @@
2
2
 
3
3
  [![NPM Version](https://img.shields.io/npm/v/%40arcanejs%2Fdiff)](https://www.npmjs.com/package/@arcanejs/diff)
4
4
 
5
- This package provides an easy way to:
5
+ Typed JSON diff/patch utilities used by ArcaneJS to synchronize state efficiently.
6
6
 
7
- - Create diffs by comparing objects
8
- - Update objects by applying diffs
7
+ `@arcanejs/diff` provides:
9
8
 
10
- This library is written in TypeScript,
11
- and produces diffs that are type-safe,
12
- and can only be applied to objects that match the type
13
- of the objects being compared.
9
+ - `diffJson(a, b)` to compute structural differences
10
+ - `patchJson(old, diff)` to apply a diff and reconstruct the new value
11
+ - Type-level diff contracts (`Diff<T>`, `NestedDiff<T>`, `JSONValue`, etc.)
14
12
 
15
- This package is part of the
16
- [`arcanejs` project](https://github.com/arcanejs/arcanejs#arcanejs),
17
- and is used to maintain a copy of a JSON tree in downstream clients in real-time
18
- via websockets.
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install @arcanejs/diff
17
+ ```
18
+
19
+ ## API
20
+
21
+ ### `diffJson(a, b)`
22
+
23
+ Compares two JSON-compatible values and returns a typed diff.
24
+
25
+ Possible diff forms:
26
+
27
+ - `{ type: 'match' }`
28
+ - `{ type: 'value', after }` for primitive/type changes
29
+ - `{ type: 'splice', start, count, items }` for array length changes
30
+ - `{ type: 'modified-a', changes }` for same-length array item updates
31
+ - `{ type: 'modified-o', additions?, deletions?, changes? }` for object updates
32
+
33
+ ### `patchJson(old, diff)`
34
+
35
+ Applies a diff to a previous value and returns the patched result.
36
+
37
+ Patch behavior is immutable (returns new arrays/objects where needed).
19
38
 
20
39
  ## Usage
21
40
 
22
41
  ```ts
23
- import { diffJson, Diff } from '@arcanejs/diff/diff';
24
- import { patchJson } from '@arcanejs/diff/patch';
42
+ import { diffJson, patchJson, type Diff } from '@arcanejs/diff';
25
43
 
26
- type E = {
27
- foo: string;
28
- bar?: number[];
44
+ type Model = {
45
+ name: string;
46
+ values: number[];
29
47
  };
30
48
 
31
- const a: E = { foo: 'bar' };
32
- const b: E = { foo: 'baz', bar: [1] };
49
+ const previous: Model = { name: 'A', values: [1, 2, 3] };
50
+ const next: Model = { name: 'B', values: [1, 4, 3, 5] };
33
51
 
34
- const diffA: Diff<E> = diffJson(a, b);
52
+ const diff: Diff<Model> = diffJson(previous, next);
53
+ const reconstructed = patchJson(previous, diff);
35
54
 
36
- const resultA = patchJson(a, diffA);
55
+ console.log(reconstructed); // { name: 'B', values: [1, 4, 3, 5] }
56
+ ```
37
57
 
38
- console.log(resultB); // { foo: 'baz', bar: [1] }
58
+ ## Type Safety
39
59
 
40
- const c = { baz: 'foo' };
60
+ `Diff<T>` is parameterized on the JSON value type, so diffs and patch operations remain tied to the expected shape.
41
61
 
42
- const resultB = patchJson(c, diffA); // TypeScript Type Error: Property 'baz' is missing in type '{ foo: string; bar?: number[] | undefined; }' but required in type '{ baz: string; }'
43
- ```
62
+ ## Error Cases
63
+
64
+ `patchJson` throws when diff/value kinds are incompatible, for example:
65
+
66
+ - applying `splice` to non-arrays
67
+ - applying `modified-o` to non-objects
68
+
69
+ ## ArcaneJS Usage
70
+
71
+ ArcaneJS server tracks the last tree sent to each client and sends `tree-diff` updates computed with `diffJson`; browser stage reconstructs latest tree with `patchJson`.
72
+
73
+ Relevant references:
74
+
75
+ - Diff producer: <https://github.com/ArcaneWizards/arcanejs/blob/main/packages/toolkit/src/backend/toolkit.ts>
76
+ - Diff consumer: <https://github.com/ArcaneWizards/arcanejs/blob/main/packages/toolkit/src/frontend/stage.tsx>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcanejs/diff",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "private": false,
5
5
  "description": "Create and apply JSON diffs of JSON objects",
6
6
  "keywords": [
@@ -18,26 +18,26 @@
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "https://github.com/arcanejs/arcanejs.git"
21
+ "url": "https://github.com/ArcaneWizards/arcanejs.git"
22
22
  },
23
23
  "exports": {
24
24
  ".": {
25
25
  "@arcanejs/source": "./src/index.ts",
26
+ "types": "./dist/index.d.ts",
26
27
  "import": "./dist/index.mjs",
27
- "require": "./dist/index.js",
28
- "types": "./dist/index.d.ts"
28
+ "require": "./dist/index.js"
29
29
  },
30
30
  "./diff": {
31
31
  "@arcanejs/source": "./src/diff.ts",
32
+ "types": "./dist/diff.d.ts",
32
33
  "import": "./dist/diff.mjs",
33
- "require": "./dist/diff.js",
34
- "types": "./dist/diff.d.ts"
34
+ "require": "./dist/diff.js"
35
35
  },
36
36
  "./patch": {
37
37
  "@arcanejs/source": "./src/patch.ts",
38
+ "types": "./dist/patch.d.ts",
38
39
  "import": "./dist/patch.mjs",
39
- "require": "./dist/patch.js",
40
- "types": "./dist/patch.d.ts"
40
+ "require": "./dist/patch.js"
41
41
  },
42
42
  "./package.json": "./package.json"
43
43
  },