@pie-players/pie-assessment-toolkit 0.3.30 → 0.3.31
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 +289 -5
- package/dist/components/ItemToolBar.custom-element.js +165 -92
- package/dist/components/PieAssessmentToolkit.custom-element.js +604 -107
- package/dist/components/SectionToolBar.custom-element.js +0 -36
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/policy/core/PolicySource.d.ts +64 -0
- package/dist/policy/core/PolicySource.d.ts.map +1 -0
- package/dist/policy/core/PolicySource.js +17 -0
- package/dist/policy/core/PolicySource.js.map +1 -0
- package/dist/policy/core/ToolPolicyEngine.d.ts +123 -0
- package/dist/policy/core/ToolPolicyEngine.d.ts.map +1 -0
- package/dist/policy/core/ToolPolicyEngine.js +217 -0
- package/dist/policy/core/ToolPolicyEngine.js.map +1 -0
- package/dist/policy/core/compose-decision.d.ts +37 -0
- package/dist/policy/core/compose-decision.d.ts.map +1 -0
- package/dist/policy/core/compose-decision.js +332 -0
- package/dist/policy/core/compose-decision.js.map +1 -0
- package/dist/policy/core/decision-types.d.ts +142 -0
- package/dist/policy/core/decision-types.d.ts.map +1 -0
- package/dist/policy/core/decision-types.js +13 -0
- package/dist/policy/core/decision-types.js.map +1 -0
- package/dist/policy/core/engine-context.d.ts +30 -0
- package/dist/policy/core/engine-context.d.ts.map +1 -0
- package/dist/policy/core/engine-context.js +28 -0
- package/dist/policy/core/engine-context.js.map +1 -0
- package/dist/policy/core/policy-source-tag.d.ts +32 -0
- package/dist/policy/core/policy-source-tag.d.ts.map +1 -0
- package/dist/policy/core/policy-source-tag.js +29 -0
- package/dist/policy/core/policy-source-tag.js.map +1 -0
- package/dist/policy/core/provenance.d.ts +163 -0
- package/dist/policy/core/provenance.d.ts.map +1 -0
- package/dist/policy/core/provenance.js +232 -0
- package/dist/policy/core/provenance.js.map +1 -0
- package/dist/policy/core/qti-inputs.d.ts +67 -0
- package/dist/policy/core/qti-inputs.d.ts.map +1 -0
- package/dist/policy/core/qti-inputs.js +139 -0
- package/dist/policy/core/qti-inputs.js.map +1 -0
- package/dist/policy/engine.d.ts +28 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +24 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/internal.d.ts +26 -0
- package/dist/policy/internal.d.ts.map +1 -0
- package/dist/policy/internal.js +26 -0
- package/dist/policy/internal.js.map +1 -0
- package/dist/policy/sources/QtiPolicySource.d.ts +146 -0
- package/dist/policy/sources/QtiPolicySource.d.ts.map +1 -0
- package/dist/policy/sources/QtiPolicySource.js +270 -0
- package/dist/policy/sources/QtiPolicySource.js.map +1 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +145 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts.map +1 -1
- package/dist/runtime/SectionRuntimeEngine.js +164 -3
- package/dist/runtime/SectionRuntimeEngine.js.map +1 -1
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts +144 -0
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts.map +1 -0
- package/dist/runtime/adapter/SectionEngineAdapter.js +183 -0
- package/dist/runtime/adapter/SectionEngineAdapter.js.map +1 -0
- package/dist/runtime/adapter/coordinator-bridge.d.ts +93 -0
- package/dist/runtime/adapter/coordinator-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/coordinator-bridge.js +127 -0
- package/dist/runtime/adapter/coordinator-bridge.js.map +1 -0
- package/dist/runtime/adapter/dom-event-bridge.d.ts +63 -0
- package/dist/runtime/adapter/dom-event-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/dom-event-bridge.js +95 -0
- package/dist/runtime/adapter/dom-event-bridge.js.map +1 -0
- package/dist/runtime/adapter/framework-error-bridge.d.ts +37 -0
- package/dist/runtime/adapter/framework-error-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/framework-error-bridge.js +47 -0
- package/dist/runtime/adapter/framework-error-bridge.js.map +1 -0
- package/dist/runtime/adapter/instrumentation-bridge.d.ts +32 -0
- package/dist/runtime/adapter/instrumentation-bridge.d.ts.map +1 -0
- package/dist/runtime/adapter/instrumentation-bridge.js +39 -0
- package/dist/runtime/adapter/instrumentation-bridge.js.map +1 -0
- package/dist/runtime/adapter/subscriber-fanout.d.ts +35 -0
- package/dist/runtime/adapter/subscriber-fanout.d.ts.map +1 -0
- package/dist/runtime/adapter/subscriber-fanout.js +60 -0
- package/dist/runtime/adapter/subscriber-fanout.js.map +1 -0
- package/dist/runtime/core/SectionEngineCore.d.ts +52 -0
- package/dist/runtime/core/SectionEngineCore.d.ts.map +1 -0
- package/dist/runtime/core/SectionEngineCore.js +81 -0
- package/dist/runtime/core/SectionEngineCore.js.map +1 -0
- package/dist/runtime/core/cohort.d.ts +40 -0
- package/dist/runtime/core/cohort.d.ts.map +1 -0
- package/dist/runtime/core/cohort.js +49 -0
- package/dist/runtime/core/cohort.js.map +1 -0
- package/dist/runtime/core/engine-input.d.ts +114 -0
- package/dist/runtime/core/engine-input.d.ts.map +1 -0
- package/dist/runtime/core/engine-input.js +19 -0
- package/dist/runtime/core/engine-input.js.map +1 -0
- package/dist/runtime/core/engine-output.d.ts +62 -0
- package/dist/runtime/core/engine-output.d.ts.map +1 -0
- package/dist/runtime/core/engine-output.js +27 -0
- package/dist/runtime/core/engine-output.js.map +1 -0
- package/dist/runtime/core/engine-readiness.d.ts +49 -0
- package/dist/runtime/core/engine-readiness.d.ts.map +1 -0
- package/dist/runtime/core/engine-readiness.js +47 -0
- package/dist/runtime/core/engine-readiness.js.map +1 -0
- package/dist/runtime/core/engine-resolver.d.ts +172 -0
- package/dist/runtime/core/engine-resolver.d.ts.map +1 -0
- package/dist/runtime/core/engine-resolver.js +170 -0
- package/dist/runtime/core/engine-resolver.js.map +1 -0
- package/dist/runtime/core/engine-stage-derivation.d.ts +19 -0
- package/dist/runtime/core/engine-stage-derivation.d.ts.map +1 -0
- package/dist/runtime/core/engine-stage-derivation.js +30 -0
- package/dist/runtime/core/engine-stage-derivation.js.map +1 -0
- package/dist/runtime/core/engine-state.d.ts +83 -0
- package/dist/runtime/core/engine-state.d.ts.map +1 -0
- package/dist/runtime/core/engine-state.js +49 -0
- package/dist/runtime/core/engine-state.js.map +1 -0
- package/dist/runtime/core/engine-transition.d.ts +49 -0
- package/dist/runtime/core/engine-transition.d.ts.map +1 -0
- package/dist/runtime/core/engine-transition.js +261 -0
- package/dist/runtime/core/engine-transition.js.map +1 -0
- package/dist/runtime/engine-context.d.ts +40 -0
- package/dist/runtime/engine-context.d.ts.map +1 -0
- package/dist/runtime/engine-context.js +32 -0
- package/dist/runtime/engine-context.js.map +1 -0
- package/dist/runtime/engine.d.ts +24 -0
- package/dist/runtime/engine.d.ts.map +1 -0
- package/dist/runtime/engine.js +24 -0
- package/dist/runtime/engine.js.map +1 -0
- package/dist/runtime/internal.d.ts +44 -0
- package/dist/runtime/internal.d.ts.map +1 -0
- package/dist/runtime/internal.js +46 -0
- package/dist/runtime/internal.js.map +1 -0
- package/dist/runtime/runtime-id.d.ts +8 -0
- package/dist/runtime/runtime-id.d.ts.map +1 -0
- package/dist/runtime/runtime-id.js +10 -0
- package/dist/runtime/runtime-id.js.map +1 -0
- package/dist/runtime/section-runtime-engine-host-context.d.ts +74 -0
- package/dist/runtime/section-runtime-engine-host-context.d.ts.map +1 -0
- package/dist/runtime/section-runtime-engine-host-context.js +96 -0
- package/dist/runtime/section-runtime-engine-host-context.js.map +1 -0
- package/dist/runtime/stage-emit-gate.d.ts +93 -0
- package/dist/runtime/stage-emit-gate.d.ts.map +1 -0
- package/dist/runtime/stage-emit-gate.js +83 -0
- package/dist/runtime/stage-emit-gate.js.map +1 -0
- package/dist/services/ToolkitCoordinator.d.ts +264 -6
- package/dist/services/ToolkitCoordinator.d.ts.map +1 -1
- package/dist/services/ToolkitCoordinator.js +350 -32
- package/dist/services/ToolkitCoordinator.js.map +1 -1
- package/dist/services/framework-error-bus.d.ts +73 -0
- package/dist/services/framework-error-bus.d.ts.map +1 -0
- package/dist/services/framework-error-bus.js +68 -0
- package/dist/services/framework-error-bus.js.map +1 -0
- package/dist/services/framework-error.d.ts +36 -1
- package/dist/services/framework-error.d.ts.map +1 -1
- package/dist/services/framework-error.js +37 -0
- package/dist/services/framework-error.js.map +1 -1
- package/dist/services/interfaces.d.ts +78 -0
- package/dist/services/interfaces.d.ts.map +1 -1
- package/dist/services/interfaces.js.map +1 -1
- package/dist/services/tools-config-normalizer.d.ts +23 -0
- package/dist/services/tools-config-normalizer.d.ts.map +1 -1
- package/dist/services/tools-config-normalizer.js +13 -1
- package/dist/services/tools-config-normalizer.js.map +1 -1
- package/dist/tools/client.d.ts +0 -1
- package/dist/tools/client.d.ts.map +1 -1
- package/dist/tools/client.js +0 -2
- package/dist/tools/client.js.map +1 -1
- package/dist/tools/types.d.ts +0 -26
- package/dist/tools/types.d.ts.map +1 -1
- package/package.json +23 -7
- package/dist/runtime/runtime-event-guards.d.ts +0 -2
- package/dist/runtime/runtime-event-guards.d.ts.map +0 -1
- package/dist/runtime/runtime-event-guards.js +0 -4
- package/dist/runtime/runtime-event-guards.js.map +0 -1
- package/dist/tools/tool-coordinator.d.ts +0 -72
- package/dist/tools/tool-coordinator.d.ts.map +0 -1
- package/dist/tools/tool-coordinator.js +0 -194
- package/dist/tools/tool-coordinator.js.map +0 -1
- package/dist/types/events.d.ts +0 -157
- package/dist/types/events.d.ts.map +0 -1
- package/dist/types/events.js +0 -11
- package/dist/types/events.js.map +0 -1
|
@@ -33,7 +33,7 @@ import { sanitizeSvgIcon } from '@pie-players/pie-players-shared/security';
|
|
|
33
33
|
import { createFocusTrap } from '@pie-players/pie-players-shared';
|
|
34
34
|
import { createPackagedToolRegistry } from '../services/createDefaultToolRegistry.js';
|
|
35
35
|
import { DEFAULT_TOOL_MODULE_LOADERS } from '../tools/default-tool-module-loaders.js';
|
|
36
|
-
import {
|
|
36
|
+
import { parseToolList } from '../services/tools-config-normalizer.js';
|
|
37
37
|
import { createScopedToolId, parseScopedToolId } from '../services/tool-instance-id.js';
|
|
38
38
|
|
|
39
39
|
var root_4 = $.from_html(`<span class="item-toolbar__element-host svelte-rnx3ie"></span>`);
|
|
@@ -79,9 +79,6 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
79
79
|
position = $.prop($$props, 'position', 7, 'bottom'),
|
|
80
80
|
scopeElement = $.prop($$props, 'scopeElement', 7, null),
|
|
81
81
|
toolRegistry = $.prop($$props, 'toolRegistry', 7, null),
|
|
82
|
-
pnpResolver = $.prop($$props, 'pnpResolver', 7, null),
|
|
83
|
-
assessment = $.prop($$props, 'assessment', 7, null),
|
|
84
|
-
itemRef = $.prop($$props, 'itemRef', 7, null),
|
|
85
82
|
item = $.prop($$props, 'item', 7, null),
|
|
86
83
|
hostButtons = $.prop($$props, 'hostButtons', 23, () => []),
|
|
87
84
|
className = $.prop($$props, 'class', 7, ''),
|
|
@@ -93,6 +90,14 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
93
90
|
let shellContext = $.state(null);
|
|
94
91
|
let moduleLoadVersion = $.state(0);
|
|
95
92
|
|
|
93
|
+
// Bumped from `coordinator.onPolicyChange(...)` so the engine-driven
|
|
94
|
+
// `policyDecision` / `policyInputs` derivations rerun on input
|
|
95
|
+
// changes (`updateAssessment`, `setQtiEnforcement`, custom source
|
|
96
|
+
// register / remove). The decision itself is computed by the
|
|
97
|
+
// coordinator's policy engine — this counter is just the reactive
|
|
98
|
+
// fanout that lets Svelte know the engine answer may have changed.
|
|
99
|
+
let policyChangeVersion = $.state(0);
|
|
100
|
+
|
|
96
101
|
$.user_effect(() => {
|
|
97
102
|
if (!$.get(toolbarRootElement)) return;
|
|
98
103
|
|
|
@@ -109,6 +114,25 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
109
114
|
});
|
|
110
115
|
});
|
|
111
116
|
|
|
117
|
+
$.user_effect(() => {
|
|
118
|
+
const coord = $.get(runtimeContext)?.toolkitCoordinator;
|
|
119
|
+
|
|
120
|
+
if (!coord || typeof coord.onPolicyChange !== 'function') return;
|
|
121
|
+
|
|
122
|
+
const unsubscribe = coord.onPolicyChange(() => {
|
|
123
|
+
$.set(policyChangeVersion, $.get(policyChangeVersion) + 1);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
return () => {
|
|
127
|
+
try {
|
|
128
|
+
unsubscribe?.();
|
|
129
|
+
} catch {
|
|
130
|
+
// detach errors are non-fatal: the coordinator may already
|
|
131
|
+
// be torn down, in which case the listener set is GC-eligible.
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
|
|
112
136
|
const effectiveToolCoordinator = $.derived(() => $.get(runtimeContext)?.toolCoordinator);
|
|
113
137
|
const effectiveTTSService = $.derived(() => $.get(runtimeContext)?.ttsService);
|
|
114
138
|
const effectiveElementToolStateStore = $.derived(() => $.get(runtimeContext)?.elementToolStateStore);
|
|
@@ -142,12 +166,6 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
142
166
|
const explicitTools = $.derived(() => parseToolList(tools()));
|
|
143
167
|
const normalizedExplicitTools = $.derived(() => $.get(effectiveToolRegistry).normalizeToolIds($.get(explicitTools)).filter(Boolean));
|
|
144
168
|
|
|
145
|
-
const effectiveToolsConfig = $.derived(() => {
|
|
146
|
-
const coordinatorConfig = $.get(runtimeContext)?.toolkitCoordinator?.config?.tools;
|
|
147
|
-
|
|
148
|
-
return normalizeToolsConfig(coordinatorConfig || {});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
169
|
const placementLevel = $.derived(() => {
|
|
152
170
|
if ($.get(effectiveLevel) === 'section') return 'section';
|
|
153
171
|
if ($.get(effectiveLevel) === 'passage' || $.get(effectiveContentKind) === 'rubric-block-stimulus') return 'passage';
|
|
@@ -155,48 +173,58 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
155
173
|
return 'item';
|
|
156
174
|
});
|
|
157
175
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
176
|
+
// Pass 1 — single source of truth via the ToolPolicyEngine
|
|
177
|
+
// (M8 PR 3). When the toolbar is mounted under
|
|
178
|
+
// `<pie-assessment-toolkit>` the coordinator owns the engine and
|
|
179
|
+
// applies `placement → policy.allowed → policy.blocked →
|
|
180
|
+
// providers → QTI` plus any custom `PolicySource`s the host has
|
|
181
|
+
// registered. The toolbar trusts that decision verbatim — the
|
|
182
|
+
// `tools=` prop is *not* applied as a downstream filter.
|
|
183
|
+
//
|
|
184
|
+
// The `tools=` attribute is only consulted in the standalone
|
|
185
|
+
// fallback path (no coordinator in scope, e.g. fixtures that
|
|
186
|
+
// mount `<pie-item-toolbar>` directly). Hosts that want to
|
|
187
|
+
// restrict the engine's visible set should configure
|
|
188
|
+
// `tools.policy` / `tools.providers` on the assessment-toolkit
|
|
189
|
+
// inputs, or register a custom `PolicySource`, rather than
|
|
190
|
+
// passing `tools=` here.
|
|
191
|
+
const policyDecision = $.derived(() => {
|
|
192
|
+
// Read `policyChangeVersion` so we re-derive whenever the
|
|
193
|
+
// coordinator emits a policy change (assessment binding,
|
|
194
|
+
// QTI enforcement override, custom source registration).
|
|
195
|
+
void $.get(policyChangeVersion);
|
|
196
|
+
|
|
197
|
+
const coord = $.get(runtimeContext)?.toolkitCoordinator;
|
|
198
|
+
|
|
199
|
+
if (!coord || typeof coord.decideToolPolicy !== 'function') {
|
|
200
|
+
return null;
|
|
175
201
|
}
|
|
176
202
|
|
|
177
|
-
return
|
|
203
|
+
return coord.decideToolPolicy({
|
|
204
|
+
level: $.get(placementLevel),
|
|
205
|
+
scope: {
|
|
206
|
+
level: $.get(effectiveLevel),
|
|
207
|
+
scopeId: $.get(effectiveScopeId),
|
|
208
|
+
assessmentId: $.get(runtimeContext)?.assessmentId,
|
|
209
|
+
sectionId: $.get(effectiveSectionId) || undefined,
|
|
210
|
+
itemId: $.get(effectiveItemId) || undefined,
|
|
211
|
+
canonicalItemId: $.get(effectiveCanonicalItemId) || undefined,
|
|
212
|
+
contentKind: $.get(effectiveContentKind)
|
|
213
|
+
}
|
|
214
|
+
});
|
|
178
215
|
});
|
|
179
216
|
|
|
180
|
-
const isProviderEnabled = (toolId) => $.get(normalizedProviderConfig)[toolId]?.enabled !== false;
|
|
181
|
-
|
|
182
|
-
// Pass 1: determine allowed tools
|
|
183
217
|
const allowedToolIds = $.derived(() => {
|
|
184
|
-
const configuredTools = $.get(normalizedExplicitTools).length > 0
|
|
185
|
-
? $.get(normalizedExplicitTools)
|
|
186
|
-
: $.get(placementAllowedToolIds);
|
|
187
|
-
|
|
188
|
-
const providerEnabledConfiguredTools = configuredTools.filter((toolId) => isProviderEnabled(toolId));
|
|
189
218
|
const dedupe = (toolIds) => Array.from(new Set(toolIds));
|
|
190
219
|
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (providerEnabledConfiguredTools.length === 0) return allowedByPnp;
|
|
195
|
-
|
|
196
|
-
return dedupe(allowedByPnp.filter((toolId) => providerEnabledConfiguredTools.includes(toolId)));
|
|
220
|
+
if ($.get(policyDecision)) {
|
|
221
|
+
return dedupe($.get(effectiveToolRegistry).normalizeToolIds($.get(policyDecision).visibleTools.map((entry) => entry.toolId)).filter(Boolean));
|
|
197
222
|
}
|
|
198
223
|
|
|
199
|
-
|
|
224
|
+
// Standalone fallback: no coordinator in scope. Honour the
|
|
225
|
+
// explicit `tools=` prop verbatim so demo fixtures keep
|
|
226
|
+
// working without a `<pie-assessment-toolkit>` ancestor.
|
|
227
|
+
return dedupe($.get(normalizedExplicitTools));
|
|
200
228
|
});
|
|
201
229
|
|
|
202
230
|
const contentReady = $.derived(() => {
|
|
@@ -207,17 +235,41 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
207
235
|
return !!($.get(effectiveItem) && config && typeof config === 'object');
|
|
208
236
|
});
|
|
209
237
|
|
|
238
|
+
// QTI inputs (`assessment`, `currentItemRef`) live on the
|
|
239
|
+
// coordinator after M8 PR 2; the toolbar reads them through
|
|
240
|
+
// `getPolicyInputs()` so it can build the correct Pass-2 context
|
|
241
|
+
// without re-binding props. Standalone (no-coordinator) usage
|
|
242
|
+
// falls back to the empty / canonical-id-derived contexts that
|
|
243
|
+
// satisfy the `ToolContext` shape for `isVisibleInContext` calls.
|
|
244
|
+
const policyInputs = $.derived(() => {
|
|
245
|
+
void $.get(policyChangeVersion);
|
|
246
|
+
|
|
247
|
+
const coord = $.get(runtimeContext)?.toolkitCoordinator;
|
|
248
|
+
|
|
249
|
+
if (!coord || typeof coord.getPolicyInputs !== 'function') {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return coord.getPolicyInputs();
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const effectiveAssessment = $.derived(() => $.get(policyInputs)?.assessment ?? null);
|
|
257
|
+
const effectiveItemRef = $.derived(() => $.get(policyInputs)?.currentItemRef ?? null);
|
|
258
|
+
|
|
210
259
|
const toolContext = $.derived(() => {
|
|
211
260
|
if ($.get(effectiveLevel) === 'section') {
|
|
212
261
|
return {
|
|
213
262
|
level: 'section',
|
|
214
|
-
assessment:
|
|
263
|
+
assessment: $.get(effectiveAssessment) || {},
|
|
215
264
|
section: {}
|
|
216
265
|
};
|
|
217
266
|
}
|
|
218
267
|
|
|
219
268
|
if ($.get(effectiveLevel) === 'assessment') {
|
|
220
|
-
return {
|
|
269
|
+
return {
|
|
270
|
+
level: 'assessment',
|
|
271
|
+
assessment: $.get(effectiveAssessment) || {}
|
|
272
|
+
};
|
|
221
273
|
}
|
|
222
274
|
|
|
223
275
|
if (!$.get(contentReady) || !$.get(effectiveItem)) {
|
|
@@ -227,16 +279,16 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
227
279
|
if ($.get(effectiveLevel) === 'passage') {
|
|
228
280
|
return {
|
|
229
281
|
level: 'passage',
|
|
230
|
-
assessment:
|
|
231
|
-
itemRef:
|
|
282
|
+
assessment: $.get(effectiveAssessment) || {},
|
|
283
|
+
itemRef: $.get(effectiveItemRef) || { id: $.get(effectiveCanonicalItemId) },
|
|
232
284
|
passage: $.get(effectiveItem)
|
|
233
285
|
};
|
|
234
286
|
}
|
|
235
287
|
|
|
236
288
|
return {
|
|
237
289
|
level: 'item',
|
|
238
|
-
assessment:
|
|
239
|
-
itemRef:
|
|
290
|
+
assessment: $.get(effectiveAssessment) || {},
|
|
291
|
+
itemRef: $.get(effectiveItemRef) || { id: $.get(effectiveCanonicalItemId) },
|
|
240
292
|
item: $.get(effectiveItem)
|
|
241
293
|
};
|
|
242
294
|
});
|
|
@@ -246,8 +298,8 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
246
298
|
|
|
247
299
|
return {
|
|
248
300
|
level: 'item',
|
|
249
|
-
assessment:
|
|
250
|
-
itemRef:
|
|
301
|
+
assessment: $.get(effectiveAssessment) || {},
|
|
302
|
+
itemRef: $.get(effectiveItemRef) || { id: $.get(effectiveCanonicalItemId) },
|
|
251
303
|
item: $.get(effectiveItem) || { id: $.get(effectiveCanonicalItemId), config: {} }
|
|
252
304
|
};
|
|
253
305
|
});
|
|
@@ -264,8 +316,8 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
264
316
|
|
|
265
317
|
return models.filter((model) => model && typeof model === 'object' && typeof model.id === 'string').map((model) => ({
|
|
266
318
|
level: 'element',
|
|
267
|
-
assessment:
|
|
268
|
-
itemRef:
|
|
319
|
+
assessment: $.get(effectiveAssessment) || {},
|
|
320
|
+
itemRef: $.get(effectiveItemRef) || { id: $.get(effectiveCanonicalItemId) },
|
|
269
321
|
item: $.get(effectiveItem),
|
|
270
322
|
elementId: model.id
|
|
271
323
|
}));
|
|
@@ -539,12 +591,32 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
539
591
|
|
|
540
592
|
for (const renderedTool of $.get(renderedTools)) {
|
|
541
593
|
if (renderedTool.subscribeActive) {
|
|
594
|
+
let disposed = false;
|
|
595
|
+
|
|
542
596
|
const unsubscribe = renderedTool.subscribeActive((active) => {
|
|
543
|
-
|
|
544
|
-
|
|
597
|
+
// Tools may dispatch their active-change signal from inside
|
|
598
|
+
// a tracked Svelte $effect (e.g. tool-tts-inline does this
|
|
599
|
+
// on mount). When the toolbar synchronously creates / re-
|
|
600
|
+
// connects the tool element during its own template/
|
|
601
|
+
// derivation pass — for example when the section player
|
|
602
|
+
// collapses on resize — that dispatch lands back here while
|
|
603
|
+
// our parent derivation is still running, and Svelte
|
|
604
|
+
// rejects the `activeToolState` write with
|
|
605
|
+
// `state_unsafe_mutation`. Queue the update on a
|
|
606
|
+
// microtask so the mutation happens after the current
|
|
607
|
+
// reactive flush settles.
|
|
608
|
+
queueMicrotask(() => {
|
|
609
|
+
if (disposed) return;
|
|
610
|
+
|
|
611
|
+
$.set(activeToolState, { ...$.get(activeToolState), [renderedTool.toolId]: active }, true);
|
|
612
|
+
renderedTool.sync?.();
|
|
613
|
+
});
|
|
545
614
|
});
|
|
546
615
|
|
|
547
|
-
unsubs.push(
|
|
616
|
+
unsubs.push(() => {
|
|
617
|
+
disposed = true;
|
|
618
|
+
unsubscribe();
|
|
619
|
+
});
|
|
548
620
|
}
|
|
549
621
|
}
|
|
550
622
|
|
|
@@ -556,9 +628,25 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
556
628
|
$.user_effect(() => {
|
|
557
629
|
if (!$.get(toolbarContext).subscribeVisibility) return;
|
|
558
630
|
|
|
559
|
-
|
|
560
|
-
|
|
631
|
+
let disposed = false;
|
|
632
|
+
|
|
633
|
+
const unsubscribe = $.get(toolbarContext).subscribeVisibility(() => {
|
|
634
|
+
// Defense-in-depth: defer the state write so a synchronous
|
|
635
|
+
// visibility broadcast from the coordinator never lands inside
|
|
636
|
+
// an active parent derivation/template flush. See the
|
|
637
|
+
// `subscribeActive` handler above for the failure mode this
|
|
638
|
+
// pattern prevents.
|
|
639
|
+
queueMicrotask(() => {
|
|
640
|
+
if (disposed) return;
|
|
641
|
+
|
|
642
|
+
syncRenderedToolsState();
|
|
643
|
+
});
|
|
561
644
|
});
|
|
645
|
+
|
|
646
|
+
return () => {
|
|
647
|
+
disposed = true;
|
|
648
|
+
unsubscribe?.();
|
|
649
|
+
};
|
|
562
650
|
});
|
|
563
651
|
|
|
564
652
|
$.user_effect(() => {
|
|
@@ -566,13 +654,28 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
566
654
|
|
|
567
655
|
if (typeof toolkitCoordinator?.subscribeTelemetry !== 'function') return;
|
|
568
656
|
|
|
569
|
-
|
|
570
|
-
|
|
657
|
+
let disposed = false;
|
|
658
|
+
|
|
659
|
+
const unsubscribe = toolkitCoordinator.subscribeTelemetry(({ eventName, payload }) => {
|
|
660
|
+
if (eventName !== 'pie-toolkit-tool-config-updated') return;
|
|
571
661
|
if (payload?.toolId && !$.get(toolbarVisibleToolIds).includes(payload.toolId)) return;
|
|
572
662
|
|
|
573
|
-
|
|
574
|
-
|
|
663
|
+
// Defense-in-depth: telemetry can be emitted from anywhere in
|
|
664
|
+
// the toolkit lifecycle, including paths that flush
|
|
665
|
+
// synchronously while this component's deriveds are running.
|
|
666
|
+
// Defer the writes so the parent flush always settles first.
|
|
667
|
+
queueMicrotask(() => {
|
|
668
|
+
if (disposed) return;
|
|
669
|
+
|
|
670
|
+
$.set(moduleLoadVersion, $.get(moduleLoadVersion) + 1);
|
|
671
|
+
syncRenderedToolsState();
|
|
672
|
+
});
|
|
575
673
|
});
|
|
674
|
+
|
|
675
|
+
return () => {
|
|
676
|
+
disposed = true;
|
|
677
|
+
unsubscribe?.();
|
|
678
|
+
};
|
|
576
679
|
});
|
|
577
680
|
|
|
578
681
|
function mountElement(node, element) {
|
|
@@ -1334,33 +1437,6 @@ export default function ItemToolBar($$anchor, $$props) {
|
|
|
1334
1437
|
$.flush();
|
|
1335
1438
|
},
|
|
1336
1439
|
|
|
1337
|
-
get pnpResolver() {
|
|
1338
|
-
return pnpResolver();
|
|
1339
|
-
},
|
|
1340
|
-
|
|
1341
|
-
set pnpResolver($$value) {
|
|
1342
|
-
pnpResolver($$value);
|
|
1343
|
-
$.flush();
|
|
1344
|
-
},
|
|
1345
|
-
|
|
1346
|
-
get assessment() {
|
|
1347
|
-
return assessment();
|
|
1348
|
-
},
|
|
1349
|
-
|
|
1350
|
-
set assessment($$value) {
|
|
1351
|
-
assessment($$value);
|
|
1352
|
-
$.flush();
|
|
1353
|
-
},
|
|
1354
|
-
|
|
1355
|
-
get itemRef() {
|
|
1356
|
-
return itemRef();
|
|
1357
|
-
},
|
|
1358
|
-
|
|
1359
|
-
set itemRef($$value) {
|
|
1360
|
-
itemRef($$value);
|
|
1361
|
-
$.flush();
|
|
1362
|
-
},
|
|
1363
|
-
|
|
1364
1440
|
get item() {
|
|
1365
1441
|
return item();
|
|
1366
1442
|
},
|
|
@@ -1796,9 +1872,6 @@ __pieDefineSafely('pie-item-toolbar', $.create_custom_element(
|
|
|
1796
1872
|
language: { attribute: 'language', type: 'String' },
|
|
1797
1873
|
scopeElement: { type: 'Object' },
|
|
1798
1874
|
toolRegistry: { type: 'Object' },
|
|
1799
|
-
pnpResolver: { type: 'Object' },
|
|
1800
|
-
assessment: { type: 'Object' },
|
|
1801
|
-
itemRef: { type: 'Object' },
|
|
1802
1875
|
item: { type: 'Object' },
|
|
1803
1876
|
hostButtons: { type: 'Object' },
|
|
1804
1877
|
class: {}
|