@pie-players/pie-assessment-toolkit 0.3.74 → 0.3.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +349 -313
- package/dist/attempt/TestSession.d.ts +1 -20
- package/dist/attempt/TestSession.js +8 -99
- package/dist/components/ItemScope.custom-element.d.ts +1 -0
- package/dist/components/ItemScope.custom-element.js +1 -0
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +14 -14
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-7tt7v2xp.js +4 -0
- package/dist/components/chunks/{ItemToolBar-gmrryv2v.js → ItemToolBar-97hx60z4.js} +1 -1
- package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +2 -0
- package/dist/components/chunks/ItemToolBar-jx38w99s.js +2 -0
- package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +40 -0
- package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
- package/dist/components/chunks/sre-engine-jd8cc08x.js +1 -0
- package/dist/components/item-scope-element.d.ts +2 -0
- package/dist/components/item-scope-element.js +2 -0
- package/dist/context/assessment-toolkit-context.d.ts +27 -6
- package/dist/index.d.ts +22 -47
- package/dist/index.js +12 -36
- package/dist/policy/core/PolicySource.d.ts +1 -1
- package/dist/policy/core/ToolPolicyEngine.d.ts +77 -32
- package/dist/policy/core/ToolPolicyEngine.js +136 -46
- package/dist/policy/core/compose-decision.d.ts +28 -7
- package/dist/policy/core/compose-decision.js +75 -54
- package/dist/policy/core/decision-types.d.ts +65 -34
- package/dist/policy/core/feature-decision.d.ts +16 -9
- package/dist/policy/core/feature-decision.js +14 -8
- package/dist/policy/core/pnp-policy-inputs.d.ts +24 -33
- package/dist/policy/core/pnp-policy-inputs.js +28 -56
- package/dist/policy/core/provenance.d.ts +9 -4
- package/dist/policy/core/provenance.js +1 -1
- package/dist/policy/engine.d.ts +7 -23
- package/dist/policy/engine.js +5 -20
- package/dist/policy/sources/PnpPolicySource.d.ts +44 -61
- package/dist/policy/sources/PnpPolicySource.js +117 -118
- package/dist/runtime/SectionControllerBinding.d.ts +279 -0
- package/dist/runtime/SectionControllerBinding.js +450 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
- package/dist/runtime/SectionRuntimeEngine.js +30 -372
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
- package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
- package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
- package/dist/runtime/adapter/dom-event-bridge.js +17 -44
- package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -2
- package/dist/runtime/adapter/subscriber-fanout.js +1 -2
- package/dist/runtime/catalog-context.d.ts +19 -0
- package/dist/runtime/catalog-context.js +28 -0
- package/dist/runtime/composition-emit-scheduler.d.ts +9 -15
- package/dist/runtime/composition-emit-scheduler.js +9 -15
- package/dist/runtime/content-language.d.ts +32 -0
- package/dist/runtime/content-language.js +46 -0
- package/dist/runtime/content-region.d.ts +17 -0
- package/dist/runtime/content-region.js +29 -0
- package/dist/runtime/content-registration.d.ts +13 -0
- package/dist/runtime/content-registration.js +25 -0
- package/dist/runtime/core/SectionEngineCore.d.ts +2 -2
- package/dist/runtime/core/SectionEngineCore.js +2 -2
- package/dist/runtime/core/cohort.d.ts +1 -1
- package/dist/runtime/core/cohort.js +1 -1
- package/dist/runtime/core/engine-input.d.ts +18 -30
- package/dist/runtime/core/engine-input.js +11 -12
- package/dist/runtime/core/engine-output.d.ts +16 -40
- package/dist/runtime/core/engine-output.js +9 -21
- package/dist/runtime/core/engine-readiness.d.ts +5 -37
- package/dist/runtime/core/engine-readiness.js +8 -41
- package/dist/runtime/core/engine-resolver.d.ts +46 -74
- package/dist/runtime/core/engine-resolver.js +18 -43
- package/dist/runtime/core/engine-state.d.ts +28 -36
- package/dist/runtime/core/engine-state.js +18 -21
- package/dist/runtime/core/engine-transition.d.ts +14 -19
- package/dist/runtime/core/engine-transition.js +71 -51
- package/dist/runtime/engine.d.ts +16 -19
- package/dist/runtime/engine.js +12 -19
- package/dist/runtime/page-warnings.d.ts +13 -0
- package/dist/runtime/page-warnings.js +22 -0
- package/dist/runtime/policy-input-forwarding.d.ts +25 -0
- package/dist/runtime/policy-input-forwarding.js +25 -0
- package/dist/runtime/registration-events.d.ts +11 -0
- package/dist/runtime/runtime-event-claim.d.ts +8 -0
- package/dist/runtime/runtime-event-claim.js +15 -0
- package/dist/runtime/shell-event-bridge.d.ts +45 -0
- package/dist/runtime/shell-event-bridge.js +127 -0
- package/dist/runtime/shell-registration.d.ts +73 -0
- package/dist/runtime/shell-registration.js +95 -0
- package/dist/runtime/shell-scope.d.ts +68 -0
- package/dist/runtime/shell-scope.js +188 -0
- package/dist/runtime/tool-host-contract.d.ts +8 -10
- package/dist/runtime/tool-host-contract.js +11 -11
- package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
- package/dist/runtime/unclaimed-registration-watch.js +23 -0
- package/dist/services/ElementToolStateStore.d.ts +14 -10
- package/dist/services/ElementToolStateStore.js +37 -13
- package/dist/services/HighlightCoordinator.d.ts +21 -21
- package/dist/services/HighlightCoordinator.js +431 -325
- package/dist/services/RangeSerializer.d.ts +10 -1
- package/dist/services/RangeSerializer.js +87 -14
- package/dist/services/TTSService.d.ts +117 -70
- package/dist/services/TTSService.js +668 -578
- package/dist/services/ToolCoordinator.d.ts +43 -60
- package/dist/services/ToolCoordinator.js +164 -206
- package/dist/services/ToolRegistry.d.ts +74 -57
- package/dist/services/ToolRegistry.js +104 -114
- package/dist/services/ToolkitCoordinator.d.ts +183 -189
- package/dist/services/ToolkitCoordinator.js +477 -431
- package/dist/services/audio-handoff.d.ts +6 -7
- package/dist/services/audio-handoff.js +20 -14
- package/dist/services/catalog-owner.d.ts +0 -1
- package/dist/services/framework-error-bus.d.ts +3 -6
- package/dist/services/framework-error-bus.js +3 -6
- package/dist/services/framework-error.d.ts +22 -7
- package/dist/services/framework-error.js +9 -7
- package/dist/services/interfaces.d.ts +158 -129
- package/dist/services/section-session-assignment.d.ts +21 -0
- package/dist/services/section-session-assignment.js +82 -0
- package/dist/services/spoken-audio-cards.d.ts +0 -2
- package/dist/services/spoken-audio-cards.js +0 -2
- package/dist/services/tool-config-defaults.d.ts +3 -3
- package/dist/services/tool-config-defaults.js +3 -3
- package/dist/services/tool-config-validation.d.ts +4 -5
- package/dist/services/tool-config-validation.js +36 -61
- package/dist/services/tool-context.d.ts +0 -8
- package/dist/services/tool-context.js +0 -12
- package/dist/services/tool-icons.d.ts +4 -3
- package/dist/services/tool-icons.js +4 -3
- package/dist/services/tool-instance-id.d.ts +0 -1
- package/dist/services/tool-instance-id.js +0 -6
- package/dist/services/tool-providers/TTSToolProvider.d.ts +18 -19
- package/dist/services/tool-providers/TTSToolProvider.js +37 -34
- package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -4
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +30 -26
- package/dist/services/tool-providers/ToolProviderRegistry.js +119 -93
- package/dist/services/tool-request.d.ts +27 -12
- package/dist/services/tool-request.js +24 -14
- package/dist/services/toolbar-decided-tools.d.ts +15 -0
- package/dist/services/toolbar-decided-tools.js +28 -0
- package/dist/services/tools-config-normalizer.d.ts +17 -22
- package/dist/services/tools-config-normalizer.js +2 -10
- package/dist/services/tts/browser-provider.d.ts +38 -2
- package/dist/services/tts/browser-provider.js +276 -140
- package/dist/services/tts/flat-tree.d.ts +71 -0
- package/dist/services/tts/flat-tree.js +269 -0
- package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
- package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
- package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
- package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
- package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
- package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +12 -4
- package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
- package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
- package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
- package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
- package/dist/services/tts/math-aware-text-processing.js +32 -18
- package/dist/services/tts/math-control-names.d.ts +21 -0
- package/dist/services/tts/math-control-names.js +142 -0
- package/dist/services/tts/math-speech.d.ts +11 -0
- package/dist/services/tts/math-speech.js +51 -18
- package/dist/services/tts/provider-options.d.ts +41 -0
- package/dist/services/tts/provider-options.js +1 -0
- package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
- package/dist/services/tts/ssml/spoken-text.js +29 -0
- package/dist/services/tts/start-failure.d.ts +11 -0
- package/dist/services/tts/start-failure.js +19 -0
- package/dist/services/tts/text-processing.d.ts +9 -0
- package/dist/services/tts/text-processing.js +46 -33
- package/dist/services/tts/text-segmentation.d.ts +7 -0
- package/dist/services/tts/text-segmentation.js +47 -0
- package/dist/services/tts-runtime-config.d.ts +25 -17
- package/dist/services/tts-runtime-config.js +16 -95
- package/dist/tools/content-capability-resolution.d.ts +7 -9
- package/dist/tools/content-capability-resolution.js +8 -45
- package/dist/tools/registration.d.ts +58 -0
- package/dist/tools/registration.js +54 -0
- package/dist/tools/registrations/toolbar-registration-helpers.js +2 -2
- package/dist/tools/tool-surface-host.d.ts +6 -10
- package/dist/tools/tool-surface-host.js +44 -42
- package/dist/tools/tool-tag-map.d.ts +5 -15
- package/dist/tools/tool-tag-map.js +6 -20
- package/dist/utils/structural-equality.d.ts +11 -0
- package/dist/utils/structural-equality.js +47 -0
- package/package.json +13 -29
- package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
- package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
- package/dist/components/chunks/ItemToolBar-b9dz5jvd.js +0 -40
- package/dist/components/chunks/ItemToolBar-h4xap0t0.js +0 -4
- package/dist/components/chunks/ItemToolBar-wr2myaah.js +0 -2
- package/dist/components/chunks/sre-engine-wf9s43gg.js +0 -1
- package/dist/context/runtime-context-consumer.d.ts +0 -13
- package/dist/context/runtime-context-consumer.js +0 -18
- package/dist/item-loader.d.ts +0 -44
- package/dist/item-loader.js +0 -61
- package/dist/policy/core/engine-context.d.ts +0 -29
- package/dist/policy/core/engine-context.js +0 -27
- package/dist/policy/core/policy-source-tag.d.ts +0 -31
- package/dist/policy/core/policy-source-tag.js +0 -28
- package/dist/policy/internal.d.ts +0 -25
- package/dist/policy/internal.js +0 -25
- package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
- package/dist/runtime/adapter/coordinator-bridge.js +0 -126
- package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
- package/dist/runtime/adapter/framework-error-bridge.js +0 -46
- package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
- package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
- package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
- package/dist/runtime/core/engine-stage-derivation.js +0 -29
- package/dist/runtime/engine-context.d.ts +0 -39
- package/dist/runtime/engine-context.js +0 -31
- package/dist/runtime/internal.d.ts +0 -43
- package/dist/runtime/internal.js +0 -45
- package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -74
- package/dist/runtime/section-runtime-engine-host-context.js +0 -57
- package/dist/runtime/stage-emit-gate.d.ts +0 -92
- package/dist/runtime/stage-emit-gate.js +0 -82
- package/dist/services/I18nService.d.ts +0 -47
- package/dist/services/I18nService.js +0 -84
- package/dist/services/ThemeProvider.d.ts +0 -95
- package/dist/services/ThemeProvider.js +0 -334
- package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
- package/dist/services/defaultPersonalNeedsProfile.js +0 -26
- package/dist/services/pnp-standard-features.d.ts +0 -238
- package/dist/services/pnp-standard-features.js +0 -338
- package/dist/tools/client.d.ts +0 -10
- package/dist/tools/client.js +0 -10
- package/dist/tools/internal.d.ts +0 -44
- package/dist/tools/internal.js +0 -39
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PNP Policy Source
|
|
3
|
-
* (see
|
|
2
|
+
* PNP Policy Source: step 5 of `composeDecision` (see
|
|
4
3
|
* `docs/tools-and-accomodations/architecture.md`).
|
|
5
4
|
*
|
|
6
5
|
* This source applies the PNP/profile precedence rules as a `(candidates, pnpPolicyInputs) →
|
|
@@ -16,12 +15,15 @@ export class PnpPolicySource {
|
|
|
16
15
|
}
|
|
17
16
|
apply(args) {
|
|
18
17
|
const { ctx, result } = this.prepare(args);
|
|
19
|
-
const { pnp, districtPolicy, itemSettings } = ctx;
|
|
18
|
+
const { pnp, districtPolicy, testAdmin, itemSettings } = ctx;
|
|
20
19
|
const allSupports = new Set();
|
|
21
20
|
pnp?.supports?.forEach((s) => allSupports.add(s));
|
|
22
21
|
pnp?.prohibitedSupports?.forEach((s) => allSupports.add(s));
|
|
23
22
|
districtPolicy?.blockedTools?.forEach((s) => allSupports.add(s));
|
|
24
23
|
districtPolicy?.requiredTools?.forEach((s) => allSupports.add(s));
|
|
24
|
+
for (const s of Object.keys(testAdmin?.toolOverrides ?? {})) {
|
|
25
|
+
allSupports.add(s);
|
|
26
|
+
}
|
|
25
27
|
itemSettings?.requiredTools?.forEach((s) => allSupports.add(s));
|
|
26
28
|
itemSettings?.restrictedTools?.forEach((s) => allSupports.add(s));
|
|
27
29
|
for (const supportId of allSupports) {
|
|
@@ -30,20 +32,18 @@ export class PnpPolicySource {
|
|
|
30
32
|
return result;
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
33
|
-
* Evaluate exactly one PNP support id through the same
|
|
35
|
+
* Evaluate exactly one PNP support id through the same eight-level
|
|
34
36
|
* precedence `apply(...)` uses.
|
|
35
37
|
*
|
|
36
38
|
* This exists for **policy-addressable capabilities that are not toolbar
|
|
37
39
|
* tools** — a signed alternate rendered as its own region, for example.
|
|
38
40
|
* `apply(...)` only evaluates support ids that appear somewhere in the
|
|
39
|
-
* bound policy inputs
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* Evaluating one id in isolation avoids both problems: the returned result
|
|
43
|
-
* carries exactly one decision, and `decisions[0].action` is the verdict.
|
|
41
|
+
* bound policy inputs. Evaluating one id in isolation answers for any
|
|
42
|
+
* feature: the returned result carries exactly one decision, and
|
|
43
|
+
* `decisions[0].action` is the verdict.
|
|
44
44
|
*
|
|
45
45
|
* Reusing `resolveSupport(...)` rather than re-walking the precedence rules
|
|
46
|
-
* is the point — a second copy of the
|
|
46
|
+
* is the point — a second copy of the eight levels would drift.
|
|
47
47
|
*/
|
|
48
48
|
resolveFeature(featureId, args) {
|
|
49
49
|
const { ctx, result } = this.prepare(args);
|
|
@@ -55,16 +55,17 @@ export class PnpPolicySource {
|
|
|
55
55
|
* configuration-source attribution) from the bound policy inputs.
|
|
56
56
|
*/
|
|
57
57
|
prepare(args) {
|
|
58
|
-
const { assessment,
|
|
58
|
+
const { assessment, item } = args;
|
|
59
59
|
const pnp = assessment?.personalNeedsProfile;
|
|
60
60
|
const settings = assessment?.settings;
|
|
61
|
-
const itemSettings =
|
|
61
|
+
const itemSettings = item?.settings;
|
|
62
62
|
const result = {
|
|
63
63
|
blockedToolIds: new Set(),
|
|
64
64
|
mandatedToolIds: new Set(),
|
|
65
65
|
perToolFlags: new Map(),
|
|
66
66
|
decisions: [],
|
|
67
|
-
unmappedSupportIds:
|
|
67
|
+
unmappedSupportIds: this.unmappedIds(pnp, settings, itemSettings),
|
|
68
|
+
blockedOverrides: new Map(),
|
|
68
69
|
sources: {},
|
|
69
70
|
};
|
|
70
71
|
if (settings?.districtPolicy || settings?.testAdministration) {
|
|
@@ -81,11 +82,11 @@ export class PnpPolicySource {
|
|
|
81
82
|
config: pnp,
|
|
82
83
|
};
|
|
83
84
|
}
|
|
84
|
-
if (
|
|
85
|
+
if (item) {
|
|
85
86
|
result.sources.item = {
|
|
86
|
-
id:
|
|
87
|
-
name:
|
|
88
|
-
config:
|
|
87
|
+
id: item.id,
|
|
88
|
+
name: item.id,
|
|
89
|
+
config: item.settings,
|
|
89
90
|
};
|
|
90
91
|
}
|
|
91
92
|
const ctx = {
|
|
@@ -100,12 +101,11 @@ export class PnpPolicySource {
|
|
|
100
101
|
resolveSupport(supportId, ctx, out) {
|
|
101
102
|
// 1. District block (absolute veto)
|
|
102
103
|
if (ctx.districtPolicy?.blockedTools?.includes(supportId)) {
|
|
103
|
-
|
|
104
|
-
out.blockedToolIds.add(toolId);
|
|
104
|
+
out.blockedToolIds.add(supportId);
|
|
105
105
|
out.decisions.push({
|
|
106
106
|
precedence: 1,
|
|
107
107
|
rule: "district-block",
|
|
108
|
-
featureId:
|
|
108
|
+
featureId: supportId,
|
|
109
109
|
action: "block",
|
|
110
110
|
sourceType: "assessment",
|
|
111
111
|
reason: `District policy blocks "${supportId}" for all assessments`,
|
|
@@ -113,29 +113,32 @@ export class PnpPolicySource {
|
|
|
113
113
|
});
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
|
-
// 2. Test administration override
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
// 2. Test administration override `false`: withdraws the support for the
|
|
117
|
+
// session, outranking every level below.
|
|
118
|
+
const override = ctx.testAdmin?.toolOverrides?.[supportId];
|
|
119
|
+
if (override === false) {
|
|
120
|
+
out.blockedToolIds.add(supportId);
|
|
120
121
|
out.decisions.push({
|
|
121
122
|
precedence: 2,
|
|
122
123
|
rule: "test-admin-override",
|
|
123
|
-
featureId:
|
|
124
|
+
featureId: supportId,
|
|
124
125
|
action: "block",
|
|
125
126
|
sourceType: "assessment",
|
|
126
127
|
reason: `Test administrator disabled "${supportId}" for this session`,
|
|
127
|
-
value: ctx.testAdmin
|
|
128
|
+
value: ctx.testAdmin?.toolOverrides,
|
|
128
129
|
});
|
|
129
130
|
return;
|
|
130
131
|
}
|
|
131
132
|
// 3. Item restriction (per-item block)
|
|
132
133
|
if (ctx.itemSettings?.restrictedTools?.includes(supportId)) {
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
out.blockedToolIds.add(supportId);
|
|
135
|
+
if (override === true) {
|
|
136
|
+
out.blockedOverrides.set(supportId, "item-restriction");
|
|
137
|
+
}
|
|
135
138
|
out.decisions.push({
|
|
136
139
|
precedence: 3,
|
|
137
140
|
rule: "item-restriction",
|
|
138
|
-
featureId:
|
|
141
|
+
featureId: supportId,
|
|
139
142
|
action: "block",
|
|
140
143
|
sourceType: "item",
|
|
141
144
|
reason: `Item restricts "${supportId}" (e.g., mental math question blocks calculator)`,
|
|
@@ -143,21 +146,57 @@ export class PnpPolicySource {
|
|
|
143
146
|
});
|
|
144
147
|
return;
|
|
145
148
|
}
|
|
146
|
-
// 4.
|
|
149
|
+
// 4. Profile prohibition: the student's profile withdraws the support,
|
|
150
|
+
// outranking a `true` override and every requirement.
|
|
151
|
+
if (ctx.pnp?.prohibitedSupports?.includes(supportId)) {
|
|
152
|
+
out.blockedToolIds.add(supportId);
|
|
153
|
+
if (override === true) {
|
|
154
|
+
out.blockedOverrides.set(supportId, "pnp-prohibited");
|
|
155
|
+
}
|
|
156
|
+
out.decisions.push({
|
|
157
|
+
precedence: 4,
|
|
158
|
+
rule: "pnp-prohibited",
|
|
159
|
+
featureId: supportId,
|
|
160
|
+
action: "block",
|
|
161
|
+
sourceType: "student",
|
|
162
|
+
reason: `Student PNP profile prohibits "${supportId}"`,
|
|
163
|
+
value: ctx.pnp.prohibitedSupports,
|
|
164
|
+
});
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
// 5. Test administration override `true`: grants the support for the
|
|
168
|
+
// session.
|
|
169
|
+
if (override === true) {
|
|
170
|
+
out.perToolFlags.set(supportId, {
|
|
171
|
+
required: false,
|
|
172
|
+
alwaysAvailable: true,
|
|
173
|
+
settings: this.resolveToolSettings(supportId, ctx),
|
|
174
|
+
rule: "test-admin-override",
|
|
175
|
+
});
|
|
176
|
+
out.decisions.push({
|
|
177
|
+
precedence: 5,
|
|
178
|
+
rule: "test-admin-override",
|
|
179
|
+
featureId: supportId,
|
|
180
|
+
action: "enable",
|
|
181
|
+
sourceType: "assessment",
|
|
182
|
+
reason: `Test administrator enabled "${supportId}" for this session`,
|
|
183
|
+
value: ctx.testAdmin?.toolOverrides,
|
|
184
|
+
});
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// 6. Item requirement (forces enable)
|
|
147
188
|
if (ctx.itemSettings?.requiredTools?.includes(supportId)) {
|
|
148
|
-
|
|
149
|
-
out.
|
|
150
|
-
out.perToolFlags.set(toolId, {
|
|
189
|
+
out.mandatedToolIds.add(supportId);
|
|
190
|
+
out.perToolFlags.set(supportId, {
|
|
151
191
|
required: true,
|
|
152
192
|
alwaysAvailable: false,
|
|
153
193
|
settings: this.resolveToolSettings(supportId, ctx),
|
|
154
194
|
rule: "item-requirement",
|
|
155
|
-
sourceType: "item",
|
|
156
195
|
});
|
|
157
196
|
out.decisions.push({
|
|
158
|
-
precedence:
|
|
197
|
+
precedence: 6,
|
|
159
198
|
rule: "item-requirement",
|
|
160
|
-
featureId:
|
|
199
|
+
featureId: supportId,
|
|
161
200
|
action: "enable",
|
|
162
201
|
sourceType: "item",
|
|
163
202
|
reason: `Item requires "${supportId}" for this question`,
|
|
@@ -165,21 +204,19 @@ export class PnpPolicySource {
|
|
|
165
204
|
});
|
|
166
205
|
return;
|
|
167
206
|
}
|
|
168
|
-
//
|
|
207
|
+
// 7. District requirement
|
|
169
208
|
if (ctx.districtPolicy?.requiredTools?.includes(supportId)) {
|
|
170
|
-
|
|
171
|
-
out.
|
|
172
|
-
out.perToolFlags.set(toolId, {
|
|
209
|
+
out.mandatedToolIds.add(supportId);
|
|
210
|
+
out.perToolFlags.set(supportId, {
|
|
173
211
|
required: true,
|
|
174
212
|
alwaysAvailable: false,
|
|
175
213
|
settings: this.resolveToolSettings(supportId, ctx),
|
|
176
214
|
rule: "district-requirement",
|
|
177
|
-
sourceType: "assessment",
|
|
178
215
|
});
|
|
179
216
|
out.decisions.push({
|
|
180
|
-
precedence:
|
|
217
|
+
precedence: 7,
|
|
181
218
|
rule: "district-requirement",
|
|
182
|
-
featureId:
|
|
219
|
+
featureId: supportId,
|
|
183
220
|
action: "enable",
|
|
184
221
|
sourceType: "assessment",
|
|
185
222
|
reason: `District policy requires "${supportId}" for all assessments`,
|
|
@@ -187,34 +224,18 @@ export class PnpPolicySource {
|
|
|
187
224
|
});
|
|
188
225
|
return;
|
|
189
226
|
}
|
|
190
|
-
//
|
|
191
|
-
if (ctx.pnp?.prohibitedSupports?.includes(supportId)) {
|
|
192
|
-
const toolId = this.mapSupportToToolId(supportId, out);
|
|
193
|
-
out.blockedToolIds.add(toolId);
|
|
194
|
-
out.decisions.push({
|
|
195
|
-
precedence: 6,
|
|
196
|
-
rule: "pnp-prohibited",
|
|
197
|
-
featureId: toolId,
|
|
198
|
-
action: "block",
|
|
199
|
-
sourceType: "student",
|
|
200
|
-
reason: `Student PNP profile prohibits "${supportId}"`,
|
|
201
|
-
value: ctx.pnp.prohibitedSupports,
|
|
202
|
-
});
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
227
|
+
// 8. Profile supports (student needs)
|
|
205
228
|
if (ctx.pnp?.supports?.includes(supportId)) {
|
|
206
|
-
|
|
207
|
-
out.perToolFlags.set(toolId, {
|
|
229
|
+
out.perToolFlags.set(supportId, {
|
|
208
230
|
required: false,
|
|
209
231
|
alwaysAvailable: true,
|
|
210
232
|
settings: this.resolveToolSettings(supportId, ctx),
|
|
211
233
|
rule: "pnp-support",
|
|
212
|
-
sourceType: "student",
|
|
213
234
|
});
|
|
214
235
|
out.decisions.push({
|
|
215
|
-
precedence:
|
|
236
|
+
precedence: 8,
|
|
216
237
|
rule: "pnp-support",
|
|
217
|
-
featureId:
|
|
238
|
+
featureId: supportId,
|
|
218
239
|
action: "enable",
|
|
219
240
|
sourceType: "student",
|
|
220
241
|
reason: `Student PNP profile requests "${supportId}"`,
|
|
@@ -222,16 +243,12 @@ export class PnpPolicySource {
|
|
|
222
243
|
});
|
|
223
244
|
return;
|
|
224
245
|
}
|
|
225
|
-
//
|
|
226
|
-
//
|
|
227
|
-
// the same way as every other branch — PR 5's debugger surfaces
|
|
228
|
-
// index provenance trails by tool id and would otherwise show
|
|
229
|
-
// orphaned support-id entries here (M8 PR 1 R3 S1).
|
|
230
|
-
const toolId = this.mapSupportToToolId(supportId, out);
|
|
246
|
+
// 8 (skip): no rule fired. The trail is keyed by tool id, as in every
|
|
247
|
+
// other branch.
|
|
231
248
|
out.decisions.push({
|
|
232
|
-
precedence:
|
|
249
|
+
precedence: 8,
|
|
233
250
|
rule: "pnp-support",
|
|
234
|
-
featureId:
|
|
251
|
+
featureId: supportId,
|
|
235
252
|
action: "skip",
|
|
236
253
|
sourceType: "system",
|
|
237
254
|
reason: `Feature "${supportId}" not configured at any level`,
|
|
@@ -239,57 +256,39 @@ export class PnpPolicySource {
|
|
|
239
256
|
});
|
|
240
257
|
}
|
|
241
258
|
/**
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
* Resolution rules:
|
|
246
|
-
*
|
|
247
|
-
* 1. **Multiple tools register the same support id:** the
|
|
248
|
-
* *first-registered* tool wins. `ToolRegistry.getToolsByPNPSupport`
|
|
249
|
-
* returns a `Set<string>` whose iteration order matches the
|
|
250
|
-
* `register(...)` insertion order, so the result is
|
|
251
|
-
* deterministic across runs but order-sensitive at registration
|
|
252
|
-
* time. This is an unusual configuration — the typical case is
|
|
253
|
-
* one tool per support id — but it is reachable when an
|
|
254
|
-
* integrator overrides a default tool with a replacement that
|
|
255
|
-
* claims the same `pnpSupportIds`. In that case the integrator
|
|
256
|
-
* should `unregister(...)` the default before registering the
|
|
257
|
-
* replacement.
|
|
258
|
-
*
|
|
259
|
-
* 2. **No tool registers the support id:** the support id is
|
|
260
|
-
* returned verbatim as the `featureId` for provenance trails
|
|
261
|
-
* and `ToolPolicyEntry.toolId`. This lets hosts use raw QTI
|
|
262
|
-
* strings for tools the registry does not (yet) carry without
|
|
263
|
-
* losing them in policy evaluation.
|
|
264
|
-
*
|
|
265
|
-
* `tests/policy/PnpPolicySource.test.ts` locks this mapping behavior.
|
|
259
|
+
* The named ids no tool is registered under, with the rules naming each in
|
|
260
|
+
* precedence order. A support id is the id of the tool it grants, so an id
|
|
261
|
+
* missing from the registry matches nothing placed.
|
|
266
262
|
*/
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
if (
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
263
|
+
unmappedIds(pnp, settings, itemSettings) {
|
|
264
|
+
const unmapped = new Map();
|
|
265
|
+
if (this.toolRegistry.getAllTools().length === 0)
|
|
266
|
+
return unmapped;
|
|
267
|
+
const named = [
|
|
268
|
+
["district-block", settings?.districtPolicy?.blockedTools],
|
|
269
|
+
[
|
|
270
|
+
"test-admin-override",
|
|
271
|
+
Object.keys(settings?.testAdministration?.toolOverrides ?? {}),
|
|
272
|
+
],
|
|
273
|
+
["item-restriction", itemSettings?.restrictedTools],
|
|
274
|
+
["pnp-prohibited", pnp?.prohibitedSupports],
|
|
275
|
+
["item-requirement", itemSettings?.requiredTools],
|
|
276
|
+
["district-requirement", settings?.districtPolicy?.requiredTools],
|
|
277
|
+
["pnp-support", pnp?.supports],
|
|
278
|
+
];
|
|
279
|
+
for (const [rule, ids] of named) {
|
|
280
|
+
for (const id of ids ?? []) {
|
|
281
|
+
if (this.toolRegistry.has(id))
|
|
282
|
+
continue;
|
|
283
|
+
const rules = unmapped.get(id) ?? [];
|
|
284
|
+
if (!rules.includes(rule))
|
|
285
|
+
rules.push(rule);
|
|
286
|
+
unmapped.set(id, rules);
|
|
276
287
|
}
|
|
277
|
-
return supportId;
|
|
278
288
|
}
|
|
279
|
-
return
|
|
289
|
+
return unmapped;
|
|
280
290
|
}
|
|
281
|
-
/**
|
|
282
|
-
* Resolve tool-specific settings, item-level taking precedence over
|
|
283
|
-
* assessment-level.
|
|
284
|
-
*
|
|
285
|
-
* Uses `??` (nullish-coalescing). Tool config values are typed `unknown` and may legitimately
|
|
286
|
-
* be `false` / `0` / `""` (e.g. a tool whose canonical "off" config
|
|
287
|
-
* is the literal `false`). `||` would treat those as missing and
|
|
288
|
-
* silently fall through to the assessment-level config, masking the
|
|
289
|
-
* authored item-level intent. `??` only falls through on
|
|
290
|
-
* `null`/`undefined`, which matches the semantic of "value not
|
|
291
|
-
* provided."
|
|
292
|
-
*/
|
|
291
|
+
/** Tool parameters: the item's entry, else the assessment's. */
|
|
293
292
|
resolveToolSettings(supportId, ctx) {
|
|
294
293
|
return (ctx.itemSettings?.toolParameters?.[supportId] ??
|
|
295
294
|
ctx.toolConfigs?.[supportId]);
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Section controller binding — the toolkit's side of a section runtime.
|
|
3
|
+
*
|
|
4
|
+
* `PieAssessmentToolkit` holds one per element. It resolves the section's
|
|
5
|
+
* controller from the coordinator (`initialize`), keeps the registered item and
|
|
6
|
+
* passage shells (`RuntimeRegistry`) and which of them have loaded, replays
|
|
7
|
+
* both into each controller it resolves, and forwards shell events, session
|
|
8
|
+
* updates and host commands to that controller.
|
|
9
|
+
*
|
|
10
|
+
* The registry outlives a section switch: the shells of the section being left
|
|
11
|
+
* stay registered until they unmount. One membership rule routes every shell
|
|
12
|
+
* event, in replay or live: an event goes to the controller of the section
|
|
13
|
+
* whose composition renders the shell, which is the current controller or a
|
|
14
|
+
* cached controller of a section this binding bound earlier, and is dropped
|
|
15
|
+
* with a warning when no bound section renders it; see `controllerFor`. A
|
|
16
|
+
* cached controller re-bound on a revisit first forgets the loads of shells
|
|
17
|
+
* that are no longer registered, so its `section-loading-complete` waits for
|
|
18
|
+
* the new shells.
|
|
19
|
+
*
|
|
20
|
+
* The section's stage chain is a separate object: the section player's layout
|
|
21
|
+
* kernel drives a `SectionRuntimeEngine` from the readiness signals it derives.
|
|
22
|
+
* The two share no state.
|
|
23
|
+
*/
|
|
24
|
+
import type { ToolkitCoordinator } from "../services/ToolkitCoordinator.js";
|
|
25
|
+
import type { SectionControllerEvent, SectionControllerHandle, SectionControllerSessionState } from "../services/section-controller-types.js";
|
|
26
|
+
import type { MediaTimeSource } from "@pie-players/pie-players-shared/timed-media";
|
|
27
|
+
import type { RuntimeRegistrationDetail } from "./registration-events.js";
|
|
28
|
+
import { RuntimeRegistry } from "./RuntimeRegistry.js";
|
|
29
|
+
/**
|
|
30
|
+
* Structural view of the resolved section controller, widened with the
|
|
31
|
+
* extra methods the toolkit's runtime CE calls directly. Optional so
|
|
32
|
+
* stub controllers used in tests do not need every entry point.
|
|
33
|
+
*/
|
|
34
|
+
interface RuntimeController extends SectionControllerHandle {
|
|
35
|
+
getCompositionModel?: () => unknown;
|
|
36
|
+
getCanonicalItemId?: (itemId: string) => string;
|
|
37
|
+
handleContentLoaded?: (args: {
|
|
38
|
+
itemId: string;
|
|
39
|
+
canonicalItemId?: string;
|
|
40
|
+
contentKind?: string;
|
|
41
|
+
detail?: unknown;
|
|
42
|
+
timestamp?: number;
|
|
43
|
+
}) => void;
|
|
44
|
+
handleContentRegistered?: (args: {
|
|
45
|
+
itemId: string;
|
|
46
|
+
canonicalItemId?: string;
|
|
47
|
+
contentKind?: string;
|
|
48
|
+
}) => void;
|
|
49
|
+
handleContentUnregistered?: (args: {
|
|
50
|
+
itemId: string;
|
|
51
|
+
canonicalItemId?: string;
|
|
52
|
+
contentKind?: string;
|
|
53
|
+
}) => void;
|
|
54
|
+
handleItemPlayerError?: (args: {
|
|
55
|
+
itemId: string;
|
|
56
|
+
canonicalItemId?: string;
|
|
57
|
+
contentKind?: string;
|
|
58
|
+
error: unknown;
|
|
59
|
+
timestamp?: number;
|
|
60
|
+
}) => void;
|
|
61
|
+
reportSectionError?: (args: {
|
|
62
|
+
source: "item-player" | "section-runtime" | "toolkit" | "controller";
|
|
63
|
+
error: unknown;
|
|
64
|
+
itemId?: string;
|
|
65
|
+
canonicalItemId?: string;
|
|
66
|
+
contentKind?: string;
|
|
67
|
+
timestamp?: number;
|
|
68
|
+
}) => void;
|
|
69
|
+
updateItemSession?: (itemId: string, sessionDetail: unknown) => {
|
|
70
|
+
eventDetail?: unknown;
|
|
71
|
+
} | null;
|
|
72
|
+
subscribe?: (listener: (event: SectionControllerEvent) => void) => () => void;
|
|
73
|
+
navigateToItem?: (index: number) => unknown;
|
|
74
|
+
attachMediaTimeSource?: (source: MediaTimeSource, options?: {
|
|
75
|
+
origin?: "native-adapter" | "host";
|
|
76
|
+
renderableId?: string;
|
|
77
|
+
}) => void;
|
|
78
|
+
detachMediaTimeSource?: (options?: {
|
|
79
|
+
origin?: "native-adapter" | "host";
|
|
80
|
+
}) => void;
|
|
81
|
+
pauseMediaForCompetingAudio?: () => boolean;
|
|
82
|
+
}
|
|
83
|
+
/** What a media-time-source registration reaching the binding has to say. */
|
|
84
|
+
export interface SectionRuntimeMediaTimeSourceAction {
|
|
85
|
+
renderableId: string;
|
|
86
|
+
action: "attach" | "detach";
|
|
87
|
+
source?: MediaTimeSource;
|
|
88
|
+
origin?: "native-adapter" | "host";
|
|
89
|
+
}
|
|
90
|
+
/** What a formative action reaching the binding has to say. */
|
|
91
|
+
export interface SectionRuntimeFormativeAction {
|
|
92
|
+
itemId: string;
|
|
93
|
+
canonicalItemId?: string;
|
|
94
|
+
action: "check" | "retry";
|
|
95
|
+
outcomes?: unknown[];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Initialize args used by the toolkit CE to resolve the coordinator-backed
|
|
99
|
+
* section controller.
|
|
100
|
+
*/
|
|
101
|
+
export interface SectionControllerBindingInitArgs {
|
|
102
|
+
coordinator: ToolkitCoordinator;
|
|
103
|
+
section: unknown;
|
|
104
|
+
sectionId: string;
|
|
105
|
+
assessmentId: string;
|
|
106
|
+
view: string;
|
|
107
|
+
attemptId?: string;
|
|
108
|
+
/**
|
|
109
|
+
* A host-supplied session for this section, applied by the coordinator in
|
|
110
|
+
* place of `hydrate()` when it creates the controller. Absent, creation
|
|
111
|
+
* hydrates from the persistence strategy as before.
|
|
112
|
+
*/
|
|
113
|
+
initialSession?: SectionControllerSessionState | null;
|
|
114
|
+
createDefaultController: () => Promise<RuntimeController> | RuntimeController;
|
|
115
|
+
onCompositionChanged?: (composition: unknown) => void;
|
|
116
|
+
/**
|
|
117
|
+
* The controller event that caused a republish, for the few events the toolkit
|
|
118
|
+
* has to act on rather than merely propagate — a timed-media policy that cannot
|
|
119
|
+
* be enforced becomes a framework warning, and malformed cue data becomes a
|
|
120
|
+
* framework error. Every other event reaches hosts through the composition
|
|
121
|
+
* republish and the coordinator's own subscriptions.
|
|
122
|
+
*/
|
|
123
|
+
onControllerEvent?: (event: SectionControllerEvent) => void;
|
|
124
|
+
}
|
|
125
|
+
export declare class SectionControllerBinding {
|
|
126
|
+
private readonly registry;
|
|
127
|
+
private controller;
|
|
128
|
+
private coordinator;
|
|
129
|
+
private sectionId;
|
|
130
|
+
private attemptId;
|
|
131
|
+
private unsubscribeController;
|
|
132
|
+
private activeInitToken;
|
|
133
|
+
/**
|
|
134
|
+
* Ids of the renderables in the current controller's composition model, read
|
|
135
|
+
* when `initialize` resolves it. `null` while no controller is resolved, and
|
|
136
|
+
* for a controller that publishes no `renderables`: its section cannot be
|
|
137
|
+
* told apart, so every shell reaches it.
|
|
138
|
+
*/
|
|
139
|
+
private sectionRenderableIds;
|
|
140
|
+
/**
|
|
141
|
+
* The renderable ids of every section this binding has bound, keyed by
|
|
142
|
+
* section and attempt, least recently bound first. `controllerFor` reads it
|
|
143
|
+
* to find the section that owns a shell outside the current one.
|
|
144
|
+
*/
|
|
145
|
+
private readonly boundSections;
|
|
146
|
+
/**
|
|
147
|
+
* Tracks which `(canonicalItemId, contentKind)` pairs have already
|
|
148
|
+
* fired `handleContentLoaded` on this binding, so a section handoff can
|
|
149
|
+
* replay the persistent shells' loaded state into the new controller; see
|
|
150
|
+
* `replayRegisteredShellsIntoController`.
|
|
151
|
+
*
|
|
152
|
+
* Records loads of every registered shell, in or out of the current
|
|
153
|
+
* section, so a shell registered ahead of its section's controller is
|
|
154
|
+
* replayed as loaded. A key is dropped when its last shell unregisters,
|
|
155
|
+
* and on `dispose`.
|
|
156
|
+
*/
|
|
157
|
+
private readonly loadedRenderableKeys;
|
|
158
|
+
initialize(args: SectionControllerBindingInitArgs): Promise<void>;
|
|
159
|
+
/**
|
|
160
|
+
* Re-feed the binding's `RuntimeRegistry` and loaded-set into the
|
|
161
|
+
* resolved controller, limited to the shells of its section (see
|
|
162
|
+
* `isSectionRenderable`). Runs on every `initialize`.
|
|
163
|
+
*
|
|
164
|
+
* Two-pass order — register every shell in document order, then
|
|
165
|
+
* issue `handleContentLoaded` for each shell whose load already
|
|
166
|
+
* fired on this binding. The two-pass shape prevents
|
|
167
|
+
* `evaluateSectionLoadingState` from flapping
|
|
168
|
+
* `section-loading-complete` `false→true→false→…` while replay is
|
|
169
|
+
* mid-walk: any subscriber wired before the binding's own
|
|
170
|
+
* `controller.subscribe` (no such caller today, but cheap defense
|
|
171
|
+
* for future wiring) sees one clean `false→true` transition.
|
|
172
|
+
*
|
|
173
|
+
* Idempotent on the controller side: `handleContentRegistered` and
|
|
174
|
+
* `handleContentLoaded` return early on duplicates, so re-feeding shells
|
|
175
|
+
* the controller already tracks emits nothing.
|
|
176
|
+
*/
|
|
177
|
+
private replayRegisteredShellsIntoController;
|
|
178
|
+
/**
|
|
179
|
+
* Stable key for the binding's `loadedRenderableKeys` set. Mirrors
|
|
180
|
+
* the `(canonicalItemId, contentKind)` shape `SectionController`
|
|
181
|
+
* uses internally (see `getRenderableKey`); we only need
|
|
182
|
+
* consistent add/check semantics on this side, not byte-identical
|
|
183
|
+
* normalization with the controller.
|
|
184
|
+
*/
|
|
185
|
+
private getLoadedKey;
|
|
186
|
+
/**
|
|
187
|
+
* Whether a shell renders one of the current section's renderables: its
|
|
188
|
+
* runtime or canonical id is among the composition model's renderable ids.
|
|
189
|
+
* An item in two sections belongs to both, so its shell carries over a
|
|
190
|
+
* switch the way a persistent passage shell does.
|
|
191
|
+
*/
|
|
192
|
+
private isSectionRenderable;
|
|
193
|
+
private getSectionKey;
|
|
194
|
+
/**
|
|
195
|
+
* The controller a shell event belongs to: the current controller when the
|
|
196
|
+
* shell renders one of its section's renderables, otherwise the cached
|
|
197
|
+
* controller of the most recently bound section that renders it — the
|
|
198
|
+
* section being left, for an outgoing shell's teardown. `null` when no bound
|
|
199
|
+
* section renders the shell or its controller is gone.
|
|
200
|
+
*/
|
|
201
|
+
private controllerFor;
|
|
202
|
+
/** `controllerFor`, warning when the event has nowhere to go. */
|
|
203
|
+
private requireControllerFor;
|
|
204
|
+
/**
|
|
205
|
+
* Forget, on a cached controller about to be re-bound, every load whose
|
|
206
|
+
* shell is no longer registered. A shell that unmounted while its section
|
|
207
|
+
* was not current told that section's controller through `controllerFor`;
|
|
208
|
+
* this covers one whose unregister never arrived.
|
|
209
|
+
*/
|
|
210
|
+
private forgetUnregisteredLoads;
|
|
211
|
+
register(detail: RuntimeRegistrationDetail): boolean;
|
|
212
|
+
unregister(element: HTMLElement): boolean;
|
|
213
|
+
getCompositionModel(): unknown;
|
|
214
|
+
getCanonicalItemId(itemId: string): string;
|
|
215
|
+
handleContentRegistered(detail: RuntimeRegistrationDetail): void;
|
|
216
|
+
/**
|
|
217
|
+
* Called after `unregister` removed the shell from the registry. While
|
|
218
|
+
* another registered shell renders the same renderable — the next
|
|
219
|
+
* section's shell for an item both sections hold — the renderable stays
|
|
220
|
+
* registered and loaded.
|
|
221
|
+
*/
|
|
222
|
+
handleContentUnregistered(detail: RuntimeRegistrationDetail): void;
|
|
223
|
+
handleContentLoaded(args: {
|
|
224
|
+
itemId: string;
|
|
225
|
+
canonicalItemId?: string;
|
|
226
|
+
contentKind?: string;
|
|
227
|
+
detail?: unknown;
|
|
228
|
+
timestamp?: number;
|
|
229
|
+
}): void;
|
|
230
|
+
handleItemPlayerError(args: {
|
|
231
|
+
itemId: string;
|
|
232
|
+
canonicalItemId?: string;
|
|
233
|
+
contentKind?: string;
|
|
234
|
+
error: unknown;
|
|
235
|
+
timestamp?: number;
|
|
236
|
+
}): void;
|
|
237
|
+
reportSectionError(args: {
|
|
238
|
+
source: "item-player" | "section-runtime" | "toolkit" | "controller";
|
|
239
|
+
error: unknown;
|
|
240
|
+
itemId?: string;
|
|
241
|
+
canonicalItemId?: string;
|
|
242
|
+
contentKind?: string;
|
|
243
|
+
timestamp?: number;
|
|
244
|
+
}): void;
|
|
245
|
+
updateItemSession(itemId: string, session: unknown): unknown;
|
|
246
|
+
navigateToItem(index: number): unknown;
|
|
247
|
+
/**
|
|
248
|
+
* Route a learner's formative action to the controller.
|
|
249
|
+
*
|
|
250
|
+
* Canonicalized here for the same reason `updateItemSession` is: the runtime
|
|
251
|
+
* id a card dispatches with is not necessarily the identifier the controller
|
|
252
|
+
* keys state by. Both ids are kept, since the composition's renderables are
|
|
253
|
+
* keyed by the runtime one.
|
|
254
|
+
*/
|
|
255
|
+
handleFormativeAction(action: SectionRuntimeFormativeAction): void;
|
|
256
|
+
/**
|
|
257
|
+
* Bind or release the section's Media Time Source.
|
|
258
|
+
*
|
|
259
|
+
* A pass-through, like `handleFormativeAction`: the binding routes, the
|
|
260
|
+
* controller decides. `renderableId` travels with the attach because whether the
|
|
261
|
+
* registering renderable is the one `stimulusRef` names is the controller's call
|
|
262
|
+
* — it validated `stimulusRef` in the first place.
|
|
263
|
+
*/
|
|
264
|
+
handleMediaTimeSource(action: SectionRuntimeMediaTimeSourceAction): void;
|
|
265
|
+
/**
|
|
266
|
+
* Silence media audio because something else is about to speak.
|
|
267
|
+
*
|
|
268
|
+
* A pass-through like `handleMediaTimeSource`, and for the same reason: which
|
|
269
|
+
* source is authoritative and whether it reports `canPause` are the controller's
|
|
270
|
+
* to know. Returns whether media audio is now silent, or `true` where there is
|
|
271
|
+
* no timed-media controller to ask — nothing is playing.
|
|
272
|
+
*/
|
|
273
|
+
requestMediaPauseForCompetingAudio(): boolean;
|
|
274
|
+
persist(): Promise<void>;
|
|
275
|
+
hydrate(): Promise<void>;
|
|
276
|
+
getRegistry(): RuntimeRegistry;
|
|
277
|
+
dispose(): Promise<void>;
|
|
278
|
+
}
|
|
279
|
+
export {};
|