j-templates 6.1.11 → 7.0.0
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/createAssignment.js +4 -5
- package/DOM/createAttributeAssignment.d.ts +1 -0
- package/DOM/createAttributeAssignment.js +16 -0
- package/DOM/createPropertyAssignment.d.ts +1 -0
- package/DOM/createPropertyAssignment.js +7 -0
- package/DOM/domNodeConfig.js +41 -1
- package/DOM/elements.d.ts +80 -26
- package/DOM/elements.js +12 -101
- package/DOM/index.d.ts +0 -1
- package/DOM/index.js +0 -1
- package/DOM/svgElements.d.ts +0 -4
- package/DOM/svgElements.js +0 -16
- package/Node/component.d.ts +19 -16
- package/Node/component.js +25 -31
- package/Node/component.types.d.ts +5 -0
- package/Node/nodeConfig.d.ts +7 -0
- package/Node/vNode.d.ts +20 -0
- package/Node/vNode.js +296 -0
- package/Node/vNode.types.d.ts +45 -0
- package/Store/Tree/observableNode.js +1 -2
- package/Store/Tree/observableScope.d.ts +3 -4
- package/Store/Tree/observableScope.js +64 -66
- package/Utils/avlTree.d.ts +15 -0
- package/Utils/avlTree.js +139 -0
- package/Utils/decorators.d.ts +4 -25
- package/Utils/decorators.js +3 -61
- 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 -2
- package/package.json +1 -1
- package/Node/boundNode.d.ts +0 -4
- package/Node/boundNode.js +0 -115
- package/Node/boundNode.types.d.ts +0 -57
- package/Node/componentNode.d.ts +0 -7
- package/Node/componentNode.js +0 -123
- package/Node/componentNode.types.d.ts +0 -37
- package/Node/elementNode.d.ts +0 -5
- package/Node/elementNode.js +0 -176
- package/Node/elementNode.types.d.ts +0 -40
- package/Node/elementNode.types.js +0 -2
- package/Node/nodeRef.d.ts +0 -26
- package/Node/nodeRef.js +0 -252
- package/Node/nodeRef.types.d.ts +0 -21
- package/Node/nodeRef.types.js +0 -2
- package/Node/textNode.types.d.ts +0 -7
- package/Node/textNode.types.js +0 -2
- /package/Node/{boundNode.types.js → component.types.js} +0 -0
- /package/Node/{componentNode.types.js → vNode.types.js} +0 -0
package/Node/vNode.js
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vNode = void 0;
|
|
4
|
+
const Store_1 = require("../Store");
|
|
5
|
+
const injector_1 = require("../Utils/injector");
|
|
6
|
+
const list_1 = require("../Utils/list");
|
|
7
|
+
const thread_1 = require("../Utils/thread");
|
|
8
|
+
const nodeConfig_1 = require("./nodeConfig");
|
|
9
|
+
var vNode;
|
|
10
|
+
(function (vNode) {
|
|
11
|
+
function Create(definition) {
|
|
12
|
+
return {
|
|
13
|
+
definition,
|
|
14
|
+
injector: injector_1.Injector.Current() ?? new injector_1.Injector(),
|
|
15
|
+
node: null,
|
|
16
|
+
children: null,
|
|
17
|
+
destroyed: false,
|
|
18
|
+
assignProperties: null,
|
|
19
|
+
assignEvents: null,
|
|
20
|
+
assignAttributes: null,
|
|
21
|
+
component: null,
|
|
22
|
+
scopes: []
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
vNode.Create = Create;
|
|
26
|
+
function Init(vnode) {
|
|
27
|
+
if (vnode.node !== null)
|
|
28
|
+
return;
|
|
29
|
+
InitNode(vnode);
|
|
30
|
+
}
|
|
31
|
+
vNode.Init = Init;
|
|
32
|
+
function InitAll(vnodes) {
|
|
33
|
+
for (let x = 0; x < vnodes.length; x++)
|
|
34
|
+
Init(vnodes[x]);
|
|
35
|
+
}
|
|
36
|
+
vNode.InitAll = InitAll;
|
|
37
|
+
function Destroy(vnode) {
|
|
38
|
+
if (vnode.destroyed)
|
|
39
|
+
return;
|
|
40
|
+
vnode.destroyed = true;
|
|
41
|
+
vnode.assignEvents?.(null);
|
|
42
|
+
vnode.component?.Destroy();
|
|
43
|
+
Store_1.ObservableScope.DestroyAll(vnode.scopes);
|
|
44
|
+
vnode.children && DestroyAll(vnode.children);
|
|
45
|
+
}
|
|
46
|
+
vNode.Destroy = Destroy;
|
|
47
|
+
function DestroyAll(vnodes) {
|
|
48
|
+
for (let x = 0; x < vnodes.length; x++)
|
|
49
|
+
Destroy(vnodes[x]);
|
|
50
|
+
}
|
|
51
|
+
vNode.DestroyAll = DestroyAll;
|
|
52
|
+
function ToFunction(type, namespace) {
|
|
53
|
+
return function (config, children) {
|
|
54
|
+
const childrenConfig = children ? Array.isArray(children) ? { childrenArray: children } : { children } : undefined;
|
|
55
|
+
const definition = Object.assign({
|
|
56
|
+
type,
|
|
57
|
+
namespace: namespace ?? null
|
|
58
|
+
}, config, childrenConfig);
|
|
59
|
+
return Create(definition);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
vNode.ToFunction = ToFunction;
|
|
63
|
+
function Attach(node, vnode) {
|
|
64
|
+
Init(vnode);
|
|
65
|
+
nodeConfig_1.NodeConfig.addChild(node, vnode.node);
|
|
66
|
+
return vnode;
|
|
67
|
+
}
|
|
68
|
+
vNode.Attach = Attach;
|
|
69
|
+
})(vNode || (exports.vNode = vNode = {}));
|
|
70
|
+
function InitNode(vnode) {
|
|
71
|
+
const { type, namespace, props, attrs, on, data, componentConstructor, children, childrenArray } = vnode.definition;
|
|
72
|
+
const node = nodeConfig_1.NodeConfig.createNode(type, namespace);
|
|
73
|
+
vnode.node = node;
|
|
74
|
+
if (props) {
|
|
75
|
+
vnode.assignProperties = nodeConfig_1.NodeConfig.createPropertyAssignment(node);
|
|
76
|
+
if (typeof props === 'function') {
|
|
77
|
+
const scope = Store_1.ObservableScope.Create(props);
|
|
78
|
+
vnode.scopes.push(scope);
|
|
79
|
+
Store_1.ObservableScope.Watch(scope, CreateScheduledCallback(function () {
|
|
80
|
+
const value = Store_1.ObservableScope.Peek(scope);
|
|
81
|
+
vnode.assignProperties(value);
|
|
82
|
+
}));
|
|
83
|
+
const value = Store_1.ObservableScope.Peek(scope);
|
|
84
|
+
vnode.assignProperties(value);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
vnode.assignProperties(props);
|
|
88
|
+
vnode.assignProperties = null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (on) {
|
|
92
|
+
vnode.assignEvents = nodeConfig_1.NodeConfig.createEventAssignment(node);
|
|
93
|
+
if (typeof on === 'function') {
|
|
94
|
+
const scope = Store_1.ObservableScope.Create(on);
|
|
95
|
+
vnode.scopes.push(scope);
|
|
96
|
+
Store_1.ObservableScope.Watch(scope, CreateScheduledCallback(function () {
|
|
97
|
+
const value = Store_1.ObservableScope.Peek(scope);
|
|
98
|
+
vnode.assignEvents(value);
|
|
99
|
+
}));
|
|
100
|
+
const value = Store_1.ObservableScope.Peek(scope);
|
|
101
|
+
vnode.assignEvents(value);
|
|
102
|
+
}
|
|
103
|
+
else
|
|
104
|
+
vnode.assignEvents(on);
|
|
105
|
+
}
|
|
106
|
+
if (attrs) {
|
|
107
|
+
vnode.assignAttributes = nodeConfig_1.NodeConfig.createAttributeAssignment(node);
|
|
108
|
+
if (typeof attrs === 'function') {
|
|
109
|
+
const scope = Store_1.ObservableScope.Create(attrs);
|
|
110
|
+
vnode.scopes.push(scope);
|
|
111
|
+
Store_1.ObservableScope.Watch(scope, CreateScheduledCallback(function () {
|
|
112
|
+
const value = Store_1.ObservableScope.Peek(scope);
|
|
113
|
+
vnode.assignAttributes(value);
|
|
114
|
+
}));
|
|
115
|
+
const value = Store_1.ObservableScope.Peek(scope);
|
|
116
|
+
vnode.assignAttributes(value);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
vnode.assignAttributes(attrs);
|
|
120
|
+
vnode.assignAttributes = null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (componentConstructor) {
|
|
124
|
+
vnode.component = new componentConstructor(vnode);
|
|
125
|
+
const componentScope = Store_1.ObservableScope.Create(function () {
|
|
126
|
+
let nodes = vnode.component.Template();
|
|
127
|
+
if (!Array.isArray(nodes))
|
|
128
|
+
nodes = [nodes];
|
|
129
|
+
return nodes;
|
|
130
|
+
});
|
|
131
|
+
vnode.scopes.push(componentScope);
|
|
132
|
+
Store_1.ObservableScope.Watch(componentScope, CreateScheduledCallback(function () {
|
|
133
|
+
const nodes = Store_1.ObservableScope.Peek(componentScope);
|
|
134
|
+
vNode.DestroyAll(vnode.children);
|
|
135
|
+
vnode.children = nodes;
|
|
136
|
+
UpdateChildren(vnode);
|
|
137
|
+
}));
|
|
138
|
+
const nodes = Store_1.ObservableScope.Peek(componentScope);
|
|
139
|
+
vnode.children = nodes;
|
|
140
|
+
}
|
|
141
|
+
else if (childrenArray) {
|
|
142
|
+
vnode.children = childrenArray;
|
|
143
|
+
}
|
|
144
|
+
else if (children) {
|
|
145
|
+
if (data) {
|
|
146
|
+
DynamicChildren(vnode, children, ToArray(data));
|
|
147
|
+
}
|
|
148
|
+
else
|
|
149
|
+
StaticChildren(vnode, children);
|
|
150
|
+
}
|
|
151
|
+
UpdateChildren(vnode, true);
|
|
152
|
+
}
|
|
153
|
+
function StaticChildren(vnode, children) {
|
|
154
|
+
const childrenScope = Store_1.ObservableScope.Create(WrapStaticChildren(vnode.injector, children));
|
|
155
|
+
const child = Store_1.ObservableScope.Peek(childrenScope);
|
|
156
|
+
if (typeof child === 'string') {
|
|
157
|
+
const node = vNode.Create({
|
|
158
|
+
type: 'text',
|
|
159
|
+
namespace: null,
|
|
160
|
+
props() {
|
|
161
|
+
return { nodeValue: Store_1.ObservableScope.Value(childrenScope) };
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
node.scopes.push(childrenScope);
|
|
165
|
+
vnode.children = [node];
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
vnode.scopes.push(childrenScope);
|
|
169
|
+
Store_1.ObservableScope.Touch(childrenScope);
|
|
170
|
+
Store_1.ObservableScope.Watch(childrenScope, CreateScheduledCallback(function () {
|
|
171
|
+
vNode.DestroyAll(vnode.children);
|
|
172
|
+
const nodes = Store_1.ObservableScope.Peek(childrenScope);
|
|
173
|
+
vnode.children = Array.isArray(nodes) ? nodes : [nodes];
|
|
174
|
+
UpdateChildren(vnode);
|
|
175
|
+
}));
|
|
176
|
+
vnode.children = Array.isArray(child) ? child : [child];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function WrapStaticChildren(injector, children) {
|
|
180
|
+
return function () {
|
|
181
|
+
return injector_1.Injector.Scope(injector, children, undefined);
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function DestroyNodeList(nodeList) {
|
|
185
|
+
for (let node = nodeList.head; node !== null; node = node.next) {
|
|
186
|
+
vNode.DestroyAll(node.data.nodes);
|
|
187
|
+
Store_1.ObservableScope.Destroy(node.data.scope);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function DynamicChildren(vnode, children, data) {
|
|
191
|
+
const dataScope = Store_1.ObservableScope.Create(data);
|
|
192
|
+
vnode.scopes.push(dataScope);
|
|
193
|
+
const nodeList = list_1.List.Create();
|
|
194
|
+
const childrenScope = Store_1.ObservableScope.Create(WrapDynamicChildren(dataScope, nodeList, vnode.injector, children));
|
|
195
|
+
vnode.scopes.push(childrenScope);
|
|
196
|
+
Store_1.ObservableScope.OnDestroyed(dataScope, function () {
|
|
197
|
+
DestroyNodeList(nodeList);
|
|
198
|
+
});
|
|
199
|
+
Store_1.ObservableScope.Watch(childrenScope, CreateScheduledCallback(function () {
|
|
200
|
+
vnode.children = Store_1.ObservableScope.Peek(childrenScope);
|
|
201
|
+
UpdateChildren(vnode);
|
|
202
|
+
}));
|
|
203
|
+
vnode.children = Store_1.ObservableScope.Value(childrenScope);
|
|
204
|
+
}
|
|
205
|
+
function WrapDynamicChildren(dataScope, nodeList, injector, children) {
|
|
206
|
+
return function () {
|
|
207
|
+
const nextData = Store_1.ObservableScope.Value(dataScope);
|
|
208
|
+
const nodeMap = list_1.List.ToNodeMap(nodeList, function (data) { return data.data; });
|
|
209
|
+
const nextNodeList = list_1.List.Create();
|
|
210
|
+
const nextNodeArray = [];
|
|
211
|
+
for (let x = 0; x < nextData.length; x++) {
|
|
212
|
+
const data = nextData[x];
|
|
213
|
+
const existingNodeArray = nodeMap.get(data);
|
|
214
|
+
let existingNode = null;
|
|
215
|
+
;
|
|
216
|
+
for (let x = 0; existingNodeArray && x < existingNodeArray.length && existingNode === null; x++) {
|
|
217
|
+
existingNode = existingNodeArray[x];
|
|
218
|
+
existingNodeArray[x] = null;
|
|
219
|
+
}
|
|
220
|
+
if (existingNode !== null) {
|
|
221
|
+
list_1.List.RemoveNode(nodeList, existingNode);
|
|
222
|
+
list_1.List.AddNode(nextNodeList, existingNode);
|
|
223
|
+
if (existingNode.data.scope.dirty) {
|
|
224
|
+
const newNodes = Store_1.ObservableScope.Value(existingNode.data.scope);
|
|
225
|
+
vNode.DestroyAll(existingNode.data.nodes);
|
|
226
|
+
existingNode.data.nodes = newNodes;
|
|
227
|
+
existingNode.data.nodes = Store_1.ObservableScope.Value(existingNode.data.scope);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
const childrenScope = Store_1.ObservableScope.Create(function () {
|
|
232
|
+
const childNodes = injector_1.Injector.Scope(injector, children, data);
|
|
233
|
+
return Array.isArray(childNodes) ? childNodes : [childNodes];
|
|
234
|
+
});
|
|
235
|
+
list_1.List.Add(nextNodeList, {
|
|
236
|
+
data,
|
|
237
|
+
nodes: Store_1.ObservableScope.Value(childrenScope),
|
|
238
|
+
scope: childrenScope
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
nextNodeArray.push(...nextNodeList.tail.data.nodes);
|
|
242
|
+
}
|
|
243
|
+
DestroyNodeList(nodeList);
|
|
244
|
+
list_1.List.Clear(nodeList);
|
|
245
|
+
list_1.List.Append(nodeList, nextNodeList);
|
|
246
|
+
return nextNodeArray;
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function UpdateChildren(vnode, init = false) {
|
|
250
|
+
if (!vnode.children)
|
|
251
|
+
return;
|
|
252
|
+
const children = vnode.children;
|
|
253
|
+
(0, thread_1.Thread)(function () {
|
|
254
|
+
if (vnode.destroyed || children !== vnode.children)
|
|
255
|
+
return;
|
|
256
|
+
for (let x = 0; x < children.length; x++)
|
|
257
|
+
if (children[x].node === null) {
|
|
258
|
+
const childNode = children[x];
|
|
259
|
+
(0, thread_1.Schedule)(function () {
|
|
260
|
+
if (vnode.destroyed || children !== vnode.children)
|
|
261
|
+
return;
|
|
262
|
+
vNode.Init(childNode);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
(0, thread_1.Thread)(function (async) {
|
|
266
|
+
if (vnode.destroyed || children !== vnode.children)
|
|
267
|
+
return;
|
|
268
|
+
if (init || !async)
|
|
269
|
+
nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, vnode.children.map(vnode => vnode.node));
|
|
270
|
+
else
|
|
271
|
+
nodeConfig_1.NodeConfig.scheduleUpdate(function () {
|
|
272
|
+
if (vnode.destroyed || children !== vnode.children)
|
|
273
|
+
return;
|
|
274
|
+
nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, vnode.children.map(vnode => vnode.node));
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
function ToArray(callback) {
|
|
280
|
+
return function (...args) {
|
|
281
|
+
const result = callback(...args);
|
|
282
|
+
if (Array.isArray(result))
|
|
283
|
+
return result;
|
|
284
|
+
if (!result)
|
|
285
|
+
return [];
|
|
286
|
+
return [result];
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function CreateScheduledCallback(callback) {
|
|
290
|
+
let scheduled = false;
|
|
291
|
+
return function () {
|
|
292
|
+
if (scheduled)
|
|
293
|
+
return;
|
|
294
|
+
nodeConfig_1.NodeConfig.scheduleUpdate(callback);
|
|
295
|
+
};
|
|
296
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Component } from "./component";
|
|
2
|
+
import { IObservableScope } from "../Store/Tree/observableScope";
|
|
3
|
+
import { Injector } from "../Utils/injector";
|
|
4
|
+
import { RecursivePartial } from "../Utils/utils.types";
|
|
5
|
+
export type FunctionOr<T> = {
|
|
6
|
+
(): T | Promise<T>;
|
|
7
|
+
} | T;
|
|
8
|
+
export type vNodeEvents<E extends {
|
|
9
|
+
[event: string]: any;
|
|
10
|
+
} = any> = {
|
|
11
|
+
[P in keyof E]?: {
|
|
12
|
+
(events: E[P]): void;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export type vNode = {
|
|
16
|
+
definition: vNodeDefinition<any, any, any>;
|
|
17
|
+
injector: Injector;
|
|
18
|
+
node: Node | null;
|
|
19
|
+
children: vNode[] | null;
|
|
20
|
+
destroyed: boolean;
|
|
21
|
+
assignProperties: (next: any) => void;
|
|
22
|
+
assignEvents: (next: {
|
|
23
|
+
[event: string]: (event: Event) => void;
|
|
24
|
+
}) => void;
|
|
25
|
+
assignAttributes: (next: {
|
|
26
|
+
[attr: string]: string;
|
|
27
|
+
}) => void;
|
|
28
|
+
scopes: IObservableScope<unknown>[];
|
|
29
|
+
component: Component;
|
|
30
|
+
};
|
|
31
|
+
export type vNodeDefinition<P = HTMLElement, E = HTMLElementEventMap, T = never> = {
|
|
32
|
+
type: string;
|
|
33
|
+
namespace: string | null;
|
|
34
|
+
props?: FunctionOr<RecursivePartial<P>>;
|
|
35
|
+
attrs?: FunctionOr<{
|
|
36
|
+
[name: string]: string;
|
|
37
|
+
}>;
|
|
38
|
+
on?: FunctionOr<vNodeEvents<E>>;
|
|
39
|
+
data?: () => T | Array<T> | Promise<Array<T>> | Promise<T>;
|
|
40
|
+
children?: (data: T) => string | vNode | vNode[];
|
|
41
|
+
childrenArray?: vNode[];
|
|
42
|
+
componentConstructor?: {
|
|
43
|
+
new (vnode: vNode): Component<any, any, any>;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
@@ -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 {
|
|
@@ -54,13 +52,14 @@ export declare namespace ObservableScope {
|
|
|
54
52
|
}): IObservableScope<T>;
|
|
55
53
|
function Register(emitter: Emitter): void;
|
|
56
54
|
function Init<T>(scope: IObservableScope<T>): void;
|
|
55
|
+
function Peek<T>(scope: IObservableScope<T>): T;
|
|
57
56
|
function Value<T>(scope: IObservableScope<T>): T;
|
|
58
|
-
function Watching(): boolean;
|
|
59
57
|
function Touch<T>(scope: IObservableScope<T>): void;
|
|
60
58
|
function Watch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T>]>): void;
|
|
61
59
|
function Unwatch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T> | ObservableScopeValue<T>]>): void;
|
|
62
60
|
function OnDestroyed(scope: IObservableScope<unknown>, callback: () => void): void;
|
|
63
61
|
function Update(scope: IObservableScope<any>): void;
|
|
64
62
|
function Destroy<T>(scope: IObservableScope<T>): void;
|
|
63
|
+
function DestroyAll(scopes: IObservableScope<unknown>[]): void;
|
|
65
64
|
}
|
|
66
65
|
export {};
|
|
@@ -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 distinctArray_1 = require("../../Utils/distinctArray");
|
|
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,24 @@ 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 = [distinctArray_1.DistinctArray.Create(emitter_1.Emitter.GetId), []];
|
|
58
55
|
const value = scope.getFunction();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
const emitters = distinctArray_1.DistinctArray.Get(watchState[0]);
|
|
57
|
+
emitters.sort(emitter_1.Emitter.Compare);
|
|
58
|
+
const result = [value, emitters, watchState[1]];
|
|
59
|
+
watchState = parent;
|
|
60
|
+
return result;
|
|
63
61
|
}
|
|
64
62
|
function CalcScope(callback) {
|
|
65
63
|
const value = callback();
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
watchingScope.calcFunctions.push({
|
|
64
|
+
if (watchState !== null)
|
|
65
|
+
watchState[1].push({
|
|
69
66
|
getFunction: callback,
|
|
70
67
|
value
|
|
71
68
|
});
|
|
72
|
-
}
|
|
73
69
|
return value;
|
|
74
70
|
}
|
|
75
71
|
(function (ObservableScope) {
|
|
@@ -82,11 +78,9 @@ function CalcScope(callback) {
|
|
|
82
78
|
dirty: true,
|
|
83
79
|
emitter: emitter_1.Emitter.Create(),
|
|
84
80
|
emitters: [],
|
|
85
|
-
calcFunctions:
|
|
81
|
+
calcFunctions: [],
|
|
86
82
|
onDestroyed: null,
|
|
87
83
|
destroyed: false,
|
|
88
|
-
watchEmitters: null,
|
|
89
|
-
watchEmittersSet: null,
|
|
90
84
|
setCallback: function () {
|
|
91
85
|
return OnSet(scope);
|
|
92
86
|
},
|
|
@@ -95,35 +89,31 @@ function CalcScope(callback) {
|
|
|
95
89
|
}
|
|
96
90
|
ObservableScope.Create = Create;
|
|
97
91
|
function Register(emitter) {
|
|
98
|
-
if (
|
|
92
|
+
if (watchState === null)
|
|
99
93
|
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
|
-
}
|
|
94
|
+
distinctArray_1.DistinctArray.Push(watchState[0], emitter);
|
|
107
95
|
}
|
|
108
96
|
ObservableScope.Register = Register;
|
|
109
97
|
function Init(scope) {
|
|
110
98
|
if (!scope)
|
|
111
99
|
return;
|
|
112
|
-
|
|
100
|
+
UpdateValue(scope);
|
|
113
101
|
}
|
|
114
102
|
ObservableScope.Init = Init;
|
|
115
|
-
function
|
|
103
|
+
function Peek(scope) {
|
|
116
104
|
if (!scope)
|
|
117
105
|
return undefined;
|
|
118
|
-
|
|
119
|
-
UpdateScope(scope);
|
|
106
|
+
UpdateValue(scope);
|
|
120
107
|
return scope.value;
|
|
121
108
|
}
|
|
122
|
-
ObservableScope.
|
|
123
|
-
function
|
|
124
|
-
|
|
109
|
+
ObservableScope.Peek = Peek;
|
|
110
|
+
function Value(scope) {
|
|
111
|
+
if (!scope)
|
|
112
|
+
return undefined;
|
|
113
|
+
Touch(scope);
|
|
114
|
+
return Peek(scope);
|
|
125
115
|
}
|
|
126
|
-
ObservableScope.
|
|
116
|
+
ObservableScope.Value = Value;
|
|
127
117
|
function Touch(scope) {
|
|
128
118
|
if (!scope || !scope.emitter)
|
|
129
119
|
return;
|
|
@@ -148,6 +138,8 @@ function CalcScope(callback) {
|
|
|
148
138
|
}
|
|
149
139
|
ObservableScope.OnDestroyed = OnDestroyed;
|
|
150
140
|
function Update(scope) {
|
|
141
|
+
if (!scope || scope.dirty || scope.destroyed)
|
|
142
|
+
return;
|
|
151
143
|
OnSet(scope);
|
|
152
144
|
}
|
|
153
145
|
ObservableScope.Update = Update;
|
|
@@ -155,26 +147,12 @@ function CalcScope(callback) {
|
|
|
155
147
|
DestroyScope(scope);
|
|
156
148
|
}
|
|
157
149
|
ObservableScope.Destroy = Destroy;
|
|
150
|
+
function DestroyAll(scopes) {
|
|
151
|
+
for (let x = 0; x < scopes.length; x++)
|
|
152
|
+
Destroy(scopes[x]);
|
|
153
|
+
}
|
|
154
|
+
ObservableScope.DestroyAll = DestroyAll;
|
|
158
155
|
})(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
156
|
function CalcChanged(calc) {
|
|
179
157
|
const value = calc.getFunction();
|
|
180
158
|
const changed = calc.value !== value;
|
|
@@ -182,22 +160,43 @@ function CalcChanged(calc) {
|
|
|
182
160
|
return changed;
|
|
183
161
|
}
|
|
184
162
|
function DirtyScope(scope) {
|
|
185
|
-
scope.dirty
|
|
186
|
-
|
|
163
|
+
if (scope.dirty || !scope.getFunction)
|
|
164
|
+
return;
|
|
165
|
+
scope.dirty = scope.calcFunctions.length === 0 || scope.calcFunctions.some(CalcChanged);
|
|
166
|
+
if (!scope.dirty)
|
|
167
|
+
return;
|
|
168
|
+
if (scope.async) {
|
|
169
|
+
UpdateValue(scope);
|
|
170
|
+
scope.promise.then(function () {
|
|
171
|
+
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else
|
|
175
|
+
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
176
|
+
}
|
|
177
|
+
const scopeQueue = new Set();
|
|
178
|
+
function ProcessScopeQueue() {
|
|
179
|
+
const scopes = Array.from(scopeQueue);
|
|
180
|
+
scopeQueue.clear();
|
|
181
|
+
for (let x = 0; x < scopes.length; x++)
|
|
182
|
+
DirtyScope(scopes[x]);
|
|
187
183
|
}
|
|
188
184
|
function OnSet(scope) {
|
|
189
|
-
if (
|
|
190
|
-
return
|
|
185
|
+
if (scope.destroyed)
|
|
186
|
+
return true;
|
|
187
|
+
if (scope.async || scope.calcFunctions.length > 0) {
|
|
188
|
+
if (scopeQueue.size === 0)
|
|
189
|
+
queueMicrotask(ProcessScopeQueue);
|
|
190
|
+
scopeQueue.add(scope);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
191
193
|
DirtyScope(scope);
|
|
192
|
-
return false;
|
|
193
194
|
}
|
|
194
195
|
function UpdateValue(scope) {
|
|
195
196
|
if (!scope.dirty)
|
|
196
197
|
return;
|
|
197
198
|
scope.dirty = false;
|
|
198
|
-
|
|
199
|
-
scope.calcFunctions = null;
|
|
200
|
-
const value = WatchScope(scope);
|
|
199
|
+
const [value, emitters, calcFunctions] = WatchScope(scope);
|
|
201
200
|
if (scope.async) {
|
|
202
201
|
scope.promise = value.then(function (result) {
|
|
203
202
|
scope.value = result;
|
|
@@ -206,11 +205,11 @@ function UpdateValue(scope) {
|
|
|
206
205
|
}
|
|
207
206
|
else
|
|
208
207
|
scope.value = value;
|
|
209
|
-
|
|
208
|
+
scope.calcFunctions = calcFunctions;
|
|
209
|
+
UpdateEmitters(scope, emitters);
|
|
210
210
|
}
|
|
211
|
-
function UpdateEmitters(scope) {
|
|
212
|
-
|
|
213
|
-
if (right === null) {
|
|
211
|
+
function UpdateEmitters(scope, right) {
|
|
212
|
+
if (right.length === 0) {
|
|
214
213
|
if (scope.emitters.length > 0) {
|
|
215
214
|
for (let x = 0; x < scope.emitters.length; x++)
|
|
216
215
|
emitter_1.Emitter.Remove(scope.emitters[x], scope.setCallback);
|
|
@@ -218,7 +217,6 @@ function UpdateEmitters(scope) {
|
|
|
218
217
|
}
|
|
219
218
|
return;
|
|
220
219
|
}
|
|
221
|
-
emitter_1.Emitter.Sort(right);
|
|
222
220
|
(0, array_1.ReconcileSortedArrays)(scope.emitters, right, function (emitter) {
|
|
223
221
|
emitter_1.Emitter.On(emitter, scope.setCallback);
|
|
224
222
|
}, 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 {};
|