@repobit/dex-store-elements 1.7.2 → 2.0.0

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 +5 -905
  2. package/README.md +9 -7
  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
@@ -4,248 +4,184 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { dataLayerContext } from "../contexts/context.datalayer.js";
8
- import { optionContext } from "../contexts/context.option.js";
9
- import { productContext } from "../contexts/context.product.js";
10
- import { toDSLContext } from "../renders/context.js";
11
- import { consume, provide } from "@lit/context";
12
- import { Task } from "@lit/task";
13
- import { property } from "lit/decorators.js";
14
- import { StateNode } from "./node.state.js";
15
- export class OptionNode extends StateNode {
7
+ import { extendBdOptionScope } from '../contexts/context.scope.js';
8
+ import { BdActionResolveController } from '../controllers/controller.action-resolve.js';
9
+ import { BdScopedElement } from '../core/node.scope.js';
10
+ import { applyOptionUpdate } from '../core/option-update.js';
11
+ import { property } from 'lit/decorators.js';
12
+ export class OptionNode extends BdScopedElement {
16
13
  constructor() {
17
14
  super(...arguments);
18
- this.bundle = [];
19
- // ensure datalayer is fired only once (first load)
20
- this._sentDataLayer = false;
21
- this._changeOptionEvent = new Task(this, {
22
- task: async ([evt, store]) => {
23
- if (!evt || !store) {
24
- return null;
25
- }
26
- // Ignore events matching this node's ignoreEvents list (works for DOM or context)
27
- if (this._isIgnoredSource(evt)) {
28
- return null;
29
- }
30
- this._collectFromTask(this._changeOptionEvent.taskComplete);
31
- let option = null;
32
- if (this.isActionEvent(evt)) {
33
- // Record event-driven attribute values (if any) so attribute task can skip
34
- this._pendingDevicesFromEvent = evt.detail?.devices;
35
- this._pendingSubscriptionFromEvent = evt.detail?.subscription;
36
- option = await this.__applyAction(evt.detail || {});
37
- }
38
- if (this.isBundleToogle(evt)) {
39
- option = await this.__applyBundle(evt.detail || {});
40
- }
41
- if (this.isDeltaUpdate(evt)) {
42
- option = await this._applyDeltaUpdate(evt.detail || {});
43
- }
44
- this._option = option;
45
- return option;
15
+ this._dataLayerSent = false;
16
+ this._workflow = new BdActionResolveController(this, {
17
+ name: 'option',
18
+ args: () => [
19
+ this.parentScope,
20
+ this.devices,
21
+ this.subscription
22
+ ],
23
+ transition: ([parentScope]) => parentScope?.transition,
24
+ derive: ([parentScope, devices, subscription], { transition }) => {
25
+ const action = transition?.command.kind === 'set-action'
26
+ ? transition.command.action
27
+ : undefined;
28
+ const update = transition?.command.kind === 'update-by-delta'
29
+ ? transition.command.update
30
+ : undefined;
31
+ return [
32
+ parentScope,
33
+ action?.devices ??
34
+ applyOptionUpdate('devices', devices, update, parentScope?.product),
35
+ action?.subscription ??
36
+ applyOptionUpdate('subscription', subscription, update, parentScope?.product)
37
+ ];
46
38
  },
47
- args: () => [this._event, this._store]
48
- });
49
- // Ensure datalayer is emitted if the callback becomes available slightly
50
- // after the first option was computed.
51
- this._fireDataLayerTask = new Task(this, {
52
- task: async ([opt, dl, evt]) => {
53
- if (this._sentDataLayer)
54
- return;
55
- if (opt && dl && evt) {
56
- dl({ option: opt, event: evt });
57
- this._sentDataLayer = true;
39
+ enabled: ([parentScope, devices, subscription]) => Boolean(parentScope?.product &&
40
+ typeof devices === 'number' &&
41
+ typeof subscription === 'number'),
42
+ filterTransition: (candidate) => this._filterTransition(candidate),
43
+ resolve: async ([parentScope, devices, subscription], _resolveContext, actionContext) => {
44
+ if (!parentScope?.product ||
45
+ typeof devices !== 'number' ||
46
+ typeof subscription !== 'number') {
47
+ return undefined;
58
48
  }
49
+ return await resolveOption({
50
+ parentScope,
51
+ /**
52
+ * Read the previously committed option via closure, NOT through
53
+ * args(). Feeding currentScope.option back into args() makes the
54
+ * resolver consume its own output and spin forever whenever resolve
55
+ * returns a fresh ProductOption instance (e.g. bundles).
56
+ */
57
+ currentOption: this.option,
58
+ devices,
59
+ subscription,
60
+ transition: actionContext.transition
61
+ });
59
62
  },
60
- args: () => [this._option, this._dataLayer, this.dataLayerEvent]
61
- });
62
- this._loadOptionByAttributes = new Task(this, {
63
- task: async ([devices, subscription]) => {
64
- const hasPendingDevices = this._pendingDevicesFromEvent !== undefined;
65
- const hasPendingSubscription = this._pendingSubscriptionFromEvent !== undefined;
66
- const matchesPendingDevices = !hasPendingDevices || devices === this._pendingDevicesFromEvent;
67
- const matchesPendingSubscription = !hasPendingSubscription || subscription === this._pendingSubscriptionFromEvent;
68
- // Skip only when current attribute values were just set by an event
69
- if ((hasPendingDevices || hasPendingSubscription)
70
- && matchesPendingDevices
71
- && matchesPendingSubscription) {
72
- this._pendingDevicesFromEvent = undefined;
73
- this._pendingSubscriptionFromEvent = undefined;
74
- return this._option;
75
- }
76
- if (!this._option) {
77
- return null;
78
- }
79
- if (devices === undefined || subscription === undefined) {
80
- this._option = null;
81
- return null;
63
+ commit: (option, [parentScope], _resolveContext, actionContext) => {
64
+ if (!option || !parentScope) {
65
+ this.option = undefined;
66
+ this.setLocalOptionSeed(undefined);
67
+ this.clearScope();
68
+ return;
82
69
  }
83
- this._collectFromTask(this._loadOptionByAttributes.taskComplete);
84
- const option = await this.option?.getOption({ devices, subscription });
85
- this._option = option;
86
- return option;
70
+ this.option = option;
71
+ this.devices = option.getDevices();
72
+ this.subscription = option.getSubscription();
73
+ this.setLocalOptionSeed(option);
74
+ this.publishScope(extendBdOptionScope(parentScope, option, actionContext.transition));
75
+ this.fireDataLayer();
87
76
  },
88
- args: () => [this.devices, this.subscription]
77
+ onDisabled: () => {
78
+ this.option = undefined;
79
+ this.setLocalOptionSeed(undefined);
80
+ this.clearScope();
81
+ }
89
82
  });
90
83
  }
91
- get option() {
92
- return this._option;
93
- }
94
- _collectFromTask(taskComplete) {
95
- this._optionContext = taskComplete;
96
- if (!this.noCollect) {
97
- this.collectOption({
98
- name: this.storeName,
99
- options: taskComplete.then((option) => option ? [option] : [])
100
- });
101
- }
102
- }
103
- _syncOptionAttributes(option) {
104
- const devices = option.getDevices();
105
- const subscription = option.getSubscription();
106
- // Mark as event-driven attribute update to avoid double work
107
- this._pendingDevicesFromEvent = devices;
108
- this._pendingSubscriptionFromEvent = subscription;
109
- this.devices = devices;
110
- this.subscription = subscription;
111
- }
112
- getEtaArgs() {
113
- return [this._option, this.state, this.product, this._derived];
114
- }
115
- async buildEtaContext() {
116
- await this._changeOptionEvent.taskComplete;
117
- await this._loadOptionByAttributes.taskComplete;
118
- if (!this._option)
119
- return undefined;
120
- return await toDSLContext({ option: this._option, product: this.product, state: this.state, derived: this._derived });
84
+ get scope() {
85
+ return this.currentScope;
121
86
  }
122
- connectedCallback() {
123
- super.connectedCallback();
124
- if (!this.noCollect) {
125
- this.collectOption({
126
- name: this.storeName,
127
- options: Promise.resolve(this._option ? [this._option] : [])
128
- });
87
+ updated(changedProperties) {
88
+ super.updated(changedProperties);
89
+ if (changedProperties.has('dataLayerEvent') ||
90
+ changedProperties.has('dataLayer')) {
91
+ this.fireDataLayer();
129
92
  }
130
93
  }
131
- disconnectedCallback() {
132
- this.collectOption({
133
- name: this.storeName,
134
- options: null
135
- });
136
- super.disconnectedCallback();
137
- }
138
- async getUpdateComplete() {
139
- const result = await super.getUpdateComplete();
140
- await this._changeOptionEvent.taskComplete;
141
- await this._loadOptionByAttributes.taskComplete;
142
- await this._fireDataLayerTask.taskComplete;
143
- return result;
144
- }
145
- _eventChange(e) {
146
- // Respect option-level ignore list
147
- if (this._isIgnoredSource(e)) {
148
- e.stopPropagation();
94
+ fireDataLayer() {
95
+ const dataLayer = this.currentScope?.dataLayer;
96
+ if (this._dataLayerSent ||
97
+ !this.option ||
98
+ !dataLayer ||
99
+ this.dataLayerEvent === undefined) {
149
100
  return;
150
101
  }
151
- // Always capture locally
152
- this._eventDom = e;
153
- // Allow only product-change events to bubble up to <bd-product>
154
- if (this.isProductChange(e)) {
155
- return; // no stopPropagation → let it bubble
156
- }
157
- // Keep all other events scoped to this option
158
- e.stopPropagation();
159
- }
160
- async _applyDeltaUpdate({ type, delta, useAsValue, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER }) {
161
- const devices = useAsValue && type === "devices" ? Number(delta) : this.devices;
162
- const subscription = useAsValue && type === "subscription" ? Number(delta) : this.subscription;
163
- let option;
164
- if (useAsValue) {
165
- if (devices === undefined
166
- || subscription === undefined
167
- || Number.isNaN(devices)
168
- || Number.isNaN(subscription)) {
169
- return null;
170
- }
171
- option = await this.option?.getOption({ devices, subscription });
172
- }
173
- else {
174
- option = await this.option?.nextOption(type === "devices" ?
175
- { devices: delta } :
176
- { subscription: delta });
177
- }
178
- if (!option) {
179
- return null;
180
- }
181
- if (type === "devices" && (option.getDevices() < min || option.getDevices() > max)) {
182
- return null;
183
- }
184
- if (type === "subscription" && (option.getSubscription() < min || option.getSubscription() > max)) {
185
- return null;
186
- }
187
- this._syncOptionAttributes(option);
188
- return option;
189
- }
190
- async __applyAction({ id, campaign, devices, subscription }) {
191
- this.devices = devices ?? this.devices;
192
- this.subscription = subscription ?? this.subscription;
193
- if (this.devices === undefined || this.subscription === undefined) {
194
- return null;
195
- }
196
- if (id) {
197
- const product = await this._store?.getProduct({ id, campaign });
198
- return product?.getOption({
199
- devices: this.devices,
200
- subscription: this.subscription,
201
- bundle: this.option?.getBundle() || []
202
- });
203
- }
204
- return this.option?.getOption({ devices: this.devices, subscription: this.subscription });
205
- }
206
- async __applyBundle(option) {
207
- const devices = option.devices ?? this.devices;
208
- const subscription = option.subscription ?? this.subscription;
209
- if (devices === undefined || subscription === undefined || !option.id) {
210
- return null;
211
- }
212
- const productToBeBundled = await this._store?.getProduct({ id: option.id, campaign: option.campaign });
213
- const optionToBeBundled = await productToBeBundled?.getOption({ devices, subscription });
214
- if (!optionToBeBundled) {
215
- return null;
216
- }
217
- if (this.devices !== undefined && this.subscription !== undefined) {
218
- return this.option?.toogleBundle({
219
- devicesFixed: Boolean(option.devices),
220
- subscriptionFixed: Boolean(option.subscription),
221
- option: optionToBeBundled
222
- });
223
- }
224
- return null;
102
+ dataLayer({
103
+ option: this.option,
104
+ event: this.dataLayerEvent
105
+ });
106
+ this._dataLayerSent = true;
225
107
  }
226
108
  }
227
109
  __decorate([
228
- provide({ context: optionContext }),
229
- property({ attribute: false })
230
- ], OptionNode.prototype, "_optionContext", void 0);
231
- __decorate([
232
- consume({ context: dataLayerContext, subscribe: true }),
233
- property({ attribute: false })
234
- ], OptionNode.prototype, "_dataLayer", void 0);
235
- __decorate([
236
- consume({ context: productContext, subscribe: true }),
237
- property({ attribute: false })
238
- ], OptionNode.prototype, "product", void 0);
239
- __decorate([
240
- property({ attribute: false })
241
- ], OptionNode.prototype, "bundle", void 0);
242
- __decorate([
243
- property({ type: Number, reflect: true })
110
+ property({
111
+ type: Number,
112
+ reflect: true
113
+ })
244
114
  ], OptionNode.prototype, "devices", void 0);
245
115
  __decorate([
246
- property({ type: Number, reflect: true })
116
+ property({
117
+ type: Number,
118
+ reflect: true
119
+ })
247
120
  ], OptionNode.prototype, "subscription", void 0);
248
121
  __decorate([
249
- property({ attribute: 'data-layer-event' })
122
+ property({
123
+ attribute: false
124
+ })
125
+ ], OptionNode.prototype, "option", void 0);
126
+ __decorate([
127
+ property({
128
+ attribute: 'data-layer-event'
129
+ })
250
130
  ], OptionNode.prototype, "dataLayerEvent", void 0);
131
+ async function resolveOption(params) {
132
+ const action = params.transition?.command.kind === 'set-action'
133
+ ? params.transition.command.action
134
+ : undefined;
135
+ if (action?.bundle && action.id) {
136
+ return await resolveBundleOption(params, action);
137
+ }
138
+ if (params.currentOption &&
139
+ params.currentOption.getProduct() === params.parentScope.product) {
140
+ return await params.currentOption.getOption({
141
+ devices: params.devices,
142
+ subscription: params.subscription
143
+ });
144
+ }
145
+ return await params.parentScope.product?.getOption({
146
+ devices: params.devices,
147
+ subscription: params.subscription
148
+ });
149
+ }
150
+ async function resolveBundleOption(params, action) {
151
+ if (!action.id) {
152
+ return undefined;
153
+ }
154
+ const reuseCurrentOption = params.currentOption !== undefined &&
155
+ params.currentOption.getProduct() === params.parentScope.product;
156
+ const baseOption = reuseCurrentOption
157
+ ? params.currentOption
158
+ : await params.parentScope.product?.getOption({
159
+ devices: params.devices,
160
+ subscription: params.subscription
161
+ });
162
+ if (!baseOption) {
163
+ return undefined;
164
+ }
165
+ const bundleProduct = await params.parentScope.store?.getProduct({
166
+ id: action.id,
167
+ campaign: action.campaign
168
+ });
169
+ if (!bundleProduct) {
170
+ return undefined;
171
+ }
172
+ const bundleDevices = action.devices ?? params.devices;
173
+ const bundleSubscription = action.subscription ?? params.subscription;
174
+ const bundleOption = await bundleProduct.getOption({
175
+ devices: bundleDevices,
176
+ subscription: bundleSubscription
177
+ });
178
+ if (!bundleOption) {
179
+ return undefined;
180
+ }
181
+ return await baseOption.toogleBundle({
182
+ option: bundleOption,
183
+ devicesFixed: action.devices !== undefined,
184
+ subscriptionFixed: action.subscription !== undefined
185
+ });
186
+ }
251
187
  //# sourceMappingURL=node.option.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.option.js","sourceRoot":"","sources":["../../../src/nodes/node.option.ts"],"names":[],"mappings":"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","sourcesContent":["import { dataLayerContext, dataLayerContextType, dataLayerPayload } from \"@/contexts/context.datalayer\";\nimport { optionContext, optionContextType } from \"@/contexts/context.option\";\nimport { productContext, productContextType } from \"@/contexts/context.product\";\nimport { Action, EventType, UpdateByDelta } from \"@/events/events\";\nimport { toDSLContext } from \"@/renders/context\";\nimport { consume, provide } from \"@lit/context\";\nimport { Task } from \"@lit/task\";\nimport { ProductBundleOption, ProductOption } from \"@repobit/dex-store\";\nimport { property } from \"lit/decorators.js\";\nimport { StateNode } from \"./node.state\";\n\nexport class OptionNode extends StateNode {\n @provide({ context: optionContext })\n @property({ attribute: false })\n _optionContext?: optionContextType;\n\n @consume({ context: dataLayerContext, subscribe: true })\n @property({ attribute: false })\n _dataLayer?: dataLayerContextType;\n\n @consume({ context: productContext, subscribe: true })\n @property({ attribute: false })\n product?: productContextType;\n\n @property({ attribute: false })\n bundle = [] as ProductBundleOption[];\n\n @property({ type: Number, reflect: true })\n devices?: number;\n\n @property({ type: Number, reflect: true })\n subscription?: number;\n\n // Optional data layer event name to publish when option loads/changes\n @property({ attribute: 'data-layer-event' })\n dataLayerEvent?: dataLayerPayload[\"event\"];\n\n _option: ProductOption | null | undefined;\n // ensure datalayer is fired only once (first load)\n private _sentDataLayer = false;\n\n // Track attribute values last set by an incoming event\n // to avoid double work in _loadOptionByAttributes.\n private _pendingDevicesFromEvent : number | undefined;\n private _pendingSubscriptionFromEvent: number | undefined;\n\n get option(): ProductOption | null | undefined {\n return this._option;\n }\n\n private _collectFromTask(taskComplete: Promise<ProductOption | null | undefined>) {\n this._optionContext = taskComplete;\n\n if (!this.noCollect) {\n this.collectOption({\n name : this.storeName,\n options: taskComplete.then((option) => option ? [option] : [])\n });\n }\n }\n\n private _syncOptionAttributes(option: ProductOption) {\n const devices = option.getDevices();\n const subscription = option.getSubscription();\n\n // Mark as event-driven attribute update to avoid double work\n this._pendingDevicesFromEvent = devices;\n this._pendingSubscriptionFromEvent = subscription;\n\n this.devices = devices;\n this.subscription = subscription;\n }\n\n private _changeOptionEvent = new Task(this, {\n task: async ([evt, store]) => {\n if (!evt || !store) {\n return null;\n }\n\n // Ignore events matching this node's ignoreEvents list (works for DOM or context)\n if (this._isIgnoredSource(evt)) {\n return null;\n }\n\n this._collectFromTask(this._changeOptionEvent.taskComplete);\n\n let option: ProductOption | null | undefined = null;\n\n if (this.isActionEvent(evt)) {\n // Record event-driven attribute values (if any) so attribute task can skip\n this._pendingDevicesFromEvent = evt.detail?.devices;\n this._pendingSubscriptionFromEvent = evt.detail?.subscription;\n option = await this.__applyAction(evt.detail || {});\n }\n\n if (this.isBundleToogle(evt)) {\n option = await this.__applyBundle(evt.detail || {});\n }\n\n if (this.isDeltaUpdate(evt)) {\n option = await this._applyDeltaUpdate(evt.detail || {});\n }\n\n this._option = option;\n\n return option;\n },\n args: () => [this._event, this._store]\n });\n\n // Ensure datalayer is emitted if the callback becomes available slightly\n // after the first option was computed.\n private _fireDataLayerTask = new Task(this, {\n task: async ([opt, dl, evt]) => {\n if (this._sentDataLayer) return;\n if (opt && dl && evt) {\n dl({ option: opt, event: evt });\n this._sentDataLayer = true;\n }\n },\n args: () => [this._option, this._dataLayer, this.dataLayerEvent]\n });\n\n private _loadOptionByAttributes = new Task(this, {\n task: async ([devices, subscription]) => {\n const hasPendingDevices = this._pendingDevicesFromEvent !== undefined;\n const hasPendingSubscription = this._pendingSubscriptionFromEvent !== undefined;\n const matchesPendingDevices = !hasPendingDevices || devices === this._pendingDevicesFromEvent;\n const matchesPendingSubscription = !hasPendingSubscription || subscription === this._pendingSubscriptionFromEvent;\n\n // Skip only when current attribute values were just set by an event\n if (\n (hasPendingDevices || hasPendingSubscription)\n && matchesPendingDevices\n && matchesPendingSubscription\n ) {\n this._pendingDevicesFromEvent = undefined;\n this._pendingSubscriptionFromEvent = undefined;\n return this._option;\n }\n\n if (!this._option) {\n return null;\n }\n\n if (devices === undefined || subscription === undefined) {\n this._option = null;\n return null;\n }\n\n this._collectFromTask(this._loadOptionByAttributes.taskComplete);\n\n const option = await this.option?.getOption({ devices, subscription });\n\n this._option = option;\n return option;\n },\n args: () => [this.devices, this.subscription]\n });\n\n override getEtaArgs(): unknown[] {\n return [this._option, this.state, this.product, this._derived];\n }\n\n override async buildEtaContext(): Promise<object | undefined> {\n await this._changeOptionEvent.taskComplete;\n await this._loadOptionByAttributes.taskComplete;\n if (!this._option) return undefined;\n return await toDSLContext({ option: this._option, product: this.product, state: this.state, derived: this._derived });\n }\n\n connectedCallback() {\n super.connectedCallback();\n if (!this.noCollect) {\n this.collectOption({\n name : this.storeName,\n options: Promise.resolve(this._option ? [this._option] : [])\n });\n }\n }\n\n disconnectedCallback() {\n this.collectOption({\n name : this.storeName,\n options: null\n });\n super.disconnectedCallback();\n }\n\n protected async getUpdateComplete() {\n const result = await super.getUpdateComplete();\n await this._changeOptionEvent.taskComplete;\n await this._loadOptionByAttributes.taskComplete;\n await this._fireDataLayerTask.taskComplete;\n return result;\n }\n\n protected _eventChange(e: EventType): void {\n // Respect option-level ignore list\n if (this._isIgnoredSource(e)) {\n e.stopPropagation();\n return;\n }\n\n // Always capture locally\n this._eventDom = e;\n\n // Allow only product-change events to bubble up to <bd-product>\n if (this.isProductChange(e)) {\n return; // no stopPropagation → let it bubble\n }\n\n // Keep all other events scoped to this option\n e.stopPropagation();\n }\n\n private async _applyDeltaUpdate({\n type,\n delta,\n useAsValue,\n min = Number.MIN_SAFE_INTEGER,\n max = Number.MAX_SAFE_INTEGER\n }: UpdateByDelta) {\n const devices = useAsValue && type === \"devices\" ? Number(delta) : this.devices;\n const subscription = useAsValue && type === \"subscription\" ? Number(delta) : this.subscription;\n let option: ProductOption | undefined;\n\n if (useAsValue) {\n if (\n devices === undefined\n || subscription === undefined\n || Number.isNaN(devices)\n || Number.isNaN(subscription)\n ) {\n return null;\n }\n\n option = await this.option?.getOption({ devices, subscription });\n } else {\n option = await this.option?.nextOption(\n type === \"devices\" ?\n { devices: delta } :\n { subscription: delta }\n );\n }\n\n if (!option) {\n return null;\n }\n\n if (type === \"devices\" && (option.getDevices() < min || option.getDevices() > max)) {\n return null\n }\n\n if (type === \"subscription\" && (option.getSubscription() < min || option.getSubscription() > max)) {\n return null\n }\n\n this._syncOptionAttributes(option);\n return option;\n }\n\n private async __applyAction({ id, campaign, devices, subscription }: Action) {\n this.devices = devices ?? this.devices;\n this.subscription = subscription ?? this.subscription;\n\n if (this.devices === undefined || this.subscription === undefined) {\n return null;\n }\n\n if (id) {\n const product = await this._store?.getProduct({ id, campaign });\n return product?.getOption({\n devices : this.devices,\n subscription: this.subscription,\n bundle : this.option?.getBundle() || [] });\n }\n\n return this.option?.getOption({ devices: this.devices, subscription: this.subscription });\n }\n\n private async __applyBundle(option: Action) {\n const devices = option.devices ?? this.devices;\n const subscription = option.subscription ?? this.subscription;\n\n if (devices === undefined || subscription === undefined || !option.id) {\n return null\n }\n\n const productToBeBundled = await this._store?.getProduct({ id: option.id, campaign: option.campaign })\n\n const optionToBeBundled = await productToBeBundled?.getOption({ devices, subscription })\n\n if (!optionToBeBundled) {\n return null;\n }\n\n if (this.devices !== undefined && this.subscription !== undefined) {\n return this.option?.toogleBundle({\n devicesFixed : Boolean(option.devices),\n subscriptionFixed: Boolean(option.subscription),\n option : optionToBeBundled\n });\n }\n return null;\n }\n\n}\n"]}
1
+ {"version":3,"file":"node.option.js","sourceRoot":"","sources":["../../../src/nodes/node.option.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n extendBdOptionScope,\n type BdDataLayerEvent,\n type BdScope\n} from '@/contexts/context.scope.js';\nimport { BdActionResolveController } from '@/controllers/controller.action-resolve.js';\nimport type {\n Action,\n BdTransition\n} from '@/core/actions.js';\nimport { BdScopedElement } from '@/core/node.scope.js';\nimport { applyOptionUpdate } from '@/core/option-update.js';\nimport type { ProductOption } from '@repobit/dex-store';\nimport { property } from 'lit/decorators.js';\n\nexport class OptionNode extends BdScopedElement {\n @property({\n type : Number,\n reflect: true\n })\n devices?: number;\n\n @property({\n type : Number,\n reflect: true\n })\n subscription?: number;\n\n @property({\n attribute: false\n })\n option?: ProductOption;\n\n @property({\n attribute: 'data-layer-event'\n })\n dataLayerEvent?: BdDataLayerEvent;\n\n private _dataLayerSent = false;\n\n private readonly _workflow =\n new BdActionResolveController(\n this,\n {\n name: 'option',\n args: () => [\n this.parentScope,\n this.devices,\n this.subscription\n ] as const,\n transition: ([parentScope]) =>\n parentScope?.transition,\n derive: ([\n parentScope,\n devices,\n subscription\n ], { transition }) => {\n const action =\n transition?.command.kind === 'set-action'\n ? transition.command.action\n : undefined;\n\n const update =\n transition?.command.kind === 'update-by-delta'\n ? transition.command.update\n : undefined;\n\n return [\n parentScope,\n action?.devices ??\n applyOptionUpdate(\n 'devices',\n devices,\n update,\n parentScope?.product\n ),\n action?.subscription ??\n applyOptionUpdate(\n 'subscription',\n subscription,\n update,\n parentScope?.product\n )\n ] as const;\n },\n enabled: ([parentScope, devices, subscription]) =>\n Boolean(\n parentScope?.product &&\n typeof devices === 'number' &&\n typeof subscription === 'number'\n ),\n filterTransition: (candidate) =>\n this._filterTransition(candidate),\n resolve: async ([\n parentScope,\n devices,\n subscription\n ], _resolveContext, actionContext) => {\n if (\n !parentScope?.product ||\n typeof devices !== 'number' ||\n typeof subscription !== 'number'\n ) {\n return undefined;\n }\n\n return await resolveOption({\n parentScope,\n /**\n * Read the previously committed option via closure, NOT through\n * args(). Feeding currentScope.option back into args() makes the\n * resolver consume its own output and spin forever whenever resolve\n * returns a fresh ProductOption instance (e.g. bundles).\n */\n currentOption: this.option,\n devices,\n subscription,\n transition : actionContext.transition\n });\n },\n commit: (\n option,\n [parentScope],\n _resolveContext,\n actionContext\n ) => {\n if (!option || !parentScope) {\n this.option = undefined;\n this.setLocalOptionSeed(undefined);\n this.clearScope();\n return;\n }\n\n this.option = option;\n this.devices = option.getDevices();\n this.subscription = option.getSubscription();\n this.setLocalOptionSeed(option);\n\n this.publishScope(\n extendBdOptionScope(\n parentScope,\n option,\n actionContext.transition\n )\n );\n\n this.fireDataLayer();\n },\n onDisabled: () => {\n this.option = undefined;\n this.setLocalOptionSeed(undefined);\n this.clearScope();\n }\n }\n );\n\n get scope(): BdScope | undefined {\n return this.currentScope;\n }\n\n protected override updated(\n changedProperties: Map<PropertyKey, unknown>\n ): void {\n super.updated(changedProperties);\n\n if (\n changedProperties.has('dataLayerEvent') ||\n changedProperties.has('dataLayer')\n ) {\n this.fireDataLayer();\n }\n }\n\n private fireDataLayer(): void {\n const dataLayer = this.currentScope?.dataLayer;\n\n if (\n this._dataLayerSent ||\n !this.option ||\n !dataLayer ||\n this.dataLayerEvent === undefined\n ) {\n return;\n }\n\n dataLayer({\n option: this.option,\n event : this.dataLayerEvent\n });\n this._dataLayerSent = true;\n }\n}\n\nasync function resolveOption(\n params: Readonly<{\n parentScope : BdScope;\n currentOption?: ProductOption;\n devices : number;\n subscription : number;\n transition? : BdTransition;\n }>\n): Promise<ProductOption | undefined> {\n const action =\n params.transition?.command.kind === 'set-action'\n ? params.transition.command.action\n : undefined;\n\n if (action?.bundle && action.id) {\n return await resolveBundleOption(\n params,\n action\n );\n }\n\n if (\n params.currentOption &&\n params.currentOption.getProduct() === params.parentScope.product\n ) {\n return await params.currentOption.getOption({\n devices : params.devices,\n subscription: params.subscription\n });\n }\n\n return await params.parentScope.product?.getOption({\n devices : params.devices,\n subscription: params.subscription\n });\n}\n\nasync function resolveBundleOption(\n params: Readonly<{\n parentScope : BdScope;\n currentOption?: ProductOption;\n devices : number;\n subscription : number;\n }>,\n action: Action\n): Promise<ProductOption | undefined> {\n if (!action.id) {\n return undefined;\n }\n\n const reuseCurrentOption =\n params.currentOption !== undefined &&\n params.currentOption.getProduct() === params.parentScope.product;\n\n const baseOption =\n reuseCurrentOption\n ? params.currentOption\n : await params.parentScope.product?.getOption({\n devices : params.devices,\n subscription: params.subscription\n });\n\n if (!baseOption) {\n return undefined;\n }\n\n const bundleProduct =\n await params.parentScope.store?.getProduct({\n id : action.id,\n campaign: action.campaign\n });\n\n if (!bundleProduct) {\n return undefined;\n }\n\n const bundleDevices =\n action.devices ?? params.devices;\n\n const bundleSubscription =\n action.subscription ?? params.subscription;\n\n const bundleOption =\n await bundleProduct.getOption({\n devices : bundleDevices,\n subscription: bundleSubscription\n });\n\n if (!bundleOption) {\n return undefined;\n }\n\n return await baseOption.toogleBundle({\n option : bundleOption,\n devicesFixed : action.devices !== undefined,\n subscriptionFixed: action.subscription !== undefined\n });\n}\n"]}
@@ -1,15 +1,11 @@
1
- import type { Product } from "@repobit/dex-store";
2
- import { StateNode } from "./node.state.js";
3
- export declare class ProductNode extends StateNode {
4
- autoForward: boolean;
1
+ import { type BdScope } from '../contexts/context.scope.js';
2
+ import { BdScopedElement } from '../core/node.scope.js';
3
+ import type { Product } from '@repobit/dex-store';
4
+ export declare class ProductNode extends BdScopedElement {
5
5
  productId?: string;
6
6
  campaign?: string;
7
+ bundle: boolean;
7
8
  product?: Product;
8
- private _forwardAndNotify;
9
- private _productChangeEvent;
10
- private _forwardEventTask;
11
- private _loadProductTask;
12
- getEtaArgs(): unknown[];
13
- buildEtaContext(): Promise<object | undefined>;
14
- protected getUpdateComplete(): Promise<boolean>;
9
+ private readonly _workflow;
10
+ get scope(): BdScope | undefined;
15
11
  }