@pie-players/pie-assessment-toolkit 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.
Files changed (74) hide show
  1. package/README.md +81 -33
  2. package/dist/components/ItemToolBar.custom-element.js +1 -1
  3. package/dist/components/PieAssessmentToolkit.custom-element.js +9 -8
  4. package/dist/components/SectionToolBar.custom-element.js +1 -1
  5. package/dist/components/chunks/ItemToolBar-8jgdz50p.js +51 -0
  6. package/dist/components/chunks/ItemToolBar-cvs646j3.js +36 -0
  7. package/dist/index.d.ts +7 -8
  8. package/dist/index.js +10 -5
  9. package/dist/policy/core/PolicySource.d.ts +2 -2
  10. package/dist/policy/core/PolicySource.js +2 -2
  11. package/dist/policy/core/ToolPolicyEngine.d.ts +7 -3
  12. package/dist/policy/core/ToolPolicyEngine.js +11 -3
  13. package/dist/policy/core/compose-decision.d.ts +3 -2
  14. package/dist/policy/core/compose-decision.js +3 -2
  15. package/dist/policy/core/decision-types.d.ts +2 -2
  16. package/dist/policy/core/decision-types.js +2 -2
  17. package/dist/policy/core/feature-decision.d.ts +28 -1
  18. package/dist/policy/core/feature-decision.js +25 -3
  19. package/dist/policy/core/pnp-policy-inputs.d.ts +2 -2
  20. package/dist/policy/core/pnp-policy-inputs.js +2 -2
  21. package/dist/policy/core/provenance.d.ts +4 -1
  22. package/dist/policy/core/provenance.js +4 -1
  23. package/dist/policy/sources/PnpPolicySource.d.ts +2 -1
  24. package/dist/policy/sources/PnpPolicySource.js +2 -1
  25. package/dist/runtime/composition-emit-scheduler.d.ts +78 -0
  26. package/dist/runtime/composition-emit-scheduler.js +154 -0
  27. package/dist/runtime/core/engine-resolver.d.ts +1 -1
  28. package/dist/runtime/core/engine-transition.js +3 -1
  29. package/dist/services/AccessibilityCatalogResolver.d.ts +49 -10
  30. package/dist/services/AccessibilityCatalogResolver.js +180 -11
  31. package/dist/services/TTSService.d.ts +11 -0
  32. package/dist/services/TTSService.js +220 -32
  33. package/dist/services/ToolRegistry.d.ts +259 -8
  34. package/dist/services/ToolRegistry.js +181 -11
  35. package/dist/services/ToolkitCoordinator.d.ts +20 -2
  36. package/dist/services/ToolkitCoordinator.js +47 -8
  37. package/dist/services/catalog-owner.d.ts +71 -0
  38. package/dist/services/catalog-owner.js +64 -0
  39. package/dist/services/createDefaultToolRegistry.d.ts +25 -58
  40. package/dist/services/createDefaultToolRegistry.js +24 -104
  41. package/dist/services/defaultPersonalNeedsProfile.d.ts +16 -14
  42. package/dist/services/defaultPersonalNeedsProfile.js +17 -38
  43. package/dist/services/framework-error.d.ts +1 -1
  44. package/dist/services/interfaces.d.ts +15 -3
  45. package/dist/services/pnp-standard-features.d.ts +1 -1
  46. package/dist/services/tool-config-defaults.d.ts +7 -23
  47. package/dist/services/tool-config-defaults.js +7 -46
  48. package/dist/services/tool-config-validation.d.ts +1 -1
  49. package/dist/services/tool-config-validation.js +44 -4
  50. package/dist/services/tts/browser-provider.js +191 -24
  51. package/dist/services/tts-runtime-config.js +7 -2
  52. package/dist/tools/internal.d.ts +35 -0
  53. package/dist/tools/internal.js +33 -0
  54. package/dist/tools/tool-tag-map.d.ts +15 -3
  55. package/dist/tools/tool-tag-map.js +21 -18
  56. package/package.json +14 -10
  57. package/dist/components/chunks/ItemToolBar-3cppre9r.js +0 -51
  58. package/dist/components/chunks/ItemToolBar-7rq2gj8b.js +0 -22
  59. package/dist/runtime/catalog-registration.d.ts +0 -67
  60. package/dist/runtime/catalog-registration.js +0 -86
  61. package/dist/services/sign-language-cards.d.ts +0 -82
  62. package/dist/services/sign-language-cards.js +0 -133
  63. package/dist/tools/registrations/accessibility-tools.d.ts +0 -34
  64. package/dist/tools/registrations/accessibility-tools.js +0 -217
  65. package/dist/tools/registrations/calculator.d.ts +0 -20
  66. package/dist/tools/registrations/calculator.js +0 -228
  67. package/dist/tools/registrations/interaction-tools.d.ts +0 -27
  68. package/dist/tools/registrations/interaction-tools.js +0 -143
  69. package/dist/tools/registrations/measurement-tools.d.ts +0 -24
  70. package/dist/tools/registrations/measurement-tools.js +0 -130
  71. package/dist/tools/registrations/subject-specific-tools.d.ts +0 -27
  72. package/dist/tools/registrations/subject-specific-tools.js +0 -158
  73. package/dist/tools/registrations/tts.d.ts +0 -21
  74. package/dist/tools/registrations/tts.js +0 -184
package/README.md CHANGED
@@ -235,7 +235,7 @@ const coordinator = new ToolkitCoordinator({
235
235
  assessmentId: 'demo-assessment',
236
236
  tools: {
237
237
  providers: {
238
- textToSpeech: { enabled: true, backend: 'browser', defaultVoice: 'en-US' },
238
+ textToSpeech: { enabled: true, backend: 'browser' },
239
239
  calculator: { enabled: true }
240
240
  },
241
241
  placement: {
@@ -418,7 +418,7 @@ tools: {
418
418
  },
419
419
  providers: {
420
420
  calculator: { authFetcher: async () => ({ apiKey: '...' }) },
421
- textToSpeech: { enabled: true, backend: 'browser', defaultVoice: 'en-US' }
421
+ textToSpeech: { enabled: true, backend: 'browser' }
422
422
  }
423
423
  }
424
424
  ```
@@ -1053,34 +1053,42 @@ Consumers select by type and then validate the form they expect; a card with no
1053
1053
  string form is not text content, and treating it as such would speak or render an
1054
1054
  empty string.
1055
1055
 
1056
- Catalogs registered for a rendered item or passage are filed under a
1057
- `CatalogOwnerContext`, which the resolver matches field by field. Build lookup
1058
- contexts with `catalogOwnerContextFor` rather than as a literal it is the same
1059
- function the runtime registers with, so the two cannot drift:
1056
+ Catalogs carried by a rendered item or passage are registered as one owner-level
1057
+ transaction. The resolver owns the walk over entity-root,
1058
+ `config.extractedCatalogs`, and model catalogs, along with their registration
1059
+ precedence and change notification:
1060
1060
 
1061
1061
  ```typescript
1062
1062
  import {
1063
1063
  catalogOwnerContextFor,
1064
- collectEntityCatalogRegistrations,
1065
1064
  } from '@pie-players/pie-assessment-toolkit';
1066
1065
 
1067
- const context = catalogOwnerContextFor({
1066
+ const owner = {
1068
1067
  kind: 'item',
1069
1068
  itemId: item.id,
1070
1069
  canonicalItemId,
1071
1070
  assessmentId,
1072
1071
  sectionId,
1073
- });
1072
+ } as const;
1074
1073
 
1075
- // Every catalog an entity carries, paired with the scope it belongs in:
1076
- // entity-level `accessibilityCatalogs`, `config.extractedCatalogs`, and each
1077
- // model's own catalogs (filed under that `modelId`).
1078
- const registrations = collectEntityCatalogRegistrations(item, {
1079
- kind: 'item',
1080
- itemId: item.id,
1074
+ const unregister = resolver.registerOwner({ owner, entity: item });
1075
+ const ownerView = resolver.forOwner(catalogOwnerContextFor(owner));
1076
+
1077
+ const stopObserving = ownerView.onChange(() => {
1078
+ const snapshot = ownerView.snapshot();
1079
+ // Interpret only the card types your capability owns.
1081
1080
  });
1081
+
1082
+ stopObserving();
1083
+ unregister();
1082
1084
  ```
1083
1085
 
1086
+ `CatalogOwnerSnapshot` is immutable and deterministic. A content capability
1087
+ receives it as `ToolContentDependencyContext.catalogs`; it does not receive the
1088
+ raw entity, resolver, or separately assembled lookup context. Direct consumers
1089
+ such as TTS may still call `getAlternative(...)` with a context built by
1090
+ `catalogOwnerContextFor`.
1091
+
1084
1092
  ### SSMLExtractor
1085
1093
 
1086
1094
  ```typescript
@@ -1097,20 +1105,20 @@ item.config.extractedCatalogs = result.catalogs;
1097
1105
  catalogResolver.addItemCatalogs(result.catalogs);
1098
1106
  ```
1099
1107
 
1100
- ### Sign-language cards
1108
+ ### Cards without an extractor
1101
1109
 
1102
- Signed alternates have no extractor and deliberately so: a `sign-language` card is
1103
- authored or written by an importer, never lifted out of item markup at render
1104
- time. One such lift existed and was removed nothing produced the inline form,
1105
- and a runtime that could not parse the markup left the video in the visible
1106
- content, showing the accommodation to every learner regardless of eligibility.
1110
+ Not every catalog card is lifted out of item markup. A signed alternate is
1111
+ authored or written by an importer and has no extractor at all; one such lift
1112
+ existed and was removed, because nothing produced the inline form and a runtime
1113
+ that could not parse the markup left the video in the visible content, showing the
1114
+ accommodation to every learner regardless of eligibility.
1107
1115
 
1108
- Whether a card describes a playable signed alternate is decided in one place,
1109
- `resolveSignLanguageMedia` a payload with no usable source resolves to `null`
1110
- rather than rendering an empty player, and source URLs are restricted to schemes
1111
- a media element can actually fetch. `matchesRequestedSignLanguage` holds the
1112
- deliberate strictness: there is no cross-sign-language substitution, since
1113
- handing an ASL learner a BSL recording is worse than handing them nothing.
1116
+ This package resolves and registers those cards through
1117
+ `AccessibilityCatalogResolver` and the generic media helpers in
1118
+ `catalog-media.ts`. Which card types mean what belongs to the capability that
1119
+ needs them signing's card validators and its resolution rules live in
1120
+ `@pie-players/pie-tool-sign-language`, behind that capability's
1121
+ `requiresAuthoredContent`.
1114
1122
 
1115
1123
  ### Feature policy without a placement
1116
1124
 
@@ -1121,10 +1129,28 @@ placement. Use it for capabilities that are not toolbar surfaces — signing is
1121
1129
  first — where a placement-scoped `decide(...)` would answer the wrong question:
1122
1130
  absent because it was never placed, rather than absent because policy said no.
1123
1131
 
1124
- `computeDefaultSupports()` excludes `ACCOMMODATION_ONLY_SUPPORT_IDS`, which lists
1125
- `signLanguage`. The computed default profile derives from every registered tool's
1126
- `pnpSupportIds`, which is right for universal features and wrong for an
1127
- accommodation requiring a documented need.
1132
+ `createEmptyPersonalNeedsProfile()` is the only profile this package ships, and it
1133
+ grants nothing. Which capabilities a deployment grants by default is a property
1134
+ of the program rather than of a capability TTS is a universal feature in one
1135
+ program and a documented accommodation in another — so it belongs in policy
1136
+ configuration alongside the district and test-administration levels. Hosts that
1137
+ want today's universal set take `createUniversalPersonalNeedsProfile()` from
1138
+ `@pie-players/pie-default-tool-loaders`, which ships it as data.
1139
+
1140
+ Nothing derives a profile from the registry any more. Doing so read registry
1141
+ membership as eligibility tier — registration means "policy-addressable", not
1142
+ "universal, on by default" — and had to be corrected with a compile-time list of
1143
+ ids to exclude that a host could not extend for its own accommodation.
1144
+
1145
+ ### Live registry changes
1146
+
1147
+ `ToolRegistry.onRegistryChange(listener)` observes successful `register`,
1148
+ `override`, `unregister`, `clear`, component-override, and module-loader
1149
+ changes synchronously. Invalid and no-op mutations do not emit, listener
1150
+ failures do not interrupt other listeners, and unsubscribe is idempotent.
1151
+ Section-player subscribes internally, so a capability registered after mount
1152
+ appears without a host-forced rerender; unregister and clear destroy their
1153
+ mounted surface elements immediately.
1128
1154
 
1129
1155
  ## Integration with Section Player
1130
1156
 
@@ -1227,10 +1253,10 @@ Use `createToolsConfig()` when you want to pre-validate and inspect diagnostics
1227
1253
 
1228
1254
  ```typescript
1229
1255
  import {
1230
- createPackagedToolRegistry,
1231
1256
  createToolsConfig,
1232
1257
  ToolkitCoordinator
1233
1258
  } from "@pie-players/pie-assessment-toolkit";
1259
+ import { createPackagedToolRegistry } from "@pie-players/pie-default-tool-loaders";
1234
1260
 
1235
1261
  const toolRegistry = createPackagedToolRegistry();
1236
1262
  const { config, diagnostics } = createToolsConfig({
@@ -1267,7 +1293,9 @@ Notes:
1267
1293
  `ToolkitCoordinator.subscribeFrameworkErrors(listener)`. The callback
1268
1294
  prop fires exactly once per error, regardless of wrapper depth. Filter
1269
1295
  by `model.kind` (e.g. `"tts-init"`, `"provider-init"`,
1270
- `"provider-register"`) for tool- or provider-specific handling.
1296
+ `"provider-register"`, `"tool-surface"`) for tool- or provider-specific
1297
+ handling. Recoverable warnings remain observable but do not move section
1298
+ readiness to `error`.
1271
1299
  - See `docs/tools-and-accomodations/framework-owned-error-handling.md` for event payload and error-kind mapping details.
1272
1300
 
1273
1301
  ## Section Runtime Engine (advanced)
@@ -1303,6 +1331,26 @@ pick the stability surface that matches their use case:
1303
1331
  `resolveSectionEngineRuntimeState` helpers. Symbols here may change
1304
1332
  between minor versions with a changeset note.
1305
1333
 
1334
+ ## Writing a capability package
1335
+
1336
+ `@pie-players/pie-assessment-toolkit/tools/internal` is what a capability
1337
+ package imports: the `ToolRegistration` contract, the surface and content
1338
+ dependency types, `resolveToolTag` and the toolbar registration helpers. Same
1339
+ stability contract as the other `*/internal` entry points — symbols may change
1340
+ between minor versions with a changeset note.
1341
+
1342
+ Import it rather than the package root: the root pulls in `ToolkitCoordinator`,
1343
+ `TTSService` and the components, none of which a registration needs, and a
1344
+ capability bundle that inlines them ends up with a second `ToolRegistry` class
1345
+ that fails every `instanceof` across the host boundary. Mark the toolkit external
1346
+ in the package's build with a pattern that covers subpaths, not a bare specifier.
1347
+
1348
+ `@pie-players/pie-tool-sign-language` is the worked example end to end: a
1349
+ registration, a content resolver, its own custom element, and no edit to any
1350
+ generic package. `packages/default-tool-loaders/README.md` covers how a
1351
+ deployment then composes it in, and `docs/TOOL_REGISTRY.md` the registration and
1352
+ host-surface contracts.
1353
+
1306
1354
  ### Lifecycle emit coordination
1307
1355
 
1308
1356
  When `<pie-assessment-toolkit>` is nested inside a section-player layout,
@@ -1 +1 @@
1
- import{a}from"./chunks/ItemToolBar-7rq2gj8b.js";import"./chunks/ItemToolBar-3cppre9r.js";export{a as default};
1
+ import{a}from"./chunks/ItemToolBar-cvs646j3.js";import"./chunks/ItemToolBar-8jgdz50p.js";export{a as default};