@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.
Files changed (74) hide show
  1. package/dist/browser/index.d.mts +161 -5
  2. package/dist/browser/index.mjs +357 -55
  3. package/dist/browser/index.mjs.map +1 -1
  4. package/dist/node/directives/AreDirectiveFor.directive.d.mts +7 -0
  5. package/dist/node/directives/AreDirectiveFor.directive.d.ts +7 -0
  6. package/dist/node/directives/AreDirectiveFor.directive.js +17 -2
  7. package/dist/node/directives/AreDirectiveFor.directive.js.map +1 -1
  8. package/dist/node/directives/AreDirectiveFor.directive.mjs +17 -2
  9. package/dist/node/directives/AreDirectiveFor.directive.mjs.map +1 -1
  10. package/dist/node/directives/AreDirectiveShow.directive.d.mts +32 -0
  11. package/dist/node/directives/AreDirectiveShow.directive.d.ts +32 -0
  12. package/dist/node/directives/AreDirectiveShow.directive.js +81 -0
  13. package/dist/node/directives/AreDirectiveShow.directive.js.map +1 -0
  14. package/dist/node/directives/AreDirectiveShow.directive.mjs +71 -0
  15. package/dist/node/directives/AreDirectiveShow.directive.mjs.map +1 -0
  16. package/dist/node/engine/AreHTML.engine.d.mts +2 -1
  17. package/dist/node/engine/AreHTML.engine.d.ts +2 -1
  18. package/dist/node/engine/AreHTML.engine.js +8 -2
  19. package/dist/node/engine/AreHTML.engine.js.map +1 -1
  20. package/dist/node/engine/AreHTML.engine.mjs +8 -2
  21. package/dist/node/engine/AreHTML.engine.mjs.map +1 -1
  22. package/dist/node/engine/AreHTML.interpreter.d.mts +3 -0
  23. package/dist/node/engine/AreHTML.interpreter.d.ts +3 -0
  24. package/dist/node/engine/AreHTML.interpreter.js +29 -0
  25. package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
  26. package/dist/node/engine/AreHTML.interpreter.mjs +29 -0
  27. package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
  28. package/dist/node/index.d.mts +4 -1
  29. package/dist/node/index.d.ts +4 -1
  30. package/dist/node/index.js +21 -0
  31. package/dist/node/index.mjs +3 -0
  32. package/dist/node/instructions/AreHTML.instructions.constants.d.mts +1 -0
  33. package/dist/node/instructions/AreHTML.instructions.constants.d.ts +1 -0
  34. package/dist/node/instructions/AreHTML.instructions.constants.js +2 -1
  35. package/dist/node/instructions/AreHTML.instructions.constants.js.map +1 -1
  36. package/dist/node/instructions/AreHTML.instructions.constants.mjs +2 -1
  37. package/dist/node/instructions/AreHTML.instructions.constants.mjs.map +1 -1
  38. package/dist/node/instructions/AreHTML.instructions.types.d.mts +9 -1
  39. package/dist/node/instructions/AreHTML.instructions.types.d.ts +9 -1
  40. package/dist/node/instructions/HideElement.instruction.d.mts +13 -0
  41. package/dist/node/instructions/HideElement.instruction.d.ts +13 -0
  42. package/dist/node/instructions/HideElement.instruction.js +31 -0
  43. package/dist/node/instructions/HideElement.instruction.js.map +1 -0
  44. package/dist/node/instructions/HideElement.instruction.mjs +24 -0
  45. package/dist/node/instructions/HideElement.instruction.mjs.map +1 -0
  46. package/dist/node/lib/AreRoot/AreRoot.component.d.mts +57 -3
  47. package/dist/node/lib/AreRoot/AreRoot.component.d.ts +57 -3
  48. package/dist/node/lib/AreRoot/AreRoot.component.js +137 -48
  49. package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
  50. package/dist/node/lib/AreRoot/AreRoot.component.mjs +139 -50
  51. package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
  52. package/dist/node/lib/AreRoot/AreRootCache.context.d.mts +58 -0
  53. package/dist/node/lib/AreRoot/AreRootCache.context.d.ts +58 -0
  54. package/dist/node/lib/AreRoot/AreRootCache.context.js +106 -0
  55. package/dist/node/lib/AreRoot/AreRootCache.context.js.map +1 -0
  56. package/dist/node/lib/AreRoot/AreRootCache.context.mjs +99 -0
  57. package/dist/node/lib/AreRoot/AreRootCache.context.mjs.map +1 -0
  58. package/examples/jumpstart/dist/index.html +1 -1
  59. package/examples/jumpstart/dist/{mq1a0fv0-ccgtz6.js → mq7hqrxy-4kus50.js} +629 -433
  60. package/examples/signal-routing/dist/index.html +1 -1
  61. package/examples/signal-routing/dist/{mq1bzrik-4lec86.js → mq7k53th-qiwy4x.js} +903 -486
  62. package/examples/signal-routing/src/components/SettingsPage.component.ts +39 -0
  63. package/examples/signal-routing/src/concept.ts +2 -0
  64. package/package.json +3 -3
  65. package/src/directives/AreDirectiveFor.directive.ts +44 -2
  66. package/src/directives/AreDirectiveShow.directive.ts +127 -0
  67. package/src/engine/AreHTML.engine.ts +11 -1
  68. package/src/engine/AreHTML.interpreter.ts +50 -0
  69. package/src/index.ts +3 -0
  70. package/src/instructions/AreHTML.instructions.constants.ts +1 -0
  71. package/src/instructions/AreHTML.instructions.types.ts +9 -0
  72. package/src/instructions/HideElement.instruction.ts +29 -0
  73. package/src/lib/AreRoot/AreRoot.component.ts +201 -71
  74. 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":"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","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":"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","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"]}
@@ -98,7 +98,7 @@
98
98
  <list-component></list-component>
99
99
  </are-root>
100
100
 
101
- <script type="module" src="./mq1a0fv0-ccgtz6.js"></script>
101
+ <script type="module" src="./mq7hqrxy-4kus50.js"></script>
102
102
  </body>
103
103
 
104
104
  </html>