j-templates 6.1.10 → 6.1.12
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.
- package/DOM/domNodeConfig.js +3 -0
- package/Node/boundNode.js +0 -27
- package/Node/boundNode.types.d.ts +2 -1
- package/Node/component.d.ts +3 -3
- package/Node/componentNode.js +1 -0
- package/Node/componentNode.types.d.ts +2 -0
- package/Node/elementNode.js +105 -104
- package/Node/elementNode.types.d.ts +9 -6
- package/Node/nodeConfig.d.ts +1 -0
- package/Node/nodeRef.d.ts +14 -11
- package/Node/nodeRef.js +47 -15
- package/Node/nodeRef.types.d.ts +4 -2
- package/Node/textNode.types.d.ts +7 -0
- package/Node/textNode.types.js +2 -0
- package/Store/Tree/observableScope.d.ts +1 -4
- package/Store/Tree/observableScope.js +41 -64
- package/Utils/avlTree.d.ts +15 -0
- package/Utils/avlTree.js +140 -0
- package/Utils/decorators.d.ts +3 -3
- package/Utils/distinctArray.d.ts +10 -0
- package/Utils/distinctArray.js +26 -0
- package/Utils/emitter.d.ts +2 -0
- package/Utils/emitter.js +5 -0
- package/index.d.ts +1 -1
- package/package.json +1 -1
package/DOM/domNodeConfig.js
CHANGED
|
@@ -57,6 +57,9 @@ exports.DOMNodeConfig = {
|
|
|
57
57
|
createTextNode(value = '') {
|
|
58
58
|
return window_1.wndw.document.createTextNode(value);
|
|
59
59
|
},
|
|
60
|
+
isTextNode(target) {
|
|
61
|
+
return target?.nodeType === Node.TEXT_NODE;
|
|
62
|
+
},
|
|
60
63
|
scheduleUpdate,
|
|
61
64
|
wrapPriorityUpdates,
|
|
62
65
|
addListener(target, type, callback) {
|
package/Node/boundNode.js
CHANGED
|
@@ -66,36 +66,9 @@ var BoundNode;
|
|
|
66
66
|
boundNode.assignEvents = null;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
-
if (nodeDef.text) {
|
|
70
|
-
boundNode.assignText = nodeConfig_1.NodeConfig.createTextAssignment(boundNode.node);
|
|
71
|
-
if (typeof nodeDef.text === 'function') {
|
|
72
|
-
const scope = observableScope_1.ObservableScope.Create(nodeDef.text);
|
|
73
|
-
boundNode.scopes ??= [];
|
|
74
|
-
boundNode.scopes.push(scope);
|
|
75
|
-
observableScope_1.ObservableScope.Watch(scope, function (scope) { ScheduleSetText(boundNode, scope); });
|
|
76
|
-
const next = observableScope_1.ObservableScope.Value(scope);
|
|
77
|
-
boundNode.assignText(next);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
boundNode.assignText(nodeDef.text);
|
|
81
|
-
boundNode.assignText = null;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
69
|
}
|
|
85
70
|
BoundNode.Init = Init;
|
|
86
71
|
})(BoundNode || (exports.BoundNode = BoundNode = {}));
|
|
87
|
-
function ScheduleSetText(node, scope) {
|
|
88
|
-
if (node.setText)
|
|
89
|
-
return;
|
|
90
|
-
node.setText = true;
|
|
91
|
-
nodeConfig_1.NodeConfig.scheduleUpdate(function () {
|
|
92
|
-
node.setText = false;
|
|
93
|
-
if (node.destroyed)
|
|
94
|
-
return;
|
|
95
|
-
const next = observableScope_1.ObservableScope.Value(scope);
|
|
96
|
-
node.assignText(next);
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
72
|
function ScheduleSetProperties(node, scope) {
|
|
100
73
|
if (node.setProperties)
|
|
101
74
|
return;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IObservableScope } from "../Store/Tree/observableScope";
|
|
2
2
|
import { RecursivePartial } from "../Utils/utils.types";
|
|
3
3
|
import { NodeRefType } from "./nodeRef";
|
|
4
|
-
import { INodeRefBase } from "./nodeRef.types";
|
|
4
|
+
import { AllNodeRefTypes, INodeRefBase } from "./nodeRef.types";
|
|
5
5
|
export type FunctionOr<T> = {
|
|
6
6
|
(...args: Array<any>): T | Promise<T>;
|
|
7
7
|
} | T;
|
|
@@ -53,4 +53,5 @@ export interface IBoundNodeBase extends INodeRefBase {
|
|
|
53
53
|
}
|
|
54
54
|
export interface IBoundNode extends IBoundNodeBase {
|
|
55
55
|
type: NodeRefType.BoundNode;
|
|
56
|
+
childNodes: AllNodeRefTypes[];
|
|
56
57
|
}
|
package/Node/component.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ComponentNodeEvents, ComponentNodeFunction } from "./componentNode.types";
|
|
2
2
|
import { ObservableScope } from "../Store/Tree/observableScope";
|
|
3
|
-
import { INodeRefBase,
|
|
3
|
+
import { INodeRefBase, ElementNodeRefTypes } from "./nodeRef.types";
|
|
4
4
|
export declare class Component<D = void, T = void, E = void> {
|
|
5
5
|
private nodeRef;
|
|
6
6
|
private componentEvents;
|
|
@@ -13,7 +13,7 @@ export declare class Component<D = void, T = void, E = void> {
|
|
|
13
13
|
protected get NodeRef(): INodeRefBase;
|
|
14
14
|
protected get Templates(): T;
|
|
15
15
|
constructor(data: D | (() => (D | Promise<D>)), templates: T, nodeRef: INodeRefBase, componentEvents: ComponentNodeEvents<E>);
|
|
16
|
-
Template():
|
|
16
|
+
Template(): ElementNodeRefTypes | ElementNodeRefTypes[];
|
|
17
17
|
Bound(): void;
|
|
18
18
|
Fire<P extends keyof E>(event: P, data?: E[P]): void;
|
|
19
19
|
Destroy(): void;
|
|
@@ -22,7 +22,7 @@ export declare namespace Component {
|
|
|
22
22
|
function ToFunction<D = void, T = void, E = void>(type: string, constructor: ComponentConstructor<D, T, E>): ComponentNodeFunction<D, T, E>;
|
|
23
23
|
function ToFunction<D = void, T = void, E = void>(type: string, namespace: string, constructor: ComponentConstructor<D, T, E>): ComponentNodeFunction<D, T, E>;
|
|
24
24
|
function Register<D = void, T = void, E = void>(name: string, constructor: ComponentConstructor<D, T, E>): void;
|
|
25
|
-
function Attach(node: Node, nodeRef:
|
|
25
|
+
function Attach(node: Node, nodeRef: ElementNodeRefTypes): void;
|
|
26
26
|
}
|
|
27
27
|
export type ComponentConstructor<D, T, E> = {
|
|
28
28
|
new (data: {
|
package/Node/componentNode.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BoundNodeFunctionParam, IBoundNodeBase, NodeDefinition } from "./boundNode.types";
|
|
2
2
|
import { Component, ComponentConstructor } from "./component";
|
|
3
3
|
import { NodeRefType } from "./nodeRef";
|
|
4
|
+
import { AllNodeRefTypes } from "./nodeRef.types";
|
|
4
5
|
export type ComponentNodeEvents<E = void> = {
|
|
5
6
|
[P in keyof E]?: {
|
|
6
7
|
(data: E[P]): void;
|
|
@@ -32,4 +33,5 @@ export interface IComponentNodeBase<D, T, E> extends IBoundNodeBase {
|
|
|
32
33
|
}
|
|
33
34
|
export interface IComponentNode<D, T, E> extends IComponentNodeBase<D, T, E> {
|
|
34
35
|
type: NodeRefType.ComponentNode;
|
|
36
|
+
childNodes: AllNodeRefTypes[];
|
|
35
37
|
}
|
package/Node/elementNode.js
CHANGED
|
@@ -21,28 +21,82 @@ var ElementNode;
|
|
|
21
21
|
return elemNode;
|
|
22
22
|
}
|
|
23
23
|
ElementNode.Create = Create;
|
|
24
|
+
function CreateValueScopeCallback(dataScope) {
|
|
25
|
+
return function () {
|
|
26
|
+
const value = observableScope_1.ObservableScope.Value(dataScope);
|
|
27
|
+
if (!value)
|
|
28
|
+
return valueDefault;
|
|
29
|
+
if (!Array.isArray(value))
|
|
30
|
+
return [value];
|
|
31
|
+
return value;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function CreateNodeScopeCallback(elementNode, valueScope) {
|
|
35
|
+
let lastNodeList;
|
|
36
|
+
return function () {
|
|
37
|
+
const values = observableScope_1.ObservableScope.Value(valueScope);
|
|
38
|
+
const lastNodeMap = lastNodeList && list_1.List.ToNodeMap(lastNodeList, GetDataValue);
|
|
39
|
+
const nextNodeList = list_1.List.Create();
|
|
40
|
+
for (let x = 0; x < values.length; x++) {
|
|
41
|
+
let curNode = null;
|
|
42
|
+
if (lastNodeMap !== undefined) {
|
|
43
|
+
const nodeArr = lastNodeMap.get(values[x]);
|
|
44
|
+
if (nodeArr !== undefined) {
|
|
45
|
+
let y = nodeArr.length - 1;
|
|
46
|
+
for (; y >= 0 && nodeArr[y] === null; y--) { }
|
|
47
|
+
curNode = nodeArr[y];
|
|
48
|
+
nodeArr[y] = null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const value = values[x];
|
|
52
|
+
if (curNode !== null) {
|
|
53
|
+
list_1.List.RemoveNode(lastNodeList, curNode);
|
|
54
|
+
list_1.List.AddNode(nextNodeList, curNode);
|
|
55
|
+
const nextNodes = observableScope_1.ObservableScope.Value(curNode.data.scope);
|
|
56
|
+
if (curNode.data.nodes !== nextNodes) {
|
|
57
|
+
list_1.List.Add(elementNode.destroyNodeList, {
|
|
58
|
+
...curNode.data,
|
|
59
|
+
scope: null
|
|
60
|
+
});
|
|
61
|
+
curNode.data.init = false;
|
|
62
|
+
curNode.data.nodes = nextNodes;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const scope = observableScope_1.ObservableScope.Create(function () {
|
|
67
|
+
return injector_1.Injector.Scope(elementNode.injector, CreateNodeArray, elementNode.children, value);
|
|
68
|
+
});
|
|
69
|
+
curNode = list_1.List.Add(nextNodeList, {
|
|
70
|
+
value,
|
|
71
|
+
init: false,
|
|
72
|
+
scope,
|
|
73
|
+
nodes: observableScope_1.ObservableScope.Value(scope),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
lastNodeList && list_1.List.Append(elementNode.destroyNodeList, lastNodeList);
|
|
78
|
+
lastNodeList = nextNodeList;
|
|
79
|
+
return nextNodeList;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
24
82
|
function Init(elementNode) {
|
|
25
|
-
|
|
26
|
-
if (elementNode.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
else if (elementNode.children !== null) {
|
|
30
|
-
const dataScope = observableScope_1.ObservableScope.Create(nodeDef.data);
|
|
31
|
-
const valueScope = observableScope_1.ObservableScope.Create(function () {
|
|
32
|
-
const value = observableScope_1.ObservableScope.Value(dataScope);
|
|
33
|
-
if (!value)
|
|
34
|
-
return valueDefault;
|
|
35
|
-
if (!Array.isArray(value))
|
|
36
|
-
return [value];
|
|
37
|
-
return value;
|
|
83
|
+
elementNode.childNodes = new Set();
|
|
84
|
+
if (elementNode.children !== null) {
|
|
85
|
+
const dataScope = elementNode.nodeDef.data ? observableScope_1.ObservableScope.Create(elementNode.nodeDef.data) : observableScope_1.ObservableScope.Create(function () {
|
|
86
|
+
return [true];
|
|
38
87
|
});
|
|
88
|
+
const valueScope = observableScope_1.ObservableScope.Create(CreateValueScopeCallback(dataScope));
|
|
89
|
+
const nodeScope = observableScope_1.ObservableScope.Create(CreateNodeScopeCallback(elementNode, valueScope));
|
|
39
90
|
elementNode.childNodes = new Set();
|
|
40
91
|
elementNode.scopes ??= [];
|
|
41
|
-
elementNode.scopes.push(dataScope, valueScope);
|
|
42
|
-
observableScope_1.ObservableScope.Watch(
|
|
43
|
-
ScheduleSetData(elementNode,
|
|
92
|
+
elementNode.scopes.push(dataScope, valueScope, nodeScope);
|
|
93
|
+
observableScope_1.ObservableScope.Watch(nodeScope, function (scope) {
|
|
94
|
+
ScheduleSetData(elementNode, scope);
|
|
44
95
|
});
|
|
45
|
-
|
|
96
|
+
UpdateNodes(elementNode, observableScope_1.ObservableScope.Value(nodeScope), true);
|
|
97
|
+
}
|
|
98
|
+
else if (elementNode.childrenArray !== null) {
|
|
99
|
+
SetDefaultData(elementNode);
|
|
46
100
|
}
|
|
47
101
|
boundNode_1.BoundNode.Init(elementNode);
|
|
48
102
|
}
|
|
@@ -56,104 +110,56 @@ function ScheduleSetData(node, scope) {
|
|
|
56
110
|
node.setData = false;
|
|
57
111
|
if (node.destroyed)
|
|
58
112
|
return;
|
|
59
|
-
|
|
113
|
+
UpdateNodes(node, observableScope_1.ObservableScope.Value(scope));
|
|
60
114
|
});
|
|
61
115
|
}
|
|
62
116
|
function SetDefaultData(node) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
(0, thread_1.Thread)(function () {
|
|
73
|
-
if (node.destroyed)
|
|
74
|
-
return;
|
|
75
|
-
const defaultNodeList = list_1.List.Create();
|
|
76
|
-
list_1.List.Add(defaultNodeList, {
|
|
77
|
-
value: null,
|
|
78
|
-
init: true,
|
|
79
|
-
nodes
|
|
80
|
-
});
|
|
81
|
-
nodeRef_1.NodeRef.ReconcileChildren(node, defaultNodeList);
|
|
82
|
-
list_1.List.Clear(defaultNodeList);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
117
|
+
const nodes = node.childrenArray ||
|
|
118
|
+
injector_1.Injector.Scope(node.injector, CreateNodeArray, node.children, true);
|
|
119
|
+
node.childrenArray = null;
|
|
120
|
+
const defaultNodeList = list_1.List.Create();
|
|
121
|
+
list_1.List.Add(defaultNodeList, {
|
|
122
|
+
value: null,
|
|
123
|
+
init: false,
|
|
124
|
+
scope: null,
|
|
125
|
+
nodes
|
|
85
126
|
});
|
|
127
|
+
UpdateNodes(node, defaultNodeList, true);
|
|
86
128
|
}
|
|
87
129
|
function GetDataValue(data) {
|
|
88
130
|
return data.value;
|
|
89
131
|
}
|
|
90
|
-
function
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let curNode = null;
|
|
96
|
-
if (nodeMap) {
|
|
97
|
-
const nodeArr = nodeMap.get(values[x]);
|
|
98
|
-
if (nodeArr) {
|
|
99
|
-
let y = nodeArr.length - 1;
|
|
100
|
-
for (; y >= 0 && !curNode; y--) {
|
|
101
|
-
curNode = nodeArr[y];
|
|
102
|
-
nodeArr[y] = null;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (curNode) {
|
|
107
|
-
list_1.List.RemoveNode(currentNodeList, curNode);
|
|
108
|
-
list_1.List.AddNode(nextNodeList, curNode);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
curNode = list_1.List.Add(nextNodeList, {
|
|
112
|
-
value: values[x],
|
|
113
|
-
init: false,
|
|
114
|
-
nodes: injector_1.Injector.Scope(node.injector, CreateNodeArray, node.children, values[x])
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
let curNode = nextNodeList.head;
|
|
119
|
-
while (curNode) {
|
|
120
|
-
const data = curNode.data;
|
|
121
|
-
!data.init && (0, thread_1.Schedule)(function () {
|
|
122
|
-
if (node.destroyed || nextNodeList.size === 0)
|
|
123
|
-
return;
|
|
124
|
-
nodeRef_1.NodeRef.InitAll(node, data.nodes);
|
|
125
|
-
data.init = true;
|
|
126
|
-
});
|
|
127
|
-
curNode = curNode.next;
|
|
128
|
-
}
|
|
129
|
-
if (currentNodeList) {
|
|
130
|
-
let curDetach = currentNodeList.head;
|
|
131
|
-
while (curDetach) {
|
|
132
|
-
const data = curDetach.data;
|
|
133
|
-
curDetach = curDetach.next;
|
|
132
|
+
function UpdateNodes(elementNode, nodeList, init = false) {
|
|
133
|
+
(0, thread_1.Synch)(function () {
|
|
134
|
+
let data;
|
|
135
|
+
while (data = list_1.List.Pop(elementNode.destroyNodeList)) {
|
|
136
|
+
observableScope_1.ObservableScope.Destroy(data.scope);
|
|
134
137
|
for (let x = 0; x < data.nodes.length; x++)
|
|
135
|
-
|
|
138
|
+
elementNode.childNodes.delete(data.nodes[x]);
|
|
136
139
|
nodeRef_1.NodeRef.DestroyAll(data.nodes);
|
|
137
140
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
for (let node = nodeList.head; node !== null; node = node.next) {
|
|
142
|
+
if (!node.data.init) {
|
|
143
|
+
const nodeData = node.data;
|
|
144
|
+
(0, thread_1.Schedule)(function () {
|
|
145
|
+
if (elementNode.destroyed || nodeData.init)
|
|
146
|
+
return;
|
|
147
|
+
nodeRef_1.NodeRef.InitAll(elementNode, nodeData.nodes);
|
|
148
|
+
nodeData.init = true;
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const startSize = nodeList.size;
|
|
147
153
|
(0, thread_1.Thread)(function (async) {
|
|
148
|
-
if (
|
|
154
|
+
if (elementNode.destroyed)
|
|
149
155
|
return;
|
|
150
156
|
if (init || !async)
|
|
151
|
-
nodeRef_1.NodeRef.ReconcileChildren(
|
|
157
|
+
nodeRef_1.NodeRef.ReconcileChildren(elementNode, nodeList);
|
|
152
158
|
else
|
|
153
159
|
nodeConfig_1.NodeConfig.scheduleUpdate(function () {
|
|
154
|
-
if (
|
|
160
|
+
if (elementNode.destroyed || nodeList.size !== startSize)
|
|
155
161
|
return;
|
|
156
|
-
nodeRef_1.NodeRef.ReconcileChildren(
|
|
162
|
+
nodeRef_1.NodeRef.ReconcileChildren(elementNode, nodeList);
|
|
157
163
|
});
|
|
158
164
|
});
|
|
159
165
|
});
|
|
@@ -161,12 +167,7 @@ function SetData(node, values, init = false) {
|
|
|
161
167
|
function CreateNodeArray(childrenFunc, value) {
|
|
162
168
|
const newNodes = childrenFunc(value);
|
|
163
169
|
if (typeof newNodes === "string" || !newNodes) {
|
|
164
|
-
const textNode = nodeRef_1.NodeRef.Create(
|
|
165
|
-
textNode.nodeDef = {
|
|
166
|
-
text: function () {
|
|
167
|
-
return childrenFunc(value);
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
+
const textNode = nodeRef_1.NodeRef.Create(newNodes, null, nodeRef_1.NodeRefType.TextNode);
|
|
170
171
|
return [textNode];
|
|
171
172
|
}
|
|
172
173
|
if (Array.isArray(newNodes))
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { IObservableScope } from "../Store/Tree/observableScope";
|
|
1
2
|
import { IList } from "../Utils/list";
|
|
2
3
|
import { NodeDefinition, BoundNodeFunctionParam, IBoundNodeBase } from "./boundNode.types";
|
|
3
4
|
import { NodeRefType } from "./nodeRef";
|
|
4
|
-
import { INodeRefBase,
|
|
5
|
+
import { INodeRefBase, ElementNodeRefTypes, AllNodeRefTypes } from "./nodeRef.types";
|
|
5
6
|
export type ElementChildrenFunction<T> = {
|
|
6
|
-
(data: T): string |
|
|
7
|
+
(data: T): string | ElementNodeRefTypes | ElementNodeRefTypes[];
|
|
7
8
|
};
|
|
8
|
-
export type ElementChildrenFunctionParam<T> = ElementChildrenFunction<T> |
|
|
9
|
+
export type ElementChildrenFunctionParam<T> = ElementChildrenFunction<T> | ElementNodeRefTypes[];
|
|
9
10
|
export type ElementNodeFunction<T> = {
|
|
10
11
|
(nodeDef: ElementNodeFunctionParam<T>, children?: ElementChildrenFunctionParam<T>): INodeRefBase;
|
|
11
12
|
};
|
|
@@ -23,15 +24,17 @@ export interface ElementNodeFunctionParam<T, P = HTMLElement, E = HTMLElementEve
|
|
|
23
24
|
export interface IElementDataNode<T> {
|
|
24
25
|
value: T;
|
|
25
26
|
init: boolean;
|
|
26
|
-
|
|
27
|
+
scope: IObservableScope<AllNodeRefTypes[] | null>;
|
|
28
|
+
nodes: AllNodeRefTypes[] | null;
|
|
27
29
|
}
|
|
28
30
|
export interface IElementNodeBase<T> extends IBoundNodeBase {
|
|
29
31
|
nodeDef: ElementNodeFunctionParam<T>;
|
|
30
32
|
children: ElementChildrenFunction<T>;
|
|
31
|
-
childrenArray:
|
|
32
|
-
|
|
33
|
+
childrenArray: ElementNodeRefTypes[];
|
|
34
|
+
destroyNodeList: IList<IElementDataNode<T>>;
|
|
33
35
|
setData: boolean;
|
|
34
36
|
}
|
|
35
37
|
export interface IElementNode<T> extends IElementNodeBase<T> {
|
|
36
38
|
type: NodeRefType.ElementNode;
|
|
39
|
+
childNodes: Set<AllNodeRefTypes>;
|
|
37
40
|
}
|
package/Node/nodeConfig.d.ts
CHANGED
|
@@ -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
|
+
isTextNode(target: any): boolean;
|
|
7
8
|
getAttribute(target: any, attribute: string): string;
|
|
8
9
|
setAttribute(target: any, attribute: string, value: string): void;
|
|
9
10
|
addListener(target: any, type: string, callback: {
|
package/Node/nodeRef.d.ts
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import { INodeRef,
|
|
1
|
+
import { INodeRef, ElementNodeRefTypes, AllNodeRefTypes } from "./nodeRef.types";
|
|
2
2
|
import { IBoundNode } from "./boundNode.types";
|
|
3
3
|
import { IElementDataNode, IElementNode } from "./elementNode.types";
|
|
4
4
|
import { IComponentNode } from "./componentNode.types";
|
|
5
5
|
import { IList } from "../Utils/list";
|
|
6
|
+
import { ITextNode } from "./textNode.types";
|
|
6
7
|
export declare enum NodeRefType {
|
|
7
8
|
NodeRef = 0,
|
|
8
9
|
BoundNode = 1,
|
|
9
10
|
ElementNode = 2,
|
|
10
|
-
ComponentNode = 3
|
|
11
|
+
ComponentNode = 3,
|
|
12
|
+
TextNode = 4
|
|
11
13
|
}
|
|
12
14
|
export declare namespace NodeRef {
|
|
13
15
|
function Wrap(node: any): INodeRef;
|
|
14
|
-
function Create(nodeType: any, namespace: string, type: NodeRefType): INodeRef | IBoundNode | IElementNode<any> | IComponentNode<any, any, any
|
|
15
|
-
function Init(nodeRef:
|
|
16
|
-
function InitAll(parentNode:
|
|
17
|
-
function AddChild(node:
|
|
18
|
-
function AddChildAfter(node:
|
|
19
|
-
function
|
|
20
|
-
function
|
|
21
|
-
function
|
|
22
|
-
function
|
|
16
|
+
function Create(nodeType: any, namespace: string, type: NodeRefType): INodeRef | IBoundNode | IElementNode<any> | IComponentNode<any, any, any> | ITextNode;
|
|
17
|
+
function Init(nodeRef: AllNodeRefTypes): void;
|
|
18
|
+
function InitAll(parentNode: ElementNodeRefTypes, nodeRefs: Array<AllNodeRefTypes>): void;
|
|
19
|
+
function AddChild(node: ElementNodeRefTypes, child: AllNodeRefTypes): void;
|
|
20
|
+
function AddChildAfter(node: ElementNodeRefTypes, currentChild: AllNodeRefTypes, newChild: AllNodeRefTypes): void;
|
|
21
|
+
function AddChildBefore(node: ElementNodeRefTypes, currentChild: AllNodeRefTypes, newChild: AllNodeRefTypes): void;
|
|
22
|
+
function ReconcileChildren(node: ElementNodeRefTypes, nextChildren: IList<IElementDataNode<unknown>>): void;
|
|
23
|
+
function DetachChild(node: ElementNodeRefTypes, child: AllNodeRefTypes): void;
|
|
24
|
+
function Destroy(node: AllNodeRefTypes): void;
|
|
25
|
+
function DestroyAll(nodes: Array<AllNodeRefTypes>): void;
|
|
23
26
|
}
|
package/Node/nodeRef.js
CHANGED
|
@@ -6,25 +6,35 @@ const injector_1 = require("../Utils/injector");
|
|
|
6
6
|
const boundNode_1 = require("./boundNode");
|
|
7
7
|
const elementNode_1 = require("./elementNode");
|
|
8
8
|
const componentNode_1 = require("./componentNode");
|
|
9
|
+
const list_1 = require("../Utils/list");
|
|
9
10
|
const Store_1 = require("../Store");
|
|
11
|
+
const domNodeConfig_1 = require("../DOM/domNodeConfig");
|
|
10
12
|
var NodeRefType;
|
|
11
13
|
(function (NodeRefType) {
|
|
12
14
|
NodeRefType[NodeRefType["NodeRef"] = 0] = "NodeRef";
|
|
13
15
|
NodeRefType[NodeRefType["BoundNode"] = 1] = "BoundNode";
|
|
14
16
|
NodeRefType[NodeRefType["ElementNode"] = 2] = "ElementNode";
|
|
15
17
|
NodeRefType[NodeRefType["ComponentNode"] = 3] = "ComponentNode";
|
|
18
|
+
NodeRefType[NodeRefType["TextNode"] = 4] = "TextNode";
|
|
16
19
|
})(NodeRefType || (exports.NodeRefType = NodeRefType = {}));
|
|
17
20
|
var NodeRef;
|
|
18
21
|
(function (NodeRef) {
|
|
19
22
|
function Wrap(node) {
|
|
20
|
-
|
|
23
|
+
const nodeRef = Create(null, null, NodeRefType.BoundNode);
|
|
21
24
|
nodeRef.node = node;
|
|
22
|
-
nodeRef.childNodes =
|
|
25
|
+
nodeRef.childNodes = [];
|
|
23
26
|
return nodeRef;
|
|
24
27
|
}
|
|
25
28
|
NodeRef.Wrap = Wrap;
|
|
26
29
|
function Create(nodeType, namespace, type) {
|
|
27
30
|
switch (type) {
|
|
31
|
+
case NodeRefType.TextNode:
|
|
32
|
+
return {
|
|
33
|
+
type: NodeRefType.TextNode,
|
|
34
|
+
parent: null,
|
|
35
|
+
node: null,
|
|
36
|
+
value: nodeType
|
|
37
|
+
};
|
|
28
38
|
case NodeRefType.NodeRef:
|
|
29
39
|
return {
|
|
30
40
|
node: null,
|
|
@@ -80,7 +90,8 @@ var NodeRef;
|
|
|
80
90
|
nodeList: null,
|
|
81
91
|
setData: false,
|
|
82
92
|
setText: false,
|
|
83
|
-
scopes: null
|
|
93
|
+
scopes: null,
|
|
94
|
+
destroyNodeList: list_1.List.Create()
|
|
84
95
|
};
|
|
85
96
|
case NodeRefType.ComponentNode:
|
|
86
97
|
return {
|
|
@@ -106,10 +117,10 @@ var NodeRef;
|
|
|
106
117
|
}
|
|
107
118
|
NodeRef.Create = Create;
|
|
108
119
|
function Init(nodeRef) {
|
|
109
|
-
if (nodeRef.node)
|
|
120
|
+
if (nodeRef.type === NodeRefType.TextNode || nodeRef.node)
|
|
110
121
|
return;
|
|
111
|
-
nodeRef.node =
|
|
112
|
-
nodeRef.childNodes = nodeRef.nodeType !==
|
|
122
|
+
nodeRef.node = nodeConfig_1.NodeConfig.createNode(nodeRef.nodeType, nodeRef.nodeNamespace);
|
|
123
|
+
nodeRef.childNodes = nodeRef.nodeType !== NodeRefType.TextNode ? [] : null;
|
|
113
124
|
switch (nodeRef.type) {
|
|
114
125
|
case NodeRefType.BoundNode:
|
|
115
126
|
boundNode_1.BoundNode.Init(nodeRef);
|
|
@@ -124,10 +135,17 @@ var NodeRef;
|
|
|
124
135
|
}
|
|
125
136
|
NodeRef.Init = Init;
|
|
126
137
|
function AddChildToNode(parentNode, child) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
138
|
+
switch (parentNode.type) {
|
|
139
|
+
case NodeRefType.ElementNode:
|
|
140
|
+
parentNode.childNodes.add(child);
|
|
141
|
+
break;
|
|
142
|
+
case NodeRefType.ComponentNode:
|
|
143
|
+
case NodeRefType.BoundNode:
|
|
144
|
+
parentNode.childNodes.push(child);
|
|
145
|
+
break;
|
|
146
|
+
default:
|
|
147
|
+
throw "Unable to add child node to node";
|
|
148
|
+
}
|
|
131
149
|
}
|
|
132
150
|
function InitAll(parentNode, nodeRefs) {
|
|
133
151
|
for (var x = 0; x < nodeRefs.length; x++) {
|
|
@@ -151,6 +169,14 @@ var NodeRef;
|
|
|
151
169
|
nodeConfig_1.NodeConfig.addChildAfter(node.node, currentChild && currentChild.node, newChild.node);
|
|
152
170
|
}
|
|
153
171
|
NodeRef.AddChildAfter = AddChildAfter;
|
|
172
|
+
function AddChildBefore(node, currentChild, newChild) {
|
|
173
|
+
if (currentChild && currentChild.parent !== node)
|
|
174
|
+
throw "currentChild is not valid";
|
|
175
|
+
newChild.parent = node;
|
|
176
|
+
AddChildToNode(node, newChild);
|
|
177
|
+
nodeConfig_1.NodeConfig.addChildBefore(node.node, currentChild && currentChild.node, newChild.node);
|
|
178
|
+
}
|
|
179
|
+
NodeRef.AddChildBefore = AddChildBefore;
|
|
154
180
|
function ReconcileChildren(node, nextChildren) {
|
|
155
181
|
const rootNode = node.node;
|
|
156
182
|
if (nextChildren.size === 0) {
|
|
@@ -162,8 +188,16 @@ var NodeRef;
|
|
|
162
188
|
let remove = false;
|
|
163
189
|
for (let curDataNode = nextChildren.head; curDataNode !== null; curDataNode = curDataNode.next) {
|
|
164
190
|
for (let x = 0; x < curDataNode.data.nodes.length; x++) {
|
|
165
|
-
const actualNode = priorNode ? nodeConfig_1.NodeConfig.getNextSibling(priorNode) : nodeConfig_1.NodeConfig.getFirstChild(rootNode);
|
|
166
191
|
const virtualNode = curDataNode.data.nodes[x];
|
|
192
|
+
const actualNode = priorNode ? nodeConfig_1.NodeConfig.getNextSibling(priorNode) : nodeConfig_1.NodeConfig.getFirstChild(rootNode);
|
|
193
|
+
if (virtualNode.type === NodeRefType.TextNode && virtualNode.node === null) {
|
|
194
|
+
if (domNodeConfig_1.DOMNodeConfig.isTextNode(actualNode)) {
|
|
195
|
+
domNodeConfig_1.DOMNodeConfig.setText(actualNode, virtualNode.value);
|
|
196
|
+
virtualNode.node = actualNode;
|
|
197
|
+
}
|
|
198
|
+
else
|
|
199
|
+
virtualNode.node = domNodeConfig_1.DOMNodeConfig.createTextNode(virtualNode.value);
|
|
200
|
+
}
|
|
167
201
|
const expectedNode = virtualNode.node;
|
|
168
202
|
if (actualNode !== expectedNode) {
|
|
169
203
|
nodeConfig_1.NodeConfig.addChildBefore(rootNode, actualNode, expectedNode);
|
|
@@ -186,14 +220,12 @@ var NodeRef;
|
|
|
186
220
|
}
|
|
187
221
|
NodeRef.ReconcileChildren = ReconcileChildren;
|
|
188
222
|
function DetachChild(node, child) {
|
|
189
|
-
if (
|
|
190
|
-
nodeConfig_1.NodeConfig.removeChild(node.node, child.node);
|
|
223
|
+
if (node.type === NodeRefType.ElementNode && node.childNodes.delete(child))
|
|
191
224
|
child.parent = null;
|
|
192
|
-
}
|
|
193
225
|
}
|
|
194
226
|
NodeRef.DetachChild = DetachChild;
|
|
195
227
|
function Destroy(node) {
|
|
196
|
-
if (node.destroyed)
|
|
228
|
+
if (node.type === NodeRefType.TextNode || node.destroyed)
|
|
197
229
|
return;
|
|
198
230
|
node.destroyed = true;
|
|
199
231
|
if (Array.isArray(node.childNodes))
|
package/Node/nodeRef.types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { IBoundNode } from "./boundNode.types";
|
|
|
3
3
|
import { IComponentNode } from "./componentNode.types";
|
|
4
4
|
import { IElementNode } from "./elementNode.types";
|
|
5
5
|
import { NodeRefType } from "./nodeRef";
|
|
6
|
+
import { ITextNode } from "./textNode.types";
|
|
6
7
|
export interface INodeRefBase {
|
|
7
8
|
type: NodeRefType;
|
|
8
9
|
node: any;
|
|
@@ -10,10 +11,11 @@ export interface INodeRefBase {
|
|
|
10
11
|
nodeNamespace: string;
|
|
11
12
|
injector: Injector;
|
|
12
13
|
parent: INodeRefBase;
|
|
13
|
-
childNodes:
|
|
14
|
+
childNodes: AllNodeRefTypes[] | Set<AllNodeRefTypes>;
|
|
14
15
|
destroyed: boolean;
|
|
15
16
|
}
|
|
16
17
|
export interface INodeRef extends INodeRefBase {
|
|
17
18
|
type: NodeRefType.NodeRef;
|
|
18
19
|
}
|
|
19
|
-
export type
|
|
20
|
+
export type ElementNodeRefTypes = INodeRef | IBoundNode | IElementNode<any> | IComponentNode<any, any, any>;
|
|
21
|
+
export type AllNodeRefTypes = ElementNodeRefTypes | ITextNode;
|
|
@@ -41,11 +41,9 @@ export interface IObservableScope<T> extends IDestroyable {
|
|
|
41
41
|
dirty: boolean;
|
|
42
42
|
emitter: Emitter;
|
|
43
43
|
emitters: (Emitter | null)[];
|
|
44
|
-
calcFunctions: ICalcFunction<any>[]
|
|
44
|
+
calcFunctions: ICalcFunction<any>[];
|
|
45
45
|
onDestroyed: Emitter | null;
|
|
46
46
|
destroyed: boolean;
|
|
47
|
-
watchEmitters: Emitter[] | null;
|
|
48
|
-
watchEmittersSet: Set<Emitter> | null;
|
|
49
47
|
}
|
|
50
48
|
export declare function CalcScope<T>(callback: () => T): T;
|
|
51
49
|
export declare namespace ObservableScope {
|
|
@@ -55,7 +53,6 @@ export declare namespace ObservableScope {
|
|
|
55
53
|
function Register(emitter: Emitter): void;
|
|
56
54
|
function Init<T>(scope: IObservableScope<T>): void;
|
|
57
55
|
function Value<T>(scope: IObservableScope<T>): T;
|
|
58
|
-
function Watching(): boolean;
|
|
59
56
|
function Touch<T>(scope: IObservableScope<T>): void;
|
|
60
57
|
function Watch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T>]>): void;
|
|
61
58
|
function Unwatch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T> | ObservableScopeValue<T>]>): void;
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ObservableScope = exports.ObservableScopeWrapper = exports.ObservableScopeValue = void 0;
|
|
4
4
|
exports.CalcScope = CalcScope;
|
|
5
5
|
const array_1 = require("../../Utils/array");
|
|
6
|
+
const avlTree_1 = require("../../Utils/avlTree");
|
|
6
7
|
const emitter_1 = require("../../Utils/emitter");
|
|
7
|
-
const list_1 = require("../../Utils/list");
|
|
8
8
|
class ObservableScopeValue {
|
|
9
9
|
get Value() {
|
|
10
10
|
return ObservableScope.Value(this.scope);
|
|
@@ -48,28 +48,22 @@ class ObservableScope extends ObservableScopeWrapper {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
exports.ObservableScope = ObservableScope;
|
|
51
|
-
let
|
|
52
|
-
let currentlyWatching = false;
|
|
51
|
+
let watchState = null;
|
|
53
52
|
function WatchScope(scope) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
watchingScope = scope;
|
|
57
|
-
currentlyWatching = true;
|
|
53
|
+
const parent = watchState;
|
|
54
|
+
watchState = [avlTree_1.AVL.Create(emitter_1.Emitter.Compare), []];
|
|
58
55
|
const value = scope.getFunction();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return value;
|
|
56
|
+
const result = [value, avlTree_1.AVL.ToArray(watchState[0]), watchState[1]];
|
|
57
|
+
watchState = parent;
|
|
58
|
+
return result;
|
|
63
59
|
}
|
|
64
60
|
function CalcScope(callback) {
|
|
65
61
|
const value = callback();
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
watchingScope.calcFunctions.push({
|
|
62
|
+
if (watchState !== null)
|
|
63
|
+
watchState[1].push({
|
|
69
64
|
getFunction: callback,
|
|
70
65
|
value
|
|
71
66
|
});
|
|
72
|
-
}
|
|
73
67
|
return value;
|
|
74
68
|
}
|
|
75
69
|
(function (ObservableScope) {
|
|
@@ -82,11 +76,9 @@ function CalcScope(callback) {
|
|
|
82
76
|
dirty: true,
|
|
83
77
|
emitter: emitter_1.Emitter.Create(),
|
|
84
78
|
emitters: [],
|
|
85
|
-
calcFunctions:
|
|
79
|
+
calcFunctions: [],
|
|
86
80
|
onDestroyed: null,
|
|
87
81
|
destroyed: false,
|
|
88
|
-
watchEmitters: null,
|
|
89
|
-
watchEmittersSet: null,
|
|
90
82
|
setCallback: function () {
|
|
91
83
|
return OnSet(scope);
|
|
92
84
|
},
|
|
@@ -95,35 +87,25 @@ function CalcScope(callback) {
|
|
|
95
87
|
}
|
|
96
88
|
ObservableScope.Create = Create;
|
|
97
89
|
function Register(emitter) {
|
|
98
|
-
if (
|
|
90
|
+
if (watchState === null)
|
|
99
91
|
return;
|
|
100
|
-
|
|
101
|
-
if (watchingScope.watchEmitters.length === 10)
|
|
102
|
-
watchingScope.watchEmittersSet ??= new Set(watchingScope.watchEmitters);
|
|
103
|
-
if (watchingScope.watchEmittersSet === null ? !watchingScope.watchEmitters.includes(emitter) : !watchingScope.watchEmittersSet.has(emitter)) {
|
|
104
|
-
watchingScope.watchEmittersSet?.add(emitter);
|
|
105
|
-
watchingScope.watchEmitters.push(emitter);
|
|
106
|
-
}
|
|
92
|
+
avlTree_1.AVL.Insert(watchState[0], emitter);
|
|
107
93
|
}
|
|
108
94
|
ObservableScope.Register = Register;
|
|
109
95
|
function Init(scope) {
|
|
110
96
|
if (!scope)
|
|
111
97
|
return;
|
|
112
|
-
|
|
98
|
+
UpdateValue(scope);
|
|
113
99
|
}
|
|
114
100
|
ObservableScope.Init = Init;
|
|
115
101
|
function Value(scope) {
|
|
116
102
|
if (!scope)
|
|
117
103
|
return undefined;
|
|
118
104
|
Register(scope.emitter);
|
|
119
|
-
|
|
105
|
+
UpdateValue(scope);
|
|
120
106
|
return scope.value;
|
|
121
107
|
}
|
|
122
108
|
ObservableScope.Value = Value;
|
|
123
|
-
function Watching() {
|
|
124
|
-
return currentlyWatching;
|
|
125
|
-
}
|
|
126
|
-
ObservableScope.Watching = Watching;
|
|
127
109
|
function Touch(scope) {
|
|
128
110
|
if (!scope || !scope.emitter)
|
|
129
111
|
return;
|
|
@@ -148,6 +130,8 @@ function CalcScope(callback) {
|
|
|
148
130
|
}
|
|
149
131
|
ObservableScope.OnDestroyed = OnDestroyed;
|
|
150
132
|
function Update(scope) {
|
|
133
|
+
if (!scope || scope.dirty || scope.destroyed)
|
|
134
|
+
return;
|
|
151
135
|
OnSet(scope);
|
|
152
136
|
}
|
|
153
137
|
ObservableScope.Update = Update;
|
|
@@ -156,25 +140,6 @@ function CalcScope(callback) {
|
|
|
156
140
|
}
|
|
157
141
|
ObservableScope.Destroy = Destroy;
|
|
158
142
|
})(ObservableScope || (exports.ObservableScope = ObservableScope = {}));
|
|
159
|
-
function UpdateScope(scope) {
|
|
160
|
-
const prePromise = scope.promise;
|
|
161
|
-
UpdateValue(scope);
|
|
162
|
-
scope.async && prePromise !== scope.promise && scope.promise.then(function () {
|
|
163
|
-
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
const updateScopeQueue = list_1.List.Create();
|
|
167
|
-
function ProcessScopeUpdateQueue() {
|
|
168
|
-
const processList = list_1.List.Split(updateScopeQueue, 0);
|
|
169
|
-
for (let node = processList.head; node !== null; node = node.next)
|
|
170
|
-
UpdateScope(node.data);
|
|
171
|
-
list_1.List.Clear(processList);
|
|
172
|
-
}
|
|
173
|
-
function QueueScopeUpdate(scope) {
|
|
174
|
-
list_1.List.Add(updateScopeQueue, scope);
|
|
175
|
-
if (updateScopeQueue.size === 1)
|
|
176
|
-
queueMicrotask(ProcessScopeUpdateQueue);
|
|
177
|
-
}
|
|
178
143
|
function CalcChanged(calc) {
|
|
179
144
|
const value = calc.getFunction();
|
|
180
145
|
const changed = calc.value !== value;
|
|
@@ -182,35 +147,48 @@ function CalcChanged(calc) {
|
|
|
182
147
|
return changed;
|
|
183
148
|
}
|
|
184
149
|
function DirtyScope(scope) {
|
|
185
|
-
scope.dirty
|
|
186
|
-
|
|
150
|
+
if (scope.dirty || !scope.getFunction)
|
|
151
|
+
return;
|
|
152
|
+
scope.dirty = scope.calcFunctions.length === 0 || scope.calcFunctions.some(CalcChanged);
|
|
153
|
+
scope.dirty && emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
154
|
+
}
|
|
155
|
+
const scopeQueue = new Set();
|
|
156
|
+
function ProcessScopeQueue() {
|
|
157
|
+
const scopes = Array.from(scopeQueue);
|
|
158
|
+
scopeQueue.clear();
|
|
159
|
+
for (let x = 0; x < scopes.length; x++)
|
|
160
|
+
DirtyScope(scopes[x]);
|
|
187
161
|
}
|
|
188
162
|
function OnSet(scope) {
|
|
189
|
-
if (
|
|
190
|
-
return
|
|
163
|
+
if (scope.destroyed)
|
|
164
|
+
return true;
|
|
165
|
+
if (scope.async || scope.calcFunctions.length > 0) {
|
|
166
|
+
if (scopeQueue.size === 0)
|
|
167
|
+
queueMicrotask(ProcessScopeQueue);
|
|
168
|
+
scopeQueue.add(scope);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
191
171
|
DirtyScope(scope);
|
|
192
|
-
return false;
|
|
193
172
|
}
|
|
194
173
|
function UpdateValue(scope) {
|
|
195
174
|
if (!scope.dirty)
|
|
196
175
|
return;
|
|
197
176
|
scope.dirty = false;
|
|
198
|
-
|
|
199
|
-
scope.calcFunctions = null;
|
|
200
|
-
const value = WatchScope(scope);
|
|
177
|
+
const [value, emitters, calcFunctions] = WatchScope(scope);
|
|
201
178
|
if (scope.async) {
|
|
202
179
|
scope.promise = value.then(function (result) {
|
|
203
180
|
scope.value = result;
|
|
181
|
+
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
204
182
|
return result;
|
|
205
183
|
});
|
|
206
184
|
}
|
|
207
185
|
else
|
|
208
186
|
scope.value = value;
|
|
209
|
-
|
|
187
|
+
scope.calcFunctions = calcFunctions;
|
|
188
|
+
UpdateEmitters(scope, emitters);
|
|
210
189
|
}
|
|
211
|
-
function UpdateEmitters(scope) {
|
|
212
|
-
|
|
213
|
-
if (right === null) {
|
|
190
|
+
function UpdateEmitters(scope, right) {
|
|
191
|
+
if (right.length === 0) {
|
|
214
192
|
if (scope.emitters.length > 0) {
|
|
215
193
|
for (let x = 0; x < scope.emitters.length; x++)
|
|
216
194
|
emitter_1.Emitter.Remove(scope.emitters[x], scope.setCallback);
|
|
@@ -218,7 +196,6 @@ function UpdateEmitters(scope) {
|
|
|
218
196
|
}
|
|
219
197
|
return;
|
|
220
198
|
}
|
|
221
|
-
emitter_1.Emitter.Sort(right);
|
|
222
199
|
(0, array_1.ReconcileSortedArrays)(scope.emitters, right, function (emitter) {
|
|
223
200
|
emitter_1.Emitter.On(emitter, scope.setCallback);
|
|
224
201
|
}, function (emitter) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type Compare<T> = (a: T, b: T) => number;
|
|
2
|
+
export interface AvlTree<T> {
|
|
3
|
+
size: number;
|
|
4
|
+
root: AvlTreeNode<T> | null;
|
|
5
|
+
compare: Compare<T>;
|
|
6
|
+
}
|
|
7
|
+
export type AvlTreeNode<T> = [T, number, number, AvlTreeNode<T> | null, AvlTreeNode<T> | null];
|
|
8
|
+
export declare namespace AVL {
|
|
9
|
+
function Create<T>(compare: Compare<T>): AvlTree<T>;
|
|
10
|
+
function Clear(tree: AvlTree<unknown>): void;
|
|
11
|
+
function Insert<T>(tree: AvlTree<T>, value: T): void;
|
|
12
|
+
function ForEach<T>(tree: AvlTree<T>, callback: (value: T) => void): void;
|
|
13
|
+
function ToArray<T>(tree: AvlTree<T>): T[];
|
|
14
|
+
}
|
|
15
|
+
export {};
|
package/Utils/avlTree.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AVL = void 0;
|
|
4
|
+
const VALUE = 0;
|
|
5
|
+
const BALANCE = 1;
|
|
6
|
+
const HEIGHT = 2;
|
|
7
|
+
const LEFT = 3;
|
|
8
|
+
const RIGHT = 4;
|
|
9
|
+
function Squash(x) {
|
|
10
|
+
return x ? x < 0 ? -1 : 1 : 0;
|
|
11
|
+
}
|
|
12
|
+
var AVL;
|
|
13
|
+
(function (AVL) {
|
|
14
|
+
function Create(compare) {
|
|
15
|
+
return CreateTree(compare);
|
|
16
|
+
}
|
|
17
|
+
AVL.Create = Create;
|
|
18
|
+
function Clear(tree) {
|
|
19
|
+
tree.root = null;
|
|
20
|
+
tree.size = 0;
|
|
21
|
+
}
|
|
22
|
+
AVL.Clear = Clear;
|
|
23
|
+
function Insert(tree, value) {
|
|
24
|
+
if (tree.size === 0) {
|
|
25
|
+
tree.root = CreateNode(value);
|
|
26
|
+
tree.size = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
InsertValue(tree, value);
|
|
30
|
+
}
|
|
31
|
+
AVL.Insert = Insert;
|
|
32
|
+
function ForEach(tree, callback) {
|
|
33
|
+
PreOrder(tree.root, callback);
|
|
34
|
+
}
|
|
35
|
+
AVL.ForEach = ForEach;
|
|
36
|
+
function ToArray(tree) {
|
|
37
|
+
const result = new Array(tree.size);
|
|
38
|
+
let index = 0;
|
|
39
|
+
ForEach(tree, function (value) {
|
|
40
|
+
result[index++] = value;
|
|
41
|
+
});
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
AVL.ToArray = ToArray;
|
|
45
|
+
})(AVL || (exports.AVL = AVL = {}));
|
|
46
|
+
function PreOrder(node, callback) {
|
|
47
|
+
if (node === null)
|
|
48
|
+
return;
|
|
49
|
+
PreOrder(node[LEFT], callback);
|
|
50
|
+
callback(node[VALUE]);
|
|
51
|
+
PreOrder(node[RIGHT], callback);
|
|
52
|
+
}
|
|
53
|
+
function CreateTree(compare) {
|
|
54
|
+
return {
|
|
55
|
+
size: 0,
|
|
56
|
+
compare,
|
|
57
|
+
root: null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function CreateNode(value) {
|
|
61
|
+
return [value, 0, 1, null, null];
|
|
62
|
+
}
|
|
63
|
+
function InsertValue(tree, value) {
|
|
64
|
+
const startSize = tree.size;
|
|
65
|
+
let node = tree.root;
|
|
66
|
+
let comp = 0;
|
|
67
|
+
const path = [];
|
|
68
|
+
while (node !== null) {
|
|
69
|
+
comp = Squash(tree.compare(value, node[VALUE]));
|
|
70
|
+
path.push([comp, node]);
|
|
71
|
+
switch (comp) {
|
|
72
|
+
case 0:
|
|
73
|
+
node = null;
|
|
74
|
+
break;
|
|
75
|
+
case -1:
|
|
76
|
+
node = node[LEFT] ??= (tree.size++, CreateNode(value));
|
|
77
|
+
break;
|
|
78
|
+
case 1:
|
|
79
|
+
node = node[RIGHT] ??= (tree.size++, CreateNode(value));
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (tree.size === startSize)
|
|
84
|
+
return;
|
|
85
|
+
for (let x = path.length - 2; x >= 0; x--) {
|
|
86
|
+
SetHeight(path[x][1]);
|
|
87
|
+
if (Math.abs(path[x][1][BALANCE]) === 2) {
|
|
88
|
+
const newRoot = BalanceNode(path[x][1]);
|
|
89
|
+
if (x === 0)
|
|
90
|
+
tree.root = newRoot;
|
|
91
|
+
else {
|
|
92
|
+
const [comp, parent] = path[x - 1];
|
|
93
|
+
switch (comp) {
|
|
94
|
+
case -1:
|
|
95
|
+
parent[LEFT] = newRoot;
|
|
96
|
+
break;
|
|
97
|
+
case 1:
|
|
98
|
+
parent[RIGHT] = newRoot;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function BalanceNode(node) {
|
|
106
|
+
if (node[BALANCE] < 0) {
|
|
107
|
+
if (node[LEFT][BALANCE] > 0)
|
|
108
|
+
node[LEFT] = RotateLeft(node[LEFT]);
|
|
109
|
+
return RotateRight(node);
|
|
110
|
+
}
|
|
111
|
+
if (node[RIGHT][BALANCE] < 0)
|
|
112
|
+
node[RIGHT] = RotateRight(node[RIGHT]);
|
|
113
|
+
return RotateLeft(node);
|
|
114
|
+
}
|
|
115
|
+
function RotateLeft(node) {
|
|
116
|
+
const startRightLeft = node[RIGHT][LEFT];
|
|
117
|
+
const root = node[RIGHT];
|
|
118
|
+
root[LEFT] = node;
|
|
119
|
+
node[RIGHT] = startRightLeft;
|
|
120
|
+
SetHeight(node);
|
|
121
|
+
SetHeight(root);
|
|
122
|
+
return root;
|
|
123
|
+
}
|
|
124
|
+
function RotateRight(node) {
|
|
125
|
+
const startLeftRight = node[LEFT][RIGHT];
|
|
126
|
+
const root = node[LEFT];
|
|
127
|
+
root[RIGHT] = node;
|
|
128
|
+
node[LEFT] = startLeftRight;
|
|
129
|
+
SetHeight(node);
|
|
130
|
+
SetHeight(root);
|
|
131
|
+
return root;
|
|
132
|
+
}
|
|
133
|
+
function SetHeight(node) {
|
|
134
|
+
const leftHeight = node[LEFT]?.[HEIGHT] ?? 0;
|
|
135
|
+
const rightHeight = node[RIGHT]?.[HEIGHT] ?? 0;
|
|
136
|
+
const balance = rightHeight - leftHeight;
|
|
137
|
+
const height = leftHeight > rightHeight ? leftHeight : rightHeight;
|
|
138
|
+
node[HEIGHT] = height + 1;
|
|
139
|
+
node[BALANCE] = balance;
|
|
140
|
+
}
|
package/Utils/decorators.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Component } from "../Node/component";
|
|
2
2
|
import { IDestroyable } from "./utils.types";
|
|
3
|
-
import {
|
|
3
|
+
import { ElementNodeRefTypes } from "../Node/nodeRef.types";
|
|
4
4
|
export declare function Computed<T extends Component<any, any, any>, K extends keyof T, V extends T[K]>(defaultValue: V): (target: T, propertyKey: K, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
5
5
|
export declare function ComputedAsync<T extends Component<any, any, any>, K extends keyof T, V extends T[K]>(defaultValue: V): (target: T, propertyKey: K, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
6
6
|
export declare function State(): any;
|
|
@@ -16,12 +16,12 @@ export declare namespace Destroy {
|
|
|
16
16
|
}
|
|
17
17
|
declare function DestroyDecorator<T extends Component<any, any, any> & Record<K, IDestroyable>, K extends string>(target: T, propertyKey: K): any;
|
|
18
18
|
export declare function PreReqTemplate(template: {
|
|
19
|
-
():
|
|
19
|
+
(): ElementNodeRefTypes | ElementNodeRefTypes[];
|
|
20
20
|
}): <T extends Component<any, any, any>>(target: {
|
|
21
21
|
new (...args: Array<any>): T;
|
|
22
22
|
}) => any;
|
|
23
23
|
export declare namespace PreReqTemplate {
|
|
24
|
-
function Get(value: any):
|
|
24
|
+
function Get(value: any): ElementNodeRefTypes[];
|
|
25
25
|
}
|
|
26
26
|
export declare function PreReq(): typeof PreReqDecorator;
|
|
27
27
|
export declare namespace PreReq {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type DistinctArray<T> = {
|
|
2
|
+
id: (value: T) => number;
|
|
3
|
+
distinct: T[];
|
|
4
|
+
array: T[];
|
|
5
|
+
};
|
|
6
|
+
export declare namespace DistinctArray {
|
|
7
|
+
function Create<T>(id: (value: T) => number): DistinctArray<T>;
|
|
8
|
+
function Push<T>({ id, distinct, array }: DistinctArray<T>, value: T): void;
|
|
9
|
+
function Get<T>({ array }: DistinctArray<T>): T[];
|
|
10
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DistinctArray = void 0;
|
|
4
|
+
var DistinctArray;
|
|
5
|
+
(function (DistinctArray) {
|
|
6
|
+
function Create(id) {
|
|
7
|
+
return {
|
|
8
|
+
id,
|
|
9
|
+
distinct: [],
|
|
10
|
+
array: []
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
DistinctArray.Create = Create;
|
|
14
|
+
function Push({ id, distinct, array }, value) {
|
|
15
|
+
const vId = id(value);
|
|
16
|
+
if (distinct[vId] === undefined) {
|
|
17
|
+
distinct[vId] = value;
|
|
18
|
+
array.push(value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
DistinctArray.Push = Push;
|
|
22
|
+
function Get({ array }) {
|
|
23
|
+
return array;
|
|
24
|
+
}
|
|
25
|
+
DistinctArray.Get = Get;
|
|
26
|
+
})(DistinctArray || (exports.DistinctArray = DistinctArray = {}));
|
package/Utils/emitter.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ export type EmitterCallback<T extends readonly any[] = any[]> = (...args: T) =>
|
|
|
2
2
|
export type Emitter = [number, ...EmitterCallback[]];
|
|
3
3
|
export declare namespace Emitter {
|
|
4
4
|
function Create(): Emitter;
|
|
5
|
+
function GetId(emitter: Emitter): number;
|
|
5
6
|
function On(emitter: Emitter, callback: EmitterCallback): void;
|
|
6
7
|
function Emit(emitter: Emitter, ...args: any[]): void;
|
|
7
8
|
function Remove(emitter: Emitter, callback: EmitterCallback): void;
|
|
8
9
|
function Clear(emitter: Emitter): void;
|
|
9
10
|
function Sort(emitters: Emitter[]): Emitter[];
|
|
11
|
+
function Compare(a: Emitter, b: Emitter): number;
|
|
10
12
|
}
|
package/Utils/emitter.js
CHANGED
|
@@ -10,6 +10,10 @@ var Emitter;
|
|
|
10
10
|
return emitter;
|
|
11
11
|
}
|
|
12
12
|
Emitter.Create = Create;
|
|
13
|
+
function GetId(emitter) {
|
|
14
|
+
return emitter[0];
|
|
15
|
+
}
|
|
16
|
+
Emitter.GetId = GetId;
|
|
13
17
|
function On(emitter, callback) {
|
|
14
18
|
emitter.push(callback);
|
|
15
19
|
}
|
|
@@ -43,4 +47,5 @@ var Emitter;
|
|
|
43
47
|
function Compare(a, b) {
|
|
44
48
|
return a[0] - b[0];
|
|
45
49
|
}
|
|
50
|
+
Emitter.Compare = Compare;
|
|
46
51
|
})(Emitter || (exports.Emitter = Emitter = {}));
|
package/index.d.ts
CHANGED