@pie-players/pie-players-shared 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 (123) hide show
  1. package/README.md +27 -1
  2. package/dist/components/vendor/nds/README.md +7 -5
  3. package/dist/config/profile.d.ts +0 -2
  4. package/dist/config/profile.js +2 -8
  5. package/dist/i18n/index.d.ts +2 -3
  6. package/dist/i18n/index.js +2 -3
  7. package/dist/i18n/messages/en-US.d.ts +10 -0
  8. package/dist/i18n/messages/en-US.js +12 -2
  9. package/dist/i18n/messages/nl-NL.d.ts +6 -0
  10. package/dist/i18n/messages/nl-NL.js +8 -2
  11. package/dist/i18n/provider.d.ts +4 -5
  12. package/dist/i18n/provider.js +4 -5
  13. package/dist/index.d.ts +4 -2
  14. package/dist/index.js +3 -1
  15. package/dist/instrumentation/index.d.ts +5 -4
  16. package/dist/instrumentation/index.js +5 -4
  17. package/dist/instrumentation/new-relic-agent.d.ts +20 -0
  18. package/dist/instrumentation/new-relic-agent.js +24 -0
  19. package/dist/instrumentation/providers/BaseInstrumentationProvider.d.ts +5 -4
  20. package/dist/instrumentation/providers/NewRelicInstrumentationProvider.d.ts +7 -7
  21. package/dist/instrumentation/providers/NewRelicInstrumentationProvider.js +21 -32
  22. package/dist/instrumentation/types.d.ts +7 -3
  23. package/dist/loader-config.d.ts +16 -6
  24. package/dist/loaders/controller-loading.d.ts +14 -0
  25. package/dist/loaders/controller-loading.js +12 -0
  26. package/dist/loaders/defaults.d.ts +10 -0
  27. package/dist/loaders/defaults.js +10 -0
  28. package/dist/loaders/element-loader.d.ts +20 -8
  29. package/dist/loaders/element-loader.js +102 -36
  30. package/dist/loaders/element-package-policy.d.ts +2 -0
  31. package/dist/loaders/element-package-policy.js +2 -1
  32. package/dist/loaders/esm-adapter.d.ts +18 -0
  33. package/dist/loaders/esm-adapter.js +617 -102
  34. package/dist/loaders/iife-adapter.d.ts +0 -5
  35. package/dist/loaders/iife-adapter.js +3 -9
  36. package/dist/loaders/index.d.ts +10 -3
  37. package/dist/loaders/index.js +8 -3
  38. package/dist/loaders/mathjax-version-conflict.d.ts +17 -0
  39. package/dist/loaders/mathjax-version-conflict.js +51 -0
  40. package/dist/loaders/module-shim.d.ts +12 -0
  41. package/dist/loaders/module-shim.js +12 -0
  42. package/dist/loaders/preloaded-alignment.d.ts +24 -0
  43. package/dist/loaders/preloaded-alignment.js +57 -0
  44. package/dist/loaders/preloaded-authored-tags.d.ts +26 -0
  45. package/dist/loaders/preloaded-authored-tags.js +69 -0
  46. package/dist/loaders/preloaded-registration.d.ts +56 -0
  47. package/dist/loaders/preloaded-registration.js +129 -0
  48. package/dist/media/index.d.ts +69 -0
  49. package/dist/media/index.js +194 -0
  50. package/dist/pie/authoring.d.ts +1 -1
  51. package/dist/pie/authoring.js +25 -18
  52. package/dist/pie/element-announcements.d.ts +39 -0
  53. package/dist/pie/element-announcements.js +67 -0
  54. package/dist/pie/element-observer.d.ts +3 -1
  55. package/dist/pie/element-observer.js +1 -0
  56. package/dist/pie/index.d.ts +6 -4
  57. package/dist/pie/index.js +6 -3
  58. package/dist/pie/initialization.js +13 -22
  59. package/dist/pie/initialize-element.d.ts +3 -0
  60. package/dist/pie/initialize-element.js +3 -4
  61. package/dist/pie/instrumentation-event-map.js +2 -9
  62. package/dist/pie/instrumentation-provider-resolution.d.ts +2 -1
  63. package/dist/pie/instrumentation-provider-resolution.js +0 -1
  64. package/dist/pie/item-session-contract.d.ts +47 -0
  65. package/dist/pie/item-session-contract.js +196 -9
  66. package/dist/pie/markup-math.d.ts +20 -0
  67. package/dist/pie/markup-math.js +118 -0
  68. package/dist/pie/math-rendering.d.ts +10 -21
  69. package/dist/pie/math-rendering.js +50 -35
  70. package/dist/pie/registry.d.ts +13 -1
  71. package/dist/pie/registry.js +39 -1
  72. package/dist/pie/resource-monitor.d.ts +6 -33
  73. package/dist/pie/resource-monitor.js +14 -213
  74. package/dist/pie/scoring.d.ts +11 -2
  75. package/dist/pie/scoring.js +18 -16
  76. package/dist/pie/session-commit.d.ts +121 -0
  77. package/dist/pie/session-commit.js +420 -0
  78. package/dist/pie/session-snapshot.d.ts +80 -0
  79. package/dist/pie/session-snapshot.js +166 -0
  80. package/dist/pie/tag-names.d.ts +1 -0
  81. package/dist/pie/tag-names.js +1 -0
  82. package/dist/pie/types.d.ts +4 -5
  83. package/dist/pie/types.js +1 -0
  84. package/dist/pie/updates.d.ts +2 -2
  85. package/dist/pie/updates.js +33 -15
  86. package/dist/pie/versioned-tag.d.ts +4 -0
  87. package/dist/pie/versioned-tag.js +4 -0
  88. package/dist/security/index.d.ts +2 -3
  89. package/dist/security/index.js +2 -3
  90. package/dist/security/sanitize-item-markup.d.ts +0 -2
  91. package/dist/security/sanitize-item-markup.js +0 -4
  92. package/dist/security/sanitize-svg-icon.d.ts +0 -2
  93. package/dist/security/sanitize-svg-icon.js +0 -5
  94. package/dist/security/wrap-overwide.d.ts +5 -0
  95. package/dist/security/wrap-overwide.js +16 -0
  96. package/dist/timed-media/policy.js +5 -16
  97. package/dist/types/index.d.ts +30 -311
  98. package/dist/types/index.js +0 -68
  99. package/dist/ui/attribute-coercion.d.ts +12 -0
  100. package/dist/ui/attribute-coercion.js +33 -0
  101. package/dist/ui/content-styles.d.ts +18 -16
  102. package/dist/ui/content-styles.js +67 -36
  103. package/dist/ui/overlay-containment.d.ts +31 -0
  104. package/dist/ui/overlay-containment.js +63 -0
  105. package/dist/ui/overlay-placement.d.ts +110 -0
  106. package/dist/ui/overlay-placement.js +222 -0
  107. package/dist/ui/pointer-gesture.d.ts +32 -0
  108. package/dist/ui/pointer-gesture.js +56 -0
  109. package/dist/ui/pointer-rotate.d.ts +29 -0
  110. package/dist/ui/pointer-rotate.js +39 -0
  111. package/package.json +21 -17
  112. package/dist/pie/component-context.d.ts +0 -21
  113. package/dist/pie/component-context.js +0 -29
  114. package/dist/pie/player-initializer.d.ts +0 -54
  115. package/dist/pie/player-initializer.js +0 -122
  116. package/dist/security/wrap-model-rich-content.d.ts +0 -1
  117. package/dist/security/wrap-model-rich-content.js +0 -40
  118. package/dist/server/npm-auth-env.d.ts +0 -13
  119. package/dist/server/npm-auth-env.js +0 -64
  120. package/dist/server/npm-registry.d.ts +0 -7
  121. package/dist/server/npm-registry.js +0 -59
  122. package/dist/ui/debug-panel-persistence.d.ts +0 -17
  123. package/dist/ui/debug-panel-persistence.js +0 -37
@@ -0,0 +1,56 @@
1
+ /**
2
+ * The lifecycle of one pointer gesture on a tool overlay: which pointer drives
3
+ * it, the listeners on the element that captured it, and every way it can end.
4
+ * `pointercancel` and `lostpointercapture` end it as well as `pointerup`,
5
+ * because iPadOS cancels a touch it takes over for a system gesture, and a
6
+ * gesture that waited for `pointerup` would stay stuck to the next touch.
7
+ *
8
+ * The claim calls `preventDefault`, which keeps a touch from scrolling or
9
+ * zooming the page and a mouse press from selecting text, and also suppresses
10
+ * the press's default focus: a caller whose keyboard alternatives act on a
11
+ * focused element focuses it itself.
12
+ */
13
+ export function createPointerGesture(args) {
14
+ let pointerId = null;
15
+ let target = null;
16
+ const handleMove = (event) => {
17
+ if (event.pointerId === pointerId)
18
+ args.onMove(event);
19
+ };
20
+ const handleEnd = (event) => {
21
+ if (event.pointerId === pointerId)
22
+ release();
23
+ };
24
+ function release() {
25
+ const releasedTarget = target;
26
+ const releasedPointerId = pointerId;
27
+ pointerId = null;
28
+ target = null;
29
+ if (!releasedTarget || releasedPointerId === null)
30
+ return;
31
+ releasedTarget.removeEventListener("pointermove", handleMove);
32
+ releasedTarget.removeEventListener("pointerup", handleEnd);
33
+ releasedTarget.removeEventListener("pointercancel", handleEnd);
34
+ releasedTarget.removeEventListener("lostpointercapture", handleEnd);
35
+ if (releasedTarget.hasPointerCapture(releasedPointerId)) {
36
+ releasedTarget.releasePointerCapture(releasedPointerId);
37
+ }
38
+ args.onEnd();
39
+ }
40
+ return {
41
+ isActive: () => pointerId !== null,
42
+ begin(event, nextTarget) {
43
+ if (event.button !== 0 || pointerId !== null)
44
+ return false;
45
+ pointerId = event.pointerId;
46
+ target = nextTarget;
47
+ nextTarget.addEventListener("pointermove", handleMove);
48
+ nextTarget.addEventListener("pointerup", handleEnd);
49
+ nextTarget.addEventListener("pointercancel", handleEnd);
50
+ nextTarget.addEventListener("lostpointercapture", handleEnd);
51
+ event.preventDefault();
52
+ return true;
53
+ },
54
+ release,
55
+ };
56
+ }
@@ -0,0 +1,29 @@
1
+ import type { PointerDragPosition } from "./pointer-drag.js";
2
+ export interface PointerRotateControllerArgs {
3
+ /** Current rotation in degrees. */
4
+ getRotation: () => number;
5
+ /** Receives the next rotation in degrees, normalised to `[0, 360)`. */
6
+ setRotation: (degrees: number) => void;
7
+ }
8
+ export interface PointerRotateController {
9
+ isRotating: () => boolean;
10
+ /**
11
+ * Begin tracking a rotation from a pointerdown on a rotation handle. `pivot`
12
+ * is the point the element turns about, in client coordinates. As with
13
+ * `createPointerDragController`, callers own pointer-capture release and
14
+ * listener attach/detach.
15
+ */
16
+ startRotating: (event: PointerEvent, container: Element, pivot: PointerDragPosition) => void;
17
+ /** No-ops when a rotation isn't in progress. */
18
+ handlePointerMove: (event: PointerEvent) => void;
19
+ endRotating: () => void;
20
+ }
21
+ /** Normalises an angle in degrees to `[0, 360)`. */
22
+ export declare function normalizeDegrees(degrees: number): number;
23
+ /**
24
+ * Tracks a pointer-capture-based rotation about a fixed pivot: the element
25
+ * turns by the angle the pointer sweeps around the pivot since the press, so
26
+ * grabbing the handle anywhere on its hit area causes no initial jump. The
27
+ * rotation counterpart of `createPointerDragController`.
28
+ */
29
+ export declare function createPointerRotateController(args: PointerRotateControllerArgs): PointerRotateController;
@@ -0,0 +1,39 @@
1
+ /** Normalises an angle in degrees to `[0, 360)`. */
2
+ export function normalizeDegrees(degrees) {
3
+ const turned = degrees % 360;
4
+ return turned < 0 ? turned + 360 : turned;
5
+ }
6
+ function angleDegrees(pivot, x, y) {
7
+ return (Math.atan2(y - pivot.y, x - pivot.x) * 180) / Math.PI;
8
+ }
9
+ /**
10
+ * Tracks a pointer-capture-based rotation about a fixed pivot: the element
11
+ * turns by the angle the pointer sweeps around the pivot since the press, so
12
+ * grabbing the handle anywhere on its hit area causes no initial jump. The
13
+ * rotation counterpart of `createPointerDragController`.
14
+ */
15
+ export function createPointerRotateController(args) {
16
+ let rotating = false;
17
+ let pivot = { x: 0, y: 0 };
18
+ let startAngle = 0;
19
+ let startRotation = 0;
20
+ return {
21
+ isRotating: () => rotating,
22
+ startRotating(event, container, nextPivot) {
23
+ container.setPointerCapture(event.pointerId);
24
+ rotating = true;
25
+ pivot = nextPivot;
26
+ startAngle = angleDegrees(pivot, event.clientX, event.clientY);
27
+ startRotation = args.getRotation();
28
+ },
29
+ handlePointerMove(event) {
30
+ if (!rotating)
31
+ return;
32
+ const swept = angleDegrees(pivot, event.clientX, event.clientY) - startAngle;
33
+ args.setRotation(normalizeDegrees(startRotation + swept));
34
+ },
35
+ endRotating() {
36
+ rotating = false;
37
+ },
38
+ };
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-players/pie-players-shared",
3
- "version": "0.3.72",
3
+ "version": "0.3.74",
4
4
  "type": "module",
5
5
  "description": "Shared runtime + UI utilities for PIE players",
6
6
  "license": "MIT",
@@ -45,6 +45,10 @@
45
45
  "types": "./dist/timed-media/index.d.ts",
46
46
  "import": "./dist/timed-media/index.js"
47
47
  },
48
+ "./media": {
49
+ "types": "./dist/media/index.d.ts",
50
+ "import": "./dist/media/index.js"
51
+ },
48
52
  "./pie": {
49
53
  "types": "./dist/pie/index.d.ts",
50
54
  "import": "./dist/pie/index.js"
@@ -57,14 +61,6 @@
57
61
  "types": "./dist/loaders/index.d.ts",
58
62
  "import": "./dist/loaders/index.js"
59
63
  },
60
- "./server/npm-registry": {
61
- "types": "./dist/server/npm-registry.d.ts",
62
- "import": "./dist/server/npm-registry.js"
63
- },
64
- "./server/npm-auth-env": {
65
- "types": "./dist/server/npm-auth-env.d.ts",
66
- "import": "./dist/server/npm-auth-env.js"
67
- },
68
64
  "./i18n": {
69
65
  "types": "./dist/i18n/index.d.ts",
70
66
  "import": "./dist/i18n/index.js"
@@ -89,6 +85,10 @@
89
85
  "types": "./dist/components/vendor/nds/nds-icon-button.d.ts",
90
86
  "import": "./dist/components/vendor/nds/nds-icon-button.js"
91
87
  },
88
+ "./ui/attribute-coercion": {
89
+ "types": "./dist/ui/attribute-coercion.d.ts",
90
+ "import": "./dist/ui/attribute-coercion.js"
91
+ },
92
92
  "./ui/content-styles": {
93
93
  "types": "./dist/ui/content-styles.d.ts",
94
94
  "import": "./dist/ui/content-styles.js"
@@ -103,27 +103,29 @@
103
103
  ],
104
104
  "dependencies": {
105
105
  "@pie-lib/math-rendering-module": "6.0.0",
106
- "dompurify": "^3.4.14",
106
+ "dompurify": "^3.4.16",
107
107
  "semver": "^7.8.5"
108
108
  },
109
109
  "scripts": {
110
- "build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && mkdir -p dist/components && cp -R src/components/vendor dist/components/vendor",
110
+ "build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && node scripts/bundle-vendored-modules.mjs && mkdir -p dist/components && cp -R src/components/vendor dist/components/vendor",
111
111
  "dev": "tsc -p tsconfig.json --watch",
112
112
  "typecheck": "tsc -p tsconfig.json --noEmit",
113
- "lint": "biome check .",
113
+ "lint": "biome lint .",
114
114
  "check": "tsc -p tsconfig.json --noEmit",
115
115
  "test": "bun test",
116
116
  "check-i18n": "bun run src/i18n/scripts/check-coverage.ts",
117
117
  "scan-hardcoded": "bun run src/i18n/scripts/scan-hardcoded.ts"
118
118
  },
119
119
  "devDependencies": {
120
- "@biomejs/biome": "^2.5.11",
121
- "@happy-dom/global-registrator": "^20.11.15",
122
- "@playwright/test": "^1.62.1",
120
+ "@biomejs/biome": "^2.5.15",
121
+ "@happy-dom/global-registrator": "^20.14.5",
122
+ "@pie-element/shared-math-rendering-mathjax": "0.1.2",
123
+ "@playwright/test": "^1.63.0",
123
124
  "@types/semver": "^7.8.0",
125
+ "es-module-shims": "^2.8.4",
124
126
  "esbuild": "^0.28.2",
125
127
  "glob": "^13.0.0",
126
- "svelte": "^5.57.0",
128
+ "svelte": "^5.57.1",
127
129
  "typescript": "^5.9.3"
128
130
  },
129
131
  "homepage": "https://github.com/pie-framework/pie-players/tree/master/packages/players-shared#readme",
@@ -133,5 +135,7 @@
133
135
  "engines": {
134
136
  "node": ">=20.0.0"
135
137
  },
136
- "sideEffects": true
138
+ "sideEffects": [
139
+ "./dist/components/vendor/nds/*.js"
140
+ ]
137
141
  }
@@ -1,21 +0,0 @@
1
- /**
2
- * Component context stack for PIE mini-players.
3
- *
4
- * Used to attribute resource load failures (fonts/images/etc.) to the currently
5
- * active mini-player component.
6
- */
7
- export type ComponentContext = {
8
- componentName: string;
9
- elementType?: string;
10
- itemId?: string;
11
- timestamp: number;
12
- };
13
- /**
14
- * Register a component as active (call when component mounts).
15
- * Returns a cleanup function to call when the component unmounts.
16
- */
17
- export declare function registerActiveComponent(context: ComponentContext): () => void;
18
- /**
19
- * Get the current active component context (top of the stack).
20
- */
21
- export declare function getCurrentComponentContext(): ComponentContext | null;
@@ -1,29 +0,0 @@
1
- /**
2
- * Component context stack for PIE mini-players.
3
- *
4
- * Used to attribute resource load failures (fonts/images/etc.) to the currently
5
- * active mini-player component.
6
- */
7
- // Track active components (stack-based for nested components)
8
- const activeComponents = [];
9
- /**
10
- * Register a component as active (call when component mounts).
11
- * Returns a cleanup function to call when the component unmounts.
12
- */
13
- export function registerActiveComponent(context) {
14
- activeComponents.push(context);
15
- return () => {
16
- const index = activeComponents.indexOf(context);
17
- if (index > -1) {
18
- activeComponents.splice(index, 1);
19
- }
20
- };
21
- }
22
- /**
23
- * Get the current active component context (top of the stack).
24
- */
25
- export function getCurrentComponentContext() {
26
- return activeComponents.length > 0
27
- ? activeComponents[activeComponents.length - 1]
28
- : null;
29
- }
@@ -1,54 +0,0 @@
1
- /**
2
- * Shared PIE player initialization logic
3
- * Used by preloaded static player runtimes
4
- */
5
- export interface PiePlayerConfig {
6
- env: any;
7
- addCorrectResponse: boolean;
8
- session: any[];
9
- externalStyleUrls?: string;
10
- customClassName?: string;
11
- containerClass?: string;
12
- passageContainerClass?: string;
13
- }
14
- export interface ItemData {
15
- item: {
16
- config: any;
17
- };
18
- passage?: {
19
- config: {
20
- markup?: string;
21
- };
22
- };
23
- }
24
- export interface PiePlayerElements {
25
- playerEl: HTMLElement;
26
- passageMarkup: string | null;
27
- }
28
- /**
29
- * Initialize PIE player with item data
30
- * Shared initialization for preloaded/static player entrypoints.
31
- */
32
- export declare function initializePiePlayer(itemData: ItemData, config: PiePlayerConfig, elements: PiePlayerElements): Promise<void>;
33
- /**
34
- * Extract passage markup from item data
35
- */
36
- export declare function extractPassageMarkup(itemData: ItemData): string | null;
37
- /**
38
- * Ensure pie-player web component is loaded
39
- */
40
- export declare function ensurePiePlayerLoaded(): Promise<void>;
41
- /**
42
- * Build event listeners map for PIE elements
43
- */
44
- export declare function buildEventListenersMap(config: any, onSessionChanged: (detail: any) => void): Record<string, Record<string, (e: CustomEvent) => void>> | undefined;
45
- /**
46
- * Build URL parameters for API request
47
- * Shared by preloaded/static player entrypoints.
48
- */
49
- export declare function buildApiParams(env: any, addCorrectResponse: boolean): URLSearchParams;
50
- /**
51
- * Fetch item data from API
52
- * Shared by preloaded/static player entrypoints.
53
- */
54
- export declare function fetchItemData(apiBaseUrl: string, itemId: string, token: string, endpoint: "packaged" | "data-only", env: any, addCorrectResponse: boolean, signal?: AbortSignal): Promise<any>;
@@ -1,122 +0,0 @@
1
- /**
2
- * Shared PIE player initialization logic
3
- * Used by preloaded static player runtimes
4
- */
5
- /**
6
- * Initialize PIE player with item data
7
- * Shared initialization for preloaded/static player entrypoints.
8
- */
9
- export async function initializePiePlayer(itemData, config, elements) {
10
- const { playerEl } = elements;
11
- if (!itemData.item?.config || !playerEl) {
12
- throw new Error("Missing item config or player element");
13
- }
14
- // Ensure pie-player is loaded
15
- await ensurePiePlayerLoaded();
16
- const defaultEnv = config.env || { mode: "evaluate", role: "instructor" };
17
- // Configure player element
18
- playerEl.config = itemData.item.config;
19
- playerEl.env = defaultEnv;
20
- const shouldShowCorrect = !!(config.addCorrectResponse ||
21
- (defaultEnv.mode === "evaluate" && defaultEnv.role === "instructor"));
22
- playerEl.addCorrectResponse = shouldShowCorrect;
23
- // Forward additional properties
24
- playerEl.session = {
25
- id: "",
26
- data: Array.isArray(config.session) ? config.session : [],
27
- };
28
- if (config.externalStyleUrls) {
29
- playerEl.externalStyleUrls = config.externalStyleUrls;
30
- }
31
- if (config.customClassName) {
32
- playerEl.customClassName = config.customClassName;
33
- }
34
- if (config.containerClass) {
35
- playerEl.containerClass = config.containerClass;
36
- }
37
- if (config.passageContainerClass) {
38
- playerEl.passageContainerClass = config.passageContainerClass;
39
- }
40
- }
41
- /**
42
- * Extract passage markup from item data
43
- */
44
- export function extractPassageMarkup(itemData) {
45
- return itemData.passage?.config?.markup || null;
46
- }
47
- /**
48
- * Ensure pie-player web component is loaded
49
- */
50
- export async function ensurePiePlayerLoaded() {
51
- if (customElements.get("pie-player"))
52
- return;
53
- const url = "https://cdn.jsdelivr.net/npm/@pie-players/pie-player-components@latest/dist/pie-player-components/pie-player-components.esm.js";
54
- await new Promise((resolve, reject) => {
55
- const existing = document.querySelector("script[data-pie-player]");
56
- if (existing) {
57
- existing.addEventListener("load", () => resolve());
58
- existing.addEventListener("error", () => reject(new Error("failed to load pie-player")));
59
- return;
60
- }
61
- const s = document.createElement("script");
62
- s.type = "module";
63
- s.dataset.piePlayer = "true";
64
- s.src = url;
65
- s.addEventListener("load", () => resolve());
66
- s.addEventListener("error", () => reject(new Error("failed to load pie-player")));
67
- document.head.appendChild(s);
68
- });
69
- await customElements.whenDefined("pie-player");
70
- }
71
- /**
72
- * Build event listeners map for PIE elements
73
- */
74
- export function buildEventListenersMap(config, onSessionChanged) {
75
- if (!config?.elements)
76
- return undefined;
77
- const listeners = {};
78
- Object.keys(config.elements).forEach((elName) => {
79
- listeners[elName] = {
80
- "session-changed": (e) => onSessionChanged(e.detail),
81
- };
82
- });
83
- return listeners;
84
- }
85
- /**
86
- * Build URL parameters for API request
87
- * Shared by preloaded/static player entrypoints.
88
- */
89
- export function buildApiParams(env, addCorrectResponse) {
90
- const params = new URLSearchParams();
91
- if (env && typeof env === "object") {
92
- if (env.mode)
93
- params.set("mode", String(env.mode));
94
- if (env.role)
95
- params.set("role", String(env.role));
96
- }
97
- if (addCorrectResponse)
98
- params.set("addCorrectResponse", "true");
99
- return params;
100
- }
101
- /**
102
- * Fetch item data from API
103
- * Shared by preloaded/static player entrypoints.
104
- */
105
- export async function fetchItemData(apiBaseUrl, itemId, token, endpoint, env, addCorrectResponse, signal) {
106
- if (typeof window === "undefined" || typeof document === "undefined") {
107
- throw new Error("PIE initialization must run in browser");
108
- }
109
- const params = buildApiParams(env, addCorrectResponse);
110
- const apiUrl = `${apiBaseUrl}/api/item/${itemId}/${endpoint}${params.toString() ? `?${params.toString()}` : ""}`;
111
- const response = await fetch(apiUrl, {
112
- headers: {
113
- Authorization: `Bearer ${token}`,
114
- Accept: "application/json",
115
- },
116
- signal,
117
- });
118
- if (!response.ok) {
119
- throw new Error(`Failed to fetch item data: ${response.statusText}`);
120
- }
121
- return await response.json();
122
- }
@@ -1 +0,0 @@
1
- export declare function wrapModelRichContent<T>(model: T): T;
@@ -1,40 +0,0 @@
1
- import { wrapOverwideImages } from "./wrap-overwide-images.js";
2
- import { wrapOverwideTables } from "./wrap-overwide-tables.js";
3
- const RICH_CONTENT_TAG_REGEX = /<(?:img|table)\b/i;
4
- const SKIPPED_KEYS = new Set(["accessibilityCatalogs"]);
5
- function maybeWrapRichContent(value) {
6
- if (!RICH_CONTENT_TAG_REGEX.test(value))
7
- return value;
8
- return wrapOverwideTables(wrapOverwideImages(value));
9
- }
10
- function wrapValue(value, parentKey) {
11
- if (parentKey && SKIPPED_KEYS.has(parentKey))
12
- return value;
13
- if (typeof value === "string")
14
- return maybeWrapRichContent(value);
15
- if (!value || typeof value !== "object")
16
- return value;
17
- if (Array.isArray(value)) {
18
- let changed = false;
19
- const next = value.map((entry) => {
20
- const wrapped = wrapValue(entry);
21
- if (wrapped !== entry)
22
- changed = true;
23
- return wrapped;
24
- });
25
- return changed ? next : value;
26
- }
27
- const record = value;
28
- let changed = false;
29
- const next = {};
30
- for (const [key, entry] of Object.entries(record)) {
31
- const wrapped = wrapValue(entry, key);
32
- if (wrapped !== entry)
33
- changed = true;
34
- next[key] = wrapped;
35
- }
36
- return changed ? next : value;
37
- }
38
- export function wrapModelRichContent(model) {
39
- return wrapValue(model);
40
- }
@@ -1,13 +0,0 @@
1
- /**
2
- * Write a temp `.npmrc` carrying a scoped `_authToken` and return an env
3
- * object pointing `NPM_CONFIG_USERCONFIG` at it, so a publish subprocess
4
- * authenticates without a separate `npm login`. The token comes from
5
- * `NPM_TOKEN`/`NODE_AUTH_TOKEN` in `baseEnv` first, falling back to parsing
6
- * an `.env`-style file at `envPath` for either key.
7
- *
8
- * Call `cleanup()` once the subprocess using `env` has exited.
9
- */
10
- export declare const createNpmAuthEnvironment: (envPath?: string, baseEnv?: NodeJS.ProcessEnv) => {
11
- env: NodeJS.ProcessEnv;
12
- cleanup: () => void;
13
- };
@@ -1,64 +0,0 @@
1
- import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- if (typeof window !== "undefined") {
5
- throw new Error("[npm-auth-env] @pie-players/pie-players-shared/server/npm-auth-env is server-only and cannot be imported in browser code");
6
- }
7
- const REGISTRY = "https://registry.npmjs.org/";
8
- const parseDotEnvToken = (envPath, key) => {
9
- try {
10
- const content = readFileSync(envPath, "utf8");
11
- const pattern = new RegExp(`^\\s*(?:export\\s+)?${key}\\s*=\\s*(.*)\\s*$`, "m");
12
- const match = content.match(pattern);
13
- if (!match?.[1])
14
- return "";
15
- const rawValue = match[1].trim();
16
- const isWrappedInQuotes = (rawValue.startsWith('"') && rawValue.endsWith('"')) ||
17
- (rawValue.startsWith("'") && rawValue.endsWith("'"));
18
- return (isWrappedInQuotes ? rawValue.slice(1, -1) : rawValue).trim();
19
- }
20
- catch {
21
- return "";
22
- }
23
- };
24
- const resolveToken = (envPath, baseEnv) => {
25
- const envToken = String(baseEnv.NPM_TOKEN || baseEnv.NODE_AUTH_TOKEN || "").trim();
26
- if (envToken)
27
- return envToken;
28
- if (!envPath)
29
- return "";
30
- return (parseDotEnvToken(envPath, "NPM_TOKEN") ||
31
- parseDotEnvToken(envPath, "NODE_AUTH_TOKEN"));
32
- };
33
- /**
34
- * Write a temp `.npmrc` carrying a scoped `_authToken` and return an env
35
- * object pointing `NPM_CONFIG_USERCONFIG` at it, so a publish subprocess
36
- * authenticates without a separate `npm login`. The token comes from
37
- * `NPM_TOKEN`/`NODE_AUTH_TOKEN` in `baseEnv` first, falling back to parsing
38
- * an `.env`-style file at `envPath` for either key.
39
- *
40
- * Call `cleanup()` once the subprocess using `env` has exited.
41
- */
42
- export const createNpmAuthEnvironment = (envPath, baseEnv = process.env) => {
43
- const token = resolveToken(envPath, baseEnv);
44
- if (!token) {
45
- return {
46
- env: baseEnv,
47
- cleanup: () => { },
48
- };
49
- }
50
- const tempDir = mkdtempSync(join(tmpdir(), "pie-npm-auth-"));
51
- const npmrcPath = join(tempDir, ".npmrc");
52
- writeFileSync(npmrcPath, `registry=${REGISTRY}\n//registry.npmjs.org/:_authToken=${token}\n`, "utf8");
53
- return {
54
- env: {
55
- ...baseEnv,
56
- NPM_CONFIG_USERCONFIG: npmrcPath,
57
- NODE_AUTH_TOKEN: String(baseEnv.NODE_AUTH_TOKEN || "").trim() || token,
58
- NPM_TOKEN: String(baseEnv.NPM_TOKEN || "").trim() || token,
59
- },
60
- cleanup: () => {
61
- rmSync(tempDir, { recursive: true, force: true });
62
- },
63
- };
64
- };
@@ -1,7 +0,0 @@
1
- type NpmFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
2
- /**
3
- * Server-only helper for npm package version lookups.
4
- * Do not import this module from browser-executed code.
5
- */
6
- export declare const getNpmPackageVersions: (element: string, fetch: NpmFetch, filter?: (v: string) => boolean, limit?: number, searchTerm?: string) => Promise<string[]>;
7
- export {};
@@ -1,59 +0,0 @@
1
- import semver from "semver";
2
- const NPM_REGISTRY_URL = "https://registry.npmjs.org";
3
- if (typeof window !== "undefined") {
4
- throw new Error("[npm-registry] @pie-players/pie-players-shared/server/npm-registry is server-only and cannot be imported in browser code");
5
- }
6
- const DEFAULT_FILTER = (v) => v.indexOf("print") === -1 &&
7
- v.indexOf("ps") === -1 &&
8
- v.indexOf("strikethrough") === -1 &&
9
- v.indexOf("alpha") === -1 &&
10
- v.indexOf("bm") === -1;
11
- /**
12
- * Server-only helper for npm package version lookups.
13
- * Do not import this module from browser-executed code.
14
- */
15
- export const getNpmPackageVersions = async (element, fetch, filter = DEFAULT_FILTER, limit, searchTerm = "") => {
16
- if (typeof window !== "undefined") {
17
- throw new Error("[npm-registry] server-only module imported in browser context");
18
- }
19
- try {
20
- const response = await fetch(`${NPM_REGISTRY_URL}/${element}`);
21
- if (!response.ok) {
22
- console.warn(`[npm-registry] npm status ${response.status} for package ${element}`);
23
- return searchTerm ? [] : ["latest"];
24
- }
25
- const json = await response.json();
26
- const versions = json?.versions;
27
- if (!versions || typeof versions !== "object") {
28
- console.warn(`[npm-registry] response for ${element} missing 'versions' property`);
29
- return searchTerm ? [] : ["latest"];
30
- }
31
- let sorted = Object.keys(versions)
32
- .filter(filter)
33
- .filter((v) => !versions[v]?.deprecated)
34
- .filter((v) => !/^11\.0\.\d+-esm\.\d+/.test(v))
35
- .filter((v) => !searchTerm || v.toLowerCase().includes(searchTerm.toLowerCase()))
36
- .sort((a, b) => {
37
- const verA = semver.valid(semver.clean(a));
38
- const verB = semver.valid(semver.clean(b));
39
- if (!verA && !verB)
40
- return 0;
41
- if (!verA)
42
- return 1;
43
- if (!verB)
44
- return -1;
45
- return semver.rcompare(verA, verB);
46
- });
47
- if (typeof limit === "number" && limit > 0) {
48
- sorted = sorted.slice(0, limit);
49
- }
50
- if (!searchTerm) {
51
- sorted.unshift("latest");
52
- }
53
- return sorted;
54
- }
55
- catch (error) {
56
- console.warn(`[npm-registry] failed package lookup for ${element}:`, error);
57
- return searchTerm ? [] : ["latest"];
58
- }
59
- };
@@ -1,17 +0,0 @@
1
- type DebugPanelStorageKeyArgs = {
2
- scope: string;
3
- panelId: string;
4
- aspect?: string;
5
- };
6
- export declare function createDebugPanelStorageKey(args: DebugPanelStorageKeyArgs): string;
7
- export declare function readDebugPanelState<T>(key: string): T | null;
8
- export declare function writeDebugPanelState<T>(key: string, value: T): void;
9
- export declare function clearDebugPanelState(key: string): void;
10
- export type DebugPanelLayoutStateV1 = {
11
- x: number;
12
- y: number;
13
- width: number;
14
- height: number;
15
- minimized: boolean;
16
- };
17
- export {};