j-templates 7.0.55 → 7.0.57

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,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CreateAssignment = CreateAssignment;
4
+ const DEFAULT_ASSIGNMENT = {};
4
5
  function CreateAssignment(target, createAssignment) {
5
6
  let last;
6
7
  let writeTo = {};
@@ -8,6 +9,7 @@ function CreateAssignment(target, createAssignment) {
8
9
  if (next === last)
9
10
  return;
10
11
  last = next;
12
+ next = !next ? DEFAULT_ASSIGNMENT : next;
11
13
  for (const key in writeTo) {
12
14
  writeTo[key](next);
13
15
  }
@@ -22,6 +22,7 @@ function CreatePropertyAssignment(target, property) {
22
22
  childAssignment(nextValue);
23
23
  }
24
24
  }
25
+ lastValue = nextValue;
25
26
  };
26
27
  }
27
28
  function CreateRootPropertyAssignment(target, property) {
@@ -59,6 +60,7 @@ function CreateRootPropertyAssignment(target, property) {
59
60
  }
60
61
  }
61
62
  }
63
+ lastValue = nextValue;
62
64
  };
63
65
  }
64
66
  function AssignNodeValue(target, value) {
@@ -100,6 +100,9 @@ exports.DOMNodeConfig = {
100
100
  setText(target, text) {
101
101
  target.nodeValue = text;
102
102
  },
103
+ copyText(source, target) {
104
+ target.nodeValue = source.nodeValue;
105
+ },
103
106
  getAttribute(target, attribute) {
104
107
  return target.getAttribute(attribute);
105
108
  },
@@ -133,15 +136,8 @@ exports.DOMNodeConfig = {
133
136
  },
134
137
  reconcileChildren(target, children) {
135
138
  if (!target.firstChild) {
136
- if (children.length > 10) {
137
- const fragment = new DocumentFragment();
138
- for (let x = 0; x < children.length; x++)
139
- fragment.appendChild(children[x]);
140
- target.appendChild(fragment);
141
- }
142
- else
143
- for (let x = 0; x < children.length; x++)
144
- target.appendChild(children[x]);
139
+ for (let x = 0; x < children.length; x++)
140
+ target.appendChild(children[x]);
145
141
  return;
146
142
  }
147
143
  if (children.length === 0) {
@@ -169,14 +165,11 @@ exports.DOMNodeConfig = {
169
165
  }
170
166
  while (target.lastChild !== children[x - 1])
171
167
  target.removeChild(target.lastChild);
172
- if (children.length - x > 10) {
173
- const fragment = new DocumentFragment();
174
- for (; x < children.length; x++)
175
- fragment.appendChild(children[x]);
176
- target.appendChild(fragment);
177
- }
178
- else
179
- for (; x < children.length; x++)
180
- target.appendChild(children[x]);
168
+ for (; x < children.length; x++)
169
+ target.appendChild(children[x]);
170
+ },
171
+ reconcileChild(target, child) {
172
+ if (target.childElementCount > 1 || target.firstChild !== child)
173
+ target.replaceChildren(child);
181
174
  },
182
175
  };
@@ -4,6 +4,7 @@ export interface INodeConfig {
4
4
  scheduleUpdate(callback: () => void): void;
5
5
  wrapPriorityUpdates<P extends any[]>(callback: (...args: P) => void): (...args: P) => void;
6
6
  setText(target: any, text: string): void;
7
+ copyText(source: any, target: any): void;
7
8
  isTextNode(target: any): boolean;
8
9
  getAttribute(target: any, attribute: string): string;
9
10
  setAttribute(target: any, attribute: string, value: string): void;
@@ -38,5 +39,6 @@ export interface INodeConfig {
38
39
  getNextSibling(target: any): any;
39
40
  replaceChildren(target: any, children: any[]): void;
40
41
  reconcileChildren(target: any, children: any[]): void;
42
+ reconcileChild(target: any, child: any): void;
41
43
  }
42
44
  export declare const NodeConfig: INodeConfig;
package/Node/vNode.js CHANGED
@@ -4,7 +4,6 @@ exports.vNode = void 0;
4
4
  const Store_1 = require("../Store");
5
5
  const emitter_1 = require("../Utils/emitter");
6
6
  const injector_1 = require("../Utils/injector");
7
- const list_1 = require("../Utils/list");
8
7
  const thread_1 = require("../Utils/thread");
9
8
  const nodeConfig_1 = require("./nodeConfig");
10
9
  var vNode;
@@ -13,7 +12,11 @@ var vNode;
13
12
  return {
14
13
  definition,
15
14
  type: definition.type,
16
- injector: injector_1.Injector.Current() ?? new injector_1.Injector(),
15
+ injector: definition.componentConstructor
16
+ ? injector_1.Injector.Scope(injector_1.Injector.Current(), function () {
17
+ return new injector_1.Injector();
18
+ })
19
+ : (injector_1.Injector.Current() ?? new injector_1.Injector()),
17
20
  node: definition.node ?? null,
18
21
  children: null,
19
22
  destroyed: false,
@@ -55,7 +58,10 @@ var vNode;
55
58
  vnode.component?.Destroy();
56
59
  Store_1.ObservableScope.DestroyAll(vnode.scopes);
57
60
  vnode.onDestroyed && emitter_1.Emitter.Emit(vnode.onDestroyed);
58
- vnode.children && DestroyAll(vnode.children);
61
+ for (let x = 0; vnode.children && x < vnode.children.length; x++) {
62
+ DestroyAll(vnode.children[x][1]);
63
+ Store_1.ObservableScope.Destroy(vnode.children[x][2]);
64
+ }
59
65
  }
60
66
  vNode.Destroy = Destroy;
61
67
  function DestroyAll(vnodes) {
@@ -93,10 +99,11 @@ function InitNode(vnode) {
93
99
  if (props) {
94
100
  const assignProperties = nodeConfig_1.NodeConfig.createPropertyAssignment(node);
95
101
  if (typeof props === "function") {
96
- const scope = Store_1.ObservableScope.Create(props);
97
- vnode.scopes.push(scope);
98
- Store_1.ObservableScope.Watch(scope, ScheduledAssignment(assignProperties));
99
- const value = Store_1.ObservableScope.Peek(scope);
102
+ const [value, scope] = Store_1.ObservableScope.CreateIf(props);
103
+ if (scope) {
104
+ vnode.scopes.push(scope);
105
+ Store_1.ObservableScope.Watch(scope, ScheduledAssignment(assignProperties));
106
+ }
100
107
  assignProperties(value);
101
108
  }
102
109
  else
@@ -105,27 +112,24 @@ function InitNode(vnode) {
105
112
  if (on) {
106
113
  const assignEvents = nodeConfig_1.NodeConfig.createEventAssignment(node);
107
114
  if (typeof on === "function") {
108
- const scope = Store_1.ObservableScope.Create(on);
109
- vnode.scopes.push(scope);
110
- Store_1.ObservableScope.Watch(scope, ScheduledAssignment(assignEvents));
111
- const value = Store_1.ObservableScope.Peek(scope);
115
+ const [value, scope] = Store_1.ObservableScope.CreateIf(on);
116
+ if (scope) {
117
+ vnode.scopes.push(scope);
118
+ Store_1.ObservableScope.Watch(scope, ScheduledAssignment(assignEvents));
119
+ }
112
120
  assignEvents(value);
113
121
  }
114
122
  else
115
123
  assignEvents(on);
116
- vnode.onDestroyed ??= emitter_1.Emitter.Create();
117
- emitter_1.Emitter.On(vnode.onDestroyed, function () {
118
- assignEvents(null);
119
- return true;
120
- });
121
124
  }
122
125
  if (attrs) {
123
126
  const assignAttributes = nodeConfig_1.NodeConfig.createAttributeAssignment(node);
124
127
  if (typeof attrs === "function") {
125
- const scope = Store_1.ObservableScope.Create(attrs);
126
- vnode.scopes.push(scope);
127
- Store_1.ObservableScope.Watch(scope, ScheduledAssignment(assignAttributes));
128
- const value = Store_1.ObservableScope.Peek(scope);
128
+ const [value, scope] = Store_1.ObservableScope.CreateIf(attrs);
129
+ if (scope) {
130
+ vnode.scopes.push(scope);
131
+ Store_1.ObservableScope.Watch(scope, ScheduledAssignment(assignAttributes));
132
+ }
129
133
  assignAttributes(value);
130
134
  }
131
135
  else
@@ -134,29 +138,14 @@ function InitNode(vnode) {
134
138
  if (componentConstructor) {
135
139
  vnode.component = new componentConstructor(vnode);
136
140
  vnode.component.Bound();
137
- const componentScope = Store_1.ObservableScope.Create(function () {
138
- let nodes = injector_1.Injector.Scope(vnode.injector, function () {
139
- return vnode.component.Template();
140
- });
141
- if (!Array.isArray(nodes))
142
- nodes = [nodes];
143
- return nodes;
144
- });
145
- vnode.scopes.push(componentScope);
146
- Store_1.ObservableScope.Watch(componentScope, CreateScheduledCallback(function () {
147
- if (vnode.destroyed)
148
- return;
149
- const nodes = injector_1.Injector.Scope(vnode.injector, Store_1.ObservableScope.Peek, componentScope);
150
- vNode.DestroyAll(vnode.children);
151
- vnode.children = nodes;
152
- UpdateChildren(vnode);
153
- }));
154
- const nodes = Store_1.ObservableScope.Peek(componentScope);
155
- vnode.children = nodes;
141
+ function componentChildren() {
142
+ return vnode.component.Template();
143
+ }
144
+ Children(vnode, componentChildren, DefaultData);
156
145
  }
157
146
  else if (childrenArray) {
158
- vnode.children = childrenArray;
159
- vNode.InitAll(vnode.children);
147
+ vnode.children = [[undefined, childrenArray, null]];
148
+ vNode.InitAll(childrenArray);
160
149
  }
161
150
  else if (children) {
162
151
  Children(vnode, children, data);
@@ -175,80 +164,146 @@ function Children(vnode, children, data) {
175
164
  }));
176
165
  AssignChildren(vnode, childrenScope);
177
166
  }
167
+ const DEFAULT_DATA = [undefined];
168
+ function DefaultData() {
169
+ return DEFAULT_DATA;
170
+ }
178
171
  function CreateChildrenScope(vnode, children, data) {
179
- if (data === undefined)
180
- return Store_1.ObservableScope.Create(WrapStaticChildren(vnode, children));
181
- const dataScope = Store_1.ObservableScope.Create(data);
182
- data = function () {
183
- const result = Store_1.ObservableScope.Value(dataScope);
184
- if (!result)
185
- return [];
186
- if (Array.isArray(result))
187
- return result;
188
- return [result];
189
- };
190
- const nodeList = list_1.List.Create();
191
- const scope = Store_1.ObservableScope.Create(WrapChildren(vnode.injector, children, data, nodeList));
192
- Store_1.ObservableScope.OnDestroyed(scope, function () {
193
- DestroyNodeList(nodeList);
194
- Store_1.ObservableScope.Destroy(dataScope);
195
- return true;
196
- });
172
+ let dataScope;
173
+ if (data !== undefined) {
174
+ dataScope = Store_1.ObservableScope.Create(data);
175
+ data = function () {
176
+ const result = Store_1.ObservableScope.Value(dataScope);
177
+ if (!result)
178
+ return [];
179
+ if (Array.isArray(result))
180
+ return result;
181
+ return [result];
182
+ };
183
+ }
184
+ else
185
+ data = DefaultData;
186
+ const scope = Store_1.ObservableScope.Create(WrapChildren(vnode.injector, children, data));
187
+ dataScope &&
188
+ Store_1.ObservableScope.OnDestroyed(scope, function () {
189
+ Store_1.ObservableScope.Destroy(dataScope);
190
+ return true;
191
+ });
197
192
  return scope;
198
193
  }
199
- function WrapStaticChildren(vnode, children) {
200
- return function () {
201
- vnode.children && vNode.DestroyAll(vnode.children);
202
- const childNodes = injector_1.Injector.Scope(vnode.injector, children, undefined);
203
- return CreateNodeArray(childNodes, vnode.children);
204
- };
205
- }
206
- function WrapChildren(injector, children, data, nodeList) {
194
+ function WrapChildren(injector, children, data) {
195
+ let nodeArray = [];
207
196
  return function () {
208
197
  const nextData = data();
209
198
  switch (nextData.length) {
210
- case 0:
211
- DestroyNodeList(nodeList);
212
- return [];
213
- default: {
214
- const nodeListMap = list_1.List.ToListMap(nodeList, GetData);
215
- const nextNodeList = list_1.List.Create();
216
- const nextNodeArray = [];
217
- for (let x = 0; x < nextData.length; x++) {
218
- const data = nextData[x];
219
- const existingNodeList = nodeListMap.get(data);
220
- const existingNode = existingNodeList && list_1.List.PopNode(existingNodeList);
221
- if (existingNode) {
222
- list_1.List.AddNode(nextNodeList, existingNode);
223
- if (existingNode.data.scope.dirty) {
224
- vNode.DestroyAll(existingNode.data.nodes);
225
- existingNode.data.nodes = Store_1.ObservableScope.Value(existingNode.data.scope);
226
- }
227
- else
228
- Store_1.ObservableScope.Touch(existingNode.data.scope);
229
- }
230
- else {
231
- nodeListMap.delete(data);
232
- const childrenScope = Store_1.ObservableScope.Create(function () {
233
- const childNodes = injector_1.Injector.Scope(injector, children, data);
234
- return CreateNodeArray(childNodes);
235
- });
236
- list_1.List.Add(nextNodeList, {
237
- data,
238
- nodes: Store_1.ObservableScope.Value(childrenScope),
239
- scope: childrenScope,
240
- });
241
- }
242
- nextNodeArray.push(...nextNodeList.tail.data.nodes);
199
+ case 0: {
200
+ for (let x = 0; x < nodeArray.length; x++) {
201
+ vNode.DestroyAll(nodeArray[x][1]);
202
+ Store_1.ObservableScope.Destroy(nodeArray[x][2]);
243
203
  }
244
- for (let value of nodeListMap.values())
245
- DestroyNodeList(value);
246
- list_1.List.Append(nodeList, nextNodeList);
247
- return nextNodeArray;
204
+ nodeArray.splice(0);
205
+ }
206
+ default: {
207
+ if (nodeArray.length < 21)
208
+ nodeArray = EvaluateNextNodesSmall(injector, children, nextData, nodeArray);
209
+ else
210
+ nodeArray = EvaluateNextNodesLarge(injector, children, nextData, nodeArray);
248
211
  }
249
212
  }
213
+ return nodeArray;
250
214
  };
251
215
  }
216
+ function EvaluateNextNodesSmall(injector, getNextChildren, nextData, nodeArray) {
217
+ if (nextData === DEFAULT_DATA) {
218
+ const nextChildren = injector_1.Injector.Scope(injector, getNextChildren, nextData[0]);
219
+ const children = CreateNodeArray(nextChildren, nodeArray[0]?.[1]);
220
+ for (let x = 0; x < nodeArray.length; x++) {
221
+ vNode.DestroyAll(nodeArray[x][1]);
222
+ Store_1.ObservableScope.Destroy(nodeArray[x][2]);
223
+ }
224
+ return [
225
+ [undefined, children, null],
226
+ ];
227
+ }
228
+ const nextNodes = new Array(nextData.length);
229
+ for (let x = 0; x < nextData.length; x++) {
230
+ const data = nextData[x];
231
+ let i = 0;
232
+ for (; i < nodeArray.length &&
233
+ (nodeArray[i] === null || nodeArray[i][0] !== data); i++) { }
234
+ if (i !== nodeArray.length) {
235
+ if (nodeArray[i][2]) {
236
+ const scope = nodeArray[i][2];
237
+ const value = scope.value;
238
+ const updatedValue = Store_1.ObservableScope.Value(scope);
239
+ if (value !== updatedValue)
240
+ nodeArray[i][1] = CreateNodeArray(updatedValue);
241
+ }
242
+ nextNodes[x] = nodeArray[i];
243
+ nodeArray[i] = null;
244
+ }
245
+ else {
246
+ const [nextChildren, scope] = Store_1.ObservableScope.CreateIf(function () {
247
+ return injector_1.Injector.Scope(injector, getNextChildren, data);
248
+ });
249
+ nextNodes[x] = [data, CreateNodeArray(nextChildren), scope];
250
+ }
251
+ }
252
+ for (let x = 0; x < nodeArray.length; x++) {
253
+ if (nodeArray[x] !== null) {
254
+ vNode.DestroyAll(nodeArray[x][1]);
255
+ Store_1.ObservableScope.Destroy(nodeArray[x][2]);
256
+ }
257
+ }
258
+ return nextNodes;
259
+ }
260
+ function EvaluateNextNodesLarge(injector, getNextChildren, nextData, nodeArray) {
261
+ const nextNodes = new Array(nextData.length);
262
+ const dataMap = new Map();
263
+ for (let x = 0; x < nodeArray.length; x++) {
264
+ const arr = dataMap.get(nodeArray[x][0]) ?? [];
265
+ arr.push(nodeArray[x]);
266
+ dataMap.set(nodeArray[x][0], arr);
267
+ }
268
+ for (let x = 0; x < nextData.length; x++) {
269
+ const data = nextData[x];
270
+ const currentChildren = dataMap.get(data);
271
+ let currentChildIndex = currentChildren ? currentChildren.length - 1 : -1;
272
+ for (; currentChildIndex >= 0 && currentChildren[currentChildIndex] === null; currentChildIndex--) { }
273
+ if (currentChildIndex !== -1) {
274
+ const currentChild = currentChildren[currentChildIndex];
275
+ if (currentChild[2]) {
276
+ const scope = currentChild[2];
277
+ const value = scope.value;
278
+ const updatedValue = Store_1.ObservableScope.Value(scope);
279
+ if (value !== updatedValue)
280
+ currentChild[1] = CreateNodeArray(updatedValue);
281
+ }
282
+ if (currentChild[2]?.dirty) {
283
+ const nextChildren = Store_1.ObservableScope.Value(currentChild[2]);
284
+ currentChild[1] = CreateNodeArray(nextChildren);
285
+ }
286
+ nextNodes[x] = currentChild;
287
+ currentChildren[currentChildIndex] = null;
288
+ if (currentChildIndex === 0)
289
+ dataMap.delete(data);
290
+ }
291
+ else {
292
+ const [nextChildren, scope] = Store_1.ObservableScope.CreateIf(function () {
293
+ return injector_1.Injector.Scope(injector, getNextChildren, data);
294
+ });
295
+ nextNodes[x] = [data, CreateNodeArray(nextChildren), scope];
296
+ }
297
+ }
298
+ for (const value of dataMap.values()) {
299
+ for (let x = 0; x < value.length; x++) {
300
+ const row = value[x];
301
+ row && vNode.DestroyAll(row[1]);
302
+ row && Store_1.ObservableScope.Destroy(row[2]);
303
+ }
304
+ }
305
+ return nextNodes;
306
+ }
252
307
  function CreateNodeArray(children, previousChildren) {
253
308
  if (Array.isArray(children))
254
309
  return children;
@@ -262,22 +317,10 @@ function CreateNodeArray(children, previousChildren) {
262
317
  ? previousChildren
263
318
  : [firstPrevChild];
264
319
  }
265
- return [
266
- vNode.CreateText(children),
267
- ];
320
+ return [vNode.CreateText(children)];
268
321
  }
269
322
  return [children];
270
323
  }
271
- function DestroyNodeList(nodeList) {
272
- for (let node = nodeList.head; node !== null; node = node.next) {
273
- vNode.DestroyAll(node.data.nodes);
274
- Store_1.ObservableScope.Destroy(node.data.scope);
275
- }
276
- list_1.List.Clear(nodeList);
277
- }
278
- function GetData(data) {
279
- return data.data;
280
- }
281
324
  function AssignChildren(vnode, childrenScope) {
282
325
  const children = Store_1.ObservableScope.Peek(childrenScope);
283
326
  vnode.children = children;
@@ -286,9 +329,9 @@ function UpdateChildren(vnode, init = false, skipInit = false) {
286
329
  if (!vnode.children)
287
330
  return;
288
331
  if (vnode.children.length === 1 &&
289
- vnode.children[0].type === "text" &&
290
- vnode.children[0].node) {
291
- nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, [vnode.children[0].node]);
332
+ vnode.children[0][1].length === 1 &&
333
+ vnode.children[0][1][0].node) {
334
+ nodeConfig_1.NodeConfig.reconcileChild(vnode.node, vnode.children[0][1][0].node);
292
335
  return;
293
336
  }
294
337
  const children = vnode.children;
@@ -296,24 +339,32 @@ function UpdateChildren(vnode, init = false, skipInit = false) {
296
339
  if (vnode.destroyed || children !== vnode.children)
297
340
  return;
298
341
  for (let x = 0; !skipInit && x < children.length; x++)
299
- if (children[x].definition) {
300
- const childNode = children[x];
301
- (0, thread_1.Schedule)(function () {
302
- if (vnode.destroyed || children !== vnode.children)
303
- return;
304
- vNode.Init(childNode);
305
- });
306
- }
342
+ for (let y = 0; y < children[x][1].length; y++)
343
+ if (children[x][1][y].definition) {
344
+ const childNode = children[x][1][y];
345
+ (0, thread_1.Schedule)(function () {
346
+ if (vnode.destroyed || children !== vnode.children)
347
+ return;
348
+ vNode.Init(childNode);
349
+ });
350
+ }
307
351
  (0, thread_1.Thread)(function (async) {
308
352
  if (vnode.destroyed || children !== vnode.children)
309
353
  return;
310
- if (init || !async)
311
- nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, vnode.children.map((vnode) => vnode.node));
354
+ if (init || !async) {
355
+ if (vnode.children.length === 1 && vnode.children[0][1].length === 1)
356
+ nodeConfig_1.NodeConfig.reconcileChild(vnode.node, vnode.children[0][1][0].node);
357
+ else
358
+ nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, vnode.children.flatMap((row) => row[1].map((vnode) => vnode.node)));
359
+ }
312
360
  else
313
361
  nodeConfig_1.NodeConfig.scheduleUpdate(function () {
314
362
  if (vnode.destroyed || children !== vnode.children)
315
363
  return;
316
- nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, vnode.children.map((vnode) => vnode.node));
364
+ if (vnode.children.length === 1 && vnode.children[0][1].length === 1)
365
+ nodeConfig_1.NodeConfig.reconcileChild(vnode.node, vnode.children[0][1][0].node);
366
+ else
367
+ nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, vnode.children.flatMap((row) => row[1].map((vnode) => vnode.node)));
317
368
  });
318
369
  });
319
370
  });
@@ -19,7 +19,7 @@ export type vNode = {
19
19
  definition: vNodeDefinition<any, any, any>;
20
20
  injector: Injector;
21
21
  node: Node | null;
22
- children: vNode[] | null;
22
+ children: [any, vNode[], IObservableScope<string | vNode | vNode[]> | null][] | null;
23
23
  destroyed: boolean;
24
24
  onDestroyed: Emitter | null;
25
25
  scopes: IObservableScope<unknown>[];
@@ -47,6 +47,9 @@ export declare namespace ObservableScope {
47
47
  function Create<T>(valueFunction: {
48
48
  (): T | Promise<T>;
49
49
  }, calc?: boolean): IObservableScope<T>;
50
+ function CreateIf<T>(valueFunction: {
51
+ (): T | Promise<T>;
52
+ }): [T, IObservableScope<T> | null];
50
53
  function Register(emitter: Emitter): void;
51
54
  function Init<T>(scope: IObservableScope<T>): void;
52
55
  function Peek<T>(scope: IObservableScope<T>): T;
@@ -65,6 +65,21 @@ function WatchScope(scope) {
65
65
  watchState = parent;
66
66
  return value;
67
67
  }
68
+ function WatchFunction(func) {
69
+ const parent = watchState;
70
+ watchState = [[], null, null];
71
+ const async = (0, functions_1.IsAsync)(func);
72
+ const result = func();
73
+ let scope = null;
74
+ if (watchState[0].length > 0 || async) {
75
+ scope = ObservableScope.Create(func);
76
+ UpdateEmitters(scope, watchState[0]);
77
+ scope.calcScopes = watchState[2];
78
+ UpdateValue(scope, result);
79
+ }
80
+ watchState = parent;
81
+ return [async ? null : result, scope];
82
+ }
68
83
  function CalcScope(callback, idOverride) {
69
84
  if (watchState === null)
70
85
  return callback();
@@ -103,6 +118,10 @@ function CalcScope(callback, idOverride) {
103
118
  return scope;
104
119
  }
105
120
  ObservableScope.Create = Create;
121
+ function CreateIf(valueFunction) {
122
+ return WatchFunction(valueFunction);
123
+ }
124
+ ObservableScope.CreateIf = CreateIf;
106
125
  function Register(emitter) {
107
126
  if (watchState === null)
108
127
  return;
@@ -205,11 +224,11 @@ function OnSet(scope) {
205
224
  }
206
225
  DirtyScope(scope);
207
226
  }
208
- function UpdateValue(scope) {
227
+ function UpdateValue(scope, valueOverride = undefined) {
209
228
  if (!scope.dirty)
210
229
  return;
211
230
  scope.dirty = false;
212
- const value = WatchScope(scope);
231
+ const value = valueOverride === undefined ? WatchScope(scope) : valueOverride;
213
232
  if (scope.async) {
214
233
  scope.promise = value.then(function (result) {
215
234
  if (scope.destroyed)
@@ -248,11 +267,14 @@ function UpdateEmitters(scope, right) {
248
267
  function DestroyScope(scope) {
249
268
  if (!scope)
250
269
  return;
270
+ emitter_1.Emitter.Clear(scope.emitter);
251
271
  const scopes = scope.calcScopes && Object.values(scope.calcScopes);
252
272
  scopes && ObservableScope.DestroyAll(scopes);
253
273
  scope.calcScopes = null;
274
+ for (let x = 0; x < scope.emitters.length; x++)
275
+ emitter_1.Emitter.Remove(scope.emitters[x], scope.setCallback);
276
+ scope.calcScopes = null;
254
277
  scope.emitters = null;
255
- emitter_1.Emitter.Clear(scope.emitter);
256
278
  scope.emitter = null;
257
279
  scope.getFunction = null;
258
280
  scope.setCallback = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "j-templates",
3
- "version": "7.0.55",
3
+ "version": "7.0.57",
4
4
  "description": "j-templates",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/TypesInCode/jTemplates",