j-templates 7.0.89 → 7.0.90
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
CHANGED
|
@@ -145,42 +145,36 @@ exports.DOMNodeConfig = {
|
|
|
145
145
|
target.replaceChildren(...children);
|
|
146
146
|
},
|
|
147
147
|
reconcileChildren(target, children) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
target.
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
148
|
+
let lastChild = null;
|
|
149
|
+
switch (children.length) {
|
|
150
|
+
case 0:
|
|
151
|
+
target.replaceChildren();
|
|
152
|
+
break;
|
|
153
|
+
case 1:
|
|
154
|
+
lastChild = getHTMLNode(children[0], target.firstChild);
|
|
155
|
+
if (target.firstChild !== lastChild)
|
|
156
|
+
target.insertBefore(lastChild, target.firstChild);
|
|
157
|
+
break;
|
|
158
|
+
default:
|
|
159
|
+
let actualChild = target.firstChild;
|
|
160
|
+
let nextChild = null;
|
|
161
|
+
let x = 0;
|
|
162
|
+
for (; x < children.length; x++) {
|
|
163
|
+
nextChild = getHTMLNode(children[x], actualChild);
|
|
164
|
+
while (actualChild && nextChild !== actualChild) {
|
|
165
|
+
const nextSibling = actualChild.nextSibling;
|
|
166
|
+
target.removeChild(actualChild);
|
|
167
|
+
actualChild = nextSibling;
|
|
168
|
+
}
|
|
169
|
+
if (actualChild)
|
|
170
|
+
actualChild = actualChild.nextSibling;
|
|
171
|
+
else
|
|
172
|
+
target.appendChild(nextChild);
|
|
173
|
+
}
|
|
174
|
+
lastChild = nextChild;
|
|
175
|
+
break;
|
|
158
176
|
}
|
|
159
|
-
|
|
160
|
-
let x = 0;
|
|
161
|
-
let removed = false;
|
|
162
|
-
for (; actualNode && x < children.length; x++) {
|
|
163
|
-
const child = children[x];
|
|
164
|
-
let expectedNode = getHTMLNode(child, actualNode);
|
|
165
|
-
if (!removed && actualNode !== expectedNode) {
|
|
166
|
-
const remove = actualNode;
|
|
167
|
-
actualNode = actualNode.nextSibling;
|
|
168
|
-
target.removeChild(remove);
|
|
169
|
-
removed = true;
|
|
170
|
-
}
|
|
171
|
-
if (actualNode !== expectedNode) {
|
|
172
|
-
target.insertBefore(expectedNode, actualNode);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
actualNode = actualNode.nextSibling;
|
|
176
|
-
removed = false;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
while (target.lastChild && target.lastChild !== children[x - 1])
|
|
177
|
+
while (target.lastChild !== lastChild)
|
|
180
178
|
target.removeChild(target.lastChild);
|
|
181
|
-
for (; x < children.length; x++) {
|
|
182
|
-
const child = getHTMLNode(children[x]);
|
|
183
|
-
target.appendChild(child);
|
|
184
|
-
}
|
|
185
179
|
},
|
|
186
180
|
};
|
|
@@ -58,10 +58,12 @@ function UnwrapProxy(value, type = (0, json_2.JsonType)(value)) {
|
|
|
58
58
|
const keys = Object.keys(value);
|
|
59
59
|
for (let x = 0; x < keys.length; x++)
|
|
60
60
|
value[keys[x]] = UnwrapProxy(value[keys[x]]);
|
|
61
|
+
break;
|
|
61
62
|
}
|
|
62
63
|
case "array": {
|
|
63
64
|
for (let x = 0; x < value.length; x++)
|
|
64
65
|
value[x] = UnwrapProxy(value[x]);
|
|
66
|
+
break;
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
return value;
|
|
@@ -17,6 +17,7 @@ interface IDynamicObservableScope<T> {
|
|
|
17
17
|
type: "dynamic";
|
|
18
18
|
/** Whether the scope's getter function is async */
|
|
19
19
|
async: boolean;
|
|
20
|
+
pending: Promise<T> | null;
|
|
20
21
|
/** Whether updates are batched (true) or immediate (false) */
|
|
21
22
|
greedy: boolean;
|
|
22
23
|
/** Whether the scope needs recomputation */
|
|
@@ -145,20 +146,22 @@ export declare namespace ObservableScope {
|
|
|
145
146
|
* @param scope The scope to watch for changes.
|
|
146
147
|
* @param callback Function to invoke when the scope's value changes.
|
|
147
148
|
*/
|
|
148
|
-
function Watch<T>(scope: IObservableScope<T>, callback:
|
|
149
|
+
function Watch<T>(scope: IObservableScope<T>, callback: (scope: IObservableScope<T>) => void): void;
|
|
149
150
|
/**
|
|
150
151
|
* Unsubscribes from changes on a dynamic scope.
|
|
151
152
|
* @template T The type of value stored in the scope.
|
|
152
153
|
* @param scope The scope to stop watching.
|
|
153
154
|
* @param callback The callback function to remove.
|
|
154
155
|
*/
|
|
155
|
-
function Unwatch<T>(scope: IObservableScope<T>, callback:
|
|
156
|
+
function Unwatch<T>(scope: IObservableScope<T>, callback: (scope: IObservableScope<T>) => void): void;
|
|
156
157
|
/**
|
|
157
158
|
* Registers a callback to be invoked when the scope is destroyed.
|
|
158
159
|
* @param scope The scope to monitor for destruction.
|
|
159
160
|
* @param callback Function to invoke when the scope is destroyed.
|
|
160
161
|
*/
|
|
161
|
-
function OnDestroyed(scope: IObservableScope<unknown>, callback:
|
|
162
|
+
function OnDestroyed(scope: IObservableScope<unknown>, callback: {
|
|
163
|
+
(): void;
|
|
164
|
+
}): void;
|
|
162
165
|
/**
|
|
163
166
|
* Marks a scope as dirty, triggering recomputation on next access or batch.
|
|
164
167
|
* @param scope The scope to mark for update.
|
|
@@ -19,6 +19,7 @@ function CreateDynamicScope(getFunction, greedy, value) {
|
|
|
19
19
|
const scope = {
|
|
20
20
|
type: "dynamic",
|
|
21
21
|
async,
|
|
22
|
+
pending: null,
|
|
22
23
|
greedy: greedy || async,
|
|
23
24
|
dirty: false,
|
|
24
25
|
destroyed: false,
|
|
@@ -80,7 +81,7 @@ function OnSetQueued(scope) {
|
|
|
80
81
|
* @returns true if the scope is static or destroyed, false if queued or non-greedy scope emitted.
|
|
81
82
|
*/
|
|
82
83
|
function OnSet() {
|
|
83
|
-
if (this.dirty)
|
|
84
|
+
if (this.dirty || this.destroyed)
|
|
84
85
|
return;
|
|
85
86
|
this.dirty = true;
|
|
86
87
|
if (this.greedy) {
|
|
@@ -229,10 +230,11 @@ function ExecuteScope(scope) {
|
|
|
229
230
|
for (const key in calcScopes)
|
|
230
231
|
DestroyScope(calcScopes[key]);
|
|
231
232
|
if (scope.async) {
|
|
232
|
-
const promise = state.value;
|
|
233
|
+
const promise = (scope.pending = state.value);
|
|
233
234
|
promise.then(function (result) {
|
|
234
|
-
if (
|
|
235
|
+
if (scope.destroyed || scope.pending !== promise)
|
|
235
236
|
return;
|
|
237
|
+
scope.pending = null;
|
|
236
238
|
scope.value = result;
|
|
237
239
|
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
238
240
|
});
|
|
@@ -256,10 +258,12 @@ function ExecuteFunction(callback, greedy, allowStatic) {
|
|
|
256
258
|
scope.scopes = state.nextCalc;
|
|
257
259
|
UpdateEmitters(scope, state);
|
|
258
260
|
if (async) {
|
|
259
|
-
|
|
261
|
+
console.log("resolving async scope");
|
|
262
|
+
const promise = (scope.pending = state.value);
|
|
260
263
|
promise.then(function (result) {
|
|
261
|
-
if (
|
|
264
|
+
if (scope.destroyed || scope.pending !== promise)
|
|
262
265
|
return;
|
|
266
|
+
scope.pending = null;
|
|
263
267
|
scope.value = result;
|
|
264
268
|
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
265
269
|
});
|
|
@@ -419,12 +423,13 @@ function DestroyAllScopes(scopes) {
|
|
|
419
423
|
function DestroyScope(scope) {
|
|
420
424
|
if (!scope || scope.type === "static")
|
|
421
425
|
return;
|
|
422
|
-
emitter_1.Emitter.Clear(scope.emitter);
|
|
423
426
|
for (const key in scope.scopes)
|
|
424
427
|
DestroyScope(scope.scopes[key]);
|
|
428
|
+
// Emitter.Destroy(scope.emitter);
|
|
429
|
+
emitter_1.Emitter.DestroyCallback(scope.setCallback);
|
|
425
430
|
if (scope.emitters !== null)
|
|
426
431
|
for (let x = 0; x < scope.emitters.length; x++)
|
|
427
|
-
emitter_1.Emitter.
|
|
432
|
+
emitter_1.Emitter.Compact(scope.emitters[x]);
|
|
428
433
|
scope.value = undefined;
|
|
429
434
|
scope.scopes = null;
|
|
430
435
|
scope.emitters = null;
|
package/Utils/emitter.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export type EmitterCallback<T extends readonly any[] = any[]> = (...args: T) =>
|
|
|
2
2
|
export type Emitter = EmitterCallback[];
|
|
3
3
|
export declare namespace Emitter {
|
|
4
4
|
function Create(): Emitter;
|
|
5
|
+
function Compact(emitter: Emitter): void;
|
|
6
|
+
function DestroyCallback(callback: EmitterCallback): void;
|
|
5
7
|
function On(emitter: Emitter, callback: EmitterCallback): void;
|
|
6
8
|
function Emit(emitter: Emitter, ...args: any[]): void;
|
|
7
9
|
function Remove(emitter: Emitter, callback: EmitterCallback): void;
|
package/Utils/emitter.js
CHANGED
|
@@ -3,18 +3,93 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Emitter = void 0;
|
|
4
4
|
var Emitter;
|
|
5
5
|
(function (Emitter) {
|
|
6
|
+
const destroyed = new WeakSet();
|
|
7
|
+
// const pendingCompactEmitters = new Set<Emitter>();
|
|
8
|
+
let pendingCompactEmitters = [];
|
|
6
9
|
function Create() {
|
|
7
10
|
return [];
|
|
8
11
|
}
|
|
9
12
|
Emitter.Create = Create;
|
|
13
|
+
const scheduleCallback = typeof requestIdleCallback !== "undefined"
|
|
14
|
+
? requestIdleCallback
|
|
15
|
+
: setTimeout;
|
|
16
|
+
function Compact(emitter) {
|
|
17
|
+
if (emitter.length === 0)
|
|
18
|
+
return;
|
|
19
|
+
pendingCompactEmitters.push(emitter);
|
|
20
|
+
ScheduleCompact();
|
|
21
|
+
}
|
|
22
|
+
Emitter.Compact = Compact;
|
|
23
|
+
let compactScheduled = false;
|
|
24
|
+
function ScheduleCompact() {
|
|
25
|
+
if (compactScheduled)
|
|
26
|
+
return;
|
|
27
|
+
compactScheduled = true;
|
|
28
|
+
scheduleCallback(PerformCompact);
|
|
29
|
+
}
|
|
30
|
+
function PerformCompact() {
|
|
31
|
+
compactScheduled = false;
|
|
32
|
+
let compactEmitters = pendingCompactEmitters;
|
|
33
|
+
pendingCompactEmitters = [];
|
|
34
|
+
const processedEmitters = new Set();
|
|
35
|
+
for (let x = 0; x < compactEmitters.length; x++)
|
|
36
|
+
if (!processedEmitters.has(compactEmitters[x])) {
|
|
37
|
+
CompactEmitter(compactEmitters[x]);
|
|
38
|
+
processedEmitters.add(compactEmitters[x]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/* export function Compact(emitter: Emitter) {
|
|
42
|
+
if (emitter.length === 0 || destroyed.has(emitter)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (pendingCompactEmitters.size === 0) {
|
|
47
|
+
scheduleCallback(CompactPending);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
pendingCompactEmitters.add(emitter);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function CompactPending() {
|
|
54
|
+
if (pendingCompactEmitters.size === 0) return;
|
|
55
|
+
|
|
56
|
+
const pending = Array.from(pendingCompactEmitters);
|
|
57
|
+
pendingCompactEmitters.clear();
|
|
58
|
+
|
|
59
|
+
for (let x = 0; x < pending.length; x++)
|
|
60
|
+
if (!destroyed.has(pending[x])) CompactEmitter(pending[x]);
|
|
61
|
+
} */
|
|
62
|
+
function CompactEmitter(emitter) {
|
|
63
|
+
let count = 0;
|
|
64
|
+
for (; count < emitter.length &&
|
|
65
|
+
(emitter[count] === null || destroyed.has(emitter[count])); count++) { }
|
|
66
|
+
if (count > 0)
|
|
67
|
+
emitter.splice(0, count);
|
|
68
|
+
let writePos = 0;
|
|
69
|
+
for (let x = 0; x < emitter.length; x++) {
|
|
70
|
+
if (emitter[x] !== null && !destroyed.has(emitter[x]))
|
|
71
|
+
emitter[writePos++] = emitter[x];
|
|
72
|
+
}
|
|
73
|
+
if (writePos < emitter.length)
|
|
74
|
+
emitter.splice(writePos);
|
|
75
|
+
}
|
|
76
|
+
function DestroyCallback(callback) {
|
|
77
|
+
destroyed.add(callback);
|
|
78
|
+
}
|
|
79
|
+
Emitter.DestroyCallback = DestroyCallback;
|
|
80
|
+
/* export function Destroy(emitter: Emitter) {
|
|
81
|
+
pendingCompactEmitters.delete(emitter);
|
|
82
|
+
destroyed.add(emitter);
|
|
83
|
+
} */
|
|
10
84
|
function On(emitter, callback) {
|
|
11
85
|
emitter.push(callback);
|
|
12
86
|
}
|
|
13
87
|
Emitter.On = On;
|
|
14
88
|
function Emit(emitter, ...args) {
|
|
89
|
+
// pendingCompactEmitters.delete(emitter);
|
|
15
90
|
let writePos = 0;
|
|
16
91
|
for (let x = 0; x < emitter.length; x++) {
|
|
17
|
-
if (emitter[x] !== null) {
|
|
92
|
+
if (emitter[x] !== null && !destroyed.has(emitter[x])) {
|
|
18
93
|
emitter[x](...args);
|
|
19
94
|
emitter[writePos++] = emitter[x];
|
|
20
95
|
}
|
|
@@ -25,11 +100,16 @@ var Emitter;
|
|
|
25
100
|
Emitter.Emit = Emit;
|
|
26
101
|
function Remove(emitter, callback) {
|
|
27
102
|
const index = emitter.indexOf(callback);
|
|
28
|
-
if (index >= 0)
|
|
103
|
+
if (index >= 0) {
|
|
29
104
|
emitter[index] = null;
|
|
105
|
+
Compact(emitter);
|
|
106
|
+
}
|
|
30
107
|
}
|
|
31
108
|
Emitter.Remove = Remove;
|
|
32
109
|
function Clear(emitter) {
|
|
110
|
+
if (emitter.length === 0)
|
|
111
|
+
return;
|
|
112
|
+
// pendingCompactEmitters.delete(emitter);
|
|
33
113
|
emitter.splice(0);
|
|
34
114
|
}
|
|
35
115
|
Emitter.Clear = Clear;
|