@adaas/are-html 0.0.20 → 0.0.21
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/dist/browser/index.d.mts +161 -5
- package/dist/browser/index.mjs +357 -55
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.d.mts +7 -0
- package/dist/node/directives/AreDirectiveFor.directive.d.ts +7 -0
- package/dist/node/directives/AreDirectiveFor.directive.js +17 -2
- package/dist/node/directives/AreDirectiveFor.directive.js.map +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.mjs +17 -2
- package/dist/node/directives/AreDirectiveFor.directive.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveShow.directive.d.mts +32 -0
- package/dist/node/directives/AreDirectiveShow.directive.d.ts +32 -0
- package/dist/node/directives/AreDirectiveShow.directive.js +81 -0
- package/dist/node/directives/AreDirectiveShow.directive.js.map +1 -0
- package/dist/node/directives/AreDirectiveShow.directive.mjs +71 -0
- package/dist/node/directives/AreDirectiveShow.directive.mjs.map +1 -0
- package/dist/node/engine/AreHTML.engine.d.mts +2 -1
- package/dist/node/engine/AreHTML.engine.d.ts +2 -1
- package/dist/node/engine/AreHTML.engine.js +8 -2
- package/dist/node/engine/AreHTML.engine.js.map +1 -1
- package/dist/node/engine/AreHTML.engine.mjs +8 -2
- package/dist/node/engine/AreHTML.engine.mjs.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.d.mts +3 -0
- package/dist/node/engine/AreHTML.interpreter.d.ts +3 -0
- package/dist/node/engine/AreHTML.interpreter.js +29 -0
- package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.mjs +29 -0
- package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
- package/dist/node/index.d.mts +4 -1
- package/dist/node/index.d.ts +4 -1
- package/dist/node/index.js +21 -0
- package/dist/node/index.mjs +3 -0
- package/dist/node/instructions/AreHTML.instructions.constants.d.mts +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.d.ts +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.js +2 -1
- package/dist/node/instructions/AreHTML.instructions.constants.js.map +1 -1
- package/dist/node/instructions/AreHTML.instructions.constants.mjs +2 -1
- package/dist/node/instructions/AreHTML.instructions.constants.mjs.map +1 -1
- package/dist/node/instructions/AreHTML.instructions.types.d.mts +9 -1
- package/dist/node/instructions/AreHTML.instructions.types.d.ts +9 -1
- package/dist/node/instructions/HideElement.instruction.d.mts +13 -0
- package/dist/node/instructions/HideElement.instruction.d.ts +13 -0
- package/dist/node/instructions/HideElement.instruction.js +31 -0
- package/dist/node/instructions/HideElement.instruction.js.map +1 -0
- package/dist/node/instructions/HideElement.instruction.mjs +24 -0
- package/dist/node/instructions/HideElement.instruction.mjs.map +1 -0
- package/dist/node/lib/AreRoot/AreRoot.component.d.mts +57 -3
- package/dist/node/lib/AreRoot/AreRoot.component.d.ts +57 -3
- package/dist/node/lib/AreRoot/AreRoot.component.js +137 -48
- package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
- package/dist/node/lib/AreRoot/AreRoot.component.mjs +139 -50
- package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
- package/dist/node/lib/AreRoot/AreRootCache.context.d.mts +58 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.d.ts +58 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.js +106 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.js.map +1 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.mjs +99 -0
- package/dist/node/lib/AreRoot/AreRootCache.context.mjs.map +1 -0
- package/examples/jumpstart/dist/index.html +1 -1
- package/examples/jumpstart/dist/{mq1a0fv0-ccgtz6.js → mq7hqrxy-4kus50.js} +629 -433
- package/examples/signal-routing/dist/index.html +1 -1
- package/examples/signal-routing/dist/{mq1bzrik-4lec86.js → mq7k53th-qiwy4x.js} +903 -486
- package/examples/signal-routing/src/components/SettingsPage.component.ts +39 -0
- package/examples/signal-routing/src/concept.ts +2 -0
- package/package.json +3 -3
- package/src/directives/AreDirectiveFor.directive.ts +44 -2
- package/src/directives/AreDirectiveShow.directive.ts +127 -0
- package/src/engine/AreHTML.engine.ts +11 -1
- package/src/engine/AreHTML.interpreter.ts +50 -0
- package/src/index.ts +3 -0
- package/src/instructions/AreHTML.instructions.constants.ts +1 -0
- package/src/instructions/AreHTML.instructions.types.ts +9 -0
- package/src/instructions/HideElement.instruction.ts +29 -0
- package/src/lib/AreRoot/AreRoot.component.ts +201 -71
- package/src/lib/AreRoot/AreRootCache.context.ts +133 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { A_Fragment } from '@adaas/a-concept';
|
|
2
|
+
import { AreNode } from '@adaas/are';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A single cached, detached component subtree for an are-root outlet.
|
|
6
|
+
*
|
|
7
|
+
* `node` is fully compiled and its scene plan is intact (it was `unmount()`ed,
|
|
8
|
+
* not destroyed), so it can be re-mounted instantly without re-tokenizing,
|
|
9
|
+
* re-loading, transforming or compiling. `subscribers` records the exact set of
|
|
10
|
+
* nodes inside the subtree that were subscribed to the signal bus at the moment
|
|
11
|
+
* of stashing — they are unsubscribed while cached (so the detached DOM never
|
|
12
|
+
* reacts to signals) and re-subscribed verbatim on restore.
|
|
13
|
+
*/
|
|
14
|
+
type AreRootCacheEntry = {
|
|
15
|
+
node: AreNode;
|
|
16
|
+
subscribers: AreNode[];
|
|
17
|
+
};
|
|
18
|
+
declare class AreRootCache extends A_Fragment {
|
|
19
|
+
/**
|
|
20
|
+
* rootId -> (component tag -> cache entry). The inner Map preserves
|
|
21
|
+
* insertion order which is used as the LRU recency order: the first key is
|
|
22
|
+
* the least-recently-used entry, the last key the most-recently-used.
|
|
23
|
+
*/
|
|
24
|
+
protected _cache: Map<string, Map<string, AreRootCacheEntry>>;
|
|
25
|
+
/**
|
|
26
|
+
* Maximum number of cached subtrees kept per root. Older entries beyond this
|
|
27
|
+
* limit are evicted (and returned to the caller so it can destroy them).
|
|
28
|
+
*/
|
|
29
|
+
protected _limit: number;
|
|
30
|
+
constructor(limit?: number);
|
|
31
|
+
/**
|
|
32
|
+
* Maximum number of cached subtrees kept per root.
|
|
33
|
+
*/
|
|
34
|
+
get limit(): number;
|
|
35
|
+
protected bucket(rootId: string): Map<string, AreRootCacheEntry>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether a subtree for the given component tag is currently cached.
|
|
38
|
+
*/
|
|
39
|
+
has(rootId: string, tag: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Retrieve AND remove a cached subtree so it can become live again. Returns
|
|
42
|
+
* `undefined` on a cache miss.
|
|
43
|
+
*/
|
|
44
|
+
take(rootId: string, tag: string): AreRootCacheEntry | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Stash a detached subtree under the given component tag. Returns any entries
|
|
47
|
+
* that were evicted to honour the LRU limit (or replaced for the same tag) so
|
|
48
|
+
* the caller can `destroy()` them.
|
|
49
|
+
*/
|
|
50
|
+
put(rootId: string, tag: string, entry: AreRootCacheEntry): AreRootCacheEntry[];
|
|
51
|
+
/**
|
|
52
|
+
* Remove and return every cached entry for a root (e.g. on teardown) so the
|
|
53
|
+
* caller can destroy them.
|
|
54
|
+
*/
|
|
55
|
+
clear(rootId: string): AreRootCacheEntry[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { AreRootCache, type AreRootCacheEntry };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { A_Fragment } from '@adaas/a-concept';
|
|
2
|
+
import { AreNode } from '@adaas/are';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A single cached, detached component subtree for an are-root outlet.
|
|
6
|
+
*
|
|
7
|
+
* `node` is fully compiled and its scene plan is intact (it was `unmount()`ed,
|
|
8
|
+
* not destroyed), so it can be re-mounted instantly without re-tokenizing,
|
|
9
|
+
* re-loading, transforming or compiling. `subscribers` records the exact set of
|
|
10
|
+
* nodes inside the subtree that were subscribed to the signal bus at the moment
|
|
11
|
+
* of stashing — they are unsubscribed while cached (so the detached DOM never
|
|
12
|
+
* reacts to signals) and re-subscribed verbatim on restore.
|
|
13
|
+
*/
|
|
14
|
+
type AreRootCacheEntry = {
|
|
15
|
+
node: AreNode;
|
|
16
|
+
subscribers: AreNode[];
|
|
17
|
+
};
|
|
18
|
+
declare class AreRootCache extends A_Fragment {
|
|
19
|
+
/**
|
|
20
|
+
* rootId -> (component tag -> cache entry). The inner Map preserves
|
|
21
|
+
* insertion order which is used as the LRU recency order: the first key is
|
|
22
|
+
* the least-recently-used entry, the last key the most-recently-used.
|
|
23
|
+
*/
|
|
24
|
+
protected _cache: Map<string, Map<string, AreRootCacheEntry>>;
|
|
25
|
+
/**
|
|
26
|
+
* Maximum number of cached subtrees kept per root. Older entries beyond this
|
|
27
|
+
* limit are evicted (and returned to the caller so it can destroy them).
|
|
28
|
+
*/
|
|
29
|
+
protected _limit: number;
|
|
30
|
+
constructor(limit?: number);
|
|
31
|
+
/**
|
|
32
|
+
* Maximum number of cached subtrees kept per root.
|
|
33
|
+
*/
|
|
34
|
+
get limit(): number;
|
|
35
|
+
protected bucket(rootId: string): Map<string, AreRootCacheEntry>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether a subtree for the given component tag is currently cached.
|
|
38
|
+
*/
|
|
39
|
+
has(rootId: string, tag: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Retrieve AND remove a cached subtree so it can become live again. Returns
|
|
42
|
+
* `undefined` on a cache miss.
|
|
43
|
+
*/
|
|
44
|
+
take(rootId: string, tag: string): AreRootCacheEntry | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Stash a detached subtree under the given component tag. Returns any entries
|
|
47
|
+
* that were evicted to honour the LRU limit (or replaced for the same tag) so
|
|
48
|
+
* the caller can `destroy()` them.
|
|
49
|
+
*/
|
|
50
|
+
put(rootId: string, tag: string, entry: AreRootCacheEntry): AreRootCacheEntry[];
|
|
51
|
+
/**
|
|
52
|
+
* Remove and return every cached entry for a root (e.g. on teardown) so the
|
|
53
|
+
* caller can destroy them.
|
|
54
|
+
*/
|
|
55
|
+
clear(rootId: string): AreRootCacheEntry[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { AreRootCache, type AreRootCacheEntry };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var aConcept = require('@adaas/a-concept');
|
|
4
|
+
var core = require('@adaas/a-frame/core');
|
|
5
|
+
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
8
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
9
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
10
|
+
if (decorator = decorators[i])
|
|
11
|
+
result = (decorator(result)) || result;
|
|
12
|
+
return result;
|
|
13
|
+
};
|
|
14
|
+
exports.AreRootCache = class AreRootCache extends aConcept.A_Fragment {
|
|
15
|
+
constructor(limit = 10) {
|
|
16
|
+
super({ name: "AreRootCache" });
|
|
17
|
+
/**
|
|
18
|
+
* rootId -> (component tag -> cache entry). The inner Map preserves
|
|
19
|
+
* insertion order which is used as the LRU recency order: the first key is
|
|
20
|
+
* the least-recently-used entry, the last key the most-recently-used.
|
|
21
|
+
*/
|
|
22
|
+
this._cache = /* @__PURE__ */ new Map();
|
|
23
|
+
this._limit = Math.max(0, Math.floor(limit));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Maximum number of cached subtrees kept per root.
|
|
27
|
+
*/
|
|
28
|
+
get limit() {
|
|
29
|
+
return this._limit;
|
|
30
|
+
}
|
|
31
|
+
bucket(rootId) {
|
|
32
|
+
let bucket = this._cache.get(rootId);
|
|
33
|
+
if (!bucket) {
|
|
34
|
+
bucket = /* @__PURE__ */ new Map();
|
|
35
|
+
this._cache.set(rootId, bucket);
|
|
36
|
+
}
|
|
37
|
+
return bucket;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Whether a subtree for the given component tag is currently cached.
|
|
41
|
+
*/
|
|
42
|
+
has(rootId, tag) {
|
|
43
|
+
return this.bucket(rootId).has(tag);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Retrieve AND remove a cached subtree so it can become live again. Returns
|
|
47
|
+
* `undefined` on a cache miss.
|
|
48
|
+
*/
|
|
49
|
+
take(rootId, tag) {
|
|
50
|
+
const bucket = this.bucket(rootId);
|
|
51
|
+
const entry = bucket.get(tag);
|
|
52
|
+
if (entry) {
|
|
53
|
+
bucket.delete(tag);
|
|
54
|
+
}
|
|
55
|
+
return entry;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Stash a detached subtree under the given component tag. Returns any entries
|
|
59
|
+
* that were evicted to honour the LRU limit (or replaced for the same tag) so
|
|
60
|
+
* the caller can `destroy()` them.
|
|
61
|
+
*/
|
|
62
|
+
put(rootId, tag, entry) {
|
|
63
|
+
const bucket = this.bucket(rootId);
|
|
64
|
+
const evicted = [];
|
|
65
|
+
const existing = bucket.get(tag);
|
|
66
|
+
if (existing) {
|
|
67
|
+
bucket.delete(tag);
|
|
68
|
+
if (existing.node !== entry.node) {
|
|
69
|
+
evicted.push(existing);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
bucket.set(tag, entry);
|
|
73
|
+
while (bucket.size > this._limit) {
|
|
74
|
+
const oldestKey = bucket.keys().next().value;
|
|
75
|
+
if (oldestKey === void 0) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
const oldest = bucket.get(oldestKey);
|
|
79
|
+
bucket.delete(oldestKey);
|
|
80
|
+
evicted.push(oldest);
|
|
81
|
+
}
|
|
82
|
+
return evicted;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Remove and return every cached entry for a root (e.g. on teardown) so the
|
|
86
|
+
* caller can destroy them.
|
|
87
|
+
*/
|
|
88
|
+
clear(rootId) {
|
|
89
|
+
const bucket = this._cache.get(rootId);
|
|
90
|
+
if (!bucket) {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
const entries = [...bucket.values()];
|
|
94
|
+
bucket.clear();
|
|
95
|
+
this._cache.delete(rootId);
|
|
96
|
+
return entries;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
exports.AreRootCache = __decorateClass([
|
|
100
|
+
core.A_Frame.Define({
|
|
101
|
+
namespace: "a-are-html",
|
|
102
|
+
description: "AreRootCache is a fragment that keeps a small per-root LRU of previously rendered are-root subtrees. When an are-root swaps the component it displays, the outgoing subtree is stashed here (unmounted + detached, but not destroyed) so that routing back to it can re-inject the preserved scene instantly instead of rebuilding from scratch."
|
|
103
|
+
})
|
|
104
|
+
], exports.AreRootCache);
|
|
105
|
+
//# sourceMappingURL=AreRootCache.context.js.map
|
|
106
|
+
//# sourceMappingURL=AreRootCache.context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/AreRoot/AreRootCache.context.ts"],"names":["AreRootCache","A_Fragment","A_Frame"],"mappings":";;;;;;;;;;;;;AAyBaA,oBAAA,GAAN,2BAA2BC,mBAAA,CAAW;AAAA,EAezC,WAAA,CAAY,QAAgB,EAAA,EAAI;AAC5B,IAAA,KAAA,CAAM,EAAE,IAAA,EAAM,cAAA,EAAgB,CAAA;AATlC;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAU,MAAA,uBAA0D,GAAA,EAAI;AAUpE,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAA,GAAgB;AAChB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EAChB;AAAA,EAEU,OAAO,MAAA,EAAgD;AAC7D,IAAA,IAAI,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA;AACnC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACT,MAAA,MAAA,uBAAa,GAAA,EAAI;AACjB,MAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAA;AAAA,IAClC;AACA,IAAA,OAAO,MAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAAI,QAAgB,GAAA,EAAsB;AACtC,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAE,IAAI,GAAG,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAA,CAAK,QAAgB,GAAA,EAA4C;AAC7D,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AACjC,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AAC5B,IAAA,IAAI,KAAA,EAAO;AACP,MAAA,MAAA,CAAO,OAAO,GAAG,CAAA;AAAA,IACrB;AACA,IAAA,OAAO,KAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,GAAA,CAAI,MAAA,EAAgB,GAAA,EAAa,KAAA,EAA+C;AAC5E,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AACjC,IAAA,MAAM,UAA+B,EAAC;AAKtC,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AAC/B,IAAA,IAAI,QAAA,EAAU;AACV,MAAA,MAAA,CAAO,OAAO,GAAG,CAAA;AACjB,MAAA,IAAI,QAAA,CAAS,IAAA,KAAS,KAAA,CAAM,IAAA,EAAM;AAC9B,QAAA,OAAA,CAAQ,KAAK,QAAQ,CAAA;AAAA,MACzB;AAAA,IACJ;AAIA,IAAA,MAAA,CAAO,GAAA,CAAI,KAAK,KAAK,CAAA;AAErB,IAAA,OAAO,MAAA,CAAO,IAAA,GAAO,IAAA,CAAK,MAAA,EAAQ;AAC9B,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AACvC,MAAA,IAAI,cAAc,MAAA,EAAW;AACzB,QAAA;AAAA,MACJ;AACA,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,GAAA,CAAI,SAAS,CAAA;AACnC,MAAA,MAAA,CAAO,OAAO,SAAS,CAAA;AACvB,MAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA,IACvB;AAEA,IAAA,OAAO,OAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,EAAqC;AACvC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA;AACrC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACT,MAAA,OAAO,EAAC;AAAA,IACZ;AACA,IAAA,MAAM,OAAA,GAAU,CAAC,GAAG,MAAA,CAAO,QAAQ,CAAA;AACnC,IAAA,MAAA,CAAO,KAAA,EAAM;AACb,IAAA,IAAA,CAAK,MAAA,CAAO,OAAO,MAAM,CAAA;AACzB,IAAA,OAAO,OAAA;AAAA,EACX;AACJ;AA3GaD,oBAAA,GAAN,eAAA,CAAA;AAAA,EAJNE,aAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACYF,oBAAA,CAAA","file":"AreRootCache.context.js","sourcesContent":["import { A_Fragment } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\nimport { AreNode } from \"@adaas/are\";\n\n\n/**\n * A single cached, detached component subtree for an are-root outlet.\n *\n * `node` is fully compiled and its scene plan is intact (it was `unmount()`ed,\n * not destroyed), so it can be re-mounted instantly without re-tokenizing,\n * re-loading, transforming or compiling. `subscribers` records the exact set of\n * nodes inside the subtree that were subscribed to the signal bus at the moment\n * of stashing — they are unsubscribed while cached (so the detached DOM never\n * reacts to signals) and re-subscribed verbatim on restore.\n */\nexport type AreRootCacheEntry = {\n node: AreNode;\n subscribers: AreNode[];\n};\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'AreRootCache is a fragment that keeps a small per-root LRU of previously rendered are-root subtrees. When an are-root swaps the component it displays, the outgoing subtree is stashed here (unmounted + detached, but not destroyed) so that routing back to it can re-inject the preserved scene instantly instead of rebuilding from scratch.'\n})\nexport class AreRootCache extends A_Fragment {\n\n /**\n * rootId -> (component tag -> cache entry). The inner Map preserves\n * insertion order which is used as the LRU recency order: the first key is\n * the least-recently-used entry, the last key the most-recently-used.\n */\n protected _cache: Map<string, Map<string, AreRootCacheEntry>> = new Map();\n\n /**\n * Maximum number of cached subtrees kept per root. Older entries beyond this\n * limit are evicted (and returned to the caller so it can destroy them).\n */\n protected _limit: number;\n\n constructor(limit: number = 10) {\n super({ name: 'AreRootCache' });\n this._limit = Math.max(0, Math.floor(limit));\n }\n\n /**\n * Maximum number of cached subtrees kept per root.\n */\n get limit(): number {\n return this._limit;\n }\n\n protected bucket(rootId: string): Map<string, AreRootCacheEntry> {\n let bucket = this._cache.get(rootId);\n if (!bucket) {\n bucket = new Map();\n this._cache.set(rootId, bucket);\n }\n return bucket;\n }\n\n /**\n * Whether a subtree for the given component tag is currently cached.\n */\n has(rootId: string, tag: string): boolean {\n return this.bucket(rootId).has(tag);\n }\n\n /**\n * Retrieve AND remove a cached subtree so it can become live again. Returns\n * `undefined` on a cache miss.\n */\n take(rootId: string, tag: string): AreRootCacheEntry | undefined {\n const bucket = this.bucket(rootId);\n const entry = bucket.get(tag);\n if (entry) {\n bucket.delete(tag);\n }\n return entry;\n }\n\n /**\n * Stash a detached subtree under the given component tag. Returns any entries\n * that were evicted to honour the LRU limit (or replaced for the same tag) so\n * the caller can `destroy()` them.\n */\n put(rootId: string, tag: string, entry: AreRootCacheEntry): AreRootCacheEntry[] {\n const bucket = this.bucket(rootId);\n const evicted: AreRootCacheEntry[] = [];\n\n // Replace any stale entry for the same tag (should not normally happen,\n // since a displayed tag is never simultaneously cached) and surface it\n // for destruction so it does not leak.\n const existing = bucket.get(tag);\n if (existing) {\n bucket.delete(tag);\n if (existing.node !== entry.node) {\n evicted.push(existing);\n }\n }\n\n // A limit of 0 disables caching: the freshly added entry is evicted\n // immediately so the caller tears it down.\n bucket.set(tag, entry);\n\n while (bucket.size > this._limit) {\n const oldestKey = bucket.keys().next().value as string | undefined;\n if (oldestKey === undefined) {\n break;\n }\n const oldest = bucket.get(oldestKey)!;\n bucket.delete(oldestKey);\n evicted.push(oldest);\n }\n\n return evicted;\n }\n\n /**\n * Remove and return every cached entry for a root (e.g. on teardown) so the\n * caller can destroy them.\n */\n clear(rootId: string): AreRootCacheEntry[] {\n const bucket = this._cache.get(rootId);\n if (!bucket) {\n return [];\n }\n const entries = [...bucket.values()];\n bucket.clear();\n this._cache.delete(rootId);\n return entries;\n }\n}\n"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { __decorateClass } from '../../chunk-EQQGB2QZ.mjs';
|
|
2
|
+
import { A_Fragment } from '@adaas/a-concept';
|
|
3
|
+
import { A_Frame } from '@adaas/a-frame/core';
|
|
4
|
+
|
|
5
|
+
let AreRootCache = class extends A_Fragment {
|
|
6
|
+
constructor(limit = 10) {
|
|
7
|
+
super({ name: "AreRootCache" });
|
|
8
|
+
/**
|
|
9
|
+
* rootId -> (component tag -> cache entry). The inner Map preserves
|
|
10
|
+
* insertion order which is used as the LRU recency order: the first key is
|
|
11
|
+
* the least-recently-used entry, the last key the most-recently-used.
|
|
12
|
+
*/
|
|
13
|
+
this._cache = /* @__PURE__ */ new Map();
|
|
14
|
+
this._limit = Math.max(0, Math.floor(limit));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Maximum number of cached subtrees kept per root.
|
|
18
|
+
*/
|
|
19
|
+
get limit() {
|
|
20
|
+
return this._limit;
|
|
21
|
+
}
|
|
22
|
+
bucket(rootId) {
|
|
23
|
+
let bucket = this._cache.get(rootId);
|
|
24
|
+
if (!bucket) {
|
|
25
|
+
bucket = /* @__PURE__ */ new Map();
|
|
26
|
+
this._cache.set(rootId, bucket);
|
|
27
|
+
}
|
|
28
|
+
return bucket;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Whether a subtree for the given component tag is currently cached.
|
|
32
|
+
*/
|
|
33
|
+
has(rootId, tag) {
|
|
34
|
+
return this.bucket(rootId).has(tag);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Retrieve AND remove a cached subtree so it can become live again. Returns
|
|
38
|
+
* `undefined` on a cache miss.
|
|
39
|
+
*/
|
|
40
|
+
take(rootId, tag) {
|
|
41
|
+
const bucket = this.bucket(rootId);
|
|
42
|
+
const entry = bucket.get(tag);
|
|
43
|
+
if (entry) {
|
|
44
|
+
bucket.delete(tag);
|
|
45
|
+
}
|
|
46
|
+
return entry;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Stash a detached subtree under the given component tag. Returns any entries
|
|
50
|
+
* that were evicted to honour the LRU limit (or replaced for the same tag) so
|
|
51
|
+
* the caller can `destroy()` them.
|
|
52
|
+
*/
|
|
53
|
+
put(rootId, tag, entry) {
|
|
54
|
+
const bucket = this.bucket(rootId);
|
|
55
|
+
const evicted = [];
|
|
56
|
+
const existing = bucket.get(tag);
|
|
57
|
+
if (existing) {
|
|
58
|
+
bucket.delete(tag);
|
|
59
|
+
if (existing.node !== entry.node) {
|
|
60
|
+
evicted.push(existing);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
bucket.set(tag, entry);
|
|
64
|
+
while (bucket.size > this._limit) {
|
|
65
|
+
const oldestKey = bucket.keys().next().value;
|
|
66
|
+
if (oldestKey === void 0) {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
const oldest = bucket.get(oldestKey);
|
|
70
|
+
bucket.delete(oldestKey);
|
|
71
|
+
evicted.push(oldest);
|
|
72
|
+
}
|
|
73
|
+
return evicted;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Remove and return every cached entry for a root (e.g. on teardown) so the
|
|
77
|
+
* caller can destroy them.
|
|
78
|
+
*/
|
|
79
|
+
clear(rootId) {
|
|
80
|
+
const bucket = this._cache.get(rootId);
|
|
81
|
+
if (!bucket) {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
const entries = [...bucket.values()];
|
|
85
|
+
bucket.clear();
|
|
86
|
+
this._cache.delete(rootId);
|
|
87
|
+
return entries;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
AreRootCache = __decorateClass([
|
|
91
|
+
A_Frame.Define({
|
|
92
|
+
namespace: "a-are-html",
|
|
93
|
+
description: "AreRootCache is a fragment that keeps a small per-root LRU of previously rendered are-root subtrees. When an are-root swaps the component it displays, the outgoing subtree is stashed here (unmounted + detached, but not destroyed) so that routing back to it can re-inject the preserved scene instantly instead of rebuilding from scratch."
|
|
94
|
+
})
|
|
95
|
+
], AreRootCache);
|
|
96
|
+
|
|
97
|
+
export { AreRootCache };
|
|
98
|
+
//# sourceMappingURL=AreRootCache.context.mjs.map
|
|
99
|
+
//# sourceMappingURL=AreRootCache.context.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/AreRoot/AreRootCache.context.ts"],"names":[],"mappings":";;;;AAyBO,IAAM,YAAA,GAAN,cAA2B,UAAA,CAAW;AAAA,EAezC,WAAA,CAAY,QAAgB,EAAA,EAAI;AAC5B,IAAA,KAAA,CAAM,EAAE,IAAA,EAAM,cAAA,EAAgB,CAAA;AATlC;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,IAAA,CAAU,MAAA,uBAA0D,GAAA,EAAI;AAUpE,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAA,GAAgB;AAChB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EAChB;AAAA,EAEU,OAAO,MAAA,EAAgD;AAC7D,IAAA,IAAI,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA;AACnC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACT,MAAA,MAAA,uBAAa,GAAA,EAAI;AACjB,MAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAA;AAAA,IAClC;AACA,IAAA,OAAO,MAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAAI,QAAgB,GAAA,EAAsB;AACtC,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA,CAAE,IAAI,GAAG,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAA,CAAK,QAAgB,GAAA,EAA4C;AAC7D,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AACjC,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AAC5B,IAAA,IAAI,KAAA,EAAO;AACP,MAAA,MAAA,CAAO,OAAO,GAAG,CAAA;AAAA,IACrB;AACA,IAAA,OAAO,KAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,GAAA,CAAI,MAAA,EAAgB,GAAA,EAAa,KAAA,EAA+C;AAC5E,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AACjC,IAAA,MAAM,UAA+B,EAAC;AAKtC,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AAC/B,IAAA,IAAI,QAAA,EAAU;AACV,MAAA,MAAA,CAAO,OAAO,GAAG,CAAA;AACjB,MAAA,IAAI,QAAA,CAAS,IAAA,KAAS,KAAA,CAAM,IAAA,EAAM;AAC9B,QAAA,OAAA,CAAQ,KAAK,QAAQ,CAAA;AAAA,MACzB;AAAA,IACJ;AAIA,IAAA,MAAA,CAAO,GAAA,CAAI,KAAK,KAAK,CAAA;AAErB,IAAA,OAAO,MAAA,CAAO,IAAA,GAAO,IAAA,CAAK,MAAA,EAAQ;AAC9B,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AACvC,MAAA,IAAI,cAAc,MAAA,EAAW;AACzB,QAAA;AAAA,MACJ;AACA,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,GAAA,CAAI,SAAS,CAAA;AACnC,MAAA,MAAA,CAAO,OAAO,SAAS,CAAA;AACvB,MAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA,IACvB;AAEA,IAAA,OAAO,OAAA;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAA,EAAqC;AACvC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA;AACrC,IAAA,IAAI,CAAC,MAAA,EAAQ;AACT,MAAA,OAAO,EAAC;AAAA,IACZ;AACA,IAAA,MAAM,OAAA,GAAU,CAAC,GAAG,MAAA,CAAO,QAAQ,CAAA;AACnC,IAAA,MAAA,CAAO,KAAA,EAAM;AACb,IAAA,IAAA,CAAK,MAAA,CAAO,OAAO,MAAM,CAAA;AACzB,IAAA,OAAO,OAAA;AAAA,EACX;AACJ;AA3Ga,YAAA,GAAN,eAAA,CAAA;AAAA,EAJN,QAAQ,MAAA,CAAO;AAAA,IACZ,SAAA,EAAW,YAAA;AAAA,IACX,WAAA,EAAa;AAAA,GAChB;AAAA,CAAA,EACY,YAAA,CAAA","file":"AreRootCache.context.mjs","sourcesContent":["import { A_Fragment } from \"@adaas/a-concept\";\nimport { A_Frame } from \"@adaas/a-frame/core\";\nimport { AreNode } from \"@adaas/are\";\n\n\n/**\n * A single cached, detached component subtree for an are-root outlet.\n *\n * `node` is fully compiled and its scene plan is intact (it was `unmount()`ed,\n * not destroyed), so it can be re-mounted instantly without re-tokenizing,\n * re-loading, transforming or compiling. `subscribers` records the exact set of\n * nodes inside the subtree that were subscribed to the signal bus at the moment\n * of stashing — they are unsubscribed while cached (so the detached DOM never\n * reacts to signals) and re-subscribed verbatim on restore.\n */\nexport type AreRootCacheEntry = {\n node: AreNode;\n subscribers: AreNode[];\n};\n\n\n@A_Frame.Define({\n namespace: 'a-are-html',\n description: 'AreRootCache is a fragment that keeps a small per-root LRU of previously rendered are-root subtrees. When an are-root swaps the component it displays, the outgoing subtree is stashed here (unmounted + detached, but not destroyed) so that routing back to it can re-inject the preserved scene instantly instead of rebuilding from scratch.'\n})\nexport class AreRootCache extends A_Fragment {\n\n /**\n * rootId -> (component tag -> cache entry). The inner Map preserves\n * insertion order which is used as the LRU recency order: the first key is\n * the least-recently-used entry, the last key the most-recently-used.\n */\n protected _cache: Map<string, Map<string, AreRootCacheEntry>> = new Map();\n\n /**\n * Maximum number of cached subtrees kept per root. Older entries beyond this\n * limit are evicted (and returned to the caller so it can destroy them).\n */\n protected _limit: number;\n\n constructor(limit: number = 10) {\n super({ name: 'AreRootCache' });\n this._limit = Math.max(0, Math.floor(limit));\n }\n\n /**\n * Maximum number of cached subtrees kept per root.\n */\n get limit(): number {\n return this._limit;\n }\n\n protected bucket(rootId: string): Map<string, AreRootCacheEntry> {\n let bucket = this._cache.get(rootId);\n if (!bucket) {\n bucket = new Map();\n this._cache.set(rootId, bucket);\n }\n return bucket;\n }\n\n /**\n * Whether a subtree for the given component tag is currently cached.\n */\n has(rootId: string, tag: string): boolean {\n return this.bucket(rootId).has(tag);\n }\n\n /**\n * Retrieve AND remove a cached subtree so it can become live again. Returns\n * `undefined` on a cache miss.\n */\n take(rootId: string, tag: string): AreRootCacheEntry | undefined {\n const bucket = this.bucket(rootId);\n const entry = bucket.get(tag);\n if (entry) {\n bucket.delete(tag);\n }\n return entry;\n }\n\n /**\n * Stash a detached subtree under the given component tag. Returns any entries\n * that were evicted to honour the LRU limit (or replaced for the same tag) so\n * the caller can `destroy()` them.\n */\n put(rootId: string, tag: string, entry: AreRootCacheEntry): AreRootCacheEntry[] {\n const bucket = this.bucket(rootId);\n const evicted: AreRootCacheEntry[] = [];\n\n // Replace any stale entry for the same tag (should not normally happen,\n // since a displayed tag is never simultaneously cached) and surface it\n // for destruction so it does not leak.\n const existing = bucket.get(tag);\n if (existing) {\n bucket.delete(tag);\n if (existing.node !== entry.node) {\n evicted.push(existing);\n }\n }\n\n // A limit of 0 disables caching: the freshly added entry is evicted\n // immediately so the caller tears it down.\n bucket.set(tag, entry);\n\n while (bucket.size > this._limit) {\n const oldestKey = bucket.keys().next().value as string | undefined;\n if (oldestKey === undefined) {\n break;\n }\n const oldest = bucket.get(oldestKey)!;\n bucket.delete(oldestKey);\n evicted.push(oldest);\n }\n\n return evicted;\n }\n\n /**\n * Remove and return every cached entry for a root (e.g. on teardown) so the\n * caller can destroy them.\n */\n clear(rootId: string): AreRootCacheEntry[] {\n const bucket = this._cache.get(rootId);\n if (!bucket) {\n return [];\n }\n const entries = [...bucket.values()];\n bucket.clear();\n this._cache.delete(rootId);\n return entries;\n }\n}\n"]}
|