@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.
- package/README.md +27 -1
- package/dist/components/vendor/nds/README.md +7 -5
- package/dist/config/profile.d.ts +0 -2
- package/dist/config/profile.js +2 -8
- package/dist/i18n/index.d.ts +2 -3
- package/dist/i18n/index.js +2 -3
- package/dist/i18n/messages/en-US.d.ts +10 -0
- package/dist/i18n/messages/en-US.js +12 -2
- package/dist/i18n/messages/nl-NL.d.ts +6 -0
- package/dist/i18n/messages/nl-NL.js +8 -2
- package/dist/i18n/provider.d.ts +4 -5
- package/dist/i18n/provider.js +4 -5
- package/dist/index.d.ts +4 -2
- package/dist/index.js +3 -1
- package/dist/instrumentation/index.d.ts +5 -4
- package/dist/instrumentation/index.js +5 -4
- package/dist/instrumentation/new-relic-agent.d.ts +20 -0
- package/dist/instrumentation/new-relic-agent.js +24 -0
- package/dist/instrumentation/providers/BaseInstrumentationProvider.d.ts +5 -4
- package/dist/instrumentation/providers/NewRelicInstrumentationProvider.d.ts +7 -7
- package/dist/instrumentation/providers/NewRelicInstrumentationProvider.js +21 -32
- package/dist/instrumentation/types.d.ts +7 -3
- package/dist/loader-config.d.ts +16 -6
- package/dist/loaders/controller-loading.d.ts +14 -0
- package/dist/loaders/controller-loading.js +12 -0
- package/dist/loaders/defaults.d.ts +10 -0
- package/dist/loaders/defaults.js +10 -0
- package/dist/loaders/element-loader.d.ts +20 -8
- package/dist/loaders/element-loader.js +102 -36
- package/dist/loaders/element-package-policy.d.ts +2 -0
- package/dist/loaders/element-package-policy.js +2 -1
- package/dist/loaders/esm-adapter.d.ts +18 -0
- package/dist/loaders/esm-adapter.js +617 -102
- package/dist/loaders/iife-adapter.d.ts +0 -5
- package/dist/loaders/iife-adapter.js +3 -9
- package/dist/loaders/index.d.ts +10 -3
- package/dist/loaders/index.js +8 -3
- package/dist/loaders/mathjax-version-conflict.d.ts +17 -0
- package/dist/loaders/mathjax-version-conflict.js +51 -0
- package/dist/loaders/module-shim.d.ts +12 -0
- package/dist/loaders/module-shim.js +12 -0
- package/dist/loaders/preloaded-alignment.d.ts +24 -0
- package/dist/loaders/preloaded-alignment.js +57 -0
- package/dist/loaders/preloaded-authored-tags.d.ts +26 -0
- package/dist/loaders/preloaded-authored-tags.js +69 -0
- package/dist/loaders/preloaded-registration.d.ts +56 -0
- package/dist/loaders/preloaded-registration.js +129 -0
- package/dist/media/index.d.ts +69 -0
- package/dist/media/index.js +194 -0
- package/dist/pie/authoring.d.ts +1 -1
- package/dist/pie/authoring.js +25 -18
- package/dist/pie/element-announcements.d.ts +39 -0
- package/dist/pie/element-announcements.js +67 -0
- package/dist/pie/element-observer.d.ts +3 -1
- package/dist/pie/element-observer.js +1 -0
- package/dist/pie/index.d.ts +6 -4
- package/dist/pie/index.js +6 -3
- package/dist/pie/initialization.js +13 -22
- package/dist/pie/initialize-element.d.ts +3 -0
- package/dist/pie/initialize-element.js +3 -4
- package/dist/pie/instrumentation-event-map.js +2 -9
- package/dist/pie/instrumentation-provider-resolution.d.ts +2 -1
- package/dist/pie/instrumentation-provider-resolution.js +0 -1
- package/dist/pie/item-session-contract.d.ts +47 -0
- package/dist/pie/item-session-contract.js +196 -9
- package/dist/pie/markup-math.d.ts +20 -0
- package/dist/pie/markup-math.js +118 -0
- package/dist/pie/math-rendering.d.ts +10 -21
- package/dist/pie/math-rendering.js +50 -35
- package/dist/pie/registry.d.ts +13 -1
- package/dist/pie/registry.js +39 -1
- package/dist/pie/resource-monitor.d.ts +6 -33
- package/dist/pie/resource-monitor.js +14 -213
- package/dist/pie/scoring.d.ts +11 -2
- package/dist/pie/scoring.js +18 -16
- package/dist/pie/session-commit.d.ts +121 -0
- package/dist/pie/session-commit.js +420 -0
- package/dist/pie/session-snapshot.d.ts +80 -0
- package/dist/pie/session-snapshot.js +166 -0
- package/dist/pie/tag-names.d.ts +1 -0
- package/dist/pie/tag-names.js +1 -0
- package/dist/pie/types.d.ts +4 -5
- package/dist/pie/types.js +1 -0
- package/dist/pie/updates.d.ts +2 -2
- package/dist/pie/updates.js +33 -15
- package/dist/pie/versioned-tag.d.ts +4 -0
- package/dist/pie/versioned-tag.js +4 -0
- package/dist/security/index.d.ts +2 -3
- package/dist/security/index.js +2 -3
- package/dist/security/sanitize-item-markup.d.ts +0 -2
- package/dist/security/sanitize-item-markup.js +0 -4
- package/dist/security/sanitize-svg-icon.d.ts +0 -2
- package/dist/security/sanitize-svg-icon.js +0 -5
- package/dist/security/wrap-overwide.d.ts +5 -0
- package/dist/security/wrap-overwide.js +16 -0
- package/dist/timed-media/policy.js +5 -16
- package/dist/types/index.d.ts +30 -311
- package/dist/types/index.js +0 -68
- package/dist/ui/attribute-coercion.d.ts +12 -0
- package/dist/ui/attribute-coercion.js +33 -0
- package/dist/ui/content-styles.d.ts +18 -16
- package/dist/ui/content-styles.js +67 -36
- package/dist/ui/overlay-containment.d.ts +31 -0
- package/dist/ui/overlay-containment.js +63 -0
- package/dist/ui/overlay-placement.d.ts +110 -0
- package/dist/ui/overlay-placement.js +222 -0
- package/dist/ui/pointer-gesture.d.ts +32 -0
- package/dist/ui/pointer-gesture.js +56 -0
- package/dist/ui/pointer-rotate.d.ts +29 -0
- package/dist/ui/pointer-rotate.js +39 -0
- package/package.json +21 -17
- package/dist/pie/component-context.d.ts +0 -21
- package/dist/pie/component-context.js +0 -29
- package/dist/pie/player-initializer.d.ts +0 -54
- package/dist/pie/player-initializer.js +0 -122
- package/dist/security/wrap-model-rich-content.d.ts +0 -1
- package/dist/security/wrap-model-rich-content.js +0 -40
- package/dist/server/npm-auth-env.d.ts +0 -13
- package/dist/server/npm-auth-env.js +0 -64
- package/dist/server/npm-registry.d.ts +0 -7
- package/dist/server/npm-registry.js +0 -59
- package/dist/ui/debug-panel-persistence.d.ts +0 -17
- 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.
|
|
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.
|
|
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
|
|
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.
|
|
121
|
-
"@happy-dom/global-registrator": "^20.
|
|
122
|
-
"@
|
|
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.
|
|
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":
|
|
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 {};
|