j-templates 7.0.52 → 7.0.53

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,2 @@
1
- import { INodeConfig } from '../Node/nodeConfig';
1
+ import { INodeConfig } from "../Node/nodeConfig";
2
2
  export declare const DOMNodeConfig: INodeConfig;
@@ -51,13 +51,13 @@ function wrapPriorityUpdates(callback) {
51
51
  }
52
52
  exports.DOMNodeConfig = {
53
53
  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);
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);
59
59
  },
60
- createTextNode(value = '') {
60
+ createTextNode(value = "") {
61
61
  return window_1.wndw.document.createTextNode(value);
62
62
  },
63
63
  isTextNode(target) {
@@ -143,8 +143,15 @@ exports.DOMNodeConfig = {
143
143
  },
144
144
  reconcileChildren(target, children) {
145
145
  if (!target.firstChild) {
146
- for (let x = 0; x < children.length; x++)
147
- target.appendChild(children[x]);
146
+ if (children.length > 10) {
147
+ const fragment = new DocumentFragment();
148
+ for (let x = 0; x < children.length; x++)
149
+ fragment.appendChild(children[x]);
150
+ target.appendChild(fragment);
151
+ }
152
+ else
153
+ for (let x = 0; x < children.length; x++)
154
+ target.appendChild(children[x]);
148
155
  return;
149
156
  }
150
157
  if (children.length === 0) {
@@ -172,7 +179,14 @@ exports.DOMNodeConfig = {
172
179
  }
173
180
  while (target.lastChild !== children[x - 1])
174
181
  target.removeChild(target.lastChild);
175
- for (; x < children.length; x++)
176
- target.appendChild(children[x]);
177
- }
182
+ if (children.length - x > 10) {
183
+ const fragment = new DocumentFragment();
184
+ for (; x < children.length; x++)
185
+ fragment.appendChild(children[x]);
186
+ target.appendChild(fragment);
187
+ }
188
+ else
189
+ for (; x < children.length; x++)
190
+ target.appendChild(children[x]);
191
+ },
178
192
  };
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,29 @@ 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
+ const calcScopeValues = calcScopes && Object.values(calcScopes);
60
+ for (let x = 0; calcScopeValues && x < calcScopeValues.length; x++)
61
+ calcScopeValues[x] && ObservableScope.Destroy(calcScopeValues[x]);
61
62
  scope.calcScopes = watchState[2];
62
63
  watchState = parent;
63
64
  return value;
64
65
  }
65
- function CalcScope(callback) {
66
+ function CalcScope(callback, idOverride) {
66
67
  if (watchState === null)
67
68
  return callback();
68
- watchState[2] ??= [];
69
+ const nextScopes = (watchState[2] ??= {});
69
70
  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
- }
71
+ const id = idOverride ?? callback.toString();
72
+ const currentScope = currentScopes?.[id];
73
+ if (currentScope) {
74
+ delete currentScopes[id];
75
+ nextScopes[id] = currentScope;
80
76
  }
81
- const scope = ObservableScope.Create(callback, true);
82
- watchState[2].push({
83
- id,
84
- scope,
85
- });
86
- return ObservableScope.Value(scope);
77
+ else if (!nextScopes[id]) {
78
+ const scope = ObservableScope.Create(callback, true);
79
+ nextScopes[id] = scope;
80
+ }
81
+ return ObservableScope.Value(nextScopes[id]);
87
82
  }
88
83
  (function (ObservableScope) {
89
84
  function Create(valueFunction, calc = false) {
@@ -174,17 +169,13 @@ function CalcScope(callback) {
174
169
  function DirtyScope(scope) {
175
170
  if (scope.dirty || !scope.getFunction)
176
171
  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
172
  scope.dirty = true;
186
- if (scope.async) {
173
+ if (scope.async)
174
+ UpdateValue(scope);
175
+ else if (scope.calc) {
176
+ const startValue = scope.value;
187
177
  UpdateValue(scope);
178
+ startValue !== scope.value && emitter_1.Emitter.Emit(scope.emitter);
188
179
  }
189
180
  else
190
181
  emitter_1.Emitter.Emit(scope.emitter, scope);
@@ -255,12 +246,14 @@ function UpdateEmitters(scope, right) {
255
246
  function DestroyScope(scope) {
256
247
  if (!scope)
257
248
  return;
249
+ const scopes = scope.calcScopes && Object.values(scope.calcScopes);
250
+ scopes && ObservableScope.DestroyAll(scopes);
251
+ scope.calcScopes = null;
258
252
  scope.emitters = null;
253
+ emitter_1.Emitter.Clear(scope.emitter);
259
254
  scope.emitter = null;
260
255
  scope.getFunction = null;
261
256
  scope.setCallback = null;
262
- for (let x = 0; scope.calcScopes && x < scope.calcScopes.length; x++)
263
- ObservableScope.Destroy(scope.calcScopes[x].scope);
264
257
  scope.destroyed = true;
265
- scope.onDestroyed !== null && emitter_1.Emitter.Emit(scope.onDestroyed);
258
+ scope.onDestroyed && emitter_1.Emitter.Emit(scope.onDestroyed);
266
259
  }
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
@@ -21,7 +21,8 @@ var Emitter;
21
21
  function Emit(emitter, ...args) {
22
22
  let removed = false;
23
23
  for (let x = 1; x < emitter.length; x++) {
24
- if (emitter[x] === null || emitter[x](...args) === true) {
24
+ if (emitter[x] === null ||
25
+ emitter[x](...args) === true) {
25
26
  removed = true;
26
27
  emitter[x] = null;
27
28
  }
@@ -41,16 +42,16 @@ var Emitter;
41
42
  }
42
43
  Emitter.Clear = Clear;
43
44
  function Distinct(emitters) {
44
- if (emitters.length === 1)
45
+ if (emitters.length < 2)
45
46
  return;
46
- emitters.length < 50 ? DistinctSmall(emitters) : DistinctLarge(emitters);
47
+ emitters.length < 51 ? DistinctSmall(emitters) : DistinctLarge(emitters);
47
48
  }
48
49
  Emitter.Distinct = Distinct;
49
50
  function DistinctSmall(emitters) {
50
51
  Sort(emitters);
51
- let lastId = -1;
52
+ let lastId = emitters[0][0];
52
53
  let remove = false;
53
- for (let x = 0; x < emitters.length; x++) {
54
+ for (let x = 1; x < emitters.length; x++) {
54
55
  const id = emitters[x][0];
55
56
  if (lastId === emitters[x][0]) {
56
57
  emitters[x] = null;
@@ -76,7 +77,10 @@ var Emitter;
76
77
  Sort(emitters);
77
78
  }
78
79
  function Sort(emitters) {
79
- return emitters.sort(Compare);
80
+ if (emitters.length < 11)
81
+ (0, array_1.InsertionSortTuples)(emitters);
82
+ else
83
+ emitters.sort(Compare);
80
84
  }
81
85
  Emitter.Sort = Sort;
82
86
  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.53",
4
4
  "description": "j-templates",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/TypesInCode/jTemplates",