@pie-players/pie-assessment-toolkit 0.3.44 → 0.3.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/README.md +59 -70
  2. package/dist/components/ItemToolBar.custom-element.js +776 -357
  3. package/dist/components/PieAssessmentToolkit.custom-element.js +19501 -3591
  4. package/dist/components/SectionToolBar.custom-element.js +1058 -540
  5. package/dist/index.d.ts +3 -6
  6. package/dist/index.js +1 -3
  7. package/dist/index.js.map +1 -1
  8. package/dist/policy/core/ToolPolicyEngine.d.ts +1 -2
  9. package/dist/policy/core/ToolPolicyEngine.js +1 -2
  10. package/dist/policy/core/ToolPolicyEngine.js.map +1 -1
  11. package/dist/policy/core/pnp-policy-inputs.d.ts +2 -3
  12. package/dist/policy/core/pnp-policy-inputs.js +2 -3
  13. package/dist/policy/core/pnp-policy-inputs.js.map +1 -1
  14. package/dist/policy/core/provenance.d.ts +7 -34
  15. package/dist/policy/core/provenance.js +4 -21
  16. package/dist/policy/core/provenance.js.map +1 -1
  17. package/dist/policy/sources/PnpPolicySource.d.ts +6 -19
  18. package/dist/policy/sources/PnpPolicySource.js +6 -19
  19. package/dist/policy/sources/PnpPolicySource.js.map +1 -1
  20. package/dist/runtime/SectionRuntimeEngine.d.ts +13 -28
  21. package/dist/runtime/SectionRuntimeEngine.js +13 -27
  22. package/dist/runtime/SectionRuntimeEngine.js.map +1 -1
  23. package/dist/runtime/adapter/SectionEngineAdapter.d.ts +2 -2
  24. package/dist/runtime/adapter/SectionEngineAdapter.js +2 -2
  25. package/dist/runtime/adapter/SectionEngineAdapter.js.map +1 -1
  26. package/dist/runtime/adapter/coordinator-bridge.d.ts +1 -1
  27. package/dist/runtime/adapter/coordinator-bridge.js +1 -1
  28. package/dist/runtime/adapter/coordinator-bridge.js.map +1 -1
  29. package/dist/runtime/adapter/dom-event-bridge.d.ts +1 -1
  30. package/dist/runtime/adapter/dom-event-bridge.js +1 -1
  31. package/dist/runtime/adapter/dom-event-bridge.js.map +1 -1
  32. package/dist/runtime/catalog-registration.d.ts +12 -0
  33. package/dist/runtime/catalog-registration.js +54 -0
  34. package/dist/runtime/catalog-registration.js.map +1 -0
  35. package/dist/runtime/core/engine-output.d.ts +2 -2
  36. package/dist/runtime/core/engine-output.js +2 -2
  37. package/dist/runtime/core/engine-output.js.map +1 -1
  38. package/dist/runtime/core/engine-readiness.d.ts +2 -2
  39. package/dist/runtime/core/engine-readiness.js.map +1 -1
  40. package/dist/runtime/core/engine-resolver.d.ts +13 -41
  41. package/dist/runtime/core/engine-resolver.js +19 -76
  42. package/dist/runtime/core/engine-resolver.js.map +1 -1
  43. package/dist/runtime/core/engine-transition.d.ts +1 -1
  44. package/dist/runtime/core/engine-transition.js +1 -1
  45. package/dist/runtime/core/engine-transition.js.map +1 -1
  46. package/dist/runtime/engine.d.ts +1 -1
  47. package/dist/runtime/engine.js.map +1 -1
  48. package/dist/runtime/section-runtime-engine-host-context.d.ts +22 -15
  49. package/dist/runtime/section-runtime-engine-host-context.js +10 -10
  50. package/dist/runtime/section-runtime-engine-host-context.js.map +1 -1
  51. package/dist/runtime/stage-emit-gate.d.ts +4 -4
  52. package/dist/runtime/stage-emit-gate.js +3 -3
  53. package/dist/runtime/stage-emit-gate.js.map +1 -1
  54. package/dist/services/AccessibilityCatalogResolver.d.ts +23 -0
  55. package/dist/services/AccessibilityCatalogResolver.js +200 -28
  56. package/dist/services/AccessibilityCatalogResolver.js.map +1 -1
  57. package/dist/services/HighlightCoordinator.d.ts +25 -0
  58. package/dist/services/HighlightCoordinator.js +125 -0
  59. package/dist/services/HighlightCoordinator.js.map +1 -1
  60. package/dist/services/SSMLExtractor.d.ts +16 -1
  61. package/dist/services/SSMLExtractor.js +86 -7
  62. package/dist/services/SSMLExtractor.js.map +1 -1
  63. package/dist/services/TTSService.d.ts +30 -4
  64. package/dist/services/TTSService.js +652 -159
  65. package/dist/services/TTSService.js.map +1 -1
  66. package/dist/services/ToolRegistry.d.ts +11 -2
  67. package/dist/services/ToolRegistry.js +1 -1
  68. package/dist/services/ToolRegistry.js.map +1 -1
  69. package/dist/services/ToolkitCoordinator.d.ts +16 -73
  70. package/dist/services/ToolkitCoordinator.js +34 -113
  71. package/dist/services/ToolkitCoordinator.js.map +1 -1
  72. package/dist/services/interfaces.d.ts +20 -2
  73. package/dist/services/interfaces.js.map +1 -1
  74. package/dist/services/tool-config-validation.d.ts +1 -1
  75. package/dist/services/tool-config-validation.js +7 -7
  76. package/dist/services/tool-config-validation.js.map +1 -1
  77. package/dist/services/tool-instance-id.js +1 -1
  78. package/dist/services/tool-instance-id.js.map +1 -1
  79. package/dist/services/tool-providers/TTSToolProvider.js +3 -3
  80. package/dist/services/tool-providers/TTSToolProvider.js.map +1 -1
  81. package/dist/services/tools-config-normalizer.d.ts +13 -2
  82. package/dist/services/tools-config-normalizer.js +3 -8
  83. package/dist/services/tools-config-normalizer.js.map +1 -1
  84. package/dist/services/tts/browser-provider.js +2 -0
  85. package/dist/services/tts/browser-provider.js.map +1 -1
  86. package/dist/services/tts/catalog-span-alignment.d.ts +39 -0
  87. package/dist/services/tts/catalog-span-alignment.js +300 -0
  88. package/dist/services/tts/catalog-span-alignment.js.map +1 -0
  89. package/dist/services/tts/generated-speech/assemble-plan.d.ts +33 -0
  90. package/dist/services/tts/generated-speech/assemble-plan.js +111 -0
  91. package/dist/services/tts/generated-speech/assemble-plan.js.map +1 -0
  92. package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +25 -0
  93. package/dist/services/tts/generated-speech/dom/build-dom-plan.js +66 -0
  94. package/dist/services/tts/generated-speech/dom/build-dom-plan.js.map +1 -0
  95. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.d.ts +19 -0
  96. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.js +71 -0
  97. package/dist/services/tts/generated-speech/dom/to-chunk-inputs.js.map +1 -0
  98. package/dist/services/tts/generated-speech/dom/types.d.ts +37 -0
  99. package/dist/services/tts/generated-speech/dom/types.js +2 -0
  100. package/dist/services/tts/generated-speech/dom/types.js.map +1 -0
  101. package/dist/services/tts/generated-speech/index.d.ts +17 -0
  102. package/dist/services/tts/generated-speech/index.js +17 -0
  103. package/dist/services/tts/generated-speech/index.js.map +1 -0
  104. package/dist/services/tts/generated-speech/math-speech-cache.d.ts +15 -0
  105. package/dist/services/tts/generated-speech/math-speech-cache.js +78 -0
  106. package/dist/services/tts/generated-speech/math-speech-cache.js.map +1 -0
  107. package/dist/services/tts/generated-speech/types.d.ts +104 -0
  108. package/dist/services/tts/generated-speech/types.js +18 -0
  109. package/dist/services/tts/generated-speech/types.js.map +1 -0
  110. package/dist/services/tts/highlight-pipeline/boundary-normalizer.d.ts +2 -0
  111. package/dist/services/tts/highlight-pipeline/boundary-normalizer.js +106 -0
  112. package/dist/services/tts/highlight-pipeline/boundary-normalizer.js.map +1 -0
  113. package/dist/services/tts/highlight-pipeline/create-highlight-plan.d.ts +6 -0
  114. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +217 -0
  115. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js.map +1 -0
  116. package/dist/services/tts/highlight-pipeline/highlight-policy.d.ts +2 -0
  117. package/dist/services/tts/highlight-pipeline/highlight-policy.js +32 -0
  118. package/dist/services/tts/highlight-pipeline/highlight-policy.js.map +1 -0
  119. package/dist/services/tts/highlight-pipeline/index.d.ts +9 -0
  120. package/dist/services/tts/highlight-pipeline/index.js +9 -0
  121. package/dist/services/tts/highlight-pipeline/index.js.map +1 -0
  122. package/dist/services/tts/highlight-pipeline/math-semantic-resolver.d.ts +3 -0
  123. package/dist/services/tts/highlight-pipeline/math-semantic-resolver.js +32 -0
  124. package/dist/services/tts/highlight-pipeline/math-semantic-resolver.js.map +1 -0
  125. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.d.ts +29 -0
  126. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js +44 -0
  127. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js.map +1 -0
  128. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.d.ts +2 -0
  129. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +20 -0
  130. package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js.map +1 -0
  131. package/dist/services/tts/highlight-pipeline/readable-region.d.ts +1 -0
  132. package/dist/services/tts/highlight-pipeline/readable-region.js +19 -0
  133. package/dist/services/tts/highlight-pipeline/readable-region.js.map +1 -0
  134. package/dist/services/tts/highlight-pipeline/rendered-math-target-resolver.d.ts +6 -0
  135. package/dist/services/tts/highlight-pipeline/rendered-math-target-resolver.js +198 -0
  136. package/dist/services/tts/highlight-pipeline/rendered-math-target-resolver.js.map +1 -0
  137. package/dist/services/tts/highlight-pipeline/types.d.ts +72 -0
  138. package/dist/services/tts/highlight-pipeline/types.js +2 -0
  139. package/dist/services/tts/highlight-pipeline/types.js.map +1 -0
  140. package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +2 -0
  141. package/dist/services/tts/highlight-pipeline/visible-map-range.js +22 -0
  142. package/dist/services/tts/highlight-pipeline/visible-map-range.js.map +1 -0
  143. package/dist/services/tts/math-alignment/index.d.ts +30 -0
  144. package/dist/services/tts/math-alignment/index.js +66 -0
  145. package/dist/services/tts/math-alignment/index.js.map +1 -0
  146. package/dist/services/tts/math-alignment/mathml-tokenizer.d.ts +2 -0
  147. package/dist/services/tts/math-alignment/mathml-tokenizer.js +317 -0
  148. package/dist/services/tts/math-alignment/mathml-tokenizer.js.map +1 -0
  149. package/dist/services/tts/math-alignment/range-resolver.d.ts +10 -0
  150. package/dist/services/tts/math-alignment/range-resolver.js +13 -0
  151. package/dist/services/tts/math-alignment/range-resolver.js.map +1 -0
  152. package/dist/services/tts/math-alignment/sequence-aligner.d.ts +7 -0
  153. package/dist/services/tts/math-alignment/sequence-aligner.js +119 -0
  154. package/dist/services/tts/math-alignment/sequence-aligner.js.map +1 -0
  155. package/dist/services/tts/math-alignment/speech-tokenizer.d.ts +31 -0
  156. package/dist/services/tts/math-alignment/speech-tokenizer.js +143 -0
  157. package/dist/services/tts/math-alignment/speech-tokenizer.js.map +1 -0
  158. package/dist/services/tts/math-alignment/types.d.ts +58 -0
  159. package/dist/services/tts/math-alignment/types.js +2 -0
  160. package/dist/services/tts/math-alignment/types.js.map +1 -0
  161. package/dist/services/tts/math-aware-text-processing.d.ts +18 -0
  162. package/dist/services/tts/math-aware-text-processing.js +348 -0
  163. package/dist/services/tts/math-aware-text-processing.js.map +1 -0
  164. package/dist/services/tts/math-speech.d.ts +44 -0
  165. package/dist/services/tts/math-speech.js +147 -0
  166. package/dist/services/tts/math-speech.js.map +1 -0
  167. package/dist/services/tts/mathml-sanitization.d.ts +1 -0
  168. package/dist/services/tts/mathml-sanitization.js +170 -0
  169. package/dist/services/tts/mathml-sanitization.js.map +1 -0
  170. package/dist/services/tts/ssml/spoken-text.d.ts +33 -0
  171. package/dist/services/tts/ssml/spoken-text.js +159 -0
  172. package/dist/services/tts/ssml/spoken-text.js.map +1 -0
  173. package/dist/services/tts/text-processing.d.ts +3 -0
  174. package/dist/services/tts/text-processing.js +30 -4
  175. package/dist/services/tts/text-processing.js.map +1 -1
  176. package/dist/services/tts-runtime-config.d.ts +17 -1
  177. package/dist/services/tts-runtime-config.js +11 -1
  178. package/dist/services/tts-runtime-config.js.map +1 -1
  179. package/dist/tools/registrations/accessibility-tools.js +0 -1
  180. package/dist/tools/registrations/accessibility-tools.js.map +1 -1
  181. package/dist/tools/registrations/calculator.js +46 -5
  182. package/dist/tools/registrations/calculator.js.map +1 -1
  183. package/dist/tools/tool-tag-map.js +0 -1
  184. package/dist/tools/tool-tag-map.js.map +1 -1
  185. package/package.json +8 -11
  186. package/dist/services/PNPToolResolver.d.ts +0 -280
  187. package/dist/services/PNPToolResolver.js +0 -514
  188. package/dist/services/PNPToolResolver.js.map +0 -1
  189. package/dist/services/pnp-provenance.d.ts +0 -166
  190. package/dist/services/pnp-provenance.js +0 -231
  191. package/dist/services/pnp-provenance.js.map +0 -1
@@ -1 +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","sourcesContent":["/**\n * DOM event bridge for the section runtime engine adapter (M7 — Variant\n * C, layered).\n *\n * Translates canonical engine outputs (`stage-change`,\n * `loading-complete`, `framework-error`) into DOM `CustomEvent`\n * dispatches on the host element. Mirrors the kernel's existing\n * `dispatch(\"pie-stage-change\", …)` / `dispatch(\"pie-loading-complete\", …)`\n * / `dispatch(\"framework-error\", …)` emit chain bit-for-bit so the M6\n * canonical event surface stays stable while the kernel migrates onto\n * the engine in PR 5.\n *\n * **Detail-shape contract.** The engine core emits structurally minimal\n * outputs (`{ stage, status, cohort }`, `{ cohort, itemCount,\n * loadedCount }`). The bridge enriches them with `runtimeId`,\n * `sourceCe`, and `timestamp` so the dispatched DOM event detail\n * matches the legacy\n * `packages/players-shared/src/pie/stages.ts#StageChangeDetail` and\n * `LoadingCompleteDetail` shapes verbatim. `runtimeId` and `sourceCe`\n * are supplied at adapter construction time (one per engine instance);\n * `timestamp` is captured per-emit via the injected `now()` clock so\n * tests can pin a deterministic value.\n *\n * **Why not import the stage tracker.** The tracker's monotonic /\n * skipped-fill enforcement now lives in the engine core's transition\n * function. The bridge is purely an output-to-DOM translator — it does\n * not gate emissions, does not re-order, does not de-duplicate. That\n * keeps the responsibility clean and matches the \"outputs are already\n * ordered correctly by the core\" contract from\n * `engine-transition.ts`.\n *\n * The bridge **must not** import `svelte`; per the M7 layering\n * constraint the adapter is plain TS.\n */\n\nimport type {\n\tLoadingCompleteDetail,\n\tStageChangeDetail,\n} from \"@pie-players/pie-players-shared/pie\";\nimport type { SectionEngineOutput } from \"../core/engine-output.js\";\n\nexport interface DomEventBridgeOptions {\n\t/** Element on which to dispatch the DOM events. */\n\thost: EventTarget;\n\t/** Stable runtime id for this engine instance. */\n\truntimeId: string;\n\t/**\n\t * Tag name of the host CE without the `--version-<encoded>` suffix.\n\t * Each layout CE that mounts the kernel passes its own canonical tag\n\t * name; the toolkit CE passes its own.\n\t */\n\tsourceCe: string;\n\t/**\n\t * Clock injection for tests. Defaults to `() => new Date().toISOString()`.\n\t */\n\tnow?: () => string;\n}\n\nexport interface DomEventBridgeHandle {\n\t/** Translate a single engine output into a DOM dispatch. */\n\tdispatch(output: SectionEngineOutput): void;\n\t/**\n\t * Update the host element after construction (e.g. when the kernel\n\t * receives its host element via Svelte action / context). The\n\t * bridge keeps the latest host; future dispatches go to that host.\n\t */\n\tsetHost(host: EventTarget): void;\n}\n\nexport function createDomEventBridge(\n\toptions: DomEventBridgeOptions,\n): DomEventBridgeHandle {\n\tconst { runtimeId, sourceCe } = options;\n\tlet host: EventTarget = options.host;\n\tconst now = options.now ?? (() => new Date().toISOString());\n\n\tfunction dispatchStageChange(\n\t\toutput: Extract<SectionEngineOutput, { kind: \"stage-change\" }>,\n\t): void {\n\t\tconst detail: StageChangeDetail = {\n\t\t\tstage: output.stage,\n\t\t\tstatus: output.status,\n\t\t\truntimeId,\n\t\t\tsectionId: output.cohort?.sectionId,\n\t\t\tattemptId: output.cohort?.attemptId ? output.cohort.attemptId : undefined,\n\t\t\ttimestamp: now(),\n\t\t\tsourceCe,\n\t\t};\n\t\thost.dispatchEvent(\n\t\t\tnew CustomEvent<StageChangeDetail>(\"pie-stage-change\", { detail }),\n\t\t);\n\t}\n\n\tfunction dispatchLoadingComplete(\n\t\toutput: Extract<SectionEngineOutput, { kind: \"loading-complete\" }>,\n\t): void {\n\t\tconst detail: LoadingCompleteDetail = {\n\t\t\truntimeId,\n\t\t\tsectionId: output.cohort.sectionId,\n\t\t\tattemptId: output.cohort.attemptId ? output.cohort.attemptId : undefined,\n\t\t\titemCount: output.itemCount,\n\t\t\tloadedCount: output.loadedCount,\n\t\t\ttimestamp: now(),\n\t\t\tsourceCe,\n\t\t};\n\t\thost.dispatchEvent(\n\t\t\tnew CustomEvent<LoadingCompleteDetail>(\"pie-loading-complete\", {\n\t\t\t\tdetail,\n\t\t\t}),\n\t\t);\n\t}\n\n\tfunction dispatchFrameworkError(\n\t\toutput: Extract<SectionEngineOutput, { kind: \"framework-error\" }>,\n\t): void {\n\t\t// Mirror the kernel's existing surface — the `framework-error`\n\t\t// DOM event detail is the framework-error model. The\n\t\t// `framework-error-bridge` separately reports the same model\n\t\t// into the bus so subscribers see one fan-out per error.\n\t\thost.dispatchEvent(\n\t\t\tnew CustomEvent(\"framework-error\", { detail: output.error }),\n\t\t);\n\t}\n\n\tfunction dispatch(output: SectionEngineOutput): void {\n\t\tswitch (output.kind) {\n\t\t\tcase \"stage-change\":\n\t\t\t\tdispatchStageChange(output);\n\t\t\t\treturn;\n\t\t\tcase \"loading-complete\":\n\t\t\t\tdispatchLoadingComplete(output);\n\t\t\t\treturn;\n\t\t\tcase \"framework-error\":\n\t\t\t\tdispatchFrameworkError(output);\n\t\t\t\treturn;\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = output;\n\t\t\t\tvoid exhaustive;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction setHost(next: EventTarget): void {\n\t\thost = next;\n\t}\n\n\treturn { dispatch, setHost };\n}\n"]}
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","sourcesContent":["/**\n * DOM event bridge for the section runtime engine adapter (M7 — Variant\n * C, layered).\n *\n * Translates canonical engine outputs (`stage-change`,\n * `loading-complete`, `framework-error`) into DOM `CustomEvent`\n * dispatches on the host element. Mirrors the kernel's existing\n * `dispatch(\"pie-stage-change\", …)` / `dispatch(\"pie-loading-complete\", …)`\n * / `dispatch(\"framework-error\", …)` emit chain bit-for-bit so the M6\n * canonical event surface stays stable while the kernel migrates onto\n * the engine in PR 5.\n *\n * **Detail-shape contract.** The engine core emits structurally minimal\n * outputs (`{ stage, status, cohort }`, `{ cohort, itemCount,\n * loadedCount }`). The bridge enriches them with `runtimeId`,\n * `sourceCe`, and `timestamp` so the dispatched DOM event detail\n * matches the canonical\n * `packages/players-shared/src/pie/stages.ts#StageChangeDetail` and\n * `LoadingCompleteDetail` shapes verbatim. `runtimeId` and `sourceCe`\n * are supplied at adapter construction time (one per engine instance);\n * `timestamp` is captured per-emit via the injected `now()` clock so\n * tests can pin a deterministic value.\n *\n * **Why not import the stage tracker.** The tracker's monotonic /\n * skipped-fill enforcement now lives in the engine core's transition\n * function. The bridge is purely an output-to-DOM translator — it does\n * not gate emissions, does not re-order, does not de-duplicate. That\n * keeps the responsibility clean and matches the \"outputs are already\n * ordered correctly by the core\" contract from\n * `engine-transition.ts`.\n *\n * The bridge **must not** import `svelte`; per the M7 layering\n * constraint the adapter is plain TS.\n */\n\nimport type {\n\tLoadingCompleteDetail,\n\tStageChangeDetail,\n} from \"@pie-players/pie-players-shared/pie\";\nimport type { SectionEngineOutput } from \"../core/engine-output.js\";\n\nexport interface DomEventBridgeOptions {\n\t/** Element on which to dispatch the DOM events. */\n\thost: EventTarget;\n\t/** Stable runtime id for this engine instance. */\n\truntimeId: string;\n\t/**\n\t * Tag name of the host CE without the `--version-<encoded>` suffix.\n\t * Each layout CE that mounts the kernel passes its own canonical tag\n\t * name; the toolkit CE passes its own.\n\t */\n\tsourceCe: string;\n\t/**\n\t * Clock injection for tests. Defaults to `() => new Date().toISOString()`.\n\t */\n\tnow?: () => string;\n}\n\nexport interface DomEventBridgeHandle {\n\t/** Translate a single engine output into a DOM dispatch. */\n\tdispatch(output: SectionEngineOutput): void;\n\t/**\n\t * Update the host element after construction (e.g. when the kernel\n\t * receives its host element via Svelte action / context). The\n\t * bridge keeps the latest host; future dispatches go to that host.\n\t */\n\tsetHost(host: EventTarget): void;\n}\n\nexport function createDomEventBridge(\n\toptions: DomEventBridgeOptions,\n): DomEventBridgeHandle {\n\tconst { runtimeId, sourceCe } = options;\n\tlet host: EventTarget = options.host;\n\tconst now = options.now ?? (() => new Date().toISOString());\n\n\tfunction dispatchStageChange(\n\t\toutput: Extract<SectionEngineOutput, { kind: \"stage-change\" }>,\n\t): void {\n\t\tconst detail: StageChangeDetail = {\n\t\t\tstage: output.stage,\n\t\t\tstatus: output.status,\n\t\t\truntimeId,\n\t\t\tsectionId: output.cohort?.sectionId,\n\t\t\tattemptId: output.cohort?.attemptId ? output.cohort.attemptId : undefined,\n\t\t\ttimestamp: now(),\n\t\t\tsourceCe,\n\t\t};\n\t\thost.dispatchEvent(\n\t\t\tnew CustomEvent<StageChangeDetail>(\"pie-stage-change\", { detail }),\n\t\t);\n\t}\n\n\tfunction dispatchLoadingComplete(\n\t\toutput: Extract<SectionEngineOutput, { kind: \"loading-complete\" }>,\n\t): void {\n\t\tconst detail: LoadingCompleteDetail = {\n\t\t\truntimeId,\n\t\t\tsectionId: output.cohort.sectionId,\n\t\t\tattemptId: output.cohort.attemptId ? output.cohort.attemptId : undefined,\n\t\t\titemCount: output.itemCount,\n\t\t\tloadedCount: output.loadedCount,\n\t\t\ttimestamp: now(),\n\t\t\tsourceCe,\n\t\t};\n\t\thost.dispatchEvent(\n\t\t\tnew CustomEvent<LoadingCompleteDetail>(\"pie-loading-complete\", {\n\t\t\t\tdetail,\n\t\t\t}),\n\t\t);\n\t}\n\n\tfunction dispatchFrameworkError(\n\t\toutput: Extract<SectionEngineOutput, { kind: \"framework-error\" }>,\n\t): void {\n\t\t// Mirror the kernel's existing surface — the `framework-error`\n\t\t// DOM event detail is the framework-error model. The\n\t\t// `framework-error-bridge` separately reports the same model\n\t\t// into the bus so subscribers see one fan-out per error.\n\t\thost.dispatchEvent(\n\t\t\tnew CustomEvent(\"framework-error\", { detail: output.error }),\n\t\t);\n\t}\n\n\tfunction dispatch(output: SectionEngineOutput): void {\n\t\tswitch (output.kind) {\n\t\t\tcase \"stage-change\":\n\t\t\t\tdispatchStageChange(output);\n\t\t\t\treturn;\n\t\t\tcase \"loading-complete\":\n\t\t\t\tdispatchLoadingComplete(output);\n\t\t\t\treturn;\n\t\t\tcase \"framework-error\":\n\t\t\t\tdispatchFrameworkError(output);\n\t\t\t\treturn;\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = output;\n\t\t\t\tvoid exhaustive;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\tfunction setHost(next: EventTarget): void {\n\t\thost = next;\n\t}\n\n\treturn { dispatch, setHost };\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import type { AccessibilityCatalog } from "@pie-players/pie-players-shared/types";
2
+ import type { CatalogOwnerContext } from "../services/AccessibilityCatalogResolver.js";
3
+ import type { RuntimeRegistrationDetail } from "./registration-events.js";
4
+ export interface CatalogRegistrationRuntimeContext {
5
+ assessmentId?: string;
6
+ sectionId?: string;
7
+ }
8
+ export interface CatalogRegistration {
9
+ context: CatalogOwnerContext;
10
+ catalogs: AccessibilityCatalog[];
11
+ }
12
+ export declare function collectCatalogRegistrations(detail: RuntimeRegistrationDetail, runtime?: CatalogRegistrationRuntimeContext): CatalogRegistration[];
@@ -0,0 +1,54 @@
1
+ const hasCatalogs = (catalogs) => Array.isArray(catalogs) && catalogs.length > 0;
2
+ export function collectCatalogRegistrations(detail, runtime = {}) {
3
+ const entity = detail.item;
4
+ if (!entity)
5
+ return [];
6
+ const registrations = [];
7
+ if (detail.kind === "passage") {
8
+ const context = {
9
+ ownerKind: "passage",
10
+ assessmentId: runtime.assessmentId,
11
+ sectionId: runtime.sectionId,
12
+ passageId: detail.canonicalItemId || detail.itemId,
13
+ };
14
+ if (hasCatalogs(entity.accessibilityCatalogs)) {
15
+ registrations.push({ context, catalogs: entity.accessibilityCatalogs });
16
+ }
17
+ if (hasCatalogs(entity.config?.extractedCatalogs)) {
18
+ registrations.push({
19
+ context,
20
+ catalogs: entity.config.extractedCatalogs,
21
+ });
22
+ }
23
+ return registrations;
24
+ }
25
+ const itemContext = {
26
+ ownerKind: "itemModel",
27
+ assessmentId: runtime.assessmentId,
28
+ sectionId: runtime.sectionId,
29
+ itemId: detail.itemId,
30
+ canonicalItemId: detail.canonicalItemId || detail.itemId,
31
+ };
32
+ if (hasCatalogs(entity.accessibilityCatalogs)) {
33
+ registrations.push({
34
+ context: itemContext,
35
+ catalogs: entity.accessibilityCatalogs,
36
+ });
37
+ }
38
+ if (hasCatalogs(entity.config?.extractedCatalogs)) {
39
+ registrations.push({
40
+ context: itemContext,
41
+ catalogs: entity.config.extractedCatalogs,
42
+ });
43
+ }
44
+ for (const model of entity.config?.models ?? []) {
45
+ if (!hasCatalogs(model.accessibilityCatalogs))
46
+ continue;
47
+ registrations.push({
48
+ context: { ...itemContext, modelId: model.id },
49
+ catalogs: model.accessibilityCatalogs,
50
+ });
51
+ }
52
+ return registrations;
53
+ }
54
+ //# sourceMappingURL=catalog-registration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-registration.js","sourceRoot":"","sources":["../../src/runtime/catalog-registration.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,GAAG,CACnB,QAA4C,EACP,EAAE,CACvC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;AAEhD,MAAM,UAAU,2BAA2B,CAC1C,MAAiC,EACjC,UAA6C,EAAE;IAE/C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAwC,CAAC;IAC/D,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,MAAM,aAAa,GAA0B,EAAE,CAAC;IAChD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAwB;YACpC,SAAS,EAAE,SAAS;YACpB,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,MAAM;SAClD,CAAC;QACF,IAAI,WAAW,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,CAAC;YAC/C,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,CAAC;YACnD,aAAa,CAAC,IAAI,CAAC;gBAClB,OAAO;gBACP,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,iBAAiB;aACzC,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,aAAa,CAAC;IACtB,CAAC;IAED,MAAM,WAAW,GAAwB;QACxC,SAAS,EAAE,WAAW;QACtB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,MAAM;KACxD,CAAC;IACF,IAAI,WAAW,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,CAAC;QAC/C,aAAa,CAAC,IAAI,CAAC;YAClB,OAAO,EAAE,WAAW;YACpB,QAAQ,EAAE,MAAM,CAAC,qBAAqB;SACtC,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,CAAC;QACnD,aAAa,CAAC,IAAI,CAAC;YAClB,OAAO,EAAE,WAAW;YACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,iBAAiB;SACzC,CAAC,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;QACjD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,qBAAqB,CAAC;YAAE,SAAS;QACxD,aAAa,CAAC,IAAI,CAAC;YAClB,OAAO,EAAE,EAAE,GAAG,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE;YAC9C,QAAQ,EAAE,KAAK,CAAC,qBAAqB;SACrC,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,aAAa,CAAC;AACtB,CAAC","sourcesContent":["import type { AccessibilityCatalog } from \"@pie-players/pie-players-shared/types\";\nimport type { CatalogOwnerContext } from \"../services/AccessibilityCatalogResolver.js\";\nimport type { RuntimeRegistrationDetail } from \"./registration-events.js\";\n\nexport interface CatalogRegistrationRuntimeContext {\n\tassessmentId?: string;\n\tsectionId?: string;\n}\n\nexport interface CatalogRegistration {\n\tcontext: CatalogOwnerContext;\n\tcatalogs: AccessibilityCatalog[];\n}\n\ntype CatalogSource = {\n\taccessibilityCatalogs?: AccessibilityCatalog[];\n\tconfig?: {\n\t\textractedCatalogs?: AccessibilityCatalog[];\n\t\tmodels?: Array<{\n\t\t\tid?: string;\n\t\t\taccessibilityCatalogs?: AccessibilityCatalog[];\n\t\t}>;\n\t};\n};\n\nconst hasCatalogs = (\n\tcatalogs: AccessibilityCatalog[] | undefined,\n): catalogs is AccessibilityCatalog[] =>\n\tArray.isArray(catalogs) && catalogs.length > 0;\n\nexport function collectCatalogRegistrations(\n\tdetail: RuntimeRegistrationDetail,\n\truntime: CatalogRegistrationRuntimeContext = {},\n): CatalogRegistration[] {\n\tconst entity = detail.item as CatalogSource | null | undefined;\n\tif (!entity) return [];\n\tconst registrations: CatalogRegistration[] = [];\n\tif (detail.kind === \"passage\") {\n\t\tconst context: CatalogOwnerContext = {\n\t\t\townerKind: \"passage\",\n\t\t\tassessmentId: runtime.assessmentId,\n\t\t\tsectionId: runtime.sectionId,\n\t\t\tpassageId: detail.canonicalItemId || detail.itemId,\n\t\t};\n\t\tif (hasCatalogs(entity.accessibilityCatalogs)) {\n\t\t\tregistrations.push({ context, catalogs: entity.accessibilityCatalogs });\n\t\t}\n\t\tif (hasCatalogs(entity.config?.extractedCatalogs)) {\n\t\t\tregistrations.push({\n\t\t\t\tcontext,\n\t\t\t\tcatalogs: entity.config.extractedCatalogs,\n\t\t\t});\n\t\t}\n\t\treturn registrations;\n\t}\n\n\tconst itemContext: CatalogOwnerContext = {\n\t\townerKind: \"itemModel\",\n\t\tassessmentId: runtime.assessmentId,\n\t\tsectionId: runtime.sectionId,\n\t\titemId: detail.itemId,\n\t\tcanonicalItemId: detail.canonicalItemId || detail.itemId,\n\t};\n\tif (hasCatalogs(entity.accessibilityCatalogs)) {\n\t\tregistrations.push({\n\t\t\tcontext: itemContext,\n\t\t\tcatalogs: entity.accessibilityCatalogs,\n\t\t});\n\t}\n\tif (hasCatalogs(entity.config?.extractedCatalogs)) {\n\t\tregistrations.push({\n\t\t\tcontext: itemContext,\n\t\t\tcatalogs: entity.config.extractedCatalogs,\n\t\t});\n\t}\n\tfor (const model of entity.config?.models ?? []) {\n\t\tif (!hasCatalogs(model.accessibilityCatalogs)) continue;\n\t\tregistrations.push({\n\t\t\tcontext: { ...itemContext, modelId: model.id },\n\t\t\tcatalogs: model.accessibilityCatalogs,\n\t\t});\n\t}\n\treturn registrations;\n}\n"]}
@@ -15,10 +15,10 @@
15
15
  * item has finished loading. This mirrors today's
16
16
  * `pie-loading-complete` DOM event semantics.
17
17
  *
18
- * The deprecated readiness output kinds (`readiness-change`,
18
+ * Readiness alias output kinds (`readiness-change`,
19
19
  * `interaction-ready`, `ready`) were removed in the broad
20
20
  * architecture review compat sweep along with their DOM-event bridge
21
- * (`legacy-event-bridge.ts`). Stage and readiness changes now flow
21
+ * event bridge. Stage and readiness changes now flow
22
22
  * through `stage-change` (with `EngineReadinessDetail` available via
23
23
  * `SectionEngineCore.getState()` / kernel `selectReadiness()`); the
24
24
  * "all items loaded" signal flows through `loading-complete` only.
@@ -15,10 +15,10 @@
15
15
  * item has finished loading. This mirrors today's
16
16
  * `pie-loading-complete` DOM event semantics.
17
17
  *
18
- * The deprecated readiness output kinds (`readiness-change`,
18
+ * Readiness alias output kinds (`readiness-change`,
19
19
  * `interaction-ready`, `ready`) were removed in the broad
20
20
  * architecture review compat sweep along with their DOM-event bridge
21
- * (`legacy-event-bridge.ts`). Stage and readiness changes now flow
21
+ * event bridge. Stage and readiness changes now flow
22
22
  * through `stage-change` (with `EngineReadinessDetail` available via
23
23
  * `SectionEngineCore.getState()` / kernel `selectReadiness()`); the
24
24
  * "all items loaded" signal flows through `loading-complete` only.
@@ -1 +1 @@
1
- {"version":3,"file":"engine-output.js","sourceRoot":"","sources":["../../../src/runtime/core/engine-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG","sourcesContent":["/**\n * Section runtime engine outputs (M7 — Variant C, layered core).\n *\n * Outputs are the closed discriminated union of effects the transition\n * function returns. The adapter (PR 2) takes the output array, walks\n * it in order, and dispatches each one to the right bridge (DOM\n * events, framework-error bus, subscriber fan-out).\n *\n * Outputs carry only plain data so the transition table can be tested\n * exhaustively without any DOM or coordinator wiring.\n *\n * Adjustment A2 from the M7 implementation plan: `loading-complete`\n * is an output, **not** an FSM phase. The transition emits it from\n * the `interactive` phase when the readiness signals indicate every\n * item has finished loading. This mirrors today's\n * `pie-loading-complete` DOM event semantics.\n *\n * The deprecated readiness output kinds (`readiness-change`,\n * `interaction-ready`, `ready`) were removed in the broad\n * architecture review compat sweep along with their DOM-event bridge\n * (`legacy-event-bridge.ts`). Stage and readiness changes now flow\n * through `stage-change` (with `EngineReadinessDetail` available via\n * `SectionEngineCore.getState()` / kernel `selectReadiness()`); the\n * \"all items loaded\" signal flows through `loading-complete` only.\n */\n\nimport type { Stage, StageStatus } from \"@pie-players/pie-players-shared/pie\";\nimport type { CohortKey } from \"./cohort.js\";\nimport type { FrameworkErrorModel } from \"../../services/framework-error.js\";\n\n/**\n * Stage transition. The adapter dispatches a `pie-stage-change` DOM\n * event with the canonical detail and forwards to subscribers /\n * coordinator. The status indicates whether the stage was entered,\n * skipped, or recorded as failed.\n */\nexport type EngineOutputStageChange = {\n\tkind: \"stage-change\";\n\tstage: Stage;\n\tstatus: StageStatus;\n\tcohort: CohortKey | null;\n};\n\n/**\n * Canonical `pie-loading-complete` emit (M6 D1). One-shot per cohort.\n * Fires from the `interactive` phase when loaded == items count and\n * the readiness signals satisfy `allLoadingComplete`.\n */\nexport type EngineOutputLoadingComplete = {\n\tkind: \"loading-complete\";\n\tcohort: CohortKey;\n\titemCount: number;\n\tloadedCount: number;\n};\n\n/**\n * Framework error fan-out. Mirrors the M3 `framework-error` DOM event\n * and the `subscribeFrameworkErrors` listener channel. Emitted on\n * every `framework-error` input.\n */\nexport type EngineOutputFrameworkError = {\n\tkind: \"framework-error\";\n\terror: FrameworkErrorModel;\n};\n\nexport type SectionEngineOutput =\n\t| EngineOutputStageChange\n\t| EngineOutputLoadingComplete\n\t| EngineOutputFrameworkError;\n"]}
1
+ {"version":3,"file":"engine-output.js","sourceRoot":"","sources":["../../../src/runtime/core/engine-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG","sourcesContent":["/**\n * Section runtime engine outputs (M7 — Variant C, layered core).\n *\n * Outputs are the closed discriminated union of effects the transition\n * function returns. The adapter (PR 2) takes the output array, walks\n * it in order, and dispatches each one to the right bridge (DOM\n * events, framework-error bus, subscriber fan-out).\n *\n * Outputs carry only plain data so the transition table can be tested\n * exhaustively without any DOM or coordinator wiring.\n *\n * Adjustment A2 from the M7 implementation plan: `loading-complete`\n * is an output, **not** an FSM phase. The transition emits it from\n * the `interactive` phase when the readiness signals indicate every\n * item has finished loading. This mirrors today's\n * `pie-loading-complete` DOM event semantics.\n *\n * Readiness alias output kinds (`readiness-change`,\n * `interaction-ready`, `ready`) were removed in the broad\n * architecture review compat sweep along with their DOM-event bridge\n * event bridge. Stage and readiness changes now flow\n * through `stage-change` (with `EngineReadinessDetail` available via\n * `SectionEngineCore.getState()` / kernel `selectReadiness()`); the\n * \"all items loaded\" signal flows through `loading-complete` only.\n */\n\nimport type { Stage, StageStatus } from \"@pie-players/pie-players-shared/pie\";\nimport type { CohortKey } from \"./cohort.js\";\nimport type { FrameworkErrorModel } from \"../../services/framework-error.js\";\n\n/**\n * Stage transition. The adapter dispatches a `pie-stage-change` DOM\n * event with the canonical detail and forwards to subscribers /\n * coordinator. The status indicates whether the stage was entered,\n * skipped, or recorded as failed.\n */\nexport type EngineOutputStageChange = {\n\tkind: \"stage-change\";\n\tstage: Stage;\n\tstatus: StageStatus;\n\tcohort: CohortKey | null;\n};\n\n/**\n * Canonical `pie-loading-complete` emit (M6 D1). One-shot per cohort.\n * Fires from the `interactive` phase when loaded == items count and\n * the readiness signals satisfy `allLoadingComplete`.\n */\nexport type EngineOutputLoadingComplete = {\n\tkind: \"loading-complete\";\n\tcohort: CohortKey;\n\titemCount: number;\n\tloadedCount: number;\n};\n\n/**\n * Framework error fan-out. Mirrors the M3 `framework-error` DOM event\n * and the `subscribeFrameworkErrors` listener channel. Emitted on\n * every `framework-error` input.\n */\nexport type EngineOutputFrameworkError = {\n\tkind: \"framework-error\";\n\terror: FrameworkErrorModel;\n};\n\nexport type SectionEngineOutput =\n\t| EngineOutputStageChange\n\t| EngineOutputLoadingComplete\n\t| EngineOutputFrameworkError;\n"]}
@@ -22,10 +22,10 @@
22
22
  * signals. Surfaced via the kernel's `selectReadiness()` /
23
23
  * `getSnapshot().readiness` selectors; M6 stages own the stage-level
24
24
  * transitions on `pie-stage-change` and use this phase as a
25
- * convenience label only. The deprecated `readiness-change` DOM
25
+ * convenience label only. The `readiness-change` DOM
26
26
  * event that used to surface this directly was removed in the broad
27
27
  * architecture review compat sweep alongside its
28
- * `legacy-event-bridge`.
28
+ * event bridge.
29
29
  */
30
30
  export type EngineReadinessPhase = "bootstrapping" | "interaction-ready" | "loading" | "ready" | "error";
31
31
  export type EngineReadinessSignals = {
@@ -1 +1 @@
1
- {"version":3,"file":"engine-readiness.js","sourceRoot":"","sources":["../../../src/runtime/core/engine-readiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAiCH,MAAM,UAAU,qBAAqB,CACpC,OAA+B;IAE/B,IAAI,OAAO,CAAC,YAAY;QAAE,OAAO,OAAO,CAAC;IACzC,IAAI,OAAO,CAAC,kBAAkB;QAAE,OAAO,OAAO,CAAC;IAC/C,IAAI,OAAO,CAAC,gBAAgB;QAAE,OAAO,mBAAmB,CAAC;IACzD,IAAI,OAAO,CAAC,YAAY;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO,eAAe,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAIrC;IACA,8EAA8E;IAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;IAChF,MAAM,gBAAgB,GACrB,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC;IACrE,MAAM,KAAK,GAAG,qBAAqB,CAAC;QACnC,GAAG,IAAI,CAAC,OAAO;QACf,kBAAkB,EAAE,UAAU;QAC9B,gBAAgB;KAChB,CAAC,CAAC;IAEH,OAAO;QACN,KAAK;QACL,gBAAgB;QAChB,kBAAkB,EAAE,UAAU;QAC9B,MAAM,EAAE,IAAI,CAAC,MAAM;KACnB,CAAC;AACH,CAAC","sourcesContent":["/**\n * Readiness derivation for the section runtime engine (M7).\n *\n * Canonical home of `createReadinessDetail` and `resolveReadinessPhase`.\n * As of M7 PR 7 the previous duplicates in\n * `packages/section-player/src/components/shared/section-player-readiness.ts`\n * have been deleted; section-player now consumes these helpers via\n * `@pie-players/pie-assessment-toolkit/runtime/internal`.\n *\n * Type duplication note: the public DOM-event detail aliases\n * (`SectionPlayerReadinessChangeDetail` /\n * `SectionPlayerReadinessPhase`) still live in section-player's\n * `contracts/public-events.ts` because that file is part of section-\n * player's published custom-element contract. The toolkit core defines\n * `EngineReadinessPhase` independently so it has zero section-player\n * imports. The two definitions must stay structurally identical;\n * that invariant is covered by the readiness assertions in this\n * package's tests, which mirror the section-player suite.\n */\n\n/**\n * Coarse readiness phase label, derived from the four readiness\n * signals. Surfaced via the kernel's `selectReadiness()` /\n * `getSnapshot().readiness` selectors; M6 stages own the stage-level\n * transitions on `pie-stage-change` and use this phase as a\n * convenience label only. The deprecated `readiness-change` DOM\n * event that used to surface this directly was removed in the broad\n * architecture review compat sweep alongside its\n * `legacy-event-bridge`.\n */\nexport type EngineReadinessPhase =\n\t| \"bootstrapping\"\n\t| \"interaction-ready\"\n\t| \"loading\"\n\t| \"ready\"\n\t| \"error\";\n\nexport type EngineReadinessSignals = {\n\tsectionReady: boolean;\n\tinteractionReady: boolean;\n\tallLoadingComplete: boolean;\n\truntimeError: boolean;\n};\n\nexport type EngineReadinessDetail = {\n\tphase: EngineReadinessPhase;\n\tinteractionReady: boolean;\n\tallLoadingComplete: boolean;\n\treason?: string;\n};\n\nexport function resolveReadinessPhase(\n\tsignals: EngineReadinessSignals,\n): EngineReadinessPhase {\n\tif (signals.runtimeError) return \"error\";\n\tif (signals.allLoadingComplete) return \"ready\";\n\tif (signals.interactionReady) return \"interaction-ready\";\n\tif (signals.sectionReady) return \"loading\";\n\treturn \"bootstrapping\";\n}\n\nexport function createReadinessDetail(args: {\n\tmode: \"progressive\" | \"strict\";\n\tsignals: EngineReadinessSignals;\n\treason?: string;\n}): EngineReadinessDetail {\n\t// Final ready must always be gated by section lifecycle and complete loading.\n\tconst finalReady = args.signals.sectionReady && args.signals.allLoadingComplete;\n\tconst interactionReady =\n\t\targs.mode === \"strict\" ? finalReady : args.signals.interactionReady;\n\tconst phase = resolveReadinessPhase({\n\t\t...args.signals,\n\t\tallLoadingComplete: finalReady,\n\t\tinteractionReady,\n\t});\n\n\treturn {\n\t\tphase,\n\t\tinteractionReady,\n\t\tallLoadingComplete: finalReady,\n\t\treason: args.reason,\n\t};\n}\n"]}
1
+ {"version":3,"file":"engine-readiness.js","sourceRoot":"","sources":["../../../src/runtime/core/engine-readiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAiCH,MAAM,UAAU,qBAAqB,CACpC,OAA+B;IAE/B,IAAI,OAAO,CAAC,YAAY;QAAE,OAAO,OAAO,CAAC;IACzC,IAAI,OAAO,CAAC,kBAAkB;QAAE,OAAO,OAAO,CAAC;IAC/C,IAAI,OAAO,CAAC,gBAAgB;QAAE,OAAO,mBAAmB,CAAC;IACzD,IAAI,OAAO,CAAC,YAAY;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO,eAAe,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAIrC;IACA,8EAA8E;IAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;IAChF,MAAM,gBAAgB,GACrB,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC;IACrE,MAAM,KAAK,GAAG,qBAAqB,CAAC;QACnC,GAAG,IAAI,CAAC,OAAO;QACf,kBAAkB,EAAE,UAAU;QAC9B,gBAAgB;KAChB,CAAC,CAAC;IAEH,OAAO;QACN,KAAK;QACL,gBAAgB;QAChB,kBAAkB,EAAE,UAAU;QAC9B,MAAM,EAAE,IAAI,CAAC,MAAM;KACnB,CAAC;AACH,CAAC","sourcesContent":["/**\n * Readiness derivation for the section runtime engine (M7).\n *\n * Canonical home of `createReadinessDetail` and `resolveReadinessPhase`.\n * As of M7 PR 7 the previous duplicates in\n * `packages/section-player/src/components/shared/section-player-readiness.ts`\n * have been deleted; section-player now consumes these helpers via\n * `@pie-players/pie-assessment-toolkit/runtime/internal`.\n *\n * Type duplication note: the public DOM-event detail aliases\n * (`SectionPlayerReadinessChangeDetail` /\n * `SectionPlayerReadinessPhase`) still live in section-player's\n * `contracts/public-events.ts` because that file is part of section-\n * player's published custom-element contract. The toolkit core defines\n * `EngineReadinessPhase` independently so it has zero section-player\n * imports. The two definitions must stay structurally identical;\n * that invariant is covered by the readiness assertions in this\n * package's tests, which mirror the section-player suite.\n */\n\n/**\n * Coarse readiness phase label, derived from the four readiness\n * signals. Surfaced via the kernel's `selectReadiness()` /\n * `getSnapshot().readiness` selectors; M6 stages own the stage-level\n * transitions on `pie-stage-change` and use this phase as a\n * convenience label only. The `readiness-change` DOM\n * event that used to surface this directly was removed in the broad\n * architecture review compat sweep alongside its\n * event bridge.\n */\nexport type EngineReadinessPhase =\n\t| \"bootstrapping\"\n\t| \"interaction-ready\"\n\t| \"loading\"\n\t| \"ready\"\n\t| \"error\";\n\nexport type EngineReadinessSignals = {\n\tsectionReady: boolean;\n\tinteractionReady: boolean;\n\tallLoadingComplete: boolean;\n\truntimeError: boolean;\n};\n\nexport type EngineReadinessDetail = {\n\tphase: EngineReadinessPhase;\n\tinteractionReady: boolean;\n\tallLoadingComplete: boolean;\n\treason?: string;\n};\n\nexport function resolveReadinessPhase(\n\tsignals: EngineReadinessSignals,\n): EngineReadinessPhase {\n\tif (signals.runtimeError) return \"error\";\n\tif (signals.allLoadingComplete) return \"ready\";\n\tif (signals.interactionReady) return \"interaction-ready\";\n\tif (signals.sectionReady) return \"loading\";\n\treturn \"bootstrapping\";\n}\n\nexport function createReadinessDetail(args: {\n\tmode: \"progressive\" | \"strict\";\n\tsignals: EngineReadinessSignals;\n\treason?: string;\n}): EngineReadinessDetail {\n\t// Final ready must always be gated by section lifecycle and complete loading.\n\tconst finalReady = args.signals.sectionReady && args.signals.allLoadingComplete;\n\tconst interactionReady =\n\t\targs.mode === \"strict\" ? finalReady : args.signals.interactionReady;\n\tconst phase = resolveReadinessPhase({\n\t\t...args.signals,\n\t\tallLoadingComplete: finalReady,\n\t\tinteractionReady,\n\t});\n\n\treturn {\n\t\tphase,\n\t\tinteractionReady,\n\t\tallLoadingComplete: finalReady,\n\t\treason: args.reason,\n\t};\n}\n"]}
@@ -18,9 +18,8 @@
18
18
  * `packages/section-player/src/components/shared/section-player-host-runtime.ts`)
19
19
  * hands its local implementation in.
20
20
  *
21
- * The strict mirror rule (M5) and the `runtime.<key>` precedence rule
22
- * are preserved bit-for-bit; the per-key precedence test in
23
- * `engine-resolver.test.ts` is the guardrail.
21
+ * Runtime-owned configuration flows through `runtime.<key>`. Layout-only
22
+ * inputs stay on the section-player host elements.
24
23
  */
25
24
  import type { LoaderConfig } from "@pie-players/pie-players-shared/loader-config";
26
25
  import type { LoadingCompleteDetail, StageChangeDetail } from "@pie-players/pie-players-shared/pie";
@@ -40,10 +39,7 @@ export type FrameworkErrorHandler = (model: FrameworkErrorModel) => void;
40
39
  export type StageChangeHandler = (detail: StageChangeDetail) => void;
41
40
  export type LoadingCompleteHandler = (detail: LoadingCompleteDetail) => void;
42
41
  /**
43
- * Two-tier section runtime config (M5 strict mirror, post-trim).
44
- *
45
- * Mirror rule: `kebab-attribute ↔ camelCaseProp ↔ runtime.<sameCamelCaseKey>`.
46
- * `runtime.<key>` always wins over the equivalent prop/attribute.
42
+ * Section runtime config.
47
43
  *
48
44
  * Documented exceptions (no runtime mirror, by design): identity
49
45
  * (`section-id`, `attempt-id`, `section`); layout-only shell knobs
@@ -66,25 +62,16 @@ export type RuntimeConfig = {
66
62
  env?: Record<string, unknown>;
67
63
  toolConfigStrictness?: ToolConfigStrictness;
68
64
  onFrameworkError?: FrameworkErrorHandler;
69
- enabledTools?: string;
70
65
  onStageChange?: StageChangeHandler;
71
66
  onLoadingComplete?: LoadingCompleteHandler;
72
67
  };
73
68
  export type RuntimeInputs = {
74
69
  assessmentId?: string;
75
- playerType?: string;
76
- player?: PlayerOverrides | null;
77
- lazyInit?: boolean;
78
- tools?: Record<string, unknown> | null;
79
- accessibility?: Record<string, unknown> | null;
80
- coordinator?: unknown;
81
- env?: Record<string, unknown> | null;
82
70
  toolConfigStrictness?: ToolConfigStrictness;
83
71
  onFrameworkError?: FrameworkErrorHandler;
84
72
  onStageChange?: StageChangeHandler;
85
73
  onLoadingComplete?: LoadingCompleteHandler;
86
74
  runtime: RuntimeConfig | null;
87
- enabledTools: string;
88
75
  };
89
76
  /**
90
77
  * Resolve the canonical `onFrameworkError` handler from the two-tier
@@ -98,21 +85,13 @@ export declare function resolveOnFrameworkError(args: {
98
85
  }): FrameworkErrorHandler | undefined;
99
86
  export declare function resolveToolsConfig(args: {
100
87
  runtime: RuntimeConfig | null;
101
- tools: Record<string, unknown> | null;
102
- enabledTools: string;
103
88
  }): {
104
89
  placement: {
105
- section?: string[] | undefined;
90
+ [x: string]: unknown;
106
91
  };
107
92
  };
108
93
  export declare function resolveRuntime(args: {
109
94
  assessmentId: string;
110
- playerType: string;
111
- player: PlayerOverrides | null;
112
- lazyInit: boolean;
113
- accessibility: Record<string, unknown> | null;
114
- coordinator: unknown;
115
- env: Record<string, unknown> | null;
116
95
  runtime: RuntimeConfig | null;
117
96
  effectiveToolsConfig: unknown;
118
97
  toolConfigStrictness?: ToolConfigStrictness;
@@ -121,18 +100,15 @@ export declare function resolveRuntime(args: {
121
100
  onLoadingComplete?: LoadingCompleteHandler;
122
101
  }): {
123
102
  assessmentId: string | undefined;
124
- playerType: string | undefined;
103
+ playerType: string;
125
104
  player: {
126
- loaderOptions: {
127
- [x: string]: unknown;
128
- };
129
- loaderConfig: {
130
- [x: string]: unknown;
131
- };
105
+ [key: string]: unknown;
106
+ loaderConfig?: LoaderConfig;
107
+ loaderOptions?: Record<string, unknown>;
132
108
  } | null;
133
- lazyInit: boolean | undefined;
134
- accessibility: Record<string, unknown> | null | undefined;
135
- coordinator: unknown;
109
+ lazyInit: boolean;
110
+ accessibility: Record<string, unknown> | null;
111
+ coordinator: {} | null;
136
112
  createSectionController: unknown;
137
113
  isolation: string;
138
114
  env: Record<string, unknown>;
@@ -142,7 +118,6 @@ export declare function resolveRuntime(args: {
142
118
  onLoadingComplete: LoadingCompleteHandler | undefined;
143
119
  tools: unknown;
144
120
  toolContextResolvers?: Record<string, unknown> | null;
145
- enabledTools?: string;
146
121
  };
147
122
  /**
148
123
  * Effective runtime returned by `resolveRuntime`. The shape is exposed
@@ -152,13 +127,10 @@ export declare function resolveRuntime(args: {
152
127
  */
153
128
  export type EffectiveRuntime = ReturnType<typeof resolveRuntime>;
154
129
  /**
155
- * Engine-side orchestrator that mirrors the legacy
156
- * `resolveSectionPlayerRuntimeState` from section-player but takes
130
+ * Engine-side orchestrator that powers `resolveSectionPlayerRuntimeState`
131
+ * from section-player and takes
157
132
  * `resolvePlayerRuntime` as an injected callable so the toolkit core
158
133
  * stays free of host-coupled defaults (`DEFAULT_PLAYER_DEFINITIONS`).
159
- *
160
- * The legacy section-player wrapper passes its local `resolvePlayerRuntime`
161
- * here in M7 PR 5 when the kernel switches onto the engine.
162
134
  */
163
135
  export declare function resolveSectionEngineRuntimeState<P>(args: RuntimeInputs, deps: {
164
136
  resolvePlayerRuntime: (resolverArgs: {
@@ -18,11 +18,9 @@
18
18
  * `packages/section-player/src/components/shared/section-player-host-runtime.ts`)
19
19
  * hands its local implementation in.
20
20
  *
21
- * The strict mirror rule (M5) and the `runtime.<key>` precedence rule
22
- * are preserved bit-for-bit; the per-key precedence test in
23
- * `engine-resolver.test.ts` is the guardrail.
21
+ * Runtime-owned configuration flows through `runtime.<key>`. Layout-only
22
+ * inputs stay on the section-player host elements.
24
23
  */
25
- import { parseToolList } from "../../services/tools-config-normalizer.js";
26
24
  export const DEFAULT_ASSESSMENT_ID = "section-demo-direct";
27
25
  export const DEFAULT_PLAYER_TYPE = "iife";
28
26
  export const DEFAULT_LAZY_INIT = true;
@@ -49,108 +47,53 @@ export function resolveOnFrameworkError(args) {
49
47
  return args.onFrameworkError;
50
48
  }
51
49
  export function resolveToolsConfig(args) {
52
- const runtimeTools = (args.runtime?.tools || args.tools || {});
53
- // `runtime.enabledTools` is the canonical mirror; the kebab attribute is
54
- // the easy-tier alias. Per Decision B1, it merges into
55
- // `tools.placement.section`. The object form (`runtime.tools`) keeps
56
- // precedence over both — that lock lives in the merge below.
57
- //
58
- // The deprecated `item-toolbar-tools` / `passage-toolbar-tools`
59
- // per-region aliases were removed in the broad architecture review
60
- // compat sweep; hosts must populate `tools.placement.item` /
61
- // `tools.placement.passage` (object form) or
62
- // `runtime.tools.placement.{item,passage}` directly.
63
- const effectiveEnabledTools = pick(args.runtime?.enabledTools, args.enabledTools) ?? "";
64
- const sectionTools = parseToolList(effectiveEnabledTools);
50
+ const runtimeTools = (args.runtime?.tools || {});
65
51
  const placement = (runtimeTools.placement || {});
66
- const overlayToolsConfig = {
67
- ...runtimeTools,
68
- placement: {
69
- ...placement,
70
- ...(sectionTools.length > 0 ? { section: sectionTools } : {}),
71
- },
72
- };
52
+ const overlayToolsConfig = { ...runtimeTools, placement: { ...placement } };
73
53
  // Keep host-provided shape intact; framework-owned validation surfaces malformed config.
74
54
  return overlayToolsConfig;
75
55
  }
76
56
  export function resolveRuntime(args) {
77
57
  const r = args.runtime || {};
78
- const topLevelPlayer = (args.player || {});
79
- const runtimePlayer = (r.player || {});
80
- const mergedPlayerCandidate = {
81
- ...topLevelPlayer,
82
- ...runtimePlayer,
83
- loaderOptions: {
84
- ...(topLevelPlayer.loaderOptions || {}),
85
- ...(runtimePlayer.loaderOptions || {}),
86
- },
87
- loaderConfig: {
88
- ...(topLevelPlayer.loaderConfig || {}),
89
- ...(runtimePlayer.loaderConfig || {}),
90
- },
91
- };
92
- const mergedPlayer = Object.keys(mergedPlayerCandidate).length > 0
93
- ? mergedPlayerCandidate
94
- : null;
58
+ const runtimePlayer = r.player ? { ...r.player } : null;
95
59
  return {
96
60
  ...r,
97
61
  assessmentId: pick(r.assessmentId, args.assessmentId),
98
- playerType: pick(r.playerType, args.playerType),
99
- player: mergedPlayer,
100
- lazyInit: pick(r.lazyInit, args.lazyInit),
101
- accessibility: pick(r.accessibility, args.accessibility),
102
- coordinator: pick(r.coordinator, args.coordinator),
62
+ playerType: r.playerType ?? DEFAULT_PLAYER_TYPE,
63
+ player: runtimePlayer,
64
+ lazyInit: r.lazyInit ?? DEFAULT_LAZY_INIT,
65
+ accessibility: r.accessibility ?? null,
66
+ coordinator: r.coordinator ?? null,
103
67
  createSectionController: r.createSectionController,
104
68
  isolation: r.isolation ?? DEFAULT_ISOLATION,
105
- env: pick(r.env, args.env) ?? DEFAULT_ENV,
69
+ env: r.env ?? DEFAULT_ENV,
106
70
  toolConfigStrictness: pick(r.toolConfigStrictness, args.toolConfigStrictness) ?? "error",
107
- // M3 mirror absorbed via the shared helper so every layout CE wires
108
- // `onFrameworkError` identically.
71
+ // Runtime callback wins; top-level callback remains a layout CE event
72
+ // convenience for hosts that do not use DOM listeners.
109
73
  onFrameworkError: resolveOnFrameworkError({
110
74
  runtime: args.runtime,
111
75
  onFrameworkError: args.onFrameworkError,
112
76
  }),
113
- // M6 mirror `onStageChange` follows the same precedence as every
114
- // other tier-1 surface: `runtime.onStageChange` wins over the
115
- // top-level prop.
77
+ // Runtime callback wins over the top-level callback prop.
116
78
  onStageChange: pick(r.onStageChange, args.onStageChange),
117
- // M6 mirror `onLoadingComplete` follows the same precedence
118
- // rule.
79
+ // Runtime callback wins over the top-level callback prop.
119
80
  onLoadingComplete: pick(r.onLoadingComplete, args.onLoadingComplete),
120
81
  tools: args.effectiveToolsConfig,
121
82
  };
122
83
  }
123
84
  /**
124
- * Engine-side orchestrator that mirrors the legacy
125
- * `resolveSectionPlayerRuntimeState` from section-player but takes
85
+ * Engine-side orchestrator that powers `resolveSectionPlayerRuntimeState`
86
+ * from section-player and takes
126
87
  * `resolvePlayerRuntime` as an injected callable so the toolkit core
127
88
  * stays free of host-coupled defaults (`DEFAULT_PLAYER_DEFINITIONS`).
128
- *
129
- * The legacy section-player wrapper passes its local `resolvePlayerRuntime`
130
- * here in M7 PR 5 when the kernel switches onto the engine.
131
89
  */
132
90
  export function resolveSectionEngineRuntimeState(args, deps) {
133
91
  const assessmentId = args.assessmentId ?? DEFAULT_ASSESSMENT_ID;
134
- const playerType = args.playerType ?? DEFAULT_PLAYER_TYPE;
135
- const player = args.player ?? null;
136
- const lazyInit = args.lazyInit ?? DEFAULT_LAZY_INIT;
137
- const accessibility = args.accessibility ?? null;
138
- const coordinator = args.coordinator ?? null;
139
- const env = args.env ?? null;
140
- const tools = args.tools ?? null;
141
92
  const effectiveToolsConfig = resolveToolsConfig({
142
93
  runtime: args.runtime,
143
- tools,
144
- enabledTools: args.enabledTools,
145
94
  });
146
95
  const effectiveRuntime = resolveRuntime({
147
96
  assessmentId,
148
- playerType,
149
- player,
150
- lazyInit,
151
- accessibility,
152
- coordinator,
153
- env,
154
97
  runtime: args.runtime,
155
98
  effectiveToolsConfig,
156
99
  toolConfigStrictness: args.toolConfigStrictness,
@@ -160,8 +103,8 @@ export function resolveSectionEngineRuntimeState(args, deps) {
160
103
  });
161
104
  const playerRuntime = deps.resolvePlayerRuntime({
162
105
  effectiveRuntime: effectiveRuntime,
163
- playerType,
164
- env,
106
+ playerType: String(effectiveRuntime.playerType ?? DEFAULT_PLAYER_TYPE),
107
+ env: effectiveRuntime.env ?? null,
165
108
  });
166
109
  return {
167
110
  effectiveToolsConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"engine-resolver.js","sourceRoot":"","sources":["../../../src/runtime/core/engine-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Section runtime engine resolver (M7).\n *\n * Canonical home of `resolveRuntime`, `resolveToolsConfig`, and their\n * supporting helpers/types. As of M7 PR 7 the previous duplicates in\n * `packages/section-player/src/components/shared/section-player-runtime.ts`\n * have been deleted; section-player now consumes these helpers via\n * `@pie-players/pie-assessment-toolkit/runtime/internal`.\n *\n * What is NOT absorbed in this module:\n * - `resolvePlayerRuntime` stays in section-player because it depends on\n * `DEFAULT_PLAYER_DEFINITIONS` (which side-effect-imports the\n * item-player package). The toolkit core stays free of that\n * dependency by exposing a parametrized orchestrator —\n * `resolveSectionEngineRuntimeState` — that takes a `resolvePlayerRuntime`\n * callable. The section-player wrapper\n * (`resolveSectionPlayerRuntimeState` in\n * `packages/section-player/src/components/shared/section-player-host-runtime.ts`)\n * hands its local implementation in.\n *\n * The strict mirror rule (M5) and the `runtime.<key>` precedence rule\n * are preserved bit-for-bit; the per-key precedence test in\n * `engine-resolver.test.ts` is the guardrail.\n */\n\nimport type { LoaderConfig } from \"@pie-players/pie-players-shared/loader-config\";\nimport type {\n\tLoadingCompleteDetail,\n\tStageChangeDetail,\n} from \"@pie-players/pie-players-shared/pie\";\nimport type { FrameworkErrorModel } from \"../../services/framework-error.js\";\nimport type { ToolConfigStrictness } from \"../../services/tool-config-validation.js\";\nimport { parseToolList } from \"../../services/tools-config-normalizer.js\";\n\nexport const DEFAULT_ASSESSMENT_ID = \"section-demo-direct\";\nexport const DEFAULT_PLAYER_TYPE = \"iife\";\nexport const DEFAULT_LAZY_INIT = true;\nexport const DEFAULT_ISOLATION = \"inherit\";\nexport const DEFAULT_ENV = { mode: \"gather\", role: \"student\" } as Record<\n\tstring,\n\tunknown\n>;\n\nexport type PlayerOverrides = {\n\tloaderConfig?: LoaderConfig;\n\tloaderOptions?: Record<string, unknown>;\n\t[key: string]: unknown;\n};\n\nexport type FrameworkErrorHandler = (model: FrameworkErrorModel) => void;\nexport type StageChangeHandler = (detail: StageChangeDetail) => void;\nexport type LoadingCompleteHandler = (detail: LoadingCompleteDetail) => void;\n\n/**\n * Two-tier section runtime config (M5 strict mirror, post-trim).\n *\n * Mirror rule: `kebab-attribute ↔ camelCaseProp ↔ runtime.<sameCamelCaseKey>`.\n * `runtime.<key>` always wins over the equivalent prop/attribute.\n *\n * Documented exceptions (no runtime mirror, by design): identity\n * (`section-id`, `attempt-id`, `section`); layout-only shell knobs\n * (`show-toolbar`, `toolbar-position`, etc.); and layout-shell host\n * data (`policies`, `hooks`, `toolRegistry`, `*HostButtons`). Those\n * surfaces are layout-shell concerns; the runtime engine does not see\n * them. See section-player's ARCHITECTURE.md for the full policy.\n */\nexport type RuntimeConfig = {\n\tassessmentId?: string;\n\tplayerType?: string;\n\tplayer?: PlayerOverrides | null;\n\tlazyInit?: boolean;\n\ttools?: Record<string, unknown> | null;\n\ttoolContextResolvers?: Record<string, unknown> | null;\n\taccessibility?: Record<string, unknown> | null;\n\tcoordinator?: unknown;\n\tcreateSectionController?: unknown;\n\tisolation?: string;\n\tenv?: Record<string, unknown>;\n\ttoolConfigStrictness?: ToolConfigStrictness;\n\n\t// M3 mirror — canonical onFrameworkError handler.\n\tonFrameworkError?: FrameworkErrorHandler;\n\n\t// M5 mirror — `enabledTools` is the canonical tier-1 shorthand for\n\t// `tools.placement.section`; `resolveToolsConfig` reads it from\n\t// `runtime?.enabledTools` when present.\n\tenabledTools?: string;\n\n\t// M6 mirror — canonical stage-change callback. The DOM event\n\t// `pie-stage-change` remains the primary channel; this callback is\n\t// the convenience surface that mirrors the event one-to-one.\n\tonStageChange?: StageChangeHandler;\n\n\t// M6 mirror — canonical loading-complete callback. Mirrors the\n\t// `pie-loading-complete` DOM event, which the engine dispatches\n\t// once per cohort when every item has finished loading.\n\tonLoadingComplete?: LoadingCompleteHandler;\n};\n\nexport type RuntimeInputs = {\n\tassessmentId?: string;\n\tplayerType?: string;\n\tplayer?: PlayerOverrides | null;\n\tlazyInit?: boolean;\n\ttools?: Record<string, unknown> | null;\n\taccessibility?: Record<string, unknown> | null;\n\tcoordinator?: unknown;\n\tenv?: Record<string, unknown> | null;\n\ttoolConfigStrictness?: ToolConfigStrictness;\n\tonFrameworkError?: FrameworkErrorHandler;\n\tonStageChange?: StageChangeHandler;\n\tonLoadingComplete?: LoadingCompleteHandler;\n\truntime: RuntimeConfig | null;\n\tenabledTools: string;\n};\n\n/**\n * Pick the runtime-tier value when defined, otherwise the prop/attribute\n * value. The strict mirror rule means every tier-1 surface is resolved\n * with this single helper; per-feature special-casing is forbidden.\n */\nfunction pick<T>(\n\truntimeVal: T | undefined,\n\tattrVal: T | undefined,\n): T | undefined {\n\treturn runtimeVal !== undefined ? runtimeVal : attrVal;\n}\n\n/**\n * Resolve the canonical `onFrameworkError` handler from the two-tier\n * surface. Precedence (highest first): `runtime.onFrameworkError`,\n * then top-level `onFrameworkError`. Layout CEs and the kernel call\n * this so every entry point converges on the same handler.\n */\nexport function resolveOnFrameworkError(args: {\n\truntime: RuntimeConfig | null;\n\tonFrameworkError?: FrameworkErrorHandler;\n}): FrameworkErrorHandler | undefined {\n\tconst r = args.runtime ?? {};\n\tif (r.onFrameworkError !== undefined) return r.onFrameworkError;\n\treturn args.onFrameworkError;\n}\n\nexport function resolveToolsConfig(args: {\n\truntime: RuntimeConfig | null;\n\ttools: Record<string, unknown> | null;\n\tenabledTools: string;\n}) {\n\tconst runtimeTools = (args.runtime?.tools || args.tools || {}) as Record<\n\t\tstring,\n\t\tunknown\n\t>;\n\t// `runtime.enabledTools` is the canonical mirror; the kebab attribute is\n\t// the easy-tier alias. Per Decision B1, it merges into\n\t// `tools.placement.section`. The object form (`runtime.tools`) keeps\n\t// precedence over both — that lock lives in the merge below.\n\t//\n\t// The deprecated `item-toolbar-tools` / `passage-toolbar-tools`\n\t// per-region aliases were removed in the broad architecture review\n\t// compat sweep; hosts must populate `tools.placement.item` /\n\t// `tools.placement.passage` (object form) or\n\t// `runtime.tools.placement.{item,passage}` directly.\n\tconst effectiveEnabledTools =\n\t\tpick(args.runtime?.enabledTools, args.enabledTools) ?? \"\";\n\tconst sectionTools = parseToolList(effectiveEnabledTools);\n\tconst placement = (runtimeTools.placement || {}) as Record<string, unknown>;\n\tconst overlayToolsConfig = {\n\t\t...runtimeTools,\n\t\tplacement: {\n\t\t\t...placement,\n\t\t\t...(sectionTools.length > 0 ? { section: sectionTools } : {}),\n\t\t},\n\t};\n\t// Keep host-provided shape intact; framework-owned validation surfaces malformed config.\n\treturn overlayToolsConfig;\n}\n\nexport function resolveRuntime(args: {\n\tassessmentId: string;\n\tplayerType: string;\n\tplayer: PlayerOverrides | null;\n\tlazyInit: boolean;\n\taccessibility: Record<string, unknown> | null;\n\tcoordinator: unknown;\n\tenv: Record<string, unknown> | null;\n\truntime: RuntimeConfig | null;\n\teffectiveToolsConfig: unknown;\n\ttoolConfigStrictness?: ToolConfigStrictness;\n\tonFrameworkError?: FrameworkErrorHandler;\n\tonStageChange?: StageChangeHandler;\n\tonLoadingComplete?: LoadingCompleteHandler;\n}) {\n\tconst r = args.runtime || {};\n\tconst topLevelPlayer = (args.player || {}) as PlayerOverrides;\n\tconst runtimePlayer = (r.player || {}) as PlayerOverrides;\n\tconst mergedPlayerCandidate = {\n\t\t...topLevelPlayer,\n\t\t...runtimePlayer,\n\t\tloaderOptions: {\n\t\t\t...((topLevelPlayer.loaderOptions || {}) as Record<string, unknown>),\n\t\t\t...((runtimePlayer.loaderOptions || {}) as Record<string, unknown>),\n\t\t},\n\t\tloaderConfig: {\n\t\t\t...((topLevelPlayer.loaderConfig || {}) as Record<string, unknown>),\n\t\t\t...((runtimePlayer.loaderConfig || {}) as Record<string, unknown>),\n\t\t},\n\t};\n\tconst mergedPlayer =\n\t\tObject.keys(mergedPlayerCandidate).length > 0\n\t\t\t? mergedPlayerCandidate\n\t\t\t: null;\n\treturn {\n\t\t...r,\n\t\tassessmentId: pick(r.assessmentId, args.assessmentId),\n\t\tplayerType: pick(r.playerType, args.playerType),\n\t\tplayer: mergedPlayer,\n\t\tlazyInit: pick(r.lazyInit, args.lazyInit),\n\t\taccessibility: pick(r.accessibility, args.accessibility),\n\t\tcoordinator: pick(r.coordinator, args.coordinator),\n\t\tcreateSectionController: r.createSectionController,\n\t\tisolation: r.isolation ?? DEFAULT_ISOLATION,\n\t\tenv: pick(r.env, args.env) ?? DEFAULT_ENV,\n\t\ttoolConfigStrictness:\n\t\t\tpick(r.toolConfigStrictness, args.toolConfigStrictness) ?? \"error\",\n\n\t\t// M3 mirror absorbed via the shared helper so every layout CE wires\n\t\t// `onFrameworkError` identically.\n\t\tonFrameworkError: resolveOnFrameworkError({\n\t\t\truntime: args.runtime,\n\t\t\tonFrameworkError: args.onFrameworkError,\n\t\t}),\n\n\t\t// M6 mirror — `onStageChange` follows the same precedence as every\n\t\t// other tier-1 surface: `runtime.onStageChange` wins over the\n\t\t// top-level prop.\n\t\tonStageChange: pick(r.onStageChange, args.onStageChange),\n\n\t\t// M6 mirror — `onLoadingComplete` follows the same precedence\n\t\t// rule.\n\t\tonLoadingComplete: pick(r.onLoadingComplete, args.onLoadingComplete),\n\n\t\ttools: args.effectiveToolsConfig,\n\t};\n}\n\n/**\n * Effective runtime returned by `resolveRuntime`. The shape is exposed\n * as `unknown` at the public boundary because consumers spread it into\n * arbitrary host props; downstream call sites narrow with the specific\n * keys they need.\n */\nexport type EffectiveRuntime = ReturnType<typeof resolveRuntime>;\n\n/**\n * Engine-side orchestrator that mirrors the legacy\n * `resolveSectionPlayerRuntimeState` from section-player but takes\n * `resolvePlayerRuntime` as an injected callable so the toolkit core\n * stays free of host-coupled defaults (`DEFAULT_PLAYER_DEFINITIONS`).\n *\n * The legacy section-player wrapper passes its local `resolvePlayerRuntime`\n * here in M7 PR 5 when the kernel switches onto the engine.\n */\nexport function resolveSectionEngineRuntimeState<P>(\n\targs: RuntimeInputs,\n\tdeps: {\n\t\tresolvePlayerRuntime: (resolverArgs: {\n\t\t\teffectiveRuntime: Record<string, unknown>;\n\t\t\tplayerType: string;\n\t\t\tenv: Record<string, unknown> | null;\n\t\t}) => P;\n\t},\n): {\n\teffectiveToolsConfig: unknown;\n\teffectiveRuntime: EffectiveRuntime;\n\tplayerRuntime: P;\n} {\n\tconst assessmentId = args.assessmentId ?? DEFAULT_ASSESSMENT_ID;\n\tconst playerType = args.playerType ?? DEFAULT_PLAYER_TYPE;\n\tconst player = args.player ?? null;\n\tconst lazyInit = args.lazyInit ?? DEFAULT_LAZY_INIT;\n\tconst accessibility = args.accessibility ?? null;\n\tconst coordinator = args.coordinator ?? null;\n\tconst env = args.env ?? null;\n\tconst tools = args.tools ?? null;\n\n\tconst effectiveToolsConfig = resolveToolsConfig({\n\t\truntime: args.runtime,\n\t\ttools,\n\t\tenabledTools: args.enabledTools,\n\t});\n\tconst effectiveRuntime = resolveRuntime({\n\t\tassessmentId,\n\t\tplayerType,\n\t\tplayer,\n\t\tlazyInit,\n\t\taccessibility,\n\t\tcoordinator,\n\t\tenv,\n\t\truntime: args.runtime,\n\t\teffectiveToolsConfig,\n\t\ttoolConfigStrictness: args.toolConfigStrictness,\n\t\tonFrameworkError: args.onFrameworkError,\n\t\tonStageChange: args.onStageChange,\n\t\tonLoadingComplete: args.onLoadingComplete,\n\t});\n\tconst playerRuntime = deps.resolvePlayerRuntime({\n\t\teffectiveRuntime: effectiveRuntime as Record<string, unknown>,\n\t\tplayerType,\n\t\tenv,\n\t});\n\treturn {\n\t\teffectiveToolsConfig,\n\t\teffectiveRuntime,\n\t\tplayerRuntime,\n\t};\n}\n"]}
1
+ {"version":3,"file":"engine-resolver.js","sourceRoot":"","sources":["../../../src/runtime/core/engine-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Section runtime engine resolver (M7).\n *\n * Canonical home of `resolveRuntime`, `resolveToolsConfig`, and their\n * supporting helpers/types. As of M7 PR 7 the previous duplicates in\n * `packages/section-player/src/components/shared/section-player-runtime.ts`\n * have been deleted; section-player now consumes these helpers via\n * `@pie-players/pie-assessment-toolkit/runtime/internal`.\n *\n * What is NOT absorbed in this module:\n * - `resolvePlayerRuntime` stays in section-player because it depends on\n * `DEFAULT_PLAYER_DEFINITIONS` (which side-effect-imports the\n * item-player package). The toolkit core stays free of that\n * dependency by exposing a parametrized orchestrator —\n * `resolveSectionEngineRuntimeState` — that takes a `resolvePlayerRuntime`\n * callable. The section-player wrapper\n * (`resolveSectionPlayerRuntimeState` in\n * `packages/section-player/src/components/shared/section-player-host-runtime.ts`)\n * hands its local implementation in.\n *\n * Runtime-owned configuration flows through `runtime.<key>`. Layout-only\n * inputs stay on the section-player host elements.\n */\n\nimport type { LoaderConfig } from \"@pie-players/pie-players-shared/loader-config\";\nimport type {\n\tLoadingCompleteDetail,\n\tStageChangeDetail,\n} from \"@pie-players/pie-players-shared/pie\";\nimport type { FrameworkErrorModel } from \"../../services/framework-error.js\";\nimport type { ToolConfigStrictness } from \"../../services/tool-config-validation.js\";\n\nexport const DEFAULT_ASSESSMENT_ID = \"section-demo-direct\";\nexport const DEFAULT_PLAYER_TYPE = \"iife\";\nexport const DEFAULT_LAZY_INIT = true;\nexport const DEFAULT_ISOLATION = \"inherit\";\nexport const DEFAULT_ENV = { mode: \"gather\", role: \"student\" } as Record<\n\tstring,\n\tunknown\n>;\n\nexport type PlayerOverrides = {\n\tloaderConfig?: LoaderConfig;\n\tloaderOptions?: Record<string, unknown>;\n\t[key: string]: unknown;\n};\n\nexport type FrameworkErrorHandler = (model: FrameworkErrorModel) => void;\nexport type StageChangeHandler = (detail: StageChangeDetail) => void;\nexport type LoadingCompleteHandler = (detail: LoadingCompleteDetail) => void;\n\n/**\n * Section runtime config.\n *\n * Documented exceptions (no runtime mirror, by design): identity\n * (`section-id`, `attempt-id`, `section`); layout-only shell knobs\n * (`show-toolbar`, `toolbar-position`, etc.); and layout-shell host\n * data (`policies`, `hooks`, `toolRegistry`, `*HostButtons`). Those\n * surfaces are layout-shell concerns; the runtime engine does not see\n * them. See section-player's ARCHITECTURE.md for the full policy.\n */\nexport type RuntimeConfig = {\n\tassessmentId?: string;\n\tplayerType?: string;\n\tplayer?: PlayerOverrides | null;\n\tlazyInit?: boolean;\n\ttools?: Record<string, unknown> | null;\n\ttoolContextResolvers?: Record<string, unknown> | null;\n\taccessibility?: Record<string, unknown> | null;\n\tcoordinator?: unknown;\n\tcreateSectionController?: unknown;\n\tisolation?: string;\n\tenv?: Record<string, unknown>;\n\ttoolConfigStrictness?: ToolConfigStrictness;\n\n\t// Canonical framework-error callback.\n\tonFrameworkError?: FrameworkErrorHandler;\n\n\t// Canonical stage-change callback. The DOM event\n\t// `pie-stage-change` remains the primary channel; this callback is\n\t// the convenience surface that mirrors the event one-to-one.\n\tonStageChange?: StageChangeHandler;\n\n\t// Canonical loading-complete callback. Mirrors the\n\t// `pie-loading-complete` DOM event, which the engine dispatches\n\t// once per cohort when every item has finished loading.\n\tonLoadingComplete?: LoadingCompleteHandler;\n};\n\nexport type RuntimeInputs = {\n\tassessmentId?: string;\n\ttoolConfigStrictness?: ToolConfigStrictness;\n\tonFrameworkError?: FrameworkErrorHandler;\n\tonStageChange?: StageChangeHandler;\n\tonLoadingComplete?: LoadingCompleteHandler;\n\truntime: RuntimeConfig | null;\n};\n\n/**\n * Pick the runtime-tier value when defined, otherwise the prop/attribute\n * value. The strict mirror rule means every tier-1 surface is resolved\n * with this single helper; per-feature special-casing is forbidden.\n */\nfunction pick<T>(\n\truntimeVal: T | undefined,\n\tattrVal: T | undefined,\n): T | undefined {\n\treturn runtimeVal !== undefined ? runtimeVal : attrVal;\n}\n\n/**\n * Resolve the canonical `onFrameworkError` handler from the two-tier\n * surface. Precedence (highest first): `runtime.onFrameworkError`,\n * then top-level `onFrameworkError`. Layout CEs and the kernel call\n * this so every entry point converges on the same handler.\n */\nexport function resolveOnFrameworkError(args: {\n\truntime: RuntimeConfig | null;\n\tonFrameworkError?: FrameworkErrorHandler;\n}): FrameworkErrorHandler | undefined {\n\tconst r = args.runtime ?? {};\n\tif (r.onFrameworkError !== undefined) return r.onFrameworkError;\n\treturn args.onFrameworkError;\n}\n\nexport function resolveToolsConfig(args: {\n\truntime: RuntimeConfig | null;\n}) {\n\tconst runtimeTools = (args.runtime?.tools || {}) as Record<string, unknown>;\n\tconst placement = (runtimeTools.placement || {}) as Record<string, unknown>;\n\tconst overlayToolsConfig = { ...runtimeTools, placement: { ...placement } };\n\t// Keep host-provided shape intact; framework-owned validation surfaces malformed config.\n\treturn overlayToolsConfig;\n}\n\nexport function resolveRuntime(args: {\n\tassessmentId: string;\n\truntime: RuntimeConfig | null;\n\teffectiveToolsConfig: unknown;\n\ttoolConfigStrictness?: ToolConfigStrictness;\n\tonFrameworkError?: FrameworkErrorHandler;\n\tonStageChange?: StageChangeHandler;\n\tonLoadingComplete?: LoadingCompleteHandler;\n}) {\n\tconst r = args.runtime || {};\n\tconst runtimePlayer = r.player ? { ...r.player } : null;\n\treturn {\n\t\t...r,\n\t\tassessmentId: pick(r.assessmentId, args.assessmentId),\n\t\tplayerType: r.playerType ?? DEFAULT_PLAYER_TYPE,\n\t\tplayer: runtimePlayer,\n\t\tlazyInit: r.lazyInit ?? DEFAULT_LAZY_INIT,\n\t\taccessibility: r.accessibility ?? null,\n\t\tcoordinator: r.coordinator ?? null,\n\t\tcreateSectionController: r.createSectionController,\n\t\tisolation: r.isolation ?? DEFAULT_ISOLATION,\n\t\tenv: r.env ?? DEFAULT_ENV,\n\t\ttoolConfigStrictness:\n\t\t\tpick(r.toolConfigStrictness, args.toolConfigStrictness) ?? \"error\",\n\n\t\t// Runtime callback wins; top-level callback remains a layout CE event\n\t\t// convenience for hosts that do not use DOM listeners.\n\t\tonFrameworkError: resolveOnFrameworkError({\n\t\t\truntime: args.runtime,\n\t\t\tonFrameworkError: args.onFrameworkError,\n\t\t}),\n\n\t\t// Runtime callback wins over the top-level callback prop.\n\t\tonStageChange: pick(r.onStageChange, args.onStageChange),\n\n\t\t// Runtime callback wins over the top-level callback prop.\n\t\tonLoadingComplete: pick(r.onLoadingComplete, args.onLoadingComplete),\n\n\t\ttools: args.effectiveToolsConfig,\n\t};\n}\n\n/**\n * Effective runtime returned by `resolveRuntime`. The shape is exposed\n * as `unknown` at the public boundary because consumers spread it into\n * arbitrary host props; downstream call sites narrow with the specific\n * keys they need.\n */\nexport type EffectiveRuntime = ReturnType<typeof resolveRuntime>;\n\n/**\n * Engine-side orchestrator that powers `resolveSectionPlayerRuntimeState`\n * from section-player and takes\n * `resolvePlayerRuntime` as an injected callable so the toolkit core\n * stays free of host-coupled defaults (`DEFAULT_PLAYER_DEFINITIONS`).\n */\nexport function resolveSectionEngineRuntimeState<P>(\n\targs: RuntimeInputs,\n\tdeps: {\n\t\tresolvePlayerRuntime: (resolverArgs: {\n\t\t\teffectiveRuntime: Record<string, unknown>;\n\t\t\tplayerType: string;\n\t\t\tenv: Record<string, unknown> | null;\n\t\t}) => P;\n\t},\n): {\n\teffectiveToolsConfig: unknown;\n\teffectiveRuntime: EffectiveRuntime;\n\tplayerRuntime: P;\n} {\n\tconst assessmentId = args.assessmentId ?? DEFAULT_ASSESSMENT_ID;\n\n\tconst effectiveToolsConfig = resolveToolsConfig({\n\t\truntime: args.runtime,\n\t});\n\tconst effectiveRuntime = resolveRuntime({\n\t\tassessmentId,\n\t\truntime: args.runtime,\n\t\teffectiveToolsConfig,\n\t\ttoolConfigStrictness: args.toolConfigStrictness,\n\t\tonFrameworkError: args.onFrameworkError,\n\t\tonStageChange: args.onStageChange,\n\t\tonLoadingComplete: args.onLoadingComplete,\n\t});\n\tconst playerRuntime = deps.resolvePlayerRuntime({\n\t\teffectiveRuntime: effectiveRuntime as Record<string, unknown>,\n\t\tplayerType: String(effectiveRuntime.playerType ?? DEFAULT_PLAYER_TYPE),\n\t\tenv: (effectiveRuntime.env as Record<string, unknown> | null) ?? null,\n\t});\n\treturn {\n\t\teffectiveToolsConfig,\n\t\teffectiveRuntime,\n\t\tplayerRuntime,\n\t};\n}\n"]}
@@ -26,7 +26,7 @@
26
26
  * 3. `framework-error` outputs are independent of the stage chain
27
27
  * and do not move the phase.
28
28
  *
29
- * The deprecated readiness output kinds (`readiness-change`,
29
+ * Readiness alias output kinds (`readiness-change`,
30
30
  * `interaction-ready`, `ready`) and their DOM-event bridge were
31
31
  * removed in the broad architecture review compat sweep. Hosts that
32
32
  * need the readiness detail read it via the kernel's `selectReadiness`
@@ -26,7 +26,7 @@
26
26
  * 3. `framework-error` outputs are independent of the stage chain
27
27
  * and do not move the phase.
28
28
  *
29
- * The deprecated readiness output kinds (`readiness-change`,
29
+ * Readiness alias output kinds (`readiness-change`,
30
30
  * `interaction-ready`, `ready`) and their DOM-event bridge were
31
31
  * removed in the broad architecture review compat sweep. Hosts that
32
32
  * need the readiness detail read it via the kernel's `selectReadiness`