j-templates 7.0.52 → 7.0.54
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 +8 -7
- package/DOM/createEventAssignment.d.ts +0 -3
- package/DOM/createEventAssignment.js +0 -6
- package/DOM/createPropertyAssignment.d.ts +1 -7
- package/DOM/createPropertyAssignment.js +53 -72
- package/DOM/domNodeConfig.d.ts +1 -1
- package/DOM/domNodeConfig.js +26 -22
- package/Node/nodeConfig.d.ts +0 -5
- package/Node/vNode.d.ts +1 -0
- package/Node/vNode.js +50 -12
- package/Node/vNode.types.d.ts +2 -0
- package/Store/Tree/observableScope.d.ts +5 -8
- package/Store/Tree/observableScope.js +27 -32
- package/Utils/array.d.ts +1 -0
- package/Utils/array.js +14 -0
- package/Utils/emitter.d.ts +1 -1
- package/Utils/emitter.js +23 -25
- package/package.json +1 -1
package/DOM/createAssignment.js
CHANGED
|
@@ -8,13 +8,14 @@ function CreateAssignment(target, createAssignment) {
|
|
|
8
8
|
if (next === last)
|
|
9
9
|
return;
|
|
10
10
|
last = next;
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
for (const key in writeTo) {
|
|
12
|
+
writeTo[key](next);
|
|
13
|
+
}
|
|
14
|
+
for (const key in next) {
|
|
15
|
+
if (!Object.hasOwn(writeTo, key)) {
|
|
16
|
+
writeTo[key] = createAssignment(target, key);
|
|
17
|
+
writeTo[key](next);
|
|
18
|
+
}
|
|
15
19
|
}
|
|
16
|
-
const writeFunctions = Object.values(writeTo);
|
|
17
|
-
for (let x = 0; x < writeFunctions.length; x++)
|
|
18
|
-
writeFunctions[x](next);
|
|
19
20
|
};
|
|
20
21
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CreateEventAssignment = CreateEventAssignment;
|
|
4
|
-
exports.AssignEvents = AssignEvents;
|
|
5
4
|
function CreateEventAssignment(target, event) {
|
|
6
5
|
let lastEvent;
|
|
7
6
|
return function (next) {
|
|
@@ -13,8 +12,3 @@ function CreateEventAssignment(target, event) {
|
|
|
13
12
|
lastEvent = nextEvent;
|
|
14
13
|
};
|
|
15
14
|
}
|
|
16
|
-
function AssignEvents(target, eventMap) {
|
|
17
|
-
const entries = Object.entries(eventMap);
|
|
18
|
-
for (let x = 0; x < entries.length; x++)
|
|
19
|
-
target.addEventListener(entries[x][0], entries[x][1]);
|
|
20
|
-
}
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
export declare function
|
|
2
|
-
export declare function CreatePropertyAssignment(target: any): ((next: {
|
|
3
|
-
nodeValue: string;
|
|
4
|
-
}) => void) | ((next: {
|
|
5
|
-
[prop: string]: any;
|
|
6
|
-
}) => void);
|
|
7
|
-
export declare function AssignProperties(target: any, next: any): void;
|
|
1
|
+
export declare function CreateRootPropertyAssignment(target: HTMLElement, property: string): (next: any) => void;
|
|
@@ -1,34 +1,65 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.CreatePropertyAssignment = CreatePropertyAssignment;
|
|
5
|
-
exports.AssignProperties = AssignProperties;
|
|
3
|
+
exports.CreateRootPropertyAssignment = CreateRootPropertyAssignment;
|
|
6
4
|
const json_1 = require("../Utils/json");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
const createAssignment_1 = require("./createAssignment");
|
|
6
|
+
function CreatePropertyAssignment(target, property) {
|
|
7
|
+
let lastValue;
|
|
8
|
+
let jsonType;
|
|
9
|
+
let childAssignment;
|
|
10
|
+
return function (next) {
|
|
11
|
+
const nextValue = next && next[property];
|
|
12
|
+
if (nextValue === lastValue)
|
|
13
|
+
return;
|
|
14
|
+
jsonType ??= (0, json_1.JsonType)(nextValue);
|
|
15
|
+
switch (jsonType) {
|
|
16
|
+
case "value":
|
|
17
|
+
target[property] = nextValue;
|
|
18
|
+
break;
|
|
19
|
+
default: {
|
|
20
|
+
const childTarget = target[property];
|
|
21
|
+
childAssignment ??= (0, createAssignment_1.CreateAssignment)(childTarget, CreateRootPropertyAssignment);
|
|
22
|
+
childAssignment(nextValue);
|
|
23
|
+
}
|
|
13
24
|
}
|
|
14
25
|
};
|
|
15
26
|
}
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
function CreateRootPropertyAssignment(target, property) {
|
|
28
|
+
let lastValue;
|
|
29
|
+
let jsonType;
|
|
30
|
+
let childAssignment;
|
|
31
|
+
return function (next) {
|
|
32
|
+
const nextValue = next && next[property];
|
|
33
|
+
if (nextValue === lastValue)
|
|
34
|
+
return;
|
|
35
|
+
switch (property) {
|
|
36
|
+
case "nodeValue": {
|
|
37
|
+
AssignNodeValue(target, nextValue);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case "className": {
|
|
41
|
+
AssignClassName(target, nextValue);
|
|
24
42
|
break;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
43
|
+
}
|
|
44
|
+
case "value": {
|
|
45
|
+
AssignValue(target, nextValue);
|
|
28
46
|
break;
|
|
47
|
+
}
|
|
48
|
+
default: {
|
|
49
|
+
jsonType ??= (0, json_1.JsonType)(nextValue);
|
|
50
|
+
switch (jsonType) {
|
|
51
|
+
case "value":
|
|
52
|
+
target[property] = nextValue;
|
|
53
|
+
break;
|
|
54
|
+
default: {
|
|
55
|
+
const childTarget = target[property];
|
|
56
|
+
childAssignment ??= (0, createAssignment_1.CreateAssignment)(childTarget, CreatePropertyAssignment);
|
|
57
|
+
childAssignment(nextValue);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
29
61
|
}
|
|
30
|
-
}
|
|
31
|
-
return index;
|
|
62
|
+
};
|
|
32
63
|
}
|
|
33
64
|
function AssignNodeValue(target, value) {
|
|
34
65
|
target.nodeValue = value;
|
|
@@ -43,53 +74,3 @@ function AssignValue(target, value) {
|
|
|
43
74
|
function AssignClassName(target, value) {
|
|
44
75
|
target.className = value;
|
|
45
76
|
}
|
|
46
|
-
function GetAssignmentFunction(path) {
|
|
47
|
-
switch (path) {
|
|
48
|
-
case "nodeValue":
|
|
49
|
-
return AssignNodeValue;
|
|
50
|
-
case "value":
|
|
51
|
-
return AssignValue;
|
|
52
|
-
case "className":
|
|
53
|
-
return AssignClassName;
|
|
54
|
-
default:
|
|
55
|
-
return new Function("t", "v", `t.${path} = v;`);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function CreatePropertyAssignment(target) {
|
|
59
|
-
if (target.nodeType === Node.TEXT_NODE) {
|
|
60
|
-
return function (next) {
|
|
61
|
-
AssignNodeValue(target, next.nodeValue);
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
const last = [
|
|
65
|
-
["", null, null],
|
|
66
|
-
];
|
|
67
|
-
function WalkCallback(path, value, index) {
|
|
68
|
-
if (index >= last.length || last[index][0] !== path) {
|
|
69
|
-
last[index] = [path, value, GetAssignmentFunction(path)];
|
|
70
|
-
last[index][2](target, value);
|
|
71
|
-
}
|
|
72
|
-
else if (last[index][1] !== value) {
|
|
73
|
-
last[index][1] = value;
|
|
74
|
-
last[index][2](target, value);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return function AssignProperty(next) {
|
|
78
|
-
if (next === null) {
|
|
79
|
-
for (let x = 0; x < last.length; x++)
|
|
80
|
-
last[x][2] !== null && last[x][2](target, null);
|
|
81
|
-
if (last.length > 0)
|
|
82
|
-
last.splice(0);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
const endIndex = WalkValue(next, WalkCallback);
|
|
86
|
-
if (endIndex < last.length)
|
|
87
|
-
last.splice(endIndex);
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
function AssignProperties(target, next) {
|
|
91
|
-
WalkValue(next, function (path, value) {
|
|
92
|
-
const assignment = GetAssignmentFunction(path);
|
|
93
|
-
assignment(target, value);
|
|
94
|
-
});
|
|
95
|
-
}
|
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
|
@@ -6,7 +6,6 @@ const list_1 = require("../Utils/list");
|
|
|
6
6
|
const createPropertyAssignment_1 = require("./createPropertyAssignment");
|
|
7
7
|
const createEventAssignment_1 = require("./createEventAssignment");
|
|
8
8
|
const createAssignment_1 = require("./createAssignment");
|
|
9
|
-
const createPropertyAssignment_2 = require("./createPropertyAssignment");
|
|
10
9
|
const createAttributeAssignment_1 = require("./createAttributeAssignment");
|
|
11
10
|
let pendingUpdates = list_1.List.Create();
|
|
12
11
|
let updateScheduled = false;
|
|
@@ -51,13 +50,13 @@ function wrapPriorityUpdates(callback) {
|
|
|
51
50
|
}
|
|
52
51
|
exports.DOMNodeConfig = {
|
|
53
52
|
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);
|
|
53
|
+
if (type === "text")
|
|
54
|
+
return window_1.wndw.document.createTextNode("");
|
|
55
|
+
return namespace
|
|
56
|
+
? window_1.wndw.document.createElementNS(namespace, type)
|
|
57
|
+
: window_1.wndw.document.createElement(type);
|
|
59
58
|
},
|
|
60
|
-
createTextNode(value =
|
|
59
|
+
createTextNode(value = "") {
|
|
61
60
|
return window_1.wndw.document.createTextNode(value);
|
|
62
61
|
},
|
|
63
62
|
isTextNode(target) {
|
|
@@ -98,9 +97,6 @@ exports.DOMNodeConfig = {
|
|
|
98
97
|
remove(target) {
|
|
99
98
|
target && target.parentNode && target.parentNode.removeChild(target);
|
|
100
99
|
},
|
|
101
|
-
createTextAssignment(target) {
|
|
102
|
-
return (0, createPropertyAssignment_1.CreateNodeValueAssignment)(target);
|
|
103
|
-
},
|
|
104
100
|
setText(target, text) {
|
|
105
101
|
target.nodeValue = text;
|
|
106
102
|
},
|
|
@@ -111,17 +107,11 @@ exports.DOMNodeConfig = {
|
|
|
111
107
|
target.setAttribute(attribute, value);
|
|
112
108
|
},
|
|
113
109
|
createPropertyAssignment(target) {
|
|
114
|
-
return (0,
|
|
115
|
-
},
|
|
116
|
-
assignProperties(target, next) {
|
|
117
|
-
(0, createPropertyAssignment_1.AssignProperties)(target, next);
|
|
110
|
+
return (0, createAssignment_1.CreateAssignment)(target, createPropertyAssignment_1.CreateRootPropertyAssignment);
|
|
118
111
|
},
|
|
119
112
|
createEventAssignment(target) {
|
|
120
113
|
return (0, createAssignment_1.CreateAssignment)(target, createEventAssignment_1.CreateEventAssignment);
|
|
121
114
|
},
|
|
122
|
-
assignEvents(target, next) {
|
|
123
|
-
(0, createEventAssignment_1.AssignEvents)(target, next);
|
|
124
|
-
},
|
|
125
115
|
createAttributeAssignment(target) {
|
|
126
116
|
return (0, createAssignment_1.CreateAssignment)(target, createAttributeAssignment_1.CreateAttributeAssignment);
|
|
127
117
|
},
|
|
@@ -143,8 +133,15 @@ exports.DOMNodeConfig = {
|
|
|
143
133
|
},
|
|
144
134
|
reconcileChildren(target, children) {
|
|
145
135
|
if (!target.firstChild) {
|
|
146
|
-
|
|
147
|
-
|
|
136
|
+
if (children.length > 10) {
|
|
137
|
+
const fragment = new DocumentFragment();
|
|
138
|
+
for (let x = 0; x < children.length; x++)
|
|
139
|
+
fragment.appendChild(children[x]);
|
|
140
|
+
target.appendChild(fragment);
|
|
141
|
+
}
|
|
142
|
+
else
|
|
143
|
+
for (let x = 0; x < children.length; x++)
|
|
144
|
+
target.appendChild(children[x]);
|
|
148
145
|
return;
|
|
149
146
|
}
|
|
150
147
|
if (children.length === 0) {
|
|
@@ -172,7 +169,14 @@ exports.DOMNodeConfig = {
|
|
|
172
169
|
}
|
|
173
170
|
while (target.lastChild !== children[x - 1])
|
|
174
171
|
target.removeChild(target.lastChild);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
if (children.length - x > 10) {
|
|
173
|
+
const fragment = new DocumentFragment();
|
|
174
|
+
for (; x < children.length; x++)
|
|
175
|
+
fragment.appendChild(children[x]);
|
|
176
|
+
target.appendChild(fragment);
|
|
177
|
+
}
|
|
178
|
+
else
|
|
179
|
+
for (; x < children.length; x++)
|
|
180
|
+
target.appendChild(children[x]);
|
|
181
|
+
},
|
|
178
182
|
};
|
package/Node/nodeConfig.d.ts
CHANGED
|
@@ -20,19 +20,14 @@ export interface INodeConfig {
|
|
|
20
20
|
removeChild(root: any, child: any): void;
|
|
21
21
|
remove(target: any): void;
|
|
22
22
|
fireEvent(target: any, event: string, data: any): void;
|
|
23
|
-
createTextAssignment(target: any): {
|
|
24
|
-
(next: string): void;
|
|
25
|
-
};
|
|
26
23
|
createPropertyAssignment(target: any): {
|
|
27
24
|
(next: any): void;
|
|
28
25
|
};
|
|
29
|
-
assignProperties(target: any, next: any): void;
|
|
30
26
|
createEventAssignment(target: any): {
|
|
31
27
|
(next: {
|
|
32
28
|
[event: string]: (event: Event) => void;
|
|
33
29
|
}): void;
|
|
34
30
|
};
|
|
35
|
-
assignEvents(target: any, next: any): void;
|
|
36
31
|
createAttributeAssignment(target: any): {
|
|
37
32
|
(next: {
|
|
38
33
|
[attribute: string]: string;
|
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
|
};
|
|
@@ -24,10 +24,6 @@ export declare class ObservableScope<T> extends ObservableScopeWrapper<T> {
|
|
|
24
24
|
(): T | Promise<T>;
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
-
interface ICalcObservable<T> {
|
|
28
|
-
id: string;
|
|
29
|
-
scope: IObservableScope<T>;
|
|
30
|
-
}
|
|
31
27
|
export interface IObservableScope<T> extends IDestroyable {
|
|
32
28
|
getFunction: {
|
|
33
29
|
(): T;
|
|
@@ -39,12 +35,14 @@ export interface IObservableScope<T> extends IDestroyable {
|
|
|
39
35
|
dirty: boolean;
|
|
40
36
|
emitter: Emitter;
|
|
41
37
|
emitters: (Emitter | null)[];
|
|
42
|
-
calcScopes:
|
|
38
|
+
calcScopes: {
|
|
39
|
+
[id: string]: IObservableScope<unknown> | null;
|
|
40
|
+
} | null;
|
|
43
41
|
calc: boolean;
|
|
44
42
|
onDestroyed: Emitter | null;
|
|
45
43
|
destroyed: boolean;
|
|
46
44
|
}
|
|
47
|
-
export declare function CalcScope<T>(callback: () => T):
|
|
45
|
+
export declare function CalcScope<T>(callback: () => T, idOverride?: string): unknown;
|
|
48
46
|
export declare namespace ObservableScope {
|
|
49
47
|
function Create<T>(valueFunction: {
|
|
50
48
|
(): T | Promise<T>;
|
|
@@ -56,9 +54,8 @@ export declare namespace ObservableScope {
|
|
|
56
54
|
function Touch<T>(scope: IObservableScope<T>): void;
|
|
57
55
|
function Watch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T>]>): void;
|
|
58
56
|
function Unwatch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T> | ObservableScopeValue<T>]>): void;
|
|
59
|
-
function OnDestroyed(scope: IObservableScope<unknown>, callback:
|
|
57
|
+
function OnDestroyed(scope: IObservableScope<unknown>, callback: EmitterCallback): void;
|
|
60
58
|
function Update(scope: IObservableScope<any>): void;
|
|
61
59
|
function Destroy<T>(scope: IObservableScope<T>): void;
|
|
62
60
|
function DestroyAll(scopes: IObservableScope<unknown>[]): void;
|
|
63
61
|
}
|
|
64
|
-
export {};
|
|
@@ -56,34 +56,31 @@ function WatchScope(scope) {
|
|
|
56
56
|
const emitters = watchState[0];
|
|
57
57
|
UpdateEmitters(scope, emitters);
|
|
58
58
|
const calcScopes = watchState[1];
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
if (calcScopes) {
|
|
60
|
+
const calcScopeValues = Object.values(calcScopes);
|
|
61
|
+
for (let x = 0; x < calcScopeValues.length; x++)
|
|
62
|
+
calcScopeValues[x] && ObservableScope.Destroy(calcScopeValues[x]);
|
|
63
|
+
}
|
|
61
64
|
scope.calcScopes = watchState[2];
|
|
62
65
|
watchState = parent;
|
|
63
66
|
return value;
|
|
64
67
|
}
|
|
65
|
-
function CalcScope(callback) {
|
|
68
|
+
function CalcScope(callback, idOverride) {
|
|
66
69
|
if (watchState === null)
|
|
67
70
|
return callback();
|
|
68
|
-
watchState[2] ??=
|
|
71
|
+
const nextScopes = (watchState[2] ??= {});
|
|
69
72
|
const currentScopes = watchState[1];
|
|
70
|
-
const id = callback.toString();
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const scope = currentScopes[index];
|
|
76
|
-
currentScopes[index] = null;
|
|
77
|
-
watchState[2].push(scope);
|
|
78
|
-
return ObservableScope.Value(scope.scope);
|
|
79
|
-
}
|
|
73
|
+
const id = idOverride ?? callback.toString();
|
|
74
|
+
const currentScope = currentScopes?.[id];
|
|
75
|
+
if (currentScope) {
|
|
76
|
+
delete currentScopes[id];
|
|
77
|
+
nextScopes[id] = currentScope;
|
|
80
78
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
id
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return ObservableScope.Value(scope);
|
|
79
|
+
else if (!nextScopes[id]) {
|
|
80
|
+
const scope = ObservableScope.Create(callback, true);
|
|
81
|
+
nextScopes[id] = scope;
|
|
82
|
+
}
|
|
83
|
+
return ObservableScope.Value(nextScopes[id]);
|
|
87
84
|
}
|
|
88
85
|
(function (ObservableScope) {
|
|
89
86
|
function Create(valueFunction, calc = false) {
|
|
@@ -174,17 +171,13 @@ function CalcScope(callback) {
|
|
|
174
171
|
function DirtyScope(scope) {
|
|
175
172
|
if (scope.dirty || !scope.getFunction)
|
|
176
173
|
return;
|
|
177
|
-
if (scope.calc) {
|
|
178
|
-
const startVal = scope.value;
|
|
179
|
-
scope.dirty = true;
|
|
180
|
-
UpdateValue(scope);
|
|
181
|
-
if (startVal !== scope.value)
|
|
182
|
-
emitter_1.Emitter.Emit(scope.emitter);
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
174
|
scope.dirty = true;
|
|
186
|
-
if (scope.async)
|
|
175
|
+
if (scope.async)
|
|
176
|
+
UpdateValue(scope);
|
|
177
|
+
else if (scope.calc) {
|
|
178
|
+
const startValue = scope.value;
|
|
187
179
|
UpdateValue(scope);
|
|
180
|
+
startValue !== scope.value && emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
188
181
|
}
|
|
189
182
|
else
|
|
190
183
|
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
@@ -255,12 +248,14 @@ function UpdateEmitters(scope, right) {
|
|
|
255
248
|
function DestroyScope(scope) {
|
|
256
249
|
if (!scope)
|
|
257
250
|
return;
|
|
251
|
+
const scopes = scope.calcScopes && Object.values(scope.calcScopes);
|
|
252
|
+
scopes && ObservableScope.DestroyAll(scopes);
|
|
253
|
+
scope.calcScopes = null;
|
|
258
254
|
scope.emitters = null;
|
|
255
|
+
emitter_1.Emitter.Clear(scope.emitter);
|
|
259
256
|
scope.emitter = null;
|
|
260
257
|
scope.getFunction = null;
|
|
261
258
|
scope.setCallback = null;
|
|
262
|
-
for (let x = 0; scope.calcScopes && x < scope.calcScopes.length; x++)
|
|
263
|
-
ObservableScope.Destroy(scope.calcScopes[x].scope);
|
|
264
259
|
scope.destroyed = true;
|
|
265
|
-
scope.onDestroyed
|
|
260
|
+
scope.onDestroyed && emitter_1.Emitter.Emit(scope.onDestroyed);
|
|
266
261
|
}
|
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/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
|
@@ -19,15 +19,14 @@ var Emitter;
|
|
|
19
19
|
}
|
|
20
20
|
Emitter.On = On;
|
|
21
21
|
function Emit(emitter, ...args) {
|
|
22
|
-
let
|
|
22
|
+
let writePos = 1;
|
|
23
23
|
for (let x = 1; x < emitter.length; x++) {
|
|
24
|
-
if (emitter[x]
|
|
25
|
-
|
|
26
|
-
emitter[
|
|
27
|
-
}
|
|
24
|
+
if (emitter[x] !== null &&
|
|
25
|
+
emitter[x](...args) !== true)
|
|
26
|
+
emitter[writePos++] = emitter[x];
|
|
28
27
|
}
|
|
29
|
-
if (
|
|
30
|
-
|
|
28
|
+
if (writePos < emitter.length)
|
|
29
|
+
emitter.splice(writePos);
|
|
31
30
|
}
|
|
32
31
|
Emitter.Emit = Emit;
|
|
33
32
|
function Remove(emitter, callback) {
|
|
@@ -41,42 +40,41 @@ var Emitter;
|
|
|
41
40
|
}
|
|
42
41
|
Emitter.Clear = Clear;
|
|
43
42
|
function Distinct(emitters) {
|
|
44
|
-
if (emitters.length
|
|
43
|
+
if (emitters.length < 2)
|
|
45
44
|
return;
|
|
46
|
-
emitters.length <
|
|
45
|
+
emitters.length < 51 ? DistinctSmall(emitters) : DistinctLarge(emitters);
|
|
47
46
|
}
|
|
48
47
|
Emitter.Distinct = Distinct;
|
|
49
48
|
function DistinctSmall(emitters) {
|
|
50
49
|
Sort(emitters);
|
|
51
|
-
let
|
|
52
|
-
let
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (lastId === emitters[x][0]) {
|
|
56
|
-
emitters[x] = null;
|
|
57
|
-
remove = true;
|
|
50
|
+
let writePos = 1;
|
|
51
|
+
for (let x = 1; x < emitters.length; x++) {
|
|
52
|
+
if (emitters[x][0] !== emitters[writePos - 1][0]) {
|
|
53
|
+
emitters[writePos++] = emitters[x];
|
|
58
54
|
}
|
|
59
|
-
lastId = id;
|
|
60
55
|
}
|
|
61
|
-
|
|
56
|
+
if (writePos < emitters.length)
|
|
57
|
+
emitters.splice(writePos);
|
|
62
58
|
}
|
|
63
59
|
function DistinctLarge(emitters) {
|
|
64
|
-
let
|
|
60
|
+
let writePos = 0;
|
|
65
61
|
const ids = new Set();
|
|
66
62
|
for (let x = 0; x < emitters.length; x++) {
|
|
67
63
|
const id = emitters[x][0];
|
|
68
|
-
if (!ids.has(id))
|
|
64
|
+
if (!ids.has(id)) {
|
|
69
65
|
ids.add(id);
|
|
70
|
-
|
|
71
|
-
emitters[x] = null;
|
|
72
|
-
remove = true;
|
|
66
|
+
emitters[writePos++] = emitters[x];
|
|
73
67
|
}
|
|
74
68
|
}
|
|
75
|
-
|
|
69
|
+
if (writePos < emitters.length)
|
|
70
|
+
emitters.splice(writePos);
|
|
76
71
|
Sort(emitters);
|
|
77
72
|
}
|
|
78
73
|
function Sort(emitters) {
|
|
79
|
-
|
|
74
|
+
if (emitters.length < 11)
|
|
75
|
+
(0, array_1.InsertionSortTuples)(emitters);
|
|
76
|
+
else
|
|
77
|
+
emitters.sort(Compare);
|
|
80
78
|
}
|
|
81
79
|
Emitter.Sort = Sort;
|
|
82
80
|
function Compare(a, b) {
|