@repobit/dex-store-elements 1.4.1 → 1.4.3

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 (96) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +15 -4
  3. package/dist/src/actions/action.button.js +4 -11
  4. package/dist/src/actions/action.button.js.map +1 -1
  5. package/dist/src/actions/action.input.js +28 -22
  6. package/dist/src/actions/action.input.js.map +1 -1
  7. package/dist/src/actions/action.select.js +10 -8
  8. package/dist/src/actions/action.select.js.map +1 -1
  9. package/dist/src/actions/index.d.ts +1 -1
  10. package/dist/src/actions/index.js +45 -44
  11. package/dist/src/actions/index.js.map +1 -1
  12. package/dist/src/actions/utilty.d.ts +1 -0
  13. package/dist/src/actions/utilty.js +59 -29
  14. package/dist/src/actions/utilty.js.map +1 -1
  15. package/dist/src/contexts/context.datalayer.js.map +1 -1
  16. package/dist/src/contexts/context.derived.js.map +1 -1
  17. package/dist/src/contexts/context.option.js.map +1 -1
  18. package/dist/src/contexts/context.product.js.map +1 -1
  19. package/dist/src/contexts/context.state.js.map +1 -1
  20. package/dist/src/contexts/context.store.js.map +1 -1
  21. package/dist/src/controllers/collect-controller.d.ts +39 -0
  22. package/dist/src/controllers/collect-controller.js +161 -0
  23. package/dist/src/controllers/collect-controller.js.map +1 -0
  24. package/dist/src/controllers/compute-controller.d.ts +55 -0
  25. package/dist/src/controllers/compute-controller.js +350 -0
  26. package/dist/src/controllers/compute-controller.js.map +1 -0
  27. package/dist/src/controllers/eta-renderer/eta-dom-renderer.d.ts +21 -0
  28. package/dist/src/controllers/eta-renderer/eta-dom-renderer.js +152 -0
  29. package/dist/src/controllers/eta-renderer/eta-dom-renderer.js.map +1 -0
  30. package/dist/src/controllers/eta-renderer/eta-mutation-observer.d.ts +28 -0
  31. package/dist/src/controllers/eta-renderer/eta-mutation-observer.js +206 -0
  32. package/dist/src/controllers/eta-renderer/eta-mutation-observer.js.map +1 -0
  33. package/dist/src/controllers/eta-renderer/eta-renderer.d.ts +21 -0
  34. package/dist/src/controllers/eta-renderer/eta-renderer.js +77 -0
  35. package/dist/src/controllers/eta-renderer/eta-renderer.js.map +1 -0
  36. package/dist/src/controllers/eta-renderer/eta-template-cache.d.ts +21 -0
  37. package/dist/src/controllers/eta-renderer/eta-template-cache.js +52 -0
  38. package/dist/src/controllers/eta-renderer/eta-template-cache.js.map +1 -0
  39. package/dist/src/controllers/eta-renderer/eta-types.d.ts +11 -0
  40. package/dist/src/controllers/eta-renderer/eta-types.js +1 -0
  41. package/dist/src/controllers/eta-renderer/eta-types.js.map +1 -0
  42. package/dist/src/controllers/eta-renderer/index.d.ts +2 -0
  43. package/dist/src/controllers/eta-renderer/index.js +2 -0
  44. package/dist/src/controllers/eta-renderer/index.js.map +1 -0
  45. package/dist/src/controllers/event-pipeline-controller.d.ts +28 -0
  46. package/dist/src/controllers/event-pipeline-controller.js +72 -0
  47. package/dist/src/controllers/event-pipeline-controller.js.map +1 -0
  48. package/dist/src/dsl/compilers/array/compiler.js.map +1 -1
  49. package/dist/src/dsl/compilers/boolean/compiler.js.map +1 -1
  50. package/dist/src/dsl/compilers/enum/compiler.js.map +1 -1
  51. package/dist/src/dsl/compilers/index.js.map +1 -1
  52. package/dist/src/dsl/utilty.js.map +1 -1
  53. package/dist/src/events/events.js.map +1 -1
  54. package/dist/src/index.js.map +1 -1
  55. package/dist/src/nodes/node.context.js.map +1 -1
  56. package/dist/src/nodes/node.option.d.ts +4 -2
  57. package/dist/src/nodes/node.option.js +56 -56
  58. package/dist/src/nodes/node.option.js.map +1 -1
  59. package/dist/src/nodes/node.product.d.ts +4 -3
  60. package/dist/src/nodes/node.product.js +16 -28
  61. package/dist/src/nodes/node.product.js.map +1 -1
  62. package/dist/src/nodes/node.root.js.map +1 -1
  63. package/dist/src/nodes/node.state.d.ts +18 -70
  64. package/dist/src/nodes/node.state.js +42 -857
  65. package/dist/src/nodes/node.state.js.map +1 -1
  66. package/dist/src/renders/attributes/buyLink.js +12 -8
  67. package/dist/src/renders/attributes/buyLink.js.map +1 -1
  68. package/dist/src/renders/attributes/devices.js +10 -10
  69. package/dist/src/renders/attributes/devices.js.map +1 -1
  70. package/dist/src/renders/attributes/discount.js +60 -81
  71. package/dist/src/renders/attributes/discount.js.map +1 -1
  72. package/dist/src/renders/attributes/hide.js +21 -26
  73. package/dist/src/renders/attributes/hide.js.map +1 -1
  74. package/dist/src/renders/attributes/index.js.map +1 -1
  75. package/dist/src/renders/attributes/price.js +60 -81
  76. package/dist/src/renders/attributes/price.js.map +1 -1
  77. package/dist/src/renders/attributes/subscription.js +11 -11
  78. package/dist/src/renders/attributes/subscription.js.map +1 -1
  79. package/dist/src/renders/attributes/trialLink.js +5 -4
  80. package/dist/src/renders/attributes/trialLink.js.map +1 -1
  81. package/dist/src/renders/attributes/utilty.d.ts +2 -0
  82. package/dist/src/renders/attributes/utilty.js +3 -0
  83. package/dist/src/renders/attributes/utilty.js.map +1 -0
  84. package/dist/src/renders/context.js.map +1 -1
  85. package/dist/src/renders/format.js.map +1 -1
  86. package/dist/src/renders/index.d.ts +1 -1
  87. package/dist/src/renders/index.js +46 -45
  88. package/dist/src/renders/index.js.map +1 -1
  89. package/dist/src/renders/observe.js.map +1 -1
  90. package/dist/src/renders/utility.js +46 -38
  91. package/dist/src/renders/utility.js.map +1 -1
  92. package/dist/src/templating/eta.js.map +1 -1
  93. package/package.json +2 -2
  94. package/dist/src/contexts/context.event.d.ts +0 -5
  95. package/dist/src/contexts/context.event.js +0 -3
  96. package/dist/src/contexts/context.event.js.map +0 -1
@@ -0,0 +1,21 @@
1
+ import { EtaTemplateCache } from "../../controllers/eta-renderer/eta-template-cache.js";
2
+ import { EtaRenderHost, ObserveShadowRoot } from "../../controllers/eta-renderer/eta-types.js";
3
+ type RenderOptions = {
4
+ fromMutation: boolean;
5
+ dirtyRoots?: Set<HTMLElement> | null;
6
+ };
7
+ export declare class EtaDomRenderer {
8
+ private host;
9
+ private cache;
10
+ private observeShadowRoot?;
11
+ constructor(host: EtaRenderHost, cache: EtaTemplateCache, observeShadowRoot?: ObserveShadowRoot);
12
+ render(context: object, { fromMutation, dirtyRoots }: RenderOptions): Promise<void>;
13
+ private _visit;
14
+ private _waitForCustomUpdate;
15
+ private _safeEtaRender;
16
+ private _renderEtaAttributes;
17
+ private _hasRenderNodes;
18
+ private _hasNestedStateNode;
19
+ private _morphElementFromHTML;
20
+ }
21
+ export {};
@@ -0,0 +1,152 @@
1
+ import eta from "../../templating/eta.js";
2
+ import morph from "nanomorph";
3
+ export class EtaDomRenderer {
4
+ constructor(host, cache, observeShadowRoot) {
5
+ this.host = host;
6
+ this.cache = cache;
7
+ this.observeShadowRoot = observeShadowRoot;
8
+ }
9
+ async render(context, { fromMutation, dirtyRoots }) {
10
+ const roots = dirtyRoots && dirtyRoots.size ? Array.from(dirtyRoots) : [this.host];
11
+ const visitWithShadow = async (root) => {
12
+ await this._visit(root, context, fromMutation);
13
+ if (root.hasAttribute("shadow") && root.shadowRoot) {
14
+ await this._visit(root.shadowRoot, context, fromMutation);
15
+ }
16
+ };
17
+ for (const r of roots) {
18
+ if (!r)
19
+ continue;
20
+ await visitWithShadow(r);
21
+ }
22
+ }
23
+ async _visit(root, context, fromMutation) {
24
+ let processed = 0;
25
+ for (const child of Array.from(root.children)) {
26
+ if (!(child instanceof HTMLElement))
27
+ continue;
28
+ await this._waitForCustomUpdate(child);
29
+ const shadowRoot = child.hasAttribute("shadow") ? child.shadowRoot : null;
30
+ const traverseShadow = async () => {
31
+ if (shadowRoot) {
32
+ await this._visit(shadowRoot, context, fromMutation);
33
+ }
34
+ };
35
+ if (shadowRoot && this.observeShadowRoot) {
36
+ this.observeShadowRoot(shadowRoot, child);
37
+ }
38
+ const currentSrc = child.innerHTML ?? "";
39
+ await this._renderEtaAttributes(child, context, fromMutation);
40
+ if (this.host.isStateNodeElement(child) && child !== this.host) {
41
+ continue; // nested provider; let it handle its subtree
42
+ }
43
+ const hasNestedStateNode = this._hasNestedStateNode(child);
44
+ if (hasNestedStateNode) {
45
+ await this._visit(child, context, fromMutation);
46
+ await traverseShadow();
47
+ continue;
48
+ }
49
+ if (this._hasRenderNodes(child)) {
50
+ await this._visit(child, context, fromMutation);
51
+ await traverseShadow();
52
+ continue;
53
+ }
54
+ if (child.hasAttribute("data-store-render")) {
55
+ continue;
56
+ }
57
+ const hadTemplate = this.cache.hasTemplate(child);
58
+ const noAttrs = this.cache.hasNoEtaAttrs(child);
59
+ if (!currentSrc.includes("{{") && noAttrs && !hadTemplate && !hasNestedStateNode) {
60
+ await traverseShadow();
61
+ continue;
62
+ }
63
+ const entry = this.cache.updateElementEntry(child, currentSrc, { allowMutationRefresh: fromMutation });
64
+ if (!fromMutation) {
65
+ const out = this._safeEtaRender(entry, context, { onErrorReturnInput: true });
66
+ await this._morphElementFromHTML(child, out);
67
+ }
68
+ await traverseShadow();
69
+ if ((++processed % 50) === 0) {
70
+ await Promise.resolve();
71
+ }
72
+ }
73
+ }
74
+ async _waitForCustomUpdate(el) {
75
+ const maybe = el.updateComplete;
76
+ if (maybe && typeof maybe.then === "function") {
77
+ try {
78
+ await maybe;
79
+ }
80
+ catch { /* ignore */ }
81
+ }
82
+ }
83
+ _safeEtaRender(entry, data, { onErrorReturnInput = false } = {}) {
84
+ try {
85
+ if (!entry.fn) {
86
+ entry.fn = eta.compile(entry.src);
87
+ }
88
+ const out = eta.render(entry.fn, data);
89
+ return typeof out === "string" ? out : String(out ?? "");
90
+ }
91
+ catch (err) {
92
+ console.error("Eta render error:", err);
93
+ return onErrorReturnInput ? entry.src : "";
94
+ }
95
+ }
96
+ async _renderEtaAttributes(el, data, fromMutation) {
97
+ const names = el.getAttributeNames();
98
+ const cache = this.cache.getOrCreateAttrCache(el);
99
+ if (this.cache.hasNoEtaAttrs(el))
100
+ return;
101
+ let foundTemplateAttr = false;
102
+ for (const a of names) {
103
+ const raw = el.getAttribute(a);
104
+ if (!raw || !raw.includes("{{"))
105
+ continue;
106
+ foundTemplateAttr = true;
107
+ const key = `imp:${a}`;
108
+ let entry = cache.get(key);
109
+ if (!entry || entry.src !== raw) {
110
+ entry = { src: raw };
111
+ cache.set(key, entry);
112
+ }
113
+ if (!fromMutation) {
114
+ const rendered = this._safeEtaRender(entry, data, { onErrorReturnInput: true });
115
+ if (rendered !== raw) {
116
+ try {
117
+ el.setAttribute(a, rendered);
118
+ }
119
+ catch { /* ignore */ }
120
+ }
121
+ }
122
+ }
123
+ if (!foundTemplateAttr) {
124
+ this.cache.markNoEtaAttrs(el);
125
+ }
126
+ }
127
+ _hasRenderNodes(el) {
128
+ const h = el;
129
+ if (!h)
130
+ return false;
131
+ if (h.hasAttribute && h.hasAttribute("data-store-render"))
132
+ return true;
133
+ const html = h.innerHTML;
134
+ return typeof html === "string" && html.includes("data-store-render");
135
+ }
136
+ _hasNestedStateNode(el) {
137
+ return !!el.querySelector?.("bd-state,bd-product,bd-option,bd-context");
138
+ }
139
+ async _morphElementFromHTML(el, html) {
140
+ if (el.innerHTML === html)
141
+ return;
142
+ try {
143
+ const wrapper = el.cloneNode(false);
144
+ wrapper.innerHTML = html;
145
+ morph(el, wrapper);
146
+ }
147
+ catch {
148
+ el.innerHTML = html;
149
+ }
150
+ }
151
+ }
152
+ //# sourceMappingURL=eta-dom-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eta-dom-renderer.js","sourceRoot":"","sources":["../../../../src/controllers/eta-renderer/eta-dom-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { EtaTemplateCache } from \"@/controllers/eta-renderer/eta-template-cache\";\nimport { EtaRenderHost, ObserveShadowRoot } from \"@/controllers/eta-renderer/eta-types\";\nimport eta from \"@/templating/eta\";\nimport morph from \"nanomorph\";\n\ntype RenderOptions = {\n fromMutation: boolean;\n dirtyRoots? : Set<HTMLElement> | null;\n};\n\ntype TemplateEntry = { src: string; fn?: ReturnType<typeof eta.compile> };\n\nexport class EtaDomRenderer {\n private host : EtaRenderHost;\n private cache : EtaTemplateCache;\n private observeShadowRoot?: ObserveShadowRoot;\n\n constructor(host: EtaRenderHost, cache: EtaTemplateCache, observeShadowRoot?: ObserveShadowRoot) {\n this.host = host;\n this.cache = cache;\n this.observeShadowRoot = observeShadowRoot;\n }\n\n async render(context: object, { fromMutation, dirtyRoots }: RenderOptions) {\n const roots = dirtyRoots && dirtyRoots.size ? Array.from(dirtyRoots) : [this.host as unknown as HTMLElement];\n\n const visitWithShadow = async (root: Element) => {\n await this._visit(root, context, fromMutation);\n if (root.hasAttribute(\"shadow\") && (root as HTMLElement).shadowRoot) {\n await this._visit((root as HTMLElement).shadowRoot as ShadowRoot, context, fromMutation);\n }\n };\n\n for (const r of roots) {\n if (!r) continue;\n await visitWithShadow(r);\n }\n }\n\n private async _visit(root: Element | ShadowRoot, context: object, fromMutation: boolean) {\n let processed = 0;\n for (const child of Array.from(root.children)) {\n if (!(child instanceof HTMLElement)) continue;\n\n await this._waitForCustomUpdate(child);\n\n const shadowRoot = child.hasAttribute(\"shadow\") ? child.shadowRoot : null;\n const traverseShadow = async () => {\n if (shadowRoot) {\n await this._visit(shadowRoot, context, fromMutation);\n }\n };\n if (shadowRoot && this.observeShadowRoot) {\n this.observeShadowRoot(shadowRoot, child);\n }\n\n const currentSrc = child.innerHTML ?? \"\";\n\n await this._renderEtaAttributes(child, context, fromMutation);\n\n if (this.host.isStateNodeElement(child) && child !== this.host) {\n continue; // nested provider; let it handle its subtree\n }\n\n const hasNestedStateNode = this._hasNestedStateNode(child);\n if (hasNestedStateNode) {\n await this._visit(child, context, fromMutation);\n await traverseShadow();\n continue;\n }\n\n if (this._hasRenderNodes(child)) {\n await this._visit(child, context, fromMutation);\n await traverseShadow();\n continue;\n }\n\n if (child.hasAttribute(\"data-store-render\")) {\n continue;\n }\n\n const hadTemplate = this.cache.hasTemplate(child);\n const noAttrs = this.cache.hasNoEtaAttrs(child);\n if (!currentSrc.includes(\"{{\") && noAttrs && !hadTemplate && !hasNestedStateNode) {\n await traverseShadow();\n continue;\n }\n\n const entry = this.cache.updateElementEntry(child, currentSrc, { allowMutationRefresh: fromMutation });\n\n if (!fromMutation) {\n const out = this._safeEtaRender(entry, context, { onErrorReturnInput: true });\n await this._morphElementFromHTML(child, out);\n }\n await traverseShadow();\n\n if ((++processed % 50) === 0) {\n await Promise.resolve();\n }\n }\n }\n\n private async _waitForCustomUpdate(el: HTMLElement) {\n const maybe = (el as unknown as { updateComplete?: Promise<unknown> }).updateComplete;\n if (maybe && typeof (maybe as Promise<unknown>).then === \"function\") {\n try {\n await maybe;\n } catch { /* ignore */ }\n }\n }\n\n private _safeEtaRender(entry: TemplateEntry, data: object, { onErrorReturnInput = false }: { onErrorReturnInput?: boolean } = {}) {\n try {\n if (!entry.fn) {\n entry.fn = eta.compile(entry.src);\n }\n const out = eta.render(entry.fn, data);\n return typeof out === \"string\" ? out : String(out ?? \"\");\n } catch (err) {\n console.error(\"Eta render error:\", err);\n return onErrorReturnInput ? entry.src : \"\";\n }\n }\n\n private async _renderEtaAttributes(el: HTMLElement, data: object, fromMutation: boolean) {\n const names = el.getAttributeNames();\n const cache = this.cache.getOrCreateAttrCache(el);\n\n if (this.cache.hasNoEtaAttrs(el)) return;\n\n let foundTemplateAttr = false;\n for (const a of names) {\n const raw = el.getAttribute(a);\n if (!raw || !raw.includes(\"{{\")) continue;\n foundTemplateAttr = true;\n const key = `imp:${a}`;\n let entry = cache.get(key);\n if (!entry || entry.src !== raw) {\n entry = { src: raw };\n cache.set(key, entry);\n }\n if (!fromMutation) {\n const rendered = this._safeEtaRender(entry, data, { onErrorReturnInput: true });\n if (rendered !== raw) {\n try { el.setAttribute(a, rendered); } catch { /* ignore */ }\n }\n }\n }\n\n if (!foundTemplateAttr) {\n this.cache.markNoEtaAttrs(el);\n }\n }\n\n private _hasRenderNodes(el: Element): boolean {\n const h = el as HTMLElement;\n if (!h) return false;\n if (h.hasAttribute && h.hasAttribute(\"data-store-render\")) return true;\n const html = h.innerHTML;\n return typeof html === \"string\" && html.includes(\"data-store-render\");\n }\n\n private _hasNestedStateNode(el: Element): boolean {\n return !!(el as Element).querySelector?.(\"bd-state,bd-product,bd-option,bd-context\");\n }\n\n private async _morphElementFromHTML(el: HTMLElement, html: string) {\n if (el.innerHTML === html) return;\n try {\n const wrapper = el.cloneNode(false) as HTMLElement;\n wrapper.innerHTML = html;\n morph(el, wrapper);\n } catch {\n el.innerHTML = html;\n }\n }\n}\n"]}
@@ -0,0 +1,28 @@
1
+ import { EtaTemplateCache } from "../../controllers/eta-renderer/eta-template-cache.js";
2
+ import { EtaRenderHost } from "../../controllers/eta-renderer/eta-types.js";
3
+ type ScheduleFn = () => void;
4
+ type Suspendable<T> = () => Promise<T> | T;
5
+ export declare class EtaMutationObserver {
6
+ private host;
7
+ private cache;
8
+ private schedule;
9
+ private slotMo?;
10
+ private shadowMos?;
11
+ private dirtyRoots;
12
+ private debounce?;
13
+ private coalesceDelay?;
14
+ private suspended;
15
+ private sawMutationWhileSuspended;
16
+ constructor(host: EtaRenderHost, cache: EtaTemplateCache, schedule: ScheduleFn);
17
+ connect(): void;
18
+ disconnect(): void;
19
+ isIdle(): boolean;
20
+ consumeDirtyRoots(): Set<HTMLElement> | undefined;
21
+ suspend<T>(fn: Suspendable<T>): Promise<T>;
22
+ ensureShadowRootObserved(sr: ShadowRoot, host?: HTMLElement): void;
23
+ private _schedule;
24
+ private _handleMutations;
25
+ private _cleanupShadowRoot;
26
+ private _findEligibleRoot;
27
+ }
28
+ export {};
@@ -0,0 +1,206 @@
1
+ export class EtaMutationObserver {
2
+ constructor(host, cache, schedule) {
3
+ this.dirtyRoots = new Set();
4
+ this.suspended = false;
5
+ this.sawMutationWhileSuspended = false;
6
+ this.host = host;
7
+ this.cache = cache;
8
+ this.schedule = schedule;
9
+ }
10
+ connect() {
11
+ if (!this.host.shouldObserveEtaMutations())
12
+ return;
13
+ if (this.slotMo)
14
+ return;
15
+ this.slotMo = new MutationObserver((muts) => this._handleMutations(muts));
16
+ this.slotMo.observe(this.host, {
17
+ childList: true,
18
+ subtree: true,
19
+ characterData: true,
20
+ attributes: true
21
+ });
22
+ this.host.querySelectorAll("[shadow]").forEach(host => {
23
+ if (host.shadowRoot)
24
+ this.ensureShadowRootObserved(host.shadowRoot, host);
25
+ });
26
+ }
27
+ disconnect() {
28
+ if (this.debounce) {
29
+ clearTimeout(this.debounce);
30
+ this.debounce = undefined;
31
+ }
32
+ this.slotMo?.disconnect();
33
+ this.slotMo = undefined;
34
+ if (this.shadowMos) {
35
+ for (const [sr, mo] of this.shadowMos.entries()) {
36
+ try {
37
+ mo.disconnect();
38
+ }
39
+ catch { /* ignore */ }
40
+ try {
41
+ this._cleanupShadowRoot(sr);
42
+ }
43
+ catch { /* ignore */ }
44
+ }
45
+ this.shadowMos.clear();
46
+ this.shadowMos = undefined;
47
+ }
48
+ }
49
+ isIdle() {
50
+ return !this.debounce;
51
+ }
52
+ consumeDirtyRoots() {
53
+ if (this.dirtyRoots.size === 0)
54
+ return undefined;
55
+ const roots = new Set(this.dirtyRoots);
56
+ this.dirtyRoots.clear();
57
+ return roots;
58
+ }
59
+ async suspend(fn) {
60
+ this.suspended = true;
61
+ try {
62
+ return await fn();
63
+ }
64
+ finally {
65
+ this.suspended = false;
66
+ if (this.sawMutationWhileSuspended) {
67
+ this.sawMutationWhileSuspended = false;
68
+ this._schedule();
69
+ }
70
+ }
71
+ }
72
+ ensureShadowRootObserved(sr, host) {
73
+ if (!this.host.shouldObserveEtaMutations())
74
+ return;
75
+ const rootHost = host ?? (sr.host instanceof HTMLElement ? sr.host : null);
76
+ if (rootHost) {
77
+ const eligible = this._findEligibleRoot(rootHost);
78
+ if (!eligible)
79
+ return;
80
+ }
81
+ if (!this.shadowMos)
82
+ this.shadowMos = new Map();
83
+ if (this.shadowMos.has(sr))
84
+ return;
85
+ const mo = new MutationObserver((muts) => this._handleMutations(muts));
86
+ mo.observe(sr, {
87
+ childList: true,
88
+ subtree: true,
89
+ characterData: true,
90
+ attributes: true
91
+ });
92
+ this.shadowMos.set(sr, mo);
93
+ sr.querySelectorAll("[shadow]").forEach(host => {
94
+ if (host.shadowRoot)
95
+ this.ensureShadowRootObserved(host.shadowRoot, host);
96
+ });
97
+ }
98
+ _schedule() {
99
+ if (!this.host.shouldObserveEtaMutations())
100
+ return;
101
+ const base = Math.max(0, Number(this.host.etaMutationDelay) || 0);
102
+ const max = Math.max(base, Number(this.host.etaMutationDelayMax) || 0);
103
+ let delay = base;
104
+ if (this.debounce) {
105
+ clearTimeout(this.debounce);
106
+ const prev = this.coalesceDelay ?? base;
107
+ delay = Math.min(prev > 0 ? prev * 2 : base, max);
108
+ }
109
+ this.coalesceDelay = delay;
110
+ this.debounce = window.setTimeout(() => {
111
+ this.debounce = undefined;
112
+ this.coalesceDelay = base;
113
+ this.schedule();
114
+ }, delay);
115
+ }
116
+ _handleMutations(muts) {
117
+ if (this.suspended) {
118
+ this.sawMutationWhileSuspended = true;
119
+ return;
120
+ }
121
+ for (const m of muts) {
122
+ if (m.type === "attributes") {
123
+ const attr = m.attributeName?.toLowerCase();
124
+ if (attr === "class" || attr === "style")
125
+ continue;
126
+ }
127
+ const targets = [];
128
+ if (m.type === "characterData" || m.type === "attributes") {
129
+ targets.push(m.target);
130
+ if (m.type === "attributes" && m.target instanceof HTMLElement) {
131
+ this.cache.clearNoEtaAttrs(m.target);
132
+ }
133
+ }
134
+ else {
135
+ targets.push(...Array.from(m.addedNodes));
136
+ for (const removed of Array.from(m.removedNodes)) {
137
+ if (!(removed instanceof HTMLElement))
138
+ continue;
139
+ if (removed.hasAttribute("shadow") && removed.shadowRoot) {
140
+ this._cleanupShadowRoot(removed.shadowRoot);
141
+ }
142
+ removed
143
+ .querySelectorAll("[shadow]")
144
+ .forEach(host => host.shadowRoot && this._cleanupShadowRoot(host.shadowRoot));
145
+ }
146
+ }
147
+ const eligibles = [];
148
+ for (const t of targets) {
149
+ if (t instanceof HTMLElement && t.hasAttribute("shadow") && t.shadowRoot) {
150
+ this.ensureShadowRootObserved(t.shadowRoot, t);
151
+ }
152
+ if (t instanceof HTMLElement) {
153
+ t.querySelectorAll("[shadow]").forEach(host => {
154
+ if (host.shadowRoot)
155
+ this.ensureShadowRootObserved(host.shadowRoot, host);
156
+ });
157
+ }
158
+ const root = this._findEligibleRoot(t);
159
+ if (root)
160
+ eligibles.push(root);
161
+ }
162
+ if (!eligibles.length)
163
+ continue;
164
+ eligibles.forEach(r => this.dirtyRoots.add(r));
165
+ this._schedule();
166
+ break;
167
+ }
168
+ }
169
+ _cleanupShadowRoot(sr) {
170
+ if (this.shadowMos && this.shadowMos.has(sr)) {
171
+ const mo = this.shadowMos.get(sr);
172
+ try {
173
+ mo?.disconnect();
174
+ }
175
+ catch { /* ignore */ }
176
+ this.shadowMos.delete(sr);
177
+ }
178
+ sr.querySelectorAll("[shadow]").forEach(host => {
179
+ if (host.shadowRoot)
180
+ this._cleanupShadowRoot(host.shadowRoot);
181
+ });
182
+ }
183
+ _findEligibleRoot(n) {
184
+ let cur = n;
185
+ while (cur && cur !== this.host) {
186
+ if (cur instanceof ShadowRoot) {
187
+ cur = cur.host;
188
+ continue;
189
+ }
190
+ if (!(cur instanceof HTMLElement)) {
191
+ cur = cur.parentNode;
192
+ continue;
193
+ }
194
+ if (this.host.isStateNodeElement(cur) && cur !== this.host)
195
+ return null;
196
+ if (cur.hasAttribute("data-store-render"))
197
+ return null;
198
+ const parentProvider = cur.parentElement?.closest("bd-state,bd-product,bd-option,bd-context");
199
+ if (parentProvider === this.host || cur.parentElement === this.host)
200
+ return cur;
201
+ cur = cur.parentNode;
202
+ }
203
+ return this.host;
204
+ }
205
+ }
206
+ //# sourceMappingURL=eta-mutation-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eta-mutation-observer.js","sourceRoot":"","sources":["../../../../src/controllers/eta-renderer/eta-mutation-observer.ts"],"names":[],"mappings":"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","sourcesContent":["import { EtaTemplateCache } from \"@/controllers/eta-renderer/eta-template-cache\";\nimport { EtaRenderHost } from \"@/controllers/eta-renderer/eta-types\";\n\ntype ScheduleFn = () => void;\n\ntype Suspendable<T> = () => Promise<T> | T;\n\nexport class EtaMutationObserver {\n private host : EtaRenderHost;\n private cache : EtaTemplateCache;\n private schedule: ScheduleFn;\n\n private slotMo? : MutationObserver;\n private shadowMos?: Map<ShadowRoot, MutationObserver>;\n private dirtyRoots = new Set<HTMLElement>();\n\n private debounce? : number;\n private coalesceDelay?: number;\n\n private suspended = false;\n private sawMutationWhileSuspended = false;\n\n constructor(host: EtaRenderHost, cache: EtaTemplateCache, schedule: ScheduleFn) {\n this.host = host;\n this.cache = cache;\n this.schedule = schedule;\n }\n\n connect() {\n if (!this.host.shouldObserveEtaMutations()) return;\n if (this.slotMo) return;\n this.slotMo = new MutationObserver((muts) => this._handleMutations(muts));\n this.slotMo.observe(this.host, {\n childList : true,\n subtree : true,\n characterData: true,\n attributes : true\n });\n this.host.querySelectorAll<HTMLElement>(\"[shadow]\").forEach(host => {\n if (host.shadowRoot) this.ensureShadowRootObserved(host.shadowRoot, host);\n });\n }\n\n disconnect() {\n if (this.debounce) {\n clearTimeout(this.debounce);\n this.debounce = undefined;\n }\n this.slotMo?.disconnect();\n this.slotMo = undefined;\n if (this.shadowMos) {\n for (const [sr, mo] of this.shadowMos.entries()) {\n try { mo.disconnect(); } catch { /* ignore */ }\n try { this._cleanupShadowRoot(sr); } catch { /* ignore */ }\n }\n this.shadowMos.clear();\n this.shadowMos = undefined;\n }\n }\n\n isIdle(): boolean {\n return !this.debounce;\n }\n\n consumeDirtyRoots(): Set<HTMLElement> | undefined {\n if (this.dirtyRoots.size === 0) return undefined;\n const roots = new Set(this.dirtyRoots);\n this.dirtyRoots.clear();\n return roots;\n }\n\n async suspend<T>(fn: Suspendable<T>): Promise<T> {\n this.suspended = true;\n try {\n return await fn();\n } finally {\n this.suspended = false;\n if (this.sawMutationWhileSuspended) {\n this.sawMutationWhileSuspended = false;\n this._schedule();\n }\n }\n }\n\n ensureShadowRootObserved(sr: ShadowRoot, host?: HTMLElement) {\n if (!this.host.shouldObserveEtaMutations()) return;\n const rootHost = host ?? (sr.host instanceof HTMLElement ? sr.host : null);\n if (rootHost) {\n const eligible = this._findEligibleRoot(rootHost);\n if (!eligible) return;\n }\n if (!this.shadowMos) this.shadowMos = new Map();\n if (this.shadowMos.has(sr)) return;\n const mo = new MutationObserver((muts) => this._handleMutations(muts));\n mo.observe(sr, {\n childList : true,\n subtree : true,\n characterData: true,\n attributes : true\n });\n this.shadowMos.set(sr, mo);\n sr.querySelectorAll<HTMLElement>(\"[shadow]\").forEach(host => {\n if (host.shadowRoot) this.ensureShadowRootObserved(host.shadowRoot, host);\n });\n }\n\n private _schedule() {\n if (!this.host.shouldObserveEtaMutations()) return;\n\n const base = Math.max(0, Number(this.host.etaMutationDelay) || 0);\n const max = Math.max(base, Number(this.host.etaMutationDelayMax) || 0);\n let delay = base;\n if (this.debounce) {\n clearTimeout(this.debounce);\n const prev = this.coalesceDelay ?? base;\n delay = Math.min(prev > 0 ? prev * 2 : base, max);\n }\n this.coalesceDelay = delay;\n this.debounce = window.setTimeout(() => {\n this.debounce = undefined;\n this.coalesceDelay = base;\n this.schedule();\n }, delay);\n }\n\n private _handleMutations(muts: MutationRecord[]) {\n if (this.suspended) {\n this.sawMutationWhileSuspended = true;\n return;\n }\n for (const m of muts) {\n if (m.type === \"attributes\") {\n const attr = m.attributeName?.toLowerCase();\n if (attr === \"class\" || attr === \"style\") continue;\n }\n\n const targets: Node[] = [];\n if (m.type === \"characterData\" || m.type === \"attributes\") {\n targets.push(m.target);\n if (m.type === \"attributes\" && m.target instanceof HTMLElement) {\n this.cache.clearNoEtaAttrs(m.target);\n }\n } else {\n targets.push(...Array.from(m.addedNodes));\n for (const removed of Array.from(m.removedNodes)) {\n if (!(removed instanceof HTMLElement)) continue;\n if (removed.hasAttribute(\"shadow\") && removed.shadowRoot) {\n this._cleanupShadowRoot(removed.shadowRoot);\n }\n removed\n .querySelectorAll<HTMLElement>(\"[shadow]\")\n .forEach(host => host.shadowRoot && this._cleanupShadowRoot(host.shadowRoot));\n }\n }\n\n const eligibles: HTMLElement[] = [];\n for (const t of targets) {\n if (t instanceof HTMLElement && t.hasAttribute(\"shadow\") && t.shadowRoot) {\n this.ensureShadowRootObserved(t.shadowRoot, t);\n }\n if (t instanceof HTMLElement) {\n t.querySelectorAll<HTMLElement>(\"[shadow]\").forEach(host => {\n if (host.shadowRoot) this.ensureShadowRootObserved(host.shadowRoot, host);\n });\n }\n const root = this._findEligibleRoot(t);\n if (root) eligibles.push(root);\n }\n if (!eligibles.length) continue;\n\n eligibles.forEach(r => this.dirtyRoots.add(r));\n this._schedule();\n break;\n }\n }\n\n private _cleanupShadowRoot(sr: ShadowRoot) {\n if (this.shadowMos && this.shadowMos.has(sr)) {\n const mo = this.shadowMos.get(sr);\n try { mo?.disconnect(); } catch { /* ignore */ }\n this.shadowMos.delete(sr);\n }\n sr.querySelectorAll<HTMLElement>(\"[shadow]\").forEach(host => {\n if (host.shadowRoot) this._cleanupShadowRoot(host.shadowRoot);\n });\n }\n\n private _findEligibleRoot(n: Node | null): HTMLElement | null {\n let cur: Node | null = n;\n while (cur && cur !== this.host) {\n if (cur instanceof ShadowRoot) {\n cur = cur.host;\n continue;\n }\n if (!(cur instanceof HTMLElement)) { cur = (cur as Node).parentNode; continue; }\n if (this.host.isStateNodeElement(cur) && cur !== this.host) return null;\n if (cur.hasAttribute(\"data-store-render\")) return null;\n const parentProvider = cur.parentElement?.closest(\"bd-state,bd-product,bd-option,bd-context\");\n if (parentProvider === this.host || cur.parentElement === this.host) return cur;\n cur = (cur as Node).parentNode;\n }\n return this.host as unknown as HTMLElement;\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import { EtaRenderHost } from "../../controllers/eta-renderer/eta-types.js";
2
+ import { ReactiveController } from "lit";
3
+ export type { EtaRenderHost } from "../../controllers/eta-renderer/eta-types.js";
4
+ export declare class EtaRenderController implements ReactiveController {
5
+ private host;
6
+ private _etaRenderTask;
7
+ private _cache;
8
+ private _observer;
9
+ private _renderer;
10
+ private _renderInProgress;
11
+ private _etaIdleWaiters;
12
+ private _mutationRequested;
13
+ constructor(host: EtaRenderHost);
14
+ get taskComplete(): Promise<unknown>;
15
+ waitForIdle(): Promise<void>;
16
+ hostConnected(): void;
17
+ hostDisconnected(): void;
18
+ private _scheduleMutationRender;
19
+ private _isEtaIdle;
20
+ private _notifyEtaIdle;
21
+ }
@@ -0,0 +1,77 @@
1
+ import { EtaDomRenderer } from "../../controllers/eta-renderer/eta-dom-renderer.js";
2
+ import { EtaMutationObserver } from "../../controllers/eta-renderer/eta-mutation-observer.js";
3
+ import { EtaTemplateCache } from "../../controllers/eta-renderer/eta-template-cache.js";
4
+ import { Task } from "@lit/task";
5
+ export class EtaRenderController {
6
+ constructor(host) {
7
+ this._cache = new EtaTemplateCache();
8
+ this._renderInProgress = false;
9
+ this._etaIdleWaiters = [];
10
+ this._mutationRequested = false;
11
+ this.host = host;
12
+ this._observer = new EtaMutationObserver(host, this._cache, () => this._scheduleMutationRender());
13
+ this._renderer = new EtaDomRenderer(host, this._cache, (sr, h) => this._observer.ensureShadowRootObserved(sr, h));
14
+ host.addController(this);
15
+ this._etaRenderTask = new Task(host, {
16
+ task: async () => {
17
+ try {
18
+ if (!this.host.shouldRunEtaStateRender())
19
+ return;
20
+ const fromMutation = this._mutationRequested;
21
+ const ctx = await this.host.buildEtaContext();
22
+ if (!ctx)
23
+ return;
24
+ if (fromMutation)
25
+ this._mutationRequested = false;
26
+ const dirtyRoots = fromMutation ? this._observer.consumeDirtyRoots() : undefined;
27
+ this._renderInProgress = true;
28
+ try {
29
+ await this._observer.suspend(async () => {
30
+ await this._renderer.render(ctx, { fromMutation, dirtyRoots });
31
+ });
32
+ }
33
+ finally {
34
+ this._renderInProgress = false;
35
+ }
36
+ }
37
+ finally {
38
+ this._notifyEtaIdle();
39
+ }
40
+ },
41
+ args: () => this.host.getEtaArgs()
42
+ });
43
+ }
44
+ get taskComplete() {
45
+ return this._etaRenderTask.taskComplete;
46
+ }
47
+ waitForIdle() {
48
+ if (this._isEtaIdle())
49
+ return Promise.resolve();
50
+ return new Promise((resolve) => {
51
+ this._etaIdleWaiters.push(resolve);
52
+ });
53
+ }
54
+ hostConnected() {
55
+ this._observer.connect();
56
+ }
57
+ hostDisconnected() {
58
+ this._observer.disconnect();
59
+ }
60
+ _scheduleMutationRender() {
61
+ this._mutationRequested = true;
62
+ this._etaRenderTask.run();
63
+ }
64
+ _isEtaIdle() {
65
+ return !this._renderInProgress && this._observer.isIdle();
66
+ }
67
+ _notifyEtaIdle() {
68
+ if (!this._isEtaIdle())
69
+ return;
70
+ if (this._etaIdleWaiters.length === 0)
71
+ return;
72
+ const waiters = this._etaIdleWaiters.splice(0);
73
+ for (const w of waiters)
74
+ w();
75
+ }
76
+ }
77
+ //# sourceMappingURL=eta-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eta-renderer.js","sourceRoot":"","sources":["../../../../src/controllers/eta-renderer/eta-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { EtaDomRenderer } from \"@/controllers/eta-renderer/eta-dom-renderer\";\nimport { EtaMutationObserver } from \"@/controllers/eta-renderer/eta-mutation-observer\";\nimport { EtaTemplateCache } from \"@/controllers/eta-renderer/eta-template-cache\";\nimport { EtaRenderHost } from \"@/controllers/eta-renderer/eta-types\";\nimport { Task } from \"@lit/task\";\nimport { ReactiveController } from \"lit\";\n\nexport type { EtaRenderHost } from \"@/controllers/eta-renderer/eta-types\";\n\nexport class EtaRenderController implements ReactiveController {\n private host : EtaRenderHost;\n private _etaRenderTask: Task<unknown[], unknown>;\n\n private _cache = new EtaTemplateCache();\n private _observer: EtaMutationObserver;\n private _renderer: EtaDomRenderer;\n\n private _renderInProgress = false;\n private _etaIdleWaiters: Array<() => void> = [];\n private _mutationRequested = false;\n\n constructor(host: EtaRenderHost) {\n this.host = host;\n\n this._observer = new EtaMutationObserver(host, this._cache, () => this._scheduleMutationRender());\n this._renderer = new EtaDomRenderer(host, this._cache, (sr, h) => this._observer.ensureShadowRootObserved(sr, h));\n\n host.addController(this);\n\n this._etaRenderTask = new Task(host, {\n task: async () => {\n try {\n if (!this.host.shouldRunEtaStateRender()) return;\n const fromMutation = this._mutationRequested;\n\n const ctx = await this.host.buildEtaContext();\n if (!ctx) return;\n\n if (fromMutation) this._mutationRequested = false;\n\n const dirtyRoots = fromMutation ? this._observer.consumeDirtyRoots() : undefined;\n\n this._renderInProgress = true;\n try {\n await this._observer.suspend(async () => {\n await this._renderer.render(ctx, { fromMutation, dirtyRoots });\n });\n } finally {\n this._renderInProgress = false;\n }\n } finally {\n this._notifyEtaIdle();\n }\n },\n args: () => this.host.getEtaArgs()\n });\n }\n\n get taskComplete() {\n return this._etaRenderTask.taskComplete;\n }\n\n waitForIdle(): Promise<void> {\n if (this._isEtaIdle()) return Promise.resolve();\n return new Promise<void>((resolve) => {\n this._etaIdleWaiters.push(resolve);\n });\n }\n\n hostConnected() {\n this._observer.connect();\n }\n\n hostDisconnected() {\n this._observer.disconnect();\n }\n\n private _scheduleMutationRender() {\n this._mutationRequested = true;\n this._etaRenderTask.run();\n }\n\n private _isEtaIdle(): boolean {\n return !this._renderInProgress && this._observer.isIdle();\n }\n\n private _notifyEtaIdle() {\n if (!this._isEtaIdle()) return;\n if (this._etaIdleWaiters.length === 0) return;\n const waiters = this._etaIdleWaiters.splice(0);\n for (const w of waiters) w();\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import eta from "../../templating/eta.js";
2
+ type TemplateEntry = {
3
+ src: string;
4
+ fn?: ReturnType<typeof eta.compile>;
5
+ };
6
+ type UpdateOptions = {
7
+ allowMutationRefresh: boolean;
8
+ };
9
+ export declare class EtaTemplateCache {
10
+ private _elementTemplates;
11
+ private _attrTemplates;
12
+ private _noEtaAttrs?;
13
+ getElementEntry(el: HTMLElement): TemplateEntry | undefined;
14
+ hasTemplate(el: HTMLElement): boolean;
15
+ getOrCreateAttrCache(el: HTMLElement): Map<string, TemplateEntry>;
16
+ hasNoEtaAttrs(el: HTMLElement): boolean;
17
+ markNoEtaAttrs(el: HTMLElement): void;
18
+ clearNoEtaAttrs(el: HTMLElement): void;
19
+ updateElementEntry(el: HTMLElement, currentSrc: string, { allowMutationRefresh }: UpdateOptions): TemplateEntry;
20
+ }
21
+ export {};
@@ -0,0 +1,52 @@
1
+ export class EtaTemplateCache {
2
+ constructor() {
3
+ this._elementTemplates = new WeakMap();
4
+ this._attrTemplates = new WeakMap();
5
+ }
6
+ getElementEntry(el) {
7
+ return this._elementTemplates.get(el);
8
+ }
9
+ hasTemplate(el) {
10
+ const entry = this._elementTemplates.get(el);
11
+ return Boolean(entry && entry.src && entry.src.includes("{{"));
12
+ }
13
+ getOrCreateAttrCache(el) {
14
+ let cache = this._attrTemplates.get(el);
15
+ if (!cache) {
16
+ cache = new Map();
17
+ this._attrTemplates.set(el, cache);
18
+ }
19
+ return cache;
20
+ }
21
+ hasNoEtaAttrs(el) {
22
+ return this._noEtaAttrs?.has(el) ?? false;
23
+ }
24
+ markNoEtaAttrs(el) {
25
+ if (!this._noEtaAttrs)
26
+ this._noEtaAttrs = new WeakSet();
27
+ this._noEtaAttrs.add(el);
28
+ }
29
+ clearNoEtaAttrs(el) {
30
+ this._noEtaAttrs?.delete(el);
31
+ }
32
+ updateElementEntry(el, currentSrc, { allowMutationRefresh }) {
33
+ let entry = this._elementTemplates.get(el);
34
+ const hadTemplate = Boolean(entry && entry.src && entry.src.includes("{{"));
35
+ if (!entry) {
36
+ entry = { src: currentSrc };
37
+ this._elementTemplates.set(el, entry);
38
+ return entry;
39
+ }
40
+ if (entry.src !== currentSrc) {
41
+ const isTemplateLike = currentSrc.includes("{{");
42
+ // Accept SPA-authored changes (even without templates) only when mutation-triggered
43
+ // and the element did not previously cache a template.
44
+ if (isTemplateLike || (allowMutationRefresh && !hadTemplate)) {
45
+ entry.src = currentSrc;
46
+ delete entry.fn;
47
+ }
48
+ }
49
+ return entry;
50
+ }
51
+ }
52
+ //# sourceMappingURL=eta-template-cache.js.map