@pie-players/pie-assessment-player 0.3.70 → 0.3.71
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
CHANGED
|
@@ -33,14 +33,32 @@ const controller =
|
|
|
33
33
|
host?.getAssessmentController?.();
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
`waitForAssessmentController(timeoutMs)` resolves
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
`waitForAssessmentController(timeoutMs)` resolves after initialization and
|
|
37
|
+
hydration succeed. At that point the getter, ready hook, and ready event all
|
|
38
|
+
observe the same controller. The getter returns `null` while initialization is
|
|
39
|
+
pending or failed, and after disconnect. A waiter resolves to `null` when its
|
|
40
|
+
active attempt fails or is retired, or its own timeout expires. A waiter's
|
|
41
|
+
timeout does not cancel a still-active initialization.
|
|
42
|
+
|
|
43
|
+
Connect the element and assign `assessmentId`, `attemptId`, `assessment`, and
|
|
44
|
+
`hooks` in the same turn, or assign them before connecting. These assignments
|
|
45
|
+
are batched; changing assessment, attempt, or hooks later retires the previous
|
|
46
|
+
controller and starts a new one. Replace object properties to update them;
|
|
47
|
+
mutating a previously assigned object in place is not an update signal. Runtime
|
|
48
|
+
props, locale, and navigation visibility do not reload the assessment.
|
|
49
|
+
|
|
50
|
+
Failed initialization exposes an error and a keyboard-accessible Retry action.
|
|
51
|
+
The element invokes the ready hook and emits the ready event once per successful
|
|
52
|
+
initialization. Ready hooks are notifications: their rejection reaches `onError`
|
|
53
|
+
and `assessment-error` without undoing successful hydration.
|
|
41
54
|
|
|
42
55
|
### Lifecycle
|
|
43
56
|
|
|
57
|
+
The element owns its assessment controller and calls its idempotent `dispose()`
|
|
58
|
+
when inputs replace the attempt or the element disconnects. Disposal removes
|
|
59
|
+
listeners and makes the old handle unusable. The nested toolkit disposes any
|
|
60
|
+
coordinator it created; a coordinator supplied by the host remains host-owned.
|
|
61
|
+
|
|
44
62
|
```ts
|
|
45
63
|
// hydrate runs as part of initialize(); call it again only on a manual reload.
|
|
46
64
|
const unsubscribe = controller.subscribe(handleEvent);
|
|
@@ -61,6 +79,15 @@ shape the persistence strategy load/save methods exchange and the same
|
|
|
61
79
|
shape per-section bridges roll up into via `updateSectionSession(sectionId,
|
|
62
80
|
snapshot)`.
|
|
63
81
|
|
|
82
|
+
The default element captures the outgoing section before navigation replaces it,
|
|
83
|
+
including navigation through the controller. A returning section waits for its
|
|
84
|
+
canonical `engine-ready` stage and restores its saved section snapshot before
|
|
85
|
+
accepting input or session updates. The section region stays `aria-busy` during
|
|
86
|
+
this handoff. Failed restoration leaves the saved snapshot intact, reports
|
|
87
|
+
`assessment-error` and `onError` with phase `navigation`, and offers Retry.
|
|
88
|
+
Navigating away or disconnecting retires that handoff. This in-memory restoration
|
|
89
|
+
does not acknowledge durable saves; persistence still uses the host's strategy.
|
|
90
|
+
|
|
64
91
|
### Event stream
|
|
65
92
|
|
|
66
93
|
The controller's typed event stream
|
|
@@ -4,25 +4,27 @@ import { AssessmentPlayerProgressSnapshot, AssessmentPlayerRuntimeHostContract,
|
|
|
4
4
|
import { AssessmentDefinition, AssessmentPlayerHooks, AssessmentPlayerRuntimeConfig } from '../types.js';
|
|
5
5
|
export declare class AssessmentPlayerDefaultElement extends HTMLElement implements AssessmentPlayerRuntimeHostContract {
|
|
6
6
|
static get observedAttributes(): string[];
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
private _assessmentId;
|
|
8
|
+
private _attemptId;
|
|
9
9
|
/**
|
|
10
10
|
* Interface locale for this player's own navigation chrome, as a BCP-47 tag.
|
|
11
11
|
* Empty means the graceful default, `en-US`. Also forwarded to the section
|
|
12
12
|
* element, which passes it on to the toolkit.
|
|
13
13
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
private _locale;
|
|
15
|
+
private _assessment;
|
|
16
|
+
private _env;
|
|
17
|
+
private _coordinator;
|
|
18
|
+
private _hooks;
|
|
19
|
+
private _showNavigation;
|
|
20
|
+
private _sectionPlayerLayout;
|
|
21
|
+
private _playerType;
|
|
22
22
|
private _debug;
|
|
23
23
|
private controller;
|
|
24
|
-
private
|
|
25
|
-
private
|
|
24
|
+
private initializingController;
|
|
25
|
+
private generation;
|
|
26
|
+
private reconcileQueued;
|
|
27
|
+
private controllerWaiters;
|
|
26
28
|
/**
|
|
27
29
|
* This player's own provider rather than a context read. Its navigation sits
|
|
28
30
|
* beside the section host, not inside it, so there is no published toolkit
|
|
@@ -33,6 +35,8 @@ export declare class AssessmentPlayerDefaultElement extends HTMLElement implemen
|
|
|
33
35
|
private unsubscribeI18n?;
|
|
34
36
|
private sectionHost;
|
|
35
37
|
private sectionControllerRef;
|
|
38
|
+
private sectionSessionReady;
|
|
39
|
+
private detachSectionListeners?;
|
|
36
40
|
/**
|
|
37
41
|
* Rendered content, tracked so a re-render can replace it without clearing the
|
|
38
42
|
* announcer below. A live region only announces changes that happen while it is
|
|
@@ -51,8 +55,27 @@ export declare class AssessmentPlayerDefaultElement extends HTMLElement implemen
|
|
|
51
55
|
private detachInstrumentationBridge?;
|
|
52
56
|
private _sectionPlayerRuntime;
|
|
53
57
|
private readiness;
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
get assessmentId(): string;
|
|
59
|
+
set assessmentId(value: string);
|
|
60
|
+
get attemptId(): string;
|
|
61
|
+
set attemptId(value: string);
|
|
62
|
+
get assessment(): AssessmentDefinition | null;
|
|
63
|
+
set assessment(value: AssessmentDefinition | null);
|
|
64
|
+
get hooks(): AssessmentPlayerHooks | null;
|
|
65
|
+
set hooks(value: AssessmentPlayerHooks | null);
|
|
66
|
+
get locale(): string;
|
|
67
|
+
set locale(value: string);
|
|
68
|
+
get env(): Env | null;
|
|
69
|
+
set env(value: Env | null);
|
|
70
|
+
get coordinator(): unknown;
|
|
71
|
+
set coordinator(value: unknown);
|
|
72
|
+
get showNavigation(): boolean | string | null | undefined;
|
|
73
|
+
set showNavigation(value: boolean | string | null | undefined);
|
|
74
|
+
get sectionPlayerLayout(): "splitpane" | "vertical";
|
|
75
|
+
set sectionPlayerLayout(value: "splitpane" | "vertical");
|
|
76
|
+
get playerType(): "iife" | "esm" | "preloaded";
|
|
77
|
+
set playerType(value: "iife" | "esm" | "preloaded");
|
|
78
|
+
attributeChangedCallback(name: string, oldValue: string | null, value: string | null): void;
|
|
56
79
|
/**
|
|
57
80
|
* Catalog loading is async, so the first paint carries whatever the provider
|
|
58
81
|
* already holds and the subscription repaints once the requested locale
|
|
@@ -70,11 +93,15 @@ export declare class AssessmentPlayerDefaultElement extends HTMLElement implemen
|
|
|
70
93
|
set sectionPlayerRuntime(value: AssessmentPlayerRuntimeConfig["sectionPlayerRuntime"]);
|
|
71
94
|
connectedCallback(): void;
|
|
72
95
|
disconnectedCallback(): void;
|
|
96
|
+
private settleControllerWaiters;
|
|
97
|
+
private retireController;
|
|
98
|
+
private queueReconciliation;
|
|
73
99
|
private dispatch;
|
|
74
100
|
private bootstrapController;
|
|
75
101
|
private resolveInstrumentationProvider;
|
|
76
102
|
private attachInstrumentationBridge;
|
|
77
103
|
private renderEmptyState;
|
|
104
|
+
private createStatusContent;
|
|
78
105
|
/**
|
|
79
106
|
* Replace the rendered content, leaving the announcer in place.
|
|
80
107
|
*/
|
|
@@ -108,6 +135,8 @@ export declare class AssessmentPlayerDefaultElement extends HTMLElement implemen
|
|
|
108
135
|
private syncCurrentSectionSessionIntoAssessment;
|
|
109
136
|
private attachSectionControllerReadyListener;
|
|
110
137
|
private render;
|
|
138
|
+
/** Locale and chrome changes must not remount a section or reload its attempt. */
|
|
139
|
+
private updateNavigationChrome;
|
|
111
140
|
/**
|
|
112
141
|
* Announce the new position, once the live region has been in the document long
|
|
113
142
|
* enough for the change to register as a change.
|
|
@@ -62,13 +62,15 @@ export type AssessmentControllerEvent = {
|
|
|
62
62
|
export interface AssessmentControllerHandle {
|
|
63
63
|
/**
|
|
64
64
|
* Bootstrap the controller: build the delivery plan, ensure a
|
|
65
|
-
* session exists, run `hydrate()
|
|
66
|
-
* `onAssessmentControllerReady`.
|
|
65
|
+
* session exists, and run `hydrate()` once. The owning element
|
|
66
|
+
* publishes readiness and invokes `onAssessmentControllerReady`.
|
|
67
67
|
*
|
|
68
68
|
* Called by the assessment player when the player CE mounts. Hosts
|
|
69
69
|
* normally do not call this directly.
|
|
70
70
|
*/
|
|
71
71
|
initialize(): Promise<void>;
|
|
72
|
+
/** Retire this attempt, detach listeners, and notify its disposal hook once. */
|
|
73
|
+
dispose(): Promise<void>;
|
|
72
74
|
/**
|
|
73
75
|
* Load and apply a previously persisted assessment session via the
|
|
74
76
|
* registered `AssessmentSessionPersistenceStrategy`. Falls back to
|
|
@@ -173,6 +175,9 @@ export declare class AssessmentController implements AssessmentControllerHandle
|
|
|
173
175
|
private readiness;
|
|
174
176
|
private submitted;
|
|
175
177
|
private persistenceStrategy?;
|
|
178
|
+
private initializationPromise?;
|
|
179
|
+
private disposalPromise?;
|
|
180
|
+
private disposed;
|
|
176
181
|
private readonly storageContext;
|
|
177
182
|
constructor(args: {
|
|
178
183
|
assessmentId: string;
|
|
@@ -181,12 +186,15 @@ export declare class AssessmentController implements AssessmentControllerHandle
|
|
|
181
186
|
hooks?: AssessmentPlayerHooks;
|
|
182
187
|
});
|
|
183
188
|
private emit;
|
|
189
|
+
private assertActive;
|
|
184
190
|
private handleError;
|
|
185
191
|
private getPersistenceStrategy;
|
|
186
192
|
private createDeliveryPlan;
|
|
187
193
|
private ensureSession;
|
|
188
194
|
initialize(): Promise<void>;
|
|
195
|
+
private initializeOnce;
|
|
189
196
|
hydrate(): Promise<void>;
|
|
197
|
+
dispose(): Promise<void>;
|
|
190
198
|
persist(): Promise<void>;
|
|
191
199
|
getSession(): AssessmentSession | null;
|
|
192
200
|
getRuntimeState(): AssessmentControllerRuntimeState;
|
|
@@ -60,7 +60,9 @@ var e = {
|
|
|
60
60
|
resizePassageAndMediaA11y: "Panelen met tekst en media verkleinen of vergroten",
|
|
61
61
|
assessment: {
|
|
62
62
|
sectionPosition: "Onderdeel {position} van {total}",
|
|
63
|
-
noSections: "Geen onderdelen"
|
|
63
|
+
noSections: "Geen onderdelen",
|
|
64
|
+
loadFailed: "De toets kon niet worden geladen. Probeer het opnieuw.",
|
|
65
|
+
restoreFailed: "Je opgeslagen antwoorden voor dit onderdeel konden niet worden hersteld. Probeer het opnieuw."
|
|
64
66
|
},
|
|
65
67
|
formative: {
|
|
66
68
|
checkAnswer: "Antwoord controleren",
|