j-templates 6.0.26 → 6.0.28

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.
@@ -1,2 +1,4 @@
1
1
  export declare function CreateNodeValueAssignment(target: HTMLElement): (value: string) => void;
2
- export declare function CreatePropertyAssignment(target: any, prop: string): (next: any) => void;
2
+ export declare function CreatePropertyAssignment(target: any): (next: {
3
+ [prop: string]: any;
4
+ }) => void;
@@ -2,8 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CreateNodeValueAssignment = CreateNodeValueAssignment;
4
4
  exports.CreatePropertyAssignment = CreatePropertyAssignment;
5
- const jsonType_1 = require("../Utils/jsonType");
6
- const createAssignment_1 = require("./createAssignment");
5
+ const json_1 = require("../Utils/json");
7
6
  function CreateNodeValueAssignment(target) {
8
7
  let lastValue = target.nodeValue;
9
8
  return function AssignNodeValue(value) {
@@ -13,39 +12,65 @@ function CreateNodeValueAssignment(target) {
13
12
  }
14
13
  };
15
14
  }
15
+ function WalkValue(next, callback, index = 0, parent = "") {
16
+ const keys = Object.keys(next);
17
+ for (let x = 0; x < keys.length; x++) {
18
+ const value = next[keys[x]];
19
+ const type = (0, json_1.JsonType)(value);
20
+ switch (type) {
21
+ case "object":
22
+ index = WalkValue(value, callback, index, `${parent}${keys[x]}.`);
23
+ break;
24
+ default:
25
+ callback(`${parent}${keys[x]}`, value, index);
26
+ index++;
27
+ break;
28
+ }
29
+ }
30
+ return index;
31
+ }
32
+ function AssignNodeValue(target, value) {
33
+ target.nodeValue = value;
34
+ }
16
35
  function AssignValue(target, value) {
17
- const start = target.selectionStart;
18
- const end = target.selectionEnd;
19
36
  target.value = value;
20
- if (target.ownerDocument.activeElement === target)
21
- target.setSelectionRange(start, end);
22
37
  }
23
- function CreatePropertyAssignment(target, prop) {
24
- let lastValue;
25
- let childPropertyAssignment;
26
- return function (next) {
27
- const nextValue = next && next[prop];
28
- if (nextValue === lastValue)
38
+ function AssignClassName(target, value) {
39
+ target.className = value;
40
+ }
41
+ function GetAssignmentFunction(path) {
42
+ switch (path) {
43
+ case "nodeValue":
44
+ return AssignNodeValue;
45
+ case "value":
46
+ return AssignValue;
47
+ case "className":
48
+ return AssignClassName;
49
+ default:
50
+ return new Function("t", "v", `t.${path} = v;`);
51
+ }
52
+ }
53
+ function CreatePropertyAssignment(target) {
54
+ const last = [["", null, null]];
55
+ function WalkCallback(path, value, index) {
56
+ if (index >= last.length || last[index][0] !== path) {
57
+ last[index] = [path, value, GetAssignmentFunction(path)];
58
+ last[index][2](target, value);
59
+ }
60
+ else if (last[index][1] !== value) {
61
+ last[index][2](target, value);
62
+ }
63
+ }
64
+ return function AssignProperty(next) {
65
+ if (next === null) {
66
+ for (let x = 0; x < last.length; x++)
67
+ last[x][2](target, null);
68
+ if (last.length > 0)
69
+ last.splice(0);
29
70
  return;
30
- lastValue = nextValue;
31
- if (childPropertyAssignment !== undefined)
32
- childPropertyAssignment(target[prop], nextValue);
33
- const nextValueType = (0, jsonType_1.JsonType)(nextValue);
34
- switch (nextValueType) {
35
- case "value":
36
- switch (prop) {
37
- case "value":
38
- AssignValue(target, nextValue || "");
39
- break;
40
- default:
41
- target[prop] = nextValue;
42
- break;
43
- }
44
- break;
45
- default:
46
- childPropertyAssignment ??= (0, createAssignment_1.CreateAssignment)(target[prop], CreatePropertyAssignment);
47
- childPropertyAssignment(target[prop], nextValue);
48
- break;
49
71
  }
72
+ const endIndex = WalkValue(next, WalkCallback);
73
+ if (endIndex < last.length)
74
+ last.splice(endIndex);
50
75
  };
51
76
  }
@@ -6,19 +6,17 @@ const list_1 = require("../Utils/list");
6
6
  const createPropertyAssignment_1 = require("./createPropertyAssignment");
7
7
  const createEventAssignment_1 = require("./createEventAssignment");
8
8
  const createAssignment_1 = require("./createAssignment");
9
+ const createPropertyAssignment_2 = require("./createPropertyAssignment");
9
10
  let pendingUpdates = list_1.List.Create();
10
11
  let updateScheduled = false;
11
12
  const updateMs = 16;
12
13
  function processUpdates() {
13
14
  list_1.List.Add(pendingUpdates, null);
14
- const start = Date.now();
15
15
  let callback;
16
16
  while ((callback = list_1.List.Pop(pendingUpdates)))
17
17
  callback();
18
18
  if (pendingUpdates.size === 0)
19
19
  updateScheduled = false;
20
- else if (Date.now() - start < updateMs)
21
- processUpdates();
22
20
  else
23
21
  window_1.wndw.requestAnimationFrame(processUpdates);
24
22
  }
@@ -84,9 +82,7 @@ exports.DOMNodeConfig = {
84
82
  target.setAttribute(attribute, value);
85
83
  },
86
84
  createPropertyAssignment(target) {
87
- if (target.nodeType === Node.TEXT_NODE)
88
- return (0, createPropertyAssignment_1.CreateNodeValueAssignment)(target);
89
- return (0, createAssignment_1.CreateAssignment)(target, createPropertyAssignment_1.CreatePropertyAssignment);
85
+ return (0, createPropertyAssignment_2.CreatePropertyAssignment)(target);
90
86
  },
91
87
  createEventAssignment(target) {
92
88
  return (0, createAssignment_1.CreateAssignment)(target, createEventAssignment_1.CreateEventAssignment);
@@ -102,13 +102,16 @@ function AddTemplate(node, init) {
102
102
  init: true,
103
103
  nodes
104
104
  });
105
- if (init)
105
+ if (init) {
106
106
  nodeRef_1.NodeRef.ReconcileChildren(node, list);
107
+ list_1.List.Clear(list);
108
+ }
107
109
  else
108
110
  nodeConfig_1.NodeConfig.scheduleUpdate(function () {
109
111
  if (node.destroyed)
110
112
  return;
111
113
  nodeRef_1.NodeRef.ReconcileChildren(node, list);
114
+ list_1.List.Clear(list);
112
115
  });
113
116
  });
114
117
  if (node.component.Bound !== component_1.Component.prototype.Bound)
@@ -72,6 +72,7 @@ function SetDefaultData(node) {
72
72
  nodes
73
73
  });
74
74
  nodeRef_1.NodeRef.ReconcileChildren(node, defaultNodeList);
75
+ list_1.List.Clear(defaultNodeList);
75
76
  });
76
77
  }
77
78
  });
package/Node/nodeRef.js CHANGED
@@ -206,6 +206,7 @@ var NodeRef;
206
206
  case NodeRefType.ComponentNode:
207
207
  node.component?.Destroy();
208
208
  case NodeRefType.BoundNode:
209
+ node.assignEvents?.(null);
209
210
  case NodeRefType.ElementNode:
210
211
  for (let x = 0; node.scopes && x < node.scopes.length; x++)
211
212
  Store_1.ObservableScope.Destroy(node.scopes[x]);
@@ -5,7 +5,6 @@ export declare const GET_TO_JSON = "toJSON";
5
5
  export declare namespace ObservableNode {
6
6
  function Create<T>(value: T): T;
7
7
  function Touch(value: unknown): void;
8
- function EnableDiff(value: boolean): void;
9
8
  function ApplyDiff(rootNode: any, diffResult: JsonDiffResult): void;
10
9
  function CreateFactory(alias?: (value: any) => any | undefined): <T>(value: T) => T;
11
10
  }
@@ -9,6 +9,7 @@ exports.GET_OBSERVABLE_VALUE = "____getObservableValue";
9
9
  exports.GET_TO_JSON = "toJSON";
10
10
  const proxyCache = new WeakMap();
11
11
  const scopeCache = new WeakMap();
12
+ const leafScopeCache = new WeakMap();
12
13
  function getOwnPropertyDescriptor(target, prop) {
13
14
  const descriptor = Object.getOwnPropertyDescriptor(target, prop);
14
15
  return {
@@ -54,7 +55,6 @@ function UnwrapProxy(value) {
54
55
  }
55
56
  return value;
56
57
  }
57
- let applyingDiff = false;
58
58
  function CreateProxyFactory(alias) {
59
59
  function CreateProxy(value) {
60
60
  value = UnwrapProxy(value);
@@ -67,7 +67,6 @@ function CreateProxyFactory(alias) {
67
67
  const typedValue = value;
68
68
  const proxy = CreateProxy(typedValue);
69
69
  return proxy.map(ToJsonCopy);
70
- break;
71
70
  }
72
71
  case "object": {
73
72
  const typedValue = alias(value) ?? value;
@@ -114,7 +113,7 @@ function CreateProxyFactory(alias) {
114
113
  return proxy;
115
114
  }
116
115
  function ArrayProxySetter(array, prop, value) {
117
- if (readOnly && !applyingDiff)
116
+ if (readOnly)
118
117
  throw `Object is readonly`;
119
118
  if (prop === exports.IS_OBSERVABLE_NODE)
120
119
  throw `Cannot assign read-only property: ${exports.IS_OBSERVABLE_NODE}`;
@@ -127,7 +126,7 @@ function CreateProxyFactory(alias) {
127
126
  function ArrayProxyGetter(array, prop) {
128
127
  if (prop === exports.IS_OBSERVABLE_NODE)
129
128
  return true;
130
- if (readOnly && !applyingDiff)
129
+ if (readOnly)
131
130
  switch (prop) {
132
131
  case "push":
133
132
  case "unshift":
@@ -136,7 +135,7 @@ function CreateProxyFactory(alias) {
136
135
  case "shift":
137
136
  case "sort":
138
137
  case "reverse":
139
- if (readOnly && !applyingDiff)
138
+ if (readOnly)
140
139
  throw `Object is readonly`;
141
140
  }
142
141
  const scope = scopeCache.get(array);
@@ -181,44 +180,36 @@ function CreateProxyFactory(alias) {
181
180
  }
182
181
  }
183
182
  }
183
+ function SetPropertyValue(object, prop, value) {
184
+ object[prop] = value;
185
+ const leafScopes = leafScopeCache.get(object);
186
+ observableScope_1.ObservableScope.Update(leafScopes && leafScopes[prop] || scopeCache.get(object));
187
+ }
184
188
  function ObjectProxySetter(object, prop, value) {
185
- if (readOnly && !applyingDiff)
189
+ if (readOnly)
186
190
  throw `Object is readonly`;
187
191
  if (prop === exports.IS_OBSERVABLE_NODE)
188
192
  throw `Cannot assign read-only property: ${exports.IS_OBSERVABLE_NODE}`;
189
- const scope = scopeCache.get(object);
190
193
  value = UnwrapProxy(value);
191
- if (applyingDiff) {
192
- object[prop] = value;
193
- observableScope_1.ObservableScope.Update(scope);
194
- }
195
- else {
196
- applyingDiff = true;
197
- const diff = (0, json_1.JsonDiff)(value, object[prop]);
198
- for (let x = 0; x < diff.length; x++) {
199
- if (diff[x].path.length === 0) {
200
- const proxy = proxyCache.get(object);
201
- proxy[prop] = diff[x].value;
202
- }
203
- else {
204
- const path = diff[x].path;
205
- let curr = object[prop];
206
- let y = 0;
207
- for (; y < path.length - 1; y++)
208
- curr = curr[path[y]];
209
- const target = proxyCache.get(curr) ?? curr;
210
- target[path[y]] = diff[x].value;
211
- }
194
+ const diff = (0, json_1.JsonDiff)(value, object[prop]);
195
+ for (let x = 0; x < diff.length; x++) {
196
+ if (diff[x].path.length === 0) {
197
+ SetPropertyValue(object, prop, diff[x].value);
198
+ }
199
+ else {
200
+ const path = diff[x].path;
201
+ let curr = object[prop];
202
+ let y = 0;
203
+ for (; y < path.length - 1; y++)
204
+ curr = curr[path[y]];
205
+ SetPropertyValue(curr, path[y], diff[x].value);
212
206
  }
213
- applyingDiff = false;
214
207
  }
215
208
  return true;
216
209
  }
217
210
  function ObjectProxyGetter(object, prop) {
218
211
  if (prop === exports.IS_OBSERVABLE_NODE)
219
212
  return true;
220
- const scope = scopeCache.get(object);
221
- object = observableScope_1.ObservableScope.Value(scope);
222
213
  switch (prop) {
223
214
  case exports.GET_TO_JSON:
224
215
  return function () {
@@ -227,14 +218,22 @@ function CreateProxyFactory(alias) {
227
218
  case exports.GET_OBSERVABLE_VALUE:
228
219
  return object;
229
220
  default: {
230
- const proxyValue = object[prop];
231
- if (typeof prop === "symbol")
232
- return proxyValue;
233
- const proxy = CreateProxyFromValue(proxyValue);
234
- return proxy;
221
+ return GetAccessorValue(object, prop);
235
222
  }
236
223
  }
237
224
  }
225
+ function GetAccessorValue(parent, prop) {
226
+ let leafScopes = leafScopeCache.get(parent);
227
+ if (leafScopes === undefined) {
228
+ leafScopes = {};
229
+ leafScopeCache.set(parent, leafScopes);
230
+ }
231
+ leafScopes[prop] ??= observableScope_1.ObservableScope.Create(function () {
232
+ const value = parent[prop];
233
+ return CreateProxyFromValue(value);
234
+ });
235
+ return observableScope_1.ObservableScope.Value(leafScopes[prop]);
236
+ }
238
237
  function CreateProxyFromValue(value) {
239
238
  const type = (0, jsonType_1.JsonType)(value);
240
239
  switch (type) {
@@ -270,10 +269,6 @@ var ObservableNode;
270
269
  observableScope_1.ObservableScope.Update(scope);
271
270
  }
272
271
  ObservableNode.Touch = Touch;
273
- function EnableDiff(value) {
274
- applyingDiff = value;
275
- }
276
- ObservableNode.EnableDiff = EnableDiff;
277
272
  function ApplyDiff(rootNode, diffResult) {
278
273
  const root = rootNode[exports.GET_OBSERVABLE_VALUE];
279
274
  const pathTuples = [["", root]];
@@ -30,21 +30,19 @@ export interface IObservableScope<T> extends IDestroyable {
30
30
  };
31
31
  async: boolean;
32
32
  value: T;
33
+ promise: Promise<T> | null;
33
34
  dirty: boolean;
34
35
  emitter: Emitter;
35
36
  emitters: (Emitter | null)[];
36
37
  setCallback: EmitterCallback;
37
38
  destroyed: boolean;
38
- calc: any[] | null;
39
- watchSet: Set<Emitter> | null;
40
- watchCalc: any[] | null;
39
+ watchEmitters: Emitter[] | null;
41
40
  }
42
41
  export declare namespace ObservableScope {
43
42
  function Create<T>(valueFunction: {
44
43
  (): T | Promise<T>;
45
44
  }): IObservableScope<T>;
46
45
  function Register(emitter: Emitter): void;
47
- function Calc<T>(value: T): T;
48
46
  function Value<T>(scope: IObservableScope<T>): T;
49
47
  function Watching(): boolean;
50
48
  function Touch<T>(scope: IObservableScope<T>): void;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ObservableScope = exports.ObservableScopeWrapper = exports.ObservableScopeValue = void 0;
4
- const array_1 = require("../../Utils/array");
5
4
  const emitter_1 = require("../../Utils/emitter");
5
+ const list_1 = require("../../Utils/list");
6
6
  class ObservableScopeValue {
7
7
  get Value() {
8
8
  return ObservableScope.Value(this.scope);
@@ -47,15 +47,15 @@ class ObservableScope extends ObservableScopeWrapper {
47
47
  }
48
48
  exports.ObservableScope = ObservableScope;
49
49
  let currentScope = null;
50
- let currentWatching = false;
50
+ let currentlyWatching = false;
51
51
  function WatchScope(scope) {
52
52
  const parentScope = currentScope;
53
- const parentWatching = currentWatching;
53
+ const parentWatching = currentlyWatching;
54
54
  currentScope = scope;
55
- currentWatching = true;
55
+ currentlyWatching = true;
56
56
  const value = scope.getFunction();
57
57
  currentScope = parentScope;
58
- currentWatching = parentWatching;
58
+ currentlyWatching = parentWatching;
59
59
  return value;
60
60
  }
61
61
  (function (ObservableScope) {
@@ -63,14 +63,13 @@ function WatchScope(scope) {
63
63
  const scope = {
64
64
  getFunction: valueFunction,
65
65
  value: null,
66
+ promise: null,
66
67
  async: valueFunction[Symbol.toStringTag] === "AsyncFunction",
67
68
  dirty: true,
68
69
  emitter: emitter_1.Emitter.Create(),
69
70
  emitters: [],
70
71
  destroyed: false,
71
- calc: null,
72
- watchSet: null,
73
- watchCalc: null,
72
+ watchEmitters: null,
74
73
  setCallback: function () {
75
74
  return OnSet(scope);
76
75
  },
@@ -79,30 +78,22 @@ function WatchScope(scope) {
79
78
  }
80
79
  ObservableScope.Create = Create;
81
80
  function Register(emitter) {
82
- if (!currentWatching)
81
+ if (!currentlyWatching)
83
82
  return;
84
- currentScope.watchSet ??= new Set();
85
- currentScope.watchSet.add(emitter);
83
+ currentScope.watchEmitters ??= [];
84
+ currentScope.watchEmitters.push(emitter);
86
85
  }
87
86
  ObservableScope.Register = Register;
88
- function Calc(value) {
89
- if (!currentWatching)
90
- return;
91
- currentScope.watchCalc ??= [];
92
- currentScope.watchCalc.push(value);
93
- return value;
94
- }
95
- ObservableScope.Calc = Calc;
96
87
  function Value(scope) {
97
88
  if (!scope)
98
89
  return undefined;
99
90
  Register(scope.emitter);
100
- UpdateValue(scope);
91
+ UpdateScope(scope);
101
92
  return scope.value;
102
93
  }
103
94
  ObservableScope.Value = Value;
104
95
  function Watching() {
105
- return currentWatching;
96
+ return currentlyWatching;
106
97
  }
107
98
  ObservableScope.Watching = Watching;
108
99
  function Touch(scope) {
@@ -132,54 +123,65 @@ function WatchScope(scope) {
132
123
  }
133
124
  ObservableScope.Destroy = Destroy;
134
125
  })(ObservableScope || (exports.ObservableScope = ObservableScope = {}));
126
+ function UpdateScope(scope) {
127
+ UpdateValue(scope);
128
+ scope.async && scope.promise.then(function () {
129
+ emitter_1.Emitter.Emit(scope.emitter, scope);
130
+ });
131
+ }
132
+ const updateScopeQueue = list_1.List.Create();
133
+ function ProcessScopeUpdateQueue() {
134
+ const processList = list_1.List.Split(updateScopeQueue, 0);
135
+ for (let node = processList.head; node !== null; node = node.next)
136
+ UpdateScope(node.data);
137
+ list_1.List.Clear(processList);
138
+ }
139
+ function QueueScopeUpdate(scope) {
140
+ list_1.List.Add(updateScopeQueue, scope);
141
+ if (updateScopeQueue.size === 1)
142
+ queueMicrotask(ProcessScopeUpdateQueue);
143
+ }
144
+ function DirtyScope(scope) {
145
+ scope.dirty = true;
146
+ scope.async ? QueueScopeUpdate(scope) : emitter_1.Emitter.Emit(scope.emitter, scope);
147
+ }
135
148
  function OnSet(scope) {
136
149
  if (!scope || scope.dirty || scope.destroyed)
137
150
  return scope?.destroyed;
138
- scope.dirty = !!scope.getFunction;
139
- emitter_1.Emitter.Emit(scope.emitter, scope);
151
+ DirtyScope(scope);
140
152
  return false;
141
153
  }
142
154
  function UpdateValue(scope) {
143
155
  if (!scope.dirty)
144
156
  return;
145
157
  scope.dirty = false;
158
+ scope.watchEmitters = null;
146
159
  const value = WatchScope(scope);
147
- const change = scope.watchCalc === null || (0, array_1.ArrayDiff)(scope.calc, scope.watchCalc);
148
- scope.calc = scope.watchCalc;
149
- if (change) {
150
- if (scope.async)
151
- Promise.resolve(value).then((val) => {
152
- scope.value = val;
153
- emitter_1.Emitter.Emit(scope.emitter, scope);
154
- });
155
- else
156
- scope.value = value;
157
- UpdateEmitters(scope);
158
- }
159
- scope.watchCalc = null;
160
- scope.watchSet?.clear();
160
+ if (scope.async) {
161
+ scope.promise = value.then(function (result) {
162
+ scope.value = result;
163
+ return result;
164
+ });
165
+ }
166
+ else
167
+ scope.value = value;
168
+ UpdateEmitters(scope);
161
169
  }
162
170
  function UpdateEmitters(scope) {
163
- const newEmitters = scope.watchSet;
171
+ const newEmitters = scope.watchEmitters;
164
172
  if (newEmitters === null) {
165
173
  for (let x = 0; x < scope.emitters.length; x++)
166
174
  emitter_1.Emitter.Remove(scope.emitters[x], scope.setCallback);
167
175
  scope.emitters = [];
168
176
  return;
169
177
  }
170
- let removed = false;
171
- for (let x = 0; x < scope.emitters.length; x++) {
172
- if (!newEmitters.delete(scope.emitters[x])) {
173
- emitter_1.Emitter.Remove(scope.emitters[x], scope.setCallback);
174
- scope.emitters[x] = null;
175
- removed = true;
176
- }
177
- }
178
- const initLength = scope.emitters.length;
179
- scope.emitters.push(...newEmitters);
180
- for (let x = initLength; x < scope.emitters.length; x++)
181
- emitter_1.Emitter.On(scope.emitters[x], scope.setCallback);
182
- removed && (0, array_1.RemoveNulls)(scope.emitters);
178
+ let x = 0;
179
+ for (; x < scope.emitters.length && x < newEmitters.length && scope.emitters[x] === newEmitters[x]; x++) { }
180
+ for (let y = x; y < scope.emitters.length; y++)
181
+ emitter_1.Emitter.Remove(scope.emitters[y], scope.setCallback);
182
+ for (let y = x; y < newEmitters.length; y++)
183
+ emitter_1.Emitter.On(newEmitters[y], scope.setCallback);
184
+ scope.emitters = newEmitters;
183
185
  }
184
186
  function DestroyScope(scope) {
185
187
  if (!scope)
@@ -1,34 +0,0 @@
1
- import { ObservableScope } from "../Tree/observableScope";
2
- export declare class ObservableTree {
3
- private valuePathResolver?;
4
- private undefinedScope;
5
- private scopeCache;
6
- private leafScopeCache;
7
- private proxyCache;
8
- private pathCache;
9
- private rootStateMap;
10
- constructor(valuePathResolver?: {
11
- (value: string): string | undefined;
12
- });
13
- static UnwrapProxyValues(value: any): any;
14
- Get<O>(path: string): O;
15
- GetPathOf(value: any): string;
16
- Scope<O, R = O>(path: string, callback?: {
17
- (obj: O): R;
18
- }): ObservableScope<O | R>;
19
- Write(path: string, value: any): void;
20
- WriteAll(data: Array<{
21
- path: string;
22
- value: any;
23
- }>): void;
24
- private GetParentScope;
25
- private GetPropertyScope;
26
- private GetValueProxy;
27
- private ObjectProxyGetter;
28
- private CreateObjectProxy;
29
- private ArrayProxyGetter;
30
- private CreateArrayProxy;
31
- private CreateProxy;
32
- private WritePath;
33
- private UpdatePathCache;
34
- }