j-templates 7.0.51 → 7.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOM/domNodeConfig.d.ts +1 -1
- package/DOM/domNodeConfig.js +25 -11
- package/Node/vNode.d.ts +1 -0
- package/Node/vNode.js +50 -12
- package/Node/vNode.types.d.ts +2 -0
- package/Store/Tree/observableNode.d.ts +1 -0
- package/Store/Tree/observableNode.js +9 -0
- package/Store/Tree/observableScope.d.ts +7 -11
- package/Store/Tree/observableScope.js +42 -30
- package/Utils/array.d.ts +1 -0
- package/Utils/array.js +14 -0
- package/Utils/decorators.js +9 -9
- package/Utils/distinctArray.d.ts +5 -3
- package/Utils/distinctArray.js +20 -11
- package/Utils/emitter.d.ts +1 -1
- package/Utils/emitter.js +10 -6
- package/Utils/injector.d.ts +1 -1
- package/Utils/injector.js +12 -10
- package/Utils/thread.js +9 -5
- package/package.json +1 -1
package/DOM/domNodeConfig.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { INodeConfig } from
|
|
1
|
+
import { INodeConfig } from "../Node/nodeConfig";
|
|
2
2
|
export declare const DOMNodeConfig: INodeConfig;
|
package/DOM/domNodeConfig.js
CHANGED
|
@@ -51,13 +51,13 @@ function wrapPriorityUpdates(callback) {
|
|
|
51
51
|
}
|
|
52
52
|
exports.DOMNodeConfig = {
|
|
53
53
|
createNode(type, namespace) {
|
|
54
|
-
if (type ===
|
|
55
|
-
return window_1.wndw.document.createTextNode(
|
|
56
|
-
return namespace
|
|
57
|
-
window_1.wndw.document.createElementNS(namespace, type)
|
|
58
|
-
window_1.wndw.document.createElement(type);
|
|
54
|
+
if (type === "text")
|
|
55
|
+
return window_1.wndw.document.createTextNode("");
|
|
56
|
+
return namespace
|
|
57
|
+
? window_1.wndw.document.createElementNS(namespace, type)
|
|
58
|
+
: window_1.wndw.document.createElement(type);
|
|
59
59
|
},
|
|
60
|
-
createTextNode(value =
|
|
60
|
+
createTextNode(value = "") {
|
|
61
61
|
return window_1.wndw.document.createTextNode(value);
|
|
62
62
|
},
|
|
63
63
|
isTextNode(target) {
|
|
@@ -143,8 +143,15 @@ exports.DOMNodeConfig = {
|
|
|
143
143
|
},
|
|
144
144
|
reconcileChildren(target, children) {
|
|
145
145
|
if (!target.firstChild) {
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
if (children.length > 10) {
|
|
147
|
+
const fragment = new DocumentFragment();
|
|
148
|
+
for (let x = 0; x < children.length; x++)
|
|
149
|
+
fragment.appendChild(children[x]);
|
|
150
|
+
target.appendChild(fragment);
|
|
151
|
+
}
|
|
152
|
+
else
|
|
153
|
+
for (let x = 0; x < children.length; x++)
|
|
154
|
+
target.appendChild(children[x]);
|
|
148
155
|
return;
|
|
149
156
|
}
|
|
150
157
|
if (children.length === 0) {
|
|
@@ -172,7 +179,14 @@ exports.DOMNodeConfig = {
|
|
|
172
179
|
}
|
|
173
180
|
while (target.lastChild !== children[x - 1])
|
|
174
181
|
target.removeChild(target.lastChild);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
182
|
+
if (children.length - x > 10) {
|
|
183
|
+
const fragment = new DocumentFragment();
|
|
184
|
+
for (; x < children.length; x++)
|
|
185
|
+
fragment.appendChild(children[x]);
|
|
186
|
+
target.appendChild(fragment);
|
|
187
|
+
}
|
|
188
|
+
else
|
|
189
|
+
for (; x < children.length; x++)
|
|
190
|
+
target.appendChild(children[x]);
|
|
191
|
+
},
|
|
178
192
|
};
|
package/Node/vNode.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ type vNodeConfig<P = HTMLElement, E = HTMLElementEventMap, T = never> = {
|
|
|
10
10
|
};
|
|
11
11
|
export declare namespace vNode {
|
|
12
12
|
function Create<P = HTMLElement, E = HTMLElementEventMap, T = never>(definition: vNodeDefinition<P, E, T>): vNodeType;
|
|
13
|
+
function CreateText(text: string): vNodeType;
|
|
13
14
|
function Init(vnode: vNodeType): void;
|
|
14
15
|
function InitAll(vnodes: vNodeType[]): void;
|
|
15
16
|
function Destroy(vnode: vNodeType): void;
|
package/Node/vNode.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.vNode = void 0;
|
|
4
4
|
const Store_1 = require("../Store");
|
|
5
|
+
const emitter_1 = require("../Utils/emitter");
|
|
5
6
|
const injector_1 = require("../Utils/injector");
|
|
6
7
|
const list_1 = require("../Utils/list");
|
|
7
8
|
const thread_1 = require("../Utils/thread");
|
|
@@ -16,11 +17,26 @@ var vNode;
|
|
|
16
17
|
node: definition.node ?? null,
|
|
17
18
|
children: null,
|
|
18
19
|
destroyed: false,
|
|
20
|
+
onDestroyed: null,
|
|
19
21
|
component: null,
|
|
20
22
|
scopes: [],
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
25
|
vNode.Create = Create;
|
|
26
|
+
function CreateText(text) {
|
|
27
|
+
return {
|
|
28
|
+
definition: null,
|
|
29
|
+
type: "text",
|
|
30
|
+
injector: null,
|
|
31
|
+
node: nodeConfig_1.NodeConfig.createTextNode(text),
|
|
32
|
+
children: null,
|
|
33
|
+
destroyed: false,
|
|
34
|
+
onDestroyed: null,
|
|
35
|
+
component: null,
|
|
36
|
+
scopes: [],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
vNode.CreateText = CreateText;
|
|
24
40
|
function Init(vnode) {
|
|
25
41
|
if (vnode.definition === null)
|
|
26
42
|
return;
|
|
@@ -38,6 +54,7 @@ var vNode;
|
|
|
38
54
|
vnode.destroyed = true;
|
|
39
55
|
vnode.component?.Destroy();
|
|
40
56
|
Store_1.ObservableScope.DestroyAll(vnode.scopes);
|
|
57
|
+
vnode.onDestroyed && emitter_1.Emitter.Emit(vnode.onDestroyed);
|
|
41
58
|
vnode.children && DestroyAll(vnode.children);
|
|
42
59
|
}
|
|
43
60
|
vNode.Destroy = Destroy;
|
|
@@ -70,7 +87,8 @@ var vNode;
|
|
|
70
87
|
})(vNode || (exports.vNode = vNode = {}));
|
|
71
88
|
function InitNode(vnode) {
|
|
72
89
|
const { type, namespace, props, attrs, on, data, componentConstructor, children, childrenArray, } = vnode.definition;
|
|
73
|
-
const node = (vnode.node =
|
|
90
|
+
const node = (vnode.node =
|
|
91
|
+
vnode.definition.node ?? nodeConfig_1.NodeConfig.createNode(type, namespace));
|
|
74
92
|
vnode.definition = null;
|
|
75
93
|
if (props) {
|
|
76
94
|
const assignProperties = nodeConfig_1.NodeConfig.createPropertyAssignment(node);
|
|
@@ -95,6 +113,11 @@ function InitNode(vnode) {
|
|
|
95
113
|
}
|
|
96
114
|
else
|
|
97
115
|
assignEvents(on);
|
|
116
|
+
vnode.onDestroyed ??= emitter_1.Emitter.Create();
|
|
117
|
+
emitter_1.Emitter.On(vnode.onDestroyed, function () {
|
|
118
|
+
assignEvents(null);
|
|
119
|
+
return true;
|
|
120
|
+
});
|
|
98
121
|
}
|
|
99
122
|
if (attrs) {
|
|
100
123
|
const assignAttributes = nodeConfig_1.NodeConfig.createAttributeAssignment(node);
|
|
@@ -112,7 +135,9 @@ function InitNode(vnode) {
|
|
|
112
135
|
vnode.component = new componentConstructor(vnode);
|
|
113
136
|
vnode.component.Bound();
|
|
114
137
|
const componentScope = Store_1.ObservableScope.Create(function () {
|
|
115
|
-
let nodes = injector_1.Injector.Scope(vnode.injector, function () {
|
|
138
|
+
let nodes = injector_1.Injector.Scope(vnode.injector, function () {
|
|
139
|
+
return vnode.component.Template();
|
|
140
|
+
});
|
|
116
141
|
if (!Array.isArray(nodes))
|
|
117
142
|
nodes = [nodes];
|
|
118
143
|
return nodes;
|
|
@@ -144,8 +169,9 @@ function Children(vnode, children, data) {
|
|
|
144
169
|
Store_1.ObservableScope.Watch(childrenScope, CreateScheduledCallback(function (scope) {
|
|
145
170
|
if (vnode.destroyed)
|
|
146
171
|
return;
|
|
172
|
+
const startChildren = vnode.children;
|
|
147
173
|
AssignChildren(vnode, scope);
|
|
148
|
-
UpdateChildren(vnode);
|
|
174
|
+
startChildren !== vnode.children && UpdateChildren(vnode);
|
|
149
175
|
}));
|
|
150
176
|
AssignChildren(vnode, childrenScope);
|
|
151
177
|
}
|
|
@@ -166,6 +192,7 @@ function CreateChildrenScope(vnode, children, data) {
|
|
|
166
192
|
Store_1.ObservableScope.OnDestroyed(scope, function () {
|
|
167
193
|
DestroyNodeList(nodeList);
|
|
168
194
|
Store_1.ObservableScope.Destroy(dataScope);
|
|
195
|
+
return true;
|
|
169
196
|
});
|
|
170
197
|
return scope;
|
|
171
198
|
}
|
|
@@ -209,7 +236,7 @@ function WrapChildren(injector, children, data, nodeList) {
|
|
|
209
236
|
list_1.List.Add(nextNodeList, {
|
|
210
237
|
data,
|
|
211
238
|
nodes: Store_1.ObservableScope.Value(childrenScope),
|
|
212
|
-
scope: childrenScope
|
|
239
|
+
scope: childrenScope,
|
|
213
240
|
});
|
|
214
241
|
}
|
|
215
242
|
nextNodeArray.push(...nextNodeList.tail.data.nodes);
|
|
@@ -225,14 +252,21 @@ function WrapChildren(injector, children, data, nodeList) {
|
|
|
225
252
|
function CreateNodeArray(children, previousChildren) {
|
|
226
253
|
if (Array.isArray(children))
|
|
227
254
|
return children;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
node
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
255
|
+
if (typeof children === "string") {
|
|
256
|
+
const firstPrevChild = previousChildren?.[0];
|
|
257
|
+
if (firstPrevChild &&
|
|
258
|
+
firstPrevChild.node &&
|
|
259
|
+
firstPrevChild.type === "text") {
|
|
260
|
+
nodeConfig_1.NodeConfig.setText(firstPrevChild.node, children);
|
|
261
|
+
return previousChildren.length === 1
|
|
262
|
+
? previousChildren
|
|
263
|
+
: [firstPrevChild];
|
|
264
|
+
}
|
|
265
|
+
return [
|
|
266
|
+
vNode.CreateText(children),
|
|
267
|
+
];
|
|
268
|
+
}
|
|
269
|
+
return [children];
|
|
236
270
|
}
|
|
237
271
|
function DestroyNodeList(nodeList) {
|
|
238
272
|
for (let node = nodeList.head; node !== null; node = node.next) {
|
|
@@ -251,6 +285,10 @@ function AssignChildren(vnode, childrenScope) {
|
|
|
251
285
|
function UpdateChildren(vnode, init = false, skipInit = false) {
|
|
252
286
|
if (!vnode.children)
|
|
253
287
|
return;
|
|
288
|
+
if (vnode.children.length === 1 && vnode.children[0].type === "text") {
|
|
289
|
+
nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, [vnode.children[0].node]);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
254
292
|
const children = vnode.children;
|
|
255
293
|
(0, thread_1.Thread)(function () {
|
|
256
294
|
if (vnode.destroyed || children !== vnode.children)
|
package/Node/vNode.types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Component } from "./component";
|
|
|
2
2
|
import { IObservableScope } from "../Store/Tree/observableScope";
|
|
3
3
|
import { Injector } from "../Utils/injector";
|
|
4
4
|
import { RecursivePartial } from "../Utils/utils.types";
|
|
5
|
+
import { Emitter } from "../Utils/emitter";
|
|
5
6
|
export type FunctionOr<T> = {
|
|
6
7
|
(): T | Promise<T>;
|
|
7
8
|
} | T;
|
|
@@ -20,6 +21,7 @@ export type vNode = {
|
|
|
20
21
|
node: Node | null;
|
|
21
22
|
children: vNode[] | null;
|
|
22
23
|
destroyed: boolean;
|
|
24
|
+
onDestroyed: Emitter | null;
|
|
23
25
|
scopes: IObservableScope<unknown>[];
|
|
24
26
|
component: Component;
|
|
25
27
|
};
|
|
@@ -3,6 +3,7 @@ export declare const IS_OBSERVABLE_NODE = "____isObservableNode";
|
|
|
3
3
|
export declare const GET_OBSERVABLE_VALUE = "____getObservableValue";
|
|
4
4
|
export declare const GET_TO_JSON = "toJSON";
|
|
5
5
|
export declare namespace ObservableNode {
|
|
6
|
+
function BypassProxy(value: boolean): void;
|
|
6
7
|
function Create<T>(value: T): T;
|
|
7
8
|
function Touch(value: unknown, prop?: string | number): void;
|
|
8
9
|
function ApplyDiff(rootNode: any, diffResult: JsonDiffResult): void;
|
|
@@ -4,6 +4,7 @@ exports.ObservableNode = exports.GET_TO_JSON = exports.GET_OBSERVABLE_VALUE = ex
|
|
|
4
4
|
const json_1 = require("../../Utils/json");
|
|
5
5
|
const jsonType_1 = require("../../Utils/jsonType");
|
|
6
6
|
const observableScope_1 = require("./observableScope");
|
|
7
|
+
let bypassProxy = false;
|
|
7
8
|
exports.IS_OBSERVABLE_NODE = "____isObservableNode";
|
|
8
9
|
exports.GET_OBSERVABLE_VALUE = "____getObservableValue";
|
|
9
10
|
exports.GET_TO_JSON = "toJSON";
|
|
@@ -146,6 +147,8 @@ function CreateProxyFactory(alias) {
|
|
|
146
147
|
const scope = scopeCache.get(array);
|
|
147
148
|
array = observableScope_1.ObservableScope.Value(scope);
|
|
148
149
|
const arrayValue = array[prop];
|
|
150
|
+
if (bypassProxy)
|
|
151
|
+
return arrayValue;
|
|
149
152
|
if (typeof prop === "symbol")
|
|
150
153
|
return arrayValue;
|
|
151
154
|
if (typeof arrayValue === "function")
|
|
@@ -221,6 +224,8 @@ function CreateProxyFactory(alias) {
|
|
|
221
224
|
case exports.GET_OBSERVABLE_VALUE:
|
|
222
225
|
return object;
|
|
223
226
|
default: {
|
|
227
|
+
if (bypassProxy)
|
|
228
|
+
return object[prop];
|
|
224
229
|
return GetAccessorValue(object, prop);
|
|
225
230
|
}
|
|
226
231
|
}
|
|
@@ -259,6 +264,10 @@ function CreateProxyFactory(alias) {
|
|
|
259
264
|
const DefaultCreateProxy = CreateProxyFactory();
|
|
260
265
|
var ObservableNode;
|
|
261
266
|
(function (ObservableNode) {
|
|
267
|
+
function BypassProxy(value) {
|
|
268
|
+
bypassProxy = value;
|
|
269
|
+
}
|
|
270
|
+
ObservableNode.BypassProxy = BypassProxy;
|
|
262
271
|
function Create(value) {
|
|
263
272
|
return DefaultCreateProxy(value);
|
|
264
273
|
}
|
|
@@ -24,12 +24,6 @@ export declare class ObservableScope<T> extends ObservableScopeWrapper<T> {
|
|
|
24
24
|
(): T | Promise<T>;
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
-
interface ICalcFunction<T> {
|
|
28
|
-
getFunction: {
|
|
29
|
-
(): T;
|
|
30
|
-
};
|
|
31
|
-
value: T;
|
|
32
|
-
}
|
|
33
27
|
export interface IObservableScope<T> extends IDestroyable {
|
|
34
28
|
getFunction: {
|
|
35
29
|
(): T;
|
|
@@ -41,15 +35,18 @@ export interface IObservableScope<T> extends IDestroyable {
|
|
|
41
35
|
dirty: boolean;
|
|
42
36
|
emitter: Emitter;
|
|
43
37
|
emitters: (Emitter | null)[];
|
|
44
|
-
|
|
38
|
+
calcScopes: {
|
|
39
|
+
[id: string]: IObservableScope<unknown> | null;
|
|
40
|
+
} | null;
|
|
41
|
+
calc: boolean;
|
|
45
42
|
onDestroyed: Emitter | null;
|
|
46
43
|
destroyed: boolean;
|
|
47
44
|
}
|
|
48
|
-
export declare function CalcScope<T>(callback: () => T):
|
|
45
|
+
export declare function CalcScope<T>(callback: () => T, idOverride?: string): unknown;
|
|
49
46
|
export declare namespace ObservableScope {
|
|
50
47
|
function Create<T>(valueFunction: {
|
|
51
48
|
(): T | Promise<T>;
|
|
52
|
-
}): IObservableScope<T>;
|
|
49
|
+
}, calc?: boolean): IObservableScope<T>;
|
|
53
50
|
function Register(emitter: Emitter): void;
|
|
54
51
|
function Init<T>(scope: IObservableScope<T>): void;
|
|
55
52
|
function Peek<T>(scope: IObservableScope<T>): T;
|
|
@@ -57,9 +54,8 @@ export declare namespace ObservableScope {
|
|
|
57
54
|
function Touch<T>(scope: IObservableScope<T>): void;
|
|
58
55
|
function Watch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T>]>): void;
|
|
59
56
|
function Unwatch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T> | ObservableScopeValue<T>]>): void;
|
|
60
|
-
function OnDestroyed(scope: IObservableScope<unknown>, callback:
|
|
57
|
+
function OnDestroyed(scope: IObservableScope<unknown>, callback: EmitterCallback): void;
|
|
61
58
|
function Update(scope: IObservableScope<any>): void;
|
|
62
59
|
function Destroy<T>(scope: IObservableScope<T>): void;
|
|
63
60
|
function DestroyAll(scopes: IObservableScope<unknown>[]): void;
|
|
64
61
|
}
|
|
65
|
-
export {};
|
|
@@ -51,25 +51,37 @@ exports.ObservableScope = ObservableScope;
|
|
|
51
51
|
let watchState = null;
|
|
52
52
|
function WatchScope(scope) {
|
|
53
53
|
const parent = watchState;
|
|
54
|
-
watchState = [[],
|
|
54
|
+
watchState = [[], scope.calcScopes, null];
|
|
55
55
|
const value = scope.getFunction();
|
|
56
56
|
const emitters = watchState[0];
|
|
57
|
-
|
|
58
|
-
const
|
|
57
|
+
UpdateEmitters(scope, emitters);
|
|
58
|
+
const calcScopes = watchState[1];
|
|
59
|
+
const calcScopeValues = calcScopes && Object.values(calcScopes);
|
|
60
|
+
for (let x = 0; calcScopeValues && x < calcScopeValues.length; x++)
|
|
61
|
+
calcScopeValues[x] && ObservableScope.Destroy(calcScopeValues[x]);
|
|
62
|
+
scope.calcScopes = watchState[2];
|
|
59
63
|
watchState = parent;
|
|
60
|
-
return result;
|
|
61
|
-
}
|
|
62
|
-
function CalcScope(callback) {
|
|
63
|
-
const value = callback();
|
|
64
|
-
if (watchState !== null)
|
|
65
|
-
watchState[1].push({
|
|
66
|
-
getFunction: callback,
|
|
67
|
-
value,
|
|
68
|
-
});
|
|
69
64
|
return value;
|
|
70
65
|
}
|
|
66
|
+
function CalcScope(callback, idOverride) {
|
|
67
|
+
if (watchState === null)
|
|
68
|
+
return callback();
|
|
69
|
+
const nextScopes = (watchState[2] ??= {});
|
|
70
|
+
const currentScopes = watchState[1];
|
|
71
|
+
const id = idOverride ?? callback.toString();
|
|
72
|
+
const currentScope = currentScopes?.[id];
|
|
73
|
+
if (currentScope) {
|
|
74
|
+
delete currentScopes[id];
|
|
75
|
+
nextScopes[id] = currentScope;
|
|
76
|
+
}
|
|
77
|
+
else if (!nextScopes[id]) {
|
|
78
|
+
const scope = ObservableScope.Create(callback, true);
|
|
79
|
+
nextScopes[id] = scope;
|
|
80
|
+
}
|
|
81
|
+
return ObservableScope.Value(nextScopes[id]);
|
|
82
|
+
}
|
|
71
83
|
(function (ObservableScope) {
|
|
72
|
-
function Create(valueFunction) {
|
|
84
|
+
function Create(valueFunction, calc = false) {
|
|
73
85
|
const scope = {
|
|
74
86
|
getFunction: valueFunction,
|
|
75
87
|
value: null,
|
|
@@ -78,9 +90,10 @@ function CalcScope(callback) {
|
|
|
78
90
|
dirty: true,
|
|
79
91
|
emitter: emitter_1.Emitter.Create(),
|
|
80
92
|
emitters: null,
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
calcScopes: null,
|
|
94
|
+
calc,
|
|
83
95
|
destroyed: false,
|
|
96
|
+
onDestroyed: null,
|
|
84
97
|
setCallback: function () {
|
|
85
98
|
return OnSet(scope);
|
|
86
99
|
},
|
|
@@ -156,16 +169,13 @@ function CalcScope(callback) {
|
|
|
156
169
|
function DirtyScope(scope) {
|
|
157
170
|
if (scope.dirty || !scope.getFunction)
|
|
158
171
|
return;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
scope.dirty = dirty;
|
|
165
|
-
if (!scope.dirty)
|
|
166
|
-
return;
|
|
167
|
-
if (scope.async) {
|
|
172
|
+
scope.dirty = true;
|
|
173
|
+
if (scope.async)
|
|
174
|
+
UpdateValue(scope);
|
|
175
|
+
else if (scope.calc) {
|
|
176
|
+
const startValue = scope.value;
|
|
168
177
|
UpdateValue(scope);
|
|
178
|
+
startValue !== scope.value && emitter_1.Emitter.Emit(scope.emitter);
|
|
169
179
|
}
|
|
170
180
|
else
|
|
171
181
|
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
@@ -185,7 +195,7 @@ function ProcessScopeQueue() {
|
|
|
185
195
|
function OnSet(scope) {
|
|
186
196
|
if (scope.destroyed)
|
|
187
197
|
return true;
|
|
188
|
-
if (scope.async || scope.
|
|
198
|
+
if (scope.async || scope.calc) {
|
|
189
199
|
if (scopeQueue.length === 0)
|
|
190
200
|
queueMicrotask(ProcessScopeQueue);
|
|
191
201
|
scopeQueue.push(scope);
|
|
@@ -197,7 +207,7 @@ function UpdateValue(scope) {
|
|
|
197
207
|
if (!scope.dirty)
|
|
198
208
|
return;
|
|
199
209
|
scope.dirty = false;
|
|
200
|
-
const
|
|
210
|
+
const value = WatchScope(scope);
|
|
201
211
|
if (scope.async) {
|
|
202
212
|
scope.promise = value.then(function (result) {
|
|
203
213
|
if (scope.destroyed)
|
|
@@ -209,10 +219,9 @@ function UpdateValue(scope) {
|
|
|
209
219
|
}
|
|
210
220
|
else
|
|
211
221
|
scope.value = value;
|
|
212
|
-
scope.calcFunctions = calcFunctions;
|
|
213
|
-
UpdateEmitters(scope, emitters);
|
|
214
222
|
}
|
|
215
223
|
function UpdateEmitters(scope, right) {
|
|
224
|
+
emitter_1.Emitter.Distinct(right);
|
|
216
225
|
if (scope.emitters === null) {
|
|
217
226
|
for (let x = 0; x < right.length; x++)
|
|
218
227
|
emitter_1.Emitter.On(right[x], scope.setCallback);
|
|
@@ -237,11 +246,14 @@ function UpdateEmitters(scope, right) {
|
|
|
237
246
|
function DestroyScope(scope) {
|
|
238
247
|
if (!scope)
|
|
239
248
|
return;
|
|
249
|
+
const scopes = scope.calcScopes && Object.values(scope.calcScopes);
|
|
250
|
+
scopes && ObservableScope.DestroyAll(scopes);
|
|
251
|
+
scope.calcScopes = null;
|
|
240
252
|
scope.emitters = null;
|
|
253
|
+
emitter_1.Emitter.Clear(scope.emitter);
|
|
241
254
|
scope.emitter = null;
|
|
242
255
|
scope.getFunction = null;
|
|
243
256
|
scope.setCallback = null;
|
|
244
|
-
scope.calcFunctions = null;
|
|
245
257
|
scope.destroyed = true;
|
|
246
|
-
scope.onDestroyed
|
|
258
|
+
scope.onDestroyed && emitter_1.Emitter.Emit(scope.onDestroyed);
|
|
247
259
|
}
|
package/Utils/array.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare function RemoveNulls(array: (unknown | null)[], startIndex?: number): void;
|
|
2
2
|
export declare function ArrayDiff(source: any[], target: any[]): boolean;
|
|
3
3
|
export declare function ReconcileSortedEmitters<T extends [number]>(left: T[], right: T[], add: (value: T) => void, remove: (value: T) => void): void;
|
|
4
|
+
export declare function InsertionSortTuples<T extends [number, ...any[]]>(arr: T[]): T[];
|
|
4
5
|
export declare function ReconcileSortedArrays<T>(left: T[], right: T[], add: (value: T) => void, remove: (value: T) => void): void;
|
package/Utils/array.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RemoveNulls = RemoveNulls;
|
|
4
4
|
exports.ArrayDiff = ArrayDiff;
|
|
5
5
|
exports.ReconcileSortedEmitters = ReconcileSortedEmitters;
|
|
6
|
+
exports.InsertionSortTuples = InsertionSortTuples;
|
|
6
7
|
exports.ReconcileSortedArrays = ReconcileSortedArrays;
|
|
7
8
|
function RemoveNulls(array, startIndex = 0) {
|
|
8
9
|
let nullIndex = startIndex;
|
|
@@ -50,6 +51,19 @@ function ReconcileSortedEmitters(left, right, add, remove) {
|
|
|
50
51
|
for (let ri = rightIndex; ri < right.length; ri++)
|
|
51
52
|
add(right[ri]);
|
|
52
53
|
}
|
|
54
|
+
function InsertionSortTuples(arr) {
|
|
55
|
+
const n = arr.length;
|
|
56
|
+
for (let i = 1; i < n; i++) {
|
|
57
|
+
const currentItem = arr[i];
|
|
58
|
+
let j = i - 1;
|
|
59
|
+
while (j >= 0 && arr[j][0] > currentItem[0]) {
|
|
60
|
+
arr[j + 1] = arr[j];
|
|
61
|
+
j--;
|
|
62
|
+
}
|
|
63
|
+
arr[j + 1] = currentItem;
|
|
64
|
+
}
|
|
65
|
+
return arr;
|
|
66
|
+
}
|
|
53
67
|
function ReconcileSortedArrays(left, right, add, remove) {
|
|
54
68
|
let leftIndex = 0;
|
|
55
69
|
let rightIndex = 0;
|
package/Utils/decorators.js
CHANGED
|
@@ -50,17 +50,17 @@ function ComputedDecorator(target, prop, descriptor, defaultValue) {
|
|
|
50
50
|
const syncStore = new Store_1.StoreSync();
|
|
51
51
|
observableScope_1.ObservableScope.Watch(getterScope, (scope) => {
|
|
52
52
|
const data = observableScope_1.ObservableScope.Value(scope);
|
|
53
|
-
syncStore.Write(data,
|
|
53
|
+
syncStore.Write(data, "root");
|
|
54
54
|
});
|
|
55
55
|
observableScope_1.ObservableScope.Init(getterScope);
|
|
56
|
-
const propertyScope = observableScope_1.ObservableScope.Create(() => syncStore.Get(
|
|
56
|
+
const propertyScope = observableScope_1.ObservableScope.Create(() => syncStore.Get("root", defaultValue));
|
|
57
57
|
observableScope_1.ObservableScope.OnDestroyed(propertyScope, function () {
|
|
58
58
|
observableScope_1.ObservableScope.Destroy(getterScope);
|
|
59
59
|
});
|
|
60
60
|
scopeMap[propertyKey] = [propertyScope, undefined];
|
|
61
61
|
}
|
|
62
62
|
return observableScope_1.ObservableScope.Value(scopeMap[propertyKey][0]);
|
|
63
|
-
}
|
|
63
|
+
},
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
function ComputedAsync(defaultValue) {
|
|
@@ -81,13 +81,13 @@ function ComputedAsyncDecorator(target, prop, descriptor, defaultValue) {
|
|
|
81
81
|
get: function () {
|
|
82
82
|
const scopeMap = GetScopeMapForInstance(this);
|
|
83
83
|
if (scopeMap[propertyKey] === undefined) {
|
|
84
|
-
const getterScope = observableScope_1.ObservableScope.Create(
|
|
84
|
+
const getterScope = observableScope_1.ObservableScope.Create(() => getter.call(this));
|
|
85
85
|
const asyncStore = new Store_1.StoreAsync();
|
|
86
86
|
observableScope_1.ObservableScope.Watch(getterScope, (scope) => {
|
|
87
|
-
asyncStore.Write(observableScope_1.ObservableScope.Value(scope),
|
|
87
|
+
asyncStore.Write(observableScope_1.ObservableScope.Value(scope), "root");
|
|
88
88
|
});
|
|
89
89
|
observableScope_1.ObservableScope.Init(getterScope);
|
|
90
|
-
const propertyScope = observableScope_1.ObservableScope.Create(() => asyncStore.Get(
|
|
90
|
+
const propertyScope = observableScope_1.ObservableScope.Create(() => asyncStore.Get("root", defaultValue));
|
|
91
91
|
observableScope_1.ObservableScope.OnDestroyed(propertyScope, function () {
|
|
92
92
|
observableScope_1.ObservableScope.Destroy(getterScope);
|
|
93
93
|
asyncStore.Destroy();
|
|
@@ -95,7 +95,7 @@ function ComputedAsyncDecorator(target, prop, descriptor, defaultValue) {
|
|
|
95
95
|
scopeMap[propertyKey] = [propertyScope, undefined];
|
|
96
96
|
}
|
|
97
97
|
return observableScope_1.ObservableScope.Value(scopeMap[propertyKey][0]);
|
|
98
|
-
}
|
|
98
|
+
},
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
function State() {
|
|
@@ -113,7 +113,7 @@ function StateDecorator(target, propertyKey) {
|
|
|
113
113
|
set: function (val) {
|
|
114
114
|
const map = GetNodeMapForInstance(this);
|
|
115
115
|
if (map[propertyKey] === undefined)
|
|
116
|
-
map[propertyKey]
|
|
116
|
+
map[propertyKey] ??= observableNode_1.ObservableNode.Create({ root: val });
|
|
117
117
|
else
|
|
118
118
|
map[propertyKey].root = val;
|
|
119
119
|
},
|
|
@@ -133,7 +133,7 @@ function ValueDecorator(target, propertyKey) {
|
|
|
133
133
|
enumerable: true,
|
|
134
134
|
get: function () {
|
|
135
135
|
const propertyMap = GetScopeMapForInstance(this);
|
|
136
|
-
const tuple = propertyMap[propertyKey] ??= [null, undefined];
|
|
136
|
+
const tuple = (propertyMap[propertyKey] ??= [null, undefined]);
|
|
137
137
|
tuple[0] ??= CreateValueScope(tuple);
|
|
138
138
|
return observableScope_1.ObservableScope.Value(tuple[0]);
|
|
139
139
|
},
|
package/Utils/distinctArray.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export type DistinctArray<T> = {
|
|
2
|
-
id: (value: T) =>
|
|
3
|
-
distinct:
|
|
2
|
+
id: (value: T) => unknown;
|
|
3
|
+
distinct: Set<unknown> | null;
|
|
4
4
|
array: T[];
|
|
5
5
|
};
|
|
6
6
|
export declare namespace DistinctArray {
|
|
7
|
-
function Create<T>(id
|
|
7
|
+
function Create<T>(id?: (value: T) => unknown): DistinctArray<T>;
|
|
8
8
|
function Push<T>(distinctArr: DistinctArray<T>, value: T): void;
|
|
9
9
|
function Get<T>({ array }: DistinctArray<T>): T[];
|
|
10
|
+
function Size<T>(distinct: DistinctArray<T>): number;
|
|
11
|
+
function Clear<T>(distinct: DistinctArray<T>): void;
|
|
10
12
|
}
|
package/Utils/distinctArray.js
CHANGED
|
@@ -3,31 +3,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DistinctArray = void 0;
|
|
4
4
|
var DistinctArray;
|
|
5
5
|
(function (DistinctArray) {
|
|
6
|
-
function Create(id) {
|
|
6
|
+
function Create(id = (val) => val) {
|
|
7
7
|
return {
|
|
8
8
|
id,
|
|
9
9
|
distinct: null,
|
|
10
|
-
array: []
|
|
10
|
+
array: [],
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
DistinctArray.Create = Create;
|
|
14
14
|
function Push(distinctArr, value) {
|
|
15
|
-
|
|
16
|
-
switch (array.length) {
|
|
15
|
+
switch (distinctArr.array.length) {
|
|
17
16
|
case 0:
|
|
18
|
-
array.push(value);
|
|
17
|
+
distinctArr.array.push(value);
|
|
19
18
|
break;
|
|
20
19
|
case 1: {
|
|
21
20
|
if (distinctArr.distinct === null) {
|
|
22
|
-
distinctArr.distinct = [
|
|
23
|
-
|
|
21
|
+
distinctArr.distinct = new Set([
|
|
22
|
+
distinctArr.id(distinctArr.array[0]),
|
|
23
|
+
]);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
default: {
|
|
27
|
-
const vId = id(value);
|
|
28
|
-
if (distinctArr.distinct
|
|
29
|
-
distinctArr.distinct
|
|
30
|
-
array.push(value);
|
|
27
|
+
const vId = distinctArr.id(value);
|
|
28
|
+
if (!distinctArr.distinct.has(vId)) {
|
|
29
|
+
distinctArr.distinct.add(vId);
|
|
30
|
+
distinctArr.array.push(value);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -37,4 +37,13 @@ var DistinctArray;
|
|
|
37
37
|
return array;
|
|
38
38
|
}
|
|
39
39
|
DistinctArray.Get = Get;
|
|
40
|
+
function Size(distinct) {
|
|
41
|
+
return distinct.distinct.size;
|
|
42
|
+
}
|
|
43
|
+
DistinctArray.Size = Size;
|
|
44
|
+
function Clear(distinct) {
|
|
45
|
+
distinct.array = [];
|
|
46
|
+
distinct.distinct?.clear();
|
|
47
|
+
}
|
|
48
|
+
DistinctArray.Clear = Clear;
|
|
40
49
|
})(DistinctArray || (exports.DistinctArray = DistinctArray = {}));
|
package/Utils/emitter.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export declare namespace Emitter {
|
|
|
8
8
|
function Remove(emitter: Emitter, callback: EmitterCallback): void;
|
|
9
9
|
function Clear(emitter: Emitter): void;
|
|
10
10
|
function Distinct(emitters: Emitter[]): void;
|
|
11
|
-
function Sort(emitters: Emitter[]):
|
|
11
|
+
function Sort(emitters: Emitter[]): void;
|
|
12
12
|
function Compare(a: Emitter, b: Emitter): number;
|
|
13
13
|
}
|
package/Utils/emitter.js
CHANGED
|
@@ -21,7 +21,8 @@ var Emitter;
|
|
|
21
21
|
function Emit(emitter, ...args) {
|
|
22
22
|
let removed = false;
|
|
23
23
|
for (let x = 1; x < emitter.length; x++) {
|
|
24
|
-
if (emitter[x] === null ||
|
|
24
|
+
if (emitter[x] === null ||
|
|
25
|
+
emitter[x](...args) === true) {
|
|
25
26
|
removed = true;
|
|
26
27
|
emitter[x] = null;
|
|
27
28
|
}
|
|
@@ -41,16 +42,16 @@ var Emitter;
|
|
|
41
42
|
}
|
|
42
43
|
Emitter.Clear = Clear;
|
|
43
44
|
function Distinct(emitters) {
|
|
44
|
-
if (emitters.length
|
|
45
|
+
if (emitters.length < 2)
|
|
45
46
|
return;
|
|
46
|
-
emitters.length <
|
|
47
|
+
emitters.length < 51 ? DistinctSmall(emitters) : DistinctLarge(emitters);
|
|
47
48
|
}
|
|
48
49
|
Emitter.Distinct = Distinct;
|
|
49
50
|
function DistinctSmall(emitters) {
|
|
50
51
|
Sort(emitters);
|
|
51
|
-
let lastId =
|
|
52
|
+
let lastId = emitters[0][0];
|
|
52
53
|
let remove = false;
|
|
53
|
-
for (let x =
|
|
54
|
+
for (let x = 1; x < emitters.length; x++) {
|
|
54
55
|
const id = emitters[x][0];
|
|
55
56
|
if (lastId === emitters[x][0]) {
|
|
56
57
|
emitters[x] = null;
|
|
@@ -76,7 +77,10 @@ var Emitter;
|
|
|
76
77
|
Sort(emitters);
|
|
77
78
|
}
|
|
78
79
|
function Sort(emitters) {
|
|
79
|
-
|
|
80
|
+
if (emitters.length < 11)
|
|
81
|
+
(0, array_1.InsertionSortTuples)(emitters);
|
|
82
|
+
else
|
|
83
|
+
emitters.sort(Compare);
|
|
80
84
|
}
|
|
81
85
|
Emitter.Sort = Sort;
|
|
82
86
|
function Compare(a, b) {
|
package/Utils/injector.d.ts
CHANGED
package/Utils/injector.js
CHANGED
|
@@ -7,15 +7,14 @@ class Injector {
|
|
|
7
7
|
this.typeMap = new Map();
|
|
8
8
|
}
|
|
9
9
|
Get(type) {
|
|
10
|
-
if (this.typeMap.
|
|
11
|
-
return this.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
ret = this.parent && this.parent.Get(type);
|
|
15
|
-
return ret;
|
|
10
|
+
if (this.typeMap.has(type)) {
|
|
11
|
+
return this.typeMap.get(type);
|
|
12
|
+
}
|
|
13
|
+
return this.parent ? this.parent.Get(type) : undefined;
|
|
16
14
|
}
|
|
17
15
|
Set(type, instance) {
|
|
18
16
|
this.typeMap.set(type, instance);
|
|
17
|
+
return instance;
|
|
19
18
|
}
|
|
20
19
|
}
|
|
21
20
|
exports.Injector = Injector;
|
|
@@ -26,11 +25,14 @@ exports.Injector = Injector;
|
|
|
26
25
|
}
|
|
27
26
|
Injector.Current = Current;
|
|
28
27
|
function Scope(injector, action, ...args) {
|
|
29
|
-
|
|
28
|
+
const parent = Current();
|
|
30
29
|
scope = injector;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
try {
|
|
31
|
+
return action(...args);
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
scope = parent;
|
|
35
|
+
}
|
|
34
36
|
}
|
|
35
37
|
Injector.Scope = Scope;
|
|
36
38
|
})(Injector || (exports.Injector = Injector = {}));
|
package/Utils/thread.js
CHANGED
|
@@ -19,7 +19,7 @@ function timeRemaining() {
|
|
|
19
19
|
function createDeadline() {
|
|
20
20
|
return {
|
|
21
21
|
end: Date.now() + workTimeMs,
|
|
22
|
-
timeRemaining
|
|
22
|
+
timeRemaining,
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
function ProcessQueue(deadline = createDeadline()) {
|
|
@@ -49,7 +49,9 @@ function DoWork(ctx, deadline = createDeadline()) {
|
|
|
49
49
|
threadContext = ctx;
|
|
50
50
|
const async = ctx.async;
|
|
51
51
|
let callback;
|
|
52
|
-
while (async === ctx.async &&
|
|
52
|
+
while (async === ctx.async &&
|
|
53
|
+
deadline.timeRemaining() > 0 &&
|
|
54
|
+
(callback = list_1.List.Pop(ctx.workList)))
|
|
53
55
|
Invoke(ctx, callback);
|
|
54
56
|
if (ctx.workList.size > 0)
|
|
55
57
|
ScheduleWork(ctx);
|
|
@@ -59,7 +61,7 @@ function CreateContext() {
|
|
|
59
61
|
return {
|
|
60
62
|
async: false,
|
|
61
63
|
workEndNode: null,
|
|
62
|
-
workList: list_1.List.Create()
|
|
64
|
+
workList: list_1.List.Create(),
|
|
63
65
|
};
|
|
64
66
|
}
|
|
65
67
|
function ScheduleCallback(callback, before, async) {
|
|
@@ -89,7 +91,9 @@ function After(callback) {
|
|
|
89
91
|
}
|
|
90
92
|
function Callback(callback) {
|
|
91
93
|
return function (a, b, c, d) {
|
|
92
|
-
Schedule(function () {
|
|
94
|
+
Schedule(function () {
|
|
95
|
+
callback(a, b, c, d);
|
|
96
|
+
});
|
|
93
97
|
};
|
|
94
98
|
}
|
|
95
99
|
var inSynchCallback = false;
|
|
@@ -109,7 +113,7 @@ function Thread(callback) {
|
|
|
109
113
|
Synch(callback);
|
|
110
114
|
}
|
|
111
115
|
function ThreadAsync(callback) {
|
|
112
|
-
return new Promise(resolve => Thread(function (async) {
|
|
116
|
+
return new Promise((resolve) => Thread(function (async) {
|
|
113
117
|
callback(async);
|
|
114
118
|
Thread(resolve);
|
|
115
119
|
}));
|