@pie-players/pie-assessment-toolkit 0.3.46 → 0.3.48
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/dist/attempt/AssessmentSession.js +2 -1
- package/dist/attempt/AssessmentSession.js.map +1 -1
- package/dist/attempt/adapters/activity-to-test-attempt-session.js +12 -8
- package/dist/attempt/adapters/activity-to-test-attempt-session.js.map +1 -1
- package/dist/components/ItemToolBar.custom-element.js +60 -21
- package/dist/components/PieAssessmentToolkit.custom-element.js +83 -28
- package/dist/components/SectionToolBar.custom-element.js +59 -21
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/policy/core/pnp-policy-inputs.js +1 -2
- package/dist/policy/core/pnp-policy-inputs.js.map +1 -1
- package/dist/policy/core/provenance.js.map +1 -1
- package/dist/runtime/SectionRuntimeEngine.js +1 -1
- package/dist/runtime/SectionRuntimeEngine.js.map +1 -1
- package/dist/runtime/core/cohort.js.map +1 -1
- package/dist/runtime/core/engine-input.js.map +1 -1
- package/dist/runtime/core/engine-readiness.js.map +1 -1
- package/dist/runtime/core/engine-resolver.js.map +1 -1
- package/dist/runtime/core/engine-transition.js +1 -3
- package/dist/runtime/core/engine-transition.js.map +1 -1
- package/dist/runtime/registration-events.js.map +1 -1
- package/dist/runtime/session-event-emitter-policy.js.map +1 -1
- package/dist/services/HighlightCoordinator.js +2 -1
- package/dist/services/HighlightCoordinator.js.map +1 -1
- package/dist/services/I18nService.d.ts +1 -1
- package/dist/services/I18nService.js.map +1 -1
- package/dist/services/SSMLExtractor.js.map +1 -1
- package/dist/services/TTSService.js +5 -2
- package/dist/services/TTSService.js.map +1 -1
- package/dist/services/ThemeProvider.js.map +1 -1
- package/dist/services/ToolRegistry.d.ts +1 -1
- package/dist/services/ToolRegistry.js.map +1 -1
- package/dist/services/ToolkitCoordinator.js +21 -11
- package/dist/services/ToolkitCoordinator.js.map +1 -1
- package/dist/services/createDefaultToolRegistry.js +4 -2
- package/dist/services/createDefaultToolRegistry.js.map +1 -1
- package/dist/services/framework-error-bus.js.map +1 -1
- package/dist/services/framework-error.js.map +1 -1
- package/dist/services/interfaces.js.map +1 -1
- package/dist/services/section-controller-types.js.map +1 -1
- package/dist/services/tool-config-defaults.js +7 -1
- package/dist/services/tool-config-defaults.js.map +1 -1
- package/dist/services/tool-config-validation.js +3 -1
- package/dist/services/tool-config-validation.js.map +1 -1
- package/dist/services/tool-instance-id.js.map +1 -1
- package/dist/services/tool-providers/DesmosToolProvider.js.map +1 -1
- package/dist/services/tool-providers/TTSToolProvider.js.map +1 -1
- package/dist/services/toolbar-items.js.map +1 -1
- package/dist/services/tools-config-normalizer.js +1 -2
- package/dist/services/tools-config-normalizer.js.map +1 -1
- package/dist/services/tts/browser-provider.js +60 -18
- package/dist/services/tts/browser-provider.js.map +1 -1
- package/dist/services/tts/catalog-span-alignment.js +8 -3
- package/dist/services/tts/catalog-span-alignment.js.map +1 -1
- package/dist/services/tts/generated-speech/assemble-plan.js.map +1 -1
- package/dist/services/tts/generated-speech/index.d.ts +1 -1
- package/dist/services/tts/generated-speech/index.js +1 -1
- package/dist/services/tts/generated-speech/index.js.map +1 -1
- package/dist/services/tts/generated-speech/math-speech-cache.js +3 -1
- package/dist/services/tts/generated-speech/math-speech-cache.js.map +1 -1
- package/dist/services/tts/highlight-pipeline/boundary-normalizer.js.map +1 -1
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js.map +1 -1
- package/dist/services/tts/math-alignment/mathml-tokenizer.js.map +1 -1
- package/dist/services/tts/math-alignment/sequence-aligner.js.map +1 -1
- package/dist/services/tts/math-alignment/speech-tokenizer.js.map +1 -1
- package/dist/services/tts/math-aware-text-processing.js +6 -3
- package/dist/services/tts/math-aware-text-processing.js.map +1 -1
- package/dist/services/tts/math-speech.js +3 -1
- package/dist/services/tts/math-speech.js.map +1 -1
- package/dist/services/tts/visual-line-ranges.js.map +1 -1
- package/dist/services/tts-runtime-config.js +6 -2
- package/dist/services/tts-runtime-config.js.map +1 -1
- package/dist/tools/calculators/desmos-provider.js.map +1 -1
- package/dist/tools/default-tool-module-loaders.js.map +1 -1
- package/dist/tools/registrations/accessibility-tools.js.map +1 -1
- package/dist/tools/registrations/calculator.js +1 -1
- package/dist/tools/registrations/calculator.js.map +1 -1
- package/dist/tools/registrations/interaction-tools.js.map +1 -1
- package/dist/tools/registrations/measurement-tools.js.map +1 -1
- package/dist/tools/registrations/subject-specific-tools.js +1 -1
- package/dist/tools/registrations/subject-specific-tools.js.map +1 -1
- package/dist/tools/registrations/tts.js +4 -2
- package/dist/tools/registrations/tts.js.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/tools/variant-resolver.js.map +1 -1
- package/package.json +7 -7
|
@@ -10415,6 +10415,38 @@ var segmentSentences = (text2, options) => {
|
|
|
10415
10415
|
}
|
|
10416
10416
|
return parsed.length > 0 ? parsed : [{ text: text2, offset: 0 }];
|
|
10417
10417
|
};
|
|
10418
|
+
var normalizeLanguageCode = (value) => String(value || "").trim().toLowerCase();
|
|
10419
|
+
var browserLanguage = () => {
|
|
10420
|
+
const navigatorLanguage = typeof navigator !== "undefined" ? navigator.language || navigator.languages?.[0] : "";
|
|
10421
|
+
return normalizeLanguageCode(navigatorLanguage || "en-US");
|
|
10422
|
+
};
|
|
10423
|
+
var findBrowserVoice = (voices, preferredName) => {
|
|
10424
|
+
if (preferredName) {
|
|
10425
|
+
const explicit = voices.find((voice) => voice.name === preferredName);
|
|
10426
|
+
if (explicit)
|
|
10427
|
+
return explicit;
|
|
10428
|
+
}
|
|
10429
|
+
const language = browserLanguage();
|
|
10430
|
+
const languagePrefix = language.split("-")[0] || "en";
|
|
10431
|
+
const matchesLanguage = (voice) => {
|
|
10432
|
+
const voiceLanguage = normalizeLanguageCode(voice.lang);
|
|
10433
|
+
return voiceLanguage === language || voiceLanguage.startsWith(`${languagePrefix}-`);
|
|
10434
|
+
};
|
|
10435
|
+
const ranked = [
|
|
10436
|
+
(voice) => voice.localService && matchesLanguage(voice),
|
|
10437
|
+
(voice) => voice.default && matchesLanguage(voice),
|
|
10438
|
+
(voice) => matchesLanguage(voice),
|
|
10439
|
+
(voice) => voice.localService,
|
|
10440
|
+
(voice) => voice.default
|
|
10441
|
+
];
|
|
10442
|
+
for (const predicate of ranked) {
|
|
10443
|
+
const voice = voices.find(predicate);
|
|
10444
|
+
if (voice)
|
|
10445
|
+
return voice;
|
|
10446
|
+
}
|
|
10447
|
+
return voices[0] || null;
|
|
10448
|
+
};
|
|
10449
|
+
var shouldAssignBrowserVoice = (voice) => !voice.default;
|
|
10418
10450
|
|
|
10419
10451
|
class BrowserTTSProvider {
|
|
10420
10452
|
providerId = "browser";
|
|
@@ -10570,24 +10602,28 @@ class BrowserTTSProviderImpl {
|
|
|
10570
10602
|
resolve(false);
|
|
10571
10603
|
return;
|
|
10572
10604
|
}
|
|
10573
|
-
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
this.utterance.voice = voice;
|
|
10579
|
-
}
|
|
10605
|
+
const utterance = new SpeechSynthesisUtterance(chunkText);
|
|
10606
|
+
this.utterance = utterance;
|
|
10607
|
+
const voice = findBrowserVoice(speechSynthesis.getVoices(), this.config?.voice);
|
|
10608
|
+
if (voice && shouldAssignBrowserVoice(voice))
|
|
10609
|
+
utterance.voice = voice;
|
|
10580
10610
|
if (this.config?.rate)
|
|
10581
|
-
|
|
10611
|
+
utterance.rate = this.config.rate;
|
|
10582
10612
|
if (this.config?.pitch)
|
|
10583
|
-
|
|
10584
|
-
|
|
10613
|
+
utterance.pitch = this.config.pitch;
|
|
10614
|
+
const clearOwnedUtterance = () => {
|
|
10615
|
+
if (this.utterance === utterance) {
|
|
10616
|
+
this.utterance = null;
|
|
10617
|
+
}
|
|
10618
|
+
};
|
|
10619
|
+
utterance.onstart = () => {
|
|
10585
10620
|
if (runId !== this.speakRunId)
|
|
10586
10621
|
return;
|
|
10587
10622
|
this._isPlaying = true;
|
|
10588
10623
|
this._isPaused = false;
|
|
10589
10624
|
};
|
|
10590
|
-
|
|
10625
|
+
utterance.onend = () => {
|
|
10626
|
+
clearOwnedUtterance();
|
|
10591
10627
|
if (runId !== this.speakRunId) {
|
|
10592
10628
|
resolve(false);
|
|
10593
10629
|
return;
|
|
@@ -10596,7 +10632,8 @@ class BrowserTTSProviderImpl {
|
|
|
10596
10632
|
this._isPaused = false;
|
|
10597
10633
|
resolve(true);
|
|
10598
10634
|
};
|
|
10599
|
-
|
|
10635
|
+
utterance.onerror = (event2) => {
|
|
10636
|
+
clearOwnedUtterance();
|
|
10600
10637
|
if (runId !== this.speakRunId) {
|
|
10601
10638
|
resolve(false);
|
|
10602
10639
|
return;
|
|
@@ -10609,17 +10646,17 @@ class BrowserTTSProviderImpl {
|
|
|
10609
10646
|
}
|
|
10610
10647
|
reject(new Error(`Speech synthesis error: ${event2.error}`));
|
|
10611
10648
|
};
|
|
10612
|
-
|
|
10649
|
+
utterance.onpause = () => {
|
|
10613
10650
|
if (runId !== this.speakRunId)
|
|
10614
10651
|
return;
|
|
10615
10652
|
this._isPaused = true;
|
|
10616
10653
|
};
|
|
10617
|
-
|
|
10654
|
+
utterance.onresume = () => {
|
|
10618
10655
|
if (runId !== this.speakRunId)
|
|
10619
10656
|
return;
|
|
10620
10657
|
this._isPaused = false;
|
|
10621
10658
|
};
|
|
10622
|
-
|
|
10659
|
+
utterance.onboundary = (event2) => {
|
|
10623
10660
|
if (runId !== this.speakRunId)
|
|
10624
10661
|
return;
|
|
10625
10662
|
console.log("[BrowserProvider] Boundary event:", event2.name, "charIndex:", event2.charIndex, "charLength:", event2.charLength);
|
|
@@ -10637,7 +10674,7 @@ class BrowserTTSProviderImpl {
|
|
|
10637
10674
|
console.log("[BrowserProvider] Calling onWordBoundary with word:", word, "at position:", absoluteBoundaryStart);
|
|
10638
10675
|
this.onWordBoundary(word, absoluteBoundaryStart, wordLength);
|
|
10639
10676
|
};
|
|
10640
|
-
speechSynthesis.speak(
|
|
10677
|
+
speechSynthesis.speak(utterance);
|
|
10641
10678
|
});
|
|
10642
10679
|
}
|
|
10643
10680
|
pause() {
|
|
@@ -10652,9 +10689,10 @@ class BrowserTTSProviderImpl {
|
|
|
10652
10689
|
}
|
|
10653
10690
|
stop() {
|
|
10654
10691
|
this.speakRunId += 1;
|
|
10655
|
-
if (this._isPlaying) {
|
|
10692
|
+
if (this._isPlaying || this.utterance) {
|
|
10656
10693
|
speechSynthesis.cancel();
|
|
10657
10694
|
}
|
|
10695
|
+
this.utterance = null;
|
|
10658
10696
|
this._isPlaying = false;
|
|
10659
10697
|
this._isPaused = false;
|
|
10660
10698
|
}
|
|
@@ -12774,6 +12812,7 @@ function ItemToolBar($$anchor, $$props) {
|
|
|
12774
12812
|
const FA_PRO_HREFS = ["/_fa-pro/fontawesome.min.css", "/_fa-pro/light.min.css"];
|
|
12775
12813
|
const FA_FREE_HREF = "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/css/all.min.css";
|
|
12776
12814
|
const ROBOTO_HREF = "https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap";
|
|
12815
|
+
const FA_HREF_PATTERN = /font.?awesome|fa-?pro/i;
|
|
12777
12816
|
let ndsAssetsInstalled = false;
|
|
12778
12817
|
const ensureNdsAssets = () => {
|
|
12779
12818
|
if (!isBrowser || ndsAssetsInstalled)
|
|
@@ -12785,6 +12824,9 @@ function ItemToolBar($$anchor, $$props) {
|
|
|
12785
12824
|
link2.href = ROBOTO_HREF;
|
|
12786
12825
|
document.head.appendChild(link2);
|
|
12787
12826
|
}
|
|
12827
|
+
const hostHasFa = Array.from(document.querySelectorAll('link[rel="stylesheet"][href]')).some((link2) => FA_HREF_PATTERN.test(link2.href));
|
|
12828
|
+
if (hostHasFa)
|
|
12829
|
+
return;
|
|
12788
12830
|
if (!document.querySelector(`link[href="${FA_FREE_HREF}"]`)) {
|
|
12789
12831
|
const link2 = document.createElement("link");
|
|
12790
12832
|
link2.rel = "stylesheet";
|
|
@@ -12801,7 +12843,6 @@ function ItemToolBar($$anchor, $$props) {
|
|
|
12801
12843
|
}
|
|
12802
12844
|
};
|
|
12803
12845
|
const FA_TOOLBAR_SHADOW_INSTALLED = "__pieFaToolbarShadowInstalled";
|
|
12804
|
-
const FA_HREF_PATTERN = /font.?awesome|fa-?pro/i;
|
|
12805
12846
|
const installFaInToolbarShadow = (root) => {
|
|
12806
12847
|
const shadow = root.getRootNode();
|
|
12807
12848
|
if (!(shadow instanceof ShadowRoot))
|
|
@@ -12823,9 +12864,6 @@ function ItemToolBar($$anchor, $$props) {
|
|
|
12823
12864
|
const documentFaLinks = Array.from(document.querySelectorAll('link[rel="stylesheet"][href]')).filter((link2) => FA_HREF_PATTERN.test(link2.href));
|
|
12824
12865
|
for (const link2 of documentFaLinks)
|
|
12825
12866
|
appendLink(link2.href);
|
|
12826
|
-
const shim = document.createElement("style");
|
|
12827
|
-
shim.textContent = '.fa-light{font-family:"Font Awesome 6 Free";font-weight:900;}';
|
|
12828
|
-
shadow.appendChild(shim);
|
|
12829
12867
|
};
|
|
12830
12868
|
const ndsIconButtonAction = (node) => {
|
|
12831
12869
|
ensureNdsAssets();
|
package/dist/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export { ToolkitCoordinator } from "./services/ToolkitCoordinator.js";
|
|
|
43
43
|
export type { CanonicalToolsConfig, ToolPlacementConfig, ToolPlacementLevel, ToolPolicyConfig, ToolProvidersConfig, } from "./services/tools-config-normalizer.js";
|
|
44
44
|
export type { FrameworkErrorKind, FrameworkErrorModel, FrameworkErrorSeverity, } from "./services/framework-error.js";
|
|
45
45
|
export { formatFrameworkErrorForConsole, frameworkErrorFromToolConfigDiagnostics, frameworkErrorFromUnknown, toFrameworkErrorModel, } from "./services/framework-error.js";
|
|
46
|
-
export type { FrameworkErrorListener
|
|
46
|
+
export type { FrameworkErrorListener } from "./services/framework-error-bus.js";
|
|
47
47
|
export type { ToolConfigDiagnostic, ToolConfigDiagnosticSeverity, ToolConfigStrictness, ToolConfigValidationOptions, ToolConfigValidationResult, } from "./services/tool-config-validation.js";
|
|
48
48
|
export type { ToolbarButtonItem, ToolbarItem, ToolbarItemBase, ToolbarLinkItem, } from "./services/toolbar-items.js";
|
|
49
49
|
export { isExternalIconUrl, isInlineSvgIcon, isToolbarLinkItem, isValidToolbarItemShape, } from "./services/toolbar-items.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * PIE Assessment Toolkit\n *\n * Independent, composable services for coordinating tools, accommodations,\n * and item players in assessment applications.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Core Infrastructure\n// ============================================================================\n\nexport type {\n\tAssessmentToolkitHostRuntimeContext,\n\tAssessmentToolkitRegionScopeContext,\n\tAssessmentToolkitRuntimeContext,\n\tAssessmentToolkitShellContext,\n\tItemPlayerConfig,\n\tItemPlayerType,\n\tShellContextKind,\n} from \"./context/assessment-toolkit-context.js\";\nexport {\n\tassessmentToolkitHostRuntimeContext,\n\tassessmentToolkitRegionScopeContext,\n\tassessmentToolkitRuntimeContext,\n\tassessmentToolkitShellContext,\n} from \"./context/assessment-toolkit-context.js\";\nexport {\n\tconnectAssessmentToolkitHostRuntimeContext,\n\tconnectAssessmentToolkitRegionScopeContext,\n\tconnectAssessmentToolkitRuntimeContext,\n\tconnectAssessmentToolkitShellContext,\n} from \"./context/runtime-context-consumer.js\";\nexport {\n\tPIE_INTERNAL_CONTENT_LOADED_EVENT,\n\tPIE_INTERNAL_ITEM_SESSION_CHANGED_EVENT,\n\tPIE_INTERNAL_ITEM_PLAYER_ERROR_EVENT,\n\tPIE_ITEM_SESSION_CHANGED_EVENT,\n\tPIE_REGISTER_EVENT,\n\tPIE_UNREGISTER_EVENT,\n\ttype InternalContentLoadedDetail,\n\ttype InternalItemSessionChangedDetail,\n\ttype InternalItemPlayerErrorDetail,\n\ttype ItemSessionChangedDetail,\n\ttype RuntimeRegistrationDetail,\n\ttype RuntimeRegistrationKind,\n} from \"./runtime/registration-events.js\";\nexport {\n\tconnectToolRegionScopeContext,\n\tconnectToolRuntimeContext,\n\tconnectToolShellContext,\n\tcreateCrossBoundaryEvent,\n\tdispatchCrossBoundaryEvent,\n\tisContextValueDefined,\n} from \"./runtime/tool-host-contract.js\";\n\n// ============================================================================\n// Service Interfaces\n// ============================================================================\n\nexport type {\n\tAccessibilityCatalogResolverApi,\n\tElementToolStateStoreApi,\n\tHighlightCoordinatorApi,\n\tI18nServiceApi,\n\tThemeProviderApi,\n\tToolCoordinatorApi,\n\tToolkitCoordinatorApi,\n\tTtsServiceApi,\n\tToolState,\n} from \"./services/interfaces.js\";\n\n// ============================================================================\n// Toolkit Services\n// ============================================================================\n\n// Accessibility Catalog Resolver (QTI 3.0 Accessibility Catalogs)\nexport type {\n\tCatalogLookupContext,\n\tCatalogLookupOptions,\n\tCatalogOwnerContext,\n\tCatalogOwnerKind,\n\tCatalogStatistics,\n\tCatalogType,\n\tResolvedCatalog,\n} from \"./services/AccessibilityCatalogResolver.js\";\nexport { AccessibilityCatalogResolver } from \"./services/AccessibilityCatalogResolver.js\";\n// Context Variable Store (QTI 3.0 Context Declarations)\nexport { ContextVariableStore } from \"./services/ContextVariableStore.js\";\n// Element Tool State Store (Element-level ephemeral tool state)\nexport { ElementToolStateStore } from \"./services/ElementToolStateStore.js\";\n// Highlight Coordinator\nexport type { Annotation } from \"./services/HighlightCoordinator.js\";\nexport {\n\tHighlightColor,\n\tHighlightCoordinator,\n\tHighlightType,\n} from \"./services/HighlightCoordinator.js\";\n// Range Serializer (for annotation persistence)\nexport type { SerializedRange } from \"./services/RangeSerializer.js\";\nexport { RangeSerializer } from \"./services/RangeSerializer.js\";\n// I18n Service\nexport type {\n\tI18nConfig,\n\tPluralTranslation,\n\tTranslationBundle,\n} from \"./services/I18nService.js\";\nexport { I18nService } from \"./services/I18nService.js\";\n// Tool Registry (Registry-based tool system)\nexport type {\n\tResolvedToolContext,\n\tToolbarContext,\n\tToolContextResolver,\n\tToolContextResolverContext,\n\tToolContextResolverMap,\n\tToolContextResolverResult,\n\tToolModuleLoader,\n\tToolToolbarButtonDefinition,\n\tToolToolbarRenderResult,\n\tToolRegistration,\n} from \"./services/ToolRegistry.js\";\nexport { ToolRegistry } from \"./services/ToolRegistry.js\";\nexport type {\n\tAssessmentToolContext,\n\tBaseToolContext,\n\tElementToolContext,\n\tItemToolContext,\n\tPassageToolContext,\n\tRubricToolContext,\n\tSectionToolContext,\n\tToolContext,\n\tToolLevel,\n} from \"./services/tool-context.js\";\nexport {\n\textractTextContent,\n\thasChoiceInteraction,\n\thasMathContent,\n\thasReadableText,\n\tisAssessmentContext,\n\tisElementContext,\n\tisItemContext,\n\tisPassageContext,\n\tisRubricContext,\n\tisSectionContext,\n} from \"./services/tool-context.js\";\nexport {\n\tDEFAULT_TOOL_PLACEMENT,\n\tDEFAULT_TOOL_ORDER,\n\tcreatePackagedToolRegistry,\n\tPACKAGED_TOOL_PLACEMENT,\n\tregisterPackagedTools,\n} from \"./services/createDefaultToolRegistry.js\";\nexport type { CreateToolsConfigArgs } from \"./services/create-tools-config.js\";\nexport { createToolsConfig } from \"./services/create-tools-config.js\";\nexport {\n\tDEFAULT_PERSONAL_NEEDS_PROFILE,\n\tcreateDefaultPersonalNeedsProfile,\n} from \"./services/defaultPersonalNeedsProfile.js\";\nexport type {\n\tToolComponentFactory,\n\tToolComponentFactoryMap,\n\tToolComponentOverrides,\n\tToolTagMap,\n} from \"./tools/tool-tag-map.js\";\nexport {\n\tcreateToolElement,\n\tDEFAULT_TOOL_TAG_MAP,\n\tresolveToolTag,\n\ttoToolIdFromTag,\n} from \"./tools/tool-tag-map.js\";\n// QTI 3.0 Standard Access Features\nexport {\n\tALL_STANDARD_ACCESS_FEATURES,\n\tEXAMPLE_PNP_CONFIGURATIONS,\n\tgetFeatureCategory,\n\tgetFeaturesInCategory,\n\tisStandardAccessFeature,\n\tQTI_STANDARD_ACCESS_FEATURES,\n} from \"./services/pnp-standard-features.js\";\n// SSML Extractor (Auto-generates catalogs from embedded SSML)\nexport type { ExtractionResult } from \"./services/SSMLExtractor.js\";\nexport { SSMLExtractor } from \"./services/SSMLExtractor.js\";\n// Theme Provider\nexport type { FontSize, ThemeConfig } from \"./services/ThemeProvider.js\";\nexport { ThemeProvider } from \"./services/ThemeProvider.js\";\n// Tool Coordinator\nexport { ToolCoordinator, ZIndexLayer } from \"./services/ToolCoordinator.js\";\n// Toolkit Coordinator (Centralized service management)\nexport type {\n\tAnswerEliminatorToolConfig,\n\tProviderLifecycleContext,\n\tSectionControllerContext,\n\tSectionControllerEvent,\n\tSectionControllerEventType,\n\tSectionItemEvent,\n\tSectionItemEventType,\n\tSectionControllerFactoryDefaults,\n\tSectionControllerHandle,\n\tSectionControllerKey,\n\tSectionScopedEvent,\n\tSectionScopedEventType,\n\tSectionSessionPersistenceConfig,\n\tSectionItemEventSubscriptionArgs,\n\tSectionScopedEventSubscriptionArgs,\n\tSectionEventSubscriptionArgs,\n\tSectionSessionPersistenceStrategy,\n\tSectionControllerLoadedRenderable,\n\tSectionControllerRuntimeState,\n\tSectionControllerSessionState,\n\tSectionPersistenceFactoryDefaults,\n\tToolConfig,\n\tToolkitCoordinatorConfig,\n\tToolkitCoordinatorHooks,\n\tToolkitErrorContext,\n\tToolkitInitStatus,\n\tToolkitServiceBundle,\n\tToolkitToolsConfig,\n\tTTSToolConfig,\n} from \"./services/ToolkitCoordinator.js\";\nexport { ToolkitCoordinator } from \"./services/ToolkitCoordinator.js\";\nexport type {\n\tCanonicalToolsConfig,\n\tToolPlacementConfig,\n\tToolPlacementLevel,\n\tToolPolicyConfig,\n\tToolProvidersConfig,\n} from \"./services/tools-config-normalizer.js\";\nexport type {\n\tFrameworkErrorKind,\n\tFrameworkErrorModel,\n\tFrameworkErrorSeverity,\n} from \"./services/framework-error.js\";\nexport {\n\tformatFrameworkErrorForConsole,\n\tframeworkErrorFromToolConfigDiagnostics,\n\tframeworkErrorFromUnknown,\n\ttoFrameworkErrorModel,\n} from \"./services/framework-error.js\";\nexport type {\n\tFrameworkErrorListener,\n} from \"./services/framework-error-bus.js\";\nexport type {\n\tToolConfigDiagnostic,\n\tToolConfigDiagnosticSeverity,\n\tToolConfigStrictness,\n\tToolConfigValidationOptions,\n\tToolConfigValidationResult,\n} from \"./services/tool-config-validation.js\";\nexport type {\n\tToolbarButtonItem,\n\tToolbarItem,\n\tToolbarItemBase,\n\tToolbarLinkItem,\n} from \"./services/toolbar-items.js\";\nexport {\n\tisExternalIconUrl,\n\tisInlineSvgIcon,\n\tisToolbarLinkItem,\n\tisValidToolbarItemShape,\n} from \"./services/toolbar-items.js\";\nexport {\n\tnormalizeToolsConfig,\n\tnormalizeToolAlias,\n\tnormalizeToolList,\n\tparseToolList,\n} from \"./services/tools-config-normalizer.js\";\nexport {\n\tframeworkErrorFromToolConfigValidation,\n\tnormalizeAndValidateToolsConfig,\n} from \"./services/tool-config-validation.js\";\nexport type {\n\tParsedToolInstanceId,\n\tToolScopeLevel,\n} from \"./services/tool-instance-id.js\";\nexport {\n\tcreateScopedToolId,\n\tparseScopedToolId,\n\ttoOverlayToolId,\n} from \"./services/tool-instance-id.js\";\n// Text-to-Speech Service\nexport type { TTSConfig } from \"./services/TTSService.js\";\nexport { PlaybackState, TTSService } from \"./services/TTSService.js\";\nexport {\n\tPIE_TTS_CONTROL_HANDOFF_EVENT,\n\ttype TTSControlHandoffDetail,\n} from \"./services/tts-control-events.js\";\nexport { BrowserTTSProvider } from \"./services/tts/browser-provider.js\";\nexport type { SREMathSpeechOptions } from \"./services/tts/math-speech.js\";\nexport type {\n\tTTSHostToolbarLayout,\n\tTTSLayoutMode,\n\tTTSRuntimeSettings,\n} from \"./services/tts-runtime-config.js\";\nexport {\n\tDEFAULT_TTS_SPEED_OPTIONS,\n\tformatTTSSpeedOptionsAsText,\n\tnormalizeTTSLayoutMode,\n\tnormalizeTTSSpeedOptions,\n\tparseTTSSpeedOptionsFromText,\n\tresolveTTSHostToolbarLayout,\n\tresolveTTSLayoutMode,\n\tresolveTTSRuntimeSettings,\n} from \"./services/tts-runtime-config.js\";\n// TTS Provider System\nexport type {\n\tITTSProvider,\n\tITTSProviderImplementation,\n\tTTSSpeechSegment,\n\tTTSFeature,\n\tTTSProviderCapabilities,\n} from \"@pie-players/pie-tts\";\n\n// ============================================================================\n// Item loading (client-resolvable default; optional backend hook)\n// ============================================================================\n\nexport type {\n\tCreateLoadItemOptions,\n\tLoadItem,\n\tLoadItemOptions,\n} from \"./item-loader.js\";\nexport {\n\tcreateFetchItemLoader,\n\tcreateLoadItem,\n\tItemLoadError,\n} from \"./item-loader.js\";\n\n// ============================================================================\n// Attempt Session\n// ============================================================================\n\nexport type {\n\tStorageLike,\n\tTestAttemptItemSession,\n\tTestAttemptSession,\n\tTestAttemptSessionNavigationState,\n\tTestAttemptSessionRealization,\n} from \"./attempt/TestSession.js\";\nexport {\n\tcreateMemoryStorage,\n\tcreateTestAttemptSessionIdentifier,\n\tcreateNewTestAttemptSession,\n\tgetBrowserLocalStorage,\n\tgetOrCreateAnonymousDeviceId,\n\tgetTestAttemptSessionStorageKey,\n\tloadTestAttemptSession,\n\tsaveTestAttemptSession,\n\tsetCurrentPosition,\n\tupsertItemSessionFromPieSessionChange,\n\tupsertVisitedItem,\n} from \"./attempt/TestSession.js\";\nexport type {\n\tAssessmentSession,\n\tAssessmentSectionSessionState,\n\tAssessmentSessionNavigationState,\n\tAssessmentSessionRealization,\n} from \"./attempt/AssessmentSession.js\";\nexport {\n\tcreateNewAssessmentSession,\n\tgetAssessmentSessionStorageKey,\n\tloadAssessmentSession,\n\tsaveAssessmentSession,\n\tsetCurrentSectionPosition,\n\tupsertSectionSession,\n} from \"./attempt/AssessmentSession.js\";\nexport type {\n\tActivitySessionPatchPayload,\n\tMapActivityToTestAttemptSessionArgs,\n\tPieBackendActivityDefinition,\n\tPieBackendActivityItemRef,\n\tPieBackendActivitySession,\n} from \"./attempt/adapters/activity-to-test-attempt-session.js\";\nexport {\n\tbuildActivitySessionItemUpdate,\n\tbuildActivitySessionPatchFromTestAttemptSession,\n\tmapActivityToTestAttemptSession,\n\ttoItemSessionsRecord,\n} from \"./attempt/adapters/activity-to-test-attempt-session.js\";\n\n// Section Player - Use @pie-players/pie-section-player web component\n\n// ============================================================================\n// Shared Components\n// ============================================================================\n\n// ItemToolBar custom element registration helper is exported via package.json exports field\n// Import using: import '@pie-players/pie-assessment-toolkit/components/item-toolbar-element';\n// PieAssessmentToolkit custom element registration helper is exported via package.json exports field\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * PIE Assessment Toolkit\n *\n * Independent, composable services for coordinating tools, accommodations,\n * and item players in assessment applications.\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// Core Infrastructure\n// ============================================================================\n\nexport type {\n\tAssessmentToolkitHostRuntimeContext,\n\tAssessmentToolkitRegionScopeContext,\n\tAssessmentToolkitRuntimeContext,\n\tAssessmentToolkitShellContext,\n\tItemPlayerConfig,\n\tItemPlayerType,\n\tShellContextKind,\n} from \"./context/assessment-toolkit-context.js\";\nexport {\n\tassessmentToolkitHostRuntimeContext,\n\tassessmentToolkitRegionScopeContext,\n\tassessmentToolkitRuntimeContext,\n\tassessmentToolkitShellContext,\n} from \"./context/assessment-toolkit-context.js\";\nexport {\n\tconnectAssessmentToolkitHostRuntimeContext,\n\tconnectAssessmentToolkitRegionScopeContext,\n\tconnectAssessmentToolkitRuntimeContext,\n\tconnectAssessmentToolkitShellContext,\n} from \"./context/runtime-context-consumer.js\";\nexport {\n\tPIE_INTERNAL_CONTENT_LOADED_EVENT,\n\tPIE_INTERNAL_ITEM_SESSION_CHANGED_EVENT,\n\tPIE_INTERNAL_ITEM_PLAYER_ERROR_EVENT,\n\tPIE_ITEM_SESSION_CHANGED_EVENT,\n\tPIE_REGISTER_EVENT,\n\tPIE_UNREGISTER_EVENT,\n\ttype InternalContentLoadedDetail,\n\ttype InternalItemSessionChangedDetail,\n\ttype InternalItemPlayerErrorDetail,\n\ttype ItemSessionChangedDetail,\n\ttype RuntimeRegistrationDetail,\n\ttype RuntimeRegistrationKind,\n} from \"./runtime/registration-events.js\";\nexport {\n\tconnectToolRegionScopeContext,\n\tconnectToolRuntimeContext,\n\tconnectToolShellContext,\n\tcreateCrossBoundaryEvent,\n\tdispatchCrossBoundaryEvent,\n\tisContextValueDefined,\n} from \"./runtime/tool-host-contract.js\";\n\n// ============================================================================\n// Service Interfaces\n// ============================================================================\n\nexport type {\n\tAccessibilityCatalogResolverApi,\n\tElementToolStateStoreApi,\n\tHighlightCoordinatorApi,\n\tI18nServiceApi,\n\tThemeProviderApi,\n\tToolCoordinatorApi,\n\tToolkitCoordinatorApi,\n\tTtsServiceApi,\n\tToolState,\n} from \"./services/interfaces.js\";\n\n// ============================================================================\n// Toolkit Services\n// ============================================================================\n\n// Accessibility Catalog Resolver (QTI 3.0 Accessibility Catalogs)\nexport type {\n\tCatalogLookupContext,\n\tCatalogLookupOptions,\n\tCatalogOwnerContext,\n\tCatalogOwnerKind,\n\tCatalogStatistics,\n\tCatalogType,\n\tResolvedCatalog,\n} from \"./services/AccessibilityCatalogResolver.js\";\nexport { AccessibilityCatalogResolver } from \"./services/AccessibilityCatalogResolver.js\";\n// Context Variable Store (QTI 3.0 Context Declarations)\nexport { ContextVariableStore } from \"./services/ContextVariableStore.js\";\n// Element Tool State Store (Element-level ephemeral tool state)\nexport { ElementToolStateStore } from \"./services/ElementToolStateStore.js\";\n// Highlight Coordinator\nexport type { Annotation } from \"./services/HighlightCoordinator.js\";\nexport {\n\tHighlightColor,\n\tHighlightCoordinator,\n\tHighlightType,\n} from \"./services/HighlightCoordinator.js\";\n// Range Serializer (for annotation persistence)\nexport type { SerializedRange } from \"./services/RangeSerializer.js\";\nexport { RangeSerializer } from \"./services/RangeSerializer.js\";\n// I18n Service\nexport type {\n\tI18nConfig,\n\tPluralTranslation,\n\tTranslationBundle,\n} from \"./services/I18nService.js\";\nexport { I18nService } from \"./services/I18nService.js\";\n// Tool Registry (Registry-based tool system)\nexport type {\n\tResolvedToolContext,\n\tToolbarContext,\n\tToolContextResolver,\n\tToolContextResolverContext,\n\tToolContextResolverMap,\n\tToolContextResolverResult,\n\tToolModuleLoader,\n\tToolToolbarButtonDefinition,\n\tToolToolbarRenderResult,\n\tToolRegistration,\n} from \"./services/ToolRegistry.js\";\nexport { ToolRegistry } from \"./services/ToolRegistry.js\";\nexport type {\n\tAssessmentToolContext,\n\tBaseToolContext,\n\tElementToolContext,\n\tItemToolContext,\n\tPassageToolContext,\n\tRubricToolContext,\n\tSectionToolContext,\n\tToolContext,\n\tToolLevel,\n} from \"./services/tool-context.js\";\nexport {\n\textractTextContent,\n\thasChoiceInteraction,\n\thasMathContent,\n\thasReadableText,\n\tisAssessmentContext,\n\tisElementContext,\n\tisItemContext,\n\tisPassageContext,\n\tisRubricContext,\n\tisSectionContext,\n} from \"./services/tool-context.js\";\nexport {\n\tDEFAULT_TOOL_PLACEMENT,\n\tDEFAULT_TOOL_ORDER,\n\tcreatePackagedToolRegistry,\n\tPACKAGED_TOOL_PLACEMENT,\n\tregisterPackagedTools,\n} from \"./services/createDefaultToolRegistry.js\";\nexport type { CreateToolsConfigArgs } from \"./services/create-tools-config.js\";\nexport { createToolsConfig } from \"./services/create-tools-config.js\";\nexport {\n\tDEFAULT_PERSONAL_NEEDS_PROFILE,\n\tcreateDefaultPersonalNeedsProfile,\n} from \"./services/defaultPersonalNeedsProfile.js\";\nexport type {\n\tToolComponentFactory,\n\tToolComponentFactoryMap,\n\tToolComponentOverrides,\n\tToolTagMap,\n} from \"./tools/tool-tag-map.js\";\nexport {\n\tcreateToolElement,\n\tDEFAULT_TOOL_TAG_MAP,\n\tresolveToolTag,\n\ttoToolIdFromTag,\n} from \"./tools/tool-tag-map.js\";\n// QTI 3.0 Standard Access Features\nexport {\n\tALL_STANDARD_ACCESS_FEATURES,\n\tEXAMPLE_PNP_CONFIGURATIONS,\n\tgetFeatureCategory,\n\tgetFeaturesInCategory,\n\tisStandardAccessFeature,\n\tQTI_STANDARD_ACCESS_FEATURES,\n} from \"./services/pnp-standard-features.js\";\n// SSML Extractor (Auto-generates catalogs from embedded SSML)\nexport type { ExtractionResult } from \"./services/SSMLExtractor.js\";\nexport { SSMLExtractor } from \"./services/SSMLExtractor.js\";\n// Theme Provider\nexport type { FontSize, ThemeConfig } from \"./services/ThemeProvider.js\";\nexport { ThemeProvider } from \"./services/ThemeProvider.js\";\n// Tool Coordinator\nexport { ToolCoordinator, ZIndexLayer } from \"./services/ToolCoordinator.js\";\n// Toolkit Coordinator (Centralized service management)\nexport type {\n\tAnswerEliminatorToolConfig,\n\tProviderLifecycleContext,\n\tSectionControllerContext,\n\tSectionControllerEvent,\n\tSectionControllerEventType,\n\tSectionItemEvent,\n\tSectionItemEventType,\n\tSectionControllerFactoryDefaults,\n\tSectionControllerHandle,\n\tSectionControllerKey,\n\tSectionScopedEvent,\n\tSectionScopedEventType,\n\tSectionSessionPersistenceConfig,\n\tSectionItemEventSubscriptionArgs,\n\tSectionScopedEventSubscriptionArgs,\n\tSectionEventSubscriptionArgs,\n\tSectionSessionPersistenceStrategy,\n\tSectionControllerLoadedRenderable,\n\tSectionControllerRuntimeState,\n\tSectionControllerSessionState,\n\tSectionPersistenceFactoryDefaults,\n\tToolConfig,\n\tToolkitCoordinatorConfig,\n\tToolkitCoordinatorHooks,\n\tToolkitErrorContext,\n\tToolkitInitStatus,\n\tToolkitServiceBundle,\n\tToolkitToolsConfig,\n\tTTSToolConfig,\n} from \"./services/ToolkitCoordinator.js\";\nexport { ToolkitCoordinator } from \"./services/ToolkitCoordinator.js\";\nexport type {\n\tCanonicalToolsConfig,\n\tToolPlacementConfig,\n\tToolPlacementLevel,\n\tToolPolicyConfig,\n\tToolProvidersConfig,\n} from \"./services/tools-config-normalizer.js\";\nexport type {\n\tFrameworkErrorKind,\n\tFrameworkErrorModel,\n\tFrameworkErrorSeverity,\n} from \"./services/framework-error.js\";\nexport {\n\tformatFrameworkErrorForConsole,\n\tframeworkErrorFromToolConfigDiagnostics,\n\tframeworkErrorFromUnknown,\n\ttoFrameworkErrorModel,\n} from \"./services/framework-error.js\";\nexport type { FrameworkErrorListener } from \"./services/framework-error-bus.js\";\nexport type {\n\tToolConfigDiagnostic,\n\tToolConfigDiagnosticSeverity,\n\tToolConfigStrictness,\n\tToolConfigValidationOptions,\n\tToolConfigValidationResult,\n} from \"./services/tool-config-validation.js\";\nexport type {\n\tToolbarButtonItem,\n\tToolbarItem,\n\tToolbarItemBase,\n\tToolbarLinkItem,\n} from \"./services/toolbar-items.js\";\nexport {\n\tisExternalIconUrl,\n\tisInlineSvgIcon,\n\tisToolbarLinkItem,\n\tisValidToolbarItemShape,\n} from \"./services/toolbar-items.js\";\nexport {\n\tnormalizeToolsConfig,\n\tnormalizeToolAlias,\n\tnormalizeToolList,\n\tparseToolList,\n} from \"./services/tools-config-normalizer.js\";\nexport {\n\tframeworkErrorFromToolConfigValidation,\n\tnormalizeAndValidateToolsConfig,\n} from \"./services/tool-config-validation.js\";\nexport type {\n\tParsedToolInstanceId,\n\tToolScopeLevel,\n} from \"./services/tool-instance-id.js\";\nexport {\n\tcreateScopedToolId,\n\tparseScopedToolId,\n\ttoOverlayToolId,\n} from \"./services/tool-instance-id.js\";\n// Text-to-Speech Service\nexport type { TTSConfig } from \"./services/TTSService.js\";\nexport { PlaybackState, TTSService } from \"./services/TTSService.js\";\nexport {\n\tPIE_TTS_CONTROL_HANDOFF_EVENT,\n\ttype TTSControlHandoffDetail,\n} from \"./services/tts-control-events.js\";\nexport { BrowserTTSProvider } from \"./services/tts/browser-provider.js\";\nexport type { SREMathSpeechOptions } from \"./services/tts/math-speech.js\";\nexport type {\n\tTTSHostToolbarLayout,\n\tTTSLayoutMode,\n\tTTSRuntimeSettings,\n} from \"./services/tts-runtime-config.js\";\nexport {\n\tDEFAULT_TTS_SPEED_OPTIONS,\n\tformatTTSSpeedOptionsAsText,\n\tnormalizeTTSLayoutMode,\n\tnormalizeTTSSpeedOptions,\n\tparseTTSSpeedOptionsFromText,\n\tresolveTTSHostToolbarLayout,\n\tresolveTTSLayoutMode,\n\tresolveTTSRuntimeSettings,\n} from \"./services/tts-runtime-config.js\";\n// TTS Provider System\nexport type {\n\tITTSProvider,\n\tITTSProviderImplementation,\n\tTTSSpeechSegment,\n\tTTSFeature,\n\tTTSProviderCapabilities,\n} from \"@pie-players/pie-tts\";\n\n// ============================================================================\n// Item loading (client-resolvable default; optional backend hook)\n// ============================================================================\n\nexport type {\n\tCreateLoadItemOptions,\n\tLoadItem,\n\tLoadItemOptions,\n} from \"./item-loader.js\";\nexport {\n\tcreateFetchItemLoader,\n\tcreateLoadItem,\n\tItemLoadError,\n} from \"./item-loader.js\";\n\n// ============================================================================\n// Attempt Session\n// ============================================================================\n\nexport type {\n\tStorageLike,\n\tTestAttemptItemSession,\n\tTestAttemptSession,\n\tTestAttemptSessionNavigationState,\n\tTestAttemptSessionRealization,\n} from \"./attempt/TestSession.js\";\nexport {\n\tcreateMemoryStorage,\n\tcreateTestAttemptSessionIdentifier,\n\tcreateNewTestAttemptSession,\n\tgetBrowserLocalStorage,\n\tgetOrCreateAnonymousDeviceId,\n\tgetTestAttemptSessionStorageKey,\n\tloadTestAttemptSession,\n\tsaveTestAttemptSession,\n\tsetCurrentPosition,\n\tupsertItemSessionFromPieSessionChange,\n\tupsertVisitedItem,\n} from \"./attempt/TestSession.js\";\nexport type {\n\tAssessmentSession,\n\tAssessmentSectionSessionState,\n\tAssessmentSessionNavigationState,\n\tAssessmentSessionRealization,\n} from \"./attempt/AssessmentSession.js\";\nexport {\n\tcreateNewAssessmentSession,\n\tgetAssessmentSessionStorageKey,\n\tloadAssessmentSession,\n\tsaveAssessmentSession,\n\tsetCurrentSectionPosition,\n\tupsertSectionSession,\n} from \"./attempt/AssessmentSession.js\";\nexport type {\n\tActivitySessionPatchPayload,\n\tMapActivityToTestAttemptSessionArgs,\n\tPieBackendActivityDefinition,\n\tPieBackendActivityItemRef,\n\tPieBackendActivitySession,\n} from \"./attempt/adapters/activity-to-test-attempt-session.js\";\nexport {\n\tbuildActivitySessionItemUpdate,\n\tbuildActivitySessionPatchFromTestAttemptSession,\n\tmapActivityToTestAttemptSession,\n\ttoItemSessionsRecord,\n} from \"./attempt/adapters/activity-to-test-attempt-session.js\";\n\n// Section Player - Use @pie-players/pie-section-player web component\n\n// ============================================================================\n// Shared Components\n// ============================================================================\n\n// ItemToolBar custom element registration helper is exported via package.json exports field\n// Import using: import '@pie-players/pie-assessment-toolkit/components/item-toolbar-element';\n// PieAssessmentToolkit custom element registration helper is exported via package.json exports field\n"]}
|
|
@@ -49,8 +49,7 @@ export function assessmentHasPnpPolicyInputs(assessment) {
|
|
|
49
49
|
pnp.prohibitedSupports.length > 0) {
|
|
50
50
|
return true;
|
|
51
51
|
}
|
|
52
|
-
if (Array.isArray(pnp.activateAtInit) &&
|
|
53
|
-
pnp.activateAtInit.length > 0) {
|
|
52
|
+
if (Array.isArray(pnp.activateAtInit) && pnp.activateAtInit.length > 0) {
|
|
54
53
|
return true;
|
|
55
54
|
}
|
|
56
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pnp-policy-inputs.js","sourceRoot":"","sources":["../../../src/policy/core/pnp-policy-inputs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAOH;;;;;;;GAOG;AACH,MAAM,UAAU,4BAA4B,CAC3C,UAA+C;IAE/C,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,MAAM,GAAG,GAAG,UAAU,CAAC,oBAAoB,CAAC;IAC5C,IAAI,GAAG,EAAE,CAAC;QACT,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACxE,IACC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YACrC,GAAG,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAChC,CAAC;YACF,OAAO,IAAI,CAAC;QACb,CAAC;QACD,
|
|
1
|
+
{"version":3,"file":"pnp-policy-inputs.js","sourceRoot":"","sources":["../../../src/policy/core/pnp-policy-inputs.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * PNP/profile policy input detection (M8 PR 4 — see `.cursor/plans/m8-design.md` F2 and\n * `.cursor/plans/m8-implementation-plan.md` § PR 4).\n *\n * Pure helpers that decide whether the inputs the engine has been given\n * actually carry PNP/profile policy material. Used by:\n *\n * - {@link ToolPolicyEngine}'s constructor as the auto-default for\n * `pnpEnforcement` when the host did not pass an explicit `\"on\"` /\n * `\"off\"`.\n * - {@link ToolkitCoordinator.resolveEffectivePnpEnforcement} as the\n * auto-mode rule. PR 2 used a coarse \"any non-null assessment → on\"\n * placeholder; PR 4 narrows it to \"assessment OR currentItemRef\n * carries profile policy material.\"\n *\n * The rule is intentionally narrow. Hosts that bind a bare assessment\n * record (only `id` / `name`, no PNP and no settings) do not engage\n * PNP/profile gates. The flip happens the moment the assessment carries any of:\n *\n * - `personalNeedsProfile` (any `supports`, `prohibitedSupports`, or\n * `activateAtInit`),\n * - `settings.districtPolicy` (any `blockedTools`, `requiredTools`,\n * or `policies`),\n * - `settings.testAdministration` (any populated key — `mode`,\n * `toolOverrides`, etc.),\n * - or the bound `currentItemRef.settings` carries\n * `requiredTools` / `restrictedTools` / `toolParameters`.\n *\n * Hosts opt out of the auto-on behavior by passing\n * `pnpEnforcement: \"off\"` explicitly (engine input or\n * `ToolkitCoordinator.setPnpEnforcement(\"off\")`).\n */\n\nimport type {\n\tAssessmentEntity,\n\tAssessmentItemRef,\n} from \"@pie-players/pie-players-shared/types\";\n\n/**\n * Return `true` when the assessment carries any PNP/profile policy\n * material that the engine's `PnpPolicySource` would consume.\n *\n * The check is structural — the presence of a non-empty PNP, district\n * policy, or test administration block is enough; the content does not\n * have to validate against any specific rule.\n */\nexport function assessmentHasPnpPolicyInputs(\n\tassessment: AssessmentEntity | null | undefined,\n): boolean {\n\tif (!assessment) return false;\n\tconst pnp = assessment.personalNeedsProfile;\n\tif (pnp) {\n\t\tif (Array.isArray(pnp.supports) && pnp.supports.length > 0) return true;\n\t\tif (\n\t\t\tArray.isArray(pnp.prohibitedSupports) &&\n\t\t\tpnp.prohibitedSupports.length > 0\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tif (Array.isArray(pnp.activateAtInit) && pnp.activateAtInit.length > 0) {\n\t\t\treturn true;\n\t\t}\n\t}\n\tconst settings = assessment.settings;\n\tif (settings) {\n\t\tconst district = settings.districtPolicy;\n\t\tif (district) {\n\t\t\tif (\n\t\t\t\tArray.isArray(district.blockedTools) &&\n\t\t\t\tdistrict.blockedTools.length > 0\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tArray.isArray(district.requiredTools) &&\n\t\t\t\tdistrict.requiredTools.length > 0\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tdistrict.policies &&\n\t\t\t\ttypeof district.policies === \"object\" &&\n\t\t\t\tObject.keys(district.policies).length > 0\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tconst admin = settings.testAdministration;\n\t\tif (admin && typeof admin === \"object\") {\n\t\t\tfor (const key of Object.keys(admin)) {\n\t\t\t\tconst value = (admin as Record<string, unknown>)[key];\n\t\t\t\tif (value === undefined || value === null) continue;\n\t\t\t\tif (Array.isArray(value) && value.length === 0) continue;\n\t\t\t\tif (\n\t\t\t\t\ttypeof value === \"object\" &&\n\t\t\t\t\t!Array.isArray(value) &&\n\t\t\t\t\tObject.keys(value as Record<string, unknown>).length === 0\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Return `true` when the bound item reference carries item-level profile policy\n * material (`requiredTools`, `restrictedTools`, or `toolParameters`).\n *\n * Used in addition to {@link assessmentHasPnpPolicyInputs} so a host that\n * navigates to an item with profile-relevant settings — without a parent\n * assessment carrying its own PNP/district/test-admin block — still\n * gets PNP/profile gates engaged for that item.\n */\nexport function itemRefHasPnpPolicyInputs(\n\titemRef: AssessmentItemRef | null | undefined,\n): boolean {\n\tconst settings = itemRef?.settings;\n\tif (!settings) return false;\n\tif (\n\t\tArray.isArray(settings.requiredTools) &&\n\t\tsettings.requiredTools.length > 0\n\t) {\n\t\treturn true;\n\t}\n\tif (\n\t\tArray.isArray(settings.restrictedTools) &&\n\t\tsettings.restrictedTools.length > 0\n\t) {\n\t\treturn true;\n\t}\n\tif (\n\t\tsettings.toolParameters &&\n\t\ttypeof settings.toolParameters === \"object\" &&\n\t\tObject.keys(settings.toolParameters).length > 0\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Resolve the default `pnpEnforcement` mode given the bound inputs.\n *\n * Returns `\"on\"` when {@link assessmentHasPnpPolicyInputs} or\n * {@link itemRefHasPnpPolicyInputs} reports any profile policy material; otherwise\n * `\"off\"`. Hosts override the default by passing an explicit\n * `pnpEnforcement` value (engine input) or by calling\n * `ToolkitCoordinator.setPnpEnforcement(\"on\" | \"off\")`.\n */\nexport function resolveDefaultPnpEnforcement(args: {\n\tassessment?: AssessmentEntity | null;\n\tcurrentItemRef?: AssessmentItemRef | null;\n}): \"on\" | \"off\" {\n\tif (assessmentHasPnpPolicyInputs(args.assessment)) return \"on\";\n\tif (itemRefHasPnpPolicyInputs(args.currentItemRef)) return \"on\";\n\treturn \"off\";\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../../src/policy/core/provenance.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool Policy Provenance (M8 — see `.cursor/plans/m8-design.md` § 4).\n *\n * Tracks decisions from every Pass-1 contributor: host placement, host policy,\n * provider veto, PNP/profile gates, and custom policy sources.\n */\n\n/**\n * Rule vocabulary for tool policy decisions.\n */\nexport type ToolPolicyDecisionRule =\n\t| \"district-block\"\n\t| \"test-admin-override\"\n\t| \"item-restriction\"\n\t| \"item-requirement\"\n\t| \"district-requirement\"\n\t| \"pnp-support\"\n\t| \"pnp-prohibited\"\n\t| \"placement-membership\"\n\t| \"provider-disabled\"\n\t| \"host-allowlist\"\n\t| \"host-blocked\"\n\t| \"required-tool-blocked\"\n\t| \"custom-source\"\n\t| \"system-default\";\n\nexport type ToolPolicySourceType =\n\t| \"organization\"\n\t| \"assessment\"\n\t| \"section\"\n\t| \"item\"\n\t| \"student\"\n\t| \"system\"\n\t| \"host\"\n\t| \"custom\";\n\nexport interface ToolPolicyResolutionDecision {\n\t/** Monotonic step index across the entire decision log. */\n\tstep: number;\n\n\t/**\n\t * Precedence level. PNP/profile rules use `1`–`6`; non-profile rules use `0`\n\t * for host-side gates or `7+` for custom sources that run after PNP/profile policy.\n\t */\n\tprecedence: number;\n\n\trule: ToolPolicyDecisionRule;\n\n\t/** Tool ID being resolved (post-PNP-support-mapping where applicable). */\n\tfeatureId: string;\n\n\taction: \"block\" | \"enable\" | \"skip\" | \"advisory\";\n\n\tsource: {\n\t\ttype: ToolPolicySourceType;\n\t\tid?: string;\n\t\tname?: string;\n\t};\n\n\treason: string;\n\n\tvalue?: unknown;\n\n\ttimestamp: Date;\n}\n\nexport interface ToolPolicyFeatureTrail {\n\tfeatureId: string;\n\tfinalState: \"enabled\" | \"blocked\" | \"not-configured\" | \"advisory-only\";\n\twinningDecision?: ToolPolicyResolutionDecision;\n\tallDecisions: ToolPolicyResolutionDecision[];\n\texplanation: string;\n}\n\nexport interface ToolPolicyProvenance {\n\tcontextId: string;\n\tresolvedAt: Date;\n\tsources: {\n\t\torganization?: { id: string; name: string; pnpDefaults?: unknown };\n\t\tassessment?: { id: string; name: string; settings?: unknown };\n\t\tsection?: { id: string; title?: string; settings?: unknown };\n\t\titem?: { id: string; name?: string; settings?: unknown };\n\t\tstudent?: { id: string; pnpProfile?: unknown };\n\t\thost?: { id: string; config?: unknown };\n\t};\n\tfeatures: Map<string, ToolPolicyFeatureTrail>;\n\tdecisionLog: ToolPolicyResolutionDecision[];\n\tsummary: {\n\t\ttotalFeatures: number;\n\t\tenabled: number;\n\t\tblocked: number;\n\t\tnotConfigured: number;\n\t\tbySource: Record<string, number>;\n\t\tbyRule: Record<string, number>;\n\t};\n}\n\ninterface AddDecisionParams {\n\tprecedence: number;\n\trule: ToolPolicyDecisionRule;\n\tfeatureId: string;\n\taction: ToolPolicyResolutionDecision[\"action\"];\n\tsourceType: ToolPolicySourceType;\n\tsourceId?: string;\n\tsourceName?: string;\n\treason: string;\n\tvalue?: unknown;\n}\n\n/**\n * Builder for `ToolPolicyProvenance`.\n */\nexport class ToolPolicyProvenanceBuilder {\n\tprivate provenance: ToolPolicyProvenance;\n\tprivate stepCounter = 0;\n\n\tconstructor(contextId: string) {\n\t\tthis.provenance = {\n\t\t\tcontextId,\n\t\t\tresolvedAt: new Date(),\n\t\t\tsources: {},\n\t\t\tfeatures: new Map(),\n\t\t\tdecisionLog: [],\n\t\t\tsummary: {\n\t\t\t\ttotalFeatures: 0,\n\t\t\t\tenabled: 0,\n\t\t\t\tblocked: 0,\n\t\t\t\tnotConfigured: 0,\n\t\t\t\tbySource: {},\n\t\t\t\tbyRule: {},\n\t\t\t},\n\t\t};\n\t}\n\n\taddSource(\n\t\ttype: keyof ToolPolicyProvenance[\"sources\"],\n\t\tdata: { id: string; name?: string; config?: unknown },\n\t): this {\n\t\tconst base = { id: data.id, name: data.name ?? data.id };\n\t\tswitch (type) {\n\t\t\tcase \"organization\":\n\t\t\t\tthis.provenance.sources.organization = {\n\t\t\t\t\t...base,\n\t\t\t\t\tpnpDefaults: data.config,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\tcase \"assessment\":\n\t\t\t\tthis.provenance.sources.assessment = {\n\t\t\t\t\t...base,\n\t\t\t\t\tsettings: data.config,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\tcase \"section\":\n\t\t\t\tthis.provenance.sources.section = { ...base, settings: data.config };\n\t\t\t\tbreak;\n\t\t\tcase \"item\":\n\t\t\t\tthis.provenance.sources.item = { ...base, settings: data.config };\n\t\t\t\tbreak;\n\t\t\tcase \"student\":\n\t\t\t\tthis.provenance.sources.student = {\n\t\t\t\t\tid: data.id,\n\t\t\t\t\tpnpProfile: data.config,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\tcase \"host\":\n\t\t\t\tthis.provenance.sources.host = { id: data.id, config: data.config };\n\t\t\t\tbreak;\n\t\t}\n\t\treturn this;\n\t}\n\n\taddDecision(params: AddDecisionParams): this {\n\t\tconst decision: ToolPolicyResolutionDecision = {\n\t\t\tstep: ++this.stepCounter,\n\t\t\tprecedence: params.precedence,\n\t\t\trule: params.rule,\n\t\t\tfeatureId: params.featureId,\n\t\t\taction: params.action,\n\t\t\tsource: {\n\t\t\t\ttype: params.sourceType,\n\t\t\t\tid: params.sourceId,\n\t\t\t\tname: params.sourceName,\n\t\t\t},\n\t\t\treason: params.reason,\n\t\t\tvalue: params.value,\n\t\t\ttimestamp: new Date(),\n\t\t};\n\n\t\tthis.provenance.decisionLog.push(decision);\n\n\t\tlet trail = this.provenance.features.get(params.featureId);\n\t\tif (!trail) {\n\t\t\ttrail = {\n\t\t\t\tfeatureId: params.featureId,\n\t\t\t\tfinalState: \"not-configured\",\n\t\t\t\tallDecisions: [],\n\t\t\t\texplanation: \"\",\n\t\t\t};\n\t\t\tthis.provenance.features.set(params.featureId, trail);\n\t\t}\n\t\ttrail.allDecisions.push(decision);\n\n\t\t// \"advisory\" doesn't change finalState — it preserves the existing\n\t\t// blocked/enabled state and only flags a documented conflict.\n\t\tif (params.action === \"advisory\") {\n\t\t\tif (trail.finalState === \"not-configured\") {\n\t\t\t\ttrail.finalState = \"advisory-only\";\n\t\t\t}\n\t\t} else if (params.action !== \"skip\") {\n\t\t\tconst isWinning =\n\t\t\t\t!trail.winningDecision ||\n\t\t\t\tdecision.precedence < trail.winningDecision.precedence;\n\t\t\tif (isWinning) {\n\t\t\t\ttrail.winningDecision = decision;\n\t\t\t\ttrail.finalState = decision.action === \"enable\" ? \"enabled\" : \"blocked\";\n\t\t\t}\n\t\t}\n\n\t\tthis.provenance.summary.bySource[params.sourceType] =\n\t\t\t(this.provenance.summary.bySource[params.sourceType] || 0) + 1;\n\t\tthis.provenance.summary.byRule[params.rule] =\n\t\t\t(this.provenance.summary.byRule[params.rule] || 0) + 1;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Reconcile every feature's `finalState` against the post-pipeline\n\t * candidate set.\n\t *\n\t * The eager `finalState` updates inside `addDecision` track the\n\t * highest-precedence non-skip decision per feature, but a tool's\n\t * *actual* visibility is only known after step 6 of the\n\t * composition pipeline — earlier decisions can be reversed by\n\t * later host gates, PNP/profile gates, or custom sources. This method\n\t * walks every feature trail and rewrites `finalState` from the\n\t * final candidate set so callers can rely on\n\t * `provenance.features.get(toolId)?.finalState` as the canonical\n\t * \"is this tool visible right now?\" answer (M8 design § 4 + § 12).\n\t *\n\t * Semantics applied per feature:\n\t * - In `survivingIds` → \"enabled\"\n\t * - Not in `survivingIds`, has any non-skip decision → \"blocked\"\n\t * - Not in `survivingIds`, only advisory decisions → \"advisory-only\"\n\t * - Otherwise → \"not-configured\"\n\t *\n\t * Surviving features without any logged decisions get a synthetic\n\t * \"enabled\" trail so the provenance is dense enough for hosts that\n\t * iterate `provenance.features` to find the visible set.\n\t */\n\treconcileFinalStates(survivingIds: ReadonlySet<string>): this {\n\t\tfor (const featureId of survivingIds) {\n\t\t\tlet trail = this.provenance.features.get(featureId);\n\t\t\tif (!trail) {\n\t\t\t\ttrail = {\n\t\t\t\t\tfeatureId,\n\t\t\t\t\tfinalState: \"enabled\",\n\t\t\t\t\tallDecisions: [],\n\t\t\t\t\texplanation: \"\",\n\t\t\t\t};\n\t\t\t\tthis.provenance.features.set(featureId, trail);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttrail.finalState = \"enabled\";\n\t\t}\n\n\t\tfor (const trail of this.provenance.features.values()) {\n\t\t\tif (survivingIds.has(trail.featureId)) continue;\n\t\t\tconst hasNonSkip = trail.allDecisions.some(\n\t\t\t\t(d) => d.action !== \"skip\" && d.action !== \"advisory\",\n\t\t\t);\n\t\t\tconst hasAdvisory = trail.allDecisions.some(\n\t\t\t\t(d) => d.action === \"advisory\",\n\t\t\t);\n\t\t\tif (hasNonSkip) {\n\t\t\t\ttrail.finalState = \"blocked\";\n\t\t\t} else if (hasAdvisory) {\n\t\t\t\ttrail.finalState = \"advisory-only\";\n\t\t\t} else {\n\t\t\t\ttrail.finalState = \"not-configured\";\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\tbuild(): ToolPolicyProvenance {\n\t\tfor (const trail of this.provenance.features.values()) {\n\t\t\ttrail.explanation = generateExplanation(trail);\n\t\t}\n\t\tfor (const trail of this.provenance.features.values()) {\n\t\t\tthis.provenance.summary.totalFeatures++;\n\t\t\tif (trail.finalState === \"enabled\") {\n\t\t\t\tthis.provenance.summary.enabled++;\n\t\t\t} else if (trail.finalState === \"blocked\") {\n\t\t\t\tthis.provenance.summary.blocked++;\n\t\t\t} else {\n\t\t\t\tthis.provenance.summary.notConfigured++;\n\t\t\t}\n\t\t}\n\t\treturn this.provenance;\n\t}\n}\n\nfunction generateExplanation(trail: ToolPolicyFeatureTrail): string {\n\tif (!trail.winningDecision) {\n\t\tif (trail.finalState === \"advisory-only\") {\n\t\t\tconst advisory = trail.allDecisions.find((d) => d.action === \"advisory\");\n\t\t\treturn advisory\n\t\t\t\t? `Feature \"${trail.featureId}\" was kept in its host-decided state; ${advisory.reason}`\n\t\t\t\t: `Feature \"${trail.featureId}\" carries an advisory note.`;\n\t\t}\n\t\treturn `Feature \"${trail.featureId}\" was not configured at any level.`;\n\t}\n\n\tconst decision = trail.winningDecision;\n\tconst sourceName = decision.source.name || decision.source.type;\n\tlet explanation = `Feature \"${trail.featureId}\" is ${trail.finalState}.\\n\\n`;\n\texplanation += `**Primary Reason** (${decision.rule}):\\n`;\n\texplanation += `${decision.reason}\\n`;\n\texplanation += `Source: ${sourceName} (${decision.source.type})\\n`;\n\tconst overridden = trail.allDecisions.filter(\n\t\t(d) =>\n\t\t\td.step !== decision.step &&\n\t\t\td.action !== \"skip\" &&\n\t\t\td.action !== \"advisory\" &&\n\t\t\td.precedence > decision.precedence,\n\t);\n\tif (overridden.length > 0) {\n\t\texplanation += `\\n**Overridden Rules**:\\n`;\n\t\tfor (const d of overridden) {\n\t\t\texplanation += `- ${d.rule}: ${d.reason}\\n`;\n\t\t}\n\t}\n\treturn explanation;\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../../src/policy/core/provenance.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool Policy Provenance (M8 — see `.cursor/plans/m8-design.md` § 4).\n *\n * Tracks decisions from every Pass-1 contributor: host placement, host policy,\n * provider veto, PNP/profile gates, and custom policy sources.\n */\n\n/**\n * Rule vocabulary for tool policy decisions.\n */\nexport type ToolPolicyDecisionRule =\n\t| \"district-block\"\n\t| \"test-admin-override\"\n\t| \"item-restriction\"\n\t| \"item-requirement\"\n\t| \"district-requirement\"\n\t| \"pnp-support\"\n\t| \"pnp-prohibited\"\n\t| \"placement-membership\"\n\t| \"provider-disabled\"\n\t| \"host-allowlist\"\n\t| \"host-blocked\"\n\t| \"required-tool-blocked\"\n\t| \"custom-source\"\n\t| \"system-default\";\n\nexport type ToolPolicySourceType =\n\t| \"organization\"\n\t| \"assessment\"\n\t| \"section\"\n\t| \"item\"\n\t| \"student\"\n\t| \"system\"\n\t| \"host\"\n\t| \"custom\";\n\nexport interface ToolPolicyResolutionDecision {\n\t/** Monotonic step index across the entire decision log. */\n\tstep: number;\n\n\t/**\n\t * Precedence level. PNP/profile rules use `1`–`6`; non-profile rules use `0`\n\t * for host-side gates or `7+` for custom sources that run after PNP/profile policy.\n\t */\n\tprecedence: number;\n\n\trule: ToolPolicyDecisionRule;\n\n\t/** Tool ID being resolved (post-PNP-support-mapping where applicable). */\n\tfeatureId: string;\n\n\taction: \"block\" | \"enable\" | \"skip\" | \"advisory\";\n\n\tsource: {\n\t\ttype: ToolPolicySourceType;\n\t\tid?: string;\n\t\tname?: string;\n\t};\n\n\treason: string;\n\n\tvalue?: unknown;\n\n\ttimestamp: Date;\n}\n\nexport interface ToolPolicyFeatureTrail {\n\tfeatureId: string;\n\tfinalState: \"enabled\" | \"blocked\" | \"not-configured\" | \"advisory-only\";\n\twinningDecision?: ToolPolicyResolutionDecision;\n\tallDecisions: ToolPolicyResolutionDecision[];\n\texplanation: string;\n}\n\nexport interface ToolPolicyProvenance {\n\tcontextId: string;\n\tresolvedAt: Date;\n\tsources: {\n\t\torganization?: { id: string; name: string; pnpDefaults?: unknown };\n\t\tassessment?: { id: string; name: string; settings?: unknown };\n\t\tsection?: { id: string; title?: string; settings?: unknown };\n\t\titem?: { id: string; name?: string; settings?: unknown };\n\t\tstudent?: { id: string; pnpProfile?: unknown };\n\t\thost?: { id: string; config?: unknown };\n\t};\n\tfeatures: Map<string, ToolPolicyFeatureTrail>;\n\tdecisionLog: ToolPolicyResolutionDecision[];\n\tsummary: {\n\t\ttotalFeatures: number;\n\t\tenabled: number;\n\t\tblocked: number;\n\t\tnotConfigured: number;\n\t\tbySource: Record<string, number>;\n\t\tbyRule: Record<string, number>;\n\t};\n}\n\ninterface AddDecisionParams {\n\tprecedence: number;\n\trule: ToolPolicyDecisionRule;\n\tfeatureId: string;\n\taction: ToolPolicyResolutionDecision[\"action\"];\n\tsourceType: ToolPolicySourceType;\n\tsourceId?: string;\n\tsourceName?: string;\n\treason: string;\n\tvalue?: unknown;\n}\n\n/**\n * Builder for `ToolPolicyProvenance`.\n */\nexport class ToolPolicyProvenanceBuilder {\n\tprivate provenance: ToolPolicyProvenance;\n\tprivate stepCounter = 0;\n\n\tconstructor(contextId: string) {\n\t\tthis.provenance = {\n\t\t\tcontextId,\n\t\t\tresolvedAt: new Date(),\n\t\t\tsources: {},\n\t\t\tfeatures: new Map(),\n\t\t\tdecisionLog: [],\n\t\t\tsummary: {\n\t\t\t\ttotalFeatures: 0,\n\t\t\t\tenabled: 0,\n\t\t\t\tblocked: 0,\n\t\t\t\tnotConfigured: 0,\n\t\t\t\tbySource: {},\n\t\t\t\tbyRule: {},\n\t\t\t},\n\t\t};\n\t}\n\n\taddSource(\n\t\ttype: keyof ToolPolicyProvenance[\"sources\"],\n\t\tdata: { id: string; name?: string; config?: unknown },\n\t): this {\n\t\tconst base = { id: data.id, name: data.name ?? data.id };\n\t\tswitch (type) {\n\t\t\tcase \"organization\":\n\t\t\t\tthis.provenance.sources.organization = {\n\t\t\t\t\t...base,\n\t\t\t\t\tpnpDefaults: data.config,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\tcase \"assessment\":\n\t\t\t\tthis.provenance.sources.assessment = {\n\t\t\t\t\t...base,\n\t\t\t\t\tsettings: data.config,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\tcase \"section\":\n\t\t\t\tthis.provenance.sources.section = { ...base, settings: data.config };\n\t\t\t\tbreak;\n\t\t\tcase \"item\":\n\t\t\t\tthis.provenance.sources.item = { ...base, settings: data.config };\n\t\t\t\tbreak;\n\t\t\tcase \"student\":\n\t\t\t\tthis.provenance.sources.student = {\n\t\t\t\t\tid: data.id,\n\t\t\t\t\tpnpProfile: data.config,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\tcase \"host\":\n\t\t\t\tthis.provenance.sources.host = { id: data.id, config: data.config };\n\t\t\t\tbreak;\n\t\t}\n\t\treturn this;\n\t}\n\n\taddDecision(params: AddDecisionParams): this {\n\t\tconst decision: ToolPolicyResolutionDecision = {\n\t\t\tstep: ++this.stepCounter,\n\t\t\tprecedence: params.precedence,\n\t\t\trule: params.rule,\n\t\t\tfeatureId: params.featureId,\n\t\t\taction: params.action,\n\t\t\tsource: {\n\t\t\t\ttype: params.sourceType,\n\t\t\t\tid: params.sourceId,\n\t\t\t\tname: params.sourceName,\n\t\t\t},\n\t\t\treason: params.reason,\n\t\t\tvalue: params.value,\n\t\t\ttimestamp: new Date(),\n\t\t};\n\n\t\tthis.provenance.decisionLog.push(decision);\n\n\t\tlet trail = this.provenance.features.get(params.featureId);\n\t\tif (!trail) {\n\t\t\ttrail = {\n\t\t\t\tfeatureId: params.featureId,\n\t\t\t\tfinalState: \"not-configured\",\n\t\t\t\tallDecisions: [],\n\t\t\t\texplanation: \"\",\n\t\t\t};\n\t\t\tthis.provenance.features.set(params.featureId, trail);\n\t\t}\n\t\ttrail.allDecisions.push(decision);\n\n\t\t// \"advisory\" doesn't change finalState — it preserves the existing\n\t\t// blocked/enabled state and only flags a documented conflict.\n\t\tif (params.action === \"advisory\") {\n\t\t\tif (trail.finalState === \"not-configured\") {\n\t\t\t\ttrail.finalState = \"advisory-only\";\n\t\t\t}\n\t\t} else if (params.action !== \"skip\") {\n\t\t\tconst isWinning =\n\t\t\t\t!trail.winningDecision ||\n\t\t\t\tdecision.precedence < trail.winningDecision.precedence;\n\t\t\tif (isWinning) {\n\t\t\t\ttrail.winningDecision = decision;\n\t\t\t\ttrail.finalState = decision.action === \"enable\" ? \"enabled\" : \"blocked\";\n\t\t\t}\n\t\t}\n\n\t\tthis.provenance.summary.bySource[params.sourceType] =\n\t\t\t(this.provenance.summary.bySource[params.sourceType] || 0) + 1;\n\t\tthis.provenance.summary.byRule[params.rule] =\n\t\t\t(this.provenance.summary.byRule[params.rule] || 0) + 1;\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Reconcile every feature's `finalState` against the post-pipeline\n\t * candidate set.\n\t *\n\t * The eager `finalState` updates inside `addDecision` track the\n\t * highest-precedence non-skip decision per feature, but a tool's\n\t * *actual* visibility is only known after step 6 of the\n\t * composition pipeline — earlier decisions can be reversed by\n\t * later host gates, PNP/profile gates, or custom sources. This method\n\t * walks every feature trail and rewrites `finalState` from the\n\t * final candidate set so callers can rely on\n\t * `provenance.features.get(toolId)?.finalState` as the canonical\n\t * \"is this tool visible right now?\" answer (M8 design § 4 + § 12).\n\t *\n\t * Semantics applied per feature:\n\t * - In `survivingIds` → \"enabled\"\n\t * - Not in `survivingIds`, has any non-skip decision → \"blocked\"\n\t * - Not in `survivingIds`, only advisory decisions → \"advisory-only\"\n\t * - Otherwise → \"not-configured\"\n\t *\n\t * Surviving features without any logged decisions get a synthetic\n\t * \"enabled\" trail so the provenance is dense enough for hosts that\n\t * iterate `provenance.features` to find the visible set.\n\t */\n\treconcileFinalStates(survivingIds: ReadonlySet<string>): this {\n\t\tfor (const featureId of survivingIds) {\n\t\t\tlet trail = this.provenance.features.get(featureId);\n\t\t\tif (!trail) {\n\t\t\t\ttrail = {\n\t\t\t\t\tfeatureId,\n\t\t\t\t\tfinalState: \"enabled\",\n\t\t\t\t\tallDecisions: [],\n\t\t\t\t\texplanation: \"\",\n\t\t\t\t};\n\t\t\t\tthis.provenance.features.set(featureId, trail);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttrail.finalState = \"enabled\";\n\t\t}\n\n\t\tfor (const trail of this.provenance.features.values()) {\n\t\t\tif (survivingIds.has(trail.featureId)) continue;\n\t\t\tconst hasNonSkip = trail.allDecisions.some(\n\t\t\t\t(d) => d.action !== \"skip\" && d.action !== \"advisory\",\n\t\t\t);\n\t\t\tconst hasAdvisory = trail.allDecisions.some(\n\t\t\t\t(d) => d.action === \"advisory\",\n\t\t\t);\n\t\t\tif (hasNonSkip) {\n\t\t\t\ttrail.finalState = \"blocked\";\n\t\t\t} else if (hasAdvisory) {\n\t\t\t\ttrail.finalState = \"advisory-only\";\n\t\t\t} else {\n\t\t\t\ttrail.finalState = \"not-configured\";\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\tbuild(): ToolPolicyProvenance {\n\t\tfor (const trail of this.provenance.features.values()) {\n\t\t\ttrail.explanation = generateExplanation(trail);\n\t\t}\n\t\tfor (const trail of this.provenance.features.values()) {\n\t\t\tthis.provenance.summary.totalFeatures++;\n\t\t\tif (trail.finalState === \"enabled\") {\n\t\t\t\tthis.provenance.summary.enabled++;\n\t\t\t} else if (trail.finalState === \"blocked\") {\n\t\t\t\tthis.provenance.summary.blocked++;\n\t\t\t} else {\n\t\t\t\tthis.provenance.summary.notConfigured++;\n\t\t\t}\n\t\t}\n\t\treturn this.provenance;\n\t}\n}\n\nfunction generateExplanation(trail: ToolPolicyFeatureTrail): string {\n\tif (!trail.winningDecision) {\n\t\tif (trail.finalState === \"advisory-only\") {\n\t\t\tconst advisory = trail.allDecisions.find((d) => d.action === \"advisory\");\n\t\t\treturn advisory\n\t\t\t\t? `Feature \"${trail.featureId}\" was kept in its host-decided state; ${advisory.reason}`\n\t\t\t\t: `Feature \"${trail.featureId}\" carries an advisory note.`;\n\t\t}\n\t\treturn `Feature \"${trail.featureId}\" was not configured at any level.`;\n\t}\n\n\tconst decision = trail.winningDecision;\n\tconst sourceName = decision.source.name || decision.source.type;\n\tlet explanation = `Feature \"${trail.featureId}\" is ${trail.finalState}.\\n\\n`;\n\texplanation += `**Primary Reason** (${decision.rule}):\\n`;\n\texplanation += `${decision.reason}\\n`;\n\texplanation += `Source: ${sourceName} (${decision.source.type})\\n`;\n\tconst overridden = trail.allDecisions.filter(\n\t\t(d) =>\n\t\t\td.step !== decision.step &&\n\t\t\td.action !== \"skip\" &&\n\t\t\td.action !== \"advisory\" &&\n\t\t\td.precedence > decision.precedence,\n\t);\n\tif (overridden.length > 0) {\n\t\texplanation += `\\n**Overridden Rules**:\\n`;\n\t\tfor (const d of overridden) {\n\t\t\texplanation += `- ${d.rule}: ${d.reason}\\n`;\n\t\t}\n\t}\n\treturn explanation;\n}\n"]}
|
|
@@ -290,7 +290,7 @@ export class SectionRuntimeEngine {
|
|
|
290
290
|
}
|
|
291
291
|
getCanonicalItemId(itemId) {
|
|
292
292
|
const map = this.registry.getCanonicalIdMap();
|
|
293
|
-
return map[itemId] || this.controller?.getCanonicalItemId?.(itemId) || itemId;
|
|
293
|
+
return (map[itemId] || this.controller?.getCanonicalItemId?.(itemId) || itemId);
|
|
294
294
|
}
|
|
295
295
|
handleContentRegistered(detail) {
|
|
296
296
|
this.controller?.handleContentRegistered?.({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionRuntimeEngine.js","sourceRoot":"","sources":["../../src/runtime/SectionRuntimeEngine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Section runtime engine — public facade (M7 — Variant C, layered).\n *\n * The facade is the narrow, stable entry point hosts use to mount,\n * drive, and dispose a section runtime. It composes three layers\n * introduced in earlier M7 PRs:\n *\n * - the **registry** (`RuntimeRegistry`) — registered item/passage\n * shells in document order, used for canonical-id lookup;\n * - the **adapter** (`SectionEngineAdapter`) — single I/O seam over\n * the pure FSM core, fanning outputs to the DOM, framework-error\n * bus, instrumentation hook, and host subscribers;\n * - the **resolver** (`resolveSectionEngineRuntimeState`) — the\n * toolkit-side resolution helper that produces the effective\n * runtime + tools snapshot a host feeds to the FSM core.\n *\n * The facade exposes an engine-side surface for stage/lifecycle inputs and a\n * controller-facing surface for item registration, session updates, and host\n * controller commands:\n *\n * 1. The **engine-side** surface (`attachHost`, `dispatchInput`,\n * `subscribe`, `getState`, `getEffectiveRuntime`,\n * `setInstrumentationHook`). This is what the kernel and the\n * `pie-assessment-toolkit` CE will switch onto in M7 PR 5 and\n * PR 6. Construction is lazy: `attachHost(...)` builds the\n * adapter on first call, with the supplied host element,\n * framework-error bus, and (optional) coordinator. After\n * construction, host re-attachments (e.g. cohort change with a\n * new layout shell) update the adapter's host element via\n * `setHost(...)`.\n *\n * 2. The **controller-side** surface (`initialize`,\n * `register`, `unregister`, `handleContent*`, `updateItemSession`,\n * `navigateToItem`, `persist`, `hydrate`, `dispose`). The\n * `PieAssessmentToolkit.svelte` CE drives section-controller and\n * item-shell events through this surface.\n *\n * The two surfaces share `RuntimeRegistry` and the resolved\n * `SectionControllerHandle`.\n */\n\nimport type { ToolkitCoordinator } from \"../services/ToolkitCoordinator.js\";\nimport type { FrameworkErrorReporter } from \"../services/framework-error-bus.js\";\nimport type {\n\tSectionControllerEvent,\n\tSectionControllerHandle,\n} from \"../services/section-controller-types.js\";\nimport {\n\tSectionEngineAdapter,\n\ttype SectionEngineAdapterOptions,\n} from \"./adapter/SectionEngineAdapter.js\";\nimport type { InstrumentationHook } from \"./adapter/instrumentation-bridge.js\";\nimport type { EngineOutputListener } from \"./adapter/subscriber-fanout.js\";\nimport type { SectionEngineInput } from \"./core/engine-input.js\";\nimport type { SectionEngineOutput } from \"./core/engine-output.js\";\nimport {\n\tresolveSectionEngineRuntimeState,\n\ttype EffectiveRuntime,\n\ttype RuntimeInputs,\n} from \"./core/engine-resolver.js\";\nimport {\n\tcreateInitialEngineState,\n\ttype SectionEngineState,\n} from \"./core/engine-state.js\";\nimport type { RuntimeRegistrationDetail } from \"./registration-events.js\";\nimport { RuntimeRegistry } from \"./RuntimeRegistry.js\";\nimport { createRuntimeId } from \"./runtime-id.js\";\n\n/**\n * Structural view of the resolved section controller, widened with the\n * extra methods the toolkit's runtime CE calls directly. Optional so\n * stub controllers used in tests do not need every entry point.\n */\ninterface RuntimeController extends SectionControllerHandle {\n\tgetCompositionModel?: () => unknown;\n\tgetCanonicalItemId?: (itemId: string) => string;\n\thandleContentLoaded?: (args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\tdetail?: unknown;\n\t\ttimestamp?: number;\n\t}) => void;\n\thandleContentRegistered?: (args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t}) => void;\n\thandleContentUnregistered?: (args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t}) => void;\n\thandleItemPlayerError?: (args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\terror: unknown;\n\t\ttimestamp?: number;\n\t}) => void;\n\treportSectionError?: (args: {\n\t\tsource: \"item-player\" | \"section-runtime\" | \"toolkit\" | \"controller\";\n\t\terror: unknown;\n\t\titemId?: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\ttimestamp?: number;\n\t}) => void;\n\tupdateItemSession?: (\n\t\titemId: string,\n\t\tsessionDetail: unknown,\n\t) => { eventDetail?: unknown } | null;\n\tsubscribe?: (listener: (event: SectionControllerEvent) => void) => () => void;\n\tnavigateToItem?: (index: number) => unknown;\n}\n\n/**\n * Initialize args used by the toolkit CE to resolve the coordinator-backed\n * section controller.\n */\ninterface EngineInitArgs {\n\tcoordinator: ToolkitCoordinator;\n\tsection: unknown;\n\tsectionId: string;\n\tassessmentId: string;\n\tview: string;\n\tattemptId?: string;\n\tcreateDefaultController: () => Promise<RuntimeController> | RuntimeController;\n\tonCompositionChanged?: (composition: unknown) => void;\n}\n\n/**\n * Engine-side `attachHost` args. The host element, framework-error bus,\n * and `sourceCe` together let the adapter dispatch DOM events and bus\n * fan-outs consistently with the kernel emit chain.\n */\nexport interface SectionRuntimeEngineHostArgs {\n\thost: EventTarget;\n\tsourceCe: string;\n\tframeworkErrorBus: FrameworkErrorReporter;\n\tcoordinator?: SectionEngineAdapterOptions[\"coordinator\"];\n\tinstrumentationHook?: InstrumentationHook;\n\tnow?: () => string;\n}\n\nexport class SectionRuntimeEngine {\n\tprivate readonly registry = new RuntimeRegistry();\n\tprivate readonly runtimeId = createRuntimeId(\"section-engine\");\n\n\t// Engine-side state (PR 3+).\n\tprivate adapter: SectionEngineAdapter | null = null;\n\n\t// Controller-side state.\n\tprivate controller: RuntimeController | null = null;\n\tprivate coordinator: ToolkitCoordinator | null = null;\n\tprivate sectionId = \"\";\n\tprivate attemptId: string | undefined;\n\tprivate unsubscribeController: (() => void) | null = null;\n\tprivate activeInitToken = 0;\n\n\t/**\n\t * Tracks which `(canonicalItemId, contentKind)` pairs have already\n\t * fired `handleContentLoaded` on this engine. Mirrored alongside\n\t * `RuntimeRegistry`'s registered set so a cohort handoff can\n\t * replay the persistent shells' loaded state into the new\n\t * controller — see `replayRegisteredShellsIntoController` and the\n\t * PIE-512 Phase B regression test.\n\t *\n\t * Cleared in lockstep with `handleContentUnregistered` and on\n\t * `dispose`. Not exposed publicly: the registry alone is the\n\t * external surface; the loaded set exists only to seed cohort B's\n\t * controller with the live state cohort A's shells produced.\n\t */\n\tprivate readonly loadedRenderableKeys = new Set<string>();\n\n\t// ============================================================\n\t// Engine-side surface (PR 3+; driven by the kernel from PR 5,\n\t// by the toolkit CE from PR 6, and by the facade smoke test today).\n\t// ============================================================\n\n\t/**\n\t * Attach the host element + framework-error bus + sourceCe so the\n\t * adapter can dispatch DOM events and bus errors. Required before\n\t * `dispatchInput` / `subscribe` produce observable effects.\n\t *\n\t * Constructs the adapter on the first call. Subsequent calls keep\n\t * the adapter and update its host element / instrumentation hook\n\t * (used by layout-shell rollovers and instrumentation reconfig).\n\t */\n\tattachHost(args: SectionRuntimeEngineHostArgs): void {\n\t\tif (this.adapter) {\n\t\t\tthis.adapter.setHost(args.host);\n\t\t\tif (args.instrumentationHook !== undefined) {\n\t\t\t\tthis.adapter.setInstrumentationHook(args.instrumentationHook);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis.adapter = new SectionEngineAdapter({\n\t\t\thost: args.host,\n\t\t\truntimeId: this.runtimeId,\n\t\t\tsourceCe: args.sourceCe,\n\t\t\tframeworkErrorBus: args.frameworkErrorBus,\n\t\t\tcoordinator: args.coordinator,\n\t\t\tinstrumentationHook: args.instrumentationHook,\n\t\t\tnow: args.now,\n\t\t});\n\t}\n\n\t/**\n\t * Forward a host-constructed input to the FSM core via the adapter.\n\t * Returns the outputs the transition produced (subscribers and the\n\t * DOM/framework-error/instrumentation bridges have already\n\t * received them).\n\t *\n\t * No-op (returns `[]`) before `attachHost(...)` so callers that\n\t * dispatch optimistically during teardown do not throw.\n\t */\n\tdispatchInput(input: SectionEngineInput): readonly SectionEngineOutput[] {\n\t\treturn this.adapter?.dispatchInput(input) ?? [];\n\t}\n\n\t/**\n\t * Subscribe to batched engine outputs (one batch per\n\t * `dispatchInput`). Returns an idempotent disposer. Pre-`attachHost`\n\t * subscriptions return a no-op disposer so callers can wire\n\t * subscriptions early without lifecycle-ordering hazards.\n\t */\n\tsubscribe(listener: EngineOutputListener): () => void {\n\t\treturn this.adapter?.subscribe(listener) ?? noopDispose;\n\t}\n\n\t/**\n\t * Read-only snapshot of the FSM state. Returns the initial idle\n\t * state before `attachHost` so callers can probe state without\n\t * special-casing the pre-attach phase.\n\t */\n\tgetState(): Readonly<SectionEngineState> {\n\t\treturn this.adapter?.getState() ?? createInitialEngineState();\n\t}\n\n\t/**\n\t * Resolve the effective runtime + tools snapshot for the given\n\t * two-tier inputs. This is a pure function over the resolver — it\n\t * does not depend on adapter state — so callers can use it both\n\t * pre- and post-`attachHost`. The kernel uses it to seed\n\t * `dispatchInput({ kind: \"initialize\", effectiveRuntime, ... })`.\n\t */\n\tgetEffectiveRuntime<P>(\n\t\targs: RuntimeInputs,\n\t\tdeps: {\n\t\t\tresolvePlayerRuntime: (resolverArgs: {\n\t\t\t\teffectiveRuntime: Record<string, unknown>;\n\t\t\t\tplayerType: string;\n\t\t\t\tenv: Record<string, unknown> | null;\n\t\t\t}) => P;\n\t\t},\n\t): EffectiveRuntime {\n\t\treturn resolveSectionEngineRuntimeState(args, deps).effectiveRuntime;\n\t}\n\n\t/**\n\t * Update the adapter's instrumentation hook. No-op pre-attach.\n\t * Hosts that always want a hook should pass it via `attachHost`.\n\t */\n\tsetInstrumentationHook(hook: InstrumentationHook | undefined): void {\n\t\tthis.adapter?.setInstrumentationHook(hook);\n\t}\n\n\t/**\n\t * Stable per-engine runtime id used to scope DOM-event details and\n\t * registry telemetry. Exposed so tests and instrumentation can pin\n\t * the value the bridges emit.\n\t */\n\tgetRuntimeId(): string {\n\t\treturn this.runtimeId;\n\t}\n\n\t// ============================================================\n\t// Controller-side surface.\n\t// ============================================================\n\n\tasync initialize(args: EngineInitArgs): Promise<void> {\n\t\tthis.activeInitToken += 1;\n\t\tconst token = this.activeInitToken;\n\t\tthis.coordinator = args.coordinator;\n\t\tthis.sectionId = args.sectionId;\n\t\tthis.attemptId = args.attemptId;\n\n\t\tconst resolved = (await args.coordinator.getOrCreateSectionController({\n\t\t\tsectionId: args.sectionId,\n\t\t\tattemptId: args.attemptId,\n\t\t\tinput: {\n\t\t\t\tsection: args.section,\n\t\t\t\tsectionId: args.sectionId,\n\t\t\t\tassessmentId: args.assessmentId,\n\t\t\t\tview: args.view,\n\t\t\t},\n\t\t\tupdateExisting: true,\n\t\t\tcreateDefaultController: args.createDefaultController,\n\t\t})) as RuntimeController;\n\n\t\tif (token !== this.activeInitToken) return;\n\t\tthis.unsubscribeController?.();\n\t\tthis.controller = resolved;\n\t\t// PIE-512 Phase C: always re-feed the registry's currently\n\t\t// registered shells (and their loaded state) into the resolved\n\t\t// controller. We do NOT gate on `resolved !== previousController`\n\t\t// any more.\n\t\t//\n\t\t// Why the gate had to go:\n\t\t// - Cohort flip resolving to a fresh controller — replay seeds\n\t\t// the new controller, which is the original Phase B fix.\n\t\t// - Same-cohort `updateInput` resolving to the existing\n\t\t// controller — the coordinator's\n\t\t// `resolveExistingSectionController` calls\n\t\t// `existingController.updateInput(input)` (engine always\n\t\t// passes `updateExisting: true`), and pre-Phase-C\n\t\t// `SectionController.initialize` wiped lifecycle tracking\n\t\t// unconditionally. A subscriber attaching between the wipe\n\t\t// and the next live event saw an empty\n\t\t// `loadedRenderables` snapshot.\n\t\t//\n\t\t// Phase C makes this re-feed safe by combining (a) the\n\t\t// section-identity gate around `resetLifecycleTracking()` in\n\t\t// `SectionController.initialize` (so same-cohort `updateInput`\n\t\t// preserves tracking) with (b) idempotent\n\t\t// `handleContentRegistered` / `handleContentLoaded` on the\n\t\t// controller (so re-feeding the same registry entries is a\n\t\t// no-op if the controller already knows about them, but\n\t\t// re-seeds the controller in the post-`updateInput`-wipe case\n\t\t// that pre-Phase-C used to encounter).\n\t\tthis.replayRegisteredShellsIntoController(resolved);\n\t\targs.onCompositionChanged?.(resolved.getCompositionModel?.());\n\t\tthis.unsubscribeController =\n\t\t\tresolved.subscribe?.(() => {\n\t\t\t\targs.onCompositionChanged?.(resolved.getCompositionModel?.());\n\t\t\t}) || null;\n\t}\n\n\t/**\n\t * Re-feed the engine's `RuntimeRegistry` and loaded-set into the\n\t * resolved controller. Call site: `initialize(...)` — runs on\n\t * EVERY initialize, both cohort-flip-resolves-fresh-controller\n\t * and same-cohort-resolves-existing-controller cases. Phase C\n\t * dropped the `resolved !== previousController` gate; see the\n\t * comment at the call site for why.\n\t *\n\t * Two-pass order — register every shell in document order, then\n\t * issue `handleContentLoaded` for each shell whose load already\n\t * fired on this engine. The two-pass shape prevents\n\t * `evaluateSectionLoadingState` from flapping\n\t * `section-loading-complete` `false→true→false→…` while replay is\n\t * mid-walk: any subscriber wired before the engine's own\n\t * `controller.subscribe` (no such caller today, but cheap defense\n\t * for future wiring) sees one clean `false→true` transition.\n\t *\n\t * Idempotent on the controller side — Phase C makes\n\t * `SectionController.handleContentRegistered` and\n\t * `handleContentLoaded` early-return on duplicates so re-feeding\n\t * the same shells into a controller that already tracks them is\n\t * a true no-op (no spurious re-emits, no re-evaluation of\n\t * `section-loading-complete`). At the call site no listener is\n\t * attached during the replay window, so `emitChange` side effects\n\t * fire into a void on this pass anyway, but the controller-side\n\t * idempotence is what makes the replay safe to run on every\n\t * initialize regardless of whether the controller is fresh.\n\t */\n\tprivate replayRegisteredShellsIntoController(\n\t\tcontroller: RuntimeController,\n\t): void {\n\t\tif (!controller.handleContentRegistered) return;\n\t\tconst shells = this.registry.getOrderedShells();\n\t\tif (shells.length === 0) return;\n\t\tfor (const shell of shells) {\n\t\t\tconst canonicalItemId = shell.canonicalItemId || shell.itemId;\n\t\t\tcontroller.handleContentRegistered({\n\t\t\t\titemId: shell.itemId,\n\t\t\t\tcanonicalItemId,\n\t\t\t\tcontentKind: shell.contentKind || shell.kind,\n\t\t\t});\n\t\t}\n\t\tconst now = Date.now();\n\t\tfor (const shell of shells) {\n\t\t\tconst canonicalItemId = shell.canonicalItemId || shell.itemId;\n\t\t\tconst key = this.getLoadedKey(canonicalItemId, shell.contentKind);\n\t\t\tif (this.loadedRenderableKeys.has(key)) {\n\t\t\t\tcontroller.handleContentLoaded?.({\n\t\t\t\t\titemId: shell.itemId,\n\t\t\t\t\tcanonicalItemId,\n\t\t\t\t\tcontentKind: shell.contentKind || shell.kind,\n\t\t\t\t\ttimestamp: now,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Stable key for the engine's `loadedRenderableKeys` set. Mirrors\n\t * the `(canonicalItemId, contentKind)` shape `SectionController`\n\t * uses internally (see `getRenderableKey`); we only need\n\t * consistent add/check semantics on this side, not byte-identical\n\t * normalization with the controller.\n\t */\n\tprivate getLoadedKey(\n\t\tcanonicalItemId: string,\n\t\tcontentKind: string | undefined,\n\t): string {\n\t\treturn `${contentKind ?? \"\"}:${canonicalItemId}`;\n\t}\n\n\tregister(detail: RuntimeRegistrationDetail): boolean {\n\t\treturn this.registry.register(detail);\n\t}\n\n\tunregister(element: HTMLElement): boolean {\n\t\treturn this.registry.unregister(element);\n\t}\n\n\tgetCompositionModel(): unknown {\n\t\treturn this.controller?.getCompositionModel?.() ?? null;\n\t}\n\n\tgetCanonicalItemId(itemId: string): string {\n\t\tconst map = this.registry.getCanonicalIdMap();\n\t\treturn map[itemId] || this.controller?.getCanonicalItemId?.(itemId) || itemId;\n\t}\n\n\thandleContentRegistered(detail: RuntimeRegistrationDetail): void {\n\t\tthis.controller?.handleContentRegistered?.({\n\t\t\titemId: detail.itemId,\n\t\t\tcanonicalItemId: detail.canonicalItemId || detail.itemId,\n\t\t\tcontentKind: detail.contentKind || detail.kind,\n\t\t});\n\t}\n\n\thandleContentUnregistered(detail: RuntimeRegistrationDetail): void {\n\t\tconst canonicalItemId = detail.canonicalItemId || detail.itemId;\n\t\t// Key the load-set delete with the same `contentKind`-only\n\t\t// shape that `handleContentLoaded` and\n\t\t// `replayRegisteredShellsIntoController` use, so add/check/\n\t\t// delete keys round-trip identically. The `|| detail.kind`\n\t\t// fallback is preserved for the controller-forwarded payload\n\t\t// because the controller normalizes via `toSectionContentKind`\n\t\t// and the `kind` field remains meaningful there.\n\t\tthis.loadedRenderableKeys.delete(\n\t\t\tthis.getLoadedKey(canonicalItemId, detail.contentKind),\n\t\t);\n\t\tthis.controller?.handleContentUnregistered?.({\n\t\t\titemId: detail.itemId,\n\t\t\tcanonicalItemId,\n\t\t\tcontentKind: detail.contentKind || detail.kind,\n\t\t});\n\t}\n\n\thandleContentLoaded(args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\tdetail?: unknown;\n\t\ttimestamp?: number;\n\t}): void {\n\t\tconst canonicalItemId = args.canonicalItemId || args.itemId;\n\t\tthis.loadedRenderableKeys.add(\n\t\t\tthis.getLoadedKey(canonicalItemId, args.contentKind),\n\t\t);\n\t\tthis.controller?.handleContentLoaded?.(args);\n\t}\n\n\thandleItemPlayerError(args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\terror: unknown;\n\t\ttimestamp?: number;\n\t}): void {\n\t\tthis.controller?.handleItemPlayerError?.(args);\n\t}\n\n\treportSectionError(args: {\n\t\tsource: \"item-player\" | \"section-runtime\" | \"toolkit\" | \"controller\";\n\t\terror: unknown;\n\t\titemId?: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\ttimestamp?: number;\n\t}): void {\n\t\tthis.controller?.reportSectionError?.(args);\n\t}\n\n\tupdateItemSession(itemId: string, session: unknown): unknown {\n\t\tconst canonicalId = this.getCanonicalItemId(itemId);\n\t\treturn this.controller?.updateItemSession?.(canonicalId, session) ?? null;\n\t}\n\n\tnavigateToItem(index: number): unknown {\n\t\treturn this.controller?.navigateToItem?.(index) ?? null;\n\t}\n\n\tasync persist(): Promise<void> {\n\t\tawait this.controller?.persist?.();\n\t}\n\n\tasync hydrate(): Promise<void> {\n\t\tawait this.controller?.hydrate?.();\n\t}\n\n\tgetRegistry(): RuntimeRegistry {\n\t\treturn this.registry;\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tthis.activeInitToken += 1;\n\t\tthis.unsubscribeController?.();\n\t\tthis.unsubscribeController = null;\n\t\tif (this.coordinator && this.sectionId) {\n\t\t\tawait this.coordinator.disposeSectionController({\n\t\t\t\tsectionId: this.sectionId,\n\t\t\t\tattemptId: this.attemptId,\n\t\t\t});\n\t\t}\n\t\tthis.registry.clear();\n\t\tthis.loadedRenderableKeys.clear();\n\t\tthis.controller = null;\n\t\tthis.coordinator = null;\n\t\t// Tear down the engine-side adapter (if attached) last so any\n\t\t// `dispose` FSM input flows through the bridges before they\n\t\t// detach. Adapter disposal is idempotent and safe even when\n\t\t// nothing is attached.\n\t\tif (this.adapter) {\n\t\t\tconst adapter = this.adapter;\n\t\t\tthis.adapter = null;\n\t\t\tawait adapter.dispose();\n\t\t}\n\t}\n}\n\nconst noopDispose = (): void => {};\n"]}
|
|
1
|
+
{"version":3,"file":"SectionRuntimeEngine.js","sourceRoot":"","sources":["../../src/runtime/SectionRuntimeEngine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Section runtime engine — public facade (M7 — Variant C, layered).\n *\n * The facade is the narrow, stable entry point hosts use to mount,\n * drive, and dispose a section runtime. It composes three layers\n * introduced in earlier M7 PRs:\n *\n * - the **registry** (`RuntimeRegistry`) — registered item/passage\n * shells in document order, used for canonical-id lookup;\n * - the **adapter** (`SectionEngineAdapter`) — single I/O seam over\n * the pure FSM core, fanning outputs to the DOM, framework-error\n * bus, instrumentation hook, and host subscribers;\n * - the **resolver** (`resolveSectionEngineRuntimeState`) — the\n * toolkit-side resolution helper that produces the effective\n * runtime + tools snapshot a host feeds to the FSM core.\n *\n * The facade exposes an engine-side surface for stage/lifecycle inputs and a\n * controller-facing surface for item registration, session updates, and host\n * controller commands:\n *\n * 1. The **engine-side** surface (`attachHost`, `dispatchInput`,\n * `subscribe`, `getState`, `getEffectiveRuntime`,\n * `setInstrumentationHook`). This is what the kernel and the\n * `pie-assessment-toolkit` CE will switch onto in M7 PR 5 and\n * PR 6. Construction is lazy: `attachHost(...)` builds the\n * adapter on first call, with the supplied host element,\n * framework-error bus, and (optional) coordinator. After\n * construction, host re-attachments (e.g. cohort change with a\n * new layout shell) update the adapter's host element via\n * `setHost(...)`.\n *\n * 2. The **controller-side** surface (`initialize`,\n * `register`, `unregister`, `handleContent*`, `updateItemSession`,\n * `navigateToItem`, `persist`, `hydrate`, `dispose`). The\n * `PieAssessmentToolkit.svelte` CE drives section-controller and\n * item-shell events through this surface.\n *\n * The two surfaces share `RuntimeRegistry` and the resolved\n * `SectionControllerHandle`.\n */\n\nimport type { ToolkitCoordinator } from \"../services/ToolkitCoordinator.js\";\nimport type { FrameworkErrorReporter } from \"../services/framework-error-bus.js\";\nimport type {\n\tSectionControllerEvent,\n\tSectionControllerHandle,\n} from \"../services/section-controller-types.js\";\nimport {\n\tSectionEngineAdapter,\n\ttype SectionEngineAdapterOptions,\n} from \"./adapter/SectionEngineAdapter.js\";\nimport type { InstrumentationHook } from \"./adapter/instrumentation-bridge.js\";\nimport type { EngineOutputListener } from \"./adapter/subscriber-fanout.js\";\nimport type { SectionEngineInput } from \"./core/engine-input.js\";\nimport type { SectionEngineOutput } from \"./core/engine-output.js\";\nimport {\n\tresolveSectionEngineRuntimeState,\n\ttype EffectiveRuntime,\n\ttype RuntimeInputs,\n} from \"./core/engine-resolver.js\";\nimport {\n\tcreateInitialEngineState,\n\ttype SectionEngineState,\n} from \"./core/engine-state.js\";\nimport type { RuntimeRegistrationDetail } from \"./registration-events.js\";\nimport { RuntimeRegistry } from \"./RuntimeRegistry.js\";\nimport { createRuntimeId } from \"./runtime-id.js\";\n\n/**\n * Structural view of the resolved section controller, widened with the\n * extra methods the toolkit's runtime CE calls directly. Optional so\n * stub controllers used in tests do not need every entry point.\n */\ninterface RuntimeController extends SectionControllerHandle {\n\tgetCompositionModel?: () => unknown;\n\tgetCanonicalItemId?: (itemId: string) => string;\n\thandleContentLoaded?: (args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\tdetail?: unknown;\n\t\ttimestamp?: number;\n\t}) => void;\n\thandleContentRegistered?: (args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t}) => void;\n\thandleContentUnregistered?: (args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t}) => void;\n\thandleItemPlayerError?: (args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\terror: unknown;\n\t\ttimestamp?: number;\n\t}) => void;\n\treportSectionError?: (args: {\n\t\tsource: \"item-player\" | \"section-runtime\" | \"toolkit\" | \"controller\";\n\t\terror: unknown;\n\t\titemId?: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\ttimestamp?: number;\n\t}) => void;\n\tupdateItemSession?: (\n\t\titemId: string,\n\t\tsessionDetail: unknown,\n\t) => { eventDetail?: unknown } | null;\n\tsubscribe?: (listener: (event: SectionControllerEvent) => void) => () => void;\n\tnavigateToItem?: (index: number) => unknown;\n}\n\n/**\n * Initialize args used by the toolkit CE to resolve the coordinator-backed\n * section controller.\n */\ninterface EngineInitArgs {\n\tcoordinator: ToolkitCoordinator;\n\tsection: unknown;\n\tsectionId: string;\n\tassessmentId: string;\n\tview: string;\n\tattemptId?: string;\n\tcreateDefaultController: () => Promise<RuntimeController> | RuntimeController;\n\tonCompositionChanged?: (composition: unknown) => void;\n}\n\n/**\n * Engine-side `attachHost` args. The host element, framework-error bus,\n * and `sourceCe` together let the adapter dispatch DOM events and bus\n * fan-outs consistently with the kernel emit chain.\n */\nexport interface SectionRuntimeEngineHostArgs {\n\thost: EventTarget;\n\tsourceCe: string;\n\tframeworkErrorBus: FrameworkErrorReporter;\n\tcoordinator?: SectionEngineAdapterOptions[\"coordinator\"];\n\tinstrumentationHook?: InstrumentationHook;\n\tnow?: () => string;\n}\n\nexport class SectionRuntimeEngine {\n\tprivate readonly registry = new RuntimeRegistry();\n\tprivate readonly runtimeId = createRuntimeId(\"section-engine\");\n\n\t// Engine-side state (PR 3+).\n\tprivate adapter: SectionEngineAdapter | null = null;\n\n\t// Controller-side state.\n\tprivate controller: RuntimeController | null = null;\n\tprivate coordinator: ToolkitCoordinator | null = null;\n\tprivate sectionId = \"\";\n\tprivate attemptId: string | undefined;\n\tprivate unsubscribeController: (() => void) | null = null;\n\tprivate activeInitToken = 0;\n\n\t/**\n\t * Tracks which `(canonicalItemId, contentKind)` pairs have already\n\t * fired `handleContentLoaded` on this engine. Mirrored alongside\n\t * `RuntimeRegistry`'s registered set so a cohort handoff can\n\t * replay the persistent shells' loaded state into the new\n\t * controller — see `replayRegisteredShellsIntoController` and the\n\t * PIE-512 Phase B regression test.\n\t *\n\t * Cleared in lockstep with `handleContentUnregistered` and on\n\t * `dispose`. Not exposed publicly: the registry alone is the\n\t * external surface; the loaded set exists only to seed cohort B's\n\t * controller with the live state cohort A's shells produced.\n\t */\n\tprivate readonly loadedRenderableKeys = new Set<string>();\n\n\t// ============================================================\n\t// Engine-side surface (PR 3+; driven by the kernel from PR 5,\n\t// by the toolkit CE from PR 6, and by the facade smoke test today).\n\t// ============================================================\n\n\t/**\n\t * Attach the host element + framework-error bus + sourceCe so the\n\t * adapter can dispatch DOM events and bus errors. Required before\n\t * `dispatchInput` / `subscribe` produce observable effects.\n\t *\n\t * Constructs the adapter on the first call. Subsequent calls keep\n\t * the adapter and update its host element / instrumentation hook\n\t * (used by layout-shell rollovers and instrumentation reconfig).\n\t */\n\tattachHost(args: SectionRuntimeEngineHostArgs): void {\n\t\tif (this.adapter) {\n\t\t\tthis.adapter.setHost(args.host);\n\t\t\tif (args.instrumentationHook !== undefined) {\n\t\t\t\tthis.adapter.setInstrumentationHook(args.instrumentationHook);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis.adapter = new SectionEngineAdapter({\n\t\t\thost: args.host,\n\t\t\truntimeId: this.runtimeId,\n\t\t\tsourceCe: args.sourceCe,\n\t\t\tframeworkErrorBus: args.frameworkErrorBus,\n\t\t\tcoordinator: args.coordinator,\n\t\t\tinstrumentationHook: args.instrumentationHook,\n\t\t\tnow: args.now,\n\t\t});\n\t}\n\n\t/**\n\t * Forward a host-constructed input to the FSM core via the adapter.\n\t * Returns the outputs the transition produced (subscribers and the\n\t * DOM/framework-error/instrumentation bridges have already\n\t * received them).\n\t *\n\t * No-op (returns `[]`) before `attachHost(...)` so callers that\n\t * dispatch optimistically during teardown do not throw.\n\t */\n\tdispatchInput(input: SectionEngineInput): readonly SectionEngineOutput[] {\n\t\treturn this.adapter?.dispatchInput(input) ?? [];\n\t}\n\n\t/**\n\t * Subscribe to batched engine outputs (one batch per\n\t * `dispatchInput`). Returns an idempotent disposer. Pre-`attachHost`\n\t * subscriptions return a no-op disposer so callers can wire\n\t * subscriptions early without lifecycle-ordering hazards.\n\t */\n\tsubscribe(listener: EngineOutputListener): () => void {\n\t\treturn this.adapter?.subscribe(listener) ?? noopDispose;\n\t}\n\n\t/**\n\t * Read-only snapshot of the FSM state. Returns the initial idle\n\t * state before `attachHost` so callers can probe state without\n\t * special-casing the pre-attach phase.\n\t */\n\tgetState(): Readonly<SectionEngineState> {\n\t\treturn this.adapter?.getState() ?? createInitialEngineState();\n\t}\n\n\t/**\n\t * Resolve the effective runtime + tools snapshot for the given\n\t * two-tier inputs. This is a pure function over the resolver — it\n\t * does not depend on adapter state — so callers can use it both\n\t * pre- and post-`attachHost`. The kernel uses it to seed\n\t * `dispatchInput({ kind: \"initialize\", effectiveRuntime, ... })`.\n\t */\n\tgetEffectiveRuntime<P>(\n\t\targs: RuntimeInputs,\n\t\tdeps: {\n\t\t\tresolvePlayerRuntime: (resolverArgs: {\n\t\t\t\teffectiveRuntime: Record<string, unknown>;\n\t\t\t\tplayerType: string;\n\t\t\t\tenv: Record<string, unknown> | null;\n\t\t\t}) => P;\n\t\t},\n\t): EffectiveRuntime {\n\t\treturn resolveSectionEngineRuntimeState(args, deps).effectiveRuntime;\n\t}\n\n\t/**\n\t * Update the adapter's instrumentation hook. No-op pre-attach.\n\t * Hosts that always want a hook should pass it via `attachHost`.\n\t */\n\tsetInstrumentationHook(hook: InstrumentationHook | undefined): void {\n\t\tthis.adapter?.setInstrumentationHook(hook);\n\t}\n\n\t/**\n\t * Stable per-engine runtime id used to scope DOM-event details and\n\t * registry telemetry. Exposed so tests and instrumentation can pin\n\t * the value the bridges emit.\n\t */\n\tgetRuntimeId(): string {\n\t\treturn this.runtimeId;\n\t}\n\n\t// ============================================================\n\t// Controller-side surface.\n\t// ============================================================\n\n\tasync initialize(args: EngineInitArgs): Promise<void> {\n\t\tthis.activeInitToken += 1;\n\t\tconst token = this.activeInitToken;\n\t\tthis.coordinator = args.coordinator;\n\t\tthis.sectionId = args.sectionId;\n\t\tthis.attemptId = args.attemptId;\n\n\t\tconst resolved = (await args.coordinator.getOrCreateSectionController({\n\t\t\tsectionId: args.sectionId,\n\t\t\tattemptId: args.attemptId,\n\t\t\tinput: {\n\t\t\t\tsection: args.section,\n\t\t\t\tsectionId: args.sectionId,\n\t\t\t\tassessmentId: args.assessmentId,\n\t\t\t\tview: args.view,\n\t\t\t},\n\t\t\tupdateExisting: true,\n\t\t\tcreateDefaultController: args.createDefaultController,\n\t\t})) as RuntimeController;\n\n\t\tif (token !== this.activeInitToken) return;\n\t\tthis.unsubscribeController?.();\n\t\tthis.controller = resolved;\n\t\t// PIE-512 Phase C: always re-feed the registry's currently\n\t\t// registered shells (and their loaded state) into the resolved\n\t\t// controller. We do NOT gate on `resolved !== previousController`\n\t\t// any more.\n\t\t//\n\t\t// Why the gate had to go:\n\t\t// - Cohort flip resolving to a fresh controller — replay seeds\n\t\t// the new controller, which is the original Phase B fix.\n\t\t// - Same-cohort `updateInput` resolving to the existing\n\t\t// controller — the coordinator's\n\t\t// `resolveExistingSectionController` calls\n\t\t// `existingController.updateInput(input)` (engine always\n\t\t// passes `updateExisting: true`), and pre-Phase-C\n\t\t// `SectionController.initialize` wiped lifecycle tracking\n\t\t// unconditionally. A subscriber attaching between the wipe\n\t\t// and the next live event saw an empty\n\t\t// `loadedRenderables` snapshot.\n\t\t//\n\t\t// Phase C makes this re-feed safe by combining (a) the\n\t\t// section-identity gate around `resetLifecycleTracking()` in\n\t\t// `SectionController.initialize` (so same-cohort `updateInput`\n\t\t// preserves tracking) with (b) idempotent\n\t\t// `handleContentRegistered` / `handleContentLoaded` on the\n\t\t// controller (so re-feeding the same registry entries is a\n\t\t// no-op if the controller already knows about them, but\n\t\t// re-seeds the controller in the post-`updateInput`-wipe case\n\t\t// that pre-Phase-C used to encounter).\n\t\tthis.replayRegisteredShellsIntoController(resolved);\n\t\targs.onCompositionChanged?.(resolved.getCompositionModel?.());\n\t\tthis.unsubscribeController =\n\t\t\tresolved.subscribe?.(() => {\n\t\t\t\targs.onCompositionChanged?.(resolved.getCompositionModel?.());\n\t\t\t}) || null;\n\t}\n\n\t/**\n\t * Re-feed the engine's `RuntimeRegistry` and loaded-set into the\n\t * resolved controller. Call site: `initialize(...)` — runs on\n\t * EVERY initialize, both cohort-flip-resolves-fresh-controller\n\t * and same-cohort-resolves-existing-controller cases. Phase C\n\t * dropped the `resolved !== previousController` gate; see the\n\t * comment at the call site for why.\n\t *\n\t * Two-pass order — register every shell in document order, then\n\t * issue `handleContentLoaded` for each shell whose load already\n\t * fired on this engine. The two-pass shape prevents\n\t * `evaluateSectionLoadingState` from flapping\n\t * `section-loading-complete` `false→true→false→…` while replay is\n\t * mid-walk: any subscriber wired before the engine's own\n\t * `controller.subscribe` (no such caller today, but cheap defense\n\t * for future wiring) sees one clean `false→true` transition.\n\t *\n\t * Idempotent on the controller side — Phase C makes\n\t * `SectionController.handleContentRegistered` and\n\t * `handleContentLoaded` early-return on duplicates so re-feeding\n\t * the same shells into a controller that already tracks them is\n\t * a true no-op (no spurious re-emits, no re-evaluation of\n\t * `section-loading-complete`). At the call site no listener is\n\t * attached during the replay window, so `emitChange` side effects\n\t * fire into a void on this pass anyway, but the controller-side\n\t * idempotence is what makes the replay safe to run on every\n\t * initialize regardless of whether the controller is fresh.\n\t */\n\tprivate replayRegisteredShellsIntoController(\n\t\tcontroller: RuntimeController,\n\t): void {\n\t\tif (!controller.handleContentRegistered) return;\n\t\tconst shells = this.registry.getOrderedShells();\n\t\tif (shells.length === 0) return;\n\t\tfor (const shell of shells) {\n\t\t\tconst canonicalItemId = shell.canonicalItemId || shell.itemId;\n\t\t\tcontroller.handleContentRegistered({\n\t\t\t\titemId: shell.itemId,\n\t\t\t\tcanonicalItemId,\n\t\t\t\tcontentKind: shell.contentKind || shell.kind,\n\t\t\t});\n\t\t}\n\t\tconst now = Date.now();\n\t\tfor (const shell of shells) {\n\t\t\tconst canonicalItemId = shell.canonicalItemId || shell.itemId;\n\t\t\tconst key = this.getLoadedKey(canonicalItemId, shell.contentKind);\n\t\t\tif (this.loadedRenderableKeys.has(key)) {\n\t\t\t\tcontroller.handleContentLoaded?.({\n\t\t\t\t\titemId: shell.itemId,\n\t\t\t\t\tcanonicalItemId,\n\t\t\t\t\tcontentKind: shell.contentKind || shell.kind,\n\t\t\t\t\ttimestamp: now,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Stable key for the engine's `loadedRenderableKeys` set. Mirrors\n\t * the `(canonicalItemId, contentKind)` shape `SectionController`\n\t * uses internally (see `getRenderableKey`); we only need\n\t * consistent add/check semantics on this side, not byte-identical\n\t * normalization with the controller.\n\t */\n\tprivate getLoadedKey(\n\t\tcanonicalItemId: string,\n\t\tcontentKind: string | undefined,\n\t): string {\n\t\treturn `${contentKind ?? \"\"}:${canonicalItemId}`;\n\t}\n\n\tregister(detail: RuntimeRegistrationDetail): boolean {\n\t\treturn this.registry.register(detail);\n\t}\n\n\tunregister(element: HTMLElement): boolean {\n\t\treturn this.registry.unregister(element);\n\t}\n\n\tgetCompositionModel(): unknown {\n\t\treturn this.controller?.getCompositionModel?.() ?? null;\n\t}\n\n\tgetCanonicalItemId(itemId: string): string {\n\t\tconst map = this.registry.getCanonicalIdMap();\n\t\treturn (\n\t\t\tmap[itemId] || this.controller?.getCanonicalItemId?.(itemId) || itemId\n\t\t);\n\t}\n\n\thandleContentRegistered(detail: RuntimeRegistrationDetail): void {\n\t\tthis.controller?.handleContentRegistered?.({\n\t\t\titemId: detail.itemId,\n\t\t\tcanonicalItemId: detail.canonicalItemId || detail.itemId,\n\t\t\tcontentKind: detail.contentKind || detail.kind,\n\t\t});\n\t}\n\n\thandleContentUnregistered(detail: RuntimeRegistrationDetail): void {\n\t\tconst canonicalItemId = detail.canonicalItemId || detail.itemId;\n\t\t// Key the load-set delete with the same `contentKind`-only\n\t\t// shape that `handleContentLoaded` and\n\t\t// `replayRegisteredShellsIntoController` use, so add/check/\n\t\t// delete keys round-trip identically. The `|| detail.kind`\n\t\t// fallback is preserved for the controller-forwarded payload\n\t\t// because the controller normalizes via `toSectionContentKind`\n\t\t// and the `kind` field remains meaningful there.\n\t\tthis.loadedRenderableKeys.delete(\n\t\t\tthis.getLoadedKey(canonicalItemId, detail.contentKind),\n\t\t);\n\t\tthis.controller?.handleContentUnregistered?.({\n\t\t\titemId: detail.itemId,\n\t\t\tcanonicalItemId,\n\t\t\tcontentKind: detail.contentKind || detail.kind,\n\t\t});\n\t}\n\n\thandleContentLoaded(args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\tdetail?: unknown;\n\t\ttimestamp?: number;\n\t}): void {\n\t\tconst canonicalItemId = args.canonicalItemId || args.itemId;\n\t\tthis.loadedRenderableKeys.add(\n\t\t\tthis.getLoadedKey(canonicalItemId, args.contentKind),\n\t\t);\n\t\tthis.controller?.handleContentLoaded?.(args);\n\t}\n\n\thandleItemPlayerError(args: {\n\t\titemId: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\terror: unknown;\n\t\ttimestamp?: number;\n\t}): void {\n\t\tthis.controller?.handleItemPlayerError?.(args);\n\t}\n\n\treportSectionError(args: {\n\t\tsource: \"item-player\" | \"section-runtime\" | \"toolkit\" | \"controller\";\n\t\terror: unknown;\n\t\titemId?: string;\n\t\tcanonicalItemId?: string;\n\t\tcontentKind?: string;\n\t\ttimestamp?: number;\n\t}): void {\n\t\tthis.controller?.reportSectionError?.(args);\n\t}\n\n\tupdateItemSession(itemId: string, session: unknown): unknown {\n\t\tconst canonicalId = this.getCanonicalItemId(itemId);\n\t\treturn this.controller?.updateItemSession?.(canonicalId, session) ?? null;\n\t}\n\n\tnavigateToItem(index: number): unknown {\n\t\treturn this.controller?.navigateToItem?.(index) ?? null;\n\t}\n\n\tasync persist(): Promise<void> {\n\t\tawait this.controller?.persist?.();\n\t}\n\n\tasync hydrate(): Promise<void> {\n\t\tawait this.controller?.hydrate?.();\n\t}\n\n\tgetRegistry(): RuntimeRegistry {\n\t\treturn this.registry;\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tthis.activeInitToken += 1;\n\t\tthis.unsubscribeController?.();\n\t\tthis.unsubscribeController = null;\n\t\tif (this.coordinator && this.sectionId) {\n\t\t\tawait this.coordinator.disposeSectionController({\n\t\t\t\tsectionId: this.sectionId,\n\t\t\t\tattemptId: this.attemptId,\n\t\t\t});\n\t\t}\n\t\tthis.registry.clear();\n\t\tthis.loadedRenderableKeys.clear();\n\t\tthis.controller = null;\n\t\tthis.coordinator = null;\n\t\t// Tear down the engine-side adapter (if attached) last so any\n\t\t// `dispose` FSM input flows through the bridges before they\n\t\t// detach. Adapter disposal is idempotent and safe even when\n\t\t// nothing is attached.\n\t\tif (this.adapter) {\n\t\t\tconst adapter = this.adapter;\n\t\t\tthis.adapter = null;\n\t\t\tawait adapter.dispose();\n\t\t}\n\t}\n}\n\nconst noopDispose = (): void => {};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cohort.js","sourceRoot":"","sources":["../../../src/runtime/core/cohort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,MAAwB;IACjD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,OAAO,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,
|
|
1
|
+
{"version":3,"file":"cohort.js","sourceRoot":"","sources":["../../../src/runtime/core/cohort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,MAAwB;IACjD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,OAAO,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;AAClD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC3B,CAAmB,EACnB,CAAmB;IAEnB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3B,OAAO,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS,CAAC;AACnE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,IAG1B;IACA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;IACvC,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO;QACN,SAAS;QACT,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;KAC/B,CAAC;AACH,CAAC","sourcesContent":["/**\n * Cohort identity for the section runtime engine (M7).\n *\n * One cohort is the tuple `(sectionId, attemptId)` for the section the\n * host is currently rendering. Stage progression, readiness latches, and\n * `pie-loading-complete` emission are all gated on this tuple — when it\n * changes, the engine emits `disposed` for the outgoing cohort and\n * resets to `composed` for the new one.\n *\n * `attemptId` is optional in the public surface (per the toolkit /\n * layout-CE prop shape) but the engine carries it as the empty string\n * when absent so the cohort key is total.\n */\n\nexport interface CohortKey {\n\t/** Section identifier; required for any non-idle cohort. */\n\tsectionId: string;\n\t/** Attempt identifier; empty string if the host did not provide one. */\n\tattemptId: string;\n}\n\n/**\n * Stable string form of the cohort tuple used as a key for the\n * `loadingCompleteEmittedForCohort` latch and equality checks.\n */\nexport function cohortKey(cohort: CohortKey | null): string {\n\tif (!cohort) return \"\";\n\treturn `${cohort.sectionId}|${cohort.attemptId}`;\n}\n\n/**\n * `true` iff the two cohorts have the same `(sectionId, attemptId)` pair.\n * Treats both inputs as identifying the cohort by value, never by\n * reference.\n */\nexport function cohortsEqual(\n\ta: CohortKey | null,\n\tb: CohortKey | null,\n): boolean {\n\tif (a === b) return true;\n\tif (!a || !b) return false;\n\treturn a.sectionId === b.sectionId && a.attemptId === b.attemptId;\n}\n\n/**\n * Normalize host-provided `(sectionId, attemptId)` into a cohort. Returns\n * `null` when the section identifier is empty — that is the engine's\n * idle state (no cohort).\n */\nexport function makeCohort(args: {\n\tsectionId: string | null | undefined;\n\tattemptId: string | null | undefined;\n}): CohortKey | null {\n\tconst sectionId = args.sectionId ?? \"\";\n\tif (!sectionId) return null;\n\treturn {\n\t\tsectionId,\n\t\tattemptId: args.attemptId ?? \"\",\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine-input.js","sourceRoot":"","sources":["../../../src/runtime/core/engine-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG","sourcesContent":["/**\n * Section runtime engine inputs (M7 — Variant C, layered core).\n *\n * Inputs are the discriminated union of events the adapter (PR 2) feeds\n * into the pure transition function (`engine-transition.ts`). The shape\n * is closed: every field is plain data so the transition can be tested\n * without any DOM, Svelte, or coordinator wiring.\n *\n * Adapter→core boundary contract:\n * - The adapter never mutates engine state directly. It always\n * constructs an input and calls `core.dispatch(input)`.\n * - Inputs are total: an unhandled `kind` is a programming error\n * (the transition uses `assertNever` exhaustiveness).\n * - Inputs carry only data, never live host references that would\n * pin lifetime. Coordinator and controller handles live in the\n * adapter; the core only sees readiness signals derived from them.\n */\n\nimport type { CohortKey } from \"./cohort.js\";\nimport type {
|
|
1
|
+
{"version":3,"file":"engine-input.js","sourceRoot":"","sources":["../../../src/runtime/core/engine-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG","sourcesContent":["/**\n * Section runtime engine inputs (M7 — Variant C, layered core).\n *\n * Inputs are the discriminated union of events the adapter (PR 2) feeds\n * into the pure transition function (`engine-transition.ts`). The shape\n * is closed: every field is plain data so the transition can be tested\n * without any DOM, Svelte, or coordinator wiring.\n *\n * Adapter→core boundary contract:\n * - The adapter never mutates engine state directly. It always\n * constructs an input and calls `core.dispatch(input)`.\n * - Inputs are total: an unhandled `kind` is a programming error\n * (the transition uses `assertNever` exhaustiveness).\n * - Inputs carry only data, never live host references that would\n * pin lifetime. Coordinator and controller handles live in the\n * adapter; the core only sees readiness signals derived from them.\n */\n\nimport type { CohortKey } from \"./cohort.js\";\nimport type { EffectiveRuntime, RuntimeInputs } from \"./engine-resolver.js\";\nimport type { EngineReadinessSignals } from \"./engine-readiness.js\";\nimport type { FrameworkErrorModel } from \"../../services/framework-error.js\";\n\n/**\n * `initialize` is the first transition out of `idle`. It carries the\n * cohort key and the resolved runtime/tools snapshot for the cohort.\n * The adapter constructs this input after running the resolver against\n * the host's two-tier inputs.\n */\nexport type EngineInputInitialize = {\n\tkind: \"initialize\";\n\tcohort: CohortKey;\n\teffectiveRuntime: EffectiveRuntime;\n\teffectiveToolsConfig: unknown;\n\titemCount: number;\n};\n\n/**\n * `update-runtime` is sent when the host two-tier inputs change but\n * the cohort does not. The transition stores the latest resolver\n * output without changing phase; readiness gates and stage progression\n * stay where they are.\n */\nexport type EngineInputUpdateRuntime = {\n\tkind: \"update-runtime\";\n\teffectiveRuntime: EffectiveRuntime;\n\teffectiveToolsConfig: unknown;\n};\n\n/**\n * `cohort-change` is sent when `(sectionId, attemptId)` changes. The\n * transition emits `disposed` for the outgoing cohort, resets state\n * to `booting-section` for the new one, and re-arms latches.\n */\nexport type EngineInputCohortChange = {\n\tkind: \"cohort-change\";\n\tcohort: CohortKey;\n\teffectiveRuntime: EffectiveRuntime;\n\teffectiveToolsConfig: unknown;\n\titemCount: number;\n};\n\n/**\n * `section-controller-resolved` is sent when the coordinator returns\n * the controller for the current cohort. Advances the phase from\n * `booting-section` → `engine-ready` (assuming `composed` is already\n * implied by `phase >= booting-section`, which the FSM treats as\n * monotonic).\n */\nexport type EngineInputSectionControllerResolved = {\n\tkind: \"section-controller-resolved\";\n};\n\n/**\n * `update-readiness-signals` carries the latest readiness snapshot\n * from the host. The transition uses it to gate the move into\n * `interactive` and to decide whether to emit `loading-complete`.\n *\n * The full signal set is sent every time so the transition does not\n * have to reason about partial overlays.\n */\nexport type EngineInputUpdateReadinessSignals = {\n\tkind: \"update-readiness-signals\";\n\tsignals: EngineReadinessSignals;\n\tloadedCount: number;\n\titemCount: number;\n\t/**\n\t * Strict-mode gate. When `\"strict\"`, `interactive` only fires\n\t * after `allLoadingComplete`; in `\"progressive\"`, `interactionReady`\n\t * is sufficient. Carried per-input so the host can reconfigure\n\t * mode mid-cohort without re-initializing.\n\t */\n\tmode: \"progressive\" | \"strict\";\n};\n\n/**\n * `framework-error` is sent for every framework-error report (M3\n * canonical channel). The transition records the latest error in\n * state and emits a `framework-error` output so the adapter can fan\n * out to subscribers and the DOM event.\n */\nexport type EngineInputFrameworkError = {\n\tkind: \"framework-error\";\n\terror: FrameworkErrorModel;\n};\n\n/**\n * `dispose` tears the engine down. Emits `disposed` for the current\n * cohort (if any) and moves to the terminal `disposed` phase. After\n * dispose the engine accepts no further inputs (the transition logs\n * a warning and is a no-op).\n */\nexport type EngineInputDispose = {\n\tkind: \"dispose\";\n};\n\nexport type SectionEngineInput =\n\t| EngineInputInitialize\n\t| EngineInputUpdateRuntime\n\t| EngineInputCohortChange\n\t| EngineInputSectionControllerResolved\n\t| EngineInputUpdateReadinessSignals\n\t| EngineInputFrameworkError\n\t| EngineInputDispose;\n\n/**\n * Convenience re-export so the adapter can import `RuntimeInputs`\n * from a single place when it constructs `initialize` inputs.\n */\nexport type { RuntimeInputs };\n"]}
|