@pie-players/pie-assessment-toolkit 0.2.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 +520 -0
- package/dist/attempt/TestSession.d.ts +90 -0
- package/dist/attempt/TestSession.d.ts.map +1 -0
- package/dist/attempt/TestSession.js +174 -0
- package/dist/attempt/TestSession.js.map +1 -0
- package/dist/core/TypedEventBus.d.ts +48 -0
- package/dist/core/TypedEventBus.d.ts.map +1 -0
- package/dist/core/TypedEventBus.js +63 -0
- package/dist/core/TypedEventBus.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/item-loader.d.ts +45 -0
- package/dist/item-loader.d.ts.map +1 -0
- package/dist/item-loader.js +62 -0
- package/dist/item-loader.js.map +1 -0
- package/dist/player/AssessmentPlayer.d.ts +388 -0
- package/dist/player/AssessmentPlayer.d.ts.map +1 -0
- package/dist/player/AssessmentPlayer.js +965 -0
- package/dist/player/AssessmentPlayer.js.map +1 -0
- package/dist/player/index.d.ts +17 -0
- package/dist/player/index.d.ts.map +1 -0
- package/dist/player/index.js +15 -0
- package/dist/player/index.js.map +1 -0
- package/dist/player/navigation-types.d.ts +63 -0
- package/dist/player/navigation-types.d.ts.map +1 -0
- package/dist/player/navigation-types.js +7 -0
- package/dist/player/navigation-types.js.map +1 -0
- package/dist/player/qti-navigation.d.ts +29 -0
- package/dist/player/qti-navigation.d.ts.map +1 -0
- package/dist/player/qti-navigation.js +160 -0
- package/dist/player/qti-navigation.js.map +1 -0
- package/dist/reference-layout/index.d.ts +19 -0
- package/dist/reference-layout/index.d.ts.map +1 -0
- package/dist/reference-layout/index.js +20 -0
- package/dist/reference-layout/index.js.map +1 -0
- package/dist/services/AccessibilityCatalogResolver.d.ts +141 -0
- package/dist/services/AccessibilityCatalogResolver.d.ts.map +1 -0
- package/dist/services/AccessibilityCatalogResolver.js +249 -0
- package/dist/services/AccessibilityCatalogResolver.js.map +1 -0
- package/dist/services/AssessmentAuthoringService.d.ts +60 -0
- package/dist/services/AssessmentAuthoringService.d.ts.map +1 -0
- package/dist/services/AssessmentAuthoringService.js +183 -0
- package/dist/services/AssessmentAuthoringService.js.map +1 -0
- package/dist/services/ContextVariableStore.d.ts +114 -0
- package/dist/services/ContextVariableStore.d.ts.map +1 -0
- package/dist/services/ContextVariableStore.js +207 -0
- package/dist/services/ContextVariableStore.js.map +1 -0
- package/dist/services/ElementToolStateStore.d.ts +125 -0
- package/dist/services/ElementToolStateStore.d.ts.map +1 -0
- package/dist/services/ElementToolStateStore.js +200 -0
- package/dist/services/ElementToolStateStore.js.map +1 -0
- package/dist/services/HighlightCoordinator.d.ts +179 -0
- package/dist/services/HighlightCoordinator.d.ts.map +1 -0
- package/dist/services/HighlightCoordinator.js +446 -0
- package/dist/services/HighlightCoordinator.js.map +1 -0
- package/dist/services/I18nService.d.ts +121 -0
- package/dist/services/I18nService.d.ts.map +1 -0
- package/dist/services/I18nService.js +276 -0
- package/dist/services/I18nService.js.map +1 -0
- package/dist/services/PNPMapper.d.ts +71 -0
- package/dist/services/PNPMapper.d.ts.map +1 -0
- package/dist/services/PNPMapper.js +98 -0
- package/dist/services/PNPMapper.js.map +1 -0
- package/dist/services/PNPToolResolver.d.ts +127 -0
- package/dist/services/PNPToolResolver.d.ts.map +1 -0
- package/dist/services/PNPToolResolver.js +222 -0
- package/dist/services/PNPToolResolver.js.map +1 -0
- package/dist/services/SSMLExtractor.d.ts +61 -0
- package/dist/services/SSMLExtractor.d.ts.map +1 -0
- package/dist/services/SSMLExtractor.js +181 -0
- package/dist/services/SSMLExtractor.js.map +1 -0
- package/dist/services/TTSService.d.ts +162 -0
- package/dist/services/TTSService.d.ts.map +1 -0
- package/dist/services/TTSService.js +465 -0
- package/dist/services/TTSService.js.map +1 -0
- package/dist/services/ThemeProvider.d.ts +95 -0
- package/dist/services/ThemeProvider.d.ts.map +1 -0
- package/dist/services/ThemeProvider.js +299 -0
- package/dist/services/ThemeProvider.js.map +1 -0
- package/dist/services/ToolConfigResolver.d.ts +162 -0
- package/dist/services/ToolConfigResolver.d.ts.map +1 -0
- package/dist/services/ToolConfigResolver.js +230 -0
- package/dist/services/ToolConfigResolver.js.map +1 -0
- package/dist/services/ToolCoordinator.d.ts +137 -0
- package/dist/services/ToolCoordinator.d.ts.map +1 -0
- package/dist/services/ToolCoordinator.js +318 -0
- package/dist/services/ToolCoordinator.js.map +1 -0
- package/dist/services/ToolkitCoordinator.d.ts +188 -0
- package/dist/services/ToolkitCoordinator.d.ts.map +1 -0
- package/dist/services/ToolkitCoordinator.js +252 -0
- package/dist/services/ToolkitCoordinator.js.map +1 -0
- package/dist/services/interfaces.d.ts +391 -0
- package/dist/services/interfaces.d.ts.map +1 -0
- package/dist/services/interfaces.js +12 -0
- package/dist/services/interfaces.js.map +1 -0
- package/dist/services/tool-providers/DesmosToolProvider.d.ts +103 -0
- package/dist/services/tool-providers/DesmosToolProvider.d.ts.map +1 -0
- package/dist/services/tool-providers/DesmosToolProvider.js +127 -0
- package/dist/services/tool-providers/DesmosToolProvider.js.map +1 -0
- package/dist/services/tool-providers/IToolProvider.d.ts +137 -0
- package/dist/services/tool-providers/IToolProvider.d.ts.map +1 -0
- package/dist/services/tool-providers/IToolProvider.js +13 -0
- package/dist/services/tool-providers/IToolProvider.js.map +1 -0
- package/dist/services/tool-providers/TIToolProvider.d.ts +107 -0
- package/dist/services/tool-providers/TIToolProvider.d.ts.map +1 -0
- package/dist/services/tool-providers/TIToolProvider.js +123 -0
- package/dist/services/tool-providers/TIToolProvider.js.map +1 -0
- package/dist/services/tool-providers/TTSToolProvider.d.ts +143 -0
- package/dist/services/tool-providers/TTSToolProvider.d.ts.map +1 -0
- package/dist/services/tool-providers/TTSToolProvider.js +168 -0
- package/dist/services/tool-providers/TTSToolProvider.js.map +1 -0
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +165 -0
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts.map +1 -0
- package/dist/services/tool-providers/ToolProviderRegistry.js +240 -0
- package/dist/services/tool-providers/ToolProviderRegistry.js.map +1 -0
- package/dist/services/tool-providers/index.d.ts +18 -0
- package/dist/services/tool-providers/index.d.ts.map +1 -0
- package/dist/services/tool-providers/index.js +15 -0
- package/dist/services/tool-providers/index.js.map +1 -0
- package/dist/services/tts/browser-provider.d.ts +24 -0
- package/dist/services/tts/browser-provider.d.ts.map +1 -0
- package/dist/services/tts/browser-provider.js +177 -0
- package/dist/services/tts/browser-provider.js.map +1 -0
- package/dist/services/tts/provider-interface.d.ts +131 -0
- package/dist/services/tts/provider-interface.d.ts.map +1 -0
- package/dist/services/tts/provider-interface.js +10 -0
- package/dist/services/tts/provider-interface.js.map +1 -0
- package/dist/tools/calculators/desmos-provider.d.ts +54 -0
- package/dist/tools/calculators/desmos-provider.d.ts.map +1 -0
- package/dist/tools/calculators/desmos-provider.js +384 -0
- package/dist/tools/calculators/desmos-provider.js.map +1 -0
- package/dist/tools/calculators/mathjs-provider.d.ts +50 -0
- package/dist/tools/calculators/mathjs-provider.d.ts.map +1 -0
- package/dist/tools/calculators/mathjs-provider.js +660 -0
- package/dist/tools/calculators/mathjs-provider.js.map +1 -0
- package/dist/tools/calculators/ti-provider.d.ts +122 -0
- package/dist/tools/calculators/ti-provider.d.ts.map +1 -0
- package/dist/tools/calculators/ti-provider.js +587 -0
- package/dist/tools/calculators/ti-provider.js.map +1 -0
- package/dist/tools/client.d.ts +17 -0
- package/dist/tools/client.d.ts.map +1 -0
- package/dist/tools/client.js +26 -0
- package/dist/tools/client.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +10 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/library-loader.d.ts +63 -0
- package/dist/tools/library-loader.d.ts.map +1 -0
- package/dist/tools/library-loader.js +292 -0
- package/dist/tools/library-loader.js.map +1 -0
- package/dist/tools/response-discovery.d.ts +72 -0
- package/dist/tools/response-discovery.d.ts.map +1 -0
- package/dist/tools/response-discovery.js +183 -0
- package/dist/tools/response-discovery.js.map +1 -0
- package/dist/tools/tool-coordinator.d.ts +76 -0
- package/dist/tools/tool-coordinator.d.ts.map +1 -0
- package/dist/tools/tool-coordinator.js +197 -0
- package/dist/tools/tool-coordinator.js.map +1 -0
- package/dist/tools/types.d.ts +427 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +13 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/variant-resolver.d.ts +48 -0
- package/dist/tools/variant-resolver.d.ts.map +1 -0
- package/dist/tools/variant-resolver.js +214 -0
- package/dist/tools/variant-resolver.js.map +1 -0
- package/dist/types/events.d.ts +157 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +11 -0
- package/dist/types/events.js.map +1 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +11 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +71 -0
- package/src/README.md +626 -0
- package/src/components/QuestionToolBar.svelte +406 -0
- package/src/player/AssessmentLayout.svelte +68 -0
- package/src/player/README.md +154 -0
- package/src/reference-layout/README.md +135 -0
- package/src/reference-layout/ReferenceLayout.svelte +209 -0
- package/src/reference-layout/components/AssessmentContent.svelte +259 -0
- package/src/reference-layout/components/AssessmentFooter.svelte +89 -0
- package/src/reference-layout/components/AssessmentHeader.svelte +250 -0
- package/src/reference-layout/components/AssessmentNavigation.svelte +134 -0
- package/src/reference-layout/components/AssessmentToolsBar.svelte +176 -0
- package/src/reference-layout/components/ItemPanel.svelte +200 -0
- package/src/reference-layout/components/NotesPanel.svelte +179 -0
- package/src/reference-layout/components/PassagePanel.svelte +76 -0
- package/src/tools/README.md +616 -0
- package/src/tools/calculators/README.md +395 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Variable Store
|
|
3
|
+
*
|
|
4
|
+
* Standalone service for managing QTI 3.0 context variables.
|
|
5
|
+
* Context variables are global assessment-level variables that can be
|
|
6
|
+
* shared across items.
|
|
7
|
+
*
|
|
8
|
+
* Can be used independently by any assessment player without requiring
|
|
9
|
+
* the full AssessmentPlayer.
|
|
10
|
+
*
|
|
11
|
+
* Part of PIE Assessment Toolkit.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Standalone service for managing QTI 3.0 context variables.
|
|
15
|
+
*
|
|
16
|
+
* Context variables are global assessment-level variables that can be
|
|
17
|
+
* shared across items. Can be used independently by any assessment player.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Initialize with declarations
|
|
22
|
+
* const store = new ContextVariableStore(declarations);
|
|
23
|
+
*
|
|
24
|
+
* // Get/set variables
|
|
25
|
+
* const seed = store.get('RANDOM_SEED');
|
|
26
|
+
* store.set('DIFFICULTY_LEVEL', 'hard');
|
|
27
|
+
*
|
|
28
|
+
* // Pass to items
|
|
29
|
+
* const context = store.toObject();
|
|
30
|
+
* await renderItem(item, session, context);
|
|
31
|
+
*
|
|
32
|
+
* // Persist in session
|
|
33
|
+
* session.contextVariables = store.toObject();
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export class ContextVariableStore {
|
|
37
|
+
variables = new Map();
|
|
38
|
+
declarations = new Map();
|
|
39
|
+
/**
|
|
40
|
+
* Initialize store with context declarations from assessment
|
|
41
|
+
*
|
|
42
|
+
* @param declarations QTI 3.0 context declarations
|
|
43
|
+
*/
|
|
44
|
+
constructor(declarations) {
|
|
45
|
+
if (declarations) {
|
|
46
|
+
this.initialize(declarations);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Initialize context variables from declarations
|
|
51
|
+
*
|
|
52
|
+
* Sets each variable to its defaultValue or type-appropriate default.
|
|
53
|
+
*/
|
|
54
|
+
initialize(declarations) {
|
|
55
|
+
this.declarations.clear();
|
|
56
|
+
this.variables.clear();
|
|
57
|
+
for (const decl of declarations) {
|
|
58
|
+
this.declarations.set(decl.identifier, decl);
|
|
59
|
+
const value = decl.defaultValue ??
|
|
60
|
+
this.getDefaultValueForType(decl.baseType, decl.cardinality);
|
|
61
|
+
this.variables.set(decl.identifier, value);
|
|
62
|
+
}
|
|
63
|
+
console.debug(`ContextVariableStore: Initialized ${declarations.length} context variables:`, Array.from(this.variables.keys()));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get context variable value
|
|
67
|
+
*
|
|
68
|
+
* @param identifier Variable identifier
|
|
69
|
+
* @returns Variable value or undefined if not found
|
|
70
|
+
*/
|
|
71
|
+
get(identifier) {
|
|
72
|
+
return this.variables.get(identifier);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Set context variable value
|
|
76
|
+
*
|
|
77
|
+
* @param identifier Variable identifier
|
|
78
|
+
* @param value New value
|
|
79
|
+
*/
|
|
80
|
+
set(identifier, value) {
|
|
81
|
+
if (!this.declarations.has(identifier)) {
|
|
82
|
+
console.warn(`ContextVariableStore: Setting undeclared context variable: ${identifier}`, "Consider declaring it in contextDeclarations");
|
|
83
|
+
}
|
|
84
|
+
// Type validation (optional but recommended)
|
|
85
|
+
const decl = this.declarations.get(identifier);
|
|
86
|
+
if (decl) {
|
|
87
|
+
this.validateValue(decl, value);
|
|
88
|
+
}
|
|
89
|
+
this.variables.set(identifier, value);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Check if variable exists
|
|
93
|
+
*/
|
|
94
|
+
has(identifier) {
|
|
95
|
+
return this.variables.has(identifier);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get all variable names
|
|
99
|
+
*/
|
|
100
|
+
getIdentifiers() {
|
|
101
|
+
return Array.from(this.variables.keys());
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get all variables as object (for passing to PIE elements)
|
|
105
|
+
*
|
|
106
|
+
* @returns Plain object with all context variables
|
|
107
|
+
*/
|
|
108
|
+
toObject() {
|
|
109
|
+
return Object.fromEntries(this.variables);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Load state from serialized object (for session restore)
|
|
113
|
+
*
|
|
114
|
+
* @param state Object containing context variable values
|
|
115
|
+
*/
|
|
116
|
+
fromObject(state) {
|
|
117
|
+
for (const [key, value] of Object.entries(state)) {
|
|
118
|
+
this.variables.set(key, value);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Clear all variables (reset to defaults)
|
|
123
|
+
*/
|
|
124
|
+
reset() {
|
|
125
|
+
for (const [identifier, decl] of this.declarations) {
|
|
126
|
+
const value = decl.defaultValue ??
|
|
127
|
+
this.getDefaultValueForType(decl.baseType, decl.cardinality);
|
|
128
|
+
this.variables.set(identifier, value);
|
|
129
|
+
}
|
|
130
|
+
console.debug("ContextVariableStore: Reset to default values");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get declaration for variable
|
|
134
|
+
*
|
|
135
|
+
* @param identifier Variable identifier
|
|
136
|
+
* @returns Declaration or undefined if not found
|
|
137
|
+
*/
|
|
138
|
+
getDeclaration(identifier) {
|
|
139
|
+
return this.declarations.get(identifier);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get all declarations
|
|
143
|
+
*/
|
|
144
|
+
getDeclarations() {
|
|
145
|
+
return Array.from(this.declarations.values());
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Get default value for QTI base type
|
|
149
|
+
*
|
|
150
|
+
* @private
|
|
151
|
+
*/
|
|
152
|
+
getDefaultValueForType(baseType, cardinality) {
|
|
153
|
+
if (cardinality === "multiple" || cardinality === "ordered") {
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
if (cardinality === "record") {
|
|
157
|
+
return {};
|
|
158
|
+
}
|
|
159
|
+
// Single cardinality defaults
|
|
160
|
+
switch (baseType) {
|
|
161
|
+
case "boolean":
|
|
162
|
+
return false;
|
|
163
|
+
case "integer":
|
|
164
|
+
return 0;
|
|
165
|
+
case "float":
|
|
166
|
+
return 0.0;
|
|
167
|
+
case "string":
|
|
168
|
+
case "identifier":
|
|
169
|
+
case "uri":
|
|
170
|
+
return "";
|
|
171
|
+
case "point":
|
|
172
|
+
return [0, 0];
|
|
173
|
+
case "pair":
|
|
174
|
+
return ["", ""];
|
|
175
|
+
case "directedPair":
|
|
176
|
+
return ["", ""];
|
|
177
|
+
case "duration":
|
|
178
|
+
return 0;
|
|
179
|
+
case "file":
|
|
180
|
+
return null;
|
|
181
|
+
default:
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Validate value matches declared type (basic validation)
|
|
187
|
+
*
|
|
188
|
+
* @private
|
|
189
|
+
*/
|
|
190
|
+
validateValue(decl, value) {
|
|
191
|
+
// Basic type checking - can be extended
|
|
192
|
+
if (decl.baseType === "integer" && !Number.isInteger(value)) {
|
|
193
|
+
console.warn(`ContextVariableStore: Variable ${decl.identifier} expects integer, got:`, typeof value);
|
|
194
|
+
}
|
|
195
|
+
if (decl.baseType === "float" && typeof value !== "number") {
|
|
196
|
+
console.warn(`ContextVariableStore: Variable ${decl.identifier} expects float, got:`, typeof value);
|
|
197
|
+
}
|
|
198
|
+
if (decl.baseType === "boolean" && typeof value !== "boolean") {
|
|
199
|
+
console.warn(`ContextVariableStore: Variable ${decl.identifier} expects boolean, got:`, typeof value);
|
|
200
|
+
}
|
|
201
|
+
if ((decl.cardinality === "multiple" || decl.cardinality === "ordered") &&
|
|
202
|
+
!Array.isArray(value)) {
|
|
203
|
+
console.warn(`ContextVariableStore: Variable ${decl.identifier} expects array (cardinality: ${decl.cardinality}), got:`, typeof value);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=ContextVariableStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextVariableStore.js","sourceRoot":"","sources":["../../src/services/ContextVariableStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ElementToolStateStore - Manages element-level ephemeral tool state
|
|
3
|
+
*
|
|
4
|
+
* Provides centralized storage for UI tool state (answer eliminations, flags, etc.)
|
|
5
|
+
* that should NOT be sent to the server for scoring. Each element is uniquely identified
|
|
6
|
+
* across the entire assessment using composite keys.
|
|
7
|
+
*
|
|
8
|
+
* Key features:
|
|
9
|
+
* - Element-level granularity (not item-level)
|
|
10
|
+
* - Composite keys for global uniqueness: `assessmentId:sectionId:itemId:elementId`
|
|
11
|
+
* - Cross-section state persistence
|
|
12
|
+
* - Reactive subscriptions
|
|
13
|
+
* - Optional persistence callback integration
|
|
14
|
+
* - Generic solution for any tool
|
|
15
|
+
*/
|
|
16
|
+
export interface ElementIdComponents {
|
|
17
|
+
assessmentId: string;
|
|
18
|
+
sectionId: string;
|
|
19
|
+
itemId: string;
|
|
20
|
+
elementId: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class ElementToolStateStore {
|
|
23
|
+
private elementStates;
|
|
24
|
+
private listeners;
|
|
25
|
+
private onStateChange;
|
|
26
|
+
/**
|
|
27
|
+
* Generates a globally unique element ID by combining assessment, section, item, and element IDs.
|
|
28
|
+
* Format: `${assessmentId}:${sectionId}:${itemId}:${elementId}`
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* getGlobalElementId('demo-assessment', 'section-1', 'q1', 'mc1')
|
|
32
|
+
* // Returns: "demo-assessment:section-1:q1:mc1"
|
|
33
|
+
*/
|
|
34
|
+
getGlobalElementId(assessmentId: string, sectionId: string, itemId: string, elementId: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Parses a global element ID into its component parts.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* parseGlobalElementId('demo-assessment:section-1:q1:mc1')
|
|
40
|
+
* // Returns: { assessmentId: 'demo-assessment', sectionId: 'section-1', itemId: 'q1', elementId: 'mc1' }
|
|
41
|
+
*/
|
|
42
|
+
parseGlobalElementId(globalElementId: string): ElementIdComponents | null;
|
|
43
|
+
/**
|
|
44
|
+
* Sets tool state for a specific element.
|
|
45
|
+
* Notifies all subscribers and triggers persistence callback.
|
|
46
|
+
*
|
|
47
|
+
* @param globalElementId Composite key identifying the element
|
|
48
|
+
* @param toolId Tool identifier (e.g., 'answerEliminator', 'flagging')
|
|
49
|
+
* @param state Tool-specific state object
|
|
50
|
+
*/
|
|
51
|
+
setState(globalElementId: string, toolId: string, state: any): void;
|
|
52
|
+
/**
|
|
53
|
+
* Gets tool state for a specific element.
|
|
54
|
+
*
|
|
55
|
+
* @param globalElementId Composite key identifying the element
|
|
56
|
+
* @param toolId Tool identifier
|
|
57
|
+
* @returns Tool state or undefined if not found
|
|
58
|
+
*/
|
|
59
|
+
getState(globalElementId: string, toolId: string): any | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Gets all tool states for a specific element.
|
|
62
|
+
*
|
|
63
|
+
* @param globalElementId Composite key identifying the element
|
|
64
|
+
* @returns Object with tool states keyed by toolId
|
|
65
|
+
*/
|
|
66
|
+
getElementState(globalElementId: string): Record<string, any>;
|
|
67
|
+
/**
|
|
68
|
+
* Gets all tool states for all elements.
|
|
69
|
+
* Used for persistence and debugging.
|
|
70
|
+
*
|
|
71
|
+
* @returns Nested object: { globalElementId: { toolId: state } }
|
|
72
|
+
*/
|
|
73
|
+
getAllState(): Record<string, Record<string, any>>;
|
|
74
|
+
/**
|
|
75
|
+
* Subscribes to state changes.
|
|
76
|
+
* Callback is invoked whenever any element's tool state changes.
|
|
77
|
+
*
|
|
78
|
+
* @param callback Function to call on state changes
|
|
79
|
+
* @returns Unsubscribe function
|
|
80
|
+
*/
|
|
81
|
+
subscribe(callback: (state: Map<string, Map<string, any>>) => void): () => void;
|
|
82
|
+
private _notifyListeners;
|
|
83
|
+
/**
|
|
84
|
+
* Sets a callback to be invoked on state changes for persistence integration.
|
|
85
|
+
* Used by demo/app layer to persist tool state to localStorage or server.
|
|
86
|
+
*
|
|
87
|
+
* @param callback Function to call with serialized state on changes
|
|
88
|
+
*/
|
|
89
|
+
setOnStateChange(callback: (state: Record<string, Record<string, any>>) => void): void;
|
|
90
|
+
private _notifyStateChange;
|
|
91
|
+
/**
|
|
92
|
+
* Loads tool state from serialized format.
|
|
93
|
+
* Used to restore state from localStorage or server.
|
|
94
|
+
*
|
|
95
|
+
* @param state Serialized state object
|
|
96
|
+
*/
|
|
97
|
+
loadState(state: Record<string, Record<string, any>>): void;
|
|
98
|
+
/**
|
|
99
|
+
* Clears all tool state for a specific element.
|
|
100
|
+
*
|
|
101
|
+
* @param globalElementId Composite key identifying the element
|
|
102
|
+
*/
|
|
103
|
+
clearElement(globalElementId: string): void;
|
|
104
|
+
/**
|
|
105
|
+
* Clears state for a specific tool across all elements.
|
|
106
|
+
* Useful when disabling a tool globally.
|
|
107
|
+
*
|
|
108
|
+
* @param toolId Tool identifier
|
|
109
|
+
*/
|
|
110
|
+
clearTool(toolId: string): void;
|
|
111
|
+
/**
|
|
112
|
+
* Clears all tool state for a specific section.
|
|
113
|
+
* Useful when unmounting/disposing a section.
|
|
114
|
+
*
|
|
115
|
+
* @param assessmentId Assessment identifier
|
|
116
|
+
* @param sectionId Section identifier
|
|
117
|
+
*/
|
|
118
|
+
clearSection(assessmentId: string, sectionId: string): void;
|
|
119
|
+
/**
|
|
120
|
+
* Clears all tool state.
|
|
121
|
+
* Useful when switching between assessments or demos.
|
|
122
|
+
*/
|
|
123
|
+
clearAll(): void;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=ElementToolStateStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ElementToolStateStore.d.ts","sourceRoot":"","sources":["../../src/services/ElementToolStateStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,mBAAmB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,qBAAqB;IACjC,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,SAAS,CAA6D;IAC9E,OAAO,CAAC,aAAa,CAEN;IAEf;;;;;;;OAOG;IACH,kBAAkB,CACjB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GACf,MAAM;IAIT;;;;;;OAMG;IACH,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI;IAWzE;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAWnE;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAIlE;;;;;OAKG;IACH,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAM7D;;;;;OAKG;IACH,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAQlD;;;;;;OAMG;IACH,SAAS,CACR,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,GACtD,MAAM,IAAI;IAKb,OAAO,CAAC,gBAAgB;IAMxB;;;;;OAKG;IACH,gBAAgB,CACf,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,GAC5D,IAAI;IAIP,OAAO,CAAC,kBAAkB;IAM1B;;;;;OAKG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI;IAS3D;;;;OAIG;IACH,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI;IAM3C;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ/B;;;;;;OAMG;IACH,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAe3D;;;OAGG;IACH,QAAQ,IAAI,IAAI;CAKhB"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ElementToolStateStore - Manages element-level ephemeral tool state
|
|
3
|
+
*
|
|
4
|
+
* Provides centralized storage for UI tool state (answer eliminations, flags, etc.)
|
|
5
|
+
* that should NOT be sent to the server for scoring. Each element is uniquely identified
|
|
6
|
+
* across the entire assessment using composite keys.
|
|
7
|
+
*
|
|
8
|
+
* Key features:
|
|
9
|
+
* - Element-level granularity (not item-level)
|
|
10
|
+
* - Composite keys for global uniqueness: `assessmentId:sectionId:itemId:elementId`
|
|
11
|
+
* - Cross-section state persistence
|
|
12
|
+
* - Reactive subscriptions
|
|
13
|
+
* - Optional persistence callback integration
|
|
14
|
+
* - Generic solution for any tool
|
|
15
|
+
*/
|
|
16
|
+
export class ElementToolStateStore {
|
|
17
|
+
elementStates = new Map();
|
|
18
|
+
listeners = new Set();
|
|
19
|
+
onStateChange = null;
|
|
20
|
+
/**
|
|
21
|
+
* Generates a globally unique element ID by combining assessment, section, item, and element IDs.
|
|
22
|
+
* Format: `${assessmentId}:${sectionId}:${itemId}:${elementId}`
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* getGlobalElementId('demo-assessment', 'section-1', 'q1', 'mc1')
|
|
26
|
+
* // Returns: "demo-assessment:section-1:q1:mc1"
|
|
27
|
+
*/
|
|
28
|
+
getGlobalElementId(assessmentId, sectionId, itemId, elementId) {
|
|
29
|
+
return `${assessmentId}:${sectionId}:${itemId}:${elementId}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parses a global element ID into its component parts.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* parseGlobalElementId('demo-assessment:section-1:q1:mc1')
|
|
36
|
+
* // Returns: { assessmentId: 'demo-assessment', sectionId: 'section-1', itemId: 'q1', elementId: 'mc1' }
|
|
37
|
+
*/
|
|
38
|
+
parseGlobalElementId(globalElementId) {
|
|
39
|
+
const parts = globalElementId.split(":");
|
|
40
|
+
if (parts.length !== 4)
|
|
41
|
+
return null;
|
|
42
|
+
return {
|
|
43
|
+
assessmentId: parts[0],
|
|
44
|
+
sectionId: parts[1],
|
|
45
|
+
itemId: parts[2],
|
|
46
|
+
elementId: parts[3],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Sets tool state for a specific element.
|
|
51
|
+
* Notifies all subscribers and triggers persistence callback.
|
|
52
|
+
*
|
|
53
|
+
* @param globalElementId Composite key identifying the element
|
|
54
|
+
* @param toolId Tool identifier (e.g., 'answerEliminator', 'flagging')
|
|
55
|
+
* @param state Tool-specific state object
|
|
56
|
+
*/
|
|
57
|
+
setState(globalElementId, toolId, state) {
|
|
58
|
+
let elementState = this.elementStates.get(globalElementId);
|
|
59
|
+
if (!elementState) {
|
|
60
|
+
elementState = new Map();
|
|
61
|
+
this.elementStates.set(globalElementId, elementState);
|
|
62
|
+
}
|
|
63
|
+
elementState.set(toolId, state);
|
|
64
|
+
this._notifyListeners();
|
|
65
|
+
this._notifyStateChange();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Gets tool state for a specific element.
|
|
69
|
+
*
|
|
70
|
+
* @param globalElementId Composite key identifying the element
|
|
71
|
+
* @param toolId Tool identifier
|
|
72
|
+
* @returns Tool state or undefined if not found
|
|
73
|
+
*/
|
|
74
|
+
getState(globalElementId, toolId) {
|
|
75
|
+
return this.elementStates.get(globalElementId)?.get(toolId);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Gets all tool states for a specific element.
|
|
79
|
+
*
|
|
80
|
+
* @param globalElementId Composite key identifying the element
|
|
81
|
+
* @returns Object with tool states keyed by toolId
|
|
82
|
+
*/
|
|
83
|
+
getElementState(globalElementId) {
|
|
84
|
+
const elementState = this.elementStates.get(globalElementId);
|
|
85
|
+
if (!elementState)
|
|
86
|
+
return {};
|
|
87
|
+
return Object.fromEntries(elementState.entries());
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Gets all tool states for all elements.
|
|
91
|
+
* Used for persistence and debugging.
|
|
92
|
+
*
|
|
93
|
+
* @returns Nested object: { globalElementId: { toolId: state } }
|
|
94
|
+
*/
|
|
95
|
+
getAllState() {
|
|
96
|
+
const result = {};
|
|
97
|
+
for (const [globalElementId, toolStates] of this.elementStates.entries()) {
|
|
98
|
+
result[globalElementId] = Object.fromEntries(toolStates.entries());
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Subscribes to state changes.
|
|
104
|
+
* Callback is invoked whenever any element's tool state changes.
|
|
105
|
+
*
|
|
106
|
+
* @param callback Function to call on state changes
|
|
107
|
+
* @returns Unsubscribe function
|
|
108
|
+
*/
|
|
109
|
+
subscribe(callback) {
|
|
110
|
+
this.listeners.add(callback);
|
|
111
|
+
return () => this.listeners.delete(callback);
|
|
112
|
+
}
|
|
113
|
+
_notifyListeners() {
|
|
114
|
+
for (const listener of this.listeners) {
|
|
115
|
+
listener(this.elementStates);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Sets a callback to be invoked on state changes for persistence integration.
|
|
120
|
+
* Used by demo/app layer to persist tool state to localStorage or server.
|
|
121
|
+
*
|
|
122
|
+
* @param callback Function to call with serialized state on changes
|
|
123
|
+
*/
|
|
124
|
+
setOnStateChange(callback) {
|
|
125
|
+
this.onStateChange = callback;
|
|
126
|
+
}
|
|
127
|
+
_notifyStateChange() {
|
|
128
|
+
if (this.onStateChange) {
|
|
129
|
+
this.onStateChange(this.getAllState());
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Loads tool state from serialized format.
|
|
134
|
+
* Used to restore state from localStorage or server.
|
|
135
|
+
*
|
|
136
|
+
* @param state Serialized state object
|
|
137
|
+
*/
|
|
138
|
+
loadState(state) {
|
|
139
|
+
this.elementStates.clear();
|
|
140
|
+
for (const [globalElementId, toolStates] of Object.entries(state)) {
|
|
141
|
+
const elementState = new Map(Object.entries(toolStates));
|
|
142
|
+
this.elementStates.set(globalElementId, elementState);
|
|
143
|
+
}
|
|
144
|
+
this._notifyListeners();
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Clears all tool state for a specific element.
|
|
148
|
+
*
|
|
149
|
+
* @param globalElementId Composite key identifying the element
|
|
150
|
+
*/
|
|
151
|
+
clearElement(globalElementId) {
|
|
152
|
+
this.elementStates.delete(globalElementId);
|
|
153
|
+
this._notifyListeners();
|
|
154
|
+
this._notifyStateChange();
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Clears state for a specific tool across all elements.
|
|
158
|
+
* Useful when disabling a tool globally.
|
|
159
|
+
*
|
|
160
|
+
* @param toolId Tool identifier
|
|
161
|
+
*/
|
|
162
|
+
clearTool(toolId) {
|
|
163
|
+
for (const elementState of this.elementStates.values()) {
|
|
164
|
+
elementState.delete(toolId);
|
|
165
|
+
}
|
|
166
|
+
this._notifyListeners();
|
|
167
|
+
this._notifyStateChange();
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Clears all tool state for a specific section.
|
|
171
|
+
* Useful when unmounting/disposing a section.
|
|
172
|
+
*
|
|
173
|
+
* @param assessmentId Assessment identifier
|
|
174
|
+
* @param sectionId Section identifier
|
|
175
|
+
*/
|
|
176
|
+
clearSection(assessmentId, sectionId) {
|
|
177
|
+
const prefix = `${assessmentId}:${sectionId}:`;
|
|
178
|
+
const keysToDelete = [];
|
|
179
|
+
for (const key of this.elementStates.keys()) {
|
|
180
|
+
if (key.startsWith(prefix)) {
|
|
181
|
+
keysToDelete.push(key);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
for (const key of keysToDelete) {
|
|
185
|
+
this.elementStates.delete(key);
|
|
186
|
+
}
|
|
187
|
+
this._notifyListeners();
|
|
188
|
+
this._notifyStateChange();
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Clears all tool state.
|
|
192
|
+
* Useful when switching between assessments or demos.
|
|
193
|
+
*/
|
|
194
|
+
clearAll() {
|
|
195
|
+
this.elementStates.clear();
|
|
196
|
+
this._notifyListeners();
|
|
197
|
+
this._notifyStateChange();
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=ElementToolStateStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ElementToolStateStore.js","sourceRoot":"","sources":["../../src/services/ElementToolStateStore.ts"],"names":[],"mappings":"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"}
|