j-templates 7.0.90 → 7.0.92
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.d.ts +3 -0
- package/DOM/createAssignment.js +6 -0
- package/DOM/createAttributeAssignment.d.ts +1 -0
- package/DOM/createAttributeAssignment.js +4 -0
- package/DOM/createEventAssignment.d.ts +1 -0
- package/DOM/createEventAssignment.js +4 -0
- package/DOM/createPropertyAssignment.d.ts +1 -0
- package/DOM/createPropertyAssignment.js +29 -0
- package/DOM/domNodeConfig.js +35 -15
- package/Node/component.js +2 -0
- package/Node/nodeConfig.d.ts +3 -0
- package/Node/vNode.js +61 -160
- package/Node/vNode.types.d.ts +1 -5
- package/Store/Store/store.js +1 -1
- package/Store/Store/storeAsync.js +1 -1
- package/Store/Store/storeSync.js +3 -3
- package/Store/Tree/observableNode.d.ts +1 -15
- package/Store/Tree/observableNode.js +129 -112
- package/Store/Tree/observableScope.d.ts +29 -11
- package/Store/Tree/observableScope.js +162 -52
- package/Utils/decorators.js +4 -4
- package/Utils/emitter.d.ts +1 -3
- package/Utils/emitter.js +43 -92
- package/Utils/functions.js +1 -1
- package/Utils/json.js +3 -3
- package/index.d.ts +1 -1
- package/index.js +2 -1
- package/package.json +1 -1
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ObservableScope = void 0;
|
|
4
4
|
exports.InlineScope = InlineScope;
|
|
5
|
+
exports.MappedScope = MappedScope;
|
|
5
6
|
exports.GateScope = GateScope;
|
|
6
7
|
exports.PeekScope = PeekScope;
|
|
7
8
|
const emitter_1 = require("../../Utils/emitter");
|
|
8
9
|
const functions_1 = require("../../Utils/functions");
|
|
10
|
+
function Invoke(param, callback) {
|
|
11
|
+
return callback(param);
|
|
12
|
+
}
|
|
9
13
|
/**
|
|
10
14
|
* Creates a dynamic (reactive) observable scope.
|
|
11
15
|
* @template T The type of value stored in the scope.
|
|
@@ -28,12 +32,22 @@ function CreateDynamicScope(getFunction, greedy, value) {
|
|
|
28
32
|
value,
|
|
29
33
|
emitter: emitter_1.Emitter.Create(),
|
|
30
34
|
emitters: null,
|
|
35
|
+
onUpdated: null,
|
|
31
36
|
onDestroyed: null,
|
|
32
37
|
scopes: null,
|
|
38
|
+
mappedScopes: null,
|
|
33
39
|
};
|
|
34
40
|
scope.setCallback = OnSet.bind(scope);
|
|
35
41
|
return scope;
|
|
36
42
|
}
|
|
43
|
+
function CreateBasicScope(getFunction) {
|
|
44
|
+
return {
|
|
45
|
+
type: "basic",
|
|
46
|
+
getFunction,
|
|
47
|
+
emitter: emitter_1.Emitter.Create(),
|
|
48
|
+
destroyed: false
|
|
49
|
+
};
|
|
50
|
+
}
|
|
37
51
|
/**
|
|
38
52
|
* Creates a static (non-reactive) observable scope.
|
|
39
53
|
* Static scopes are optimized for values that never change and don't need dependency tracking.
|
|
@@ -45,6 +59,8 @@ function CreateStaticScope(initialValue) {
|
|
|
45
59
|
return {
|
|
46
60
|
type: "static",
|
|
47
61
|
value: initialValue,
|
|
62
|
+
onDestroyed: null,
|
|
63
|
+
destroyed: false
|
|
48
64
|
};
|
|
49
65
|
}
|
|
50
66
|
let scopeQueue = [];
|
|
@@ -173,6 +189,8 @@ function RegisterScope(scope) {
|
|
|
173
189
|
* @returns The scope's current value.
|
|
174
190
|
*/
|
|
175
191
|
function GetScopeValue(scope) {
|
|
192
|
+
if (scope.type === "basic")
|
|
193
|
+
return scope.getFunction();
|
|
176
194
|
if (scope.type === "static" || !scope.dirty || scope.destroyed)
|
|
177
195
|
return scope.value;
|
|
178
196
|
ExecuteScope(scope);
|
|
@@ -195,15 +213,17 @@ let watchState = null;
|
|
|
195
213
|
* @param currentCalc Optional map of existing inline scopes to reuse.
|
|
196
214
|
* @returns The watch state containing tracked dependencies and result.
|
|
197
215
|
*/
|
|
198
|
-
function WatchFunction(callback,
|
|
216
|
+
function WatchFunction(callback, currentScopes, currentMappedScopes, initialEmitters) {
|
|
199
217
|
const parent = watchState;
|
|
200
218
|
watchState = {
|
|
201
219
|
emitterIndex: 0,
|
|
202
220
|
value: null,
|
|
203
221
|
emitters: initialEmitters,
|
|
204
222
|
emitterSet: null,
|
|
205
|
-
|
|
206
|
-
|
|
223
|
+
currentScopes,
|
|
224
|
+
nextScopes: null,
|
|
225
|
+
currentMappedScopes: currentMappedScopes,
|
|
226
|
+
nextMappedScopes: null,
|
|
207
227
|
strategy: initialEmitters === null ? INIT_STRATEGY : SAME_STRATEGY,
|
|
208
228
|
};
|
|
209
229
|
watchState.value = callback();
|
|
@@ -223,24 +243,35 @@ function WatchFunction(callback, currentCalc, initialEmitters) {
|
|
|
223
243
|
*/
|
|
224
244
|
function ExecuteScope(scope) {
|
|
225
245
|
scope.dirty = false;
|
|
226
|
-
const state = WatchFunction(scope.getFunction, scope.scopes, scope.emitters);
|
|
246
|
+
const state = WatchFunction(scope.getFunction, scope.scopes, scope.mappedScopes, scope.emitters);
|
|
227
247
|
UpdateEmitters(scope, state);
|
|
228
|
-
const
|
|
229
|
-
scope.scopes = state.
|
|
230
|
-
|
|
231
|
-
|
|
248
|
+
const currentScopes = state.currentScopes;
|
|
249
|
+
scope.scopes = state.nextScopes;
|
|
250
|
+
const currentMappedScopes = state.currentMappedScopes;
|
|
251
|
+
scope.mappedScopes = state.nextMappedScopes;
|
|
252
|
+
if (currentScopes)
|
|
253
|
+
for (let x = 0; x < currentScopes.length; x++)
|
|
254
|
+
currentScopes[x] && DestroyScope(currentScopes[x][1]);
|
|
255
|
+
if (currentMappedScopes && currentMappedScopes.size > 0)
|
|
256
|
+
for (const scopes of currentMappedScopes.values())
|
|
257
|
+
DestroyAllScopes(scopes);
|
|
232
258
|
if (scope.async) {
|
|
233
259
|
const promise = (scope.pending = state.value);
|
|
234
260
|
promise.then(function (result) {
|
|
235
261
|
if (scope.destroyed || scope.pending !== promise)
|
|
236
262
|
return;
|
|
237
263
|
scope.pending = null;
|
|
264
|
+
const lastValue = scope.value;
|
|
238
265
|
scope.value = result;
|
|
266
|
+
scope.onUpdated && emitter_1.Emitter.Emit(scope.onUpdated, lastValue, scope);
|
|
239
267
|
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
240
268
|
});
|
|
241
269
|
}
|
|
242
|
-
else
|
|
270
|
+
else {
|
|
271
|
+
const lastValue = scope.value;
|
|
243
272
|
scope.value = state.value;
|
|
273
|
+
scope.onUpdated && emitter_1.Emitter.Emit(scope.onUpdated, lastValue, scope);
|
|
274
|
+
}
|
|
244
275
|
}
|
|
245
276
|
/**
|
|
246
277
|
* Creates a scope from a function, choosing between static and dynamic based on dependencies.
|
|
@@ -250,15 +281,15 @@ function ExecuteScope(scope) {
|
|
|
250
281
|
* @param allowStatic Whether to return a static scope if no dependencies are found.
|
|
251
282
|
* @returns A new observable scope.
|
|
252
283
|
*/
|
|
253
|
-
function ExecuteFunction(callback, greedy
|
|
284
|
+
function ExecuteFunction(callback, greedy) {
|
|
254
285
|
const async = (0, functions_1.IsAsync)(callback);
|
|
255
|
-
const state = WatchFunction(callback, null, null);
|
|
256
|
-
if (
|
|
286
|
+
const state = WatchFunction(callback, null, null, null);
|
|
287
|
+
if (async || state.emitters !== null) {
|
|
257
288
|
const scope = CreateDynamicScope(callback, greedy, async ? null : state.value);
|
|
258
|
-
scope.scopes = state.
|
|
289
|
+
scope.scopes = state.nextScopes;
|
|
290
|
+
scope.mappedScopes = state.nextMappedScopes;
|
|
259
291
|
UpdateEmitters(scope, state);
|
|
260
292
|
if (async) {
|
|
261
|
-
console.log("resolving async scope");
|
|
262
293
|
const promise = (scope.pending = state.value);
|
|
263
294
|
promise.then(function (result) {
|
|
264
295
|
if (scope.destroyed || scope.pending !== promise)
|
|
@@ -273,17 +304,57 @@ function ExecuteFunction(callback, greedy, allowStatic) {
|
|
|
273
304
|
const value = state.value;
|
|
274
305
|
return CreateStaticScope(value);
|
|
275
306
|
}
|
|
276
|
-
function ScopeHelper(callback,
|
|
277
|
-
const nextScopes = (watchState.
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
307
|
+
function ScopeHelper(callback, key, greedy) {
|
|
308
|
+
const nextScopes = (watchState.nextScopes ??= []);
|
|
309
|
+
const currentScopes = watchState.currentScopes;
|
|
310
|
+
let x = 0;
|
|
311
|
+
if (currentScopes)
|
|
312
|
+
for (; x < currentScopes.length && (currentScopes[x] === null || currentScopes[x][0] !== key); x++) { }
|
|
313
|
+
if (!currentScopes || x === currentScopes.length) {
|
|
314
|
+
const nextScope = ExecuteFunction(callback, greedy);
|
|
315
|
+
nextScopes.push([key, nextScope]);
|
|
316
|
+
return nextScope;
|
|
317
|
+
}
|
|
318
|
+
const nextScopePair = currentScopes[x];
|
|
319
|
+
currentScopes[x] = null;
|
|
320
|
+
nextScopes.push(nextScopePair);
|
|
321
|
+
return nextScopePair[1];
|
|
286
322
|
}
|
|
323
|
+
function MappedScopeHelper(callback, data, onUpdated, onDestroyed) {
|
|
324
|
+
const nextScopes = (watchState.nextMappedScopes ??= new Map());
|
|
325
|
+
const currentScopes = watchState.currentMappedScopes;
|
|
326
|
+
if (currentScopes?.has(data)) {
|
|
327
|
+
const nextScopeArray = currentScopes.get(data);
|
|
328
|
+
if (nextScopeArray.length === 1) {
|
|
329
|
+
currentScopes.delete(data);
|
|
330
|
+
nextScopes.set(data, nextScopeArray);
|
|
331
|
+
return nextScopeArray[0];
|
|
332
|
+
}
|
|
333
|
+
const nullIndex = nextScopeArray.lastIndexOf(null);
|
|
334
|
+
const valueIndex = nullIndex < 0 ? 0 : nullIndex + 1;
|
|
335
|
+
if (valueIndex === nextScopeArray.length - 1)
|
|
336
|
+
currentScopes.delete(data);
|
|
337
|
+
else {
|
|
338
|
+
const scope = nextScopeArray[valueIndex];
|
|
339
|
+
nextScopeArray[valueIndex] = null;
|
|
340
|
+
const scopes = nextScopes.get(data) ?? [];
|
|
341
|
+
scopes.push(scope);
|
|
342
|
+
nextScopes.set(data, scopes);
|
|
343
|
+
return scope;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
const getFunction = Invoke.bind(null, data, callback);
|
|
347
|
+
const scope = ExecuteFunction(getFunction, false);
|
|
348
|
+
onUpdated && ObservableScope.OnUpdated(scope, onUpdated);
|
|
349
|
+
onDestroyed && ObservableScope.OnDestroyed(scope, onDestroyed);
|
|
350
|
+
const scopes = nextScopes.get(data) ?? [];
|
|
351
|
+
scopes.push(scope);
|
|
352
|
+
nextScopes.set(data, scopes);
|
|
353
|
+
return scope;
|
|
354
|
+
}
|
|
355
|
+
const SCOPE_DEFAULT = Symbol("SCOPE_DEFAULT");
|
|
356
|
+
const GATE_DEFAULT = Symbol("GATE_DEFAULT");
|
|
357
|
+
const PEEK_DEFAULT = Symbol("PEEK_DEFAULT");
|
|
287
358
|
/**
|
|
288
359
|
* Creates an inline computed scope registered as a dependency of the parent.
|
|
289
360
|
* The scope is memoized by ID and reused across reads within the same parent evaluation.
|
|
@@ -304,11 +375,19 @@ function InlineScope(callback, idOverride) {
|
|
|
304
375
|
if (watchState === null) {
|
|
305
376
|
throw new Error("scope() must be called within a watch context");
|
|
306
377
|
}
|
|
307
|
-
const id = idOverride ??
|
|
378
|
+
const id = idOverride ?? SCOPE_DEFAULT;
|
|
308
379
|
const scope = ScopeHelper(callback, id, false);
|
|
309
380
|
RegisterScope(scope);
|
|
310
381
|
return GetScopeValue(scope);
|
|
311
382
|
}
|
|
383
|
+
function MappedScope(data, callback, onUpdated, onDestroyed) {
|
|
384
|
+
if (watchState === null) {
|
|
385
|
+
throw new Error("scope() must be called within a watch context");
|
|
386
|
+
}
|
|
387
|
+
const scope = MappedScopeHelper(callback, data, onUpdated, onDestroyed);
|
|
388
|
+
RegisterScope(scope);
|
|
389
|
+
return GetScopeValue(scope);
|
|
390
|
+
}
|
|
312
391
|
/**
|
|
313
392
|
* Creates a gatekeeper scope that only emits when the value actually changes (===).
|
|
314
393
|
* Prevents unnecessary downstream re-evaluations when the derived value stays the same.
|
|
@@ -331,7 +410,7 @@ function GateScope(callback, idOverride) {
|
|
|
331
410
|
if (watchState === null) {
|
|
332
411
|
throw new Error("gate() must be called within a watch context");
|
|
333
412
|
}
|
|
334
|
-
const id = idOverride ??
|
|
413
|
+
const id = idOverride ?? GATE_DEFAULT;
|
|
335
414
|
const scope = ScopeHelper(callback, id, true);
|
|
336
415
|
RegisterScope(scope);
|
|
337
416
|
return GetScopeValue(scope);
|
|
@@ -360,7 +439,7 @@ function PeekScope(callback, idOverride) {
|
|
|
360
439
|
if (watchState === null) {
|
|
361
440
|
throw new Error("peek() must be called within a watch context");
|
|
362
441
|
}
|
|
363
|
-
const id = idOverride ??
|
|
442
|
+
const id = idOverride ?? PEEK_DEFAULT;
|
|
364
443
|
const scope = ScopeHelper(callback, id, false);
|
|
365
444
|
return GetScopeValue(scope);
|
|
366
445
|
}
|
|
@@ -421,23 +500,38 @@ function DestroyAllScopes(scopes) {
|
|
|
421
500
|
* @param scope The scope to destroy.
|
|
422
501
|
*/
|
|
423
502
|
function DestroyScope(scope) {
|
|
424
|
-
if (!scope || scope.
|
|
503
|
+
if (!scope || scope.destroyed)
|
|
425
504
|
return;
|
|
426
|
-
for (const key in scope.scopes)
|
|
427
|
-
DestroyScope(scope.scopes[key]);
|
|
428
|
-
// Emitter.Destroy(scope.emitter);
|
|
429
|
-
emitter_1.Emitter.DestroyCallback(scope.setCallback);
|
|
430
|
-
if (scope.emitters !== null)
|
|
431
|
-
for (let x = 0; x < scope.emitters.length; x++)
|
|
432
|
-
emitter_1.Emitter.Compact(scope.emitters[x]);
|
|
433
|
-
scope.value = undefined;
|
|
434
|
-
scope.scopes = null;
|
|
435
|
-
scope.emitters = null;
|
|
436
|
-
scope.emitter = null;
|
|
437
|
-
scope.getFunction = null;
|
|
438
|
-
scope.setCallback = null;
|
|
439
505
|
scope.destroyed = true;
|
|
440
|
-
|
|
506
|
+
switch (scope.type) {
|
|
507
|
+
case "basic": {
|
|
508
|
+
scope.emitter = null;
|
|
509
|
+
break;
|
|
510
|
+
}
|
|
511
|
+
case "dynamic": {
|
|
512
|
+
if (scope.scopes)
|
|
513
|
+
for (let x = 0; x < scope.scopes.length; x++)
|
|
514
|
+
DestroyScope(scope.scopes[x][1]);
|
|
515
|
+
if (scope.mappedScopes && scope.mappedScopes.size > 0)
|
|
516
|
+
for (const childScopes of scope.mappedScopes.values())
|
|
517
|
+
DestroyAllScopes(childScopes);
|
|
518
|
+
if (scope.emitters !== null)
|
|
519
|
+
for (let x = 0; x < scope.emitters.length; x++)
|
|
520
|
+
emitter_1.Emitter.Remove(scope.emitters[x], scope.setCallback);
|
|
521
|
+
scope.scopes = null;
|
|
522
|
+
scope.mappedScopes = null;
|
|
523
|
+
scope.emitters = null;
|
|
524
|
+
scope.emitter = null;
|
|
525
|
+
scope.getFunction = null;
|
|
526
|
+
scope.setCallback = null;
|
|
527
|
+
}
|
|
528
|
+
case "static": {
|
|
529
|
+
const lastValue = scope.value;
|
|
530
|
+
scope.value = undefined;
|
|
531
|
+
scope.onDestroyed && emitter_1.Emitter.Emit(scope.onDestroyed, lastValue);
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
441
535
|
}
|
|
442
536
|
var ObservableScope;
|
|
443
537
|
(function (ObservableScope) {
|
|
@@ -449,10 +543,18 @@ var ObservableScope;
|
|
|
449
543
|
* @param force If true, always creates a dynamic scope even without dependencies. Defaults to false.
|
|
450
544
|
* @returns A new observable scope.
|
|
451
545
|
*/
|
|
452
|
-
function Create(valueFunction
|
|
453
|
-
return ExecuteFunction(valueFunction,
|
|
546
|
+
function Create(valueFunction) {
|
|
547
|
+
return ExecuteFunction(valueFunction, false);
|
|
454
548
|
}
|
|
455
549
|
ObservableScope.Create = Create;
|
|
550
|
+
function Greedy(valueFunction) {
|
|
551
|
+
return ExecuteFunction(valueFunction, true);
|
|
552
|
+
}
|
|
553
|
+
ObservableScope.Greedy = Greedy;
|
|
554
|
+
function Basic(valueFunction) {
|
|
555
|
+
return CreateBasicScope(valueFunction);
|
|
556
|
+
}
|
|
557
|
+
ObservableScope.Basic = Basic;
|
|
456
558
|
/**
|
|
457
559
|
* Registers an emitter as a dependency for the current watch context.
|
|
458
560
|
* @param emitter The emitter to register as a dependency.
|
|
@@ -478,7 +580,7 @@ var ObservableScope;
|
|
|
478
580
|
* @returns The scope's current value.
|
|
479
581
|
*/
|
|
480
582
|
function Value(scope) {
|
|
481
|
-
if (!scope)
|
|
583
|
+
if (!scope || scope.destroyed)
|
|
482
584
|
return undefined;
|
|
483
585
|
Touch(scope);
|
|
484
586
|
return Peek(scope);
|
|
@@ -490,7 +592,7 @@ var ObservableScope;
|
|
|
490
592
|
* @param scope The scope to register as a dependency.
|
|
491
593
|
*/
|
|
492
594
|
function Touch(scope) {
|
|
493
|
-
if (!scope)
|
|
595
|
+
if (!scope || scope.destroyed)
|
|
494
596
|
return;
|
|
495
597
|
RegisterScope(scope);
|
|
496
598
|
}
|
|
@@ -502,7 +604,7 @@ var ObservableScope;
|
|
|
502
604
|
* @param callback Function to invoke when the scope's value changes.
|
|
503
605
|
*/
|
|
504
606
|
function Watch(scope, callback) {
|
|
505
|
-
if (!scope || scope.type === "static")
|
|
607
|
+
if (!scope || scope.destroyed || scope.type === "static")
|
|
506
608
|
return;
|
|
507
609
|
emitter_1.Emitter.On(scope.emitter, callback);
|
|
508
610
|
}
|
|
@@ -514,19 +616,24 @@ var ObservableScope;
|
|
|
514
616
|
* @param callback The callback function to remove.
|
|
515
617
|
*/
|
|
516
618
|
function Unwatch(scope, callback) {
|
|
517
|
-
if (!scope || scope.type === "static")
|
|
619
|
+
if (!scope || scope.destroyed || scope.type === "static")
|
|
518
620
|
return;
|
|
519
621
|
emitter_1.Emitter.Remove(scope.emitter, callback);
|
|
520
622
|
}
|
|
521
623
|
ObservableScope.Unwatch = Unwatch;
|
|
624
|
+
function OnUpdated(scope, callback) {
|
|
625
|
+
if (scope.type !== "dynamic")
|
|
626
|
+
return;
|
|
627
|
+
scope.onUpdated ??= emitter_1.Emitter.Create();
|
|
628
|
+
emitter_1.Emitter.On(scope.onUpdated, callback);
|
|
629
|
+
}
|
|
630
|
+
ObservableScope.OnUpdated = OnUpdated;
|
|
522
631
|
/**
|
|
523
632
|
* Registers a callback to be invoked when the scope is destroyed.
|
|
524
633
|
* @param scope The scope to monitor for destruction.
|
|
525
634
|
* @param callback Function to invoke when the scope is destroyed.
|
|
526
635
|
*/
|
|
527
636
|
function OnDestroyed(scope, callback) {
|
|
528
|
-
if (scope.type === "static")
|
|
529
|
-
return;
|
|
530
637
|
scope.onDestroyed ??= emitter_1.Emitter.Create();
|
|
531
638
|
emitter_1.Emitter.On(scope.onDestroyed, callback);
|
|
532
639
|
}
|
|
@@ -536,9 +643,12 @@ var ObservableScope;
|
|
|
536
643
|
* @param scope The scope to mark for update.
|
|
537
644
|
*/
|
|
538
645
|
function Update(scope) {
|
|
539
|
-
if (!scope || scope.type === "static")
|
|
646
|
+
if (!scope || scope.destroyed || scope.type === "static")
|
|
540
647
|
return;
|
|
541
|
-
|
|
648
|
+
if (scope.type === "basic") {
|
|
649
|
+
emitter_1.Emitter.Emit(scope.emitter, this);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
542
652
|
scope.setCallback();
|
|
543
653
|
}
|
|
544
654
|
ObservableScope.Update = Update;
|
package/Utils/decorators.js
CHANGED
|
@@ -134,7 +134,7 @@ function GetDestroyArrayForPrototype(prototype, create = true) {
|
|
|
134
134
|
return array;
|
|
135
135
|
}
|
|
136
136
|
function CreateComputedScope(getter, store, defaultValue) {
|
|
137
|
-
const getterScope = observableScope_1.ObservableScope.
|
|
137
|
+
const getterScope = observableScope_1.ObservableScope.Greedy(getter);
|
|
138
138
|
observableScope_1.ObservableScope.Watch(getterScope, (scope) => {
|
|
139
139
|
const data = observableScope_1.ObservableScope.Peek(scope);
|
|
140
140
|
store.Write(data, "root");
|
|
@@ -566,9 +566,9 @@ function Value() {
|
|
|
566
566
|
* @returns An observable scope created from the tuple's value.
|
|
567
567
|
*/
|
|
568
568
|
function CreateValueScope(tuple) {
|
|
569
|
-
return observableScope_1.ObservableScope.
|
|
569
|
+
return observableScope_1.ObservableScope.Basic(function () {
|
|
570
570
|
return tuple[1];
|
|
571
|
-
}
|
|
571
|
+
});
|
|
572
572
|
}
|
|
573
573
|
/**
|
|
574
574
|
* Value decorator implementation for creating value properties.
|
|
@@ -814,7 +814,7 @@ function WatchDecorator(target, propertyKey, descriptor, scopeFunction) {
|
|
|
814
814
|
function scopeFunctionWrapper() {
|
|
815
815
|
return scopeFunction(instance);
|
|
816
816
|
}
|
|
817
|
-
const scope = observableScope_1.ObservableScope.
|
|
817
|
+
const scope = observableScope_1.ObservableScope.Greedy(scopeFunctionWrapper);
|
|
818
818
|
const propertyMap = GetScopeMapForInstance(this);
|
|
819
819
|
propertyMap[propertyKey] = [scope, undefined];
|
|
820
820
|
observableScope_1.ObservableScope.Watch(scope, function (scope) {
|
package/Utils/emitter.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export type EmitterCallback<T extends readonly any[] = any[]> = (...args: T) => void;
|
|
2
|
-
export type Emitter = EmitterCallback[];
|
|
2
|
+
export type Emitter = [number, ...EmitterCallback[]];
|
|
3
3
|
export declare namespace Emitter {
|
|
4
4
|
function Create(): Emitter;
|
|
5
|
-
function Compact(emitter: Emitter): void;
|
|
6
|
-
function DestroyCallback(callback: EmitterCallback): void;
|
|
7
5
|
function On(emitter: Emitter, callback: EmitterCallback): void;
|
|
8
6
|
function Emit(emitter: Emitter, ...args: any[]): void;
|
|
9
7
|
function Remove(emitter: Emitter, callback: EmitterCallback): void;
|
package/Utils/emitter.js
CHANGED
|
@@ -1,116 +1,67 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Emitter = void 0;
|
|
4
|
+
const scheduleCallback = typeof requestIdleCallback !== "undefined"
|
|
5
|
+
? requestIdleCallback
|
|
6
|
+
: setTimeout;
|
|
7
|
+
const pendingCompactEmitters = new Set();
|
|
8
|
+
function Compact(emitter) {
|
|
9
|
+
if (emitter.length === 1 || emitter[0] === 0)
|
|
10
|
+
return;
|
|
11
|
+
pendingCompactEmitters.add(emitter);
|
|
12
|
+
ScheduleCompact();
|
|
13
|
+
}
|
|
14
|
+
let compactScheduled = false;
|
|
15
|
+
function ScheduleCompact() {
|
|
16
|
+
if (compactScheduled)
|
|
17
|
+
return;
|
|
18
|
+
compactScheduled = true;
|
|
19
|
+
scheduleCallback(PerformCompact);
|
|
20
|
+
}
|
|
21
|
+
function PerformCompact() {
|
|
22
|
+
compactScheduled = false;
|
|
23
|
+
let compactEmitters = Array.from(pendingCompactEmitters);
|
|
24
|
+
pendingCompactEmitters.clear();
|
|
25
|
+
for (let x = 0; x < compactEmitters.length; x++)
|
|
26
|
+
CompactEmitter(compactEmitters[x]);
|
|
27
|
+
}
|
|
28
|
+
function CompactEmitter(emitter) {
|
|
29
|
+
if (emitter[0] === 0)
|
|
30
|
+
return;
|
|
31
|
+
emitter.splice(1, emitter[0]);
|
|
32
|
+
emitter[0] = 0;
|
|
33
|
+
}
|
|
4
34
|
var Emitter;
|
|
5
35
|
(function (Emitter) {
|
|
6
|
-
const destroyed = new WeakSet();
|
|
7
|
-
// const pendingCompactEmitters = new Set<Emitter>();
|
|
8
|
-
let pendingCompactEmitters = [];
|
|
9
36
|
function Create() {
|
|
10
|
-
return [];
|
|
37
|
+
return [0];
|
|
11
38
|
}
|
|
12
39
|
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
|
-
} */
|
|
84
40
|
function On(emitter, callback) {
|
|
85
41
|
emitter.push(callback);
|
|
86
42
|
}
|
|
87
43
|
Emitter.On = On;
|
|
88
44
|
function Emit(emitter, ...args) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
for (let x = 0; x < emitter.length; x++) {
|
|
92
|
-
if (emitter[x] !== null && !destroyed.has(emitter[x])) {
|
|
93
|
-
emitter[x](...args);
|
|
94
|
-
emitter[writePos++] = emitter[x];
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
if (writePos < emitter.length)
|
|
98
|
-
emitter.splice(writePos);
|
|
45
|
+
for (let x = emitter[0] + 1; x < emitter.length; x++)
|
|
46
|
+
emitter[x](...args);
|
|
99
47
|
}
|
|
100
48
|
Emitter.Emit = Emit;
|
|
101
49
|
function Remove(emitter, callback) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
50
|
+
if (emitter.length === 1)
|
|
51
|
+
return;
|
|
52
|
+
const startIndex = emitter[0] + 1;
|
|
53
|
+
const index = emitter.indexOf(callback, startIndex);
|
|
54
|
+
if (index > 0) {
|
|
55
|
+
emitter[0]++;
|
|
56
|
+
emitter[index] = emitter[startIndex];
|
|
57
|
+
emitter[startIndex] = null;
|
|
105
58
|
Compact(emitter);
|
|
106
59
|
}
|
|
107
60
|
}
|
|
108
61
|
Emitter.Remove = Remove;
|
|
109
62
|
function Clear(emitter) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
// pendingCompactEmitters.delete(emitter);
|
|
113
|
-
emitter.splice(0);
|
|
63
|
+
emitter.length > 1 && emitter.splice(1);
|
|
64
|
+
emitter[0] = 0;
|
|
114
65
|
}
|
|
115
66
|
Emitter.Clear = Clear;
|
|
116
67
|
})(Emitter || (exports.Emitter = Emitter = {}));
|
package/Utils/functions.js
CHANGED
package/Utils/json.js
CHANGED
|
@@ -55,9 +55,9 @@ function JsonDiffFactory() {
|
|
|
55
55
|
case "array": {
|
|
56
56
|
const typedSource = source;
|
|
57
57
|
const typedPatch = patch;
|
|
58
|
-
const result = typedPatch.
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
const result = new Array(typedPatch.length);
|
|
59
|
+
for (let x = 0; x < typedPatch.length; x++)
|
|
60
|
+
result[x] = JsonMerge(typedSource[x], typedPatch[x]);
|
|
61
61
|
return result;
|
|
62
62
|
}
|
|
63
63
|
case "object": {
|
package/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Component } from './Node/component';
|
|
2
|
-
export { InlineScope as scope, GateScope as gate, PeekScope as peek } from './Store/Tree/observableScope';
|
|
2
|
+
export { InlineScope as scope, GateScope as gate, PeekScope as peek, MappedScope as mapped } from './Store/Tree/observableScope';
|
package/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.peek = exports.gate = exports.scope = exports.Component = void 0;
|
|
3
|
+
exports.mapped = exports.peek = exports.gate = exports.scope = exports.Component = void 0;
|
|
4
4
|
var component_1 = require("./Node/component");
|
|
5
5
|
Object.defineProperty(exports, "Component", { enumerable: true, get: function () { return component_1.Component; } });
|
|
6
6
|
var observableScope_1 = require("./Store/Tree/observableScope");
|
|
7
7
|
Object.defineProperty(exports, "scope", { enumerable: true, get: function () { return observableScope_1.InlineScope; } });
|
|
8
8
|
Object.defineProperty(exports, "gate", { enumerable: true, get: function () { return observableScope_1.GateScope; } });
|
|
9
9
|
Object.defineProperty(exports, "peek", { enumerable: true, get: function () { return observableScope_1.PeekScope; } });
|
|
10
|
+
Object.defineProperty(exports, "mapped", { enumerable: true, get: function () { return observableScope_1.MappedScope; } });
|