@tanstack/db 0.0.1

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 (154) hide show
  1. package/README.md +37 -0
  2. package/dist/cjs/SortedMap.cjs +140 -0
  3. package/dist/cjs/SortedMap.cjs.map +1 -0
  4. package/dist/cjs/SortedMap.d.cts +91 -0
  5. package/dist/cjs/collection.cjs +597 -0
  6. package/dist/cjs/collection.cjs.map +1 -0
  7. package/dist/cjs/collection.d.cts +176 -0
  8. package/dist/cjs/deferred.cjs +25 -0
  9. package/dist/cjs/deferred.cjs.map +1 -0
  10. package/dist/cjs/deferred.d.cts +20 -0
  11. package/dist/cjs/errors.cjs +10 -0
  12. package/dist/cjs/errors.cjs.map +1 -0
  13. package/dist/cjs/errors.d.cts +3 -0
  14. package/dist/cjs/index.cjs +33 -0
  15. package/dist/cjs/index.cjs.map +1 -0
  16. package/dist/cjs/index.d.cts +9 -0
  17. package/dist/cjs/proxy.cjs +654 -0
  18. package/dist/cjs/proxy.cjs.map +1 -0
  19. package/dist/cjs/proxy.d.cts +59 -0
  20. package/dist/cjs/query/compiled-query.cjs +162 -0
  21. package/dist/cjs/query/compiled-query.cjs.map +1 -0
  22. package/dist/cjs/query/compiled-query.d.cts +22 -0
  23. package/dist/cjs/query/evaluators.cjs +146 -0
  24. package/dist/cjs/query/evaluators.cjs.map +1 -0
  25. package/dist/cjs/query/evaluators.d.cts +9 -0
  26. package/dist/cjs/query/extractors.cjs +122 -0
  27. package/dist/cjs/query/extractors.cjs.map +1 -0
  28. package/dist/cjs/query/extractors.d.cts +22 -0
  29. package/dist/cjs/query/functions.cjs +152 -0
  30. package/dist/cjs/query/functions.cjs.map +1 -0
  31. package/dist/cjs/query/functions.d.cts +21 -0
  32. package/dist/cjs/query/group-by.cjs +91 -0
  33. package/dist/cjs/query/group-by.cjs.map +1 -0
  34. package/dist/cjs/query/group-by.d.cts +40 -0
  35. package/dist/cjs/query/index.d.cts +5 -0
  36. package/dist/cjs/query/joins.cjs +155 -0
  37. package/dist/cjs/query/joins.cjs.map +1 -0
  38. package/dist/cjs/query/joins.d.cts +14 -0
  39. package/dist/cjs/query/key-by.cjs +43 -0
  40. package/dist/cjs/query/key-by.cjs.map +1 -0
  41. package/dist/cjs/query/key-by.d.cts +3 -0
  42. package/dist/cjs/query/order-by.cjs +229 -0
  43. package/dist/cjs/query/order-by.cjs.map +1 -0
  44. package/dist/cjs/query/order-by.d.cts +3 -0
  45. package/dist/cjs/query/pipeline-compiler.cjs +94 -0
  46. package/dist/cjs/query/pipeline-compiler.cjs.map +1 -0
  47. package/dist/cjs/query/pipeline-compiler.d.cts +9 -0
  48. package/dist/cjs/query/query-builder.cjs +314 -0
  49. package/dist/cjs/query/query-builder.cjs.map +1 -0
  50. package/dist/cjs/query/query-builder.d.cts +219 -0
  51. package/dist/cjs/query/schema.d.cts +98 -0
  52. package/dist/cjs/query/select.cjs +107 -0
  53. package/dist/cjs/query/select.cjs.map +1 -0
  54. package/dist/cjs/query/select.d.cts +3 -0
  55. package/dist/cjs/query/types.d.cts +188 -0
  56. package/dist/cjs/query/utils.cjs +154 -0
  57. package/dist/cjs/query/utils.cjs.map +1 -0
  58. package/dist/cjs/query/utils.d.cts +37 -0
  59. package/dist/cjs/transactions.cjs +137 -0
  60. package/dist/cjs/transactions.cjs.map +1 -0
  61. package/dist/cjs/transactions.d.cts +27 -0
  62. package/dist/cjs/types.d.cts +94 -0
  63. package/dist/cjs/utils.cjs +17 -0
  64. package/dist/cjs/utils.cjs.map +1 -0
  65. package/dist/cjs/utils.d.cts +3 -0
  66. package/dist/esm/SortedMap.d.ts +91 -0
  67. package/dist/esm/SortedMap.js +140 -0
  68. package/dist/esm/SortedMap.js.map +1 -0
  69. package/dist/esm/collection.d.ts +176 -0
  70. package/dist/esm/collection.js +597 -0
  71. package/dist/esm/collection.js.map +1 -0
  72. package/dist/esm/deferred.d.ts +20 -0
  73. package/dist/esm/deferred.js +25 -0
  74. package/dist/esm/deferred.js.map +1 -0
  75. package/dist/esm/errors.d.ts +3 -0
  76. package/dist/esm/errors.js +10 -0
  77. package/dist/esm/errors.js.map +1 -0
  78. package/dist/esm/index.d.ts +9 -0
  79. package/dist/esm/index.js +33 -0
  80. package/dist/esm/index.js.map +1 -0
  81. package/dist/esm/proxy.d.ts +59 -0
  82. package/dist/esm/proxy.js +654 -0
  83. package/dist/esm/proxy.js.map +1 -0
  84. package/dist/esm/query/compiled-query.d.ts +22 -0
  85. package/dist/esm/query/compiled-query.js +162 -0
  86. package/dist/esm/query/compiled-query.js.map +1 -0
  87. package/dist/esm/query/evaluators.d.ts +9 -0
  88. package/dist/esm/query/evaluators.js +146 -0
  89. package/dist/esm/query/evaluators.js.map +1 -0
  90. package/dist/esm/query/extractors.d.ts +22 -0
  91. package/dist/esm/query/extractors.js +122 -0
  92. package/dist/esm/query/extractors.js.map +1 -0
  93. package/dist/esm/query/functions.d.ts +21 -0
  94. package/dist/esm/query/functions.js +152 -0
  95. package/dist/esm/query/functions.js.map +1 -0
  96. package/dist/esm/query/group-by.d.ts +40 -0
  97. package/dist/esm/query/group-by.js +91 -0
  98. package/dist/esm/query/group-by.js.map +1 -0
  99. package/dist/esm/query/index.d.ts +5 -0
  100. package/dist/esm/query/joins.d.ts +14 -0
  101. package/dist/esm/query/joins.js +155 -0
  102. package/dist/esm/query/joins.js.map +1 -0
  103. package/dist/esm/query/key-by.d.ts +3 -0
  104. package/dist/esm/query/key-by.js +43 -0
  105. package/dist/esm/query/key-by.js.map +1 -0
  106. package/dist/esm/query/order-by.d.ts +3 -0
  107. package/dist/esm/query/order-by.js +229 -0
  108. package/dist/esm/query/order-by.js.map +1 -0
  109. package/dist/esm/query/pipeline-compiler.d.ts +9 -0
  110. package/dist/esm/query/pipeline-compiler.js +94 -0
  111. package/dist/esm/query/pipeline-compiler.js.map +1 -0
  112. package/dist/esm/query/query-builder.d.ts +219 -0
  113. package/dist/esm/query/query-builder.js +314 -0
  114. package/dist/esm/query/query-builder.js.map +1 -0
  115. package/dist/esm/query/schema.d.ts +98 -0
  116. package/dist/esm/query/select.d.ts +3 -0
  117. package/dist/esm/query/select.js +107 -0
  118. package/dist/esm/query/select.js.map +1 -0
  119. package/dist/esm/query/types.d.ts +188 -0
  120. package/dist/esm/query/utils.d.ts +37 -0
  121. package/dist/esm/query/utils.js +154 -0
  122. package/dist/esm/query/utils.js.map +1 -0
  123. package/dist/esm/transactions.d.ts +27 -0
  124. package/dist/esm/transactions.js +137 -0
  125. package/dist/esm/transactions.js.map +1 -0
  126. package/dist/esm/types.d.ts +94 -0
  127. package/dist/esm/utils.d.ts +3 -0
  128. package/dist/esm/utils.js +17 -0
  129. package/dist/esm/utils.js.map +1 -0
  130. package/package.json +57 -0
  131. package/src/SortedMap.ts +163 -0
  132. package/src/collection.ts +919 -0
  133. package/src/deferred.ts +47 -0
  134. package/src/errors.ts +6 -0
  135. package/src/index.ts +12 -0
  136. package/src/proxy.ts +1104 -0
  137. package/src/query/compiled-query.ts +193 -0
  138. package/src/query/evaluators.ts +222 -0
  139. package/src/query/extractors.ts +211 -0
  140. package/src/query/functions.ts +297 -0
  141. package/src/query/group-by.ts +137 -0
  142. package/src/query/index.ts +5 -0
  143. package/src/query/joins.ts +247 -0
  144. package/src/query/key-by.ts +61 -0
  145. package/src/query/order-by.ts +312 -0
  146. package/src/query/pipeline-compiler.ts +152 -0
  147. package/src/query/query-builder.ts +898 -0
  148. package/src/query/schema.ts +255 -0
  149. package/src/query/select.ts +173 -0
  150. package/src/query/types.ts +417 -0
  151. package/src/query/utils.ts +245 -0
  152. package/src/transactions.ts +198 -0
  153. package/src/types.ts +125 -0
  154. package/src/utils.ts +15 -0
@@ -0,0 +1,654 @@
1
+ function debugLog(...args) {
2
+ const isBrowser = typeof window !== `undefined` && typeof localStorage !== `undefined`;
3
+ if (isBrowser && localStorage.getItem(`DEBUG`) === `true`) {
4
+ console.log(`[proxy]`, ...args);
5
+ } else if (!isBrowser && typeof process !== `undefined` && process.env.DEBUG === `true`) {
6
+ console.log(`[proxy]`, ...args);
7
+ }
8
+ }
9
+ function deepClone(obj, visited = /* @__PURE__ */ new WeakMap()) {
10
+ if (obj === null || obj === void 0) {
11
+ return obj;
12
+ }
13
+ if (typeof obj !== `object`) {
14
+ return obj;
15
+ }
16
+ if (visited.has(obj)) {
17
+ return visited.get(obj);
18
+ }
19
+ if (obj instanceof Date) {
20
+ return new Date(obj.getTime());
21
+ }
22
+ if (obj instanceof RegExp) {
23
+ return new RegExp(obj.source, obj.flags);
24
+ }
25
+ if (Array.isArray(obj)) {
26
+ const arrayClone = [];
27
+ visited.set(obj, arrayClone);
28
+ obj.forEach((item, index) => {
29
+ arrayClone[index] = deepClone(item, visited);
30
+ });
31
+ return arrayClone;
32
+ }
33
+ if (ArrayBuffer.isView(obj) && !(obj instanceof DataView)) {
34
+ const TypedArrayConstructor = Object.getPrototypeOf(obj).constructor;
35
+ const clone2 = new TypedArrayConstructor(
36
+ obj.length
37
+ );
38
+ visited.set(obj, clone2);
39
+ for (let i = 0; i < obj.length; i++) {
40
+ clone2[i] = obj[i];
41
+ }
42
+ return clone2;
43
+ }
44
+ if (obj instanceof Map) {
45
+ const clone2 = /* @__PURE__ */ new Map();
46
+ visited.set(obj, clone2);
47
+ obj.forEach((value, key) => {
48
+ clone2.set(key, deepClone(value, visited));
49
+ });
50
+ return clone2;
51
+ }
52
+ if (obj instanceof Set) {
53
+ const clone2 = /* @__PURE__ */ new Set();
54
+ visited.set(obj, clone2);
55
+ obj.forEach((value) => {
56
+ clone2.add(deepClone(value, visited));
57
+ });
58
+ return clone2;
59
+ }
60
+ const clone = {};
61
+ visited.set(obj, clone);
62
+ for (const key in obj) {
63
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
64
+ clone[key] = deepClone(
65
+ obj[key],
66
+ visited
67
+ );
68
+ }
69
+ }
70
+ const symbolProps = Object.getOwnPropertySymbols(obj);
71
+ for (const sym of symbolProps) {
72
+ clone[sym] = deepClone(
73
+ obj[sym],
74
+ visited
75
+ );
76
+ }
77
+ return clone;
78
+ }
79
+ function deepEqual(a, b) {
80
+ if (a === b) return true;
81
+ if (a === null || b === null || typeof a !== `object` || typeof b !== `object`) {
82
+ return false;
83
+ }
84
+ if (a instanceof Date && b instanceof Date) {
85
+ return a.getTime() === b.getTime();
86
+ }
87
+ if (a instanceof RegExp && b instanceof RegExp) {
88
+ return a.source === b.source && a.flags === b.flags;
89
+ }
90
+ if (a instanceof Map && b instanceof Map) {
91
+ if (a.size !== b.size) return false;
92
+ const entries = Array.from(a.entries());
93
+ for (const [key, val] of entries) {
94
+ if (!b.has(key) || !deepEqual(val, b.get(key))) {
95
+ return false;
96
+ }
97
+ }
98
+ return true;
99
+ }
100
+ if (a instanceof Set && b instanceof Set) {
101
+ if (a.size !== b.size) return false;
102
+ const aValues = Array.from(a);
103
+ const bValues = Array.from(b);
104
+ if (aValues.every((val) => typeof val !== `object`)) {
105
+ return aValues.every((val) => b.has(val));
106
+ }
107
+ return aValues.length === bValues.length;
108
+ }
109
+ if (Array.isArray(a) && Array.isArray(b)) {
110
+ if (a.length !== b.length) return false;
111
+ for (let i = 0; i < a.length; i++) {
112
+ if (!deepEqual(a[i], b[i])) return false;
113
+ }
114
+ return true;
115
+ }
116
+ if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b) && !(a instanceof DataView) && !(b instanceof DataView)) {
117
+ const typedA = a;
118
+ const typedB = b;
119
+ if (typedA.length !== typedB.length) return false;
120
+ for (let i = 0; i < typedA.length; i++) {
121
+ if (typedA[i] !== typedB[i]) return false;
122
+ }
123
+ return true;
124
+ }
125
+ const keysA = Object.keys(a);
126
+ const keysB = Object.keys(b);
127
+ if (keysA.length !== keysB.length) return false;
128
+ return keysA.every(
129
+ (key) => Object.prototype.hasOwnProperty.call(b, key) && deepEqual(a[key], b[key])
130
+ );
131
+ }
132
+ function createChangeProxy(target, parent) {
133
+ const proxyCache = /* @__PURE__ */ new WeakMap();
134
+ const changeTracker = {
135
+ changes: {},
136
+ originalObject: deepClone(target),
137
+ // Create a deep clone to preserve the original state
138
+ modified: false,
139
+ assigned_: {},
140
+ parent,
141
+ target
142
+ // Store reference to the target object
143
+ };
144
+ function markChanged(state) {
145
+ if (!state.modified) {
146
+ state.modified = true;
147
+ if (state.parent) {
148
+ markChanged(state.parent.tracker);
149
+ }
150
+ }
151
+ }
152
+ function checkIfReverted(state) {
153
+ debugLog(
154
+ `checkIfReverted called with assigned keys:`,
155
+ Object.keys(state.assigned_)
156
+ );
157
+ if (Object.keys(state.assigned_).length === 0 && Object.getOwnPropertySymbols(state.assigned_).length === 0) {
158
+ debugLog(`No assigned properties, returning true`);
159
+ return true;
160
+ }
161
+ for (const prop in state.assigned_) {
162
+ if (state.assigned_[prop] === true) {
163
+ const currentValue = state.copy_ ? state.copy_[prop] : null;
164
+ const originalValue = state.originalObject[prop];
165
+ debugLog(
166
+ `Checking property ${String(prop)}, current:`,
167
+ currentValue,
168
+ `original:`,
169
+ originalValue
170
+ );
171
+ if (!deepEqual(currentValue, originalValue)) {
172
+ debugLog(`Property ${String(prop)} is different, returning false`);
173
+ return false;
174
+ }
175
+ } else if (state.assigned_[prop] === false) {
176
+ debugLog(`Property ${String(prop)} was deleted, returning false`);
177
+ return false;
178
+ }
179
+ }
180
+ const symbolProps = Object.getOwnPropertySymbols(state.assigned_);
181
+ for (const sym of symbolProps) {
182
+ if (state.assigned_[sym.toString()] === true) {
183
+ const currentValue = state.copy_ ? state.copy_[sym] : null;
184
+ const originalValue = state.originalObject[sym];
185
+ if (!deepEqual(currentValue, originalValue)) {
186
+ debugLog(`Symbol property is different, returning false`);
187
+ return false;
188
+ }
189
+ } else if (state.assigned_[sym.toString()] === false) {
190
+ debugLog(`Symbol property was deleted, returning false`);
191
+ return false;
192
+ }
193
+ }
194
+ debugLog(`All properties match original values, returning true`);
195
+ return true;
196
+ }
197
+ function updateModifiedStatus(state) {
198
+ debugLog(
199
+ `updateModifiedStatus called, assigned keys:`,
200
+ Object.keys(state.assigned_)
201
+ );
202
+ if (Object.keys(state.assigned_).length === 0 && Object.getOwnPropertySymbols(state.assigned_).length === 0) {
203
+ debugLog(`No assigned properties, returning false`);
204
+ return false;
205
+ }
206
+ const isReverted = checkIfReverted(state);
207
+ debugLog(`checkIfReverted returned:`, isReverted);
208
+ if (!isReverted) {
209
+ debugLog(`Object has changes that aren't reverted, returning true`);
210
+ return true;
211
+ }
212
+ debugLog(`All changes reverted, clearing tracking`);
213
+ state.modified = false;
214
+ state.changes = {};
215
+ state.assigned_ = {};
216
+ if (state.parent) {
217
+ debugLog(`Checking parent status for prop:`, state.parent.prop);
218
+ checkParentStatus(state.parent.tracker, state.parent.prop);
219
+ }
220
+ return false;
221
+ }
222
+ function checkParentStatus(parentState, childProp) {
223
+ debugLog(`checkParentStatus called for child prop:`, childProp);
224
+ const isReverted = checkIfReverted(parentState);
225
+ debugLog(`Parent checkIfReverted returned:`, isReverted);
226
+ if (isReverted) {
227
+ debugLog(`Parent is fully reverted, clearing tracking`);
228
+ parentState.modified = false;
229
+ parentState.changes = {};
230
+ parentState.assigned_ = {};
231
+ if (parentState.parent) {
232
+ debugLog(`Continuing up the parent chain`);
233
+ checkParentStatus(parentState.parent.tracker, parentState.parent.prop);
234
+ }
235
+ }
236
+ }
237
+ function createObjectProxy(obj) {
238
+ if (proxyCache.has(obj)) {
239
+ return proxyCache.get(obj);
240
+ }
241
+ const proxy2 = new Proxy(obj, {
242
+ get(ptarget, prop) {
243
+ const value = ptarget[prop];
244
+ const desc = Object.getOwnPropertyDescriptor(ptarget, prop);
245
+ if (desc == null ? void 0 : desc.get) {
246
+ return value;
247
+ }
248
+ if (typeof value === `function`) {
249
+ if (ptarget instanceof Map || ptarget instanceof Set) {
250
+ const methodName = prop.toString();
251
+ const modifyingMethods = /* @__PURE__ */ new Set([
252
+ `set`,
253
+ `delete`,
254
+ `clear`,
255
+ `add`,
256
+ `pop`,
257
+ `push`,
258
+ `shift`,
259
+ `unshift`,
260
+ `splice`,
261
+ `sort`,
262
+ `reverse`
263
+ ]);
264
+ if (modifyingMethods.has(methodName)) {
265
+ return function(...args) {
266
+ const result = value.apply(ptarget, args);
267
+ markChanged(changeTracker);
268
+ return result;
269
+ };
270
+ }
271
+ const iteratorMethods = /* @__PURE__ */ new Set([
272
+ `entries`,
273
+ `keys`,
274
+ `values`,
275
+ `forEach`,
276
+ Symbol.iterator
277
+ ]);
278
+ if (iteratorMethods.has(methodName) || prop === Symbol.iterator) {
279
+ return function(...args) {
280
+ const result = value.apply(ptarget, args);
281
+ if (methodName === `forEach`) {
282
+ const callback = args[0];
283
+ if (typeof callback === `function`) {
284
+ const wrappedCallback = function(value2, key, collection) {
285
+ const cbresult = callback.call(
286
+ this,
287
+ value2,
288
+ key,
289
+ collection
290
+ );
291
+ markChanged(changeTracker);
292
+ return cbresult;
293
+ };
294
+ return value.apply(ptarget, [
295
+ wrappedCallback,
296
+ ...args.slice(1)
297
+ ]);
298
+ }
299
+ }
300
+ if (methodName === `entries` || methodName === `values` || methodName === Symbol.iterator.toString() || prop === Symbol.iterator) {
301
+ const originalIterator = result;
302
+ return {
303
+ next() {
304
+ const nextResult = originalIterator.next();
305
+ if (!nextResult.done && nextResult.value && typeof nextResult.value === `object`) {
306
+ if (methodName === `entries` && Array.isArray(nextResult.value) && nextResult.value.length === 2) {
307
+ if (nextResult.value[1] && typeof nextResult.value[1] === `object`) {
308
+ const { proxy: valueProxy } = createChangeProxy(
309
+ nextResult.value[1],
310
+ {
311
+ tracker: changeTracker,
312
+ prop: typeof nextResult.value[0] === `symbol` ? nextResult.value[0] : String(nextResult.value[0])
313
+ }
314
+ );
315
+ nextResult.value[1] = valueProxy;
316
+ }
317
+ } else if (methodName === `values` || methodName === Symbol.iterator.toString() || prop === Symbol.iterator) {
318
+ if (typeof nextResult.value === `object` && nextResult.value !== null) {
319
+ const tempKey = Symbol(`iterator-value`);
320
+ const { proxy: valueProxy } = createChangeProxy(
321
+ nextResult.value,
322
+ {
323
+ tracker: changeTracker,
324
+ prop: tempKey
325
+ }
326
+ );
327
+ nextResult.value = valueProxy;
328
+ }
329
+ }
330
+ }
331
+ return nextResult;
332
+ },
333
+ [Symbol.iterator]() {
334
+ return this;
335
+ }
336
+ };
337
+ }
338
+ return result;
339
+ };
340
+ }
341
+ }
342
+ return value.bind(ptarget);
343
+ }
344
+ if (value && typeof value === `object` && !(value instanceof Date) && !(value instanceof RegExp)) {
345
+ const nestedParent = {
346
+ tracker: changeTracker,
347
+ prop: String(prop)
348
+ };
349
+ const { proxy: nestedProxy } = createChangeProxy(value, nestedParent);
350
+ proxyCache.set(value, nestedProxy);
351
+ return nestedProxy;
352
+ }
353
+ return value;
354
+ },
355
+ set(sobj, prop, value) {
356
+ const currentValue = sobj[prop];
357
+ debugLog(
358
+ `set called for property ${String(prop)}, current:`,
359
+ currentValue,
360
+ `new:`,
361
+ value
362
+ );
363
+ if (Array.isArray(sobj) && prop === `length`) {
364
+ const newLength = Number(value);
365
+ const oldLength = sobj.length;
366
+ const newArray = Array.from(
367
+ { length: newLength },
368
+ (_, i) => i < oldLength ? sobj[i] : void 0
369
+ );
370
+ if (parent) {
371
+ parent.tracker.changes[parent.prop] = newArray;
372
+ parent.tracker.assigned_[parent.prop] = true;
373
+ markChanged(parent.tracker);
374
+ }
375
+ sobj.length = newLength;
376
+ return true;
377
+ }
378
+ if (!deepEqual(currentValue, value)) {
379
+ const originalValue = changeTracker.originalObject[prop];
380
+ const isRevertToOriginal = deepEqual(value, originalValue);
381
+ debugLog(
382
+ `Value different, original:`,
383
+ originalValue,
384
+ `isRevertToOriginal:`,
385
+ isRevertToOriginal
386
+ );
387
+ if (isRevertToOriginal) {
388
+ debugLog(`Reverting property ${String(prop)} to original value`);
389
+ delete changeTracker.changes[prop.toString()];
390
+ delete changeTracker.assigned_[prop.toString()];
391
+ if (changeTracker.copy_) {
392
+ debugLog(`Updating copy with original value for ${String(prop)}`);
393
+ changeTracker.copy_[prop] = deepClone(originalValue);
394
+ }
395
+ debugLog(`Checking if all properties reverted`);
396
+ const allReverted = checkIfReverted(changeTracker);
397
+ debugLog(`All reverted:`, allReverted);
398
+ if (allReverted) {
399
+ debugLog(`All properties reverted, clearing tracking`);
400
+ changeTracker.modified = false;
401
+ changeTracker.changes = {};
402
+ changeTracker.assigned_ = {};
403
+ if (parent) {
404
+ debugLog(`Updating parent for property:`, parent.prop);
405
+ checkParentStatus(parent.tracker, parent.prop);
406
+ }
407
+ } else {
408
+ debugLog(`Some properties still changed, keeping modified flag`);
409
+ changeTracker.modified = true;
410
+ }
411
+ } else {
412
+ debugLog(`Setting new value for property ${String(prop)}`);
413
+ prepareCopy(changeTracker);
414
+ if (changeTracker.copy_) {
415
+ changeTracker.copy_[prop] = value;
416
+ }
417
+ obj[prop] = value;
418
+ changeTracker.assigned_[prop.toString()] = true;
419
+ changeTracker.changes[prop.toString()] = deepClone(value);
420
+ debugLog(`Marking object and ancestors as modified`);
421
+ markChanged(changeTracker);
422
+ }
423
+ } else {
424
+ debugLog(`Value unchanged, not tracking`);
425
+ }
426
+ return true;
427
+ },
428
+ defineProperty(ptarget, prop, descriptor) {
429
+ const result = Reflect.defineProperty(ptarget, prop, descriptor);
430
+ if (result) {
431
+ if (`value` in descriptor) {
432
+ changeTracker.changes[prop.toString()] = deepClone(descriptor.value);
433
+ changeTracker.assigned_[prop.toString()] = true;
434
+ markChanged(changeTracker);
435
+ }
436
+ }
437
+ return result;
438
+ },
439
+ setPrototypeOf(ptarget, proto) {
440
+ return Object.setPrototypeOf(ptarget, proto);
441
+ },
442
+ deleteProperty(dobj, prop) {
443
+ const stringProp = typeof prop === `symbol` ? prop.toString() : prop;
444
+ if (stringProp in dobj) {
445
+ const hadPropertyInOriginal = stringProp in changeTracker.originalObject;
446
+ prepareCopy(changeTracker);
447
+ if (changeTracker.copy_) {
448
+ delete changeTracker.copy_[prop];
449
+ }
450
+ delete dobj[prop];
451
+ if (!hadPropertyInOriginal) {
452
+ delete changeTracker.changes[stringProp];
453
+ delete changeTracker.assigned_[stringProp];
454
+ if (Object.keys(changeTracker.assigned_).length === 0 && Object.getOwnPropertySymbols(changeTracker.assigned_).length === 0) {
455
+ changeTracker.modified = false;
456
+ } else {
457
+ changeTracker.modified = true;
458
+ }
459
+ } else {
460
+ changeTracker.assigned_[stringProp] = false;
461
+ changeTracker.changes[stringProp] = void 0;
462
+ markChanged(changeTracker);
463
+ }
464
+ }
465
+ return true;
466
+ }
467
+ });
468
+ proxyCache.set(obj, proxy2);
469
+ return proxy2;
470
+ }
471
+ const proxy = createObjectProxy(target);
472
+ return {
473
+ proxy,
474
+ getChanges: () => {
475
+ debugLog(
476
+ `getChanges called, modified:`,
477
+ changeTracker.modified,
478
+ `assigned keys:`,
479
+ Object.keys(changeTracker.assigned_)
480
+ );
481
+ if (!changeTracker.modified) {
482
+ debugLog(`Object not modified, returning empty object`);
483
+ return {};
484
+ }
485
+ if (Object.keys(changeTracker.assigned_).length === 0 && Object.getOwnPropertySymbols(changeTracker.assigned_).length === 0) {
486
+ debugLog(`No assigned properties, checking deep equality`);
487
+ if (changeTracker.copy_) {
488
+ debugLog(`Comparing copy with original`);
489
+ if (deepEqual(changeTracker.copy_, changeTracker.originalObject)) {
490
+ debugLog(`Copy equals original, returning empty object`);
491
+ changeTracker.modified = false;
492
+ return {};
493
+ }
494
+ } else if (deepEqual(target, changeTracker.originalObject)) {
495
+ debugLog(`Target equals original, returning empty object`);
496
+ changeTracker.modified = false;
497
+ changeTracker.changes = {};
498
+ changeTracker.assigned_ = {};
499
+ return {};
500
+ }
501
+ }
502
+ debugLog(`Forcing full check for reverted state`);
503
+ updateModifiedStatus(changeTracker);
504
+ if (!changeTracker.modified) {
505
+ debugLog(`No longer modified after check, returning empty object`);
506
+ return {};
507
+ }
508
+ if (changeTracker.modified) {
509
+ const objToCheck = changeTracker.copy_ || target;
510
+ debugLog(
511
+ `Checking if object is equal to original:`,
512
+ objToCheck,
513
+ changeTracker.originalObject
514
+ );
515
+ if (deepEqual(objToCheck, changeTracker.originalObject)) {
516
+ debugLog(`Object equals original, returning empty object`);
517
+ changeTracker.modified = false;
518
+ changeTracker.changes = {};
519
+ changeTracker.assigned_ = {};
520
+ return {};
521
+ }
522
+ }
523
+ if (Object.keys(changeTracker.assigned_).length > 0 || Object.getOwnPropertySymbols(changeTracker.assigned_).length > 0) {
524
+ if (changeTracker.copy_) {
525
+ const changes = {};
526
+ for (const key in changeTracker.assigned_) {
527
+ if (changeTracker.assigned_[key] === true) {
528
+ changes[key] = deepClone(changeTracker.copy_[key]);
529
+ } else if (changeTracker.assigned_[key] === false) {
530
+ changes[key] = void 0;
531
+ }
532
+ }
533
+ const symbolProps = Object.getOwnPropertySymbols(
534
+ changeTracker.assigned_
535
+ );
536
+ for (const sym of symbolProps) {
537
+ if (changeTracker.assigned_[sym.toString()] === true) {
538
+ const value = changeTracker.copy_[sym];
539
+ changes[sym.toString()] = deepClone(value);
540
+ }
541
+ }
542
+ return changes;
543
+ }
544
+ return changeTracker.changes;
545
+ }
546
+ if (changeTracker.modified && !parent) {
547
+ debugLog(`Root object with nested changes, checking deep equality`);
548
+ const currentState = changeTracker.copy_ || target;
549
+ debugLog(
550
+ `Comparing current state with original:`,
551
+ currentState,
552
+ changeTracker.originalObject
553
+ );
554
+ if (deepEqual(currentState, changeTracker.originalObject)) {
555
+ debugLog(`Current state equals original, returning empty object`);
556
+ changeTracker.modified = false;
557
+ return {};
558
+ }
559
+ debugLog(
560
+ `Comparing target with original:`,
561
+ target,
562
+ changeTracker.originalObject
563
+ );
564
+ if (deepEqual(target, changeTracker.originalObject)) {
565
+ debugLog(`Target equals original, returning empty object`);
566
+ changeTracker.modified = false;
567
+ changeTracker.changes = {};
568
+ changeTracker.assigned_ = {};
569
+ return {};
570
+ }
571
+ if (typeof target === `object` && target !== null) {
572
+ let allNestedReverted = true;
573
+ for (const key in target) {
574
+ if (Object.prototype.hasOwnProperty.call(target, key)) {
575
+ const currentValue = target[key];
576
+ const originalValue = changeTracker.originalObject[key];
577
+ if (!deepEqual(currentValue, originalValue)) {
578
+ allNestedReverted = false;
579
+ break;
580
+ }
581
+ }
582
+ }
583
+ if (allNestedReverted) {
584
+ debugLog(
585
+ `All nested properties match original values, returning empty object`
586
+ );
587
+ changeTracker.modified = false;
588
+ changeTracker.changes = {};
589
+ changeTracker.assigned_ = {};
590
+ return {};
591
+ }
592
+ }
593
+ debugLog(
594
+ `Changes detected, returning full object:`,
595
+ changeTracker.copy_ || target
596
+ );
597
+ const result = changeTracker.copy_ || target;
598
+ return result;
599
+ }
600
+ debugLog(`No changes detected, returning empty object`);
601
+ return {};
602
+ }
603
+ };
604
+ }
605
+ function createArrayChangeProxy(targets) {
606
+ const proxiesWithChanges = targets.map((target) => createChangeProxy(target));
607
+ return {
608
+ proxies: proxiesWithChanges.map((p) => p.proxy),
609
+ getChanges: () => proxiesWithChanges.map((p) => p.getChanges())
610
+ };
611
+ }
612
+ function withChangeTracking(target, callback) {
613
+ const { proxy, getChanges } = createChangeProxy(target);
614
+ callback(proxy);
615
+ return getChanges();
616
+ }
617
+ function withArrayChangeTracking(targets, callback) {
618
+ const { proxies, getChanges } = createArrayChangeProxy(targets);
619
+ callback(proxies);
620
+ return getChanges();
621
+ }
622
+ function prepareCopy(state) {
623
+ if (!state.copy_) {
624
+ state.copy_ = shallowCopy(state.originalObject);
625
+ }
626
+ }
627
+ function shallowCopy(obj) {
628
+ if (Array.isArray(obj)) {
629
+ return [...obj];
630
+ }
631
+ if (obj instanceof Map) {
632
+ return new Map(obj);
633
+ }
634
+ if (obj instanceof Set) {
635
+ return new Set(obj);
636
+ }
637
+ if (obj instanceof Date) {
638
+ return new Date(obj.getTime());
639
+ }
640
+ if (obj instanceof RegExp) {
641
+ return new RegExp(obj.source, obj.flags);
642
+ }
643
+ if (obj !== null && typeof obj === `object`) {
644
+ return { ...obj };
645
+ }
646
+ return obj;
647
+ }
648
+ export {
649
+ createArrayChangeProxy,
650
+ createChangeProxy,
651
+ withArrayChangeTracking,
652
+ withChangeTracking
653
+ };
654
+ //# sourceMappingURL=proxy.js.map