j-templates 7.0.52 → 7.0.54

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.
@@ -8,13 +8,14 @@ function CreateAssignment(target, createAssignment) {
8
8
  if (next === last)
9
9
  return;
10
10
  last = next;
11
- const nextKeys = next && Object.keys(next);
12
- for (let x = 0; nextKeys && x < nextKeys.length; x++) {
13
- const key = nextKeys[x];
14
- writeTo[key] ??= createAssignment(target, key);
11
+ for (const key in writeTo) {
12
+ writeTo[key](next);
13
+ }
14
+ for (const key in next) {
15
+ if (!Object.hasOwn(writeTo, key)) {
16
+ writeTo[key] = createAssignment(target, key);
17
+ writeTo[key](next);
18
+ }
15
19
  }
16
- const writeFunctions = Object.values(writeTo);
17
- for (let x = 0; x < writeFunctions.length; x++)
18
- writeFunctions[x](next);
19
20
  };
20
21
  }
@@ -1,4 +1 @@
1
1
  export declare function CreateEventAssignment(target: HTMLElement, event: string): (next: any) => void;
2
- export declare function AssignEvents(target: HTMLElement, eventMap: {
3
- [event: string]: any;
4
- }): void;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CreateEventAssignment = CreateEventAssignment;
4
- exports.AssignEvents = AssignEvents;
5
4
  function CreateEventAssignment(target, event) {
6
5
  let lastEvent;
7
6
  return function (next) {
@@ -13,8 +12,3 @@ function CreateEventAssignment(target, event) {
13
12
  lastEvent = nextEvent;
14
13
  };
15
14
  }
16
- function AssignEvents(target, eventMap) {
17
- const entries = Object.entries(eventMap);
18
- for (let x = 0; x < entries.length; x++)
19
- target.addEventListener(entries[x][0], entries[x][1]);
20
- }
@@ -1,7 +1 @@
1
- export declare function CreateNodeValueAssignment(target: HTMLElement): (value: string) => void;
2
- export declare function CreatePropertyAssignment(target: any): ((next: {
3
- nodeValue: string;
4
- }) => void) | ((next: {
5
- [prop: string]: any;
6
- }) => void);
7
- export declare function AssignProperties(target: any, next: any): void;
1
+ export declare function CreateRootPropertyAssignment(target: HTMLElement, property: string): (next: any) => void;
@@ -1,34 +1,65 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CreateNodeValueAssignment = CreateNodeValueAssignment;
4
- exports.CreatePropertyAssignment = CreatePropertyAssignment;
5
- exports.AssignProperties = AssignProperties;
3
+ exports.CreateRootPropertyAssignment = CreateRootPropertyAssignment;
6
4
  const json_1 = require("../Utils/json");
7
- function CreateNodeValueAssignment(target) {
8
- let lastValue = target.nodeValue;
9
- return function AssignNodeValue(value) {
10
- if (value !== lastValue) {
11
- target.nodeValue = value;
12
- lastValue = value;
5
+ const createAssignment_1 = require("./createAssignment");
6
+ function CreatePropertyAssignment(target, property) {
7
+ let lastValue;
8
+ let jsonType;
9
+ let childAssignment;
10
+ return function (next) {
11
+ const nextValue = next && next[property];
12
+ if (nextValue === lastValue)
13
+ return;
14
+ jsonType ??= (0, json_1.JsonType)(nextValue);
15
+ switch (jsonType) {
16
+ case "value":
17
+ target[property] = nextValue;
18
+ break;
19
+ default: {
20
+ const childTarget = target[property];
21
+ childAssignment ??= (0, createAssignment_1.CreateAssignment)(childTarget, CreateRootPropertyAssignment);
22
+ childAssignment(nextValue);
23
+ }
13
24
  }
14
25
  };
15
26
  }
16
- function WalkValue(next, callback, index = 0, parent = "") {
17
- const entries = Object.entries(next);
18
- for (let x = 0; x < entries.length; x++) {
19
- const [key, value] = entries[x];
20
- const type = (0, json_1.JsonType)(value);
21
- switch (type) {
22
- case "object":
23
- index = WalkValue(value, callback, index, `${parent}${key}.`);
27
+ function CreateRootPropertyAssignment(target, property) {
28
+ let lastValue;
29
+ let jsonType;
30
+ let childAssignment;
31
+ return function (next) {
32
+ const nextValue = next && next[property];
33
+ if (nextValue === lastValue)
34
+ return;
35
+ switch (property) {
36
+ case "nodeValue": {
37
+ AssignNodeValue(target, nextValue);
38
+ break;
39
+ }
40
+ case "className": {
41
+ AssignClassName(target, nextValue);
24
42
  break;
25
- default:
26
- callback(`${parent}${key}`, value, index);
27
- index++;
43
+ }
44
+ case "value": {
45
+ AssignValue(target, nextValue);
28
46
  break;
47
+ }
48
+ default: {
49
+ jsonType ??= (0, json_1.JsonType)(nextValue);
50
+ switch (jsonType) {
51
+ case "value":
52
+ target[property] = nextValue;
53
+ break;
54
+ default: {
55
+ const childTarget = target[property];
56
+ childAssignment ??= (0, createAssignment_1.CreateAssignment)(childTarget, CreatePropertyAssignment);
57
+ childAssignment(nextValue);
58
+ }
59
+ }
60
+ }
29
61
  }
30
- }
31
- return index;
62
+ };
32
63
  }
33
64
  function AssignNodeValue(target, value) {
34
65
  target.nodeValue = value;
@@ -43,53 +74,3 @@ function AssignValue(target, value) {
43
74
  function AssignClassName(target, value) {
44
75
  target.className = value;
45
76
  }
46
- function GetAssignmentFunction(path) {
47
- switch (path) {
48
- case "nodeValue":
49
- return AssignNodeValue;
50
- case "value":
51
- return AssignValue;
52
- case "className":
53
- return AssignClassName;
54
- default:
55
- return new Function("t", "v", `t.${path} = v;`);
56
- }
57
- }
58
- function CreatePropertyAssignment(target) {
59
- if (target.nodeType === Node.TEXT_NODE) {
60
- return function (next) {
61
- AssignNodeValue(target, next.nodeValue);
62
- };
63
- }
64
- const last = [
65
- ["", null, null],
66
- ];
67
- function WalkCallback(path, value, index) {
68
- if (index >= last.length || last[index][0] !== path) {
69
- last[index] = [path, value, GetAssignmentFunction(path)];
70
- last[index][2](target, value);
71
- }
72
- else if (last[index][1] !== value) {
73
- last[index][1] = value;
74
- last[index][2](target, value);
75
- }
76
- }
77
- return function AssignProperty(next) {
78
- if (next === null) {
79
- for (let x = 0; x < last.length; x++)
80
- last[x][2] !== null && last[x][2](target, null);
81
- if (last.length > 0)
82
- last.splice(0);
83
- return;
84
- }
85
- const endIndex = WalkValue(next, WalkCallback);
86
- if (endIndex < last.length)
87
- last.splice(endIndex);
88
- };
89
- }
90
- function AssignProperties(target, next) {
91
- WalkValue(next, function (path, value) {
92
- const assignment = GetAssignmentFunction(path);
93
- assignment(target, value);
94
- });
95
- }
@@ -1,2 +1,2 @@
1
- import { INodeConfig } from '../Node/nodeConfig';
1
+ import { INodeConfig } from "../Node/nodeConfig";
2
2
  export declare const DOMNodeConfig: INodeConfig;
@@ -6,7 +6,6 @@ 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");
10
9
  const createAttributeAssignment_1 = require("./createAttributeAssignment");
11
10
  let pendingUpdates = list_1.List.Create();
12
11
  let updateScheduled = false;
@@ -51,13 +50,13 @@ function wrapPriorityUpdates(callback) {
51
50
  }
52
51
  exports.DOMNodeConfig = {
53
52
  createNode(type, namespace) {
54
- if (type === 'text')
55
- return window_1.wndw.document.createTextNode('');
56
- return namespace ?
57
- window_1.wndw.document.createElementNS(namespace, type) :
58
- window_1.wndw.document.createElement(type);
53
+ if (type === "text")
54
+ return window_1.wndw.document.createTextNode("");
55
+ return namespace
56
+ ? window_1.wndw.document.createElementNS(namespace, type)
57
+ : window_1.wndw.document.createElement(type);
59
58
  },
60
- createTextNode(value = '') {
59
+ createTextNode(value = "") {
61
60
  return window_1.wndw.document.createTextNode(value);
62
61
  },
63
62
  isTextNode(target) {
@@ -98,9 +97,6 @@ exports.DOMNodeConfig = {
98
97
  remove(target) {
99
98
  target && target.parentNode && target.parentNode.removeChild(target);
100
99
  },
101
- createTextAssignment(target) {
102
- return (0, createPropertyAssignment_1.CreateNodeValueAssignment)(target);
103
- },
104
100
  setText(target, text) {
105
101
  target.nodeValue = text;
106
102
  },
@@ -111,17 +107,11 @@ exports.DOMNodeConfig = {
111
107
  target.setAttribute(attribute, value);
112
108
  },
113
109
  createPropertyAssignment(target) {
114
- return (0, createPropertyAssignment_2.CreatePropertyAssignment)(target);
115
- },
116
- assignProperties(target, next) {
117
- (0, createPropertyAssignment_1.AssignProperties)(target, next);
110
+ return (0, createAssignment_1.CreateAssignment)(target, createPropertyAssignment_1.CreateRootPropertyAssignment);
118
111
  },
119
112
  createEventAssignment(target) {
120
113
  return (0, createAssignment_1.CreateAssignment)(target, createEventAssignment_1.CreateEventAssignment);
121
114
  },
122
- assignEvents(target, next) {
123
- (0, createEventAssignment_1.AssignEvents)(target, next);
124
- },
125
115
  createAttributeAssignment(target) {
126
116
  return (0, createAssignment_1.CreateAssignment)(target, createAttributeAssignment_1.CreateAttributeAssignment);
127
117
  },
@@ -143,8 +133,15 @@ exports.DOMNodeConfig = {
143
133
  },
144
134
  reconcileChildren(target, children) {
145
135
  if (!target.firstChild) {
146
- for (let x = 0; x < children.length; x++)
147
- target.appendChild(children[x]);
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]);
148
145
  return;
149
146
  }
150
147
  if (children.length === 0) {
@@ -172,7 +169,14 @@ exports.DOMNodeConfig = {
172
169
  }
173
170
  while (target.lastChild !== children[x - 1])
174
171
  target.removeChild(target.lastChild);
175
- for (; x < children.length; x++)
176
- target.appendChild(children[x]);
177
- }
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]);
181
+ },
178
182
  };
@@ -20,19 +20,14 @@ export interface INodeConfig {
20
20
  removeChild(root: any, child: any): void;
21
21
  remove(target: any): void;
22
22
  fireEvent(target: any, event: string, data: any): void;
23
- createTextAssignment(target: any): {
24
- (next: string): void;
25
- };
26
23
  createPropertyAssignment(target: any): {
27
24
  (next: any): void;
28
25
  };
29
- assignProperties(target: any, next: any): void;
30
26
  createEventAssignment(target: any): {
31
27
  (next: {
32
28
  [event: string]: (event: Event) => void;
33
29
  }): void;
34
30
  };
35
- assignEvents(target: any, next: any): void;
36
31
  createAttributeAssignment(target: any): {
37
32
  (next: {
38
33
  [attribute: string]: string;
package/Node/vNode.d.ts CHANGED
@@ -10,6 +10,7 @@ type vNodeConfig<P = HTMLElement, E = HTMLElementEventMap, T = never> = {
10
10
  };
11
11
  export declare namespace vNode {
12
12
  function Create<P = HTMLElement, E = HTMLElementEventMap, T = never>(definition: vNodeDefinition<P, E, T>): vNodeType;
13
+ function CreateText(text: string): vNodeType;
13
14
  function Init(vnode: vNodeType): void;
14
15
  function InitAll(vnodes: vNodeType[]): void;
15
16
  function Destroy(vnode: vNodeType): void;
package/Node/vNode.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.vNode = void 0;
4
4
  const Store_1 = require("../Store");
5
+ const emitter_1 = require("../Utils/emitter");
5
6
  const injector_1 = require("../Utils/injector");
6
7
  const list_1 = require("../Utils/list");
7
8
  const thread_1 = require("../Utils/thread");
@@ -16,11 +17,26 @@ var vNode;
16
17
  node: definition.node ?? null,
17
18
  children: null,
18
19
  destroyed: false,
20
+ onDestroyed: null,
19
21
  component: null,
20
22
  scopes: [],
21
23
  };
22
24
  }
23
25
  vNode.Create = Create;
26
+ function CreateText(text) {
27
+ return {
28
+ definition: null,
29
+ type: "text",
30
+ injector: null,
31
+ node: nodeConfig_1.NodeConfig.createTextNode(text),
32
+ children: null,
33
+ destroyed: false,
34
+ onDestroyed: null,
35
+ component: null,
36
+ scopes: [],
37
+ };
38
+ }
39
+ vNode.CreateText = CreateText;
24
40
  function Init(vnode) {
25
41
  if (vnode.definition === null)
26
42
  return;
@@ -38,6 +54,7 @@ var vNode;
38
54
  vnode.destroyed = true;
39
55
  vnode.component?.Destroy();
40
56
  Store_1.ObservableScope.DestroyAll(vnode.scopes);
57
+ vnode.onDestroyed && emitter_1.Emitter.Emit(vnode.onDestroyed);
41
58
  vnode.children && DestroyAll(vnode.children);
42
59
  }
43
60
  vNode.Destroy = Destroy;
@@ -70,7 +87,8 @@ var vNode;
70
87
  })(vNode || (exports.vNode = vNode = {}));
71
88
  function InitNode(vnode) {
72
89
  const { type, namespace, props, attrs, on, data, componentConstructor, children, childrenArray, } = vnode.definition;
73
- const node = (vnode.node = vnode.definition.node ?? nodeConfig_1.NodeConfig.createNode(type, namespace));
90
+ const node = (vnode.node =
91
+ vnode.definition.node ?? nodeConfig_1.NodeConfig.createNode(type, namespace));
74
92
  vnode.definition = null;
75
93
  if (props) {
76
94
  const assignProperties = nodeConfig_1.NodeConfig.createPropertyAssignment(node);
@@ -95,6 +113,11 @@ function InitNode(vnode) {
95
113
  }
96
114
  else
97
115
  assignEvents(on);
116
+ vnode.onDestroyed ??= emitter_1.Emitter.Create();
117
+ emitter_1.Emitter.On(vnode.onDestroyed, function () {
118
+ assignEvents(null);
119
+ return true;
120
+ });
98
121
  }
99
122
  if (attrs) {
100
123
  const assignAttributes = nodeConfig_1.NodeConfig.createAttributeAssignment(node);
@@ -112,7 +135,9 @@ function InitNode(vnode) {
112
135
  vnode.component = new componentConstructor(vnode);
113
136
  vnode.component.Bound();
114
137
  const componentScope = Store_1.ObservableScope.Create(function () {
115
- let nodes = injector_1.Injector.Scope(vnode.injector, function () { return vnode.component.Template(); });
138
+ let nodes = injector_1.Injector.Scope(vnode.injector, function () {
139
+ return vnode.component.Template();
140
+ });
116
141
  if (!Array.isArray(nodes))
117
142
  nodes = [nodes];
118
143
  return nodes;
@@ -144,8 +169,9 @@ function Children(vnode, children, data) {
144
169
  Store_1.ObservableScope.Watch(childrenScope, CreateScheduledCallback(function (scope) {
145
170
  if (vnode.destroyed)
146
171
  return;
172
+ const startChildren = vnode.children;
147
173
  AssignChildren(vnode, scope);
148
- UpdateChildren(vnode);
174
+ startChildren !== vnode.children && UpdateChildren(vnode);
149
175
  }));
150
176
  AssignChildren(vnode, childrenScope);
151
177
  }
@@ -166,6 +192,7 @@ function CreateChildrenScope(vnode, children, data) {
166
192
  Store_1.ObservableScope.OnDestroyed(scope, function () {
167
193
  DestroyNodeList(nodeList);
168
194
  Store_1.ObservableScope.Destroy(dataScope);
195
+ return true;
169
196
  });
170
197
  return scope;
171
198
  }
@@ -209,7 +236,7 @@ function WrapChildren(injector, children, data, nodeList) {
209
236
  list_1.List.Add(nextNodeList, {
210
237
  data,
211
238
  nodes: Store_1.ObservableScope.Value(childrenScope),
212
- scope: childrenScope
239
+ scope: childrenScope,
213
240
  });
214
241
  }
215
242
  nextNodeArray.push(...nextNodeList.tail.data.nodes);
@@ -225,14 +252,21 @@ function WrapChildren(injector, children, data, nodeList) {
225
252
  function CreateNodeArray(children, previousChildren) {
226
253
  if (Array.isArray(children))
227
254
  return children;
228
- return typeof children === 'string' ? [vNode.Create({
229
- type: 'text',
230
- namespace: null,
231
- node: previousChildren?.[0]?.type === 'text' && previousChildren[0].node || undefined,
232
- props: {
233
- nodeValue: children
234
- }
235
- })] : [children];
255
+ if (typeof children === "string") {
256
+ const firstPrevChild = previousChildren?.[0];
257
+ if (firstPrevChild &&
258
+ firstPrevChild.node &&
259
+ firstPrevChild.type === "text") {
260
+ nodeConfig_1.NodeConfig.setText(firstPrevChild.node, children);
261
+ return previousChildren.length === 1
262
+ ? previousChildren
263
+ : [firstPrevChild];
264
+ }
265
+ return [
266
+ vNode.CreateText(children),
267
+ ];
268
+ }
269
+ return [children];
236
270
  }
237
271
  function DestroyNodeList(nodeList) {
238
272
  for (let node = nodeList.head; node !== null; node = node.next) {
@@ -251,6 +285,10 @@ function AssignChildren(vnode, childrenScope) {
251
285
  function UpdateChildren(vnode, init = false, skipInit = false) {
252
286
  if (!vnode.children)
253
287
  return;
288
+ if (vnode.children.length === 1 && vnode.children[0].type === "text") {
289
+ nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, [vnode.children[0].node]);
290
+ return;
291
+ }
254
292
  const children = vnode.children;
255
293
  (0, thread_1.Thread)(function () {
256
294
  if (vnode.destroyed || children !== vnode.children)
@@ -2,6 +2,7 @@ import { Component } from "./component";
2
2
  import { IObservableScope } from "../Store/Tree/observableScope";
3
3
  import { Injector } from "../Utils/injector";
4
4
  import { RecursivePartial } from "../Utils/utils.types";
5
+ import { Emitter } from "../Utils/emitter";
5
6
  export type FunctionOr<T> = {
6
7
  (): T | Promise<T>;
7
8
  } | T;
@@ -20,6 +21,7 @@ export type vNode = {
20
21
  node: Node | null;
21
22
  children: vNode[] | null;
22
23
  destroyed: boolean;
24
+ onDestroyed: Emitter | null;
23
25
  scopes: IObservableScope<unknown>[];
24
26
  component: Component;
25
27
  };
@@ -24,10 +24,6 @@ export declare class ObservableScope<T> extends ObservableScopeWrapper<T> {
24
24
  (): T | Promise<T>;
25
25
  });
26
26
  }
27
- interface ICalcObservable<T> {
28
- id: string;
29
- scope: IObservableScope<T>;
30
- }
31
27
  export interface IObservableScope<T> extends IDestroyable {
32
28
  getFunction: {
33
29
  (): T;
@@ -39,12 +35,14 @@ export interface IObservableScope<T> extends IDestroyable {
39
35
  dirty: boolean;
40
36
  emitter: Emitter;
41
37
  emitters: (Emitter | null)[];
42
- calcScopes: ICalcObservable<unknown>[] | null;
38
+ calcScopes: {
39
+ [id: string]: IObservableScope<unknown> | null;
40
+ } | null;
43
41
  calc: boolean;
44
42
  onDestroyed: Emitter | null;
45
43
  destroyed: boolean;
46
44
  }
47
- export declare function CalcScope<T>(callback: () => T): any;
45
+ export declare function CalcScope<T>(callback: () => T, idOverride?: string): unknown;
48
46
  export declare namespace ObservableScope {
49
47
  function Create<T>(valueFunction: {
50
48
  (): T | Promise<T>;
@@ -56,9 +54,8 @@ export declare namespace ObservableScope {
56
54
  function Touch<T>(scope: IObservableScope<T>): void;
57
55
  function Watch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T>]>): void;
58
56
  function Unwatch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T> | ObservableScopeValue<T>]>): void;
59
- function OnDestroyed(scope: IObservableScope<unknown>, callback: () => void): void;
57
+ function OnDestroyed(scope: IObservableScope<unknown>, callback: EmitterCallback): void;
60
58
  function Update(scope: IObservableScope<any>): void;
61
59
  function Destroy<T>(scope: IObservableScope<T>): void;
62
60
  function DestroyAll(scopes: IObservableScope<unknown>[]): void;
63
61
  }
64
- export {};
@@ -56,34 +56,31 @@ function WatchScope(scope) {
56
56
  const emitters = watchState[0];
57
57
  UpdateEmitters(scope, emitters);
58
58
  const calcScopes = watchState[1];
59
- for (let x = 0; calcScopes && x < calcScopes.length; x++)
60
- ObservableScope.Destroy(calcScopes[x]?.scope);
59
+ if (calcScopes) {
60
+ const calcScopeValues = Object.values(calcScopes);
61
+ for (let x = 0; x < calcScopeValues.length; x++)
62
+ calcScopeValues[x] && ObservableScope.Destroy(calcScopeValues[x]);
63
+ }
61
64
  scope.calcScopes = watchState[2];
62
65
  watchState = parent;
63
66
  return value;
64
67
  }
65
- function CalcScope(callback) {
68
+ function CalcScope(callback, idOverride) {
66
69
  if (watchState === null)
67
70
  return callback();
68
- watchState[2] ??= [];
71
+ const nextScopes = (watchState[2] ??= {});
69
72
  const currentScopes = watchState[1];
70
- const id = callback.toString();
71
- if (currentScopes !== null) {
72
- let index = 0;
73
- for (; currentScopes[index].id !== id; index++) { }
74
- if (index < currentScopes.length) {
75
- const scope = currentScopes[index];
76
- currentScopes[index] = null;
77
- watchState[2].push(scope);
78
- return ObservableScope.Value(scope.scope);
79
- }
73
+ const id = idOverride ?? callback.toString();
74
+ const currentScope = currentScopes?.[id];
75
+ if (currentScope) {
76
+ delete currentScopes[id];
77
+ nextScopes[id] = currentScope;
80
78
  }
81
- const scope = ObservableScope.Create(callback, true);
82
- watchState[2].push({
83
- id,
84
- scope,
85
- });
86
- return ObservableScope.Value(scope);
79
+ else if (!nextScopes[id]) {
80
+ const scope = ObservableScope.Create(callback, true);
81
+ nextScopes[id] = scope;
82
+ }
83
+ return ObservableScope.Value(nextScopes[id]);
87
84
  }
88
85
  (function (ObservableScope) {
89
86
  function Create(valueFunction, calc = false) {
@@ -174,17 +171,13 @@ function CalcScope(callback) {
174
171
  function DirtyScope(scope) {
175
172
  if (scope.dirty || !scope.getFunction)
176
173
  return;
177
- if (scope.calc) {
178
- const startVal = scope.value;
179
- scope.dirty = true;
180
- UpdateValue(scope);
181
- if (startVal !== scope.value)
182
- emitter_1.Emitter.Emit(scope.emitter);
183
- return;
184
- }
185
174
  scope.dirty = true;
186
- if (scope.async) {
175
+ if (scope.async)
176
+ UpdateValue(scope);
177
+ else if (scope.calc) {
178
+ const startValue = scope.value;
187
179
  UpdateValue(scope);
180
+ startValue !== scope.value && emitter_1.Emitter.Emit(scope.emitter, scope);
188
181
  }
189
182
  else
190
183
  emitter_1.Emitter.Emit(scope.emitter, scope);
@@ -255,12 +248,14 @@ function UpdateEmitters(scope, right) {
255
248
  function DestroyScope(scope) {
256
249
  if (!scope)
257
250
  return;
251
+ const scopes = scope.calcScopes && Object.values(scope.calcScopes);
252
+ scopes && ObservableScope.DestroyAll(scopes);
253
+ scope.calcScopes = null;
258
254
  scope.emitters = null;
255
+ emitter_1.Emitter.Clear(scope.emitter);
259
256
  scope.emitter = null;
260
257
  scope.getFunction = null;
261
258
  scope.setCallback = null;
262
- for (let x = 0; scope.calcScopes && x < scope.calcScopes.length; x++)
263
- ObservableScope.Destroy(scope.calcScopes[x].scope);
264
259
  scope.destroyed = true;
265
- scope.onDestroyed !== null && emitter_1.Emitter.Emit(scope.onDestroyed);
260
+ scope.onDestroyed && emitter_1.Emitter.Emit(scope.onDestroyed);
266
261
  }
package/Utils/array.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export declare function RemoveNulls(array: (unknown | null)[], startIndex?: number): void;
2
2
  export declare function ArrayDiff(source: any[], target: any[]): boolean;
3
3
  export declare function ReconcileSortedEmitters<T extends [number]>(left: T[], right: T[], add: (value: T) => void, remove: (value: T) => void): void;
4
+ export declare function InsertionSortTuples<T extends [number, ...any[]]>(arr: T[]): T[];
4
5
  export declare function ReconcileSortedArrays<T>(left: T[], right: T[], add: (value: T) => void, remove: (value: T) => void): void;
package/Utils/array.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RemoveNulls = RemoveNulls;
4
4
  exports.ArrayDiff = ArrayDiff;
5
5
  exports.ReconcileSortedEmitters = ReconcileSortedEmitters;
6
+ exports.InsertionSortTuples = InsertionSortTuples;
6
7
  exports.ReconcileSortedArrays = ReconcileSortedArrays;
7
8
  function RemoveNulls(array, startIndex = 0) {
8
9
  let nullIndex = startIndex;
@@ -50,6 +51,19 @@ function ReconcileSortedEmitters(left, right, add, remove) {
50
51
  for (let ri = rightIndex; ri < right.length; ri++)
51
52
  add(right[ri]);
52
53
  }
54
+ function InsertionSortTuples(arr) {
55
+ const n = arr.length;
56
+ for (let i = 1; i < n; i++) {
57
+ const currentItem = arr[i];
58
+ let j = i - 1;
59
+ while (j >= 0 && arr[j][0] > currentItem[0]) {
60
+ arr[j + 1] = arr[j];
61
+ j--;
62
+ }
63
+ arr[j + 1] = currentItem;
64
+ }
65
+ return arr;
66
+ }
53
67
  function ReconcileSortedArrays(left, right, add, remove) {
54
68
  let leftIndex = 0;
55
69
  let rightIndex = 0;
@@ -8,6 +8,6 @@ export declare namespace Emitter {
8
8
  function Remove(emitter: Emitter, callback: EmitterCallback): void;
9
9
  function Clear(emitter: Emitter): void;
10
10
  function Distinct(emitters: Emitter[]): void;
11
- function Sort(emitters: Emitter[]): Emitter[];
11
+ function Sort(emitters: Emitter[]): void;
12
12
  function Compare(a: Emitter, b: Emitter): number;
13
13
  }
package/Utils/emitter.js CHANGED
@@ -19,15 +19,14 @@ var Emitter;
19
19
  }
20
20
  Emitter.On = On;
21
21
  function Emit(emitter, ...args) {
22
- let removed = false;
22
+ let writePos = 1;
23
23
  for (let x = 1; x < emitter.length; x++) {
24
- if (emitter[x] === null || emitter[x](...args) === true) {
25
- removed = true;
26
- emitter[x] = null;
27
- }
24
+ if (emitter[x] !== null &&
25
+ emitter[x](...args) !== true)
26
+ emitter[writePos++] = emitter[x];
28
27
  }
29
- if (removed)
30
- (0, array_1.RemoveNulls)(emitter);
28
+ if (writePos < emitter.length)
29
+ emitter.splice(writePos);
31
30
  }
32
31
  Emitter.Emit = Emit;
33
32
  function Remove(emitter, callback) {
@@ -41,42 +40,41 @@ var Emitter;
41
40
  }
42
41
  Emitter.Clear = Clear;
43
42
  function Distinct(emitters) {
44
- if (emitters.length === 1)
43
+ if (emitters.length < 2)
45
44
  return;
46
- emitters.length < 50 ? DistinctSmall(emitters) : DistinctLarge(emitters);
45
+ emitters.length < 51 ? DistinctSmall(emitters) : DistinctLarge(emitters);
47
46
  }
48
47
  Emitter.Distinct = Distinct;
49
48
  function DistinctSmall(emitters) {
50
49
  Sort(emitters);
51
- let lastId = -1;
52
- let remove = false;
53
- for (let x = 0; x < emitters.length; x++) {
54
- const id = emitters[x][0];
55
- if (lastId === emitters[x][0]) {
56
- emitters[x] = null;
57
- remove = true;
50
+ let writePos = 1;
51
+ for (let x = 1; x < emitters.length; x++) {
52
+ if (emitters[x][0] !== emitters[writePos - 1][0]) {
53
+ emitters[writePos++] = emitters[x];
58
54
  }
59
- lastId = id;
60
55
  }
61
- remove && (0, array_1.RemoveNulls)(emitters);
56
+ if (writePos < emitters.length)
57
+ emitters.splice(writePos);
62
58
  }
63
59
  function DistinctLarge(emitters) {
64
- let remove = false;
60
+ let writePos = 0;
65
61
  const ids = new Set();
66
62
  for (let x = 0; x < emitters.length; x++) {
67
63
  const id = emitters[x][0];
68
- if (!ids.has(id))
64
+ if (!ids.has(id)) {
69
65
  ids.add(id);
70
- else {
71
- emitters[x] = null;
72
- remove = true;
66
+ emitters[writePos++] = emitters[x];
73
67
  }
74
68
  }
75
- remove && (0, array_1.RemoveNulls)(emitters);
69
+ if (writePos < emitters.length)
70
+ emitters.splice(writePos);
76
71
  Sort(emitters);
77
72
  }
78
73
  function Sort(emitters) {
79
- return emitters.sort(Compare);
74
+ if (emitters.length < 11)
75
+ (0, array_1.InsertionSortTuples)(emitters);
76
+ else
77
+ emitters.sort(Compare);
80
78
  }
81
79
  Emitter.Sort = Sort;
82
80
  function Compare(a, b) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "j-templates",
3
- "version": "7.0.52",
3
+ "version": "7.0.54",
4
4
  "description": "j-templates",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/TypesInCode/jTemplates",