@pie-players/pie-default-tool-loaders 0.3.64 → 0.3.66

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
@@ -1,24 +1,118 @@
1
1
  # PIE Default Tool Loaders
2
2
 
3
- Default lazy module loader mappings for built-in PIE assessment tools.
3
+ Composition layer for the packaged PIE assessment tools: which capabilities exist
4
+ in a deployment, and how a program tiers them.
4
5
 
5
- This package intentionally owns concrete `pie-tool-*` dependencies so toolkit core can remain dependency-light and cycle-safe.
6
+ It owns the concrete `pie-tool-*` dependencies so toolkit core can stay
7
+ dependency-light and cycle-safe, and it is the layer above core — core knows
8
+ `featureId`, placement levels, activation kinds and precedence rules, and knows
9
+ no capability ids.
10
+
11
+ It owns five things, all answers to "which capabilities does this deployment have
12
+ and how does the program tier them":
13
+
14
+ | Export | What it decides |
15
+ | --- | --- |
16
+ | `PACKAGED_TOOL_REGISTRATIONS`, `createPackagedToolRegistry`, `registerPackagedTools` | Which capabilities exist, and their toolbar and surface contracts |
17
+ | `PACKAGED_TOOL_TAG_MAP` | Which custom element each one renders as |
18
+ | `PACKAGED_TOOL_PLACEMENT`, `SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT`, `PACKAGED_TOOL_ORDER` | Where they appear and in what order |
19
+ | `UNIVERSAL_SUPPORTS_PRESET`, `createUniversalPersonalNeedsProfile` | Which of their support ids the program grants to everyone |
20
+ | `DEFAULT_TOOL_MODULE_LOADERS`, `registerSectionToolModuleLoaders` | When each one's bundle loads |
21
+
22
+ The individual registrations are exported too, so a host can compose its own set
23
+ rather than take the packaged one whole.
24
+
25
+ These exports are projections of one internal **Packaged Capability
26
+ Composition**. Each packaged capability is authored once with its registration,
27
+ element delivery, loader bootstrap sets, placement/order membership and explicit
28
+ universal-support policy. The package build rejects contradictory PIE-owned data
29
+ — for example, a region capability with a toolbar tag, or a universal support
30
+ id its registration does not declare — so release tests find a missing facet
31
+ instead of a learner finding a dead affordance. The browser does not repeat that
32
+ strict gate at import time: a PIE authoring defect must block publication, not an
33
+ otherwise usable assessment.
34
+
35
+ That invariant boundary does not make host input stricter. The existing public
36
+ factory and constants are unchanged: lazy module loading remains opt-in,
37
+ registration/tag/factory overrides retain precedence, an empty `toolIds` array
38
+ still selects the full packaged set, and unknown selected ids are ignored while
39
+ known ids continue to register.
6
40
 
7
41
  ## Usage
8
42
 
9
43
  ```ts
10
- import { createDefaultToolRegistry } from "@pie-players/pie-assessment-toolkit";
11
44
  import {
45
+ createPackagedToolRegistry,
12
46
  DEFAULT_TOOL_MODULE_LOADERS,
13
- registerSectionToolModuleLoaders,
14
47
  } from "@pie-players/pie-default-tool-loaders";
15
48
 
16
- // Full default loaders (item + section tools)
17
- const registry = createDefaultToolRegistry({
49
+ // The packaged capability set, lazily loaded.
50
+ const registry = createPackagedToolRegistry({
18
51
  toolModuleLoaders: DEFAULT_TOOL_MODULE_LOADERS,
19
52
  });
53
+ ```
54
+
55
+ `createDefaultToolRegistry()` in the toolkit is the other end of that choice: it
56
+ builds an empty registry, and a host composing its own set registers into it.
57
+
58
+ ```ts
59
+ import { createDefaultToolRegistry } from "@pie-players/pie-assessment-toolkit";
60
+ import {
61
+ calculatorToolRegistration,
62
+ registerSectionToolModuleLoaders,
63
+ ttsToolRegistration,
64
+ } from "@pie-players/pie-default-tool-loaders";
20
65
 
21
- // Section-only loaders (for section toolbar bootstrap points)
66
+ const registry = createDefaultToolRegistry({
67
+ registrations: [calculatorToolRegistration, ttsToolRegistration],
68
+ });
69
+ // Section-only loaders, for section toolbar bootstrap points.
22
70
  registerSectionToolModuleLoaders(registry);
23
71
  ```
24
72
 
73
+ ## Content-dependent capabilities require an explicit packaging decision
74
+
75
+ A content-dependent capability is never inferred into
76
+ `UNIVERSAL_SUPPORTS_PRESET`. It may ship in `PACKAGED_TOOL_REGISTRATIONS` only
77
+ when it has a useful presentation path without a grant and declares
78
+ `resolvesWithoutGrant`. Audio transcript is the shipped example: an authored
79
+ `visibility: "always"` transcript reaches every player, while its accommodation
80
+ path remains policy-gated and `transcript` stays out of the universal preset.
81
+
82
+ A content-dependent capability with no presentation path remains an explicit
83
+ deployment choice. Signing is the shipped example: install
84
+ `@pie-players/pie-tool-sign-language` and register it, which is the same two
85
+ lines a host writes for a capability of its own.
86
+
87
+ ```ts
88
+ import { signLanguageRegistration } from "@pie-players/pie-tool-sign-language";
89
+
90
+ registry.register(signLanguageRegistration);
91
+ ```
92
+
93
+ ## Universal supports preset
94
+
95
+ `createUniversalPersonalNeedsProfile()` builds a `PersonalNeedsProfile` granting
96
+ `UNIVERSAL_SUPPORTS_PRESET` — the support ids the packaged tool set treats as
97
+ universal features.
98
+
99
+ ```ts
100
+ import { createUniversalPersonalNeedsProfile } from "@pie-players/pie-default-tool-loaders";
101
+
102
+ const section = {
103
+ ...authoredSection,
104
+ personalNeedsProfile: createUniversalPersonalNeedsProfile(),
105
+ };
106
+ ```
107
+
108
+ The core ships no populated default — `createEmptyPersonalNeedsProfile()` in
109
+ `@pie-players/pie-assessment-toolkit` grants nothing. Which capabilities a
110
+ deployment grants by default is a property of the program, not of a capability:
111
+ TTS is a universal feature in one program and a documented accommodation in
112
+ another. So the preset is data to adopt, extend or replace alongside the district
113
+ and test-administration configuration, and it deliberately excludes any
114
+ capability that declares a content dependency.
115
+
116
+ A section carrying no profile is left alone. `pnpEnforcement` auto-detection
117
+ engages on real host policy material, so supplying no profile means placement
118
+ alone decides which tools appear.
package/dist/index.d.ts CHANGED
@@ -1,16 +1,9 @@
1
- export type ToolModuleLoader = () => Promise<unknown>;
2
- export interface ToolRegistryLike {
3
- setToolModuleLoaders(loaders: Partial<Record<string, ToolModuleLoader>>): void;
4
- }
5
- export declare const SECTION_TOOL_MODULE_LOADERS: Record<string, ToolModuleLoader>;
6
- export declare const ITEM_TOOL_MODULE_LOADERS: Record<string, ToolModuleLoader>;
7
- export declare const DEFAULT_TOOL_MODULE_LOADERS: Record<string, ToolModuleLoader>;
8
- export type RegisterDefaultToolModuleLoadersOptions = {
9
- loaders?: Partial<Record<string, ToolModuleLoader>>;
10
- };
11
- /**
12
- * Register built-in lazy module loaders on a registry.
13
- * Hosts can override or extend the defaults via options.loaders.
14
- */
15
- export declare function registerDefaultToolModuleLoaders(registry: ToolRegistryLike, options?: RegisterDefaultToolModuleLoadersOptions): void;
16
- export declare function registerSectionToolModuleLoaders(registry: ToolRegistryLike, options?: RegisterDefaultToolModuleLoadersOptions): void;
1
+ export type { PackagedToolRegistryOptions, RegisterDefaultToolModuleLoadersOptions, RegisterPackagedToolsOptions, ToolModuleLoader, ToolRegistryLike, } from "./packaged-capability-composition.js";
2
+ export { createPackagedToolRegistry, createUniversalPersonalNeedsProfile, DEFAULT_TOOL_MODULE_LOADERS, ITEM_TOOL_MODULE_LOADERS, PACKAGED_TOOL_ORDER, PACKAGED_TOOL_PLACEMENT, PACKAGED_TOOL_REGISTRATIONS, PACKAGED_TOOL_TAG_MAP, registerDefaultToolModuleLoaders, registerPackagedTools, registerSectionToolModuleLoaders, SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT, SECTION_TOOL_MODULE_LOADERS, UNIVERSAL_SUPPORTS_PRESET, } from "./packaged-capability-composition.js";
3
+ export { annotationToolbarRegistration, lineReaderToolRegistration, themeToolRegistration, } from "./registrations/accessibility-tools.js";
4
+ export { AUDIO_TRANSCRIPT_FEATURE_ID, AUDIO_TRANSCRIPT_REGION_CLASS, AUDIO_TRANSCRIPT_REGION_LABEL, audioTranscriptRegistration, resolveAudioTranscript, type ResolvedAudioTranscript, } from "./registrations/audio-transcript.js";
5
+ export { calculatorToolRegistration } from "./registrations/calculator.js";
6
+ export { answerEliminatorToolRegistration, highlighterToolRegistration, } from "./registrations/interaction-tools.js";
7
+ export { protractorToolRegistration, rulerToolRegistration, } from "./registrations/measurement-tools.js";
8
+ export { graphToolRegistration, periodicTableToolRegistration, } from "./registrations/subject-specific-tools.js";
9
+ export { ttsToolRegistration } from "./registrations/tts.js";
package/dist/index.js CHANGED
@@ -1,45 +1,10 @@
1
- const loadSideEffectModule = (load) => load().then(() => undefined);
2
- function loadCalculatorModule() {
3
- if (typeof globalThis !== "undefined" &&
4
- "customElements" in globalThis &&
5
- globalThis.customElements?.get("pie-tool-calculator")) {
6
- return Promise.resolve();
7
- }
8
- return loadSideEffectModule(() => import("@pie-players/pie-tool-calculator-desmos"));
9
- }
10
- export const SECTION_TOOL_MODULE_LOADERS = {
11
- calculator: loadCalculatorModule,
12
- graph: () => loadSideEffectModule(() => import("@pie-players/pie-tool-graph")),
13
- periodicTable: () => loadSideEffectModule(() => import("@pie-players/pie-tool-periodic-table")),
14
- ruler: () => loadSideEffectModule(() => import("@pie-players/pie-tool-ruler")),
15
- protractor: () => loadSideEffectModule(() => import("@pie-players/pie-tool-protractor")),
16
- lineReader: () => loadSideEffectModule(() => import("@pie-players/pie-tool-line-reader")),
17
- };
18
- export const ITEM_TOOL_MODULE_LOADERS = {
19
- calculator: loadCalculatorModule,
20
- textToSpeech: () => loadSideEffectModule(() => import("@pie-players/pie-tool-tts-inline")),
21
- answerEliminator: () => loadSideEffectModule(() => import("@pie-players/pie-tool-answer-eliminator")),
22
- highlighter: () => loadSideEffectModule(() => import("@pie-players/pie-tool-annotation-toolbar")),
23
- annotationToolbar: () => loadSideEffectModule(() => import("@pie-players/pie-tool-annotation-toolbar")),
24
- theme: () => loadSideEffectModule(() => import("@pie-players/pie-tool-theme")),
25
- };
26
- export const DEFAULT_TOOL_MODULE_LOADERS = {
27
- ...ITEM_TOOL_MODULE_LOADERS,
28
- ...SECTION_TOOL_MODULE_LOADERS,
29
- };
30
- /**
31
- * Register built-in lazy module loaders on a registry.
32
- * Hosts can override or extend the defaults via options.loaders.
33
- */
34
- export function registerDefaultToolModuleLoaders(registry, options = {}) {
35
- registry.setToolModuleLoaders({
36
- ...DEFAULT_TOOL_MODULE_LOADERS,
37
- ...(options.loaders || {}),
38
- });
39
- }
40
- export function registerSectionToolModuleLoaders(registry, options = {}) {
41
- registry.setToolModuleLoaders({
42
- ...SECTION_TOOL_MODULE_LOADERS,
43
- ...(options.loaders || {}),
44
- });
45
- }
1
+ export { createPackagedToolRegistry, createUniversalPersonalNeedsProfile, DEFAULT_TOOL_MODULE_LOADERS, ITEM_TOOL_MODULE_LOADERS, PACKAGED_TOOL_ORDER, PACKAGED_TOOL_PLACEMENT, PACKAGED_TOOL_REGISTRATIONS, PACKAGED_TOOL_TAG_MAP, registerDefaultToolModuleLoaders, registerPackagedTools, registerSectionToolModuleLoaders, SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT, SECTION_TOOL_MODULE_LOADERS, UNIVERSAL_SUPPORTS_PRESET, } from "./packaged-capability-composition.js";
2
+ // Individual registrations, for a host composing a subset rather than the whole
3
+ // packaged set.
4
+ export { annotationToolbarRegistration, lineReaderToolRegistration, themeToolRegistration, } from "./registrations/accessibility-tools.js";
5
+ export { AUDIO_TRANSCRIPT_FEATURE_ID, AUDIO_TRANSCRIPT_REGION_CLASS, AUDIO_TRANSCRIPT_REGION_LABEL, audioTranscriptRegistration, resolveAudioTranscript, } from "./registrations/audio-transcript.js";
6
+ export { calculatorToolRegistration } from "./registrations/calculator.js";
7
+ export { answerEliminatorToolRegistration, highlighterToolRegistration, } from "./registrations/interaction-tools.js";
8
+ export { protractorToolRegistration, rulerToolRegistration, } from "./registrations/measurement-tools.js";
9
+ export { graphToolRegistration, periodicTableToolRegistration, } from "./registrations/subject-specific-tools.js";
10
+ export { ttsToolRegistration } from "./registrations/tts.js";
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The one authored description of PIE's packaged capability composition.
3
+ *
4
+ * Registrations describe what a capability can do. This module owns the
5
+ * deployment decisions around them: element tags, lazy module bootstrap sets,
6
+ * placement presets, toolbar order and the explicit universal-support policy.
7
+ * Public constants are projections of this composition so adding a capability
8
+ * cannot leave a second hand-maintained catalogue silently behind.
9
+ */
10
+ import { ToolRegistry, type ToolComponentFactory, type ToolComponentFactoryMap, type ToolRegistration, type ToolTagMap } from "@pie-players/pie-assessment-toolkit/tools/internal";
11
+ import type { PersonalNeedsProfile } from "@pie-players/pie-players-shared/types";
12
+ export type ToolModuleLoader = () => Promise<unknown>;
13
+ export interface ToolRegistryLike {
14
+ setToolModuleLoaders(loaders: Partial<Record<string, ToolModuleLoader>>): void;
15
+ }
16
+ export interface PackagedToolRegistryOptions {
17
+ /** Override packaged registrations by toolId. */
18
+ overrides?: Partial<Record<string, ToolRegistration>>;
19
+ /** Override or extend the packaged element tag mapping. */
20
+ toolTagMap?: Partial<ToolTagMap>;
21
+ /** Override the component factory globally or per tool. */
22
+ toolComponentFactory?: ToolComponentFactory;
23
+ toolComponentFactories?: Partial<ToolComponentFactoryMap>;
24
+ /** Lazy module loaders keyed by toolId. */
25
+ toolModuleLoaders?: Partial<Record<string, ToolModuleLoader>>;
26
+ /** Restrict registration to specific packaged tool ids. */
27
+ toolIds?: string[];
28
+ }
29
+ export interface RegisterPackagedToolsOptions {
30
+ toolIds?: string[];
31
+ applyOverrides?: (registration: ToolRegistration) => ToolRegistration;
32
+ }
33
+ export type RegisterDefaultToolModuleLoadersOptions = {
34
+ loaders?: Partial<Record<string, ToolModuleLoader>>;
35
+ };
36
+ /**
37
+ * Release/build gate for PIE-authored composition data.
38
+ *
39
+ * Deliberately not called by the browser runtime: an invariant regression must
40
+ * stop the package before publication, not turn into an import-time exception
41
+ * that prevents an otherwise usable assessment from rendering.
42
+ */
43
+ export declare function assertPackagedCapabilityComposition(): void;
44
+ export declare const PACKAGED_TOOL_REGISTRATIONS: readonly [ToolRegistration, ToolRegistration, ToolRegistration, ToolRegistration, ToolRegistration, ToolRegistration, ToolRegistration, ToolRegistration, ToolRegistration, ToolRegistration, ToolRegistration, ToolRegistration];
45
+ export declare const PACKAGED_TOOL_TAG_MAP: ToolTagMap;
46
+ export declare const ITEM_TOOL_MODULE_LOADERS: Record<string, ToolModuleLoader>;
47
+ export declare const SECTION_TOOL_MODULE_LOADERS: Record<string, ToolModuleLoader>;
48
+ export declare const DEFAULT_TOOL_MODULE_LOADERS: Record<string, ToolModuleLoader>;
49
+ export declare const PACKAGED_TOOL_PLACEMENT: {
50
+ readonly assessment: readonly ["theme"];
51
+ readonly section: readonly ["theme"];
52
+ readonly item: readonly ["textToSpeech", "highlighter", "annotationToolbar", "graph", "periodicTable"];
53
+ readonly passage: readonly ["textToSpeech", "highlighter", "annotationToolbar", "lineReader"];
54
+ readonly rubric: readonly ["textToSpeech", "highlighter", "annotationToolbar", "lineReader"];
55
+ readonly element: readonly ["calculator", "answerEliminator", "textToSpeech", "ruler", "protractor", "highlighter", "annotationToolbar", "graph", "periodicTable"];
56
+ };
57
+ export declare const SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT: {
58
+ section: string[];
59
+ item: string[];
60
+ passage: string[];
61
+ };
62
+ export declare const PACKAGED_TOOL_ORDER: readonly ["theme", "calculator", "textToSpeech", "lineReader", "annotationToolbar", "highlighter", "answerEliminator", "ruler", "protractor", "graph", "periodicTable"];
63
+ export declare const UNIVERSAL_SUPPORTS_PRESET: readonly string[];
64
+ /** Register packaged PIE capabilities onto an existing registry. */
65
+ export declare function registerPackagedTools(registry: ToolRegistry, options?: RegisterPackagedToolsOptions): void;
66
+ /** Create a registry holding the packaged PIE capabilities. */
67
+ export declare function createPackagedToolRegistry(options?: PackagedToolRegistryOptions): ToolRegistry;
68
+ /** Build a fresh profile granting the explicit universal-support preset. */
69
+ export declare function createUniversalPersonalNeedsProfile(): PersonalNeedsProfile;
70
+ /** Register packaged lazy module loaders, followed by host overrides. */
71
+ export declare function registerDefaultToolModuleLoaders(registry: ToolRegistryLike, options?: RegisterDefaultToolModuleLoadersOptions): void;
72
+ /** Register only the section-bootstrap loader subset, then host overrides. */
73
+ export declare function registerSectionToolModuleLoaders(registry: ToolRegistryLike, options?: RegisterDefaultToolModuleLoadersOptions): void;