@repobit/dex-store-elements 1.7.3 → 2.0.1

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 (227) hide show
  1. package/CHANGELOG.md +6 -906
  2. package/README.md +308 -283
  3. package/dist/src/actions/action.adapter.d.ts +36 -0
  4. package/dist/src/actions/action.adapter.js +183 -0
  5. package/dist/src/actions/action.adapter.js.map +1 -0
  6. package/dist/src/actions/action.attributes.d.ts +15 -0
  7. package/dist/src/actions/action.attributes.js +137 -0
  8. package/dist/src/actions/action.attributes.js.map +1 -0
  9. package/dist/src/actions/action.registry.d.ts +4 -0
  10. package/dist/src/actions/action.registry.js +119 -0
  11. package/dist/src/actions/action.registry.js.map +1 -0
  12. package/dist/src/actions/index.d.ts +3 -2
  13. package/dist/src/actions/index.js +3 -80
  14. package/dist/src/actions/index.js.map +1 -1
  15. package/dist/src/compute/compute.expand.d.ts +70 -0
  16. package/dist/src/compute/compute.expand.js +319 -0
  17. package/dist/src/compute/compute.expand.js.map +1 -0
  18. package/dist/src/compute/compute.scan.d.ts +54 -0
  19. package/dist/src/compute/compute.scan.js +160 -0
  20. package/dist/src/compute/compute.scan.js.map +1 -0
  21. package/dist/src/compute/option-resolver.d.ts +31 -0
  22. package/dist/src/compute/option-resolver.js +147 -0
  23. package/dist/src/compute/option-resolver.js.map +1 -0
  24. package/dist/src/contexts/context.compute.d.ts +12 -0
  25. package/dist/src/contexts/context.compute.js +4 -0
  26. package/dist/src/contexts/context.compute.js.map +1 -0
  27. package/dist/src/contexts/context.scope.d.ts +139 -0
  28. package/dist/src/contexts/context.scope.js +48 -0
  29. package/dist/src/contexts/context.scope.js.map +1 -0
  30. package/dist/src/controllers/controller.action-resolve.d.ts +110 -0
  31. package/dist/src/controllers/controller.action-resolve.js +203 -0
  32. package/dist/src/controllers/controller.action-resolve.js.map +1 -0
  33. package/dist/src/controllers/controller.action-topology.d.ts +59 -0
  34. package/dist/src/controllers/controller.action-topology.js +130 -0
  35. package/dist/src/controllers/controller.action-topology.js.map +1 -0
  36. package/dist/src/controllers/controller.compute.d.ts +72 -0
  37. package/dist/src/controllers/controller.compute.js +110 -0
  38. package/dist/src/controllers/controller.compute.js.map +1 -0
  39. package/dist/src/controllers/controller.resolve.d.ts +78 -0
  40. package/dist/src/controllers/controller.resolve.js +205 -0
  41. package/dist/src/controllers/controller.resolve.js.map +1 -0
  42. package/dist/src/core/action-topology.d.ts +62 -0
  43. package/dist/src/core/action-topology.js +67 -0
  44. package/dist/src/core/action-topology.js.map +1 -0
  45. package/dist/src/core/actions.d.ts +64 -0
  46. package/dist/src/core/actions.js +47 -0
  47. package/dist/src/core/actions.js.map +1 -0
  48. package/dist/src/core/node.element.d.ts +179 -0
  49. package/dist/src/core/node.element.js +573 -0
  50. package/dist/src/core/node.element.js.map +1 -0
  51. package/dist/src/core/node.scope.d.ts +374 -0
  52. package/dist/src/core/node.scope.js +558 -0
  53. package/dist/src/core/node.scope.js.map +1 -0
  54. package/dist/src/core/option-update.d.ts +11 -0
  55. package/dist/src/core/option-update.js +59 -0
  56. package/dist/src/core/option-update.js.map +1 -0
  57. package/dist/src/dsl/compilers/array/compiler.js +13 -14
  58. package/dist/src/dsl/compilers/array/compiler.js.map +1 -1
  59. package/dist/src/dsl/compilers/boolean/compiler.d.ts +1 -1
  60. package/dist/src/dsl/compilers/boolean/compiler.js +14 -27
  61. package/dist/src/dsl/compilers/boolean/compiler.js.map +1 -1
  62. package/dist/src/dsl/compilers/enum/compiler.js +7 -10
  63. package/dist/src/dsl/compilers/enum/compiler.js.map +1 -1
  64. package/dist/src/dsl/compilers/index.d.ts +1 -1
  65. package/dist/src/dsl/compilers/index.js +5 -5
  66. package/dist/src/dsl/compilers/index.js.map +1 -1
  67. package/dist/src/dsl/utilty.d.ts +0 -4
  68. package/dist/src/dsl/utilty.js +3 -30
  69. package/dist/src/dsl/utilty.js.map +1 -1
  70. package/dist/src/eta/batch.d.ts +123 -0
  71. package/dist/src/eta/batch.js +162 -0
  72. package/dist/src/eta/batch.js.map +1 -0
  73. package/dist/src/eta/batcher.d.ts +184 -0
  74. package/dist/src/eta/batcher.js +335 -0
  75. package/dist/src/eta/batcher.js.map +1 -0
  76. package/dist/src/eta/cache.d.ts +36 -0
  77. package/dist/src/eta/cache.js +56 -0
  78. package/dist/src/eta/cache.js.map +1 -0
  79. package/dist/src/eta/controller.d.ts +608 -0
  80. package/dist/src/eta/controller.js +1036 -0
  81. package/dist/src/eta/controller.js.map +1 -0
  82. package/dist/src/eta/factory.d.ts +74 -0
  83. package/dist/src/eta/factory.js +121 -0
  84. package/dist/src/eta/factory.js.map +1 -0
  85. package/dist/src/eta/idle.d.ts +39 -0
  86. package/dist/src/eta/idle.js +52 -0
  87. package/dist/src/eta/idle.js.map +1 -0
  88. package/dist/src/eta/index.d.ts +52 -0
  89. package/dist/src/eta/index.js +13 -0
  90. package/dist/src/eta/index.js.map +1 -0
  91. package/dist/src/eta/observer.d.ts +263 -0
  92. package/dist/src/eta/observer.js +263 -0
  93. package/dist/src/eta/observer.js.map +1 -0
  94. package/dist/src/eta/operations.d.ts +41 -0
  95. package/dist/src/eta/operations.js +59 -0
  96. package/dist/src/eta/operations.js.map +1 -0
  97. package/dist/src/eta/source-registry.d.ts +198 -0
  98. package/dist/src/eta/source-registry.js +267 -0
  99. package/dist/src/eta/source-registry.js.map +1 -0
  100. package/dist/src/eta/template-index.d.ts +285 -0
  101. package/dist/src/eta/template-index.js +642 -0
  102. package/dist/src/eta/template-index.js.map +1 -0
  103. package/dist/src/eta/types.d.ts +529 -0
  104. package/dist/src/eta/types.js +2 -0
  105. package/dist/src/eta/types.js.map +1 -0
  106. package/dist/src/index.d.ts +21 -9
  107. package/dist/src/index.js +22 -11
  108. package/dist/src/index.js.map +1 -1
  109. package/dist/src/nodes/node.context.d.ts +5 -3
  110. package/dist/src/nodes/node.context.js +48 -3
  111. package/dist/src/nodes/node.context.js.map +1 -1
  112. package/dist/src/nodes/node.option.d.ts +11 -31
  113. package/dist/src/nodes/node.option.js +158 -222
  114. package/dist/src/nodes/node.option.js.map +1 -1
  115. package/dist/src/nodes/node.product.d.ts +7 -11
  116. package/dist/src/nodes/node.product.js +85 -64
  117. package/dist/src/nodes/node.product.js.map +1 -1
  118. package/dist/src/renders/attributes/buyLink.d.ts +2 -2
  119. package/dist/src/renders/attributes/buyLink.js +14 -11
  120. package/dist/src/renders/attributes/buyLink.js.map +1 -1
  121. package/dist/src/renders/attributes/devices.d.ts +2 -2
  122. package/dist/src/renders/attributes/devices.js +9 -19
  123. package/dist/src/renders/attributes/devices.js.map +1 -1
  124. package/dist/src/renders/attributes/discount.d.ts +2 -2
  125. package/dist/src/renders/attributes/discount.js +56 -44
  126. package/dist/src/renders/attributes/discount.js.map +1 -1
  127. package/dist/src/renders/attributes/hide.d.ts +2 -2
  128. package/dist/src/renders/attributes/hide.js +49 -14
  129. package/dist/src/renders/attributes/hide.js.map +1 -1
  130. package/dist/src/renders/attributes/index.d.ts +3 -3
  131. package/dist/src/renders/attributes/index.js +2 -4
  132. package/dist/src/renders/attributes/index.js.map +1 -1
  133. package/dist/src/renders/attributes/price.d.ts +2 -2
  134. package/dist/src/renders/attributes/price.js +30 -44
  135. package/dist/src/renders/attributes/price.js.map +1 -1
  136. package/dist/src/renders/attributes/subscription.d.ts +2 -2
  137. package/dist/src/renders/attributes/subscription.js +14 -20
  138. package/dist/src/renders/attributes/subscription.js.map +1 -1
  139. package/dist/src/renders/attributes/utilty.d.ts +2 -0
  140. package/dist/src/renders/attributes/utilty.js +17 -4
  141. package/dist/src/renders/attributes/utilty.js.map +1 -1
  142. package/dist/src/renders/context.d.ts +122 -10
  143. package/dist/src/renders/context.js +140 -80
  144. package/dist/src/renders/context.js.map +1 -1
  145. package/dist/src/renders/format.js +2 -2
  146. package/dist/src/renders/format.js.map +1 -1
  147. package/dist/src/renders/index.d.ts +6 -2
  148. package/dist/src/renders/index.js +67 -29
  149. package/dist/src/renders/index.js.map +1 -1
  150. package/dist/src/renders/observe.d.ts +1 -4
  151. package/dist/src/renders/observe.js +10 -24
  152. package/dist/src/renders/observe.js.map +1 -1
  153. package/dist/src/renders/render.wrapper.d.ts +37 -0
  154. package/dist/src/renders/render.wrapper.js +147 -0
  155. package/dist/src/renders/render.wrapper.js.map +1 -0
  156. package/dist/src/templating/eta.js +1 -4
  157. package/dist/src/templating/eta.js.map +1 -1
  158. package/package.json +4 -5
  159. package/dist/src/actions/action.button.d.ts +0 -2
  160. package/dist/src/actions/action.button.js +0 -8
  161. package/dist/src/actions/action.button.js.map +0 -1
  162. package/dist/src/actions/action.input.d.ts +0 -2
  163. package/dist/src/actions/action.input.js +0 -43
  164. package/dist/src/actions/action.input.js.map +0 -1
  165. package/dist/src/actions/action.select.d.ts +0 -2
  166. package/dist/src/actions/action.select.js +0 -14
  167. package/dist/src/actions/action.select.js.map +0 -1
  168. package/dist/src/actions/utilty.d.ts +0 -16
  169. package/dist/src/actions/utilty.js +0 -149
  170. package/dist/src/actions/utilty.js.map +0 -1
  171. package/dist/src/contexts/context.datalayer.d.ts +0 -9
  172. package/dist/src/contexts/context.datalayer.js +0 -3
  173. package/dist/src/contexts/context.datalayer.js.map +0 -1
  174. package/dist/src/contexts/context.derived.d.ts +0 -12
  175. package/dist/src/contexts/context.derived.js +0 -3
  176. package/dist/src/contexts/context.derived.js.map +0 -1
  177. package/dist/src/contexts/context.option.d.ts +0 -5
  178. package/dist/src/contexts/context.option.js +0 -3
  179. package/dist/src/contexts/context.option.js.map +0 -1
  180. package/dist/src/contexts/context.product.d.ts +0 -5
  181. package/dist/src/contexts/context.product.js +0 -3
  182. package/dist/src/contexts/context.product.js.map +0 -1
  183. package/dist/src/contexts/context.state.d.ts +0 -28
  184. package/dist/src/contexts/context.state.js +0 -3
  185. package/dist/src/contexts/context.state.js.map +0 -1
  186. package/dist/src/contexts/context.store.d.ts +0 -5
  187. package/dist/src/contexts/context.store.js +0 -3
  188. package/dist/src/contexts/context.store.js.map +0 -1
  189. package/dist/src/controllers/collect-controller.d.ts +0 -39
  190. package/dist/src/controllers/collect-controller.js +0 -161
  191. package/dist/src/controllers/collect-controller.js.map +0 -1
  192. package/dist/src/controllers/compute-controller.d.ts +0 -55
  193. package/dist/src/controllers/compute-controller.js +0 -350
  194. package/dist/src/controllers/compute-controller.js.map +0 -1
  195. package/dist/src/controllers/eta-renderer/eta-dom-renderer.d.ts +0 -25
  196. package/dist/src/controllers/eta-renderer/eta-dom-renderer.js +0 -192
  197. package/dist/src/controllers/eta-renderer/eta-dom-renderer.js.map +0 -1
  198. package/dist/src/controllers/eta-renderer/eta-mutation-observer.d.ts +0 -28
  199. package/dist/src/controllers/eta-renderer/eta-mutation-observer.js +0 -206
  200. package/dist/src/controllers/eta-renderer/eta-mutation-observer.js.map +0 -1
  201. package/dist/src/controllers/eta-renderer/eta-renderer.d.ts +0 -21
  202. package/dist/src/controllers/eta-renderer/eta-renderer.js +0 -77
  203. package/dist/src/controllers/eta-renderer/eta-renderer.js.map +0 -1
  204. package/dist/src/controllers/eta-renderer/eta-template-cache.d.ts +0 -24
  205. package/dist/src/controllers/eta-renderer/eta-template-cache.js +0 -61
  206. package/dist/src/controllers/eta-renderer/eta-template-cache.js.map +0 -1
  207. package/dist/src/controllers/eta-renderer/eta-types.d.ts +0 -11
  208. package/dist/src/controllers/eta-renderer/eta-types.js +0 -1
  209. package/dist/src/controllers/eta-renderer/eta-types.js.map +0 -1
  210. package/dist/src/controllers/eta-renderer/index.d.ts +0 -2
  211. package/dist/src/controllers/eta-renderer/index.js +0 -2
  212. package/dist/src/controllers/eta-renderer/index.js.map +0 -1
  213. package/dist/src/controllers/event-pipeline-controller.d.ts +0 -28
  214. package/dist/src/controllers/event-pipeline-controller.js +0 -72
  215. package/dist/src/controllers/event-pipeline-controller.js.map +0 -1
  216. package/dist/src/events/events.d.ts +0 -75
  217. package/dist/src/events/events.js +0 -78
  218. package/dist/src/events/events.js.map +0 -1
  219. package/dist/src/nodes/node.root.d.ts +0 -16
  220. package/dist/src/nodes/node.root.js +0 -49
  221. package/dist/src/nodes/node.root.js.map +0 -1
  222. package/dist/src/nodes/node.state.d.ts +0 -88
  223. package/dist/src/nodes/node.state.js +0 -330
  224. package/dist/src/nodes/node.state.js.map +0 -1
  225. package/dist/src/renders/utility.d.ts +0 -32
  226. package/dist/src/renders/utility.js +0 -191
  227. package/dist/src/renders/utility.js.map +0 -1
@@ -0,0 +1,374 @@
1
+ import type { BdComputeResult } from '../compute/compute.expand.js';
2
+ import { BdScope, type BdDataLayerFn, type BdScopeChangeFn, type BdScopeDeriveFn } from '../contexts/context.scope.js';
3
+ import { BdComputeController } from '../controllers/controller.compute.js';
4
+ import { type BdTransition } from '../core/actions.js';
5
+ import type { EtaMutationBatchSchedule } from '../eta/types.js';
6
+ import { type TemplateOptionContext, type TemplateProductContext, type TemplateStateContext } from '../renders/context.js';
7
+ import type { Store } from '@repobit/dex-store';
8
+ import type { PropertyValues } from 'lit';
9
+ import { BdNodeElement } from './node.element.js';
10
+ /**
11
+ * The shape templates see under a `BdScopedElement`.
12
+ *
13
+ * Mirrors the v1 `it.*` layout: `option` / `product` / `state` are flattened
14
+ * DTOs with pre-formatted strings, and `ctx` is an alias of `state`. Adding
15
+ * a new field here is a public surface change (every consumer can read it),
16
+ * so prefer extending `TemplateDslContext` and rebinding this snapshot
17
+ * rather than spreading the raw `BdScope` object.
18
+ *
19
+ * `derived` carries whatever object `scope.derived({...})` returned for the
20
+ * current scope — templates read derived properties as `<%= it.derived.foo
21
+ * %>`. `undefined` when the scope has no `derived` factory.
22
+ */
23
+ export type BdScopedTemplateContext = {
24
+ store: Store | undefined;
25
+ product: TemplateProductContext | undefined;
26
+ option: TemplateOptionContext | undefined;
27
+ state: TemplateStateContext | undefined;
28
+ ctx: TemplateStateContext | undefined;
29
+ derived: Readonly<Record<string, unknown>> | undefined;
30
+ };
31
+ export declare abstract class BdScopedElement extends BdNodeElement {
32
+ #private;
33
+ private readonly scopedValueKeys;
34
+ protected computeResult?: BdComputeResult;
35
+ readonly compute: BdComputeController;
36
+ /**
37
+ * Owning boundary for the Eta template index.
38
+ *
39
+ * `BdScopedElement` IS the index root — every nested template
40
+ * is owned by the closest enclosing bd-* node, and that node
41
+ * in turn owns the controller that renders its subtree.
42
+ */
43
+ get root(): Element;
44
+ /**
45
+ * Eta template controller that renders the subtree against the
46
+ * current scope and compute result.
47
+ *
48
+ * Args trigger a re-render when the scope, the compute result,
49
+ * or the eta-enabled flag change. The render is gated on
50
+ * `isEtaEnabled` so a disabled scope does not flicker
51
+ * intermediate state.
52
+ *
53
+ * The context exposes **only** `store`, `product`, `option`,
54
+ * and `state` — exactly the fields templates are expected to
55
+ * reference. We do not spread the full scope, do not surface
56
+ * `$scope` / `$state` handles, and do not leak the transition
57
+ * object. New fields belong on `BdScope` plus an explicit
58
+ * binding here so the public template surface stays auditable.
59
+ *
60
+ * The boundary predicate uses raw tag names so nested
61
+ * `bd-context` / `bd-product` / `bd-option` nodes
62
+ * keep their own controllers and templates do not leak across
63
+ * scope boundaries. Tag-name checks are stable before custom
64
+ * element upgrade — `EtaTemplateControllerOptions.isBoundaryElement`
65
+ * MUST work on raw DOM shape.
66
+ */
67
+ readonly eta: import("../eta/controller.js").EtaTemplateController<readonly [scope: Readonly<Partial<{
68
+ store: Store;
69
+ product: import("@repobit/dex-store").Product;
70
+ option: import("@repobit/dex-store").ProductOption;
71
+ transition: BdTransition;
72
+ computeDisabled: boolean;
73
+ etaDisabled: boolean;
74
+ derived: BdScopeDeriveFn;
75
+ mutationBatchSchedule: EtaMutationBatchSchedule;
76
+ onScopeChange: BdScopeChangeFn;
77
+ dataLayer: BdDataLayerFn;
78
+ }>> | undefined, compute: Readonly<{
79
+ min: number;
80
+ max: number;
81
+ minFormatted: string;
82
+ maxFormatted: string;
83
+ scenarios: number;
84
+ price: import("../compute/compute.expand.js").BdComputeMonthlyRange;
85
+ discountedPrice: import("../compute/compute.expand.js").BdComputeMonthlyRange;
86
+ discount: import("../compute/compute.expand.js").BdComputeDiscountRange;
87
+ }> | undefined], BdScopedTemplateContext>;
88
+ etaDisabled: boolean;
89
+ protected get isEtaEnabled(): boolean;
90
+ computeDisabled: boolean;
91
+ protected parentScope?: BdScope;
92
+ protected providedScope?: BdScope;
93
+ protected get currentScope(): BdScope | undefined;
94
+ protected get isComputeEnabled(): boolean;
95
+ /**
96
+ * Comma-separated list of event ids to ignore.
97
+ *
98
+ * Pair with `data-store-event-id` on action elements: any transition
99
+ * whose command carries a matching `eventId` is dropped before it can
100
+ * drive this node (or any of its descendants, since the cascade is
101
+ * gated here).
102
+ *
103
+ * Example:
104
+ * ```html
105
+ * <button data-store-action
106
+ * data-store-event-id="devicesBtn"
107
+ * data-store-set-devices="25">25</button>
108
+ *
109
+ * <bd-option ignore-events="devicesBtn, subscriptionBtn">
110
+ * ...
111
+ * </bd-option>
112
+ * ```
113
+ */
114
+ ignoreEvents?: string;
115
+ /**
116
+ * When set, this node only reacts to events originating inside its own
117
+ * subtree. Cascading transitions from `parentScope.transition` are
118
+ * dropped, mirroring v1's `<bd-state ignore-events-parent>` semantics.
119
+ *
120
+ * `<bd-context>` enables this by default (it is a hard event boundary).
121
+ */
122
+ ignoreEventsParent: boolean;
123
+ protected get ignoredEventIds(): ReadonlySet<string>;
124
+ /**
125
+ * Filter callback handed to each node's `BdActionResolveController`.
126
+ *
127
+ * Drops transitions whose `eventId` matches an entry in `ignore-events`,
128
+ * and — when `ignore-events-parent` is set — drops any cascade from a
129
+ * parent scope. Concrete nodes pass `filterTransition: (c) =>
130
+ * this._filterTransition(c)` into their controller config; the
131
+ * controller invokes this for both local `bd-action-request` events
132
+ * and inherited transitions.
133
+ */
134
+ protected _filterTransition(candidate: {
135
+ transition: BdTransition;
136
+ source: 'local' | 'parent';
137
+ }): boolean;
138
+ protected publishScope(nextScope: BdScope): BdScope;
139
+ private buildScopeChangeSnapshot;
140
+ /**
141
+ * Fires `onScopeChange` for compute-result-only transitions.
142
+ *
143
+ * `BdComputeController.onResult` writes `computeResult`, which
144
+ * is part of the published snapshot's `state`. Without this
145
+ * trigger, consumers watching the snapshot would miss compute
146
+ * state changes that are not accompanied by a scope publish
147
+ * or clear. Targeted invocation keeps the contract in one
148
+ * place: `publishScope()` and `clearScope()` keep their own
149
+ * paths; this helper handles the compute-only path.
150
+ *
151
+ * Idempotent: no-op when no scope has been published yet
152
+ * (the hook is not on any scope) or when the snapshot's
153
+ * `state` did not actually change (caller short-circuits via
154
+ * `Object.is` before calling).
155
+ */
156
+ private _fireOnScopeChangeForCompute;
157
+ private snapshotsEqual;
158
+ private scopeWithoutOwnedValues;
159
+ private updateScopedValueKeys;
160
+ private updateScopedValueKey;
161
+ protected clearScope(): void;
162
+ protected requireParentScope(): BdScope;
163
+ /**
164
+ * Single-pass overlay applied to every published scope.
165
+ *
166
+ * The pass runs in two phases:
167
+ *
168
+ * 1. **Sparse boolean flags** — `computeDisabled` and
169
+ * `etaDisabled`. Reflected from `isComputeEnabled` /
170
+ * `isEtaEnabled` (the inverse of "is enabled").
171
+ * 2. **Value overlays** — `derived` and
172
+ * `mutationBatchSchedule`. Caller-supplied values win; the
173
+ * per-instance property fills in when the caller did not
174
+ * supply one.
175
+ *
176
+ * Both phases share the same lazy-allocation strategy: a new
177
+ * scope object is only created when at least one phase has a
178
+ * write to perform. A scope with nothing to merge is returned
179
+ * by reference, which lets `publishScope`'s `Object.is` check
180
+ * short-circuit the downstream `@provide` notification.
181
+ */
182
+ private applyScopedFlags;
183
+ /**
184
+ * Per-instance derived Eta context factory.
185
+ *
186
+ * Users supply this on any bd-* node (via constructor,
187
+ * attribute, or `instance.derived = fn`) to expose additional
188
+ * template bindings under the `derived` key. The factory
189
+ * receives `{ store, product, option }` and returns an object
190
+ * whose properties become available to templates as
191
+ * `<%= it.derived.<key> %>`.
192
+ *
193
+ * `publishScope` merges this property into the published scope
194
+ * automatically when the caller did not supply an explicit
195
+ * `derived` of its own — so a user just needs to assign
196
+ * `node.derived = fn` (or set the `derived` attribute) and
197
+ * the factory becomes part of the scope for free.
198
+ *
199
+ * Reactivity: the field is a Lit `@property`, so reassigning
200
+ * `this.derived = newFactory` triggers `requestUpdate()` and a
201
+ * re-publish via `willUpdate`. Method references declared
202
+ * once per instance are stable, so the `@lit/task` args
203
+ * comparison short-circuits re-renders for unrelated changes.
204
+ *
205
+ * `derived` is intended to be supplied by users at the call
206
+ * site, not declared on concrete node subclasses. Subclasses
207
+ * that need a static default can still assign it in their
208
+ * constructor; the merge step lets callers override.
209
+ *
210
+ * @example
211
+ *
212
+ * ```ts
213
+ * const product = document.createElement('bd-product');
214
+ * product.productId = 'acrobat-pro';
215
+ * product.derived = ({ product, option }) => ({
216
+ * canBuy : Boolean(product && option),
217
+ * hasDiscount: Boolean(option?.discounted)
218
+ * });
219
+ * ```
220
+ *
221
+ * Or via plain JS (recommended — functions cannot be authored
222
+ * as attribute strings):
223
+ *
224
+ * ```ts
225
+ * const product = document.createElement('bd-product');
226
+ * product.productId = 'acrobat-pro';
227
+ * product.derived = ({ product, option }) => ({
228
+ * canBuy : Boolean(product && option),
229
+ * hasDiscount: Boolean(option?.discounted)
230
+ * });
231
+ * ```
232
+ *
233
+ * The attribute mapping is intentionally omitted — Lit's
234
+ * default converter cannot turn a string into a typed
235
+ * function, so the property is JS-only. Hosts that want
236
+ * attribute-driven configuration should expose a wrapper
237
+ * attribute on their own subclass and assign `derived` from
238
+ * the wrapper's converter.
239
+ */
240
+ derived?: BdScopeDeriveFn;
241
+ /**
242
+ * Per-instance mutation batch schedule.
243
+ *
244
+ * Wired through the scope so descendants can read the same
245
+ * value via `parentScope.mutationBatchSchedule`. Existing Eta
246
+ * controllers receive a resolver callback, so flipping the
247
+ * schedule after connection affects future mutation flushes
248
+ * once the parent republishes its scope.
249
+ *
250
+ * Accepted via constructor / `instance.mutationBatchSchedule =
251
+ * 'idle'`. The attribute mapping is intentionally omitted
252
+ * because Lit's default converter is happy with the string
253
+ * union, but exposing it as an attribute would invite the
254
+ * same authoring pitfalls we deliberately avoid for
255
+ * `derived` (callers writing `schedule="animation-frame"`
256
+ * without realising the value is scope-driven rather than an
257
+ * imperative one-shot switch).
258
+ *
259
+ * @example
260
+ *
261
+ * ```ts
262
+ * const product = document.createElement('bd-product');
263
+ * product.productId = 'acrobat-pro';
264
+ * product.mutationBatchSchedule = 'microtask';
265
+ * ```
266
+ */
267
+ mutationBatchSchedule?: EtaMutationBatchSchedule;
268
+ /**
269
+ * Per-instance scope-change hook.
270
+ *
271
+ * Fired whenever this node's effective published scope changes
272
+ * — both when `publishScope(...)` produces a new normalized
273
+ * scope reference, and when `clearScope()` removes the
274
+ * scope. The hook receives a narrow snapshot exposing only
275
+ * `store`, `product`, `option`, and `state` — the four fields
276
+ * that drive template rendering. It does NOT receive the
277
+ * transition, the disabled flags, the derived factory, or the
278
+ * mutation batch schedule.
279
+ *
280
+ * Wired through `BdScope.onScopeChange` like `derived` and
281
+ * `mutationBatchSchedule`, so descendants can read the
282
+ * inherited hook from `parentScope.onScopeChange` and a child
283
+ * can override its ancestor's hook by assigning its own.
284
+ *
285
+ * Attribute mapping is intentionally omitted — functions
286
+ * cannot be represented as attribute strings, and a stale or
287
+ * stale-shaped `on-scope-change="..."` attribute would invite
288
+ * the same authoring pitfalls we deliberately avoid for
289
+ * `derived`. Configure via JS instead:
290
+ *
291
+ * @example
292
+ *
293
+ * ```ts
294
+ * const product = document.createElement('bd-product');
295
+ * product.productId = 'acrobat-pro';
296
+ * product.onScopeChange = ({ store, product, option, state }) => {
297
+ * console.log('scope changed', { store, product, option, state });
298
+ * };
299
+ * ```
300
+ */
301
+ onScopeChange?: BdScopeChangeFn;
302
+ /**
303
+ * Inherited callback for option-load data-layer events.
304
+ * Configure it as a JavaScript property; functions are not
305
+ * represented as attributes.
306
+ */
307
+ dataLayer?: BdDataLayerFn;
308
+ /**
309
+ * Per-instance store reference.
310
+ *
311
+ * When set on any `BdScopedElement` subclass, the value is published
312
+ * into the scope context via `createBdStoreScope(this.store)` so
313
+ * descendants can consume it from `parentScope.store`. Setting it back
314
+ * to `undefined` calls `clearScope()` to remove the published scope;
315
+ * flipping from one store to another re-publishes the existing scope
316
+ * with the new reference.
317
+ *
318
+ * The store-property publish is intentionally additive — it does not
319
+ * replace the existing `BdActionResolveController` flow used by
320
+ * `bd-context`, `bd-product`, and `bd-option`. Those controllers
321
+ * capture their own transition for the action-request path; the store
322
+ * scope is purely a value-publish surface.
323
+ *
324
+ * @example
325
+ *
326
+ * ```ts
327
+ * const root = document.createElement('bd-context');
328
+ * root.store = myStore;
329
+ * // descendants under <bd-context> now see { store: myStore }
330
+ * // via parentScope.store.
331
+ *
332
+ * // Clear the published scope
333
+ * root.store = undefined;
334
+ * ```
335
+ *
336
+ * The attribute mapping is intentionally omitted — Lit's default
337
+ * converter cannot turn a string into a `Store` instance, and
338
+ * serializing a store to an attribute would defeat the point of
339
+ * holding it as a typed reference. Configure via JS instead, the
340
+ * same way `derived` and `onScopeChange` are configured.
341
+ */
342
+ store?: Store;
343
+ /**
344
+ * Publishes or clears the scope for a `store` property change.
345
+ *
346
+ * Single entry point for the three transitions `store` can drive:
347
+ *
348
+ * 1. `store` is `undefined` → `clearScope()` removes the published
349
+ * scope and fires the `onScopeChange` hook with all-undefined
350
+ * fields.
351
+ * 2. `store` is defined and a scope is already published →
352
+ * re-publishes the existing scope with the new store reference
353
+ * (the rest of the scope — `derived`, `mutationBatchSchedule`,
354
+ * `onScopeChange`, flags — is preserved).
355
+ * 3. `store` is defined and no scope is published yet → publishes a
356
+ * fresh `createBdStoreScope(this.store)` so the first descendant
357
+ * read sees a non-undefined `parentScope.store`.
358
+ *
359
+ * Called from `willUpdate` whenever `changedProperties.has('store')`.
360
+ * Idempotent: re-publishing the same scope reference is a no-op for
361
+ * the `@provide` notification because `publishScope` already short-
362
+ * circuits on `Object.is(this.providedScope, normalizedScope)`.
363
+ */
364
+ protected publishStoreScope(): void;
365
+ protected willUpdate(changedProperties: PropertyValues<this>): void;
366
+ }
367
+ /**
368
+ * Parses the comma-separated `ignore-events` attribute into a set of ids.
369
+ *
370
+ * Empty entries are skipped so `"foo, ,bar"` produces `{ foo, bar }`.
371
+ * The function is exported so test code can compare against the same
372
+ * parsing rules the runtime uses.
373
+ */
374
+ export declare function parseIgnoreEvents(value: string | undefined): ReadonlySet<string>;