@pie-players/pie-assessment-toolkit 0.3.30 → 0.3.32
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/README.md +289 -5
- package/dist/components/ItemToolBar.custom-element.js +165 -92
- package/dist/components/PieAssessmentToolkit.custom-element.js +604 -107
- package/dist/components/SectionToolBar.custom-element.js +0 -36
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/policy/core/PolicySource.d.ts +64 -0
- package/dist/policy/core/PolicySource.d.ts.map +1 -0
- package/dist/policy/core/PolicySource.js +17 -0
- package/dist/policy/core/PolicySource.js.map +1 -0
- package/dist/policy/core/ToolPolicyEngine.d.ts +123 -0
- package/dist/policy/core/ToolPolicyEngine.d.ts.map +1 -0
- package/dist/policy/core/ToolPolicyEngine.js +217 -0
- package/dist/policy/core/ToolPolicyEngine.js.map +1 -0
- package/dist/policy/core/compose-decision.d.ts +37 -0
- package/dist/policy/core/compose-decision.d.ts.map +1 -0
- package/dist/policy/core/compose-decision.js +332 -0
- package/dist/policy/core/compose-decision.js.map +1 -0
- package/dist/policy/core/decision-types.d.ts +142 -0
- package/dist/policy/core/decision-types.d.ts.map +1 -0
- package/dist/policy/core/decision-types.js +13 -0
- package/dist/policy/core/decision-types.js.map +1 -0
- package/dist/policy/core/engine-context.d.ts +30 -0
- package/dist/policy/core/engine-context.d.ts.map +1 -0
- package/dist/policy/core/engine-context.js +28 -0
- package/dist/policy/core/engine-context.js.map +1 -0
- package/dist/policy/core/policy-source-tag.d.ts +32 -0
- package/dist/policy/core/policy-source-tag.d.ts.map +1 -0
- package/dist/policy/core/policy-source-tag.js +29 -0
- package/dist/policy/core/policy-source-tag.js.map +1 -0
- package/dist/policy/core/provenance.d.ts +163 -0
- package/dist/policy/core/provenance.d.ts.map +1 -0
- package/dist/policy/core/provenance.js +232 -0
- package/dist/policy/core/provenance.js.map +1 -0
- package/dist/policy/core/qti-inputs.d.ts +67 -0
- package/dist/policy/core/qti-inputs.d.ts.map +1 -0
- package/dist/policy/core/qti-inputs.js +139 -0
- package/dist/policy/core/qti-inputs.js.map +1 -0
- package/dist/policy/engine.d.ts +28 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +24 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/internal.d.ts +26 -0
- package/dist/policy/internal.d.ts.map +1 -0
- package/dist/policy/internal.js +26 -0
- package/dist/policy/internal.js.map +1 -0
- package/dist/policy/sources/QtiPolicySource.d.ts +146 -0
- package/dist/policy/sources/QtiPolicySource.d.ts.map +1 -0
- package/dist/policy/sources/QtiPolicySource.js +270 -0
- package/dist/policy/sources/QtiPolicySource.js.map +1 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +145 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts.map +1 -1
- package/dist/runtime/SectionRuntimeEngine.js +164 -3
- package/dist/runtime/SectionRuntimeEngine.js.map +1 -1
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts +144 -0
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts.map +1 -0
- package/dist/runtime/adapter/SectionEngineAdapter.js +183 -0
- package/dist/runtime/adapter/SectionEngineAdapter.js.map +1 -0
- package/dist/runtime/adapter/coordinator-bridge.d.ts +93 -0
- package/dist/runtime/adapter/coordinator-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/coordinator-bridge.js +127 -0
- package/dist/runtime/adapter/coordinator-bridge.js.map +1 -0
- package/dist/runtime/adapter/dom-event-bridge.d.ts +63 -0
- package/dist/runtime/adapter/dom-event-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/dom-event-bridge.js +95 -0
- package/dist/runtime/adapter/dom-event-bridge.js.map +1 -0
- package/dist/runtime/adapter/framework-error-bridge.d.ts +37 -0
- package/dist/runtime/adapter/framework-error-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/framework-error-bridge.js +47 -0
- package/dist/runtime/adapter/framework-error-bridge.js.map +1 -0
- package/dist/runtime/adapter/instrumentation-bridge.d.ts +32 -0
- package/dist/runtime/adapter/instrumentation-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/instrumentation-bridge.js +39 -0
- package/dist/runtime/adapter/instrumentation-bridge.js.map +1 -0
- package/dist/runtime/adapter/subscriber-fanout.d.ts +35 -0
- package/dist/runtime/adapter/subscriber-fanout.d.ts.map +1 -0
- package/dist/runtime/adapter/subscriber-fanout.js +60 -0
- package/dist/runtime/adapter/subscriber-fanout.js.map +1 -0
- package/dist/runtime/core/SectionEngineCore.d.ts +52 -0
- package/dist/runtime/core/SectionEngineCore.d.ts.map +1 -0
- package/dist/runtime/core/SectionEngineCore.js +81 -0
- package/dist/runtime/core/SectionEngineCore.js.map +1 -0
- package/dist/runtime/core/cohort.d.ts +40 -0
- package/dist/runtime/core/cohort.d.ts.map +1 -0
- package/dist/runtime/core/cohort.js +49 -0
- package/dist/runtime/core/cohort.js.map +1 -0
- package/dist/runtime/core/engine-input.d.ts +114 -0
- package/dist/runtime/core/engine-input.d.ts.map +1 -0
- package/dist/runtime/core/engine-input.js +19 -0
- package/dist/runtime/core/engine-input.js.map +1 -0
- package/dist/runtime/core/engine-output.d.ts +62 -0
- package/dist/runtime/core/engine-output.d.ts.map +1 -0
- package/dist/runtime/core/engine-output.js +27 -0
- package/dist/runtime/core/engine-output.js.map +1 -0
- package/dist/runtime/core/engine-readiness.d.ts +49 -0
- package/dist/runtime/core/engine-readiness.d.ts.map +1 -0
- package/dist/runtime/core/engine-readiness.js +47 -0
- package/dist/runtime/core/engine-readiness.js.map +1 -0
- package/dist/runtime/core/engine-resolver.d.ts +172 -0
- package/dist/runtime/core/engine-resolver.d.ts.map +1 -0
- package/dist/runtime/core/engine-resolver.js +170 -0
- package/dist/runtime/core/engine-resolver.js.map +1 -0
- package/dist/runtime/core/engine-stage-derivation.d.ts +19 -0
- package/dist/runtime/core/engine-stage-derivation.d.ts.map +1 -0
- package/dist/runtime/core/engine-stage-derivation.js +30 -0
- package/dist/runtime/core/engine-stage-derivation.js.map +1 -0
- package/dist/runtime/core/engine-state.d.ts +83 -0
- package/dist/runtime/core/engine-state.d.ts.map +1 -0
- package/dist/runtime/core/engine-state.js +49 -0
- package/dist/runtime/core/engine-state.js.map +1 -0
- package/dist/runtime/core/engine-transition.d.ts +49 -0
- package/dist/runtime/core/engine-transition.d.ts.map +1 -0
- package/dist/runtime/core/engine-transition.js +261 -0
- package/dist/runtime/core/engine-transition.js.map +1 -0
- package/dist/runtime/engine-context.d.ts +40 -0
- package/dist/runtime/engine-context.d.ts.map +1 -0
- package/dist/runtime/engine-context.js +32 -0
- package/dist/runtime/engine-context.js.map +1 -0
- package/dist/runtime/engine.d.ts +24 -0
- package/dist/runtime/engine.d.ts.map +1 -0
- package/dist/runtime/engine.js +24 -0
- package/dist/runtime/engine.js.map +1 -0
- package/dist/runtime/internal.d.ts +44 -0
- package/dist/runtime/internal.d.ts.map +1 -0
- package/dist/runtime/internal.js +46 -0
- package/dist/runtime/internal.js.map +1 -0
- package/dist/runtime/runtime-id.d.ts +8 -0
- package/dist/runtime/runtime-id.d.ts.map +1 -0
- package/dist/runtime/runtime-id.js +10 -0
- package/dist/runtime/runtime-id.js.map +1 -0
- package/dist/runtime/section-runtime-engine-host-context.d.ts +74 -0
- package/dist/runtime/section-runtime-engine-host-context.d.ts.map +1 -0
- package/dist/runtime/section-runtime-engine-host-context.js +96 -0
- package/dist/runtime/section-runtime-engine-host-context.js.map +1 -0
- package/dist/runtime/stage-emit-gate.d.ts +93 -0
- package/dist/runtime/stage-emit-gate.d.ts.map +1 -0
- package/dist/runtime/stage-emit-gate.js +83 -0
- package/dist/runtime/stage-emit-gate.js.map +1 -0
- package/dist/services/ToolkitCoordinator.d.ts +280 -7
- package/dist/services/ToolkitCoordinator.d.ts.map +1 -1
- package/dist/services/ToolkitCoordinator.js +412 -32
- package/dist/services/ToolkitCoordinator.js.map +1 -1
- package/dist/services/framework-error-bus.d.ts +73 -0
- package/dist/services/framework-error-bus.d.ts.map +1 -0
- package/dist/services/framework-error-bus.js +68 -0
- package/dist/services/framework-error-bus.js.map +1 -0
- package/dist/services/framework-error.d.ts +36 -1
- package/dist/services/framework-error.d.ts.map +1 -1
- package/dist/services/framework-error.js +37 -0
- package/dist/services/framework-error.js.map +1 -1
- package/dist/services/interfaces.d.ts +78 -0
- package/dist/services/interfaces.d.ts.map +1 -1
- package/dist/services/interfaces.js.map +1 -1
- package/dist/services/section-controller-types.d.ts +20 -0
- package/dist/services/section-controller-types.d.ts.map +1 -1
- package/dist/services/tools-config-normalizer.d.ts +23 -0
- package/dist/services/tools-config-normalizer.d.ts.map +1 -1
- package/dist/services/tools-config-normalizer.js +13 -1
- package/dist/services/tools-config-normalizer.js.map +1 -1
- package/dist/tools/client.d.ts +0 -1
- package/dist/tools/client.d.ts.map +1 -1
- package/dist/tools/client.js +0 -2
- package/dist/tools/client.js.map +1 -1
- package/dist/tools/types.d.ts +0 -26
- package/dist/tools/types.d.ts.map +1 -1
- package/package.json +23 -7
- package/dist/runtime/runtime-event-guards.d.ts +0 -2
- package/dist/runtime/runtime-event-guards.d.ts.map +0 -1
- package/dist/runtime/runtime-event-guards.js +0 -4
- package/dist/runtime/runtime-event-guards.js.map +0 -1
- package/dist/tools/tool-coordinator.d.ts +0 -72
- package/dist/tools/tool-coordinator.d.ts.map +0 -1
- package/dist/tools/tool-coordinator.js +0 -194
- package/dist/tools/tool-coordinator.js.map +0 -1
- package/dist/types/events.d.ts +0 -157
- package/dist/types/events.d.ts.map +0 -1
- package/dist/types/events.js +0 -11
- package/dist/types/events.js.map +0 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Section runtime engine adapter (M7 — Variant C, layered).
|
|
3
|
+
*
|
|
4
|
+
* The adapter is the single I/O seam between the pure FSM core
|
|
5
|
+
* (`SectionEngineCore`) and the rest of the world (DOM, coordinator,
|
|
6
|
+
* framework-error bus, host subscribers, instrumentation). It does
|
|
7
|
+
* exactly two jobs:
|
|
8
|
+
*
|
|
9
|
+
* 1. Translate **host inputs** (from kernels, the toolkit CE, or
|
|
10
|
+
* direct facade callers) into `SectionEngineInput`s and forward
|
|
11
|
+
* them to the core via `core.dispatch(input)`.
|
|
12
|
+
*
|
|
13
|
+
* 2. Subscribe to the core's output stream and **route each output**
|
|
14
|
+
* through the bridges in a deterministic order so the public DOM
|
|
15
|
+
* surface, framework-error bus, instrumentation hook, and host
|
|
16
|
+
* subscribers all see exactly the same fan-out with
|
|
17
|
+
* byte-identical detail shapes.
|
|
18
|
+
*
|
|
19
|
+
* Output routing is a single exhaustive `switch` (`assertNever` on
|
|
20
|
+
* the default branch) so adding a new `SectionEngineOutput` kind in
|
|
21
|
+
* `engine-output.ts` is a compile error here until the adapter knows
|
|
22
|
+
* what to do with it.
|
|
23
|
+
*
|
|
24
|
+
* **Routing order per output:**
|
|
25
|
+
* - canonical DOM event (`pie-stage-change`, `pie-loading-complete`,
|
|
26
|
+
* `framework-error`)
|
|
27
|
+
* - framework-error bus (single fan-out for in-process subscribers)
|
|
28
|
+
* - instrumentation hook
|
|
29
|
+
* - public subscriber fan-out (batched, runs once per
|
|
30
|
+
* `core.dispatch`)
|
|
31
|
+
*
|
|
32
|
+
* The deprecated `readiness-change` / `interaction-ready` / `ready`
|
|
33
|
+
* DOM events and their `legacy-event-bridge.ts` were removed in the
|
|
34
|
+
* broad architecture review compat sweep; the corresponding output
|
|
35
|
+
* kinds are gone from `engine-output.ts`.
|
|
36
|
+
*
|
|
37
|
+
* **Layering constraint.** The adapter is plain TS. It must not
|
|
38
|
+
* import `svelte` — the M7 implementation plan and
|
|
39
|
+
* `scripts/check-engine-core-purity.mjs` enforce the core's purity;
|
|
40
|
+
* the adapter follows the same constraint by convention so it stays
|
|
41
|
+
* usable from non-Svelte hosts (Node tests, Storybook, or future
|
|
42
|
+
* non-Svelte consumers). `bun run check:custom-elements` already
|
|
43
|
+
* blocks `.svelte` imports in published `dist`; adding a Svelte
|
|
44
|
+
* dependency here would also leak through that gate.
|
|
45
|
+
*/
|
|
46
|
+
import { SectionEngineCore } from "../core/SectionEngineCore.js";
|
|
47
|
+
import { createCoordinatorBridge, } from "./coordinator-bridge.js";
|
|
48
|
+
import { createDomEventBridge, } from "./dom-event-bridge.js";
|
|
49
|
+
import { createFrameworkErrorBridge, } from "./framework-error-bridge.js";
|
|
50
|
+
import { createInstrumentationBridge, } from "./instrumentation-bridge.js";
|
|
51
|
+
import { createSubscriberFanout, } from "./subscriber-fanout.js";
|
|
52
|
+
export class SectionEngineAdapter {
|
|
53
|
+
core;
|
|
54
|
+
domEventBridge;
|
|
55
|
+
frameworkErrorBridge;
|
|
56
|
+
instrumentationBridge;
|
|
57
|
+
subscriberFanout;
|
|
58
|
+
coordinatorBridge;
|
|
59
|
+
unsubscribeCore;
|
|
60
|
+
disposed = false;
|
|
61
|
+
constructor(options) {
|
|
62
|
+
this.core = options.core ?? new SectionEngineCore();
|
|
63
|
+
this.domEventBridge = createDomEventBridge({
|
|
64
|
+
host: options.host,
|
|
65
|
+
runtimeId: options.runtimeId,
|
|
66
|
+
sourceCe: options.sourceCe,
|
|
67
|
+
now: options.now,
|
|
68
|
+
});
|
|
69
|
+
this.frameworkErrorBridge = createFrameworkErrorBridge({
|
|
70
|
+
bus: options.frameworkErrorBus,
|
|
71
|
+
});
|
|
72
|
+
this.instrumentationBridge = createInstrumentationBridge({
|
|
73
|
+
hook: options.instrumentationHook,
|
|
74
|
+
});
|
|
75
|
+
this.subscriberFanout = createSubscriberFanout();
|
|
76
|
+
this.coordinatorBridge = options.coordinator
|
|
77
|
+
? createCoordinatorBridge({
|
|
78
|
+
coordinator: options.coordinator,
|
|
79
|
+
dispatchCoreInput: (input) => this.dispatchInput(input),
|
|
80
|
+
})
|
|
81
|
+
: null;
|
|
82
|
+
this.unsubscribeCore = this.core.subscribe((outputs) => {
|
|
83
|
+
this.routeOutputs(outputs);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Read-only snapshot of the FSM state. Mirrors
|
|
88
|
+
* `SectionEngineCore.getState()`.
|
|
89
|
+
*/
|
|
90
|
+
getState() {
|
|
91
|
+
return this.core.getState();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Forward a host-constructed input to the core. Returns the outputs
|
|
95
|
+
* that resulted (the bridges have already received them).
|
|
96
|
+
*/
|
|
97
|
+
dispatchInput(input) {
|
|
98
|
+
if (this.disposed)
|
|
99
|
+
return [];
|
|
100
|
+
return this.core.dispatch(input);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Subscribe to batched output streams, one batch per
|
|
104
|
+
* `dispatchInput`.
|
|
105
|
+
*/
|
|
106
|
+
subscribe(listener) {
|
|
107
|
+
return this.subscriberFanout.subscribe(listener);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Update the host element after construction (e.g. when the kernel
|
|
111
|
+
* receives its host element via Svelte action / context).
|
|
112
|
+
*/
|
|
113
|
+
setHost(host) {
|
|
114
|
+
this.domEventBridge.setHost(host);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Update the instrumentation hook at runtime.
|
|
118
|
+
*/
|
|
119
|
+
setInstrumentationHook(hook) {
|
|
120
|
+
this.instrumentationBridge.setHook(hook);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Resolve a section controller through the configured coordinator.
|
|
124
|
+
*
|
|
125
|
+
* Throws if the adapter was constructed without a coordinator.
|
|
126
|
+
* Standalone callers should manually feed
|
|
127
|
+
* `{ kind: "section-controller-resolved" }` after their own
|
|
128
|
+
* controller resolution path completes.
|
|
129
|
+
*/
|
|
130
|
+
resolveSectionController(args) {
|
|
131
|
+
if (!this.coordinatorBridge) {
|
|
132
|
+
throw new Error("[SectionEngineAdapter] resolveSectionController called without a coordinator.");
|
|
133
|
+
}
|
|
134
|
+
return this.coordinatorBridge.resolveSectionController(args);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Tear the adapter down. Safe to call more than once. Disposes the
|
|
138
|
+
* coordinator bridge (which in turn disposes the section
|
|
139
|
+
* controller for the current cohort), detaches the core
|
|
140
|
+
* subscription, and clears subscribers.
|
|
141
|
+
*
|
|
142
|
+
* Does **not** dispose the framework-error bus — its lifetime is
|
|
143
|
+
* owned by the toolkit CE / host.
|
|
144
|
+
*/
|
|
145
|
+
async dispose() {
|
|
146
|
+
if (this.disposed)
|
|
147
|
+
return;
|
|
148
|
+
this.disposed = true;
|
|
149
|
+
// Dispatch the FSM `dispose` input first so the disposed-stage
|
|
150
|
+
// output flows through the bridges before we tear anything down.
|
|
151
|
+
this.core.dispatch({ kind: "dispose" });
|
|
152
|
+
this.unsubscribeCore();
|
|
153
|
+
this.subscriberFanout.dispose();
|
|
154
|
+
if (this.coordinatorBridge) {
|
|
155
|
+
await this.coordinatorBridge.dispose();
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
routeOutputs(outputs) {
|
|
159
|
+
for (const output of outputs) {
|
|
160
|
+
this.routeOne(output);
|
|
161
|
+
}
|
|
162
|
+
this.subscriberFanout.emit(outputs);
|
|
163
|
+
}
|
|
164
|
+
routeOne(output) {
|
|
165
|
+
switch (output.kind) {
|
|
166
|
+
case "stage-change":
|
|
167
|
+
case "loading-complete":
|
|
168
|
+
this.domEventBridge.dispatch(output);
|
|
169
|
+
break;
|
|
170
|
+
case "framework-error":
|
|
171
|
+
this.domEventBridge.dispatch(output);
|
|
172
|
+
this.frameworkErrorBridge.dispatch(output);
|
|
173
|
+
break;
|
|
174
|
+
default: {
|
|
175
|
+
const exhaustive = output;
|
|
176
|
+
void exhaustive;
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
this.instrumentationBridge.dispatch(output);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=SectionEngineAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SectionEngineAdapter.js","sourceRoot":"","sources":["../../../src/runtime/adapter/SectionEngineAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coordinator bridge for the section runtime engine adapter (M7 —
|
|
3
|
+
* Variant C, layered).
|
|
4
|
+
*
|
|
5
|
+
* Unlike the DOM / legacy / framework-error bridges (which translate
|
|
6
|
+
* **outputs** into I/O), the coordinator bridge is an **input source**:
|
|
7
|
+
* it listens to a `ToolkitCoordinator` and feeds the resulting events
|
|
8
|
+
* into the core via the `dispatchCoreInput` callback supplied by the
|
|
9
|
+
* adapter.
|
|
10
|
+
*
|
|
11
|
+
* Responsibilities:
|
|
12
|
+
* 1. **Framework-error subscription.** When the coordinator reports
|
|
13
|
+
* a framework error through its bus, dispatch a
|
|
14
|
+
* `{ kind: "framework-error" }` core input. Listener isolation
|
|
15
|
+
* matches `FrameworkErrorBus`: a throwing bridge handler is
|
|
16
|
+
* caught and `console.warn`-logged so the original fan-out is
|
|
17
|
+
* not interrupted.
|
|
18
|
+
*
|
|
19
|
+
* 2. **Section-controller resolution.** When the host calls
|
|
20
|
+
* `resolveSectionController({ ... })`, the bridge invokes
|
|
21
|
+
* `coordinator.getOrCreateSectionController({ ... })` and, on
|
|
22
|
+
* successful resolution, dispatches
|
|
23
|
+
* `{ kind: "section-controller-resolved" }` to the core. Init
|
|
24
|
+
* tokens guard against late resolutions overwriting a more
|
|
25
|
+
* recent cohort (mirrors `SectionRuntimeEngine.initialize`'s
|
|
26
|
+
* `activeInitToken` pattern).
|
|
27
|
+
*
|
|
28
|
+
* 3. **Disposal.** On `dispose()`, the bridge unsubscribes from the
|
|
29
|
+
* framework-error bus and (if the engine owns the section
|
|
30
|
+
* controller for the cohort) calls
|
|
31
|
+
* `coordinator.disposeSectionController({ ... })`. It does
|
|
32
|
+
* **not** dispose the coordinator itself — the coordinator's
|
|
33
|
+
* lifetime is owned by the toolkit CE / host, not by the engine.
|
|
34
|
+
*
|
|
35
|
+
* Disposal is idempotent: calling `dispose()` twice is a no-op.
|
|
36
|
+
*
|
|
37
|
+
* The bridge **must not** import `svelte`.
|
|
38
|
+
*/
|
|
39
|
+
import type { SectionControllerHandle } from "../../services/section-controller-types.js";
|
|
40
|
+
import type { CohortKey } from "../core/cohort.js";
|
|
41
|
+
import type { SectionEngineInput } from "../core/engine-input.js";
|
|
42
|
+
/**
|
|
43
|
+
* Subset of the `ToolkitCoordinator` surface the bridge consumes. Kept
|
|
44
|
+
* structural so tests can pass a fake without pulling the full
|
|
45
|
+
* coordinator.
|
|
46
|
+
*/
|
|
47
|
+
export interface CoordinatorPort {
|
|
48
|
+
subscribeFrameworkErrors(listener: (model: import("../../services/framework-error.js").FrameworkErrorModel) => void): () => void;
|
|
49
|
+
getOrCreateSectionController(args: {
|
|
50
|
+
sectionId: string;
|
|
51
|
+
attemptId?: string;
|
|
52
|
+
input?: unknown;
|
|
53
|
+
updateExisting?: boolean;
|
|
54
|
+
createDefaultController: () => SectionControllerHandle | Promise<SectionControllerHandle>;
|
|
55
|
+
}): Promise<SectionControllerHandle>;
|
|
56
|
+
disposeSectionController(args: {
|
|
57
|
+
sectionId: string;
|
|
58
|
+
attemptId?: string;
|
|
59
|
+
}): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
export interface ResolveSectionControllerArgs {
|
|
62
|
+
cohort: CohortKey;
|
|
63
|
+
assessmentId: string;
|
|
64
|
+
view: string;
|
|
65
|
+
section: unknown;
|
|
66
|
+
createDefaultController: () => SectionControllerHandle | Promise<SectionControllerHandle>;
|
|
67
|
+
/**
|
|
68
|
+
* Optional callback invoked when the controller resolves and on
|
|
69
|
+
* every controller `subscribe` event. The kernel uses this to keep
|
|
70
|
+
* its composition snapshot in sync with the controller's view.
|
|
71
|
+
*
|
|
72
|
+
* The bridge is responsible for unsubscribing on dispose / cohort
|
|
73
|
+
* change so a stale controller doesn't keep emitting after rollover.
|
|
74
|
+
*/
|
|
75
|
+
onCompositionChanged?: (composition: unknown) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Optional callback invoked once with the resolved controller handle
|
|
78
|
+
* the moment it is available. Lets the host keep a reference for
|
|
79
|
+
* direct method calls (e.g. `navigateToItem`, `applySession`)
|
|
80
|
+
* without re-querying the coordinator.
|
|
81
|
+
*/
|
|
82
|
+
onControllerResolved?: (controller: SectionControllerHandle) => void;
|
|
83
|
+
}
|
|
84
|
+
export interface CoordinatorBridgeOptions {
|
|
85
|
+
coordinator: CoordinatorPort;
|
|
86
|
+
dispatchCoreInput: (input: SectionEngineInput) => void;
|
|
87
|
+
}
|
|
88
|
+
export interface CoordinatorBridgeHandle {
|
|
89
|
+
resolveSectionController(args: ResolveSectionControllerArgs): Promise<void>;
|
|
90
|
+
dispose(): Promise<void>;
|
|
91
|
+
}
|
|
92
|
+
export declare function createCoordinatorBridge(options: CoordinatorBridgeOptions): CoordinatorBridgeHandle;
|
|
93
|
+
//# sourceMappingURL=coordinator-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator-bridge.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/coordinator-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAEX,uBAAuB,EACvB,MAAM,4CAA4C,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC/B,wBAAwB,CACvB,QAAQ,EAAE,CACT,KAAK,EAAE,OAAO,mCAAmC,EAAE,mBAAmB,KAClE,IAAI,GACP,MAAM,IAAI,CAAC;IAEd,4BAA4B,CAAC,IAAI,EAAE;QAClC,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,uBAAuB,EAAE,MACtB,uBAAuB,GACvB,OAAO,CAAC,uBAAuB,CAAC,CAAC;KACpC,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAErC,wBAAwB,CAAC,IAAI,EAAE;QAC9B,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,4BAA4B;IAC5C,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,uBAAuB,EAAE,MACtB,uBAAuB,GACvB,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACpC;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACrE;AAED,MAAM,WAAW,wBAAwB;IACxC,WAAW,EAAE,eAAe,CAAC;IAC7B,iBAAiB,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,uBAAuB;IACvC,wBAAwB,CAAC,IAAI,EAAE,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,wBAAgB,uBAAuB,CACtC,OAAO,EAAE,wBAAwB,GAC/B,uBAAuB,CA8GzB"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coordinator bridge for the section runtime engine adapter (M7 —
|
|
3
|
+
* Variant C, layered).
|
|
4
|
+
*
|
|
5
|
+
* Unlike the DOM / legacy / framework-error bridges (which translate
|
|
6
|
+
* **outputs** into I/O), the coordinator bridge is an **input source**:
|
|
7
|
+
* it listens to a `ToolkitCoordinator` and feeds the resulting events
|
|
8
|
+
* into the core via the `dispatchCoreInput` callback supplied by the
|
|
9
|
+
* adapter.
|
|
10
|
+
*
|
|
11
|
+
* Responsibilities:
|
|
12
|
+
* 1. **Framework-error subscription.** When the coordinator reports
|
|
13
|
+
* a framework error through its bus, dispatch a
|
|
14
|
+
* `{ kind: "framework-error" }` core input. Listener isolation
|
|
15
|
+
* matches `FrameworkErrorBus`: a throwing bridge handler is
|
|
16
|
+
* caught and `console.warn`-logged so the original fan-out is
|
|
17
|
+
* not interrupted.
|
|
18
|
+
*
|
|
19
|
+
* 2. **Section-controller resolution.** When the host calls
|
|
20
|
+
* `resolveSectionController({ ... })`, the bridge invokes
|
|
21
|
+
* `coordinator.getOrCreateSectionController({ ... })` and, on
|
|
22
|
+
* successful resolution, dispatches
|
|
23
|
+
* `{ kind: "section-controller-resolved" }` to the core. Init
|
|
24
|
+
* tokens guard against late resolutions overwriting a more
|
|
25
|
+
* recent cohort (mirrors `SectionRuntimeEngine.initialize`'s
|
|
26
|
+
* `activeInitToken` pattern).
|
|
27
|
+
*
|
|
28
|
+
* 3. **Disposal.** On `dispose()`, the bridge unsubscribes from the
|
|
29
|
+
* framework-error bus and (if the engine owns the section
|
|
30
|
+
* controller for the cohort) calls
|
|
31
|
+
* `coordinator.disposeSectionController({ ... })`. It does
|
|
32
|
+
* **not** dispose the coordinator itself — the coordinator's
|
|
33
|
+
* lifetime is owned by the toolkit CE / host, not by the engine.
|
|
34
|
+
*
|
|
35
|
+
* Disposal is idempotent: calling `dispose()` twice is a no-op.
|
|
36
|
+
*
|
|
37
|
+
* The bridge **must not** import `svelte`.
|
|
38
|
+
*/
|
|
39
|
+
export function createCoordinatorBridge(options) {
|
|
40
|
+
const { coordinator, dispatchCoreInput } = options;
|
|
41
|
+
let activeInitToken = 0;
|
|
42
|
+
let activeCohort = null;
|
|
43
|
+
let unsubscribeController = null;
|
|
44
|
+
let disposed = false;
|
|
45
|
+
const unsubscribeFrameworkErrors = coordinator.subscribeFrameworkErrors((model) => {
|
|
46
|
+
try {
|
|
47
|
+
dispatchCoreInput({ kind: "framework-error", error: model });
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.warn("[CoordinatorBridge] framework-error dispatch failed:", error);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
function detachControllerSubscription() {
|
|
54
|
+
if (!unsubscribeController)
|
|
55
|
+
return;
|
|
56
|
+
try {
|
|
57
|
+
unsubscribeController();
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.warn("[CoordinatorBridge] controller unsubscribe failed:", error);
|
|
61
|
+
}
|
|
62
|
+
unsubscribeController = null;
|
|
63
|
+
}
|
|
64
|
+
async function resolveSectionController(args) {
|
|
65
|
+
if (disposed)
|
|
66
|
+
return;
|
|
67
|
+
activeInitToken += 1;
|
|
68
|
+
const token = activeInitToken;
|
|
69
|
+
activeCohort = args.cohort;
|
|
70
|
+
const controller = await coordinator.getOrCreateSectionController({
|
|
71
|
+
sectionId: args.cohort.sectionId,
|
|
72
|
+
attemptId: args.cohort.attemptId || undefined,
|
|
73
|
+
input: {
|
|
74
|
+
section: args.section,
|
|
75
|
+
sectionId: args.cohort.sectionId,
|
|
76
|
+
assessmentId: args.assessmentId,
|
|
77
|
+
view: args.view,
|
|
78
|
+
},
|
|
79
|
+
updateExisting: true,
|
|
80
|
+
createDefaultController: args.createDefaultController,
|
|
81
|
+
});
|
|
82
|
+
// Drop late resolutions — a cohort change or dispose may have
|
|
83
|
+
// rolled the token forward while we awaited the coordinator.
|
|
84
|
+
if (token !== activeInitToken || disposed)
|
|
85
|
+
return;
|
|
86
|
+
detachControllerSubscription();
|
|
87
|
+
args.onControllerResolved?.(controller);
|
|
88
|
+
const getCompositionModel = controller.getCompositionModel;
|
|
89
|
+
args.onCompositionChanged?.(getCompositionModel?.());
|
|
90
|
+
if (typeof controller.subscribe === "function") {
|
|
91
|
+
unsubscribeController = controller.subscribe((_event) => {
|
|
92
|
+
if (token !== activeInitToken || disposed)
|
|
93
|
+
return;
|
|
94
|
+
args.onCompositionChanged?.(getCompositionModel?.());
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
dispatchCoreInput({ kind: "section-controller-resolved" });
|
|
98
|
+
}
|
|
99
|
+
async function dispose() {
|
|
100
|
+
if (disposed)
|
|
101
|
+
return;
|
|
102
|
+
disposed = true;
|
|
103
|
+
activeInitToken += 1;
|
|
104
|
+
detachControllerSubscription();
|
|
105
|
+
try {
|
|
106
|
+
unsubscribeFrameworkErrors();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
console.warn("[CoordinatorBridge] framework-error unsubscribe failed:", error);
|
|
110
|
+
}
|
|
111
|
+
const cohort = activeCohort;
|
|
112
|
+
activeCohort = null;
|
|
113
|
+
if (cohort) {
|
|
114
|
+
try {
|
|
115
|
+
await coordinator.disposeSectionController({
|
|
116
|
+
sectionId: cohort.sectionId,
|
|
117
|
+
attemptId: cohort.attemptId || undefined,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
console.warn("[CoordinatorBridge] section-controller dispose failed:", error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { resolveSectionController, dispose };
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=coordinator-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator-bridge.js","sourceRoot":"","sources":["../../../src/runtime/adapter/coordinator-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM event bridge for the section runtime engine adapter (M7 — Variant
|
|
3
|
+
* C, layered).
|
|
4
|
+
*
|
|
5
|
+
* Translates canonical engine outputs (`stage-change`,
|
|
6
|
+
* `loading-complete`, `framework-error`) into DOM `CustomEvent`
|
|
7
|
+
* dispatches on the host element. Mirrors the kernel's existing
|
|
8
|
+
* `dispatch("pie-stage-change", …)` / `dispatch("pie-loading-complete", …)`
|
|
9
|
+
* / `dispatch("framework-error", …)` emit chain bit-for-bit so the M6
|
|
10
|
+
* canonical event surface stays stable while the kernel migrates onto
|
|
11
|
+
* the engine in PR 5.
|
|
12
|
+
*
|
|
13
|
+
* **Detail-shape contract.** The engine core emits structurally minimal
|
|
14
|
+
* outputs (`{ stage, status, cohort }`, `{ cohort, itemCount,
|
|
15
|
+
* loadedCount }`). The bridge enriches them with `runtimeId`,
|
|
16
|
+
* `sourceCe`, and `timestamp` so the dispatched DOM event detail
|
|
17
|
+
* matches the legacy
|
|
18
|
+
* `packages/players-shared/src/pie/stages.ts#StageChangeDetail` and
|
|
19
|
+
* `LoadingCompleteDetail` shapes verbatim. `runtimeId` and `sourceCe`
|
|
20
|
+
* are supplied at adapter construction time (one per engine instance);
|
|
21
|
+
* `timestamp` is captured per-emit via the injected `now()` clock so
|
|
22
|
+
* tests can pin a deterministic value.
|
|
23
|
+
*
|
|
24
|
+
* **Why not import the stage tracker.** The tracker's monotonic /
|
|
25
|
+
* skipped-fill enforcement now lives in the engine core's transition
|
|
26
|
+
* function. The bridge is purely an output-to-DOM translator — it does
|
|
27
|
+
* not gate emissions, does not re-order, does not de-duplicate. That
|
|
28
|
+
* keeps the responsibility clean and matches the "outputs are already
|
|
29
|
+
* ordered correctly by the core" contract from
|
|
30
|
+
* `engine-transition.ts`.
|
|
31
|
+
*
|
|
32
|
+
* The bridge **must not** import `svelte`; per the M7 layering
|
|
33
|
+
* constraint the adapter is plain TS.
|
|
34
|
+
*/
|
|
35
|
+
import type { SectionEngineOutput } from "../core/engine-output.js";
|
|
36
|
+
export interface DomEventBridgeOptions {
|
|
37
|
+
/** Element on which to dispatch the DOM events. */
|
|
38
|
+
host: EventTarget;
|
|
39
|
+
/** Stable runtime id for this engine instance. */
|
|
40
|
+
runtimeId: string;
|
|
41
|
+
/**
|
|
42
|
+
* Tag name of the host CE without the `--version-<encoded>` suffix.
|
|
43
|
+
* Each layout CE that mounts the kernel passes its own canonical tag
|
|
44
|
+
* name; the toolkit CE passes its own.
|
|
45
|
+
*/
|
|
46
|
+
sourceCe: string;
|
|
47
|
+
/**
|
|
48
|
+
* Clock injection for tests. Defaults to `() => new Date().toISOString()`.
|
|
49
|
+
*/
|
|
50
|
+
now?: () => string;
|
|
51
|
+
}
|
|
52
|
+
export interface DomEventBridgeHandle {
|
|
53
|
+
/** Translate a single engine output into a DOM dispatch. */
|
|
54
|
+
dispatch(output: SectionEngineOutput): void;
|
|
55
|
+
/**
|
|
56
|
+
* Update the host element after construction (e.g. when the kernel
|
|
57
|
+
* receives its host element via Svelte action / context). The
|
|
58
|
+
* bridge keeps the latest host; future dispatches go to that host.
|
|
59
|
+
*/
|
|
60
|
+
setHost(host: EventTarget): void;
|
|
61
|
+
}
|
|
62
|
+
export declare function createDomEventBridge(options: DomEventBridgeOptions): DomEventBridgeHandle;
|
|
63
|
+
//# sourceMappingURL=dom-event-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom-event-bridge.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/dom-event-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,WAAW,qBAAqB;IACrC,mDAAmD;IACnD,IAAI,EAAE,WAAW,CAAC;IAClB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACpC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC5C;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;CACjC;AAED,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,qBAAqB,GAC5B,oBAAoB,CA6EtB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM event bridge for the section runtime engine adapter (M7 — Variant
|
|
3
|
+
* C, layered).
|
|
4
|
+
*
|
|
5
|
+
* Translates canonical engine outputs (`stage-change`,
|
|
6
|
+
* `loading-complete`, `framework-error`) into DOM `CustomEvent`
|
|
7
|
+
* dispatches on the host element. Mirrors the kernel's existing
|
|
8
|
+
* `dispatch("pie-stage-change", …)` / `dispatch("pie-loading-complete", …)`
|
|
9
|
+
* / `dispatch("framework-error", …)` emit chain bit-for-bit so the M6
|
|
10
|
+
* canonical event surface stays stable while the kernel migrates onto
|
|
11
|
+
* the engine in PR 5.
|
|
12
|
+
*
|
|
13
|
+
* **Detail-shape contract.** The engine core emits structurally minimal
|
|
14
|
+
* outputs (`{ stage, status, cohort }`, `{ cohort, itemCount,
|
|
15
|
+
* loadedCount }`). The bridge enriches them with `runtimeId`,
|
|
16
|
+
* `sourceCe`, and `timestamp` so the dispatched DOM event detail
|
|
17
|
+
* matches the legacy
|
|
18
|
+
* `packages/players-shared/src/pie/stages.ts#StageChangeDetail` and
|
|
19
|
+
* `LoadingCompleteDetail` shapes verbatim. `runtimeId` and `sourceCe`
|
|
20
|
+
* are supplied at adapter construction time (one per engine instance);
|
|
21
|
+
* `timestamp` is captured per-emit via the injected `now()` clock so
|
|
22
|
+
* tests can pin a deterministic value.
|
|
23
|
+
*
|
|
24
|
+
* **Why not import the stage tracker.** The tracker's monotonic /
|
|
25
|
+
* skipped-fill enforcement now lives in the engine core's transition
|
|
26
|
+
* function. The bridge is purely an output-to-DOM translator — it does
|
|
27
|
+
* not gate emissions, does not re-order, does not de-duplicate. That
|
|
28
|
+
* keeps the responsibility clean and matches the "outputs are already
|
|
29
|
+
* ordered correctly by the core" contract from
|
|
30
|
+
* `engine-transition.ts`.
|
|
31
|
+
*
|
|
32
|
+
* The bridge **must not** import `svelte`; per the M7 layering
|
|
33
|
+
* constraint the adapter is plain TS.
|
|
34
|
+
*/
|
|
35
|
+
export function createDomEventBridge(options) {
|
|
36
|
+
const { runtimeId, sourceCe } = options;
|
|
37
|
+
let host = options.host;
|
|
38
|
+
const now = options.now ?? (() => new Date().toISOString());
|
|
39
|
+
function dispatchStageChange(output) {
|
|
40
|
+
const detail = {
|
|
41
|
+
stage: output.stage,
|
|
42
|
+
status: output.status,
|
|
43
|
+
runtimeId,
|
|
44
|
+
sectionId: output.cohort?.sectionId,
|
|
45
|
+
attemptId: output.cohort?.attemptId ? output.cohort.attemptId : undefined,
|
|
46
|
+
timestamp: now(),
|
|
47
|
+
sourceCe,
|
|
48
|
+
};
|
|
49
|
+
host.dispatchEvent(new CustomEvent("pie-stage-change", { detail }));
|
|
50
|
+
}
|
|
51
|
+
function dispatchLoadingComplete(output) {
|
|
52
|
+
const detail = {
|
|
53
|
+
runtimeId,
|
|
54
|
+
sectionId: output.cohort.sectionId,
|
|
55
|
+
attemptId: output.cohort.attemptId ? output.cohort.attemptId : undefined,
|
|
56
|
+
itemCount: output.itemCount,
|
|
57
|
+
loadedCount: output.loadedCount,
|
|
58
|
+
timestamp: now(),
|
|
59
|
+
sourceCe,
|
|
60
|
+
};
|
|
61
|
+
host.dispatchEvent(new CustomEvent("pie-loading-complete", {
|
|
62
|
+
detail,
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
function dispatchFrameworkError(output) {
|
|
66
|
+
// Mirror the kernel's existing surface — the `framework-error`
|
|
67
|
+
// DOM event detail is the framework-error model. The
|
|
68
|
+
// `framework-error-bridge` separately reports the same model
|
|
69
|
+
// into the bus so subscribers see one fan-out per error.
|
|
70
|
+
host.dispatchEvent(new CustomEvent("framework-error", { detail: output.error }));
|
|
71
|
+
}
|
|
72
|
+
function dispatch(output) {
|
|
73
|
+
switch (output.kind) {
|
|
74
|
+
case "stage-change":
|
|
75
|
+
dispatchStageChange(output);
|
|
76
|
+
return;
|
|
77
|
+
case "loading-complete":
|
|
78
|
+
dispatchLoadingComplete(output);
|
|
79
|
+
return;
|
|
80
|
+
case "framework-error":
|
|
81
|
+
dispatchFrameworkError(output);
|
|
82
|
+
return;
|
|
83
|
+
default: {
|
|
84
|
+
const exhaustive = output;
|
|
85
|
+
void exhaustive;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function setHost(next) {
|
|
91
|
+
host = next;
|
|
92
|
+
}
|
|
93
|
+
return { dispatch, setHost };
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=dom-event-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom-event-bridge.js","sourceRoot":"","sources":["../../../src/runtime/adapter/dom-event-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAoCH,MAAM,UAAU,oBAAoB,CACnC,OAA8B;IAE9B,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACxC,IAAI,IAAI,GAAgB,OAAO,CAAC,IAAI,CAAC;IACrC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAE5D,SAAS,mBAAmB,CAC3B,MAA8D;QAE9D,MAAM,MAAM,GAAsB;YACjC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS;YACT,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS;YACnC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACzE,SAAS,EAAE,GAAG,EAAE;YAChB,QAAQ;SACR,CAAC;QACF,IAAI,CAAC,aAAa,CACjB,IAAI,WAAW,CAAoB,kBAAkB,EAAE,EAAE,MAAM,EAAE,CAAC,CAClE,CAAC;IACH,CAAC;IAED,SAAS,uBAAuB,CAC/B,MAAkE;QAElE,MAAM,MAAM,GAA0B;YACrC,SAAS;YACT,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS;YAClC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACxE,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,SAAS,EAAE,GAAG,EAAE;YAChB,QAAQ;SACR,CAAC;QACF,IAAI,CAAC,aAAa,CACjB,IAAI,WAAW,CAAwB,sBAAsB,EAAE;YAC9D,MAAM;SACN,CAAC,CACF,CAAC;IACH,CAAC;IAED,SAAS,sBAAsB,CAC9B,MAAiE;QAEjE,+DAA+D;QAC/D,qDAAqD;QACrD,6DAA6D;QAC7D,yDAAyD;QACzD,IAAI,CAAC,aAAa,CACjB,IAAI,WAAW,CAAC,iBAAiB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAC5D,CAAC;IACH,CAAC;IAED,SAAS,QAAQ,CAAC,MAA2B;QAC5C,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,cAAc;gBAClB,mBAAmB,CAAC,MAAM,CAAC,CAAC;gBAC5B,OAAO;YACR,KAAK,kBAAkB;gBACtB,uBAAuB,CAAC,MAAM,CAAC,CAAC;gBAChC,OAAO;YACR,KAAK,iBAAiB;gBACrB,sBAAsB,CAAC,MAAM,CAAC,CAAC;gBAC/B,OAAO;YACR,OAAO,CAAC,CAAC,CAAC;gBACT,MAAM,UAAU,GAAU,MAAM,CAAC;gBACjC,KAAK,UAAU,CAAC;gBAChB,OAAO;YACR,CAAC;QACF,CAAC;IACF,CAAC;IAED,SAAS,OAAO,CAAC,IAAiB;QACjC,IAAI,GAAG,IAAI,CAAC;IACb,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-error bridge for the section runtime engine adapter (M7 —
|
|
3
|
+
* Variant C, layered).
|
|
4
|
+
*
|
|
5
|
+
* Routes `framework-error` engine outputs into a `FrameworkErrorBus`
|
|
6
|
+
* (write side: `FrameworkErrorReporter`). The bus is the single
|
|
7
|
+
* fan-out point shared with the toolkit CE's banner, the coordinator's
|
|
8
|
+
* canonical `onFrameworkError` lifecycle hook, and any direct host
|
|
9
|
+
* subscribers via `subscribeFrameworkErrors`. See
|
|
10
|
+
* `packages/assessment-toolkit/src/services/framework-error-bus.ts`
|
|
11
|
+
* for the full bus contract.
|
|
12
|
+
*
|
|
13
|
+
* **Why a separate bridge.** The dom-event-bridge dispatches the
|
|
14
|
+
* `framework-error` DOM event on the host. The framework-error-bridge
|
|
15
|
+
* routes the same model into the in-process bus so listeners that
|
|
16
|
+
* subscribe via `coordinator.subscribeFrameworkErrors(...)` see the
|
|
17
|
+
* same fan-out with byte-identical payloads. Splitting the
|
|
18
|
+
* responsibilities lets a host opt out of either side (DOM-only or
|
|
19
|
+
* bus-only) without re-implementing the other.
|
|
20
|
+
*
|
|
21
|
+
* **Bus ownership.** The bridge does not construct the bus; the
|
|
22
|
+
* adapter receives one externally so the toolkit CE can keep sharing
|
|
23
|
+
* its bus with the coordinator (matching today's
|
|
24
|
+
* `PieAssessmentToolkit.svelte` lifetime model). This avoids the
|
|
25
|
+
* "second bus" pitfall — a dual-bus topology would silently fragment
|
|
26
|
+
* fan-out.
|
|
27
|
+
*/
|
|
28
|
+
import type { FrameworkErrorReporter } from "../../services/framework-error-bus.js";
|
|
29
|
+
import type { SectionEngineOutput } from "../core/engine-output.js";
|
|
30
|
+
export interface FrameworkErrorBridgeOptions {
|
|
31
|
+
bus: FrameworkErrorReporter;
|
|
32
|
+
}
|
|
33
|
+
export interface FrameworkErrorBridgeHandle {
|
|
34
|
+
dispatch(output: SectionEngineOutput): void;
|
|
35
|
+
}
|
|
36
|
+
export declare function createFrameworkErrorBridge(options: FrameworkErrorBridgeOptions): FrameworkErrorBridgeHandle;
|
|
37
|
+
//# sourceMappingURL=framework-error-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-error-bridge.d.ts","sourceRoot":"","sources":["../../../src/runtime/adapter/framework-error-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AACpF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,WAAW,2BAA2B;IAC3C,GAAG,EAAE,sBAAsB,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC5C;AAED,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,2BAA2B,GAClC,0BAA0B,CAoB5B"}
|