spotdiff 0.1.0

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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/dist/cjs/diff.d.ts +3 -0
  4. package/dist/cjs/diff.d.ts.map +1 -0
  5. package/dist/cjs/diff.js +162 -0
  6. package/dist/cjs/diff.js.map +1 -0
  7. package/dist/cjs/humanize.d.ts +3 -0
  8. package/dist/cjs/humanize.d.ts.map +1 -0
  9. package/dist/cjs/humanize.js +27 -0
  10. package/dist/cjs/humanize.js.map +1 -0
  11. package/dist/cjs/index.d.ts +5 -0
  12. package/dist/cjs/index.d.ts.map +1 -0
  13. package/dist/cjs/index.js +13 -0
  14. package/dist/cjs/index.js.map +1 -0
  15. package/dist/cjs/patch.d.ts +6 -0
  16. package/dist/cjs/patch.d.ts.map +1 -0
  17. package/dist/cjs/patch.js +142 -0
  18. package/dist/cjs/patch.js.map +1 -0
  19. package/dist/cjs/types.d.ts +19 -0
  20. package/dist/cjs/types.d.ts.map +1 -0
  21. package/dist/cjs/types.js +3 -0
  22. package/dist/cjs/types.js.map +1 -0
  23. package/dist/cjs/utils.d.ts +7 -0
  24. package/dist/cjs/utils.d.ts.map +1 -0
  25. package/dist/cjs/utils.js +34 -0
  26. package/dist/cjs/utils.js.map +1 -0
  27. package/dist/esm/diff.d.ts +3 -0
  28. package/dist/esm/diff.d.ts.map +1 -0
  29. package/dist/esm/diff.js +162 -0
  30. package/dist/esm/diff.js.map +1 -0
  31. package/dist/esm/humanize.d.ts +3 -0
  32. package/dist/esm/humanize.d.ts.map +1 -0
  33. package/dist/esm/humanize.js +27 -0
  34. package/dist/esm/humanize.js.map +1 -0
  35. package/dist/esm/index.d.ts +5 -0
  36. package/dist/esm/index.d.ts.map +1 -0
  37. package/dist/esm/index.js +13 -0
  38. package/dist/esm/index.js.map +1 -0
  39. package/dist/esm/patch.d.ts +6 -0
  40. package/dist/esm/patch.d.ts.map +1 -0
  41. package/dist/esm/patch.js +142 -0
  42. package/dist/esm/patch.js.map +1 -0
  43. package/dist/esm/types.d.ts +19 -0
  44. package/dist/esm/types.d.ts.map +1 -0
  45. package/dist/esm/types.js +3 -0
  46. package/dist/esm/types.js.map +1 -0
  47. package/dist/esm/utils.d.ts +7 -0
  48. package/dist/esm/utils.d.ts.map +1 -0
  49. package/dist/esm/utils.js +34 -0
  50. package/dist/esm/utils.js.map +1 -0
  51. package/dist/types/diff.d.ts +3 -0
  52. package/dist/types/diff.d.ts.map +1 -0
  53. package/dist/types/humanize.d.ts +3 -0
  54. package/dist/types/humanize.d.ts.map +1 -0
  55. package/dist/types/index.d.ts +5 -0
  56. package/dist/types/index.d.ts.map +1 -0
  57. package/dist/types/patch.d.ts +6 -0
  58. package/dist/types/patch.d.ts.map +1 -0
  59. package/dist/types/types.d.ts +19 -0
  60. package/dist/types/types.d.ts.map +1 -0
  61. package/dist/types/utils.d.ts +7 -0
  62. package/dist/types/utils.d.ts.map +1 -0
  63. package/package.json +71 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ricardo Nain
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # spotdiff
2
+
3
+ Compare two JS objects, find what changed, patch back, humanize the diff.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install spotdiff
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { spotdiff, patch, humanize } from 'spotdiff'
15
+
16
+ const v1 = { user: { name: 'Juan', age: 30, tags: ['a', 'b'] } }
17
+ const v2 = { user: { name: 'Juan', age: 31, tags: ['a', 'c', 'd'] } }
18
+
19
+ const changes = spotdiff(v1, v2)
20
+ // [
21
+ // { path: 'user.age', op: 'changed', from: 30, to: 31 },
22
+ // { path: 'user.tags[1]', op: 'changed', from: 'b', to: 'c' },
23
+ // { path: 'user.tags[2]', op: 'added', from: undefined, to: 'd' },
24
+ // ]
25
+
26
+ patch(v1, changes) // → v2
27
+ patch(v2, changes, true) // → v1
28
+
29
+ humanize(changes)
30
+ // [
31
+ // "user.age changed from 30 to 31",
32
+ // "user.tags[1] changed from b to c",
33
+ // "user.tags[2] was added with value d"
34
+ // ]
35
+
36
+ humanize(changes, { lang: 'es' })
37
+ // [
38
+ // "user.age cambió de 30 a 31",
39
+ // "user.tags[1] cambió de b a c",
40
+ // "user.tags[2] fue agregado con valor d"
41
+ // ]
42
+ ```
43
+
44
+ ## API
45
+
46
+ ### `spotdiff(a, b, options?): Change[]`
47
+
48
+ | Option | Type | Default | Description |
49
+ |--------|------|---------|-------------|
50
+ | `maxDepth` | `number` | `Infinity` | Stop recursion at this depth |
51
+ | `ignoreKeys` | `string[]` | `[]` | Skip these keys everywhere |
52
+ | `arrays` | `'index' \| 'smart'` | `'index'` | Array comparison strategy |
53
+
54
+ ### `patch(obj, changes, reverse?): unknown`
55
+
56
+ Apply changes forward or backward (reverse=true).
57
+
58
+ ### `humanize(changes, options?): string[]`
59
+
60
+ | Option | Type | Default |
61
+ |--------|------|---------|
62
+ | `lang` | `'en' \| 'es'` | `'en'` |
63
+
64
+ ## Change shape
65
+
66
+ ```ts
67
+ interface Change {
68
+ path: string // "user.address.city" or "tags[2]"
69
+ op: 'added' | 'removed' | 'changed'
70
+ from: unknown // undefined if op is 'added'
71
+ to: unknown // undefined if op is 'removed'
72
+ }
73
+ ```
74
+
75
+ ## Notes
76
+
77
+ - Zero production dependencies
78
+ - Dual package ESM + CJS
79
+ - TypeScript strict mode
80
+ - Never mutates inputs
81
+ - Handles `null`, `undefined`, `Date`, `Map`, `Set`
82
+ - Throws on circular references with a descriptive message
@@ -0,0 +1,3 @@
1
+ import type { Change, SpotdiffOptions } from './types.js';
2
+ export declare function spotdiff(a: unknown, b: unknown, options?: SpotdiffOptions): Change[];
3
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAyMzD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,EAAE,CAaxF"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.spotdiff = spotdiff;
4
+ const utils_js_1 = require("./utils.js");
5
+ function walk(a, b, path, depth, ctx) {
6
+ if ((0, utils_js_1.areEqual)(a, b))
7
+ return;
8
+ // Both primitives or incompatible types — emit change directly
9
+ const aIsObj = (0, utils_js_1.isObject)(a) || Array.isArray(a);
10
+ const bIsObj = (0, utils_js_1.isObject)(b) || Array.isArray(b);
11
+ if (!aIsObj && !bIsObj) {
12
+ ctx.changes.push({ path, op: 'changed', from: a, to: b });
13
+ return;
14
+ }
15
+ // Type mismatch (one is object/array, other is not)
16
+ if (!aIsObj || !bIsObj) {
17
+ ctx.changes.push({ path, op: 'changed', from: a, to: b });
18
+ return;
19
+ }
20
+ if (depth >= ctx.options.maxDepth) {
21
+ if (!(0, utils_js_1.areEqual)(a, b))
22
+ ctx.changes.push({ path, op: 'changed', from: a, to: b });
23
+ return;
24
+ }
25
+ // Circular reference detection
26
+ if (typeof a === 'object' && a !== null) {
27
+ if (ctx.visited.has(a))
28
+ throw new Error(`Circular reference detected at path: ${path || '(root)'}`);
29
+ ctx.visited.add(a);
30
+ }
31
+ if (typeof b === 'object' && b !== null) {
32
+ if (ctx.visited.has(b))
33
+ throw new Error(`Circular reference detected at path: ${path || '(root)'}`);
34
+ ctx.visited.add(b);
35
+ }
36
+ if (Array.isArray(a) && Array.isArray(b)) {
37
+ diffArrays(a, b, path, depth, ctx);
38
+ }
39
+ else if (Array.isArray(a) !== Array.isArray(b)) {
40
+ ctx.changes.push({ path, op: 'changed', from: a, to: b });
41
+ }
42
+ else {
43
+ diffObjects(a, b, path, depth, ctx);
44
+ }
45
+ }
46
+ function diffArrays(a, b, path, depth, ctx) {
47
+ if (ctx.options.arrays === 'smart') {
48
+ diffArraysSmart(a, b, path, depth, ctx);
49
+ return;
50
+ }
51
+ const len = Math.max(a.length, b.length);
52
+ for (let i = 0; i < len; i++) {
53
+ const childPath = `${path}[${i}]`;
54
+ if (i >= a.length) {
55
+ ctx.changes.push({ path: childPath, op: 'added', from: undefined, to: b[i] });
56
+ }
57
+ else if (i >= b.length) {
58
+ ctx.changes.push({ path: childPath, op: 'removed', from: a[i], to: undefined });
59
+ }
60
+ else {
61
+ walk(a[i], b[i], childPath, depth + 1, ctx);
62
+ }
63
+ }
64
+ }
65
+ function diffArraysSmart(a, b, path, depth, ctx) {
66
+ // For object arrays: try to match by identity keys (id, key, name)
67
+ // Fall back to index-based for primitive arrays
68
+ const allObjects = a.every(utils_js_1.isObject) && b.every(utils_js_1.isObject);
69
+ if (!allObjects) {
70
+ diffArraysIndex(a, b, path, depth, ctx);
71
+ return;
72
+ }
73
+ const IDENTITY_KEYS = ['id', 'key', '_id', 'name'];
74
+ const identityKey = IDENTITY_KEYS.find(k => a.every(item => (0, utils_js_1.isObject)(item) && k in item));
75
+ if (!identityKey) {
76
+ diffArraysIndex(a, b, path, depth, ctx);
77
+ return;
78
+ }
79
+ const aMap = new Map();
80
+ for (let i = 0; i < a.length; i++) {
81
+ const item = a[i];
82
+ aMap.set(item[identityKey], { item, idx: i });
83
+ }
84
+ const matched = new Set();
85
+ for (let j = 0; j < b.length; j++) {
86
+ const bItem = b[j];
87
+ const id = bItem[identityKey];
88
+ const childPath = `${path}[${j}]`;
89
+ if (aMap.has(id)) {
90
+ matched.add(id);
91
+ const { item: aItem } = aMap.get(id);
92
+ walk(aItem, bItem, childPath, depth + 1, ctx);
93
+ }
94
+ else {
95
+ ctx.changes.push({ path: childPath, op: 'added', from: undefined, to: bItem });
96
+ }
97
+ }
98
+ for (let i = 0; i < a.length; i++) {
99
+ const aItem = a[i];
100
+ const id = aItem[identityKey];
101
+ if (!matched.has(id)) {
102
+ ctx.changes.push({ path: `${path}[${i}]`, op: 'removed', from: aItem, to: undefined });
103
+ }
104
+ }
105
+ }
106
+ function diffArraysIndex(a, b, path, depth, ctx) {
107
+ const len = Math.max(a.length, b.length);
108
+ for (let i = 0; i < len; i++) {
109
+ const childPath = `${path}[${i}]`;
110
+ if (i >= a.length) {
111
+ ctx.changes.push({ path: childPath, op: 'added', from: undefined, to: b[i] });
112
+ }
113
+ else if (i >= b.length) {
114
+ ctx.changes.push({ path: childPath, op: 'removed', from: a[i], to: undefined });
115
+ }
116
+ else {
117
+ walk(a[i], b[i], childPath, depth + 1, ctx);
118
+ }
119
+ }
120
+ }
121
+ function checkCircular(val, path, visited) {
122
+ if (typeof val === 'object' && val !== null && !(val instanceof Date) && !(val instanceof Map) && !(val instanceof Set)) {
123
+ if (visited.has(val)) {
124
+ throw new Error(`Circular reference detected at path: ${path || '(root)'}`);
125
+ }
126
+ }
127
+ }
128
+ function diffObjects(a, b, path, depth, ctx) {
129
+ const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
130
+ for (const key of keys) {
131
+ if (ctx.options.ignoreKeys.includes(key))
132
+ continue;
133
+ const childPath = path ? `${path}.${key}` : key;
134
+ const inA = Object.prototype.hasOwnProperty.call(a, key);
135
+ const inB = Object.prototype.hasOwnProperty.call(b, key);
136
+ if (!inA) {
137
+ checkCircular(b[key], childPath, ctx.visited);
138
+ ctx.changes.push({ path: childPath, op: 'added', from: undefined, to: b[key] });
139
+ }
140
+ else if (!inB) {
141
+ checkCircular(a[key], childPath, ctx.visited);
142
+ ctx.changes.push({ path: childPath, op: 'removed', from: a[key], to: undefined });
143
+ }
144
+ else {
145
+ walk(a[key], b[key], childPath, depth + 1, ctx);
146
+ }
147
+ }
148
+ }
149
+ function spotdiff(a, b, options = {}) {
150
+ const ctx = {
151
+ changes: [],
152
+ options: {
153
+ maxDepth: options.maxDepth ?? Infinity,
154
+ ignoreKeys: options.ignoreKeys ?? [],
155
+ arrays: options.arrays ?? 'index',
156
+ },
157
+ visited: new WeakSet(),
158
+ };
159
+ walk(a, b, '', 0, ctx);
160
+ return ctx.changes;
161
+ }
162
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/diff.ts"],"names":[],"mappings":";;AAyMA,4BAaC;AArND,yCAA4D;AAQ5D,SAAS,IAAI,CACX,CAAU,EACV,CAAU,EACV,IAAY,EACZ,KAAa,EACb,GAAgB;IAEhB,IAAI,IAAA,mBAAQ,EAAC,CAAC,EAAE,CAAC,CAAC;QAAE,OAAM;IAE1B,+DAA+D;IAC/D,MAAM,MAAM,GAAG,IAAA,mBAAQ,EAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAC9C,MAAM,MAAM,GAAG,IAAA,mBAAQ,EAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAE9C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;QACzD,OAAM;IACR,CAAC;IAED,oDAAoD;IACpD,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;QACzD,OAAM;IACR,CAAC;IAED,IAAI,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QAClC,IAAI,CAAC,IAAA,mBAAQ,EAAC,CAAC,EAAE,CAAC,CAAC;YAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;QAC9E,OAAM;IACR,CAAC;IAED,+BAA+B;IAC/B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACxC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAW,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,IAAI,QAAQ,EAAE,CAAC,CAAA;QAC7G,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAW,CAAC,CAAA;IAC9B,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACxC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAW,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,IAAI,QAAQ,EAAE,CAAC,CAAA;QAC7G,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAW,CAAC,CAAA;IAC9B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;IACpC,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;IAC3D,CAAC;SAAM,CAAC;QACN,WAAW,CACT,CAA4B,EAC5B,CAA4B,EAC5B,IAAI,EACJ,KAAK,EACL,GAAG,CACJ,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CACjB,CAAY,EACZ,CAAY,EACZ,IAAY,EACZ,KAAa,EACb,GAAgB;IAEhB,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QACnC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QACvC,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,CAAA;QACjC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YAClB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QAC/E,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;QACjF,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CACtB,CAAY,EACZ,CAAY,EACZ,IAAY,EACZ,KAAa,EACb,GAAgB;IAEhB,mEAAmE;IACnE,gDAAgD;IAChD,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,mBAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,mBAAQ,CAAC,CAAA;IAEzD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QACvC,OAAM;IACR,CAAC;IAED,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;IAClD,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAA,mBAAQ,EAAC,IAAI,CAAC,IAAI,CAAC,IAAK,IAAgC,CAAC,CAC/E,CAAA;IAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QACvC,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2D,CAAA;IAC/E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAA4B,CAAA;QAC5C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;IAC/C,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAW,CAAA;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAA4B,CAAA;QAC7C,MAAM,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,CAAA;QAC7B,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,CAAA;QAEjC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACf,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAE,CAAA;YACrC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;QAC/C,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QAChF,CAAC;IACH,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAA4B,CAAA;QAC7C,MAAM,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,CAAA;QAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACrB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;QACxF,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CACtB,CAAY,EACZ,CAAY,EACZ,IAAY,EACZ,KAAa,EACb,GAAgB;IAEhB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,CAAA;QACjC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YAClB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QAC/E,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;QACjF,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,GAAY,EAAE,IAAY,EAAE,OAAwB;IACzE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,GAAG,CAAC,EAAE,CAAC;QACxH,IAAI,OAAO,CAAC,GAAG,CAAC,GAAa,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,IAAI,QAAQ,EAAE,CAAC,CAAA;QAC7E,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAClB,CAA0B,EAC1B,CAA0B,EAC1B,IAAY,EACZ,KAAa,EACb,GAAgB;IAEhB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAE5D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAQ;QAElD,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;QAC/C,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QACxD,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAExD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;YAC7C,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACjF,CAAC;aAAM,IAAI,CAAC,GAAG,EAAE,CAAC;YAChB,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;YAC7C,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAA;QACnF,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;QACjD,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAU,EAAE,CAAU,EAAE,UAA2B,EAAE;IAC5E,MAAM,GAAG,GAAgB;QACvB,OAAO,EAAE,EAAE;QACX,OAAO,EAAE;YACP,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ;YACtC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,EAAE;YACpC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO;SAClC;QACD,OAAO,EAAE,IAAI,OAAO,EAAE;KACvB,CAAA;IAED,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;IACtB,OAAO,GAAG,CAAC,OAAO,CAAA;AACpB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Change, HumanizeOptions } from './types.js';
2
+ export declare function humanize(changes: Change[], options?: HumanizeOptions): string[];
3
+ //# sourceMappingURL=humanize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"humanize.d.ts","sourceRoot":"","sources":["../../src/humanize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAqBzD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,EAAE,CASnF"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.humanize = humanize;
4
+ const templates = {
5
+ en: {
6
+ changed: (path, from, to) => `${path} changed from ${from} to ${to}`,
7
+ added: (path, to) => `${path} was added with value ${to}`,
8
+ removed: (path, from) => `${path} was removed (was ${from})`,
9
+ },
10
+ es: {
11
+ changed: (path, from, to) => `${path} cambió de ${from} a ${to}`,
12
+ added: (path, to) => `${path} fue agregado con valor ${to}`,
13
+ removed: (path, from) => `${path} fue eliminado (era ${from})`,
14
+ },
15
+ };
16
+ function humanize(changes, options = {}) {
17
+ const lang = options.lang ?? 'en';
18
+ const t = templates[lang] ?? templates['en'];
19
+ return changes.map(({ path, op, from, to }) => {
20
+ if (op === 'changed')
21
+ return t.changed(path, from, to);
22
+ if (op === 'added')
23
+ return t.added(path, to);
24
+ return t.removed(path, from);
25
+ });
26
+ }
27
+ //# sourceMappingURL=humanize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"humanize.js","sourceRoot":"","sources":["../../src/humanize.ts"],"names":[],"mappings":";;AAqBA,4BASC;AAtBD,MAAM,SAAS,GAA8B;IAC3C,EAAE,EAAE;QACF,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,iBAAiB,IAAI,OAAO,EAAE,EAAE;QACpE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,yBAAyB,EAAE,EAAE;QACzD,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,qBAAqB,IAAI,GAAG;KAC7D;IACD,EAAE,EAAE;QACF,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,cAAc,IAAI,MAAM,EAAE,EAAE;QAChE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,2BAA2B,EAAE,EAAE;QAC3D,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,uBAAuB,IAAI,GAAG;KAC/D;CACF,CAAA;AAED,SAAgB,QAAQ,CAAC,OAAiB,EAAE,UAA2B,EAAE;IACvE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAA;IACjC,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAA;IAE5C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE;QAC5C,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;QACtD,IAAI,EAAE,KAAK,OAAO;YAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAC5C,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAC9B,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { spotdiff } from './diff.js';
2
+ export { patch, getPath, setPath, deletePath } from './patch.js';
3
+ export { humanize } from './humanize.js';
4
+ export type { Change, Op, SpotdiffOptions, HumanizeOptions, PatchOptions } from './types.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.humanize = exports.deletePath = exports.setPath = exports.getPath = exports.patch = exports.spotdiff = void 0;
4
+ var diff_js_1 = require("./diff.js");
5
+ Object.defineProperty(exports, "spotdiff", { enumerable: true, get: function () { return diff_js_1.spotdiff; } });
6
+ var patch_js_1 = require("./patch.js");
7
+ Object.defineProperty(exports, "patch", { enumerable: true, get: function () { return patch_js_1.patch; } });
8
+ Object.defineProperty(exports, "getPath", { enumerable: true, get: function () { return patch_js_1.getPath; } });
9
+ Object.defineProperty(exports, "setPath", { enumerable: true, get: function () { return patch_js_1.setPath; } });
10
+ Object.defineProperty(exports, "deletePath", { enumerable: true, get: function () { return patch_js_1.deletePath; } });
11
+ var humanize_js_1 = require("./humanize.js");
12
+ Object.defineProperty(exports, "humanize", { enumerable: true, get: function () { return humanize_js_1.humanize; } });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAAoC;AAA3B,mGAAA,QAAQ,OAAA;AACjB,uCAAgE;AAAvD,iGAAA,KAAK,OAAA;AAAE,mGAAA,OAAO,OAAA;AAAE,mGAAA,OAAO,OAAA;AAAE,sGAAA,UAAU,OAAA;AAC5C,6CAAwC;AAA/B,uGAAA,QAAQ,OAAA"}
@@ -0,0 +1,6 @@
1
+ import type { Change } from './types.js';
2
+ export declare function getPath(obj: unknown, path: string): unknown;
3
+ export declare function setPath(obj: unknown, path: string, value: unknown): void;
4
+ export declare function deletePath(obj: unknown, path: string): void;
5
+ export declare function patch(obj: unknown, changes: Change[], reverse?: boolean): unknown;
6
+ //# sourceMappingURL=patch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../src/patch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAA;AAoCtD,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAY3D;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CA4BxE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAoB3D;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,UAAQ,GAAG,OAAO,CA2B/E"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPath = getPath;
4
+ exports.setPath = setPath;
5
+ exports.deletePath = deletePath;
6
+ exports.patch = patch;
7
+ function cloneDeep(val) {
8
+ if (val === null || val === undefined)
9
+ return val;
10
+ if (val instanceof Date)
11
+ return new Date(val.getTime());
12
+ if (val instanceof Map)
13
+ return new Map(val);
14
+ if (val instanceof Set)
15
+ return new Set(val);
16
+ if (Array.isArray(val))
17
+ return val.map(cloneDeep);
18
+ if (typeof val === 'object') {
19
+ const out = {};
20
+ for (const key of Object.keys(val)) {
21
+ out[key] = cloneDeep(val[key]);
22
+ }
23
+ return out;
24
+ }
25
+ return val;
26
+ }
27
+ function parsePath(path) {
28
+ const segments = [];
29
+ // Split on dots and brackets
30
+ // e.g. "user.tags[2].name" → ['user', 'tags', '[2]', 'name']
31
+ const regex = /([^.[]+)|\[(\d+)\]/g;
32
+ let match;
33
+ while ((match = regex.exec(path)) !== null) {
34
+ if (match[1] !== undefined) {
35
+ segments.push({ type: 'key', key: match[1] });
36
+ }
37
+ else if (match[2] !== undefined) {
38
+ segments.push({ type: 'index', index: parseInt(match[2], 10) });
39
+ }
40
+ }
41
+ return segments;
42
+ }
43
+ function getPath(obj, path) {
44
+ const segments = parsePath(path);
45
+ let cur = obj;
46
+ for (const seg of segments) {
47
+ if (cur === null || cur === undefined)
48
+ return undefined;
49
+ if (seg.type === 'key') {
50
+ cur = cur[seg.key];
51
+ }
52
+ else {
53
+ cur = cur[seg.index];
54
+ }
55
+ }
56
+ return cur;
57
+ }
58
+ function setPath(obj, path, value) {
59
+ const segments = parsePath(path);
60
+ let cur = obj;
61
+ for (let i = 0; i < segments.length - 1; i++) {
62
+ const seg = segments[i];
63
+ if (seg.type === 'key') {
64
+ const o = cur;
65
+ if (o[seg.key] === null || o[seg.key] === undefined) {
66
+ const next = segments[i + 1];
67
+ o[seg.key] = next.type === 'index' ? [] : {};
68
+ }
69
+ cur = o[seg.key];
70
+ }
71
+ else {
72
+ const arr = cur;
73
+ if (arr[seg.index] === null || arr[seg.index] === undefined) {
74
+ const next = segments[i + 1];
75
+ arr[seg.index] = next.type === 'index' ? [] : {};
76
+ }
77
+ cur = arr[seg.index];
78
+ }
79
+ }
80
+ const last = segments[segments.length - 1];
81
+ if (last.type === 'key') {
82
+ cur[last.key] = value;
83
+ }
84
+ else {
85
+ cur[last.index] = value;
86
+ }
87
+ }
88
+ function deletePath(obj, path) {
89
+ const segments = parsePath(path);
90
+ let cur = obj;
91
+ for (let i = 0; i < segments.length - 1; i++) {
92
+ const seg = segments[i];
93
+ if (cur === null || cur === undefined)
94
+ return;
95
+ if (seg.type === 'key') {
96
+ cur = cur[seg.key];
97
+ }
98
+ else {
99
+ cur = cur[seg.index];
100
+ }
101
+ }
102
+ if (cur === null || cur === undefined)
103
+ return;
104
+ const last = segments[segments.length - 1];
105
+ if (last.type === 'key') {
106
+ delete cur[last.key];
107
+ }
108
+ else {
109
+ cur.splice(last.index, 1);
110
+ }
111
+ }
112
+ function patch(obj, changes, reverse = false) {
113
+ const cloned = cloneDeep(obj);
114
+ for (const change of changes) {
115
+ const { path, op, from, to } = change;
116
+ if (reverse) {
117
+ // Invert: added→remove, removed→add, changed→swap from/to
118
+ if (op === 'added') {
119
+ deletePath(cloned, path);
120
+ }
121
+ else if (op === 'removed') {
122
+ setPath(cloned, path, from);
123
+ }
124
+ else {
125
+ setPath(cloned, path, from);
126
+ }
127
+ }
128
+ else {
129
+ if (op === 'added') {
130
+ setPath(cloned, path, to);
131
+ }
132
+ else if (op === 'removed') {
133
+ deletePath(cloned, path);
134
+ }
135
+ else {
136
+ setPath(cloned, path, to);
137
+ }
138
+ }
139
+ }
140
+ return cloned;
141
+ }
142
+ //# sourceMappingURL=patch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch.js","sourceRoot":"","sources":["../../src/patch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export type Op = 'added' | 'removed' | 'changed';
2
+ export interface Change {
3
+ path: string;
4
+ op: Op;
5
+ from: unknown;
6
+ to: unknown;
7
+ }
8
+ export interface SpotdiffOptions {
9
+ maxDepth?: number;
10
+ ignoreKeys?: string[];
11
+ arrays?: 'index' | 'smart';
12
+ }
13
+ export interface HumanizeOptions {
14
+ lang?: 'en' | 'es';
15
+ }
16
+ export interface PatchOptions {
17
+ reverse?: boolean;
18
+ }
19
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,EAAE,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAA;AAEhD,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,EAAE,CAAA;IACN,IAAI,EAAE,OAAO,CAAA;IACb,EAAE,EAAE,OAAO,CAAA;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import type { Op } from './types.js';
2
+ export declare function isObject(val: unknown): val is Record<string, unknown>;
3
+ export declare function isPrimitive(val: unknown): boolean;
4
+ export declare function invertOp(op: Op): Op;
5
+ export declare function normalizePath(path: string): string;
6
+ export declare function areEqual(a: unknown, b: unknown): boolean;
7
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAA;AAEpC,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAErE;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAKjD;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAInC;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAGxD"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isObject = isObject;
4
+ exports.isPrimitive = isPrimitive;
5
+ exports.invertOp = invertOp;
6
+ exports.normalizePath = normalizePath;
7
+ exports.areEqual = areEqual;
8
+ function isObject(val) {
9
+ return val !== null && typeof val === 'object' && !(val instanceof Date) && !Array.isArray(val);
10
+ }
11
+ function isPrimitive(val) {
12
+ if (val === null || val === undefined)
13
+ return true;
14
+ if (val instanceof Date)
15
+ return true;
16
+ const t = typeof val;
17
+ return t === 'string' || t === 'number' || t === 'boolean' || t === 'bigint' || t === 'symbol';
18
+ }
19
+ function invertOp(op) {
20
+ if (op === 'added')
21
+ return 'removed';
22
+ if (op === 'removed')
23
+ return 'added';
24
+ return 'changed';
25
+ }
26
+ function normalizePath(path) {
27
+ return path;
28
+ }
29
+ function areEqual(a, b) {
30
+ if (a instanceof Date && b instanceof Date)
31
+ return a.getTime() === b.getTime();
32
+ return Object.is(a, b);
33
+ }
34
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";;AAEA,4BAEC;AAED,kCAKC;AAED,4BAIC;AAED,sCAEC;AAED,4BAGC;AAxBD,SAAgB,QAAQ,CAAC,GAAY;IACnC,OAAO,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,YAAY,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;AACjG,CAAC;AAED,SAAgB,WAAW,CAAC,GAAY;IACtC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAClD,IAAI,GAAG,YAAY,IAAI;QAAE,OAAO,IAAI,CAAA;IACpC,MAAM,CAAC,GAAG,OAAO,GAAG,CAAA;IACpB,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,CAAA;AAChG,CAAC;AAED,SAAgB,QAAQ,CAAC,EAAM;IAC7B,IAAI,EAAE,KAAK,OAAO;QAAE,OAAO,SAAS,CAAA;IACpC,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,OAAO,CAAA;IACpC,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAgB,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAU,EAAE,CAAU;IAC7C,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,IAAI;QAAE,OAAO,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAA;IAC9E,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACxB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Change, SpotdiffOptions } from './types.js';
2
+ export declare function spotdiff(a: unknown, b: unknown, options?: SpotdiffOptions): Change[];
3
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAyMzD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,EAAE,CAaxF"}