@pie-players/pie-assessment-toolkit 0.3.67 → 0.3.68

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.
Files changed (57) hide show
  1. package/README.md +1 -1
  2. package/dist/attempt/AssessmentSession.d.ts +7 -27
  3. package/dist/components/ItemToolBar.custom-element.js +1 -1
  4. package/dist/components/PieAssessmentToolkit.custom-element.js +13 -13
  5. package/dist/components/SectionToolBar.custom-element.js +1 -1
  6. package/dist/components/chunks/ItemToolBar-38mhtjsq.js +51 -0
  7. package/dist/components/chunks/ItemToolBar-9ymm7pd1.js +46 -0
  8. package/dist/components/item-toolbar-element.js +1 -0
  9. package/dist/components/pie-assessment-toolkit-element.js +1 -0
  10. package/dist/components/section-toolbar-element.js +1 -0
  11. package/dist/context/assessment-toolkit-context.d.ts +28 -0
  12. package/dist/index.d.ts +7 -3
  13. package/dist/index.js +4 -2
  14. package/dist/runtime/SectionRuntimeEngine.d.ts +56 -0
  15. package/dist/runtime/SectionRuntimeEngine.js +66 -1
  16. package/dist/runtime/core/engine-resolver.d.ts +25 -1
  17. package/dist/runtime/registration-events.d.ts +52 -0
  18. package/dist/runtime/registration-events.js +2 -0
  19. package/dist/services/AccessibilityCatalogResolver.js +21 -5
  20. package/dist/services/I18nService.d.ts +28 -100
  21. package/dist/services/I18nService.js +43 -233
  22. package/dist/services/TTSService.d.ts +12 -0
  23. package/dist/services/TTSService.js +18 -17
  24. package/dist/services/ToolRegistry.d.ts +86 -2
  25. package/dist/services/ToolRegistry.js +30 -0
  26. package/dist/services/ToolkitCoordinator.d.ts +39 -37
  27. package/dist/services/ToolkitCoordinator.js +40 -0
  28. package/dist/services/audio-handoff.d.ts +39 -0
  29. package/dist/services/audio-handoff.js +58 -0
  30. package/dist/services/catalog-media.d.ts +35 -4
  31. package/dist/services/catalog-media.js +92 -3
  32. package/dist/services/framework-error.d.ts +15 -1
  33. package/dist/services/interfaces.d.ts +28 -0
  34. package/dist/services/pnp-standard-features.d.ts +1 -1
  35. package/dist/services/section-controller-types.d.ts +218 -7
  36. package/dist/services/selection-action.d.ts +49 -0
  37. package/dist/services/selection-action.js +10 -0
  38. package/dist/services/spoken-audio-cards.js +5 -1
  39. package/dist/services/tool-context.d.ts +6 -5
  40. package/dist/services/tool-context.js +197 -152
  41. package/dist/services/tool-icons.d.ts +18 -0
  42. package/dist/services/tool-icons.js +31 -0
  43. package/dist/services/tool-providers/DesmosToolProvider.d.ts +6 -5
  44. package/dist/services/tool-request.d.ts +106 -0
  45. package/dist/services/tool-request.js +127 -0
  46. package/dist/services/toolbar-items.d.ts +6 -0
  47. package/dist/tools/client.d.ts +0 -1
  48. package/dist/tools/client.js +0 -2
  49. package/dist/tools/internal.d.ts +6 -0
  50. package/dist/tools/internal.js +7 -0
  51. package/dist/tools/tool-surface-host.d.ts +57 -0
  52. package/dist/tools/tool-surface-host.js +610 -0
  53. package/package.json +10 -10
  54. package/dist/components/chunks/ItemToolBar-8jgdz50p.js +0 -51
  55. package/dist/components/chunks/ItemToolBar-cvs646j3.js +0 -36
  56. package/dist/tools/calculators/desmos-provider.d.ts +0 -46
  57. package/dist/tools/calculators/desmos-provider.js +0 -393
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Tool open requests.
3
+ *
4
+ * A surface that acts on the learner's current selection has to hand that selection
5
+ * to a tool it does not mount. The annotation strip is the case PIE ships: it is a
6
+ * section-scoped singleton in its own shadow root, and the tool it opens is mounted
7
+ * by a toolbar under a scoped instance id the strip cannot construct.
8
+ *
9
+ * Resolution is a claim, not a broadcast. Each toolbar registers as the target for its
10
+ * placement level, and a request reaches exactly one: the first target that currently
11
+ * hosts the tool, preferring section scope. A broadcast would open a panel in every
12
+ * toolbar whose scope contains the selection, which in a section player is the item
13
+ * card's toolbar and the section's both.
14
+ *
15
+ * `params` reaches the tool through the same seam a host-registered context resolver
16
+ * feeds, so receiving a request costs a tool nothing: whatever already reads
17
+ * `getToolRenderParams` sees it.
18
+ *
19
+ * Core names no capability. The requester supplies the tool id, which is why the
20
+ * pairing of a selection action to a dictionary lives in the composition layer.
21
+ */
22
+ /** Level a request resolves against when the requester names none. */
23
+ export const DEFAULT_TOOL_REQUEST_LEVEL = "section";
24
+ /**
25
+ * Registry of the toolbars a request can reach.
26
+ *
27
+ * Insertion order is the tie-break within a level, so a target registered while an
28
+ * earlier one is still mounted does not displace it.
29
+ */
30
+ export class ToolRequestRegistry {
31
+ targets = new Set();
32
+ changeListeners = new Set();
33
+ registerTarget(target) {
34
+ this.targets.add(target);
35
+ this.notifyChange();
36
+ return () => {
37
+ if (!this.targets.delete(target))
38
+ return;
39
+ this.notifyChange();
40
+ };
41
+ }
42
+ /**
43
+ * Whether a request for this tool would reach a toolbar.
44
+ *
45
+ * A surface asks before offering the affordance: a button that silently does
46
+ * nothing is worse than an absent one, and availability moves with policy —
47
+ * hence {@link onTargetsChange}.
48
+ */
49
+ canRequest(toolId, level) {
50
+ return this.findTarget(toolId, level) !== null;
51
+ }
52
+ /** Returns whether a target claimed the request. */
53
+ request(request) {
54
+ const target = this.findTarget(request.toolId, request.level);
55
+ if (!target)
56
+ return false;
57
+ try {
58
+ target.open(request.toolId, request.params);
59
+ }
60
+ catch (error) {
61
+ console.error(`[ToolRequestRegistry] Target failed to open "${request.toolId}":`, error);
62
+ return false;
63
+ }
64
+ return true;
65
+ }
66
+ /**
67
+ * Fires when a toolbar registers or unregisters.
68
+ *
69
+ * Not when a registered toolbar's own visible set changes: `hostsTool` is read
70
+ * live, so a caller re-asking `canRequest` gets the current answer. A surface
71
+ * that needs to notice a policy change should also follow the policy signal it
72
+ * already has.
73
+ */
74
+ onTargetsChange(listener) {
75
+ this.changeListeners.add(listener);
76
+ return () => {
77
+ this.changeListeners.delete(listener);
78
+ };
79
+ }
80
+ /**
81
+ * An explicit level is a constraint; the default is a preference.
82
+ *
83
+ * Falling back off `"section"` is what lets a host place a tool at item scope only
84
+ * and still have a section-scoped gateway reach it. Requesting a level explicitly
85
+ * does not fall back, because a requester that named one meant it.
86
+ */
87
+ findTarget(toolId, level) {
88
+ const preferred = this.findTargetAtLevel(toolId, level ?? DEFAULT_TOOL_REQUEST_LEVEL);
89
+ if (preferred || level !== undefined)
90
+ return preferred;
91
+ for (const target of this.targets) {
92
+ if (target.level === DEFAULT_TOOL_REQUEST_LEVEL)
93
+ continue;
94
+ if (this.hostsTool(target, toolId))
95
+ return target;
96
+ }
97
+ return null;
98
+ }
99
+ findTargetAtLevel(toolId, level) {
100
+ for (const target of this.targets) {
101
+ if (target.level !== level)
102
+ continue;
103
+ if (this.hostsTool(target, toolId))
104
+ return target;
105
+ }
106
+ return null;
107
+ }
108
+ hostsTool(target, toolId) {
109
+ try {
110
+ return target.hostsTool(toolId) === true;
111
+ }
112
+ catch (error) {
113
+ console.warn(`[ToolRequestRegistry] Target at level "${target.level}" failed the host check for "${toolId}":`, error);
114
+ return false;
115
+ }
116
+ }
117
+ notifyChange() {
118
+ for (const listener of this.changeListeners) {
119
+ try {
120
+ listener();
121
+ }
122
+ catch (error) {
123
+ console.warn("[ToolRequestRegistry] Target change listener threw:", error);
124
+ }
125
+ }
126
+ }
127
+ }
@@ -3,6 +3,12 @@ export interface ToolbarItemBase {
3
3
  label: string;
4
4
  ariaLabel?: string;
5
5
  icon?: string;
6
+ /**
7
+ * FontAwesome icon name, opting this item into `<nds-icon-button>` rendering
8
+ * where the host enables NDS icons. Set by a tool registration's button
9
+ * definition, or by a host contributing its own button.
10
+ */
11
+ faIconName?: string;
6
12
  tooltip?: string;
7
13
  active?: boolean;
8
14
  disabled?: boolean;
@@ -8,7 +8,6 @@
8
8
  * '@pie-players/pie-assessment-toolkit' to ensure
9
9
  * they don't accidentally pull in server-side dependencies.
10
10
  */
11
- export { DesmosCalculatorProvider } from "./calculators/desmos-provider.js";
12
11
  export { COMMON_LIBRARIES, LibraryLoaderImpl, libraryLoader, } from "./library-loader.js";
13
12
  export { ResponseDiscoveryServiceImpl, responseDiscovery, } from "./response-discovery.js";
14
13
  export * from "./types.js";
@@ -8,8 +8,6 @@
8
8
  * '@pie-players/pie-assessment-toolkit' to ensure
9
9
  * they don't accidentally pull in server-side dependencies.
10
10
  */
11
- // Calculator providers (client-safe, have SSR guards)
12
- export { DesmosCalculatorProvider } from "./calculators/desmos-provider.js";
13
11
  // Library loader (client-safe, has SSR guards)
14
12
  export { COMMON_LIBRARIES, LibraryLoaderImpl, libraryLoader, } from "./library-loader.js";
15
13
  // Response discovery (client-safe, browser-only)
@@ -20,9 +20,15 @@
20
20
  */
21
21
  export type { HostedToolContext, HostedToolSize, ResolvedToolContext, ToolActivation, ToolContentDependency, ToolContentDependencyContext, ToolModuleLoader, ToolProviderDescriptor, ToolRegistration, ToolRenderElement, ToolSingletonScope, ToolSurfaceRenderContext, ToolSurfaceRenderResult, ToolSurfaceServices, ToolToolbarButtonDefinition, ToolToolbarRenderResult, ToolWindowShellConfig, ToolbarContext, } from "../services/ToolRegistry.js";
22
22
  export { ToolRegistry } from "../services/ToolRegistry.js";
23
+ export { resolveToolRegistrationName } from "../services/ToolRegistry.js";
23
24
  export type { CatalogOwnerCard, CatalogOwnerSnapshot, } from "../services/AccessibilityCatalogResolver.js";
25
+ export type { ToolSelectionAction, ToolSelectionContext, } from "../services/selection-action.js";
26
+ export type { ToolOpenRequest, ToolRequestTarget, } from "../services/tool-request.js";
27
+ export { resolveFallbackToolIcon, TOOL_FALLBACK_ICONS, } from "../services/tool-icons.js";
24
28
  export type { ContentCapabilityPhase, ContentCapabilityPolicy, ResolveContentCapabilitiesArgs, ResolvedContentCapability, } from "./content-capability-resolution.js";
25
29
  export { resolveContentCapabilities } from "./content-capability-resolution.js";
30
+ export type { ToolSurfaceHost, ToolSurfaceHostInput, ToolSurfaceHostOptions, ToolSurfaceHostSnapshot, ToolSurfaceScope, } from "./tool-surface-host.js";
31
+ export { createToolSurfaceHost } from "./tool-surface-host.js";
26
32
  export type { ToolContext, ToolLevel } from "../services/tool-context.js";
27
33
  export { hasChoiceInteraction, hasMathContent, hasReadableText, hasScienceContent, } from "../services/tool-context.js";
28
34
  export { createScopedToolId } from "../services/tool-instance-id.js";
@@ -19,7 +19,14 @@
19
19
  * point — the mechanism is the same one our own registrations use.
20
20
  */
21
21
  export { ToolRegistry } from "../services/ToolRegistry.js";
22
+ // A registration's own display name in the interface locale. A tool window's
23
+ // title is the registration's name, so the shell needs the same `nameKey`-then-
24
+ // `name` precedence the toolbar uses rather than the raw English field.
25
+ export { resolveToolRegistrationName } from "../services/ToolRegistry.js";
26
+ // So a gateway button and the toolbar button for the same tool draw one icon.
27
+ export { resolveFallbackToolIcon, TOOL_FALLBACK_ICONS, } from "../services/tool-icons.js";
22
28
  export { resolveContentCapabilities } from "./content-capability-resolution.js";
29
+ export { createToolSurfaceHost } from "./tool-surface-host.js";
23
30
  export { hasChoiceInteraction, hasMathContent, hasReadableText, hasScienceContent, } from "../services/tool-context.js";
24
31
  // Scoped tool instance ids, so two placements of one tool do not share state.
25
32
  export { createScopedToolId } from "../services/tool-instance-id.js";
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Headless host for capabilities that render into a renderer's surfaces.
3
+ *
4
+ * The interface deliberately exposes only current input, a two-boolean snapshot,
5
+ * and teardown. Discovery, policy/catalog invalidation, content resolution, lazy
6
+ * loading, DOM reconciliation, error isolation, and registry observation stay
7
+ * inside this module. Svelte callers are geometry adapters over this seam.
8
+ *
9
+ * It lives here rather than in `section-player`, where it was written, because a
10
+ * second renderer now opens a surface: the annotation toolbar hosts the
11
+ * capabilities that act on a text selection. Two copies of mount/reconcile/
12
+ * registry-observation would drift, and the drift would be invisible until one
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}.
17
+ */
18
+ import type { CatalogOwnerContext } from "../services/catalog-owner.js";
19
+ import type { ToolRegistry, ToolSurfaceServices } from "../services/ToolRegistry.js";
20
+ export type ToolSurfaceScope = {
21
+ kind: "content";
22
+ ownerContext: CatalogOwnerContext;
23
+ } | {
24
+ kind: "section";
25
+ assessmentId: string;
26
+ sectionId: string;
27
+ };
28
+ export interface ToolSurfaceHostInput {
29
+ anchor: HTMLElement | null;
30
+ surface: string;
31
+ registry: ToolRegistry | null;
32
+ services: ToolSurfaceServices;
33
+ scope: ToolSurfaceScope;
34
+ }
35
+ export interface ToolSurfaceHostSnapshot {
36
+ /** At least one capability is eligible, including one still loading. */
37
+ mountable: boolean;
38
+ /** At least one capability successfully mounted an element. */
39
+ occupied: boolean;
40
+ }
41
+ export interface ToolSurfaceHost {
42
+ update(input: ToolSurfaceHostInput): void;
43
+ destroy(): void;
44
+ }
45
+ export interface ToolSurfaceHostOptions {
46
+ /**
47
+ * Which renderer this host belongs to, for framework-error `source` and console
48
+ * warnings — `"pie-section-player"`, `"pie-tool-annotation-toolbar"`.
49
+ *
50
+ * A warning that named the module but not its renderer would be unactionable
51
+ * now that two of them mount surfaces: the same `render` failure on the same
52
+ * `toolId` means different things depending on which surface asked.
53
+ */
54
+ hostLabel: string;
55
+ }
56
+ /** Create one lifecycle owner for one host surface anchor. */
57
+ export declare function createToolSurfaceHost(onSnapshot: (snapshot: ToolSurfaceHostSnapshot) => void, options: ToolSurfaceHostOptions): ToolSurfaceHost;