j-templates 8.1.0 → 8.1.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.
@@ -35,7 +35,9 @@ export class DiffSync {
35
35
  }
36
36
  SplicePath(path, start, deleteCount, items) {
37
37
  const spliceResult = this.diffTree.SplicePath(path, start, deleteCount, items);
38
- spliceResult.diffResult.push(...this.diffTree.RunProjections());
38
+ const projectionDiff = this.diffTree.RunProjections();
39
+ spliceResult.diffResult = spliceResult.diffResult.concat(projectionDiff);
40
+ // spliceResult.diffResult.push(...this.diffTree.RunProjections());
39
41
  return spliceResult;
40
42
  }
41
43
  }
@@ -214,7 +214,7 @@ function BuildProjectionOrder(projections) {
214
214
  * @returns Diff entries for every projection whose result changed
215
215
  */
216
216
  function RunProjections(source, keyFunc, projections, memo) {
217
- const diffResult = [];
217
+ let diffResult = [];
218
218
  for (let x = 0; x < projections.length; x++) {
219
219
  const { id, reads, projection } = projections[x];
220
220
  const values = [];
@@ -244,10 +244,19 @@ function RunProjections(source, keyFunc, projections, memo) {
244
244
  if (!ArraysEqual(priorValues, values)) {
245
245
  const result = projection(keys, ...values);
246
246
  memo.set(id, values);
247
+ const diff = UpdateSource(source, PROJECTION_PREFIX + id, result, keyFunc);
248
+ diffResult = diffResult.concat(diff);
247
249
  // The same diff-and-apply UpdateSource uses for any other write, so a keyed entity
248
250
  // embedded in a projection's result is flattened to its own root like any other write,
249
251
  // and the diff reported here is unfiltered, the same as DiffPath returns.
250
- diffResult.push(...UpdateSource(source, PROJECTION_PREFIX + id, result, keyFunc));
252
+ /* diffResult.push(
253
+ ...UpdateSource(
254
+ source,
255
+ PROJECTION_PREFIX + id,
256
+ result,
257
+ keyFunc,
258
+ ),
259
+ ); */
251
260
  }
252
261
  }
253
262
  }
@@ -294,12 +303,13 @@ function ResolveKeyPath(source, path, keyFunc) {
294
303
  * @returns Diff results showing all changes made
295
304
  */
296
305
  function UpdateSource(source, path, value, keyFunc) {
297
- const diffResult = [];
306
+ let diffResult = [];
298
307
  if (keyFunc) {
299
308
  const keyPath = ResolveKeyPath(source, path, keyFunc);
300
309
  if (keyPath !== path) {
301
310
  const keyDiffResult = UpdateSource(source, keyPath, value, keyFunc);
302
- diffResult.push(...keyDiffResult);
311
+ diffResult = diffResult.concat(keyDiffResult);
312
+ // diffResult.push(...keyDiffResult);
303
313
  }
304
314
  }
305
315
  const [sourceValue] = GetPathValue(source, path);
@@ -83,7 +83,7 @@ export class ReadStore {
83
83
  this.rootMap.set(rootPath, newRootObject);
84
84
  return;
85
85
  }
86
- ObservableNode.ApplyDiff(rootObject, results);
86
+ ObservableNode.ApplyDiff(rootObject, results, this.cloneData);
87
87
  }
88
88
  }
89
89
  /**
@@ -6,8 +6,8 @@ const NODE_PROXY = Symbol("NODE_PROXY");
6
6
  const NODE_SNAPSHOT = Symbol("NODE_SNAPSHOT");
7
7
  const toJSON = "toJSON";
8
8
  const IS_NODE = Symbol("IS_NODE");
9
+ const ARRAY_SCOPE = Symbol("ARRAY_SCOPE");
9
10
  const OBJECT_SCOPE = Symbol("OBJECT_SCOPE");
10
- const ITERATOR_SCOPE = Symbol("ITERATOR_SCOPE");
11
11
  function Identity(value) {
12
12
  return value;
13
13
  }
@@ -34,34 +34,37 @@ function InvalidateSnapshotForValue(value) {
34
34
  InvalidateSnapshotForValue(parent);
35
35
  }
36
36
  function getOwnPropertyDescriptor(target, prop) {
37
+ ObservableScope.Touch(target[OBJECT_SCOPE]);
37
38
  const descriptor = Object.getOwnPropertyDescriptor(target[NODE_VALUE], prop);
38
- return {
39
+ return descriptor && {
39
40
  ...descriptor,
40
41
  configurable: true,
41
42
  };
42
43
  }
43
44
  function getOwnPropertyDescriptorArray(target, prop) {
44
- const descriptor = Object.getOwnPropertyDescriptor(target[NODE_VALUE], prop);
45
- return {
46
- ...descriptor,
47
- configurable: true,
45
+ ObservableScope.Touch(target[ARRAY_SCOPE]);
46
+ const descriptor = Object.getOwnPropertyDescriptor(target, prop);
47
+ const nodeDescriptor = Object.getOwnPropertyDescriptor(target[NODE_VALUE], prop);
48
+ return nodeDescriptor && {
49
+ ...nodeDescriptor,
50
+ configurable: descriptor?.configurable ?? true,
48
51
  };
49
52
  }
50
53
  function has(value, prop) {
51
- ObservableScope.Touch(value[ITERATOR_SCOPE]);
54
+ ObservableScope.Touch(value[OBJECT_SCOPE]);
52
55
  return Object.hasOwn(value[NODE_VALUE], prop);
53
56
  }
54
57
  function hasArray(value, prop) {
55
- ObservableScope.Touch(value[ITERATOR_SCOPE]);
58
+ ObservableScope.Touch(value[ARRAY_SCOPE]);
56
59
  return Object.hasOwn(value[NODE_VALUE], prop);
57
60
  }
58
61
  function ownKeys(value) {
59
- ObservableScope.Touch(value[ITERATOR_SCOPE]);
62
+ ObservableScope.Touch(value[OBJECT_SCOPE]);
60
63
  return Object.keys(value[NODE_VALUE]);
61
64
  }
62
65
  function ownKeysArray(value) {
63
- ObservableScope.Touch(value[ITERATOR_SCOPE]);
64
- return Object.keys(value[NODE_VALUE]);
66
+ ObservableScope.Touch(value[ARRAY_SCOPE]);
67
+ return Reflect.ownKeys(value[NODE_VALUE]);
65
68
  }
66
69
  function UnwrapProxy(value, type = JsonType(value)) {
67
70
  if (type === "value")
@@ -106,20 +109,30 @@ function CloneProxy(value, type = JsonType(value)) {
106
109
  }
107
110
  return value;
108
111
  }
109
- function GetPropertyScope(object, prop) {
110
- return object[prop] ??= ObservableScope.Basic(Property.bind(null, object[NODE_VALUE], prop));
112
+ function GetPropertyScope(object, prop, create = true) {
113
+ if (!Object.hasOwn(object, prop)) {
114
+ if (!create)
115
+ return undefined;
116
+ Object.defineProperty(object, prop, {
117
+ value: ObservableScope.Basic(Property.bind(null, object[NODE_VALUE], prop)),
118
+ writable: true,
119
+ enumerable: true,
120
+ configurable: true,
121
+ });
122
+ }
123
+ return object[prop];
111
124
  }
112
125
  function SetObjectValue(object, prop, value) {
113
126
  const propExists = Object.hasOwn(object[NODE_VALUE], prop);
114
127
  object[NODE_VALUE][prop] = value;
115
128
  InvalidateSnapshotForValue(object[NODE_VALUE]);
116
- ObservableScope.Update(object[prop]);
117
- !propExists && ObservableScope.Update(object[ITERATOR_SCOPE]);
129
+ Object.hasOwn(object, prop) && ObservableScope.Update(object[prop]);
130
+ !propExists && ObservableScope.Update(object[OBJECT_SCOPE]);
118
131
  }
119
132
  function SetArrayValue(object, prop, value) {
120
133
  object[NODE_VALUE][prop] = value;
121
134
  InvalidateSnapshotForValue(object[NODE_VALUE]);
122
- ObservableScope.Update(object[OBJECT_SCOPE]);
135
+ ObservableScope.Update(object[ARRAY_SCOPE]);
123
136
  }
124
137
  function CreateProxyFactory(alias) {
125
138
  /**
@@ -174,7 +187,7 @@ function CreateProxyFactory(alias) {
174
187
  const wrapper = Object.assign([], {
175
188
  [NODE_VALUE]: value,
176
189
  [NODE_PROXY]: null,
177
- [OBJECT_SCOPE]: ObservableScope.Basic(Identity.bind(null, value))
190
+ [ARRAY_SCOPE]: ObservableScope.Basic(Identity.bind(null, value))
178
191
  });
179
192
  const proxy = wrapper[NODE_PROXY] = new Proxy(wrapper, {
180
193
  get: ArrayProxyGetter,
@@ -217,7 +230,7 @@ function CreateProxyFactory(alias) {
217
230
  case NODE_SNAPSHOT:
218
231
  return CreateSnapshot(object[NODE_VALUE]);
219
232
  default: {
220
- const scope = object[OBJECT_SCOPE];
233
+ const scope = object[ARRAY_SCOPE];
221
234
  const array = ObservableScope.Value(scope);
222
235
  const arrayValue = array[prop];
223
236
  if (typeof prop === "symbol")
@@ -254,7 +267,7 @@ function CreateProxyFactory(alias) {
254
267
  const wrapper = {
255
268
  [NODE_VALUE]: value,
256
269
  [NODE_PROXY]: null,
257
- [ITERATOR_SCOPE]: ObservableScope.Basic(Identity.bind(null, value))
270
+ [OBJECT_SCOPE]: ObservableScope.Basic(Identity.bind(null, value))
258
271
  };
259
272
  const proxy = wrapper[NODE_PROXY] = new Proxy(wrapper, {
260
273
  get: ObjectProxyGetter,
@@ -274,7 +287,6 @@ function CreateProxyFactory(alias) {
274
287
  return true;
275
288
  }
276
289
  function ObjectProxyGetter(object, prop) {
277
- ObservableScope.Touch(object[OBJECT_SCOPE]);
278
290
  switch (prop) {
279
291
  case IS_NODE:
280
292
  return true;
@@ -314,7 +326,7 @@ function CreateProxyFactory(alias) {
314
326
  case "array": {
315
327
  const wrapper = wrapperCache.get(value);
316
328
  const proxy = wrapper?.[NODE_PROXY] ?? CreateArrayProxy(value);
317
- ObservableScope.Touch(wrapper?.[OBJECT_SCOPE]);
329
+ ObservableScope.Touch(wrapper?.[ARRAY_SCOPE]);
318
330
  return proxy;
319
331
  }
320
332
  default:
@@ -401,7 +413,7 @@ export var ObservableNode;
401
413
  function Update(value, prop) {
402
414
  const wrapper = wrapperCache.get(value);
403
415
  if (wrapper) {
404
- const scope = Array.isArray(wrapper) ? wrapper[OBJECT_SCOPE] : (prop && wrapper[prop]) ?? wrapper[ITERATOR_SCOPE];
416
+ const scope = Array.isArray(wrapper) ? wrapper[ARRAY_SCOPE] : (prop && GetPropertyScope(wrapper, prop)) ?? wrapper[OBJECT_SCOPE];
405
417
  ObservableScope.Update(scope);
406
418
  }
407
419
  }
@@ -425,7 +437,7 @@ export var ObservableNode;
425
437
  function Touch(value, prop) {
426
438
  const wrapper = wrapperCache.get(value);
427
439
  if (wrapper) {
428
- const scope = prop && GetPropertyScope(wrapper, prop) || wrapper[OBJECT_SCOPE];
440
+ const scope = prop && GetPropertyScope(wrapper, prop) || wrapper[ARRAY_SCOPE] || wrapper[OBJECT_SCOPE];
429
441
  ObservableScope.Touch(scope);
430
442
  }
431
443
  }
@@ -433,7 +445,7 @@ export var ObservableNode;
433
445
  function Read(value, prop) {
434
446
  const wrapper = wrapperCache.get(value);
435
447
  if (wrapper) {
436
- const scope = Array.isArray(wrapper) ? wrapper[OBJECT_SCOPE] : (prop && wrapper[prop]) ?? wrapper[ITERATOR_SCOPE];
448
+ const scope = Array.isArray(wrapper) ? wrapper[ARRAY_SCOPE] : (prop && wrapper[prop]) ?? wrapper[OBJECT_SCOPE];
437
449
  ObservableScope.Update(scope);
438
450
  }
439
451
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "j-templates",
3
- "version": "8.1.0",
3
+ "version": "8.1.2",
4
4
  "description": "j-templates",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/TypesInCode/jTemplates",