@pie-players/pie-assessment-toolkit 0.3.72 → 0.3.74

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 (108) hide show
  1. package/README.md +171 -56
  2. package/dist/attempt/AssessmentSession.d.ts +1 -5
  3. package/dist/attempt/AssessmentSession.js +0 -29
  4. package/dist/components/ItemToolBar.custom-element.d.ts +1 -0
  5. package/dist/components/ItemToolBar.custom-element.js +1 -1
  6. package/dist/components/PieAssessmentToolkit.custom-element.d.ts +1 -0
  7. package/dist/components/PieAssessmentToolkit.custom-element.js +14 -14
  8. package/dist/components/SectionToolBar.custom-element.d.ts +1 -0
  9. package/dist/components/SectionToolBar.custom-element.js +1 -1
  10. package/dist/components/chunks/ItemToolBar-b9dz5jvd.js +40 -0
  11. package/dist/components/chunks/ItemToolBar-gmrryv2v.js +2 -0
  12. package/dist/components/chunks/ItemToolBar-h4xap0t0.js +4 -0
  13. package/dist/components/chunks/ItemToolBar-wr2myaah.js +2 -0
  14. package/dist/components/chunks/sre-engine-wf9s43gg.js +1 -0
  15. package/dist/context/assessment-toolkit-context.d.ts +5 -0
  16. package/dist/context/runtime-context-consumer.js +5 -38
  17. package/dist/index.d.ts +6 -6
  18. package/dist/index.js +8 -9
  19. package/dist/policy/core/ToolPolicyEngine.d.ts +8 -2
  20. package/dist/policy/core/ToolPolicyEngine.js +12 -0
  21. package/dist/runtime/adapter/SectionEngineAdapter.d.ts +3 -3
  22. package/dist/runtime/adapter/SectionEngineAdapter.js +3 -3
  23. package/dist/runtime/registration-events.d.ts +3 -0
  24. package/dist/runtime/section-runtime-engine-host-context.d.ts +3 -9
  25. package/dist/runtime/section-runtime-engine-host-context.js +5 -43
  26. package/dist/runtime/tool-host-contract.d.ts +20 -0
  27. package/dist/runtime/tool-host-contract.js +21 -0
  28. package/dist/services/HighlightCoordinator.d.ts +1 -7
  29. package/dist/services/HighlightCoordinator.js +1 -3
  30. package/dist/services/TTSService.d.ts +15 -1
  31. package/dist/services/TTSService.js +88 -35
  32. package/dist/services/ToolCoordinator.d.ts +1 -7
  33. package/dist/services/ToolCoordinator.js +1 -3
  34. package/dist/services/ToolRegistry.d.ts +13 -6
  35. package/dist/services/ToolRegistry.js +19 -7
  36. package/dist/services/ToolkitCoordinator.d.ts +110 -18
  37. package/dist/services/ToolkitCoordinator.js +273 -85
  38. package/dist/services/catalog-owner.d.ts +11 -0
  39. package/dist/services/catalog-owner.js +25 -0
  40. package/dist/services/create-tools-config.d.ts +2 -2
  41. package/dist/services/framework-error.d.ts +8 -1
  42. package/dist/services/interfaces.d.ts +9 -9
  43. package/dist/services/pnp-standard-features.d.ts +1 -1
  44. package/dist/services/section-controller-types.d.ts +30 -0
  45. package/dist/services/spoken-audio-cards.js +1 -1
  46. package/dist/services/tool-config-validation.d.ts +13 -2
  47. package/dist/services/tool-config-validation.js +33 -16
  48. package/dist/services/tool-context.js +29 -13
  49. package/dist/services/tool-providers/TTSToolProvider.d.ts +27 -65
  50. package/dist/services/tool-providers/TTSToolProvider.js +47 -9
  51. package/dist/services/tool-providers/ToolProviderRegistry.d.ts +4 -4
  52. package/dist/services/tool-providers/ToolProviderRegistry.js +4 -16
  53. package/dist/services/tool-providers/index.d.ts +0 -9
  54. package/dist/services/tool-providers/index.js +2 -4
  55. package/dist/services/tools-config-normalizer.d.ts +20 -1
  56. package/dist/services/tts/catalog-span-alignment.d.ts +2 -17
  57. package/dist/services/tts/catalog-span-alignment.js +17 -142
  58. package/dist/services/tts/generated-speech/types.d.ts +0 -12
  59. package/dist/services/tts/highlight-pipeline/boundary-normalizer.js +12 -62
  60. package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +26 -1
  61. package/dist/services/tts/highlight-pipeline/normalize-speech-chunks.js +3 -6
  62. package/dist/services/tts/math-alignment/index.d.ts +0 -5
  63. package/dist/services/tts/math-alignment/index.js +5 -25
  64. package/dist/services/tts/math-alignment/speech-tokenizer.d.ts +9 -1
  65. package/dist/services/tts/math-alignment/speech-tokenizer.js +38 -36
  66. package/dist/services/tts/math-alignment/types.d.ts +4 -2
  67. package/dist/services/tts/math-aware-text-processing.js +44 -2
  68. package/dist/services/tts/math-speech.d.ts +5 -1
  69. package/dist/services/tts/math-speech.js +9 -6
  70. package/dist/services/tts/sre-engine.d.ts +7 -0
  71. package/dist/services/tts/sre-engine.js +11 -0
  72. package/dist/services/tts/sre-locales.d.ts +14 -0
  73. package/dist/services/tts/sre-locales.js +57 -0
  74. package/dist/services/tts/text-processing.d.ts +0 -1
  75. package/dist/services/tts/text-processing.js +0 -1
  76. package/dist/services/tts-runtime-config.d.ts +21 -3
  77. package/dist/services/tts-runtime-config.js +11 -3
  78. package/dist/tools/client.d.ts +1 -3
  79. package/dist/tools/client.js +1 -5
  80. package/dist/tools/internal.d.ts +6 -5
  81. package/dist/tools/internal.js +6 -8
  82. package/package.json +17 -36
  83. package/dist/components/chunks/ItemToolBar-byq80z42.js +0 -40
  84. package/dist/components/chunks/ItemToolBar-d36g3aw4.js +0 -49
  85. package/dist/services/ToolConfigResolver.d.ts +0 -161
  86. package/dist/services/ToolConfigResolver.js +0 -229
  87. package/dist/services/catalog-media.d.ts +0 -56
  88. package/dist/services/catalog-media.js +0 -190
  89. package/dist/services/createDefaultToolRegistry.d.ts +0 -53
  90. package/dist/services/createDefaultToolRegistry.js +0 -45
  91. package/dist/services/tool-providers/CortexToolProvider.d.ts +0 -13
  92. package/dist/services/tool-providers/CortexToolProvider.js +0 -32
  93. package/dist/services/tool-providers/DesmosToolProvider.d.ts +0 -14
  94. package/dist/services/tool-providers/DesmosToolProvider.js +0 -32
  95. package/dist/services/tool-providers/GeoGebraToolProvider.d.ts +0 -16
  96. package/dist/services/tool-providers/GeoGebraToolProvider.js +0 -32
  97. package/dist/services/tool-providers/LazyCalculatorToolProvider.d.ts +0 -35
  98. package/dist/services/tool-providers/LazyCalculatorToolProvider.js +0 -95
  99. package/dist/services/tts/visual-line-ranges.d.ts +0 -18
  100. package/dist/services/tts/visual-line-ranges.js +0 -226
  101. package/dist/tools/index.d.ts +0 -8
  102. package/dist/tools/index.js +0 -10
  103. package/dist/tools/response-discovery.d.ts +0 -61
  104. package/dist/tools/response-discovery.js +0 -113
  105. package/dist/tools/types.d.ts +0 -337
  106. package/dist/tools/types.js +0 -12
  107. package/dist/tools/variant-resolver.d.ts +0 -41
  108. package/dist/tools/variant-resolver.js +0 -207
@@ -1,45 +0,0 @@
1
- /**
2
- * Tool Registry Factory
3
- *
4
- * Creates an empty `ToolRegistry` and installs whatever component overrides and
5
- * lazy module loaders the caller supplies.
6
- *
7
- * It registers nothing by itself, deliberately. Eleven concrete registrations
8
- * used to live in this package, which made the policy and registry core know
9
- * every capability by name and left a host unable to contribute one without a PR
10
- * against this package. The packaged set now lives in the composition layer:
11
- * `createPackagedToolRegistry` from `@pie-players/pie-default-tool-loaders`.
12
- */
13
- import { ToolRegistry } from "./ToolRegistry.js";
14
- import { DEFAULT_TOOL_PLACEMENT } from "./tool-config-defaults.js";
15
- /**
16
- * Create a tool registry.
17
- *
18
- * @returns an empty `ToolRegistry` unless `registrations` is supplied
19
- */
20
- export function createDefaultToolRegistry(options = {}) {
21
- const registry = new ToolRegistry();
22
- for (const registration of Object.values(options.registrations ?? {})) {
23
- if (registration)
24
- registry.register(registration);
25
- }
26
- if (options.toolModuleLoaders &&
27
- Object.keys(options.toolModuleLoaders).length > 0) {
28
- registry.setToolModuleLoaders(options.toolModuleLoaders);
29
- }
30
- registry.setComponentOverrides({
31
- toolTagMap: options.toolTagMap,
32
- toolComponentFactory: options.toolComponentFactory,
33
- toolComponentFactories: options.toolComponentFactories,
34
- });
35
- return registry;
36
- }
37
- /**
38
- * Placement configuration with every level empty.
39
- *
40
- * The only placement default this package can hold: a populated one would name
41
- * capabilities. `PACKAGED_TOOL_PLACEMENT` and
42
- * `SECTION_PLAYER_PREFERRED_TOOL_PLACEMENT` are in
43
- * `@pie-players/pie-default-tool-loaders`.
44
- */
45
- export { DEFAULT_TOOL_PLACEMENT };
@@ -1,13 +0,0 @@
1
- /** Fully bundled open-source calculator adapter for the tool-provider registry. */
2
- import type { CalculatorToolProviderInitConfig, LazyCalculatorProviderDefinition } from "./LazyCalculatorToolProvider.js";
3
- import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
4
- import type { ToolProviderCapabilities } from "./ToolProviderApi.js";
5
- export type CortexToolProviderConfig = CalculatorToolProviderInitConfig;
6
- export declare class CortexToolProvider extends LazyCalculatorToolProvider<CortexToolProviderConfig> {
7
- readonly providerId = "cortex-calculator";
8
- readonly providerName = "PIE Open-Source Calculator";
9
- readonly version = "1";
10
- readonly requiresAuth = false;
11
- protected getDefinition(): LazyCalculatorProviderDefinition<CortexToolProviderConfig>;
12
- getCapabilities(): ToolProviderCapabilities;
13
- }
@@ -1,32 +0,0 @@
1
- /** Fully bundled open-source calculator adapter for the tool-provider registry. */
2
- import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
3
- export class CortexToolProvider extends LazyCalculatorToolProvider {
4
- providerId = "cortex-calculator";
5
- providerName = "PIE Open-Source Calculator";
6
- version = "1";
7
- requiresAuth = false;
8
- getDefinition() {
9
- return {
10
- backend: "cortex",
11
- moduleImportOperation: "cortex-provider-module-import",
12
- loadProvider: async () => {
13
- const module = await import("@pie-players/pie-calculator-cortex");
14
- return module.CortexCalculatorProvider;
15
- },
16
- initializationErrorMessage: "Failed to initialize the PIE open-source calculator provider. Confirm that this browser supports module workers and that the bundled worker assets are available.",
17
- };
18
- }
19
- getCapabilities() {
20
- return {
21
- supportsOffline: true,
22
- requiresAuth: false,
23
- maxInstances: null,
24
- features: {
25
- basic: true,
26
- scientific: true,
27
- graphing: true,
28
- fourFunction: true,
29
- },
30
- };
31
- }
32
- }
@@ -1,14 +0,0 @@
1
- /** Desmos calculator adapter for the generic tool-provider registry. */
2
- import type { CalculatorProviderInit } from "@pie-players/pie-calculator";
3
- import { LazyCalculatorToolProvider, type LazyCalculatorProviderDefinition } from "./LazyCalculatorToolProvider.js";
4
- import type { ToolProviderCapabilities } from "./ToolProviderApi.js";
5
- /** Provider initialization is the provider-neutral calculator contract. */
6
- export type DesmosToolProviderConfig = CalculatorProviderInit;
7
- export declare class DesmosToolProvider extends LazyCalculatorToolProvider<DesmosToolProviderConfig> {
8
- readonly providerId = "desmos-calculator";
9
- readonly providerName = "Desmos Calculator";
10
- readonly version = "1.12";
11
- readonly requiresAuth = true;
12
- protected getDefinition(): LazyCalculatorProviderDefinition<DesmosToolProviderConfig>;
13
- getCapabilities(): ToolProviderCapabilities;
14
- }
@@ -1,32 +0,0 @@
1
- /** Desmos calculator adapter for the generic tool-provider registry. */
2
- import { LazyCalculatorToolProvider, } from "./LazyCalculatorToolProvider.js";
3
- export class DesmosToolProvider extends LazyCalculatorToolProvider {
4
- providerId = "desmos-calculator";
5
- providerName = "Desmos Calculator";
6
- version = "1.12";
7
- requiresAuth = true;
8
- getDefinition() {
9
- return {
10
- backend: "desmos",
11
- moduleImportOperation: "desmos-provider-module-import",
12
- loadProvider: async () => {
13
- const module = await import("@pie-players/pie-calculator-desmos");
14
- return module.DesmosCalculatorProvider;
15
- },
16
- initializationErrorMessage: "Failed to initialize Desmos calculator provider. Check the application key, preloaded API, runtime endpoint, or network access.",
17
- };
18
- }
19
- getCapabilities() {
20
- return {
21
- supportsOffline: false,
22
- requiresAuth: true,
23
- maxInstances: null,
24
- features: {
25
- basic: true,
26
- scientific: true,
27
- graphing: true,
28
- fourFunction: true,
29
- },
30
- };
31
- }
32
- }
@@ -1,16 +0,0 @@
1
- /** GeoGebra calculator adapter for the generic tool-provider registry. */
2
- import type { CalculatorToolProviderInitConfig, LazyCalculatorProviderDefinition } from "./LazyCalculatorToolProvider.js";
3
- import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
4
- import type { ToolProviderCapabilities } from "./ToolProviderApi.js";
5
- export interface GeoGebraToolProviderConfig extends CalculatorToolProviderInitConfig {
6
- scriptUrl?: string;
7
- appletTimeoutMs?: number;
8
- }
9
- export declare class GeoGebraToolProvider extends LazyCalculatorToolProvider<GeoGebraToolProviderConfig> {
10
- readonly providerId = "geogebra-calculator";
11
- readonly providerName = "GeoGebra Calculator";
12
- readonly version = "6";
13
- readonly requiresAuth = false;
14
- protected getDefinition(): LazyCalculatorProviderDefinition<GeoGebraToolProviderConfig>;
15
- getCapabilities(): ToolProviderCapabilities;
16
- }
@@ -1,32 +0,0 @@
1
- /** GeoGebra calculator adapter for the generic tool-provider registry. */
2
- import { LazyCalculatorToolProvider } from "./LazyCalculatorToolProvider.js";
3
- export class GeoGebraToolProvider extends LazyCalculatorToolProvider {
4
- providerId = "geogebra-calculator";
5
- providerName = "GeoGebra Calculator";
6
- version = "6";
7
- requiresAuth = false;
8
- getDefinition() {
9
- return {
10
- backend: "geogebra",
11
- moduleImportOperation: "geogebra-provider-module-import",
12
- loadProvider: async () => {
13
- const module = await import("@pie-players/pie-calculator-geogebra");
14
- return module.GeoGebraCalculatorProvider;
15
- },
16
- initializationErrorMessage: "Failed to initialize GeoGebra calculator provider. Confirm that the deployment may load GeoGebra and that its script URL is reachable.",
17
- };
18
- }
19
- getCapabilities() {
20
- return {
21
- supportsOffline: false,
22
- requiresAuth: false,
23
- maxInstances: null,
24
- features: {
25
- basic: true,
26
- scientific: true,
27
- graphing: true,
28
- fourFunction: false,
29
- },
30
- };
31
- }
32
- }
@@ -1,35 +0,0 @@
1
- import type { CalculatorProvider, CalculatorProviderInit } from "@pie-players/pie-calculator";
2
- import type { ToolProviderApi, ToolProviderCapabilities } from "./ToolProviderApi.js";
3
- export type CalculatorToolProviderInitConfig = Pick<CalculatorProviderInit, "onTelemetry">;
4
- type InitializableCalculatorProvider<TConfig> = CalculatorProvider & {
5
- initialize(config: TConfig): Promise<void>;
6
- };
7
- export interface LazyCalculatorProviderDefinition<TConfig> {
8
- backend: string;
9
- moduleImportOperation: string;
10
- loadProvider: () => Promise<new () => InitializableCalculatorProvider<TConfig>>;
11
- initializationErrorMessage: string;
12
- }
13
- /**
14
- * Shared lazy-module and lifecycle implementation for calculator tool adapters.
15
- * Concrete adapters own only their metadata, capabilities and provider import.
16
- */
17
- export declare abstract class LazyCalculatorToolProvider<TConfig extends CalculatorToolProviderInitConfig> implements ToolProviderApi<TConfig, CalculatorProvider> {
18
- abstract readonly providerId: string;
19
- abstract readonly providerName: string;
20
- readonly category: "calculator";
21
- abstract readonly version: string;
22
- abstract readonly requiresAuth: boolean;
23
- protected abstract getDefinition(): LazyCalculatorProviderDefinition<TConfig>;
24
- abstract getCapabilities(): ToolProviderCapabilities;
25
- private calculatorProvider;
26
- private initializationPromise;
27
- private lifecycleGeneration;
28
- private emitTelemetry;
29
- initialize(config?: TConfig): Promise<void>;
30
- private initializeProvider;
31
- createInstance(): Promise<CalculatorProvider>;
32
- isReady(): boolean;
33
- destroy(): void;
34
- }
35
- export {};
@@ -1,95 +0,0 @@
1
- /**
2
- * Shared lazy-module and lifecycle implementation for calculator tool adapters.
3
- * Concrete adapters own only their metadata, capabilities and provider import.
4
- */
5
- export class LazyCalculatorToolProvider {
6
- category = "calculator";
7
- calculatorProvider = null;
8
- initializationPromise = null;
9
- lifecycleGeneration = 0;
10
- async emitTelemetry(config, eventName, payload) {
11
- try {
12
- await config.onTelemetry?.(eventName, payload);
13
- }
14
- catch (error) {
15
- console.warn(`[${this.providerName}] telemetry callback failed:`, error);
16
- }
17
- }
18
- async initialize(config = {}) {
19
- if (this.calculatorProvider)
20
- return;
21
- if (this.initializationPromise)
22
- return this.initializationPromise;
23
- const generation = ++this.lifecycleGeneration;
24
- const initializationPromise = this.initializeProvider(config, generation);
25
- this.initializationPromise = initializationPromise;
26
- try {
27
- await initializationPromise;
28
- }
29
- finally {
30
- if (this.initializationPromise === initializationPromise) {
31
- this.initializationPromise = null;
32
- }
33
- }
34
- }
35
- async initializeProvider(config, generation) {
36
- const definition = this.getDefinition();
37
- const moduleLoadStartedAt = Date.now();
38
- await this.emitTelemetry(config, "pie-tool-library-load-start", {
39
- toolId: "calculator",
40
- operation: definition.moduleImportOperation,
41
- backend: definition.backend,
42
- });
43
- let ProviderConstructor;
44
- try {
45
- ProviderConstructor = await definition.loadProvider();
46
- await this.emitTelemetry(config, "pie-tool-library-load-success", {
47
- toolId: "calculator",
48
- operation: definition.moduleImportOperation,
49
- backend: definition.backend,
50
- duration: Date.now() - moduleLoadStartedAt,
51
- });
52
- }
53
- catch (error) {
54
- await this.emitTelemetry(config, "pie-tool-library-load-error", {
55
- toolId: "calculator",
56
- operation: definition.moduleImportOperation,
57
- backend: definition.backend,
58
- duration: Date.now() - moduleLoadStartedAt,
59
- errorType: "ToolLibraryLoadError",
60
- message: error instanceof Error ? error.message : String(error),
61
- });
62
- throw new Error(definition.initializationErrorMessage, { cause: error });
63
- }
64
- if (generation !== this.lifecycleGeneration) {
65
- throw new Error(`${this.providerName} initialization was cancelled`);
66
- }
67
- const candidate = new ProviderConstructor();
68
- try {
69
- await candidate.initialize(config);
70
- if (generation !== this.lifecycleGeneration) {
71
- throw new Error(`${this.providerName} initialization was cancelled`);
72
- }
73
- this.calculatorProvider = candidate;
74
- }
75
- catch (error) {
76
- candidate.destroy();
77
- throw new Error(definition.initializationErrorMessage, { cause: error });
78
- }
79
- }
80
- async createInstance() {
81
- if (!this.calculatorProvider) {
82
- throw new Error(`[${this.providerName}] Provider not initialized. Call initialize() first.`);
83
- }
84
- return this.calculatorProvider;
85
- }
86
- isReady() {
87
- return this.calculatorProvider !== null;
88
- }
89
- destroy() {
90
- this.lifecycleGeneration += 1;
91
- this.initializationPromise = null;
92
- this.calculatorProvider?.destroy();
93
- this.calculatorProvider = null;
94
- }
95
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * Derive visual line box ranges inside a root element for TTS read-along.
3
- *
4
- * Cloud TTS (Polly, Google, etc.) only provides word/sentence character offsets.
5
- * “Lines” are layout-dependent (wrap, zoom, font size), so we compute them in
6
- * the browser from the same DOM Range already used for word highlighting.
7
- */
8
- /**
9
- * Intersect `range` with the contents of `root` (document order).
10
- * Returns null if there is no non-empty intersection.
11
- */
12
- export declare function intersectRangeWithElement(range: Range, root: Element): Range | null;
13
- /**
14
- * Returns one Range per visual line that intersects `focus`, expanded to the
15
- * full width of each line within `root`. Falls back to `[intersectedFocus]`
16
- * when layout or caret APIs are unavailable.
17
- */
18
- export declare function visualLineRangesForFocusInRoot(root: Element, focus: Range): Range[];
@@ -1,226 +0,0 @@
1
- /**
2
- * Derive visual line box ranges inside a root element for TTS read-along.
3
- *
4
- * Cloud TTS (Polly, Google, etc.) only provides word/sentence character offsets.
5
- * “Lines” are layout-dependent (wrap, zoom, font size), so we compute them in
6
- * the browser from the same DOM Range already used for word highlighting.
7
- */
8
- const LINE_TOP_EPSILON = 2;
9
- const CARET_INSET = 1;
10
- const HORIZONTAL_PROBE_STEP = 3;
11
- const MAX_HORIZONTAL_PROBES = 400;
12
- const MAX_LINE_RANGES = 48;
13
- function caretRangeAtPoint(doc, x, y) {
14
- const d = doc;
15
- if (typeof d.caretRangeFromPoint === "function") {
16
- try {
17
- return d.caretRangeFromPoint(x, y);
18
- }
19
- catch {
20
- return null;
21
- }
22
- }
23
- const pos = d.caretPositionFromPoint?.(x, y);
24
- if (pos?.offsetNode?.nodeType === Node.TEXT_NODE ||
25
- pos?.offsetNode?.nodeType === Node.ELEMENT_NODE) {
26
- const r = doc.createRange();
27
- try {
28
- r.setStart(pos.offsetNode, pos.offset);
29
- r.collapse(true);
30
- return r;
31
- }
32
- catch {
33
- return null;
34
- }
35
- }
36
- return null;
37
- }
38
- function collapsedRangeTop(r) {
39
- const rects = r.getClientRects();
40
- if (rects.length === 0)
41
- return null;
42
- return rects[0].top;
43
- }
44
- /**
45
- * Intersect `range` with the contents of `root` (document order).
46
- * Returns null if there is no non-empty intersection.
47
- */
48
- export function intersectRangeWithElement(range, root) {
49
- if (typeof document === "undefined")
50
- return null;
51
- if (typeof range.compareBoundaryPoints !== "function")
52
- return null;
53
- try {
54
- const doc = range.startContainer.ownerDocument || document;
55
- const rootRange = doc.createRange();
56
- rootRange.selectNodeContents(root);
57
- if (range.compareBoundaryPoints(Range.END_TO_START, rootRange) <= 0) {
58
- return null;
59
- }
60
- if (range.compareBoundaryPoints(Range.START_TO_END, rootRange) >= 0) {
61
- return null;
62
- }
63
- const out = doc.createRange();
64
- if (range.compareBoundaryPoints(Range.START_TO_START, rootRange) < 0) {
65
- out.setStart(rootRange.startContainer, rootRange.startOffset);
66
- }
67
- else {
68
- out.setStart(range.startContainer, range.startOffset);
69
- }
70
- if (range.compareBoundaryPoints(Range.END_TO_END, rootRange) > 0) {
71
- out.setEnd(rootRange.endContainer, rootRange.endOffset);
72
- }
73
- else {
74
- out.setEnd(range.endContainer, range.endOffset);
75
- }
76
- if (out.collapsed)
77
- return null;
78
- return out;
79
- }
80
- catch {
81
- return null;
82
- }
83
- }
84
- function lineKeyForRect(top) {
85
- return Math.round(top / LINE_TOP_EPSILON);
86
- }
87
- function extendLineEdge(doc, root, refTop, midY, startX, rootLeft, rootRight, direction) {
88
- let lastGood = null;
89
- let x = startX;
90
- if (direction === "left") {
91
- for (let i = 0; i < MAX_HORIZONTAL_PROBES && x >= rootLeft + CARET_INSET; i++) {
92
- const cr = caretRangeAtPoint(doc, x, midY);
93
- if (!cr || !rootContainsNode(root, cr.startContainer))
94
- break;
95
- const t = collapsedRangeTop(cr);
96
- if (t === null || Math.abs(t - refTop) > LINE_TOP_EPSILON)
97
- break;
98
- lastGood = cr.cloneRange();
99
- x -= HORIZONTAL_PROBE_STEP;
100
- }
101
- }
102
- else {
103
- for (let i = 0; i < MAX_HORIZONTAL_PROBES && x <= rootRight - CARET_INSET; i++) {
104
- const cr = caretRangeAtPoint(doc, x, midY);
105
- if (!cr || !rootContainsNode(root, cr.startContainer))
106
- break;
107
- const t = collapsedRangeTop(cr);
108
- if (t === null || Math.abs(t - refTop) > LINE_TOP_EPSILON)
109
- break;
110
- lastGood = cr.cloneRange();
111
- x += HORIZONTAL_PROBE_STEP;
112
- }
113
- }
114
- return lastGood;
115
- }
116
- function rootContainsNode(root, node) {
117
- if (typeof root.contains !== "function")
118
- return false;
119
- try {
120
- return root.contains(node);
121
- }
122
- catch {
123
- return false;
124
- }
125
- }
126
- function fallbackSingleRangeFromFocus(focus) {
127
- try {
128
- const doc = focus.startContainer.ownerDocument || document;
129
- const r = doc.createRange();
130
- r.setStart(focus.startContainer, focus.startOffset);
131
- r.setEnd(focus.endContainer, focus.endOffset);
132
- return [r];
133
- }
134
- catch {
135
- return [];
136
- }
137
- }
138
- /**
139
- * Returns one Range per visual line that intersects `focus`, expanded to the
140
- * full width of each line within `root`. Falls back to `[intersectedFocus]`
141
- * when layout or caret APIs are unavailable.
142
- */
143
- export function visualLineRangesForFocusInRoot(root, focus) {
144
- if (typeof document === "undefined")
145
- return [];
146
- if (!focus.startContainer) {
147
- return [];
148
- }
149
- const doc = focus.startContainer.ownerDocument || document;
150
- const intersected = intersectRangeWithElement(focus, root);
151
- if (!intersected) {
152
- return fallbackSingleRangeFromFocus(focus);
153
- }
154
- let rects;
155
- try {
156
- rects = Array.from(intersected.getClientRects()).filter((r) => r.width > 0 && r.height > 0);
157
- }
158
- catch {
159
- return [intersected.cloneRange()];
160
- }
161
- if (rects.length === 0) {
162
- return [intersected.cloneRange()];
163
- }
164
- let rootBounds;
165
- try {
166
- rootBounds = root.getBoundingClientRect();
167
- }
168
- catch {
169
- return [intersected.cloneRange()];
170
- }
171
- const groups = new Map();
172
- for (const rect of rects) {
173
- const key = lineKeyForRect(rect.top);
174
- const list = groups.get(key);
175
- if (list)
176
- list.push(rect);
177
- else
178
- groups.set(key, [rect]);
179
- }
180
- const sortedKeys = Array.from(groups.keys()).sort((a, b) => a - b);
181
- const out = [];
182
- for (const key of sortedKeys) {
183
- if (out.length >= MAX_LINE_RANGES)
184
- break;
185
- const group = groups.get(key);
186
- if (!group?.length)
187
- continue;
188
- let sumTop = 0;
189
- let sumMid = 0;
190
- let minL = Infinity;
191
- let maxR = -Infinity;
192
- for (const r of group) {
193
- sumTop += r.top;
194
- sumMid += r.top + r.height / 2;
195
- minL = Math.min(minL, r.left);
196
- maxR = Math.max(maxR, r.right);
197
- }
198
- const refTop = sumTop / group.length;
199
- const midY = sumMid / group.length;
200
- const leftEdge = extendLineEdge(doc, root, refTop, midY, minL, rootBounds.left, rootBounds.right, "left");
201
- const rightEdge = extendLineEdge(doc, root, refTop, midY, maxR, rootBounds.left, rootBounds.right, "right");
202
- if (!leftEdge || !rightEdge) {
203
- const fallback = intersected.cloneRange();
204
- return [fallback];
205
- }
206
- const lineRange = doc.createRange();
207
- try {
208
- lineRange.setStart(leftEdge.startContainer, leftEdge.startOffset);
209
- lineRange.setEnd(rightEdge.startContainer, rightEdge.startOffset);
210
- }
211
- catch {
212
- return [intersected.cloneRange()];
213
- }
214
- if (lineRange.collapsed) {
215
- return [intersected.cloneRange()];
216
- }
217
- const clipped = intersectRangeWithElement(lineRange, root);
218
- if (clipped && !clipped.collapsed) {
219
- out.push(clipped);
220
- }
221
- else {
222
- return [intersected.cloneRange()];
223
- }
224
- }
225
- return out.length > 0 ? out : [intersected.cloneRange()];
226
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Tool system exports
3
- *
4
- * For custom elements and client-side code, use
5
- * '@pie-players/pie-assessment-toolkit/tools/client' instead.
6
- */
7
- export * from "./client.js";
8
- export { VariantResolverImpl } from "./variant-resolver.js";
@@ -1,10 +0,0 @@
1
- /**
2
- * Tool system exports
3
- *
4
- * For custom elements and client-side code, use
5
- * '@pie-players/pie-assessment-toolkit/tools/client' instead.
6
- */
7
- // Re-export everything from client.ts (client-safe code)
8
- export * from "./client.js";
9
- // Variant resolver
10
- export { VariantResolverImpl } from "./variant-resolver.js";
@@ -1,61 +0,0 @@
1
- /**
2
- * Response Discovery Service
3
- * Finds and manages PIE response components for tool-to-response integration
4
- *
5
- * Enables tools (e.g., calculator) to insert content into response fields
6
- * Based on capability-based interface pattern (inspired by VS Code extension API)
7
- */
8
- import type { ContentFormat, PIEResponseComponent, ResponseDiscoveryService } from "./types.js";
9
- export declare class ResponseDiscoveryServiceImpl implements ResponseDiscoveryService {
10
- private responses;
11
- private activeResponseId;
12
- private activeResponseListeners;
13
- /**
14
- * Get currently active (focused) response component
15
- */
16
- getActiveResponse(): PIEResponseComponent | null;
17
- /**
18
- * Get response by ID
19
- */
20
- getResponse(responseId: string): PIEResponseComponent | null;
21
- /**
22
- * Get all registered responses
23
- */
24
- getAllResponses(): PIEResponseComponent[];
25
- /**
26
- * Get responses that accept a specific content format
27
- */
28
- getResponsesAccepting(format: ContentFormat): PIEResponseComponent[];
29
- /**
30
- * Register a response component
31
- */
32
- registerResponse(response: PIEResponseComponent): void;
33
- /**
34
- * Unregister a response component
35
- */
36
- unregisterResponse(responseId: string): void;
37
- /**
38
- * Explicitly signal that a registered response is active.
39
- */
40
- signalActive(responseId: string): void;
41
- /**
42
- * Explicitly signal that a response is no longer active.
43
- */
44
- signalInactive(responseId: string): void;
45
- /**
46
- * Set active response (internal use)
47
- */
48
- private setActiveResponse;
49
- /**
50
- * Listen for active response changes
51
- */
52
- onActiveResponseChanged(listener: (response: PIEResponseComponent | null) => void): void;
53
- /**
54
- * Clear all responses (for cleanup)
55
- */
56
- clear(): void;
57
- }
58
- /**
59
- * Singleton instance
60
- */
61
- export declare const responseDiscovery: ResponseDiscoveryServiceImpl;