@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.
- package/CHANGELOG.md +6 -906
- package/README.md +308 -283
- package/dist/src/actions/action.adapter.d.ts +36 -0
- package/dist/src/actions/action.adapter.js +183 -0
- package/dist/src/actions/action.adapter.js.map +1 -0
- package/dist/src/actions/action.attributes.d.ts +15 -0
- package/dist/src/actions/action.attributes.js +137 -0
- package/dist/src/actions/action.attributes.js.map +1 -0
- package/dist/src/actions/action.registry.d.ts +4 -0
- package/dist/src/actions/action.registry.js +119 -0
- package/dist/src/actions/action.registry.js.map +1 -0
- package/dist/src/actions/index.d.ts +3 -2
- package/dist/src/actions/index.js +3 -80
- package/dist/src/actions/index.js.map +1 -1
- package/dist/src/compute/compute.expand.d.ts +70 -0
- package/dist/src/compute/compute.expand.js +319 -0
- package/dist/src/compute/compute.expand.js.map +1 -0
- package/dist/src/compute/compute.scan.d.ts +54 -0
- package/dist/src/compute/compute.scan.js +160 -0
- package/dist/src/compute/compute.scan.js.map +1 -0
- package/dist/src/compute/option-resolver.d.ts +31 -0
- package/dist/src/compute/option-resolver.js +147 -0
- package/dist/src/compute/option-resolver.js.map +1 -0
- package/dist/src/contexts/context.compute.d.ts +12 -0
- package/dist/src/contexts/context.compute.js +4 -0
- package/dist/src/contexts/context.compute.js.map +1 -0
- package/dist/src/contexts/context.scope.d.ts +139 -0
- package/dist/src/contexts/context.scope.js +48 -0
- package/dist/src/contexts/context.scope.js.map +1 -0
- package/dist/src/controllers/controller.action-resolve.d.ts +110 -0
- package/dist/src/controllers/controller.action-resolve.js +203 -0
- package/dist/src/controllers/controller.action-resolve.js.map +1 -0
- package/dist/src/controllers/controller.action-topology.d.ts +59 -0
- package/dist/src/controllers/controller.action-topology.js +130 -0
- package/dist/src/controllers/controller.action-topology.js.map +1 -0
- package/dist/src/controllers/controller.compute.d.ts +72 -0
- package/dist/src/controllers/controller.compute.js +110 -0
- package/dist/src/controllers/controller.compute.js.map +1 -0
- package/dist/src/controllers/controller.resolve.d.ts +78 -0
- package/dist/src/controllers/controller.resolve.js +205 -0
- package/dist/src/controllers/controller.resolve.js.map +1 -0
- package/dist/src/core/action-topology.d.ts +62 -0
- package/dist/src/core/action-topology.js +67 -0
- package/dist/src/core/action-topology.js.map +1 -0
- package/dist/src/core/actions.d.ts +64 -0
- package/dist/src/core/actions.js +47 -0
- package/dist/src/core/actions.js.map +1 -0
- package/dist/src/core/node.element.d.ts +179 -0
- package/dist/src/core/node.element.js +573 -0
- package/dist/src/core/node.element.js.map +1 -0
- package/dist/src/core/node.scope.d.ts +374 -0
- package/dist/src/core/node.scope.js +558 -0
- package/dist/src/core/node.scope.js.map +1 -0
- package/dist/src/core/option-update.d.ts +11 -0
- package/dist/src/core/option-update.js +59 -0
- package/dist/src/core/option-update.js.map +1 -0
- package/dist/src/dsl/compilers/array/compiler.js +13 -14
- package/dist/src/dsl/compilers/array/compiler.js.map +1 -1
- package/dist/src/dsl/compilers/boolean/compiler.d.ts +1 -1
- package/dist/src/dsl/compilers/boolean/compiler.js +14 -27
- package/dist/src/dsl/compilers/boolean/compiler.js.map +1 -1
- package/dist/src/dsl/compilers/enum/compiler.js +7 -10
- package/dist/src/dsl/compilers/enum/compiler.js.map +1 -1
- package/dist/src/dsl/compilers/index.d.ts +1 -1
- package/dist/src/dsl/compilers/index.js +5 -5
- package/dist/src/dsl/compilers/index.js.map +1 -1
- package/dist/src/dsl/utilty.d.ts +0 -4
- package/dist/src/dsl/utilty.js +3 -30
- package/dist/src/dsl/utilty.js.map +1 -1
- package/dist/src/eta/batch.d.ts +123 -0
- package/dist/src/eta/batch.js +162 -0
- package/dist/src/eta/batch.js.map +1 -0
- package/dist/src/eta/batcher.d.ts +184 -0
- package/dist/src/eta/batcher.js +335 -0
- package/dist/src/eta/batcher.js.map +1 -0
- package/dist/src/eta/cache.d.ts +36 -0
- package/dist/src/eta/cache.js +56 -0
- package/dist/src/eta/cache.js.map +1 -0
- package/dist/src/eta/controller.d.ts +608 -0
- package/dist/src/eta/controller.js +1036 -0
- package/dist/src/eta/controller.js.map +1 -0
- package/dist/src/eta/factory.d.ts +74 -0
- package/dist/src/eta/factory.js +121 -0
- package/dist/src/eta/factory.js.map +1 -0
- package/dist/src/eta/idle.d.ts +39 -0
- package/dist/src/eta/idle.js +52 -0
- package/dist/src/eta/idle.js.map +1 -0
- package/dist/src/eta/index.d.ts +52 -0
- package/dist/src/eta/index.js +13 -0
- package/dist/src/eta/index.js.map +1 -0
- package/dist/src/eta/observer.d.ts +263 -0
- package/dist/src/eta/observer.js +263 -0
- package/dist/src/eta/observer.js.map +1 -0
- package/dist/src/eta/operations.d.ts +41 -0
- package/dist/src/eta/operations.js +59 -0
- package/dist/src/eta/operations.js.map +1 -0
- package/dist/src/eta/source-registry.d.ts +198 -0
- package/dist/src/eta/source-registry.js +267 -0
- package/dist/src/eta/source-registry.js.map +1 -0
- package/dist/src/eta/template-index.d.ts +285 -0
- package/dist/src/eta/template-index.js +642 -0
- package/dist/src/eta/template-index.js.map +1 -0
- package/dist/src/eta/types.d.ts +529 -0
- package/dist/src/eta/types.js +2 -0
- package/dist/src/eta/types.js.map +1 -0
- package/dist/src/index.d.ts +21 -9
- package/dist/src/index.js +22 -11
- package/dist/src/index.js.map +1 -1
- package/dist/src/nodes/node.context.d.ts +5 -3
- package/dist/src/nodes/node.context.js +48 -3
- package/dist/src/nodes/node.context.js.map +1 -1
- package/dist/src/nodes/node.option.d.ts +11 -31
- package/dist/src/nodes/node.option.js +158 -222
- package/dist/src/nodes/node.option.js.map +1 -1
- package/dist/src/nodes/node.product.d.ts +7 -11
- package/dist/src/nodes/node.product.js +85 -64
- package/dist/src/nodes/node.product.js.map +1 -1
- package/dist/src/renders/attributes/buyLink.d.ts +2 -2
- package/dist/src/renders/attributes/buyLink.js +14 -11
- package/dist/src/renders/attributes/buyLink.js.map +1 -1
- package/dist/src/renders/attributes/devices.d.ts +2 -2
- package/dist/src/renders/attributes/devices.js +9 -19
- package/dist/src/renders/attributes/devices.js.map +1 -1
- package/dist/src/renders/attributes/discount.d.ts +2 -2
- package/dist/src/renders/attributes/discount.js +56 -44
- package/dist/src/renders/attributes/discount.js.map +1 -1
- package/dist/src/renders/attributes/hide.d.ts +2 -2
- package/dist/src/renders/attributes/hide.js +49 -14
- package/dist/src/renders/attributes/hide.js.map +1 -1
- package/dist/src/renders/attributes/index.d.ts +3 -3
- package/dist/src/renders/attributes/index.js +2 -4
- package/dist/src/renders/attributes/index.js.map +1 -1
- package/dist/src/renders/attributes/price.d.ts +2 -2
- package/dist/src/renders/attributes/price.js +30 -44
- package/dist/src/renders/attributes/price.js.map +1 -1
- package/dist/src/renders/attributes/subscription.d.ts +2 -2
- package/dist/src/renders/attributes/subscription.js +14 -20
- package/dist/src/renders/attributes/subscription.js.map +1 -1
- package/dist/src/renders/attributes/utilty.d.ts +2 -0
- package/dist/src/renders/attributes/utilty.js +17 -4
- package/dist/src/renders/attributes/utilty.js.map +1 -1
- package/dist/src/renders/context.d.ts +122 -10
- package/dist/src/renders/context.js +140 -80
- package/dist/src/renders/context.js.map +1 -1
- package/dist/src/renders/format.js +2 -2
- package/dist/src/renders/format.js.map +1 -1
- package/dist/src/renders/index.d.ts +6 -2
- package/dist/src/renders/index.js +67 -29
- package/dist/src/renders/index.js.map +1 -1
- package/dist/src/renders/observe.d.ts +1 -4
- package/dist/src/renders/observe.js +10 -24
- package/dist/src/renders/observe.js.map +1 -1
- package/dist/src/renders/render.wrapper.d.ts +37 -0
- package/dist/src/renders/render.wrapper.js +147 -0
- package/dist/src/renders/render.wrapper.js.map +1 -0
- package/dist/src/templating/eta.js +1 -4
- package/dist/src/templating/eta.js.map +1 -1
- package/package.json +4 -5
- package/dist/src/actions/action.button.d.ts +0 -2
- package/dist/src/actions/action.button.js +0 -8
- package/dist/src/actions/action.button.js.map +0 -1
- package/dist/src/actions/action.input.d.ts +0 -2
- package/dist/src/actions/action.input.js +0 -43
- package/dist/src/actions/action.input.js.map +0 -1
- package/dist/src/actions/action.select.d.ts +0 -2
- package/dist/src/actions/action.select.js +0 -14
- package/dist/src/actions/action.select.js.map +0 -1
- package/dist/src/actions/utilty.d.ts +0 -16
- package/dist/src/actions/utilty.js +0 -149
- package/dist/src/actions/utilty.js.map +0 -1
- package/dist/src/contexts/context.datalayer.d.ts +0 -9
- package/dist/src/contexts/context.datalayer.js +0 -3
- package/dist/src/contexts/context.datalayer.js.map +0 -1
- package/dist/src/contexts/context.derived.d.ts +0 -12
- package/dist/src/contexts/context.derived.js +0 -3
- package/dist/src/contexts/context.derived.js.map +0 -1
- package/dist/src/contexts/context.option.d.ts +0 -5
- package/dist/src/contexts/context.option.js +0 -3
- package/dist/src/contexts/context.option.js.map +0 -1
- package/dist/src/contexts/context.product.d.ts +0 -5
- package/dist/src/contexts/context.product.js +0 -3
- package/dist/src/contexts/context.product.js.map +0 -1
- package/dist/src/contexts/context.state.d.ts +0 -28
- package/dist/src/contexts/context.state.js +0 -3
- package/dist/src/contexts/context.state.js.map +0 -1
- package/dist/src/contexts/context.store.d.ts +0 -5
- package/dist/src/contexts/context.store.js +0 -3
- package/dist/src/contexts/context.store.js.map +0 -1
- package/dist/src/controllers/collect-controller.d.ts +0 -39
- package/dist/src/controllers/collect-controller.js +0 -161
- package/dist/src/controllers/collect-controller.js.map +0 -1
- package/dist/src/controllers/compute-controller.d.ts +0 -55
- package/dist/src/controllers/compute-controller.js +0 -350
- package/dist/src/controllers/compute-controller.js.map +0 -1
- package/dist/src/controllers/eta-renderer/eta-dom-renderer.d.ts +0 -25
- package/dist/src/controllers/eta-renderer/eta-dom-renderer.js +0 -192
- package/dist/src/controllers/eta-renderer/eta-dom-renderer.js.map +0 -1
- package/dist/src/controllers/eta-renderer/eta-mutation-observer.d.ts +0 -28
- package/dist/src/controllers/eta-renderer/eta-mutation-observer.js +0 -206
- package/dist/src/controllers/eta-renderer/eta-mutation-observer.js.map +0 -1
- package/dist/src/controllers/eta-renderer/eta-renderer.d.ts +0 -21
- package/dist/src/controllers/eta-renderer/eta-renderer.js +0 -77
- package/dist/src/controllers/eta-renderer/eta-renderer.js.map +0 -1
- package/dist/src/controllers/eta-renderer/eta-template-cache.d.ts +0 -24
- package/dist/src/controllers/eta-renderer/eta-template-cache.js +0 -61
- package/dist/src/controllers/eta-renderer/eta-template-cache.js.map +0 -1
- package/dist/src/controllers/eta-renderer/eta-types.d.ts +0 -11
- package/dist/src/controllers/eta-renderer/eta-types.js +0 -1
- package/dist/src/controllers/eta-renderer/eta-types.js.map +0 -1
- package/dist/src/controllers/eta-renderer/index.d.ts +0 -2
- package/dist/src/controllers/eta-renderer/index.js +0 -2
- package/dist/src/controllers/eta-renderer/index.js.map +0 -1
- package/dist/src/controllers/event-pipeline-controller.d.ts +0 -28
- package/dist/src/controllers/event-pipeline-controller.js +0 -72
- package/dist/src/controllers/event-pipeline-controller.js.map +0 -1
- package/dist/src/events/events.d.ts +0 -75
- package/dist/src/events/events.js +0 -78
- package/dist/src/events/events.js.map +0 -1
- package/dist/src/nodes/node.root.d.ts +0 -16
- package/dist/src/nodes/node.root.js +0 -49
- package/dist/src/nodes/node.root.js.map +0 -1
- package/dist/src/nodes/node.state.d.ts +0 -88
- package/dist/src/nodes/node.state.js +0 -330
- package/dist/src/nodes/node.state.js.map +0 -1
- package/dist/src/renders/utility.d.ts +0 -32
- package/dist/src/renders/utility.js +0 -191
- package/dist/src/renders/utility.js.map +0 -1
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { BD_ACTION_REQUEST_EVENT, createBdTransition, isBdActionRequestEvent } from '../core/actions.js';
|
|
2
|
+
import { BdResolveController } from './controller.resolve.js';
|
|
3
|
+
/**
|
|
4
|
+
* Node workflow controller for the common bd runtime pattern:
|
|
5
|
+
*
|
|
6
|
+
* base args + fresh transition -> derived resolver args
|
|
7
|
+
* enabled -> resolve -> commit
|
|
8
|
+
* mark transition committed only after successful commit
|
|
9
|
+
*
|
|
10
|
+
* It keeps raw DOM requests out of node code and keeps transition seq
|
|
11
|
+
* bookkeeping out of every concrete resolver.
|
|
12
|
+
*/
|
|
13
|
+
export class BdActionResolveController {
|
|
14
|
+
constructor(host, options) {
|
|
15
|
+
this.host = host;
|
|
16
|
+
this.options = options;
|
|
17
|
+
this._lastCommittedTransitionSeq = 0;
|
|
18
|
+
this._listening = false;
|
|
19
|
+
this._onActionRequest = (event) => {
|
|
20
|
+
if (!isBdActionRequestEvent(event)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
event.preventDefault();
|
|
24
|
+
event.stopPropagation();
|
|
25
|
+
const transition = this.options.createTransition?.(event.detail, event) ??
|
|
26
|
+
createBdTransition(event.detail, event.target);
|
|
27
|
+
const filter = this.options.filterTransition;
|
|
28
|
+
if (filter &&
|
|
29
|
+
!filter({
|
|
30
|
+
transition,
|
|
31
|
+
source: 'local'
|
|
32
|
+
})) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this._localTransition = transition;
|
|
36
|
+
this.host.requestUpdate();
|
|
37
|
+
};
|
|
38
|
+
host.addController(this);
|
|
39
|
+
this._resolver = new BdResolveController(host, {
|
|
40
|
+
name: options.name,
|
|
41
|
+
workKey: options.workKey,
|
|
42
|
+
autoRun: options.autoRun,
|
|
43
|
+
abortOnDisconnect: options.abortOnDisconnect,
|
|
44
|
+
args: () => this._args(),
|
|
45
|
+
argsEqual: (oldArgs, newArgs) => this._argsEqual(oldArgs, newArgs),
|
|
46
|
+
enabled: ([args, context]) => options.enabled?.(args, context) ?? true,
|
|
47
|
+
resolve: ([args, actionContext], resolveContext) => options.resolve(args, resolveContext, actionContext),
|
|
48
|
+
commit: async (result, [args, actionContext], resolveContext) => {
|
|
49
|
+
const commitResult = options.commit?.(result, args, resolveContext, actionContext);
|
|
50
|
+
if (isPromiseLike(commitResult)) {
|
|
51
|
+
await commitResult;
|
|
52
|
+
}
|
|
53
|
+
this._markTransitionCommitted(actionContext);
|
|
54
|
+
},
|
|
55
|
+
onPending: ([args, actionContext], resolveContext) => options.onPending?.(args, resolveContext, actionContext),
|
|
56
|
+
onDisabled: ([args, actionContext], resolveContext) => options.onDisabled?.(args, resolveContext, actionContext),
|
|
57
|
+
onComplete: (result, [args, actionContext], resolveContext) => options.onComplete?.(result, args, resolveContext, actionContext),
|
|
58
|
+
onError: (error, [args, actionContext], resolveContext) => options.onError?.(error, args, resolveContext, actionContext),
|
|
59
|
+
onHookError: options.onHookError
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
hostConnected() {
|
|
63
|
+
if (this.options.captureActions === false) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (this._listening) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this.host.addEventListener(BD_ACTION_REQUEST_EVENT, this._onActionRequest);
|
|
70
|
+
this._listening = true;
|
|
71
|
+
}
|
|
72
|
+
hostDisconnected() {
|
|
73
|
+
if (!this._listening) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
this.host.removeEventListener(BD_ACTION_REQUEST_EVENT, this._onActionRequest);
|
|
77
|
+
this._listening = false;
|
|
78
|
+
}
|
|
79
|
+
get status() {
|
|
80
|
+
return this._resolver.status;
|
|
81
|
+
}
|
|
82
|
+
get value() {
|
|
83
|
+
return this._resolver.value;
|
|
84
|
+
}
|
|
85
|
+
get error() {
|
|
86
|
+
return this._resolver.error;
|
|
87
|
+
}
|
|
88
|
+
get pending() {
|
|
89
|
+
return this._resolver.pending;
|
|
90
|
+
}
|
|
91
|
+
get complete() {
|
|
92
|
+
return this._resolver.complete;
|
|
93
|
+
}
|
|
94
|
+
get disabled() {
|
|
95
|
+
return this._resolver.disabled;
|
|
96
|
+
}
|
|
97
|
+
get failed() {
|
|
98
|
+
return this._resolver.failed;
|
|
99
|
+
}
|
|
100
|
+
get localTransition() {
|
|
101
|
+
return this._localTransition;
|
|
102
|
+
}
|
|
103
|
+
run() {
|
|
104
|
+
return this._resolver.run();
|
|
105
|
+
}
|
|
106
|
+
abort(reason) {
|
|
107
|
+
this._localTransition = undefined;
|
|
108
|
+
this._resolver.abort(reason);
|
|
109
|
+
}
|
|
110
|
+
_args() {
|
|
111
|
+
const baseArgs = this.options.args();
|
|
112
|
+
const context = this._createActionContext(baseArgs);
|
|
113
|
+
const derivedArgs = this.options.derive(baseArgs, context);
|
|
114
|
+
return [
|
|
115
|
+
derivedArgs,
|
|
116
|
+
context
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
_createActionContext(args) {
|
|
120
|
+
const candidate = this._selectTransitionCandidate(args);
|
|
121
|
+
if (!candidate ||
|
|
122
|
+
candidate.transition.seq <= this._lastCommittedTransitionSeq) {
|
|
123
|
+
return {
|
|
124
|
+
freshTransition: false
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
transition: candidate.transition,
|
|
129
|
+
transitionSeq: candidate.transition.seq,
|
|
130
|
+
transitionSource: candidate.source,
|
|
131
|
+
freshTransition: true
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
_selectTransitionCandidate(args) {
|
|
135
|
+
const filter = this.options.filterTransition;
|
|
136
|
+
const localCandidate = this._localTransition
|
|
137
|
+
? {
|
|
138
|
+
transition: this._localTransition,
|
|
139
|
+
source: 'local'
|
|
140
|
+
}
|
|
141
|
+
: undefined;
|
|
142
|
+
const parentTransition = this.options.transition?.(args);
|
|
143
|
+
const parentCandidate = parentTransition
|
|
144
|
+
? {
|
|
145
|
+
transition: parentTransition,
|
|
146
|
+
source: 'parent'
|
|
147
|
+
}
|
|
148
|
+
: undefined;
|
|
149
|
+
const candidates = [];
|
|
150
|
+
if (localCandidate && (!filter || filter(localCandidate))) {
|
|
151
|
+
candidates.push(localCandidate);
|
|
152
|
+
}
|
|
153
|
+
if (parentCandidate && (!filter || filter(parentCandidate))) {
|
|
154
|
+
candidates.push(parentCandidate);
|
|
155
|
+
}
|
|
156
|
+
if (candidates.length === 0) {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
return candidates.reduce((latest, current) => current.transition.seq >= latest.transition.seq ? current : latest);
|
|
160
|
+
}
|
|
161
|
+
_argsEqual(oldArgs, newArgs) {
|
|
162
|
+
const [oldDerivedArgs, oldContext] = oldArgs;
|
|
163
|
+
const [newDerivedArgs, newContext] = newArgs;
|
|
164
|
+
if (newContext.freshTransition &&
|
|
165
|
+
newContext.transitionSeq !== oldContext.transitionSeq) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return (this.options.argsEqual?.(oldDerivedArgs, newDerivedArgs) ??
|
|
169
|
+
shallowArrayEqual(oldDerivedArgs, newDerivedArgs));
|
|
170
|
+
}
|
|
171
|
+
_markTransitionCommitted(context) {
|
|
172
|
+
const transition = context.transition;
|
|
173
|
+
if (!transition || !context.freshTransition) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this._lastCommittedTransitionSeq = Math.max(this._lastCommittedTransitionSeq, transition.seq);
|
|
177
|
+
if (this._localTransition === transition) {
|
|
178
|
+
this._localTransition = undefined;
|
|
179
|
+
}
|
|
180
|
+
this.host.requestUpdate();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function shallowArrayEqual(oldArgs, newArgs) {
|
|
184
|
+
if (oldArgs === newArgs) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
if (oldArgs.length !== newArgs.length) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
for (let index = 0; index < oldArgs.length; index += 1) {
|
|
191
|
+
if (!Object.is(oldArgs[index], newArgs[index])) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
function isPromiseLike(value) {
|
|
198
|
+
return (typeof value === 'object' &&
|
|
199
|
+
value !== null &&
|
|
200
|
+
'then' in value &&
|
|
201
|
+
typeof value.then === 'function');
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=controller.action-resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.action-resolve.js","sourceRoot":"","sources":["../../../src/controllers/controller.action-resolve.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReactiveController } from 'lit';\n\nimport {\n BD_ACTION_REQUEST_EVENT,\n createBdTransition,\n isBdActionRequestEvent,\n type BdActionRequestDetail,\n type BdTransition\n} from '@/core/actions.js';\nimport {\n BdResolveController,\n type BdResolveContext,\n type BdResolveHookPhase,\n type BdResolveHost,\n type BdResolveStatus,\n type BdWorkKey,\n type MaybePromise\n} from './controller.resolve.js';\n\nexport type BdActionResolveTransitionSource =\n | 'local'\n | 'parent';\n\nexport type BdActionResolveContext = Readonly<{\n /**\n * The transition passed to derive/resolve/commit.\n *\n * This is only set for a fresh transition. Once the controller marks a\n * transition committed, the same transition is suppressed from future args.\n */\n transition?: BdTransition;\n\n transitionSeq? : number;\n transitionSource?: BdActionResolveTransitionSource;\n freshTransition : boolean;\n}>;\n\nexport interface BdActionResolveHost extends BdResolveHost, EventTarget {}\n\nexport interface BdActionResolveOptions<\n TArgs extends readonly unknown[],\n TDerivedArgs extends readonly unknown[],\n TResult\n> {\n name? : string;\n workKey?: BdWorkKey;\n\n /**\n * Base node inputs. Keep this close to @lit/task naming.\n *\n * Examples:\n * () => [this.parentScope, this.devices, this.subscription] as const\n */\n args: () => TArgs;\n\n /**\n * Optional downward transition source, usually parentScope.transition.\n *\n * Local bd-action-request events captured by this controller are considered\n * alongside this transition, with the latest seq winning.\n */\n transition?: (args: TArgs) => BdTransition | undefined;\n\n /**\n * Converts base args + a fresh transition into the actual resolver args.\n *\n * This should be pure. It must not publish scope or mutate host props.\n */\n derive: (\n args: TArgs,\n context: BdActionResolveContext\n ) => TDerivedArgs;\n\n enabled?: (\n args: TDerivedArgs,\n context: BdActionResolveContext\n ) => boolean;\n\n argsEqual?: (\n oldArgs: TDerivedArgs,\n newArgs: TDerivedArgs\n ) => boolean;\n\n autoRun?: boolean | 'afterUpdate';\n\n resolve: (\n args: TDerivedArgs,\n resolveContext: BdResolveContext,\n actionContext: BdActionResolveContext\n ) => MaybePromise<TResult>;\n\n commit?: (\n result: TResult,\n args: TDerivedArgs,\n resolveContext: BdResolveContext,\n actionContext: BdActionResolveContext\n ) => MaybePromise<void>;\n\n onPending?: (\n args: TDerivedArgs,\n resolveContext: BdResolveContext,\n actionContext: BdActionResolveContext\n ) => MaybePromise<void>;\n\n onDisabled?: (\n args: TDerivedArgs,\n resolveContext: BdResolveContext,\n actionContext: BdActionResolveContext\n ) => MaybePromise<void>;\n\n onComplete?: (\n result: TResult,\n args: TDerivedArgs,\n resolveContext: BdResolveContext,\n actionContext: BdActionResolveContext\n ) => MaybePromise<void>;\n\n onError?: (\n error: unknown,\n args: TDerivedArgs,\n resolveContext: BdResolveContext,\n actionContext: BdActionResolveContext\n ) => MaybePromise<void>;\n\n onHookError?: (\n error: unknown,\n phase: BdResolveHookPhase\n ) => void;\n\n abortOnDisconnect?: boolean;\n\n /**\n * If false, this controller only consumes transitions supplied by options.transition.\n */\n captureActions?: boolean;\n\n createTransition?: (\n detail: BdActionRequestDetail,\n event: CustomEvent<BdActionRequestDetail>\n ) => BdTransition;\n\n /**\n * Optional predicate consulted for every transition candidate (both\n * local `bd-action-request` events and parent cascades).\n *\n * Return `false` to drop the candidate; the controller will not feed it\n * into `derive` / `resolve` / `commit`. The host typically uses this to\n * honour the `ignore-events` and `ignore-events-parent` attributes on\n * `bd-*` provider elements.\n */\n filterTransition?: (\n candidate: TransitionCandidate\n ) => boolean;\n}\n\ntype BdActionResolveInternalArgs<\n TDerivedArgs extends readonly unknown[]\n> = readonly [\n args: TDerivedArgs,\n context: BdActionResolveContext\n];\n\ntype TransitionCandidate = Readonly<{\n transition: BdTransition;\n source : BdActionResolveTransitionSource;\n}>;\n\n/**\n * Node workflow controller for the common bd runtime pattern:\n *\n * base args + fresh transition -> derived resolver args\n * enabled -> resolve -> commit\n * mark transition committed only after successful commit\n *\n * It keeps raw DOM requests out of node code and keeps transition seq\n * bookkeeping out of every concrete resolver.\n */\nexport class BdActionResolveController<\n TArgs extends readonly unknown[],\n TDerivedArgs extends readonly unknown[],\n TResult\n> implements ReactiveController {\n private readonly _resolver: BdResolveController<\n BdActionResolveInternalArgs<TDerivedArgs>,\n TResult\n >;\n\n private _localTransition?: BdTransition;\n private _lastCommittedTransitionSeq = 0;\n private _listening = false;\n\n constructor(\n private readonly host: BdActionResolveHost,\n private readonly options:\n BdActionResolveOptions<TArgs, TDerivedArgs, TResult>\n ) {\n host.addController(this);\n\n this._resolver = new BdResolveController(host, {\n name : options.name,\n workKey : options.workKey,\n autoRun : options.autoRun,\n abortOnDisconnect: options.abortOnDisconnect,\n args : () => this._args(),\n argsEqual : (oldArgs, newArgs) =>\n this._argsEqual(\n oldArgs,\n newArgs\n ),\n enabled: ([args, context]) =>\n options.enabled?.(\n args,\n context\n ) ?? true,\n resolve: ([args, actionContext], resolveContext) =>\n options.resolve(\n args,\n resolveContext,\n actionContext\n ),\n commit: async (\n result,\n [args, actionContext],\n resolveContext\n ) => {\n const commitResult =\n options.commit?.(\n result,\n args,\n resolveContext,\n actionContext\n );\n\n if (isPromiseLike(commitResult)) {\n await commitResult;\n }\n\n this._markTransitionCommitted(actionContext);\n },\n onPending: ([args, actionContext], resolveContext) =>\n options.onPending?.(\n args,\n resolveContext,\n actionContext\n ),\n onDisabled: ([args, actionContext], resolveContext) =>\n options.onDisabled?.(\n args,\n resolveContext,\n actionContext\n ),\n onComplete: (\n result,\n [args, actionContext],\n resolveContext\n ) =>\n options.onComplete?.(\n result,\n args,\n resolveContext,\n actionContext\n ),\n onError: (\n error,\n [args, actionContext],\n resolveContext\n ) =>\n options.onError?.(\n error,\n args,\n resolveContext,\n actionContext\n ),\n onHookError: options.onHookError\n });\n }\n\n hostConnected(): void {\n if (this.options.captureActions === false) {\n return;\n }\n\n if (this._listening) {\n return;\n }\n\n this.host.addEventListener(\n BD_ACTION_REQUEST_EVENT,\n this._onActionRequest as EventListener\n );\n\n this._listening = true;\n }\n\n hostDisconnected(): void {\n if (!this._listening) {\n return;\n }\n\n this.host.removeEventListener(\n BD_ACTION_REQUEST_EVENT,\n this._onActionRequest as EventListener\n );\n\n this._listening = false;\n }\n\n get status(): BdResolveStatus {\n return this._resolver.status;\n }\n\n get value(): TResult | undefined {\n return this._resolver.value;\n }\n\n get error(): unknown {\n return this._resolver.error;\n }\n\n get pending(): boolean {\n return this._resolver.pending;\n }\n\n get complete(): boolean {\n return this._resolver.complete;\n }\n\n get disabled(): boolean {\n return this._resolver.disabled;\n }\n\n get failed(): boolean {\n return this._resolver.failed;\n }\n\n get localTransition(): BdTransition | undefined {\n return this._localTransition;\n }\n\n run(): Promise<TResult | undefined> {\n return this._resolver.run();\n }\n\n abort(reason?: unknown): void {\n this._localTransition = undefined;\n this._resolver.abort(reason);\n }\n\n private _args(): BdActionResolveInternalArgs<TDerivedArgs> {\n const baseArgs =\n this.options.args();\n\n const context =\n this._createActionContext(baseArgs);\n\n const derivedArgs =\n this.options.derive(\n baseArgs,\n context\n );\n\n return [\n derivedArgs,\n context\n ] as const;\n }\n\n private _createActionContext(\n args: TArgs\n ): BdActionResolveContext {\n const candidate =\n this._selectTransitionCandidate(args);\n\n if (\n !candidate ||\n candidate.transition.seq <= this._lastCommittedTransitionSeq\n ) {\n return {\n freshTransition: false\n };\n }\n\n return {\n transition : candidate.transition,\n transitionSeq : candidate.transition.seq,\n transitionSource: candidate.source,\n freshTransition : true\n };\n }\n\n private _selectTransitionCandidate(\n args: TArgs\n ): TransitionCandidate | undefined {\n const filter = this.options.filterTransition;\n\n const localCandidate =\n this._localTransition\n ? {\n transition: this._localTransition,\n source : 'local' as const\n }\n : undefined;\n\n const parentTransition =\n this.options.transition?.(args);\n\n const parentCandidate =\n parentTransition\n ? {\n transition: parentTransition,\n source : 'parent' as const\n }\n : undefined;\n\n const candidates: TransitionCandidate[] = [];\n\n if (localCandidate && (!filter || filter(localCandidate))) {\n candidates.push(localCandidate);\n }\n\n if (parentCandidate && (!filter || filter(parentCandidate))) {\n candidates.push(parentCandidate);\n }\n\n if (candidates.length === 0) {\n return undefined;\n }\n\n return candidates.reduce((latest, current) =>\n current.transition.seq >= latest.transition.seq ? current : latest\n );\n }\n\n private _argsEqual(\n oldArgs: BdActionResolveInternalArgs<TDerivedArgs>,\n newArgs: BdActionResolveInternalArgs<TDerivedArgs>\n ): boolean {\n const [oldDerivedArgs, oldContext] = oldArgs;\n const [newDerivedArgs, newContext] = newArgs;\n\n if (\n newContext.freshTransition &&\n newContext.transitionSeq !== oldContext.transitionSeq\n ) {\n return false;\n }\n\n return (\n this.options.argsEqual?.(\n oldDerivedArgs,\n newDerivedArgs\n ) ??\n shallowArrayEqual(\n oldDerivedArgs,\n newDerivedArgs\n )\n );\n }\n\n private _markTransitionCommitted(\n context: BdActionResolveContext\n ): void {\n const transition = context.transition;\n\n if (!transition || !context.freshTransition) {\n return;\n }\n\n this._lastCommittedTransitionSeq = Math.max(\n this._lastCommittedTransitionSeq,\n transition.seq\n );\n\n if (this._localTransition === transition) {\n this._localTransition = undefined;\n }\n\n this.host.requestUpdate();\n }\n\n private readonly _onActionRequest = (\n event: Event\n ): void => {\n if (!isBdActionRequestEvent(event)) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n const transition =\n this.options.createTransition?.(\n event.detail,\n event\n ) ??\n createBdTransition(\n event.detail,\n event.target\n );\n\n const filter = this.options.filterTransition;\n\n if (\n filter &&\n !filter({\n transition,\n source: 'local'\n })\n ) {\n return;\n }\n\n this._localTransition = transition;\n\n this.host.requestUpdate();\n };\n}\n\nfunction shallowArrayEqual(\n oldArgs: readonly unknown[],\n newArgs: readonly unknown[]\n): boolean {\n if (oldArgs === newArgs) {\n return true;\n }\n\n if (oldArgs.length !== newArgs.length) {\n return false;\n }\n\n for (let index = 0; index < oldArgs.length; index += 1) {\n if (!Object.is(\n oldArgs[index],\n newArgs[index]\n )) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction isPromiseLike<T>(\n value: MaybePromise<T> | undefined\n): value is Promise<T> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'then' in value &&\n typeof value.then === 'function'\n );\n}\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
|
+
import { type BdComputeScan } from '../compute/compute.scan.js';
|
|
3
|
+
import type { ProductOption } from '@repobit/dex-store';
|
|
4
|
+
export interface BdActionTopologyHost extends ReactiveControllerHost, EventTarget {
|
|
5
|
+
readonly topologyBoundary?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Owns the set of native action elements that belong to a single bd node.
|
|
9
|
+
*
|
|
10
|
+
* Membership is fed incrementally by BdActionElementAdapter announcements, so
|
|
11
|
+
* no node ever rescans its DOM children. The nearest bd node catches
|
|
12
|
+
* bd-action-connect / bd-action-disconnect, exactly like bd-action-request, so
|
|
13
|
+
* an action's compute radius matches its runtime radius.
|
|
14
|
+
*
|
|
15
|
+
* Aggregation across the logical bd subtree is intentionally NOT done here. The
|
|
16
|
+
* owning element walks its bd children (which it has access to) and unions
|
|
17
|
+
* their local sets. This controller only owns local membership + a revision
|
|
18
|
+
* that already reflects descendant changes via the bubbling topology event.
|
|
19
|
+
*/
|
|
20
|
+
export declare class BdActionTopologyController implements ReactiveController {
|
|
21
|
+
private readonly host;
|
|
22
|
+
private readonly _localScans;
|
|
23
|
+
private _localOptionSeed?;
|
|
24
|
+
private _revision;
|
|
25
|
+
private _listening;
|
|
26
|
+
constructor(host: BdActionTopologyHost);
|
|
27
|
+
/**
|
|
28
|
+
* Bumped whenever this node's local set changes OR any descendant bd node's
|
|
29
|
+
* set changes (the change event bubbles through here). Use this as a compute
|
|
30
|
+
* input so a node recomputes when anything in its subtree changes.
|
|
31
|
+
*/
|
|
32
|
+
get revision(): number;
|
|
33
|
+
get localElements(): readonly HTMLElement[];
|
|
34
|
+
get localActionScans(): readonly BdComputeScan[];
|
|
35
|
+
get localOptionSeed(): ProductOption | undefined;
|
|
36
|
+
setLocalOptionSeed(option: ProductOption | undefined): void;
|
|
37
|
+
/**
|
|
38
|
+
* Signal that this node's logical subtree shape changed (a bd child node
|
|
39
|
+
* connected or disconnected) rather than an individual action element.
|
|
40
|
+
*
|
|
41
|
+
* Membership is recomputed lazily by the owning element, so this only needs
|
|
42
|
+
* to bump the revision and notify ancestors. The owning element calls this
|
|
43
|
+
* from its onBdChildConnected / onBdChildDisconnected hooks, which fire while
|
|
44
|
+
* this node is still connected even as a child subtree is torn down.
|
|
45
|
+
*/
|
|
46
|
+
markSubtreeChanged(): void;
|
|
47
|
+
hostConnected(): void;
|
|
48
|
+
hostDisconnected(): void;
|
|
49
|
+
private readonly _onActionConnect;
|
|
50
|
+
private readonly _onActionDisconnect;
|
|
51
|
+
private readonly _onActionUpdate;
|
|
52
|
+
/**
|
|
53
|
+
* Fires on this node (target phase) and every ancestor (bubbling) for a
|
|
54
|
+
* single change. Each node bumps its own revision exactly once, which is why
|
|
55
|
+
* local changes also flow through here instead of bumping directly.
|
|
56
|
+
*/
|
|
57
|
+
private readonly _onTopologyChanged;
|
|
58
|
+
private _emitChanged;
|
|
59
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { BD_ACTION_CONNECT_EVENT, BD_ACTION_DISCONNECT_EVENT, BD_ACTION_TOPOLOGY_CHANGED_EVENT, BD_ACTION_UPDATE_EVENT, dispatchBdActionTopologyChanged } from '../core/action-topology.js';
|
|
2
|
+
/**
|
|
3
|
+
* Owns the set of native action elements that belong to a single bd node.
|
|
4
|
+
*
|
|
5
|
+
* Membership is fed incrementally by BdActionElementAdapter announcements, so
|
|
6
|
+
* no node ever rescans its DOM children. The nearest bd node catches
|
|
7
|
+
* bd-action-connect / bd-action-disconnect, exactly like bd-action-request, so
|
|
8
|
+
* an action's compute radius matches its runtime radius.
|
|
9
|
+
*
|
|
10
|
+
* Aggregation across the logical bd subtree is intentionally NOT done here. The
|
|
11
|
+
* owning element walks its bd children (which it has access to) and unions
|
|
12
|
+
* their local sets. This controller only owns local membership + a revision
|
|
13
|
+
* that already reflects descendant changes via the bubbling topology event.
|
|
14
|
+
*/
|
|
15
|
+
export class BdActionTopologyController {
|
|
16
|
+
constructor(host) {
|
|
17
|
+
this.host = host;
|
|
18
|
+
this._localScans = new Map();
|
|
19
|
+
this._revision = 0;
|
|
20
|
+
this._listening = false;
|
|
21
|
+
this._onActionConnect = (event) => {
|
|
22
|
+
/**
|
|
23
|
+
* Nearest bd node wins ownership; do not let outer nodes also claim it.
|
|
24
|
+
*/
|
|
25
|
+
event.stopPropagation();
|
|
26
|
+
event.detail.claim(this.host);
|
|
27
|
+
this._localScans.set(event.detail.element, event.detail.scan);
|
|
28
|
+
this._emitChanged();
|
|
29
|
+
};
|
|
30
|
+
this._onActionDisconnect = (event) => {
|
|
31
|
+
event.stopPropagation();
|
|
32
|
+
if (!this._localScans.delete(event.detail.element)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this._emitChanged();
|
|
36
|
+
};
|
|
37
|
+
this._onActionUpdate = (event) => {
|
|
38
|
+
event.stopPropagation();
|
|
39
|
+
if (!this._localScans.has(event.detail.element)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const previous = this._localScans.get(event.detail.element);
|
|
43
|
+
if (previous &&
|
|
44
|
+
sameComputeScan(previous, event.detail.scan)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this._localScans.set(event.detail.element, event.detail.scan);
|
|
48
|
+
this._emitChanged();
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Fires on this node (target phase) and every ancestor (bubbling) for a
|
|
52
|
+
* single change. Each node bumps its own revision exactly once, which is why
|
|
53
|
+
* local changes also flow through here instead of bumping directly.
|
|
54
|
+
*/
|
|
55
|
+
this._onTopologyChanged = (event) => {
|
|
56
|
+
this._revision++;
|
|
57
|
+
this.host.requestUpdate();
|
|
58
|
+
if (this.host.topologyBoundary === true) {
|
|
59
|
+
event.stopPropagation();
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
host.addController(this);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Bumped whenever this node's local set changes OR any descendant bd node's
|
|
66
|
+
* set changes (the change event bubbles through here). Use this as a compute
|
|
67
|
+
* input so a node recomputes when anything in its subtree changes.
|
|
68
|
+
*/
|
|
69
|
+
get revision() {
|
|
70
|
+
return this._revision;
|
|
71
|
+
}
|
|
72
|
+
get localElements() {
|
|
73
|
+
return [...this._localScans.keys()];
|
|
74
|
+
}
|
|
75
|
+
get localActionScans() {
|
|
76
|
+
return [...this._localScans.values()];
|
|
77
|
+
}
|
|
78
|
+
get localOptionSeed() {
|
|
79
|
+
return this._localOptionSeed;
|
|
80
|
+
}
|
|
81
|
+
setLocalOptionSeed(option) {
|
|
82
|
+
if (Object.is(this._localOptionSeed, option)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this._localOptionSeed = option;
|
|
86
|
+
this._emitChanged();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Signal that this node's logical subtree shape changed (a bd child node
|
|
90
|
+
* connected or disconnected) rather than an individual action element.
|
|
91
|
+
*
|
|
92
|
+
* Membership is recomputed lazily by the owning element, so this only needs
|
|
93
|
+
* to bump the revision and notify ancestors. The owning element calls this
|
|
94
|
+
* from its onBdChildConnected / onBdChildDisconnected hooks, which fire while
|
|
95
|
+
* this node is still connected even as a child subtree is torn down.
|
|
96
|
+
*/
|
|
97
|
+
markSubtreeChanged() {
|
|
98
|
+
this._emitChanged();
|
|
99
|
+
}
|
|
100
|
+
hostConnected() {
|
|
101
|
+
if (this._listening) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.host.addEventListener(BD_ACTION_CONNECT_EVENT, this._onActionConnect);
|
|
105
|
+
this.host.addEventListener(BD_ACTION_DISCONNECT_EVENT, this._onActionDisconnect);
|
|
106
|
+
this.host.addEventListener(BD_ACTION_UPDATE_EVENT, this._onActionUpdate);
|
|
107
|
+
this.host.addEventListener(BD_ACTION_TOPOLOGY_CHANGED_EVENT, this._onTopologyChanged);
|
|
108
|
+
this._listening = true;
|
|
109
|
+
}
|
|
110
|
+
hostDisconnected() {
|
|
111
|
+
if (!this._listening) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.host.removeEventListener(BD_ACTION_CONNECT_EVENT, this._onActionConnect);
|
|
115
|
+
this.host.removeEventListener(BD_ACTION_DISCONNECT_EVENT, this._onActionDisconnect);
|
|
116
|
+
this.host.removeEventListener(BD_ACTION_UPDATE_EVENT, this._onActionUpdate);
|
|
117
|
+
this.host.removeEventListener(BD_ACTION_TOPOLOGY_CHANGED_EVENT, this._onTopologyChanged);
|
|
118
|
+
this._listening = false;
|
|
119
|
+
this._localScans.clear();
|
|
120
|
+
this._localOptionSeed = undefined;
|
|
121
|
+
}
|
|
122
|
+
_emitChanged() {
|
|
123
|
+
dispatchBdActionTopologyChanged(this.host);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function sameComputeScan(a, b) {
|
|
127
|
+
return (JSON.stringify(a.staticCommands) === JSON.stringify(b.staticCommands) &&
|
|
128
|
+
JSON.stringify(a.domains) === JSON.stringify(b.domains));
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=controller.action-topology.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.action-topology.js","sourceRoot":"","sources":["../../../src/controllers/controller.action-topology.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ReactiveController,\n ReactiveControllerHost\n} from 'lit';\n\nimport {\n type BdComputeScan\n} from '@/compute/compute.scan.js';\nimport {\n BD_ACTION_CONNECT_EVENT,\n BD_ACTION_DISCONNECT_EVENT,\n BD_ACTION_TOPOLOGY_CHANGED_EVENT,\n BD_ACTION_UPDATE_EVENT,\n dispatchBdActionTopologyChanged,\n type BdActionConnectDetail,\n type BdActionDisconnectDetail,\n type BdActionUpdateDetail\n} from '@/core/action-topology.js';\nimport type { ProductOption } from '@repobit/dex-store';\n\nexport interface BdActionTopologyHost\n extends ReactiveControllerHost, EventTarget {\n readonly topologyBoundary?: boolean;\n}\n\n/**\n * Owns the set of native action elements that belong to a single bd node.\n *\n * Membership is fed incrementally by BdActionElementAdapter announcements, so\n * no node ever rescans its DOM children. The nearest bd node catches\n * bd-action-connect / bd-action-disconnect, exactly like bd-action-request, so\n * an action's compute radius matches its runtime radius.\n *\n * Aggregation across the logical bd subtree is intentionally NOT done here. The\n * owning element walks its bd children (which it has access to) and unions\n * their local sets. This controller only owns local membership + a revision\n * that already reflects descendant changes via the bubbling topology event.\n */\nexport class BdActionTopologyController implements ReactiveController {\n private readonly _localScans = new Map<HTMLElement, BdComputeScan>();\n private _localOptionSeed?: ProductOption;\n private _revision = 0;\n private _listening = false;\n\n constructor(\n private readonly host: BdActionTopologyHost\n ) {\n host.addController(this);\n }\n\n /**\n * Bumped whenever this node's local set changes OR any descendant bd node's\n * set changes (the change event bubbles through here). Use this as a compute\n * input so a node recomputes when anything in its subtree changes.\n */\n get revision(): number {\n return this._revision;\n }\n\n get localElements(): readonly HTMLElement[] {\n return [...this._localScans.keys()];\n }\n\n get localActionScans(): readonly BdComputeScan[] {\n return [...this._localScans.values()];\n }\n\n get localOptionSeed(): ProductOption | undefined {\n return this._localOptionSeed;\n }\n\n setLocalOptionSeed(\n option: ProductOption | undefined\n ): void {\n if (Object.is(\n this._localOptionSeed,\n option\n )) {\n return;\n }\n\n this._localOptionSeed = option;\n this._emitChanged();\n }\n\n /**\n * Signal that this node's logical subtree shape changed (a bd child node\n * connected or disconnected) rather than an individual action element.\n *\n * Membership is recomputed lazily by the owning element, so this only needs\n * to bump the revision and notify ancestors. The owning element calls this\n * from its onBdChildConnected / onBdChildDisconnected hooks, which fire while\n * this node is still connected even as a child subtree is torn down.\n */\n markSubtreeChanged(): void {\n this._emitChanged();\n }\n\n hostConnected(): void {\n if (this._listening) {\n return;\n }\n\n this.host.addEventListener(\n BD_ACTION_CONNECT_EVENT,\n this._onActionConnect as EventListener\n );\n\n this.host.addEventListener(\n BD_ACTION_DISCONNECT_EVENT,\n this._onActionDisconnect as EventListener\n );\n\n this.host.addEventListener(\n BD_ACTION_UPDATE_EVENT,\n this._onActionUpdate as EventListener\n );\n\n this.host.addEventListener(\n BD_ACTION_TOPOLOGY_CHANGED_EVENT,\n this._onTopologyChanged as EventListener\n );\n\n this._listening = true;\n }\n\n hostDisconnected(): void {\n if (!this._listening) {\n return;\n }\n\n this.host.removeEventListener(\n BD_ACTION_CONNECT_EVENT,\n this._onActionConnect as EventListener\n );\n\n this.host.removeEventListener(\n BD_ACTION_DISCONNECT_EVENT,\n this._onActionDisconnect as EventListener\n );\n\n this.host.removeEventListener(\n BD_ACTION_UPDATE_EVENT,\n this._onActionUpdate as EventListener\n );\n\n this.host.removeEventListener(\n BD_ACTION_TOPOLOGY_CHANGED_EVENT,\n this._onTopologyChanged as EventListener\n );\n\n this._listening = false;\n this._localScans.clear();\n this._localOptionSeed = undefined;\n }\n\n private readonly _onActionConnect = (\n event: CustomEvent<BdActionConnectDetail>\n ): void => {\n /**\n * Nearest bd node wins ownership; do not let outer nodes also claim it.\n */\n event.stopPropagation();\n\n event.detail.claim(this.host);\n this._localScans.set(\n event.detail.element,\n event.detail.scan\n );\n\n this._emitChanged();\n };\n\n private readonly _onActionDisconnect = (\n event: CustomEvent<BdActionDisconnectDetail>\n ): void => {\n event.stopPropagation();\n\n if (!this._localScans.delete(event.detail.element)) {\n return;\n }\n\n this._emitChanged();\n };\n\n private readonly _onActionUpdate = (\n event: CustomEvent<BdActionUpdateDetail>\n ): void => {\n event.stopPropagation();\n\n if (!this._localScans.has(event.detail.element)) {\n return;\n }\n\n const previous =\n this._localScans.get(event.detail.element);\n\n if (\n previous &&\n sameComputeScan(\n previous,\n event.detail.scan\n )\n ) {\n return;\n }\n\n this._localScans.set(\n event.detail.element,\n event.detail.scan\n );\n\n this._emitChanged();\n };\n\n /**\n * Fires on this node (target phase) and every ancestor (bubbling) for a\n * single change. Each node bumps its own revision exactly once, which is why\n * local changes also flow through here instead of bumping directly.\n */\n private readonly _onTopologyChanged = (\n event: Event\n ): void => {\n this._revision++;\n this.host.requestUpdate();\n\n if (this.host.topologyBoundary === true) {\n event.stopPropagation();\n }\n };\n\n private _emitChanged(): void {\n dispatchBdActionTopologyChanged(this.host);\n }\n}\n\nfunction sameComputeScan(\n a: BdComputeScan,\n b: BdComputeScan\n): boolean {\n return (\n JSON.stringify(a.staticCommands) === JSON.stringify(b.staticCommands) &&\n JSON.stringify(a.domains) === JSON.stringify(b.domains)\n );\n}\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type BdComputeResult } from '../compute/compute.expand.js';
|
|
2
|
+
import { type BdComputeScan } from '../compute/compute.scan.js';
|
|
3
|
+
import type { ProductOption, Store } from '@repobit/dex-store';
|
|
4
|
+
import type { ReactiveController } from 'lit';
|
|
5
|
+
import { type BdResolveHost } from './controller.resolve.js';
|
|
6
|
+
export declare const BD_COMPUTE_CHANGED_EVENT: "bd-compute-changed";
|
|
7
|
+
export type BdComputeChangedDetail = Readonly<{
|
|
8
|
+
result?: BdComputeResult;
|
|
9
|
+
}>;
|
|
10
|
+
declare global {
|
|
11
|
+
interface HTMLElementEventMap {
|
|
12
|
+
[BD_COMPUTE_CHANGED_EVENT]: CustomEvent<BdComputeChangedDetail>;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Host requirements for the compute controller. Any BdNodeElement satisfies
|
|
17
|
+
* this: it tracks local work, is an EventTarget, can query its own subtree, and
|
|
18
|
+
* exposes the incremental action topology.
|
|
19
|
+
*/
|
|
20
|
+
export interface BdComputeHost extends BdResolveHost, EventTarget, ParentNode {
|
|
21
|
+
readonly actionTopologyRevision: number;
|
|
22
|
+
collectActionScans(): BdComputeScan[];
|
|
23
|
+
collectOptionSeeds(): ProductOption[];
|
|
24
|
+
}
|
|
25
|
+
export interface BdComputeOptions {
|
|
26
|
+
name?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The store used to resolve products. Usually `() => this.scope?.store`.
|
|
29
|
+
*/
|
|
30
|
+
store: () => Store | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Global/local compute switch. Disabled compute publishes an undefined result.
|
|
33
|
+
*/
|
|
34
|
+
enabled?: () => boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Extra change signal mixed into the task args. Defaults to the host's action
|
|
37
|
+
* topology revision, which already bumps on action and bd-subtree changes.
|
|
38
|
+
*/
|
|
39
|
+
revision?: () => number;
|
|
40
|
+
/**
|
|
41
|
+
* Safety cap on the fixed-point search size.
|
|
42
|
+
*/
|
|
43
|
+
maxScenarios?: number;
|
|
44
|
+
onResult?: (result: BdComputeResult | undefined) => void;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Dry-run min/max price compute over every product/option combination reachable
|
|
48
|
+
* from a bd node boundary.
|
|
49
|
+
*
|
|
50
|
+
* It never dispatches bd-action-request. It reads resolved option seeds and
|
|
51
|
+
* collected action declarations from topology, expands them against the same
|
|
52
|
+
* command shapes the runtime would honor, and reduces price. Reruns are driven
|
|
53
|
+
* by the store scope, the resolved seed set, and the action topology revision.
|
|
54
|
+
*/
|
|
55
|
+
export declare class BdComputeController implements ReactiveController {
|
|
56
|
+
private readonly host;
|
|
57
|
+
private readonly options;
|
|
58
|
+
result?: BdComputeResult;
|
|
59
|
+
private readonly _resolver;
|
|
60
|
+
constructor(host: BdComputeHost, options: BdComputeOptions);
|
|
61
|
+
hostConnected(): void;
|
|
62
|
+
hostDisconnected(): void;
|
|
63
|
+
get pending(): boolean;
|
|
64
|
+
get complete(): boolean;
|
|
65
|
+
get failed(): boolean;
|
|
66
|
+
get error(): unknown;
|
|
67
|
+
run(): Promise<BdComputeResult | undefined>;
|
|
68
|
+
private _compute;
|
|
69
|
+
private _publish;
|
|
70
|
+
private _revision;
|
|
71
|
+
private _enabled;
|
|
72
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// src/controllers/controller.compute.ts
|
|
2
|
+
import { expandScenarios, reducePriceRange } from '../compute/compute.expand.js';
|
|
3
|
+
import { mergeComputeScans } from '../compute/compute.scan.js';
|
|
4
|
+
import { scenarioKey } from '../compute/option-resolver.js';
|
|
5
|
+
import { BdResolveController } from './controller.resolve.js';
|
|
6
|
+
export const BD_COMPUTE_CHANGED_EVENT = 'bd-compute-changed';
|
|
7
|
+
/**
|
|
8
|
+
* Dry-run min/max price compute over every product/option combination reachable
|
|
9
|
+
* from a bd node boundary.
|
|
10
|
+
*
|
|
11
|
+
* It never dispatches bd-action-request. It reads resolved option seeds and
|
|
12
|
+
* collected action declarations from topology, expands them against the same
|
|
13
|
+
* command shapes the runtime would honor, and reduces price. Reruns are driven
|
|
14
|
+
* by the store scope, the resolved seed set, and the action topology revision.
|
|
15
|
+
*/
|
|
16
|
+
export class BdComputeController {
|
|
17
|
+
constructor(host, options) {
|
|
18
|
+
this.host = host;
|
|
19
|
+
this.options = options;
|
|
20
|
+
host.addController(this);
|
|
21
|
+
this._resolver = new BdResolveController(host, {
|
|
22
|
+
name: options.name ?? 'bd-compute',
|
|
23
|
+
args: () => [
|
|
24
|
+
this.options.store(),
|
|
25
|
+
this._enabled(),
|
|
26
|
+
optionSeedsKey(this.host.collectOptionSeeds()),
|
|
27
|
+
this._revision()
|
|
28
|
+
],
|
|
29
|
+
enabled: ([store, enabled]) => Boolean(store) &&
|
|
30
|
+
enabled,
|
|
31
|
+
resolve: async ([store], context) => await this._compute(store, context),
|
|
32
|
+
commit: (result) => {
|
|
33
|
+
this._publish(result);
|
|
34
|
+
},
|
|
35
|
+
onDisabled: () => {
|
|
36
|
+
this._publish(undefined);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
hostConnected() {
|
|
41
|
+
// BdResolveController owns compute scheduling.
|
|
42
|
+
}
|
|
43
|
+
hostDisconnected() {
|
|
44
|
+
// BdResolveController owns compute cancellation.
|
|
45
|
+
}
|
|
46
|
+
get pending() {
|
|
47
|
+
return this._resolver.pending;
|
|
48
|
+
}
|
|
49
|
+
get complete() {
|
|
50
|
+
return this._resolver.complete;
|
|
51
|
+
}
|
|
52
|
+
get failed() {
|
|
53
|
+
return this._resolver.failed;
|
|
54
|
+
}
|
|
55
|
+
get error() {
|
|
56
|
+
return this._resolver.error;
|
|
57
|
+
}
|
|
58
|
+
async run() {
|
|
59
|
+
return await this._resolver.run();
|
|
60
|
+
}
|
|
61
|
+
async _compute(store, context) {
|
|
62
|
+
if (!store) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const seeds = this.host.collectOptionSeeds()
|
|
66
|
+
.map(optionToScenario);
|
|
67
|
+
if (seeds.length === 0) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
const scan = mergeComputeScans(this.host.collectActionScans());
|
|
71
|
+
const scenarios = await expandScenarios({
|
|
72
|
+
store,
|
|
73
|
+
seeds,
|
|
74
|
+
staticCommands: scan.staticCommands,
|
|
75
|
+
domains: scan.domains,
|
|
76
|
+
signal: context.signal,
|
|
77
|
+
maxScenarios: this.options.maxScenarios
|
|
78
|
+
});
|
|
79
|
+
return reducePriceRange(scenarios);
|
|
80
|
+
}
|
|
81
|
+
_publish(result) {
|
|
82
|
+
this.result = result;
|
|
83
|
+
this.options.onResult?.(result);
|
|
84
|
+
this.host.dispatchEvent(new CustomEvent(BD_COMPUTE_CHANGED_EVENT, {
|
|
85
|
+
bubbles: true,
|
|
86
|
+
composed: true,
|
|
87
|
+
detail: { result }
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
_revision() {
|
|
91
|
+
return (this.options.revision?.() ??
|
|
92
|
+
this.host.actionTopologyRevision);
|
|
93
|
+
}
|
|
94
|
+
_enabled() {
|
|
95
|
+
return this.options.enabled?.() ?? true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function optionToScenario(option) {
|
|
99
|
+
return {
|
|
100
|
+
product: option.getProduct(),
|
|
101
|
+
option
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function optionSeedsKey(options) {
|
|
105
|
+
return options
|
|
106
|
+
.map((option) => scenarioKey(optionToScenario(option)))
|
|
107
|
+
.sort()
|
|
108
|
+
.join(';');
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=controller.compute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.compute.js","sourceRoot":"","sources":["../../../src/controllers/controller.compute.ts"],"names":[],"mappings":"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","sourcesContent":["// src/controllers/controller.compute.ts\n\nimport {\n expandScenarios,\n reducePriceRange,\n type BdComputeResult\n} from '@/compute/compute.expand.js';\nimport {\n mergeComputeScans,\n type BdComputeScan\n} from '@/compute/compute.scan.js';\nimport {\n scenarioKey,\n type BdOptionScenario\n} from '@/compute/option-resolver.js';\nimport type {\n ProductOption,\n Store\n} from '@repobit/dex-store';\nimport type { ReactiveController } from 'lit';\nimport {\n BdResolveController,\n type BdResolveContext,\n type BdResolveHost\n} from './controller.resolve.js';\n\nexport const BD_COMPUTE_CHANGED_EVENT = 'bd-compute-changed' as const;\n\nexport type BdComputeChangedDetail = Readonly<{\n result?: BdComputeResult;\n}>;\n\ndeclare global {\n interface HTMLElementEventMap {\n [BD_COMPUTE_CHANGED_EVENT]: CustomEvent<BdComputeChangedDetail>;\n }\n}\n\n/**\n * Host requirements for the compute controller. Any BdNodeElement satisfies\n * this: it tracks local work, is an EventTarget, can query its own subtree, and\n * exposes the incremental action topology.\n */\nexport interface BdComputeHost extends BdResolveHost, EventTarget, ParentNode {\n readonly actionTopologyRevision: number;\n collectActionScans(): BdComputeScan[];\n collectOptionSeeds(): ProductOption[];\n}\n\nexport interface BdComputeOptions {\n name?: string;\n\n /**\n * The store used to resolve products. Usually `() => this.scope?.store`.\n */\n store: () => Store | undefined;\n\n /**\n * Global/local compute switch. Disabled compute publishes an undefined result.\n */\n enabled?: () => boolean;\n\n /**\n * Extra change signal mixed into the task args. Defaults to the host's action\n * topology revision, which already bumps on action and bd-subtree changes.\n */\n revision?: () => number;\n\n /**\n * Safety cap on the fixed-point search size.\n */\n maxScenarios?: number;\n\n onResult?: (result: BdComputeResult | undefined) => void;\n}\n\ntype BdComputeArgs = readonly [\n store: Store | undefined,\n enabled: boolean,\n seedsKey: string,\n revision: number\n];\n\n/**\n * Dry-run min/max price compute over every product/option combination reachable\n * from a bd node boundary.\n *\n * It never dispatches bd-action-request. It reads resolved option seeds and\n * collected action declarations from topology, expands them against the same\n * command shapes the runtime would honor, and reduces price. Reruns are driven\n * by the store scope, the resolved seed set, and the action topology revision.\n */\nexport class BdComputeController implements ReactiveController {\n result?: BdComputeResult;\n\n private readonly _resolver: BdResolveController<BdComputeArgs, BdComputeResult | undefined>;\n\n constructor(\n private readonly host: BdComputeHost,\n private readonly options: BdComputeOptions\n ) {\n host.addController(this);\n\n this._resolver = new BdResolveController<BdComputeArgs, BdComputeResult | undefined>(\n host,\n {\n name: options.name ?? 'bd-compute',\n\n args: () =>\n [\n this.options.store(),\n this._enabled(),\n optionSeedsKey(this.host.collectOptionSeeds()),\n this._revision()\n ] as const,\n\n enabled: ([store, enabled]) =>\n Boolean(store) &&\n enabled,\n\n resolve: async ([store], context) =>\n await this._compute(store, context),\n\n commit: (result) => {\n this._publish(result);\n },\n\n onDisabled: () => {\n this._publish(undefined);\n }\n }\n );\n }\n\n hostConnected(): void {\n // BdResolveController owns compute scheduling.\n }\n\n hostDisconnected(): void {\n // BdResolveController owns compute cancellation.\n }\n\n get pending(): boolean {\n return this._resolver.pending;\n }\n\n get complete(): boolean {\n return this._resolver.complete;\n }\n\n get failed(): boolean {\n return this._resolver.failed;\n }\n\n get error(): unknown {\n return this._resolver.error;\n }\n\n async run(): Promise<BdComputeResult | undefined> {\n return await this._resolver.run();\n }\n\n private async _compute(\n store: Store | undefined,\n context: BdResolveContext\n ): Promise<BdComputeResult | undefined> {\n if (!store) {\n return undefined;\n }\n\n const seeds =\n this.host.collectOptionSeeds()\n .map(optionToScenario);\n\n if (seeds.length === 0) {\n return undefined;\n }\n\n const scan =\n mergeComputeScans(this.host.collectActionScans());\n\n const scenarios =\n await expandScenarios({\n store,\n seeds,\n staticCommands: scan.staticCommands,\n domains : scan.domains,\n signal : context.signal,\n maxScenarios : this.options.maxScenarios\n });\n\n return reducePriceRange(scenarios);\n }\n\n private _publish(\n result: BdComputeResult | undefined\n ): void {\n this.result = result;\n this.options.onResult?.(result);\n\n this.host.dispatchEvent(\n new CustomEvent<BdComputeChangedDetail>(\n BD_COMPUTE_CHANGED_EVENT,\n {\n bubbles : true,\n composed: true,\n detail : { result }\n }\n )\n );\n }\n\n private _revision(): number {\n return (\n this.options.revision?.() ??\n this.host.actionTopologyRevision\n );\n }\n\n private _enabled(): boolean {\n return this.options.enabled?.() ?? true;\n }\n}\n\nfunction optionToScenario(\n option: ProductOption\n): BdOptionScenario {\n return {\n product: option.getProduct(),\n option\n };\n}\n\nfunction optionSeedsKey(\n options: readonly ProductOption[]\n): string {\n return options\n .map((option) =>\n scenarioKey(optionToScenario(option))\n )\n .sort()\n .join(';');\n}\n"]}
|