@pie-players/pie-assessment-toolkit 0.3.74 → 1.0.0-beta.0
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 +658 -714
- package/custom-elements.json +1315 -0
- package/dist/attempt/TestSession.d.ts +1 -21
- package/dist/attempt/TestSession.js +16 -102
- 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-3zrc4p3d.js +4 -0
- package/dist/components/chunks/ItemToolBar-66hcwmfw.js +2 -0
- package/dist/components/chunks/ItemToolBar-9gqhfxtn.js +40 -0
- package/dist/components/chunks/ItemToolBar-hzc5wyjp.js +2 -0
- package/dist/components/chunks/{ItemToolBar-gmrryv2v.js → ItemToolBar-kkj69ptr.js} +1 -1
- package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
- package/dist/components/chunks/sre-engine-bj997w4b.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 +33 -6
- package/dist/index.d.ts +25 -50
- package/dist/index.js +15 -45
- package/dist/policy/core/PolicySource.d.ts +2 -2
- package/dist/policy/core/ToolPolicyEngine.d.ts +118 -34
- package/dist/policy/core/ToolPolicyEngine.js +203 -56
- package/dist/policy/core/compose-decision.d.ts +28 -7
- package/dist/policy/core/compose-decision.js +95 -74
- package/dist/policy/core/decision-types.d.ts +98 -55
- package/dist/policy/core/feature-decision.d.ts +28 -19
- package/dist/policy/core/feature-decision.js +15 -11
- package/dist/policy/core/pnp-policy-inputs.d.ts +29 -35
- package/dist/policy/core/pnp-policy-inputs.js +40 -88
- package/dist/policy/core/provenance.d.ts +10 -5
- package/dist/policy/core/provenance.js +1 -1
- package/dist/policy/core/tool-parameters.d.ts +11 -0
- package/dist/policy/core/tool-parameters.js +15 -0
- package/dist/policy/engine.d.ts +7 -23
- package/dist/policy/engine.js +5 -20
- package/dist/policy/sources/PnpPolicySource.d.ts +43 -68
- package/dist/policy/sources/PnpPolicySource.js +133 -132
- package/dist/runtime/SectionControllerBinding.d.ts +283 -0
- package/dist/runtime/SectionControllerBinding.js +456 -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 -3
- package/dist/runtime/adapter/subscriber-fanout.js +2 -6
- 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 +12 -18
- package/dist/runtime/composition-emit-scheduler.js +10 -16
- package/dist/runtime/content-language.d.ts +32 -0
- package/dist/runtime/content-language.js +46 -0
- package/dist/runtime/content-region.d.ts +13 -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 -4
- package/dist/runtime/core/SectionEngineCore.js +2 -6
- package/dist/runtime/core/cohort.d.ts +1 -6
- package/dist/runtime/core/cohort.js +1 -10
- 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 +17 -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 +74 -53
- 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 +22 -14
- package/dist/runtime/runtime-event-claim.d.ts +8 -0
- package/dist/runtime/runtime-event-claim.js +15 -0
- package/dist/runtime/runtime-id.d.ts +1 -1
- package/dist/runtime/runtime-id.js +1 -1
- 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 +194 -0
- package/dist/runtime/tool-host-contract.d.ts +8 -14
- package/dist/runtime/tool-host-contract.js +12 -12
- package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
- package/dist/runtime/unclaimed-registration-watch.js +23 -0
- package/dist/services/AccessibilityCatalogResolver.d.ts +21 -31
- package/dist/services/AccessibilityCatalogResolver.js +29 -42
- package/dist/services/ElementToolStateStore.d.ts +42 -67
- package/dist/services/ElementToolStateStore.js +65 -71
- package/dist/services/HighlightCoordinator.d.ts +28 -40
- package/dist/services/HighlightCoordinator.js +459 -381
- package/dist/services/RangeSerializer.d.ts +11 -33
- package/dist/services/RangeSerializer.js +88 -59
- package/dist/services/SSMLExtractor.d.ts +8 -31
- package/dist/services/SSMLExtractor.js +18 -40
- package/dist/services/TTSService.d.ts +159 -119
- package/dist/services/TTSService.js +937 -822
- package/dist/services/ToolCoordinator.d.ts +42 -102
- package/dist/services/ToolCoordinator.js +178 -256
- package/dist/services/ToolRegistry.d.ts +152 -133
- package/dist/services/ToolRegistry.js +192 -178
- package/dist/services/ToolkitCoordinator.d.ts +233 -237
- package/dist/services/ToolkitCoordinator.js +615 -557
- 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 +51 -13
- package/dist/services/framework-error.js +19 -20
- package/dist/services/interfaces.d.ts +189 -184
- package/dist/services/section-controller-types.d.ts +7 -7
- package/dist/services/section-session-assignment.d.ts +21 -0
- package/dist/services/section-session-assignment.js +80 -0
- package/dist/services/spoken-audio-cards.d.ts +2 -6
- package/dist/services/spoken-audio-cards.js +2 -6
- 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 +9 -12
- package/dist/services/tool-config-validation.js +47 -87
- package/dist/services/tool-context.d.ts +7 -31
- package/dist/services/tool-context.js +99 -65
- package/dist/services/tool-failure.d.ts +30 -0
- package/dist/services/tool-failure.js +11 -0
- package/dist/services/tool-icons.d.ts +5 -5
- package/dist/services/tool-icons.js +6 -5
- package/dist/services/tool-instance-id.d.ts +8 -7
- package/dist/services/tool-instance-id.js +12 -24
- package/dist/services/tool-providers/TTSToolProvider.d.ts +20 -58
- package/dist/services/tool-providers/TTSToolProvider.js +32 -85
- package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -11
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +29 -60
- package/dist/services/tool-providers/ToolProviderRegistry.js +128 -144
- package/dist/services/tool-request.d.ts +31 -12
- package/dist/services/tool-request.js +31 -16
- package/dist/services/toolbar-decided-tools.d.ts +16 -0
- package/dist/services/toolbar-decided-tools.js +29 -0
- package/dist/services/toolbar-items.js +2 -5
- package/dist/services/tools-config-normalizer.d.ts +33 -29
- package/dist/services/tools-config-normalizer.js +26 -28
- package/dist/services/tts/browser-provider.d.ts +39 -6
- package/dist/services/tts/browser-provider.js +280 -160
- package/dist/services/tts/catalog-span-alignment.js +14 -7
- package/dist/services/tts/flat-tree.d.ts +64 -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/dom/to-chunk-inputs.d.ts +2 -2
- 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/math-speech-cache.d.ts +3 -1
- package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
- package/dist/services/tts/generated-speech/types.d.ts +1 -1
- package/dist/services/tts/generated-speech/types.js +1 -1
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +22 -16
- 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/highlight-target-resolver.d.ts +12 -0
- package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
- package/dist/services/tts/math-aware-text-processing.js +42 -47
- 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 +12 -1
- package/dist/services/tts/math-speech.js +54 -18
- package/dist/services/tts/mathml-sanitization.d.ts +7 -0
- package/dist/services/tts/mathml-sanitization.js +9 -1
- package/dist/services/tts/provider-options.d.ts +52 -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 +4 -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 +12 -0
- package/dist/services/tts/text-segmentation.js +60 -10
- package/dist/services/tts-runtime-config.d.ts +54 -26
- package/dist/services/tts-runtime-config.js +27 -112
- package/dist/tools/content-capability-resolution.d.ts +9 -11
- package/dist/tools/content-capability-resolution.js +8 -45
- package/dist/tools/registration.d.ts +59 -0
- package/dist/tools/registration.js +55 -0
- package/dist/tools/registrations/toolbar-registration-helpers.d.ts +6 -0
- package/dist/tools/registrations/toolbar-registration-helpers.js +8 -2
- package/dist/tools/tool-surface-host.d.ts +6 -10
- package/dist/tools/tool-surface-host.js +45 -50
- 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 +15 -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/ContextVariableStore.d.ts +0 -113
- package/dist/services/ContextVariableStore.js +0 -206
- 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/services/tts-control-events.d.ts +0 -13
- package/dist/services/tts-control-events.js +0 -7
- 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
- package/dist/utils/logger.d.ts +0 -6
- package/dist/utils/logger.js +0 -10
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { ToolToolbarButtonDefinition, ToolToolbarRenderResult, ToolbarContext } from "../../services/ToolRegistry.js";
|
|
2
2
|
export type ToolOverlaySurface = "default" | "frameless";
|
|
3
|
+
/**
|
|
4
|
+
* The event a tool element dispatches, bubbling and composed, with
|
|
5
|
+
* `{ active: boolean }` as its detail when it opens or closes its own panel.
|
|
6
|
+
* A registration relays it as the toolbar button's active state.
|
|
7
|
+
*/
|
|
8
|
+
export declare const TOOL_ACTIVE_CHANGE_EVENT = "pie-tool-active-change";
|
|
3
9
|
export declare function createScopedVisibilityBinding(toolId: string, toolbarContext: ToolbarContext): {
|
|
4
10
|
fullToolId: string;
|
|
5
11
|
isActive: () => boolean;
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { createScopedToolId } from "../../services/tool-instance-id.js";
|
|
2
|
+
/**
|
|
3
|
+
* The event a tool element dispatches, bubbling and composed, with
|
|
4
|
+
* `{ active: boolean }` as its detail when it opens or closes its own panel.
|
|
5
|
+
* A registration relays it as the toolbar button's active state.
|
|
6
|
+
*/
|
|
7
|
+
export const TOOL_ACTIVE_CHANGE_EVENT = "pie-tool-active-change";
|
|
2
8
|
export function createScopedVisibilityBinding(toolId, toolbarContext) {
|
|
3
9
|
const fullToolId = createScopedToolId(toolId, toolbarContext.scope.level, toolbarContext.scope.scopeId);
|
|
4
10
|
return {
|
|
5
11
|
fullToolId,
|
|
6
|
-
isActive: () => toolbarContext.isToolVisible(
|
|
12
|
+
isActive: () => toolbarContext.isToolVisible(toolId),
|
|
7
13
|
subscribeActive: (callback) => {
|
|
8
14
|
if (!toolbarContext.subscribeVisibility)
|
|
9
15
|
return () => { };
|
|
10
16
|
return toolbarContext.subscribeVisibility(() => {
|
|
11
|
-
callback(toolbarContext.isToolVisible(
|
|
17
|
+
callback(toolbarContext.isToolVisible(toolId));
|
|
12
18
|
});
|
|
13
19
|
},
|
|
14
20
|
};
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Headless host for capabilities that render into a renderer's surfaces.
|
|
3
3
|
*
|
|
4
|
-
* The interface
|
|
5
|
-
*
|
|
4
|
+
* The interface exposes only current input, a two-boolean snapshot, and
|
|
5
|
+
* teardown. Discovery, policy/catalog invalidation, content resolution, lazy
|
|
6
6
|
* loading, DOM reconciliation, error isolation, and registry observation stay
|
|
7
7
|
* inside this module. Svelte callers are geometry adapters over this seam.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* renderer stopped honouring the grant-AND-content rule. Nothing about the module
|
|
14
|
-
* was section-shaped — it already imported only from this package — so the move
|
|
15
|
-
* is a relocation, not a rewrite. The one thing that *was* section-shaped is the
|
|
16
|
-
* name it reported errors under, which is now {@link ToolSurfaceHostOptions.hostLabel}.
|
|
9
|
+
* Every renderer that opens a surface shares this one host, so each honours the
|
|
10
|
+
* grant-AND-content rule the same way: the section player's cards and the
|
|
11
|
+
* annotation toolbar's selection surface. Errors are reported under
|
|
12
|
+
* {@link ToolSurfaceHostOptions.hostLabel}.
|
|
17
13
|
*/
|
|
18
14
|
import type { CatalogOwnerContext } from "../services/catalog-owner.js";
|
|
19
15
|
import type { ToolRegistry, ToolSurfaceServices } from "../services/ToolRegistry.js";
|
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Headless host for capabilities that render into a renderer's surfaces.
|
|
3
3
|
*
|
|
4
|
-
* The interface
|
|
5
|
-
*
|
|
4
|
+
* The interface exposes only current input, a two-boolean snapshot, and
|
|
5
|
+
* teardown. Discovery, policy/catalog invalidation, content resolution, lazy
|
|
6
6
|
* loading, DOM reconciliation, error isolation, and registry observation stay
|
|
7
7
|
* inside this module. Svelte callers are geometry adapters over this seam.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* renderer stopped honouring the grant-AND-content rule. Nothing about the module
|
|
14
|
-
* was section-shaped — it already imported only from this package — so the move
|
|
15
|
-
* is a relocation, not a rewrite. The one thing that *was* section-shaped is the
|
|
16
|
-
* name it reported errors under, which is now {@link ToolSurfaceHostOptions.hostLabel}.
|
|
9
|
+
* Every renderer that opens a surface shares this one host, so each honours the
|
|
10
|
+
* grant-AND-content rule the same way: the section player's cards and the
|
|
11
|
+
* annotation toolbar's selection surface. Errors are reported under
|
|
12
|
+
* {@link ToolSurfaceHostOptions.hostLabel}.
|
|
17
13
|
*/
|
|
18
14
|
import { isHostDeniedFeature } from "../policy/core/feature-decision.js";
|
|
19
15
|
import { toFrameworkErrorModel } from "../services/framework-error.js";
|
|
20
16
|
import { resolveContentCapabilities } from "./content-capability-resolution.js";
|
|
17
|
+
/**
|
|
18
|
+
* The scope an item's content asks feature policy with, which brings in the
|
|
19
|
+
* item's settings; other owners ask unscoped.
|
|
20
|
+
*/
|
|
21
|
+
function itemFeatureScope(owner) {
|
|
22
|
+
if (owner.ownerKind !== "itemModel")
|
|
23
|
+
return undefined;
|
|
24
|
+
return {
|
|
25
|
+
level: "item",
|
|
26
|
+
scopeId: owner.canonicalItemId || owner.itemId,
|
|
27
|
+
itemId: owner.itemId,
|
|
28
|
+
canonicalItemId: owner.canonicalItemId,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
21
31
|
const SECTION_POLICY_LEVELS = ["section", "item", "passage"];
|
|
22
32
|
function stableSerializableJson(value) {
|
|
23
33
|
const seen = new Set();
|
|
@@ -33,12 +43,6 @@ function stableSerializableJson(value) {
|
|
|
33
43
|
if (typeof current === "undefined") {
|
|
34
44
|
return undefined;
|
|
35
45
|
}
|
|
36
|
-
if (typeof current === "function" || typeof current === "symbol") {
|
|
37
|
-
throw new TypeError(`${path} is not JSON-serializable`);
|
|
38
|
-
}
|
|
39
|
-
if (typeof current === "bigint") {
|
|
40
|
-
throw new TypeError(`${path} is not JSON-serializable`);
|
|
41
|
-
}
|
|
42
46
|
if (typeof current !== "object") {
|
|
43
47
|
throw new TypeError(`${path} is not JSON-serializable`);
|
|
44
48
|
}
|
|
@@ -112,7 +116,7 @@ function contextSignature(context) {
|
|
|
112
116
|
try {
|
|
113
117
|
return stableSerializableJson({
|
|
114
118
|
toolId: context.toolId,
|
|
115
|
-
|
|
119
|
+
granted: context.granted,
|
|
116
120
|
surface: context.surface,
|
|
117
121
|
parameters: context.parameters ?? null,
|
|
118
122
|
content: context.content ?? null,
|
|
@@ -235,26 +239,22 @@ export function createToolSurfaceHost(onSnapshot, options) {
|
|
|
235
239
|
if (current.scope.kind !== "content")
|
|
236
240
|
return null;
|
|
237
241
|
const coordinator = current.services.toolkitCoordinator;
|
|
242
|
+
const featureScope = itemFeatureScope(current.scope.ownerContext);
|
|
238
243
|
const [resolved] = resolveContentCapabilities({
|
|
239
244
|
registrations: [registration],
|
|
240
245
|
catalogs,
|
|
241
|
-
// One decision per
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
//
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const decision = coordinator?.decideFeaturePolicy?.(featureId);
|
|
246
|
+
// One decision per support id, in the rule's three states. Denial's
|
|
247
|
+
// precedence over both a grant and `resolvesWithoutGrant` lives in the
|
|
248
|
+
// rule, so this host and print cannot answer differently. All this adapter
|
|
249
|
+
// owns is reading a `FeaturePolicyDecision`: `granted` is not enough on its
|
|
250
|
+
// own, because a host gate and an unconfigured feature are both
|
|
251
|
+
// `granted: false` and only one of them may be reopened by content.
|
|
252
|
+
policyFor: (supportId) => {
|
|
253
|
+
const decision = coordinator?.decideFeaturePolicy?.(supportId, featureScope);
|
|
250
254
|
if (isHostDeniedFeature(decision))
|
|
251
255
|
return { outcome: "denied" };
|
|
252
256
|
if (decision?.granted === true) {
|
|
253
|
-
return {
|
|
254
|
-
outcome: "granted",
|
|
255
|
-
featureId,
|
|
256
|
-
parameters: decision.parameters,
|
|
257
|
-
};
|
|
257
|
+
return { outcome: "granted", parameters: decision.parameters };
|
|
258
258
|
}
|
|
259
259
|
return { outcome: "silent" };
|
|
260
260
|
},
|
|
@@ -281,7 +281,7 @@ export function createToolSurfaceHost(onSnapshot, options) {
|
|
|
281
281
|
}
|
|
282
282
|
const context = {
|
|
283
283
|
toolId: registration.toolId,
|
|
284
|
-
|
|
284
|
+
granted: resolved.granted,
|
|
285
285
|
surface: current.surface,
|
|
286
286
|
parameters: resolved.parameters,
|
|
287
287
|
content: resolved.content,
|
|
@@ -303,26 +303,19 @@ export function createToolSurfaceHost(onSnapshot, options) {
|
|
|
303
303
|
const coordinator = current.services.toolkitCoordinator;
|
|
304
304
|
if (!coordinator)
|
|
305
305
|
return null;
|
|
306
|
-
|
|
307
|
-
? registration.pnpSupportIds
|
|
308
|
-
: [registration.toolId];
|
|
309
|
-
let featureId = "";
|
|
306
|
+
let granted = false;
|
|
310
307
|
let parameters;
|
|
311
308
|
try {
|
|
312
309
|
if (registration.activation === "region") {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if (decision?.granted !== true)
|
|
316
|
-
continue;
|
|
317
|
-
featureId = supportId;
|
|
318
|
-
parameters = decision.parameters;
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
|
-
if (!featureId)
|
|
310
|
+
const decision = coordinator.decideFeaturePolicy?.(registration.toolId);
|
|
311
|
+
if (decision?.granted !== true)
|
|
322
312
|
return null;
|
|
313
|
+
granted = true;
|
|
314
|
+
parameters = decision.parameters;
|
|
323
315
|
}
|
|
324
316
|
else {
|
|
325
317
|
const scopeId = current.scope.sectionId || "*";
|
|
318
|
+
let placed = false;
|
|
326
319
|
for (const level of SECTION_POLICY_LEVELS) {
|
|
327
320
|
const decision = coordinator.decideToolPolicy({
|
|
328
321
|
level,
|
|
@@ -336,11 +329,14 @@ export function createToolSurfaceHost(onSnapshot, options) {
|
|
|
336
329
|
const entry = decision.visibleTools.find((candidate) => candidate.toolId === registration.toolId);
|
|
337
330
|
if (!entry)
|
|
338
331
|
continue;
|
|
339
|
-
|
|
340
|
-
|
|
332
|
+
// Placement admits the tool; only a support, requirement or
|
|
333
|
+
// test-administration override grants it.
|
|
334
|
+
placed = true;
|
|
335
|
+
granted = entry.required || entry.alwaysAvailable;
|
|
336
|
+
parameters = entry.parameters;
|
|
341
337
|
break;
|
|
342
338
|
}
|
|
343
|
-
if (!
|
|
339
|
+
if (!placed)
|
|
344
340
|
return null;
|
|
345
341
|
}
|
|
346
342
|
}
|
|
@@ -350,7 +346,7 @@ export function createToolSurfaceHost(onSnapshot, options) {
|
|
|
350
346
|
}
|
|
351
347
|
const context = {
|
|
352
348
|
toolId: registration.toolId,
|
|
353
|
-
|
|
349
|
+
granted,
|
|
354
350
|
surface: current.surface,
|
|
355
351
|
parameters,
|
|
356
352
|
services: current.services,
|
|
@@ -463,7 +459,6 @@ export function createToolSurfaceHost(onSnapshot, options) {
|
|
|
463
459
|
}
|
|
464
460
|
}
|
|
465
461
|
report(toolId, "render", `Tool "${toolId}" failed to render into the "${current.surface}" surface.`, error);
|
|
466
|
-
return;
|
|
467
462
|
}
|
|
468
463
|
}
|
|
469
464
|
function reconcile() {
|
|
@@ -10,26 +10,16 @@ export type ToolComponentFactory = (args: {
|
|
|
10
10
|
export type ToolComponentFactoryMap = Record<string, ToolComponentFactory>;
|
|
11
11
|
export interface ToolComponentOverrides {
|
|
12
12
|
toolTagMap?: Partial<ToolTagMap>;
|
|
13
|
-
toolComponentFactory?: ToolComponentFactory;
|
|
14
13
|
toolComponentFactories?: Partial<ToolComponentFactoryMap>;
|
|
15
14
|
}
|
|
16
15
|
/**
|
|
17
|
-
* Resolve the element tag for a tool from the overrides in play.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* capabilities, and a core module holding that catalogue is why a host could not
|
|
21
|
-
* add a twelfth without editing this package — the map was overridable, but the
|
|
22
|
-
* default was core-resident. The packaged map is `PACKAGED_TOOL_TAG_MAP` in
|
|
23
|
-
* `@pie-players/pie-default-tool-loaders`, installed onto a registry through
|
|
16
|
+
* Resolve the element tag for a tool from the overrides in play. Core holds no
|
|
17
|
+
* tag map; the packaged one is `PACKAGED_TOOL_TAG_MAP` in
|
|
18
|
+
* `@pie-players/pie-default-tool-loaders`, installed through
|
|
24
19
|
* `ToolRegistry.setComponentOverrides`.
|
|
25
20
|
*
|
|
26
|
-
* An unmapped toolId
|
|
27
|
-
*
|
|
28
|
-
* word, so in practice an unmapped packaged tool throws here rather than
|
|
29
|
-
* rendering a bogus element — the failure names the missing mapping, because
|
|
30
|
-
* "custom element names must include a hyphen" is a true statement about the
|
|
31
|
-
* wrong thing.
|
|
21
|
+
* An unmapped toolId is its own tag when it contains a hyphen. Otherwise this
|
|
22
|
+
* throws an error naming the missing mapping.
|
|
32
23
|
*/
|
|
33
24
|
export declare const resolveToolTag: (toolId: string, overrides?: ToolComponentOverrides) => string;
|
|
34
25
|
export declare const createToolElement: (toolId: string, context: ToolContext, toolbarContext: ToolbarContext, overrides?: ToolComponentOverrides) => HTMLElement;
|
|
35
|
-
export declare const toToolIdFromTag: (tagName: string, overrides?: ToolComponentOverrides) => string | undefined;
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import { validateCustomElementTag } from "@pie-players/pie-players-shared/pie/tag-names";
|
|
2
2
|
/**
|
|
3
|
-
* Resolve the element tag for a tool from the overrides in play.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* capabilities, and a core module holding that catalogue is why a host could not
|
|
7
|
-
* add a twelfth without editing this package — the map was overridable, but the
|
|
8
|
-
* default was core-resident. The packaged map is `PACKAGED_TOOL_TAG_MAP` in
|
|
9
|
-
* `@pie-players/pie-default-tool-loaders`, installed onto a registry through
|
|
3
|
+
* Resolve the element tag for a tool from the overrides in play. Core holds no
|
|
4
|
+
* tag map; the packaged one is `PACKAGED_TOOL_TAG_MAP` in
|
|
5
|
+
* `@pie-players/pie-default-tool-loaders`, installed through
|
|
10
6
|
* `ToolRegistry.setComponentOverrides`.
|
|
11
7
|
*
|
|
12
|
-
* An unmapped toolId
|
|
13
|
-
*
|
|
14
|
-
* word, so in practice an unmapped packaged tool throws here rather than
|
|
15
|
-
* rendering a bogus element — the failure names the missing mapping, because
|
|
16
|
-
* "custom element names must include a hyphen" is a true statement about the
|
|
17
|
-
* wrong thing.
|
|
8
|
+
* An unmapped toolId is its own tag when it contains a hyphen. Otherwise this
|
|
9
|
+
* throws an error naming the missing mapping.
|
|
18
10
|
*/
|
|
19
11
|
export const resolveToolTag = (toolId, overrides) => {
|
|
20
12
|
const mapped = overrides?.toolTagMap?.[toolId];
|
|
@@ -26,14 +18,8 @@ export const resolveToolTag = (toolId, overrides) => {
|
|
|
26
18
|
const createDefaultToolElement = (tagName) => document.createElement(tagName);
|
|
27
19
|
export const createToolElement = (toolId, context, toolbarContext, overrides) => {
|
|
28
20
|
const tagName = resolveToolTag(toolId, overrides);
|
|
29
|
-
const
|
|
30
|
-
const factory = factoryForTool ?? overrides?.toolComponentFactory;
|
|
21
|
+
const factory = overrides?.toolComponentFactories?.[toolId];
|
|
31
22
|
return factory
|
|
32
23
|
? factory({ toolId, tagName, context, toolbarContext })
|
|
33
24
|
: createDefaultToolElement(tagName);
|
|
34
25
|
};
|
|
35
|
-
export const toToolIdFromTag = (tagName, overrides) => {
|
|
36
|
-
const validTag = validateCustomElementTag(tagName, "tool component tag");
|
|
37
|
-
const map = overrides?.toolTagMap ?? {};
|
|
38
|
-
return Object.entries(map).find(([, tag]) => tag === validTag)?.[0];
|
|
39
|
-
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural equality for plain data: host-supplied policy inputs and session
|
|
3
|
+
* payloads.
|
|
4
|
+
*
|
|
5
|
+
* Plain objects compare by own enumerable keys in any order, a key holding
|
|
6
|
+
* `undefined` matching an absent one, and arrays compare by position. Every
|
|
7
|
+
* other value compares with `Object.is`, so class instances, functions and
|
|
8
|
+
* maps are equal only to themselves. A pair already under comparison counts as
|
|
9
|
+
* equal, which keeps a cyclic value from recursing forever.
|
|
10
|
+
*/
|
|
11
|
+
export declare function structurallyEqual(a: unknown, b: unknown): boolean;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural equality for plain data: host-supplied policy inputs and session
|
|
3
|
+
* payloads.
|
|
4
|
+
*
|
|
5
|
+
* Plain objects compare by own enumerable keys in any order, a key holding
|
|
6
|
+
* `undefined` matching an absent one, and arrays compare by position. Every
|
|
7
|
+
* other value compares with `Object.is`, so class instances, functions and
|
|
8
|
+
* maps are equal only to themselves. A pair already under comparison counts as
|
|
9
|
+
* equal, which keeps a cyclic value from recursing forever.
|
|
10
|
+
*/
|
|
11
|
+
export function structurallyEqual(a, b) {
|
|
12
|
+
return compare(a, b, new WeakMap());
|
|
13
|
+
}
|
|
14
|
+
function compare(a, b, inProgress) {
|
|
15
|
+
if (Object.is(a, b))
|
|
16
|
+
return true;
|
|
17
|
+
const aIsArray = Array.isArray(a);
|
|
18
|
+
if (aIsArray !== Array.isArray(b))
|
|
19
|
+
return false;
|
|
20
|
+
if (!aIsArray && (!isPlainObject(a) || !isPlainObject(b)))
|
|
21
|
+
return false;
|
|
22
|
+
const left = a;
|
|
23
|
+
const right = b;
|
|
24
|
+
if (aIsArray && a.length !== b.length) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
let partners = inProgress.get(left);
|
|
28
|
+
if (partners?.has(right))
|
|
29
|
+
return true;
|
|
30
|
+
if (!partners) {
|
|
31
|
+
partners = new Set();
|
|
32
|
+
inProgress.set(left, partners);
|
|
33
|
+
}
|
|
34
|
+
partners.add(right);
|
|
35
|
+
const keys = new Set([...Object.keys(left), ...Object.keys(right)]);
|
|
36
|
+
for (const key of keys) {
|
|
37
|
+
if (!compare(left[key], right[key], inProgress))
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
function isPlainObject(value) {
|
|
43
|
+
if (value === null || typeof value !== "object")
|
|
44
|
+
return false;
|
|
45
|
+
const proto = Object.getPrototypeOf(value);
|
|
46
|
+
return proto === Object.prototype || proto === null;
|
|
47
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-assessment-toolkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "PIE assessment toolkit: composable services + reference implementation for assessment players and tool coordination",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"types": "./dist/index.d.ts",
|
|
22
22
|
"import": "./dist/index.js"
|
|
23
23
|
},
|
|
24
|
-
"./tools/
|
|
25
|
-
"types": "./dist/tools/
|
|
26
|
-
"import": "./dist/tools/
|
|
24
|
+
"./tools/registration": {
|
|
25
|
+
"types": "./dist/tools/registration.d.ts",
|
|
26
|
+
"import": "./dist/tools/registration.js"
|
|
27
27
|
},
|
|
28
|
-
"./
|
|
29
|
-
"types": "./dist/
|
|
30
|
-
"import": "./dist/
|
|
28
|
+
"./components/item-scope-element": {
|
|
29
|
+
"types": "./dist/components/item-scope-element.d.ts",
|
|
30
|
+
"import": "./dist/components/item-scope-element.js"
|
|
31
31
|
},
|
|
32
32
|
"./components/item-toolbar-element": {
|
|
33
33
|
"types": "./dist/components/item-toolbar-element.d.ts",
|
|
@@ -45,54 +45,40 @@
|
|
|
45
45
|
"types": "./dist/services/AccessibilityCatalogResolver.d.ts",
|
|
46
46
|
"import": "./dist/services/AccessibilityCatalogResolver.js"
|
|
47
47
|
},
|
|
48
|
-
"./services/pnp-standard-features": {
|
|
49
|
-
"types": "./dist/services/pnp-standard-features.d.ts",
|
|
50
|
-
"import": "./dist/services/pnp-standard-features.js"
|
|
51
|
-
},
|
|
52
|
-
"./services/I18nService": {
|
|
53
|
-
"types": "./dist/services/I18nService.d.ts",
|
|
54
|
-
"import": "./dist/services/I18nService.js"
|
|
55
|
-
},
|
|
56
48
|
"./runtime/engine": {
|
|
57
49
|
"types": "./dist/runtime/engine.d.ts",
|
|
58
50
|
"import": "./dist/runtime/engine.js"
|
|
59
51
|
},
|
|
60
|
-
"./runtime/internal": {
|
|
61
|
-
"types": "./dist/runtime/internal.d.ts",
|
|
62
|
-
"import": "./dist/runtime/internal.js"
|
|
63
|
-
},
|
|
64
52
|
"./policy/engine": {
|
|
65
53
|
"types": "./dist/policy/engine.d.ts",
|
|
66
54
|
"import": "./dist/policy/engine.js"
|
|
67
|
-
},
|
|
68
|
-
"./policy/internal": {
|
|
69
|
-
"types": "./dist/policy/internal.d.ts",
|
|
70
|
-
"import": "./dist/policy/internal.js"
|
|
71
55
|
}
|
|
72
56
|
},
|
|
57
|
+
"customElements": "custom-elements.json",
|
|
73
58
|
"files": [
|
|
74
59
|
"dist",
|
|
60
|
+
"custom-elements.json",
|
|
75
61
|
"README.md"
|
|
76
62
|
],
|
|
77
63
|
"scripts": {
|
|
78
64
|
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && bun ./scripts/build-ce-components.mjs",
|
|
79
65
|
"dev": "tsc -p tsconfig.json --watch",
|
|
80
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
66
|
+
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.tests.json",
|
|
81
67
|
"lint": "biome lint .",
|
|
82
68
|
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
83
69
|
"test": "bun test"
|
|
84
70
|
},
|
|
85
71
|
"dependencies": {
|
|
86
|
-
"@pie-players/pie-calculator": "0.
|
|
87
|
-
"@pie-players/pie-context": "0.
|
|
88
|
-
"@pie-players/pie-players-shared": "0.
|
|
89
|
-
"@pie-players/pie-tts": "0.
|
|
72
|
+
"@pie-players/pie-calculator": "1.0.0-beta.0",
|
|
73
|
+
"@pie-players/pie-context": "1.0.0-beta.0",
|
|
74
|
+
"@pie-players/pie-players-shared": "1.0.0-beta.0",
|
|
75
|
+
"@pie-players/pie-tts": "1.0.0-beta.0",
|
|
90
76
|
"speech-rule-engine": "5.0.0-rc.4"
|
|
91
77
|
},
|
|
92
78
|
"devDependencies": {
|
|
93
79
|
"@biomejs/biome": "^2.5.15",
|
|
94
80
|
"@happy-dom/global-registrator": "^20.14.5",
|
|
95
|
-
"@pie-players/tts-client-server": "0.
|
|
81
|
+
"@pie-players/tts-client-server": "1.0.0-beta.0",
|
|
96
82
|
"svelte": "^5.57.1",
|
|
97
83
|
"svelte-check": "^4.7.6",
|
|
98
84
|
"typescript": "^5.9.3"
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { TestAttemptSession } from "../TestSession.js";
|
|
2
|
-
export interface PieBackendActivityItemRef {
|
|
3
|
-
identifier?: string;
|
|
4
|
-
item?: {
|
|
5
|
-
id?: string;
|
|
6
|
-
identifier?: string;
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
export interface PieBackendActivityDefinition {
|
|
10
|
-
id?: string;
|
|
11
|
-
identifier?: string;
|
|
12
|
-
assessmentId?: string;
|
|
13
|
-
assessmentItemRefs?: PieBackendActivityItemRef[];
|
|
14
|
-
}
|
|
15
|
-
export interface PieBackendActivitySession {
|
|
16
|
-
id?: string;
|
|
17
|
-
activitySessionId?: string;
|
|
18
|
-
startedAt?: string;
|
|
19
|
-
updatedAt?: string;
|
|
20
|
-
completedAt?: string;
|
|
21
|
-
currentItemIndex?: number;
|
|
22
|
-
currentSectionIdentifier?: string;
|
|
23
|
-
visitedItemIdentifiers?: string[];
|
|
24
|
-
itemSessions?: Record<string, unknown>;
|
|
25
|
-
}
|
|
26
|
-
export interface MapActivityToTestAttemptSessionArgs {
|
|
27
|
-
activityDefinition?: PieBackendActivityDefinition | null;
|
|
28
|
-
activitySession?: PieBackendActivitySession | null;
|
|
29
|
-
itemRefs?: PieBackendActivityItemRef[];
|
|
30
|
-
itemSessionsByItemIdentifier?: Record<string, unknown>;
|
|
31
|
-
assessmentId?: string;
|
|
32
|
-
testAttemptSessionIdentifier?: string;
|
|
33
|
-
}
|
|
34
|
-
export interface ActivitySessionPatchPayload {
|
|
35
|
-
activitySession: {
|
|
36
|
-
id: string;
|
|
37
|
-
startedAt?: string;
|
|
38
|
-
updatedAt?: string;
|
|
39
|
-
completedAt?: string;
|
|
40
|
-
currentItemIndex: number;
|
|
41
|
-
currentSectionIdentifier?: string;
|
|
42
|
-
visitedItemIdentifiers: string[];
|
|
43
|
-
itemSessions: Record<string, unknown>;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
export declare function mapActivityToTestAttemptSession(args: MapActivityToTestAttemptSessionArgs): TestAttemptSession;
|
|
47
|
-
export declare function toItemSessionsRecord(testAttemptSession: TestAttemptSession): Record<string, unknown>;
|
|
48
|
-
export declare function buildActivitySessionPatchFromTestAttemptSession(testAttemptSession: TestAttemptSession): ActivitySessionPatchPayload;
|
|
49
|
-
export declare function buildActivitySessionItemUpdate(testAttemptSession: TestAttemptSession, itemIdentifier: string): ActivitySessionPatchPayload;
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
function nowIso() {
|
|
2
|
-
return new Date().toISOString();
|
|
3
|
-
}
|
|
4
|
-
function getItemIdentifier(itemRef) {
|
|
5
|
-
return (itemRef.identifier || itemRef.item?.identifier || itemRef.item?.id || null);
|
|
6
|
-
}
|
|
7
|
-
function resolveItemIdentifiers(args) {
|
|
8
|
-
const refs = args.itemRefs || args.activityDefinition?.assessmentItemRefs || [];
|
|
9
|
-
const identifiers = refs
|
|
10
|
-
.map((itemRef) => getItemIdentifier(itemRef))
|
|
11
|
-
.filter((itemIdentifier) => !!itemIdentifier);
|
|
12
|
-
return Array.from(new Set(identifiers));
|
|
13
|
-
}
|
|
14
|
-
function resolveAssessmentId(args) {
|
|
15
|
-
return (args.assessmentId ||
|
|
16
|
-
args.activityDefinition?.assessmentId ||
|
|
17
|
-
args.activityDefinition?.identifier ||
|
|
18
|
-
args.activityDefinition?.id ||
|
|
19
|
-
"unknown-assessment");
|
|
20
|
-
}
|
|
21
|
-
function resolveTestAttemptSessionIdentifier(args, assessmentId) {
|
|
22
|
-
return (args.testAttemptSessionIdentifier ||
|
|
23
|
-
args.activitySession?.activitySessionId ||
|
|
24
|
-
args.activitySession?.id ||
|
|
25
|
-
`tas_${assessmentId}`);
|
|
26
|
-
}
|
|
27
|
-
function resolveBackendItemSessions(args) {
|
|
28
|
-
return {
|
|
29
|
-
...(args.activitySession?.itemSessions || {}),
|
|
30
|
-
...(args.itemSessionsByItemIdentifier || {}),
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
function mapItemSessions(itemIdentifiers, backendItemSessions) {
|
|
34
|
-
return itemIdentifiers.reduce((acc, itemIdentifier) => {
|
|
35
|
-
const rawSession = backendItemSessions[itemIdentifier];
|
|
36
|
-
if (!rawSession)
|
|
37
|
-
return acc;
|
|
38
|
-
const pieSessionId = typeof rawSession.id === "string" ? rawSession.id : undefined;
|
|
39
|
-
const attemptCount = typeof rawSession.attemptCount === "number" &&
|
|
40
|
-
rawSession.attemptCount > 0
|
|
41
|
-
? rawSession.attemptCount
|
|
42
|
-
: pieSessionId
|
|
43
|
-
? 1
|
|
44
|
-
: 0;
|
|
45
|
-
const isCompleted = typeof rawSession.isCompleted === "boolean"
|
|
46
|
-
? rawSession.isCompleted
|
|
47
|
-
: Boolean(rawSession.complete);
|
|
48
|
-
const startedAt = typeof rawSession.startedAt === "string"
|
|
49
|
-
? rawSession.startedAt
|
|
50
|
-
: undefined;
|
|
51
|
-
const updatedAt = typeof rawSession.updatedAt === "string"
|
|
52
|
-
? rawSession.updatedAt
|
|
53
|
-
: undefined;
|
|
54
|
-
const completedAt = typeof rawSession.completedAt === "string"
|
|
55
|
-
? rawSession.completedAt
|
|
56
|
-
: undefined;
|
|
57
|
-
acc[itemIdentifier] = {
|
|
58
|
-
itemIdentifier,
|
|
59
|
-
pieSessionId,
|
|
60
|
-
attemptCount,
|
|
61
|
-
isCompleted,
|
|
62
|
-
startedAt,
|
|
63
|
-
updatedAt,
|
|
64
|
-
completedAt,
|
|
65
|
-
session: rawSession,
|
|
66
|
-
};
|
|
67
|
-
return acc;
|
|
68
|
-
}, {});
|
|
69
|
-
}
|
|
70
|
-
export function mapActivityToTestAttemptSession(args) {
|
|
71
|
-
const assessmentId = resolveAssessmentId(args);
|
|
72
|
-
const itemIdentifiers = resolveItemIdentifiers(args);
|
|
73
|
-
const testAttemptSessionIdentifier = resolveTestAttemptSessionIdentifier(args, assessmentId);
|
|
74
|
-
const backendItemSessions = resolveBackendItemSessions(args);
|
|
75
|
-
const now = nowIso();
|
|
76
|
-
const startedAt = args.activitySession?.startedAt || now;
|
|
77
|
-
const updatedAt = args.activitySession?.updatedAt || startedAt;
|
|
78
|
-
return {
|
|
79
|
-
version: 1,
|
|
80
|
-
testAttemptSessionIdentifier,
|
|
81
|
-
assessmentId,
|
|
82
|
-
startedAt,
|
|
83
|
-
updatedAt,
|
|
84
|
-
completedAt: args.activitySession?.completedAt,
|
|
85
|
-
navigationState: {
|
|
86
|
-
currentItemIndex: args.activitySession?.currentItemIndex ?? -1,
|
|
87
|
-
visitedItemIdentifiers: [
|
|
88
|
-
...(args.activitySession?.visitedItemIdentifiers || []),
|
|
89
|
-
],
|
|
90
|
-
currentSectionIdentifier: args.activitySession?.currentSectionIdentifier,
|
|
91
|
-
},
|
|
92
|
-
realization: {
|
|
93
|
-
seed: testAttemptSessionIdentifier,
|
|
94
|
-
itemIdentifiers,
|
|
95
|
-
},
|
|
96
|
-
itemSessions: mapItemSessions(itemIdentifiers, backendItemSessions),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
export function toItemSessionsRecord(testAttemptSession) {
|
|
100
|
-
return Object.entries(testAttemptSession.itemSessions).reduce((acc, [itemIdentifier, itemSession]) => {
|
|
101
|
-
if (itemSession.session) {
|
|
102
|
-
acc[itemIdentifier] = itemSession.session;
|
|
103
|
-
}
|
|
104
|
-
return acc;
|
|
105
|
-
}, {});
|
|
106
|
-
}
|
|
107
|
-
export function buildActivitySessionPatchFromTestAttemptSession(testAttemptSession) {
|
|
108
|
-
return {
|
|
109
|
-
activitySession: {
|
|
110
|
-
id: testAttemptSession.testAttemptSessionIdentifier,
|
|
111
|
-
startedAt: testAttemptSession.startedAt,
|
|
112
|
-
updatedAt: testAttemptSession.updatedAt,
|
|
113
|
-
completedAt: testAttemptSession.completedAt,
|
|
114
|
-
currentItemIndex: testAttemptSession.navigationState.currentItemIndex,
|
|
115
|
-
currentSectionIdentifier: testAttemptSession.navigationState.currentSectionIdentifier,
|
|
116
|
-
visitedItemIdentifiers: [
|
|
117
|
-
...testAttemptSession.navigationState.visitedItemIdentifiers,
|
|
118
|
-
],
|
|
119
|
-
itemSessions: toItemSessionsRecord(testAttemptSession),
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
export function buildActivitySessionItemUpdate(testAttemptSession, itemIdentifier) {
|
|
124
|
-
const itemSession = testAttemptSession.itemSessions[itemIdentifier];
|
|
125
|
-
return {
|
|
126
|
-
activitySession: {
|
|
127
|
-
id: testAttemptSession.testAttemptSessionIdentifier,
|
|
128
|
-
currentItemIndex: testAttemptSession.navigationState.currentItemIndex,
|
|
129
|
-
currentSectionIdentifier: testAttemptSession.navigationState.currentSectionIdentifier,
|
|
130
|
-
visitedItemIdentifiers: [
|
|
131
|
-
...testAttemptSession.navigationState.visitedItemIdentifiers,
|
|
132
|
-
],
|
|
133
|
-
itemSessions: itemSession?.session
|
|
134
|
-
? { [itemIdentifier]: itemSession.session }
|
|
135
|
-
: {},
|
|
136
|
-
},
|
|
137
|
-
};
|
|
138
|
-
}
|