@pie-players/pie-assessment-toolkit 0.3.30 → 0.3.31
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 +1 -1
- 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 +264 -6
- package/dist/services/ToolkitCoordinator.d.ts.map +1 -1
- package/dist/services/ToolkitCoordinator.js +350 -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/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
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ provider path is the item-player loader config:
|
|
|
88
88
|
- `pie-toolkit-runtime-inherited`
|
|
89
89
|
- `pie-toolkit-ready`
|
|
90
90
|
- `pie-toolkit-section-ready`
|
|
91
|
-
- `pie-toolkit-
|
|
91
|
+
- `pie-toolkit-framework-error`
|
|
92
92
|
|
|
93
93
|
Toolkit tool/backend operational stream:
|
|
94
94
|
|
|
@@ -114,6 +114,130 @@ See [ToolkitCoordinator Architecture](../../docs/architecture/TOOLKIT_COORDINATO
|
|
|
114
114
|
6. **Element-Level Granularity**: Tool state tracked per PIE element, not per item
|
|
115
115
|
7. **State Separation**: Tool state (ephemeral) separate from PIE session data (persistent)
|
|
116
116
|
|
|
117
|
+
## Configuration tiers: easy attribute + sophisticated `runtime`
|
|
118
|
+
|
|
119
|
+
This package and `@pie-players/pie-section-player` follow a deliberate
|
|
120
|
+
two-tier configuration model. The same knob can usually be set in either
|
|
121
|
+
tier; the choice is about ergonomics, not capability.
|
|
122
|
+
|
|
123
|
+
### When to use each tier
|
|
124
|
+
|
|
125
|
+
- **Easy tier — top-level CE attributes / properties.** Use these for the
|
|
126
|
+
common cases that are static for the lifetime of the player or that hosts
|
|
127
|
+
want to set declaratively in HTML / templating frameworks. Example:
|
|
128
|
+
|
|
129
|
+
```html
|
|
130
|
+
<pie-assessment-toolkit
|
|
131
|
+
assessment-id="my-assessment"
|
|
132
|
+
section-id="s-1"
|
|
133
|
+
tool-config-strictness="warn"
|
|
134
|
+
></pie-assessment-toolkit>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
- **Sophisticated tier — passing a constructed `ToolkitCoordinator` (or a
|
|
138
|
+
`runtime` object on consumer CEs).** Use this for advanced cases: composed
|
|
139
|
+
configuration, dynamic overrides, runtime mutation, fields without a
|
|
140
|
+
tier-1 attribute, or anything that benefits from being a single typed
|
|
141
|
+
object passed by reference. Example:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
const coordinator = new ToolkitCoordinator({
|
|
145
|
+
assessmentId: "my-assessment",
|
|
146
|
+
toolConfigStrictness: "warn",
|
|
147
|
+
tools: {
|
|
148
|
+
providers: { calculator: { enabled: true } },
|
|
149
|
+
placement: { item: ["calculator", "textToSpeech"] },
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
el.coordinator = coordinator;
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Naming rule
|
|
156
|
+
|
|
157
|
+
The easy-tier attribute name is the kebab-cased version of the runtime /
|
|
158
|
+
config key. `tool-config-strictness` ↔ `toolConfigStrictness`,
|
|
159
|
+
`assessment-id` ↔ `assessmentId`, `player-type` ↔ `playerType`. Hosts can
|
|
160
|
+
move a knob from the easy tier to the configuration object (or back)
|
|
161
|
+
without renaming.
|
|
162
|
+
|
|
163
|
+
### Precedence rule
|
|
164
|
+
|
|
165
|
+
The configuration object wins. When the same knob is set in both tiers,
|
|
166
|
+
resolution is:
|
|
167
|
+
|
|
168
|
+
1. The constructed `ToolkitCoordinator` config (or `runtime.<key>` on a
|
|
169
|
+
consumer CE) if set
|
|
170
|
+
2. Top-level attribute / property if set
|
|
171
|
+
3. Documented default
|
|
172
|
+
|
|
173
|
+
This applies symmetrically to `pie-assessment-toolkit` itself and to
|
|
174
|
+
section-player CEs that embed it. New knobs MUST follow this precedence;
|
|
175
|
+
do not add ad-hoc fall-throughs.
|
|
176
|
+
|
|
177
|
+
### Canonical tier-1 attribute set
|
|
178
|
+
|
|
179
|
+
The tier-1 attribute set is the same shape across
|
|
180
|
+
`pie-assessment-toolkit`, `pie-section-player-base`, and the
|
|
181
|
+
`pie-section-player-*` layout elements (locked in M5). Every tier-1
|
|
182
|
+
surface obeys the strict mirror rule:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
kebab-attribute ↔ camelCaseProp ↔ runtime.<sameCamelCaseKey>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Common members include:
|
|
189
|
+
|
|
190
|
+
- Identity: `assessment-id`, `section-id`, `attempt-id`
|
|
191
|
+
- Player: `player-type`, `lazy-init`
|
|
192
|
+
- Tools: `tools` (object property), `tool-registry` (object property),
|
|
193
|
+
`enabled-tools` (shorthand for `tools.placement.section`)
|
|
194
|
+
- Coordination: `coordinator` (`createSectionController` is a
|
|
195
|
+
runtime-only key on the section-player layout CEs — see
|
|
196
|
+
"Documented exceptions" below; `<pie-assessment-toolkit>` accepts
|
|
197
|
+
it as a direct JS prop on its own composition surface)
|
|
198
|
+
- Accessibility: `accessibility` (object property; the deprecated
|
|
199
|
+
`accessibility` *attribute* mapping was removed in M5)
|
|
200
|
+
- Diagnostics: `tool-config-strictness`, `debug`. Framework-error
|
|
201
|
+
delivery is via the canonical `onFrameworkError` callback prop and the
|
|
202
|
+
`framework-error` DOM event dispatched on the layout CE host.
|
|
203
|
+
|
|
204
|
+
Documented exceptions to the mirror rule:
|
|
205
|
+
|
|
206
|
+
- Identity (`section-id`, `attempt-id`, `section`): per-attempt host
|
|
207
|
+
state, not configuration.
|
|
208
|
+
- Layout-only shell knobs on the section-player layout CEs
|
|
209
|
+
(`show-toolbar`, `toolbar-position`, `narrow-layout-breakpoint`,
|
|
210
|
+
`split-pane-collapse-strategy`): layout-CE rendering concerns.
|
|
211
|
+
- Per-region toolbar tool placement: hosts populate
|
|
212
|
+
`tools.placement.item` / `tools.placement.passage` (object form) or
|
|
213
|
+
`runtime.tools.placement.{item,passage}` directly. The previously
|
|
214
|
+
deprecated `item-toolbar-tools` / `passage-toolbar-tools` attribute
|
|
215
|
+
aliases were removed in the broad architecture review compat sweep.
|
|
216
|
+
- Runtime-only keys on the section-player layout CEs
|
|
217
|
+
(`createSectionController`, `isolation`): accepted only via
|
|
218
|
+
`runtime.<key>`. The top-level prop aliases were removed in the
|
|
219
|
+
broad architecture review compat sweep. `<pie-assessment-toolkit>`
|
|
220
|
+
itself keeps `createSectionController` and `isolation` as JS-only
|
|
221
|
+
props (no kebab-attribute surface): section-player layouts forward
|
|
222
|
+
`runtime.isolation` and `runtime.createSectionController` to the
|
|
223
|
+
wrapped toolkit via property bindings; standalone hosts that need
|
|
224
|
+
to override coordinator inheritance should pass an explicit
|
|
225
|
+
`coordinator={...}` instead.
|
|
226
|
+
|
|
227
|
+
### When to add a tier-1 attribute
|
|
228
|
+
|
|
229
|
+
Add a tier-1 attribute only if all of the following hold:
|
|
230
|
+
|
|
231
|
+
- It is a common case that hosts set without composing a `ToolkitCoordinator`
|
|
232
|
+
/ `runtime` object.
|
|
233
|
+
- Its value is a primitive or small typed object that round-trips through
|
|
234
|
+
HTML attributes (string, boolean-like, number; structured data passes via
|
|
235
|
+
property assignment).
|
|
236
|
+
- It exists on every CE that conceptually owns the same knob, or has a
|
|
237
|
+
deliberate documented exclusion.
|
|
238
|
+
|
|
239
|
+
Otherwise expose it through the configuration object only.
|
|
240
|
+
|
|
117
241
|
## Quick Start
|
|
118
242
|
|
|
119
243
|
### Option 1: Use ToolkitCoordinator (Recommended)
|
|
@@ -562,8 +686,7 @@ The persistence strategy works with the same `SectionControllerSessionState` sha
|
|
|
562
686
|
|
|
563
687
|
### ✅ Core Infrastructure
|
|
564
688
|
|
|
565
|
-
- **TypedEventBus**:
|
|
566
|
-
- **Event Types**: Complete event definitions (player, tools, navigation, state, interaction)
|
|
689
|
+
- **TypedEventBus**: Generic type-safe `EventTarget` wrapper exported as a building block. The toolkit's own production events are emitted via DOM `CustomEvent`s on `<pie-assessment-toolkit>` and via `ToolkitCoordinator.subscribe*` helpers, not through this bus. Hosts and downstream packages may still use it to compose their own typed event maps.
|
|
567
690
|
|
|
568
691
|
### ✅ Toolkit Services
|
|
569
692
|
|
|
@@ -945,7 +1068,7 @@ player.section = mySection;
|
|
|
945
1068
|
Default behavior is now framework-owned: invalid tools/runtime initialization is handled in `pie-assessment-toolkit` without host try/catch.
|
|
946
1069
|
|
|
947
1070
|
- Framework logs a deterministic console error prefix: `[pie-framework:<kind>:<source>]`
|
|
948
|
-
- Framework emits a canonical `framework-error` event
|
|
1071
|
+
- Framework emits a canonical `framework-error` event
|
|
949
1072
|
- Framework renders a fallback error panel instead of a blank player
|
|
950
1073
|
- Startup tool-config validation can surface as `kind: "coordinator-init"` when the owned coordinator construction path throws.
|
|
951
1074
|
|
|
@@ -987,9 +1110,169 @@ Notes:
|
|
|
987
1110
|
- `providers.textToSpeech` is the canonical TTS provider key.
|
|
988
1111
|
- `providers.tts` is rejected by the validation contract.
|
|
989
1112
|
- Custom tools can provide provider-level `sanitizeConfig` and `validateConfig` hooks.
|
|
990
|
-
- Hosts can react to framework errors via `
|
|
1113
|
+
- Hosts can react to framework errors via the `framework-error` DOM event,
|
|
1114
|
+
the `onFrameworkError(model)` callback prop, or by subscribing directly
|
|
1115
|
+
to the package-internal bus via
|
|
1116
|
+
`ToolkitCoordinator.subscribeFrameworkErrors(listener)`. The callback
|
|
1117
|
+
prop fires exactly once per error, regardless of wrapper depth. Filter
|
|
1118
|
+
by `model.kind` (e.g. `"tts-init"`, `"provider-init"`,
|
|
1119
|
+
`"provider-register"`) for tool- or provider-specific handling.
|
|
991
1120
|
- See `docs/tools-and-accomodations/framework-owned-error-handling.md` for event payload and error-kind mapping details.
|
|
992
1121
|
|
|
1122
|
+
## Section Runtime Engine (advanced)
|
|
1123
|
+
|
|
1124
|
+
The toolkit exposes a layered **section runtime engine** that consolidates
|
|
1125
|
+
runtime resolution, FSM-driven stage progression, framework-error reporting,
|
|
1126
|
+
DOM-event fan-out, and instrumentation into a single object hosts can mount
|
|
1127
|
+
and dispose. The engine is what `<pie-section-player-…>` and
|
|
1128
|
+
`<pie-assessment-toolkit>` use internally, and it is also the surface
|
|
1129
|
+
custom hosts (or alternate layout shells) consume directly.
|
|
1130
|
+
|
|
1131
|
+
### Two import paths
|
|
1132
|
+
|
|
1133
|
+
The engine ships with two deliberately separate entry points so consumers
|
|
1134
|
+
pick the stability surface that matches their use case:
|
|
1135
|
+
|
|
1136
|
+
- **Stable facade — `@pie-players/pie-assessment-toolkit/runtime/engine`.**
|
|
1137
|
+
Narrow, semver-stable surface for hosts that want to mount, drive, and
|
|
1138
|
+
dispose a section runtime. Re-exports `SectionRuntimeEngine`,
|
|
1139
|
+
`SECTION_RUNTIME_ENGINE_KEY` (Svelte context), the cross-CE host
|
|
1140
|
+
context (`sectionRuntimeEngineHostContext`), and the consumer-side
|
|
1141
|
+
helper for that bridge (`connectSectionRuntimeEngineHostContext`).
|
|
1142
|
+
- **Internal surface — `@pie-players/pie-assessment-toolkit/runtime/internal`.**
|
|
1143
|
+
Wider, evolving surface for advanced hosts that need to construct an
|
|
1144
|
+
engine manually, inspect FSM state, or build alternate fan-out paths.
|
|
1145
|
+
Exposes `SectionEngineCore`, the four adapter bridges
|
|
1146
|
+
(`createDomEventBridge`, `createFrameworkErrorBridge`,
|
|
1147
|
+
`createCoordinatorBridge`, `createInstrumentationBridge`),
|
|
1148
|
+
`FrameworkErrorBus`, cohort helpers,
|
|
1149
|
+
and the `resolveRuntime` / `resolveToolsConfig` /
|
|
1150
|
+
`resolveSectionEngineRuntimeState` helpers. Symbols here may change
|
|
1151
|
+
between minor versions with a changeset note.
|
|
1152
|
+
|
|
1153
|
+
### Single-engine invariant
|
|
1154
|
+
|
|
1155
|
+
When `<pie-assessment-toolkit>` is nested inside a section-player layout,
|
|
1156
|
+
the layout kernel publishes its engine reference via
|
|
1157
|
+
`sectionRuntimeEngineHostContext`. The toolkit detects that upstream
|
|
1158
|
+
engine and **suppresses its own external lifecycle DOM emits and stage
|
|
1159
|
+
tracker** in favor of the kernel's engine. From the outside, one cohort
|
|
1160
|
+
yields one `pie-stage-change` / `pie-loading-complete` chain on the
|
|
1161
|
+
layout CE host regardless of wrapper depth — even though, during the
|
|
1162
|
+
0.x line, the toolkit still constructs a local engine instance for its
|
|
1163
|
+
controller-side surface (`register`, `handleContent*`, `initialize`).
|
|
1164
|
+
A future release collapses the toolkit's controller-side surface onto
|
|
1165
|
+
the upstream engine; until then the externally observable invariant —
|
|
1166
|
+
**one cohort, one canonical event chain** — is what hosts should rely
|
|
1167
|
+
on. A standalone `<pie-assessment-toolkit>` (no upstream context)
|
|
1168
|
+
emits from its own engine.
|
|
1169
|
+
|
|
1170
|
+
**Detection.** If a custom layout shell emits two `pie-stage-change`
|
|
1171
|
+
events per stage transition (or two `pie-loading-complete` per cohort)
|
|
1172
|
+
on the same layout CE — typically with two distinct `detail.runtimeId`
|
|
1173
|
+
values — the shell has not published its engine via
|
|
1174
|
+
`sectionRuntimeEngineHostContext`, so the wrapped
|
|
1175
|
+
`<pie-assessment-toolkit>` falls back to its standalone path and
|
|
1176
|
+
constructs a second engine. Wire the bridge as shown below.
|
|
1177
|
+
|
|
1178
|
+
### Common-host wiring example
|
|
1179
|
+
|
|
1180
|
+
Most hosts never construct the engine directly — the section-player
|
|
1181
|
+
layout CE and the toolkit CE handle it. Use the facade only when
|
|
1182
|
+
building an alternate layout shell (e.g. a custom kernel host). The
|
|
1183
|
+
shape mirrors what the section-player kernel does internally:
|
|
1184
|
+
|
|
1185
|
+
```ts
|
|
1186
|
+
import { ContextProvider } from "@pie-players/pie-context";
|
|
1187
|
+
import {
|
|
1188
|
+
SectionRuntimeEngine,
|
|
1189
|
+
sectionRuntimeEngineHostContext,
|
|
1190
|
+
} from "@pie-players/pie-assessment-toolkit/runtime/engine";
|
|
1191
|
+
import {
|
|
1192
|
+
FrameworkErrorBus,
|
|
1193
|
+
makeCohort,
|
|
1194
|
+
} from "@pie-players/pie-assessment-toolkit/runtime/internal";
|
|
1195
|
+
|
|
1196
|
+
const bus = new FrameworkErrorBus();
|
|
1197
|
+
const engine = new SectionRuntimeEngine();
|
|
1198
|
+
|
|
1199
|
+
// 1. Attach to the layout CE host. `sourceCe` is stamped onto every
|
|
1200
|
+
// DOM event the engine dispatches and is required.
|
|
1201
|
+
engine.attachHost({
|
|
1202
|
+
host: layoutHostElement,
|
|
1203
|
+
sourceCe: "my-custom-layout",
|
|
1204
|
+
frameworkErrorBus: bus,
|
|
1205
|
+
coordinator: toolkitCoordinator,
|
|
1206
|
+
});
|
|
1207
|
+
|
|
1208
|
+
// 2. Publish the engine reference on the layout CE host so any
|
|
1209
|
+
// wrapped <pie-assessment-toolkit> consumes it instead of
|
|
1210
|
+
// constructing its own (single-engine invariant).
|
|
1211
|
+
const engineProvider = new ContextProvider(layoutHostElement, {
|
|
1212
|
+
context: sectionRuntimeEngineHostContext,
|
|
1213
|
+
initialValue: { engine },
|
|
1214
|
+
});
|
|
1215
|
+
engineProvider.connect();
|
|
1216
|
+
|
|
1217
|
+
// 3. (Optional) Subscribe to the structured output stream — same set
|
|
1218
|
+
// of outputs the DOM-event bridge fans out to the host element.
|
|
1219
|
+
engine.subscribe((output) => {
|
|
1220
|
+
// tap stage transitions, readiness updates, framework errors,
|
|
1221
|
+
// instrumentation events
|
|
1222
|
+
});
|
|
1223
|
+
|
|
1224
|
+
// 4. Drive the engine. Use real `SectionEngineInput` shapes:
|
|
1225
|
+
const cohort = makeCohort({ sectionId, attemptId });
|
|
1226
|
+
engine.dispatchInput({
|
|
1227
|
+
kind: "initialize",
|
|
1228
|
+
cohort,
|
|
1229
|
+
effectiveRuntime,
|
|
1230
|
+
effectiveToolsConfig,
|
|
1231
|
+
itemCount,
|
|
1232
|
+
});
|
|
1233
|
+
|
|
1234
|
+
// On loading-progress / readiness signal updates:
|
|
1235
|
+
engine.dispatchInput({
|
|
1236
|
+
kind: "update-readiness-signals",
|
|
1237
|
+
signals: {
|
|
1238
|
+
sectionReady,
|
|
1239
|
+
interactionReady,
|
|
1240
|
+
allLoadingComplete,
|
|
1241
|
+
runtimeError,
|
|
1242
|
+
},
|
|
1243
|
+
loadedCount,
|
|
1244
|
+
itemCount,
|
|
1245
|
+
mode: "progressive",
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
// On unmount:
|
|
1249
|
+
engineProvider.disconnect();
|
|
1250
|
+
engine.dispose();
|
|
1251
|
+
```
|
|
1252
|
+
|
|
1253
|
+
The DOM events `pie-stage-change`, `pie-loading-complete`, and
|
|
1254
|
+
`framework-error` are dispatched on `host` automatically by the
|
|
1255
|
+
adapter's `dom-event-bridge`. The canonical `onFrameworkError` callback
|
|
1256
|
+
prop and the package-internal `FrameworkErrorBus` deliver each error
|
|
1257
|
+
exactly once regardless of wrapper depth. The `framework-error` DOM
|
|
1258
|
+
event on the layout CE host also delivers each error exactly once: the
|
|
1259
|
+
section-player kernel intercepts the toolkit's bubbled emit at
|
|
1260
|
+
`<pie-section-player-base>` and calls `event.stopPropagation()`, so the
|
|
1261
|
+
layout host sees only the canonical engine-bridge emit. Direct
|
|
1262
|
+
listeners on `<pie-assessment-toolkit>` itself still see the toolkit's
|
|
1263
|
+
own emit (the toolkit dispatch reaches them before the kernel listener
|
|
1264
|
+
runs). The single-emit contract is pinned by
|
|
1265
|
+
`packages/section-player/tests/section-player-framework-error-dual-emit.test.ts`.
|
|
1266
|
+
The previous dual-emit on the layout host was removed in the broad
|
|
1267
|
+
architecture review compat sweep.
|
|
1268
|
+
|
|
1269
|
+
The deprecated readiness aliases (`readiness-change`,
|
|
1270
|
+
`interaction-ready`, `ready`) and their `legacy-event-bridge` were
|
|
1271
|
+
removed in the broad architecture review compat sweep. Hosts that
|
|
1272
|
+
listened for them migrate to `pie-stage-change` (with the readiness
|
|
1273
|
+
detail also available via the kernel's `selectReadiness()`) and
|
|
1274
|
+
`pie-loading-complete`.
|
|
1275
|
+
|
|
993
1276
|
## State Separation: Tool State vs Session Data
|
|
994
1277
|
|
|
995
1278
|
The toolkit enforces a clear separation between ephemeral tool state and persistent session data:
|
|
@@ -1088,6 +1371,7 @@ from tool configuration. Two sanitization layers apply:
|
|
|
1088
1371
|
- **[PNP Configuration Guide](docs/PNP_CONFIGURATION.md)** - ⭐ NEW - How to configure student profiles, district policies, and governance rules
|
|
1089
1372
|
- [ToolkitCoordinator Architecture](../../docs/architecture/TOOLKIT_COORDINATOR.md) - Design decisions and patterns
|
|
1090
1373
|
- [Section Player README](../section-player/README.md) - Section player integration
|
|
1374
|
+
- [Section Player Architecture](../section-player/ARCHITECTURE.md#layered-runtime-engine-post-m7) - Layered runtime engine, kernel/toolkit wiring, single-engine invariant
|
|
1091
1375
|
- [Framework-Owned Error Handling](../../docs/tools-and-accomodations/framework-owned-error-handling.md) - Canonical framework error model/events and fallback behavior
|
|
1092
1376
|
- [Safe Custom Tool Configuration](../../docs/tools-and-accomodations/safe-custom-tool-config.md) - Host-side config patterns and validation guidance
|
|
1093
1377
|
- [Architecture Overview](../../docs/architecture/architecture.md) - Complete system architecture
|