j-templates 5.0.47 → 5.0.49

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.
@@ -78,5 +78,14 @@ exports.DOMNodeConfig = {
78
78
  var cEvent = new CustomEvent(event, data);
79
79
  target.dispatchEvent(cEvent);
80
80
  },
81
- setProperties: utils_1.SetProperties
81
+ setProperties: utils_1.SetProperties,
82
+ getFirstChild(target) {
83
+ return target.firstChild;
84
+ },
85
+ getNextSibling(target) {
86
+ return target.nextSibling;
87
+ },
88
+ replaceChildren(target, children) {
89
+ target.replaceChildren(...children);
90
+ },
82
91
  };
@@ -8,6 +8,7 @@ const component_1 = require("./component");
8
8
  const injector_1 = require("../Utils/injector");
9
9
  const decorators_1 = require("../Utils/decorators");
10
10
  const thread_1 = require("../Utils/thread");
11
+ const list_1 = require("../Utils/list");
11
12
  var ComponentNode;
12
13
  (function (ComponentNode) {
13
14
  function Fire(event, data) {
@@ -55,7 +56,7 @@ function AddPreReqTemplate(node) {
55
56
  (0, thread_1.Schedule)(function () {
56
57
  if (node.destroyed)
57
58
  return;
58
- nodeRef_1.NodeRef.InitAll(preNodes);
59
+ nodeRef_1.NodeRef.InitAll(node, preNodes);
59
60
  });
60
61
  (0, thread_1.Thread)(function () {
61
62
  if (node.destroyed)
@@ -91,20 +92,24 @@ function AddTemplate(node, init) {
91
92
  return;
92
93
  const nodes = injector_1.Injector.Scope(node.injector, InvokeNodeTemplate, node);
93
94
  (0, thread_1.Schedule)(function () {
94
- nodeRef_1.NodeRef.InitAll(nodes);
95
+ nodeRef_1.NodeRef.InitAll(node, nodes);
95
96
  });
96
97
  (0, thread_1.Thread)(function () {
97
98
  if (node.destroyed)
98
99
  return;
100
+ const list = list_1.List.Create();
101
+ list_1.List.Add(list, {
102
+ value: undefined,
103
+ init: true,
104
+ nodes
105
+ });
99
106
  if (init)
100
- for (var x = 0; x < nodes.length; x++)
101
- nodeRef_1.NodeRef.AddChild(node, nodes[x]);
107
+ nodeRef_1.NodeRef.ReconcileChildren(node, list);
102
108
  else
103
109
  nodeConfig_1.NodeConfig.scheduleUpdate(function () {
104
110
  if (node.destroyed)
105
111
  return;
106
- for (var x = 0; x < nodes.length; x++)
107
- nodeRef_1.NodeRef.AddChild(node, nodes[x]);
112
+ nodeRef_1.NodeRef.ReconcileChildren(node, list);
108
113
  });
109
114
  });
110
115
  if (node.component.Bound !== component_1.Component.prototype.Bound)
@@ -1,4 +1,4 @@
1
- import { ElementNodeFunctionParam, ElementChildrenFunction, IElementNode, IElementNodeBase } from "./elementNode.types";
1
+ import { ElementChildrenFunction, ElementNodeFunctionParam, IElementNode, IElementNodeBase } from "./elementNode.types";
2
2
  export declare namespace ElementNode {
3
3
  function Create<T>(type: any, namespace: string, nodeDef: ElementNodeFunctionParam<T>, children: ElementChildrenFunction<T>): IElementNode<T>;
4
4
  function Init<T>(elementNode: IElementNodeBase<T>): void;
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ElementNode = void 0;
4
- const boundNode_1 = require("./boundNode");
5
- const nodeConfig_1 = require("./nodeConfig");
4
+ const observableScope_1 = require("../Store/Tree/observableScope");
6
5
  const injector_1 = require("../Utils/injector");
7
6
  const list_1 = require("../Utils/list");
8
7
  const thread_1 = require("../Utils/thread");
8
+ const boundNode_1 = require("./boundNode");
9
+ const nodeConfig_1 = require("./nodeConfig");
9
10
  const nodeRef_1 = require("./nodeRef");
10
- const observableScope_1 = require("../Store/Tree/observableScope");
11
11
  var ElementNode;
12
12
  (function (ElementNode) {
13
13
  function Create(type, namespace, nodeDef, children) {
@@ -63,79 +63,97 @@ function SetDefaultData(node) {
63
63
  (0, thread_1.Synch)(function () {
64
64
  const nodes = injector_1.Injector.Scope(node.injector, CreateNodeArray, node.childrenFunc, true);
65
65
  if (nodes.length > 0) {
66
- nodeRef_1.NodeRef.InitAll(nodes);
66
+ nodeRef_1.NodeRef.InitAll(node, nodes);
67
67
  (0, thread_1.Thread)(function () {
68
68
  if (node.destroyed)
69
69
  return;
70
- DetachAndAddNodes(node, [], [nodes]);
70
+ const defaultNodeList = list_1.List.Create();
71
+ list_1.List.Add(defaultNodeList, {
72
+ value: null,
73
+ init: true,
74
+ nodes
75
+ });
76
+ nodeRef_1.NodeRef.ReconcileChildren(node, defaultNodeList);
71
77
  });
72
78
  }
73
79
  });
74
80
  }
75
- function SetData(node, values, init = false) {
76
- (0, thread_1.Synch)(function () {
77
- const newNodesMap = new Map();
78
- const newNodesArrays = new Array(values.length);
79
- for (let x = 0; x < values.length; x++) {
80
- const value = values[x];
81
- let nodes;
82
- if (node.nodesMap) {
83
- let nodeArrayList = node.nodesMap.get(value);
84
- nodes = nodeArrayList && list_1.List.Remove(nodeArrayList);
85
- }
86
- let newNodeArrayList = newNodesMap.get(value);
87
- if (!newNodeArrayList) {
88
- newNodeArrayList = list_1.List.Create();
89
- newNodesMap.set(value, newNodeArrayList);
90
- }
91
- if (!nodes) {
92
- nodes = injector_1.Injector.Scope(node.injector, CreateNodeArray, node.childrenFunc, value);
93
- (0, thread_1.Schedule)(function () {
94
- if (node.destroyed || newNodesMap.size === 0)
95
- return;
96
- nodeRef_1.NodeRef.InitAll(nodes);
97
- list_1.List.Push(newNodeArrayList, nodes);
98
- });
81
+ function GetDataValue(data) {
82
+ return data.value;
83
+ }
84
+ function ReconcileNodeData(node, values) {
85
+ const nextNodeList = list_1.List.Create();
86
+ const initNodeList = list_1.List.Create();
87
+ const currentNodeList = node.nodeList;
88
+ const nodeMap = currentNodeList && list_1.List.ToNodeMap(currentNodeList, GetDataValue);
89
+ for (let x = 0; x < values.length; x++) {
90
+ let curNode;
91
+ if (nodeMap) {
92
+ const nodeArr = nodeMap.get(values[x]);
93
+ if (nodeArr) {
94
+ let y = nodeArr.length - 1;
95
+ for (; y >= 0 && !curNode; y--) {
96
+ curNode = nodeArr[y];
97
+ nodeArr[y] = null;
98
+ }
99
99
  }
100
- else
101
- list_1.List.Push(newNodeArrayList, nodes);
102
- newNodesArrays[x] = nodes;
103
100
  }
104
- var detachNodes = [];
105
- if (node.nodesMap) {
106
- for (var nodeArrayList of node.nodesMap.values())
107
- nodeArrayList.size > 0 && detachNodes.push(DestroyNodeArrayList(nodeArrayList));
108
- node.nodesMap.clear();
101
+ if (curNode) {
102
+ list_1.List.RemoveNode(currentNodeList, curNode);
103
+ list_1.List.AddNode(nextNodeList, curNode);
104
+ if (!curNode.data.init)
105
+ list_1.List.Add(initNodeList, curNode.data);
109
106
  }
110
- node.nodesMap = newNodesMap;
107
+ else {
108
+ curNode = list_1.List.Add(nextNodeList, {
109
+ value: values[x],
110
+ init: false,
111
+ nodes: injector_1.Injector.Scope(node.injector, CreateNodeArray, node.childrenFunc, values[x])
112
+ });
113
+ list_1.List.Add(initNodeList, curNode.data);
114
+ }
115
+ }
116
+ let curNode = initNodeList.head;
117
+ while (curNode) {
118
+ const data = curNode.data;
119
+ (0, thread_1.Schedule)(function () {
120
+ if (node.destroyed || nextNodeList.size === 0)
121
+ return;
122
+ nodeRef_1.NodeRef.InitAll(node, data.nodes);
123
+ data.init = true;
124
+ });
125
+ curNode = curNode.next;
126
+ }
127
+ if (currentNodeList) {
128
+ let curDetach = currentNodeList.head;
129
+ while (curDetach) {
130
+ nodeRef_1.NodeRef.DestroyAll(curDetach.data.nodes);
131
+ for (let x = 0; x < curDetach.data.nodes.length; x++)
132
+ node.childNodes.delete(curDetach.data.nodes[x]);
133
+ curDetach = curDetach.next;
134
+ }
135
+ list_1.List.Clear(currentNodeList);
136
+ }
137
+ node.nodeList = nextNodeList;
138
+ }
139
+ function SetData(node, values, init = false) {
140
+ (0, thread_1.Synch)(function () {
141
+ ReconcileNodeData(node, values);
142
+ const attachNodes = node.nodeList;
111
143
  (0, thread_1.Thread)(function () {
112
144
  if (node.destroyed)
113
145
  return;
114
146
  if (init)
115
- DetachAndAddNodes(node, detachNodes, newNodesMap.size > 0 && newNodesArrays);
147
+ nodeRef_1.NodeRef.ReconcileChildren(node, attachNodes);
116
148
  else
117
149
  nodeConfig_1.NodeConfig.scheduleUpdate(function () {
118
- if (node.destroyed)
150
+ if (node.destroyed || attachNodes.size < node.childNodes.size)
119
151
  return;
120
- DetachAndAddNodes(node, detachNodes, newNodesMap.size > 0 && newNodesArrays);
152
+ nodeRef_1.NodeRef.ReconcileChildren(node, attachNodes);
121
153
  });
122
154
  });
123
155
  });
124
156
  }
125
- function DetachAndAddNodes(node, detachNodes, newNodes) {
126
- for (var x = 0; x < detachNodes.length; x++)
127
- list_1.List.ForEach(detachNodes[x], function (nodes) {
128
- for (var x = 0; x < nodes.length; x++)
129
- nodeRef_1.NodeRef.DetachChild(node, nodes[x]);
130
- });
131
- var previousNode = null;
132
- for (var x = 0; newNodes && x < newNodes.length; x++) {
133
- for (var y = 0; y < newNodes[x].length; y++) {
134
- nodeRef_1.NodeRef.AddChildAfter(node, previousNode, newNodes[x][y]);
135
- previousNode = newNodes[x][y];
136
- }
137
- }
138
- }
139
157
  function CreateNodeArray(childrenFunc, value) {
140
158
  var newNodes = childrenFunc(value);
141
159
  if (typeof newNodes === "string") {
@@ -151,7 +169,3 @@ function CreateNodeArray(childrenFunc, value) {
151
169
  return newNodes;
152
170
  return [newNodes];
153
171
  }
154
- function DestroyNodeArrayList(nodeArrayList) {
155
- list_1.List.ForEach(nodeArrayList, nodeRef_1.NodeRef.DestroyAll);
156
- return nodeArrayList;
157
- }
@@ -21,12 +21,17 @@ export type ElementChildrenFunction<T> = {
21
21
  export type ElementNodeFunction<T> = {
22
22
  (nodeDef: ElementNodeFunctionParam<T>, children?: ElementChildrenFunction<T>): INodeRefBase;
23
23
  };
24
+ export interface IElementDataNode<T> {
25
+ value: T;
26
+ init: boolean;
27
+ nodes: NodeRefTypes[] | null;
28
+ }
24
29
  export interface IElementNodeBase<T> extends IBoundNodeBase {
25
30
  nodeDef: ElementNodeFunctionParam<T>;
26
31
  childrenFunc: {
27
32
  (data: T): string | NodeRefTypes | NodeRefTypes[];
28
33
  };
29
- nodesMap: Map<T, IList<Array<NodeRefTypes>>>;
34
+ nodeList: IList<IElementDataNode<T>> | null;
30
35
  setData: boolean;
31
36
  }
32
37
  export interface IElementNode<T> extends IElementNodeBase<T> {
@@ -18,5 +18,8 @@ export interface INodeConfig {
18
18
  remove(target: any): void;
19
19
  fireEvent(target: any, event: string, data: any): void;
20
20
  setProperties(target: any, lastProperties: any, properties: any): void;
21
+ getFirstChild(target: any): any;
22
+ getNextSibling(target: any): any;
23
+ replaceChildren(target: any, children: any[]): void;
21
24
  }
22
25
  export declare const NodeConfig: INodeConfig;
package/Node/nodeRef.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { INodeRef, INodeRefBase, NodeRefTypes } from "./nodeRef.types";
2
2
  import { IBoundNode } from "./boundNode.types";
3
- import { IElementNode } from "./elementNode.types";
3
+ import { IElementDataNode, IElementNode } from "./elementNode.types";
4
4
  import { IComponentNode } from "./componentNode.types";
5
+ import { IList } from "../Utils/list";
5
6
  export declare enum NodeRefType {
6
7
  NodeRef = 0,
7
8
  BoundNode = 1,
@@ -12,9 +13,10 @@ export declare namespace NodeRef {
12
13
  function Wrap(node: any): INodeRef;
13
14
  function Create(nodeType: any, namespace: string, type: NodeRefType): INodeRef | IBoundNode | IElementNode<any> | IComponentNode<any, any, any>;
14
15
  function Init(nodeRef: NodeRefTypes): void;
15
- function InitAll(nodeRefs: Array<NodeRefTypes>): void;
16
+ function InitAll(parentNode: NodeRefTypes, nodeRefs: Array<NodeRefTypes>): void;
16
17
  function AddChild(node: INodeRefBase, child: INodeRefBase): void;
17
18
  function AddChildAfter(node: INodeRefBase, currentChild: INodeRefBase, newChild: INodeRefBase): void;
19
+ function ReconcileChildren(node: INodeRefBase, nextChildren: IList<IElementDataNode<unknown>>): void;
18
20
  function DetachChild(node: INodeRefBase, child: INodeRefBase): void;
19
21
  function Destroy(node: INodeRefBase): void;
20
22
  function DestroyAll(nodes: Array<INodeRefBase>): void;
package/Node/nodeRef.js CHANGED
@@ -70,7 +70,7 @@ var NodeRef;
70
70
  setAttributes: false,
71
71
  setEvents: false,
72
72
  childrenFunc: null,
73
- nodesMap: null,
73
+ nodeList: null,
74
74
  setData: false
75
75
  };
76
76
  case NodeRefType.ComponentNode:
@@ -113,9 +113,12 @@ var NodeRef;
113
113
  }
114
114
  }
115
115
  NodeRef.Init = Init;
116
- function InitAll(nodeRefs) {
117
- for (var x = 0; x < nodeRefs.length; x++)
116
+ function InitAll(parentNode, nodeRefs) {
117
+ for (var x = 0; x < nodeRefs.length; x++) {
118
+ nodeRefs[x].parent = parentNode;
119
+ parentNode.childNodes.add(nodeRefs[x]);
118
120
  Init(nodeRefs[x]);
121
+ }
119
122
  }
120
123
  NodeRef.InitAll = InitAll;
121
124
  function AddChild(node, child) {
@@ -125,16 +128,42 @@ var NodeRef;
125
128
  }
126
129
  NodeRef.AddChild = AddChild;
127
130
  function AddChildAfter(node, currentChild, newChild) {
128
- if (currentChild && !node.childNodes.has(currentChild))
131
+ if (currentChild && currentChild.parent !== node)
129
132
  throw "currentChild is not valid";
130
133
  newChild.parent = node;
131
134
  node.childNodes.add(newChild);
132
135
  nodeConfig_1.NodeConfig.addChildAfter(node.node, currentChild && currentChild.node, newChild.node);
133
136
  }
134
137
  NodeRef.AddChildAfter = AddChildAfter;
138
+ function ReconcileChildren(node, nextChildren) {
139
+ const rootNode = node.node;
140
+ if (nextChildren.size === 0) {
141
+ nodeConfig_1.NodeConfig.replaceChildren(rootNode, []);
142
+ return;
143
+ }
144
+ let priorNode;
145
+ let curDataNode = nextChildren?.head;
146
+ while (curDataNode) {
147
+ for (let x = 0; x < curDataNode.data.nodes.length; x++) {
148
+ const actualNode = priorNode ? nodeConfig_1.NodeConfig.getNextSibling(priorNode) : nodeConfig_1.NodeConfig.getFirstChild(rootNode);
149
+ const virtualNode = curDataNode.data.nodes[x];
150
+ const expectedNode = virtualNode.node;
151
+ if (actualNode !== expectedNode) {
152
+ nodeConfig_1.NodeConfig.addChildBefore(rootNode, actualNode, expectedNode);
153
+ }
154
+ priorNode = expectedNode;
155
+ }
156
+ curDataNode = curDataNode.next;
157
+ }
158
+ let remainingSibling = priorNode && nodeConfig_1.NodeConfig.getNextSibling(priorNode);
159
+ while (remainingSibling) {
160
+ nodeConfig_1.NodeConfig.removeChild(rootNode, remainingSibling);
161
+ remainingSibling = nodeConfig_1.NodeConfig.getNextSibling(priorNode);
162
+ }
163
+ }
164
+ NodeRef.ReconcileChildren = ReconcileChildren;
135
165
  function DetachChild(node, child) {
136
- if (node.childNodes.has(child)) {
137
- node.childNodes.delete(child);
166
+ if (node.childNodes.delete(child)) {
138
167
  nodeConfig_1.NodeConfig.removeChild(node.node, child.node);
139
168
  child.parent = null;
140
169
  }
@@ -144,7 +173,7 @@ var NodeRef;
144
173
  if (node.destroyed)
145
174
  return;
146
175
  node.destroyed = true;
147
- node.childNodes.forEach(Destroy);
176
+ node.childNodes?.forEach(Destroy);
148
177
  for (let x = 0; x < node.destroyables.length; x++)
149
178
  node.destroyables[x]?.Destroy();
150
179
  }
@@ -208,14 +208,12 @@ class ObservableTree {
208
208
  if (!parentValue)
209
209
  throw new Error("Unable to write path: " + path + ". Falsey value found at: " + pathParts.slice(0, x).join("."));
210
210
  const prop = pathParts[x];
211
- const exists = Object.hasOwn(parentValue, prop);
212
211
  const oldValue = parentValue[prop];
213
212
  const oldType = TypeOf(oldValue);
214
213
  parentValue[prop] = value;
215
- if (oldType !== Type.Value)
216
- return this.scopeCache.get(oldValue) ||
217
- this.scopeCache.get(parentValue);
218
- const leafScopes = exists && this.leafScopeCache.get(parentValue);
214
+ if (oldType !== Type.Value || Array.isArray(parentValue))
215
+ return this.scopeCache.get(parentValue) || this.scopeCache.get(oldValue);
216
+ const leafScopes = this.leafScopeCache.get(parentValue);
219
217
  return leafScopes && leafScopes[prop] || this.scopeCache.get(parentValue);
220
218
  }
221
219
  UpdatePathCache(path, value) {
@@ -223,6 +221,9 @@ class ObservableTree {
223
221
  if (type === Type.Value)
224
222
  return;
225
223
  this.pathCache.set(value, path);
224
+ this.proxyCache.delete(value);
225
+ this.scopeCache.delete(value);
226
+ this.leafScopeCache.delete(value);
226
227
  const keys = Object.keys(value);
227
228
  for (let x = 0; x < keys.length; x++)
228
229
  this.UpdatePathCache(`${path}.${keys[x]}`, value[keys[x]]);
package/Utils/list.d.ts CHANGED
@@ -14,10 +14,13 @@ export declare namespace List {
14
14
  function Push<T>(list: IList<T>, data: T): INode<T>;
15
15
  function Pop<T>(list: IList<T>): T;
16
16
  function Add<T>(list: IList<T>, data: T): INode<T>;
17
+ function AddNode<T>(list: IList<T>, node: INode<T>): INode<T>;
17
18
  function AddBefore<T>(list: IList<T>, node: INode<T>, data: T): INode<T>;
18
19
  function AddAfter<T>(list: IList<T>, node: INode<T>, data: T): INode<T>;
19
20
  function Remove<T>(list: IList<T>): T;
21
+ function RemoveNode<T>(list: IList<T>, node: INode<T>): void;
20
22
  function ForEach<T>(list: IList<T>, callback: {
21
23
  (value: T): void;
22
24
  }): void;
25
+ function ToNodeMap<T>(list: IList<T>, keyCallback: (data: T) => unknown): Map<any, INode<T>[]>;
23
26
  }
package/Utils/list.js CHANGED
@@ -47,7 +47,11 @@ var List;
47
47
  }
48
48
  List.Pop = Pop;
49
49
  function Add(list, data) {
50
- var node = { previous: null, next: null, data: data };
50
+ const node = { previous: null, next: null, data: data };
51
+ return AddNode(list, node);
52
+ }
53
+ List.Add = Add;
54
+ function AddNode(list, node) {
51
55
  if (list.size === 0) {
52
56
  list.head = node;
53
57
  list.tail = node;
@@ -61,7 +65,7 @@ var List;
61
65
  }
62
66
  return node;
63
67
  }
64
- List.Add = Add;
68
+ List.AddNode = AddNode;
65
69
  function AddBefore(list, node, data) {
66
70
  if (!node)
67
71
  return List.Add(list, data);
@@ -109,6 +113,25 @@ var List;
109
113
  return node.data;
110
114
  }
111
115
  List.Remove = Remove;
116
+ function RemoveNode(list, node) {
117
+ if (list.head === node) {
118
+ list.head = node.next;
119
+ }
120
+ else if (list.tail === node) {
121
+ list.tail = node.previous;
122
+ }
123
+ else {
124
+ const prev = node.previous;
125
+ const next = node.next;
126
+ prev.next = next;
127
+ next.previous = prev;
128
+ }
129
+ node.next = node.previous = null;
130
+ list.size--;
131
+ if (list.size > 0)
132
+ list.head.previous = list.tail.next = null;
133
+ }
134
+ List.RemoveNode = RemoveNode;
112
135
  function ForEach(list, callback) {
113
136
  var node = list.head;
114
137
  while (node) {
@@ -117,4 +140,19 @@ var List;
117
140
  }
118
141
  }
119
142
  List.ForEach = ForEach;
143
+ function ToNodeMap(list, keyCallback) {
144
+ const map = new Map();
145
+ let node = list.head;
146
+ while (node) {
147
+ const key = keyCallback(node.data);
148
+ const nodes = map.get(key) || [node];
149
+ if (nodes[0] !== node)
150
+ nodes.push(node);
151
+ else
152
+ map.set(key, nodes);
153
+ node = node.next;
154
+ }
155
+ return map;
156
+ }
157
+ List.ToNodeMap = ToNodeMap;
120
158
  })(List || (exports.List = List = {}));
package/index.debug.d.ts CHANGED
@@ -1 +0,0 @@
1
- export {};
package/index.debug.js CHANGED
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const web_export_1 = require("./web.export");
4
- class HelloWorld extends web_export_1.Component {
5
- Template() {
6
- return [
7
- (0, web_export_1.div)({ data: () => [{ prop: "Hello" }, { prop: "World" }] }, (msg) => (0, web_export_1.span)({}, () => msg.prop))
8
- ];
9
- }
10
- }
11
- const helloWorld = web_export_1.Component.ToFunction("hello-world", null, HelloWorld);
12
- web_export_1.Component.Attach(document.body, helloWorld({}));