@pie-element/element-player 0.1.1 → 0.1.2-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,9 +32,36 @@ The package has a dependency resolution issue that prevents it from building as
32
32
 
33
33
  The element player is a **standalone web component bundle** (`pie-element-player.js`) that can be dropped into any HTML page with a simple `<script>` tag. It loads PIE elements via dynamic ESM imports.
34
34
 
35
+ ## Recommendation
36
+
37
+ Use the player as a **Node package dependency** in modern applications.
38
+
39
+ - Recommended: install/import via package manager and bundle with your app.
40
+ - Secondary/fallback: dynamic script/import-map loading for environments that cannot bundle.
41
+
42
+ Positioning note:
43
+
44
+ - In normal production integrations, use the standard production player stacks from the upstream PIE projects (`../pie-elements` and `../pie-players`).
45
+ - Treat `@pie-element/element-player` as a flexible element-level host for development, testing, and composable/advanced embedding scenarios.
46
+
47
+ Why this is preferred:
48
+
49
+ - Better build-time optimization and dependency deduplication
50
+ - More reliable versioning through lockfiles
51
+ - Better TypeScript/IDE support and compile-time validation
52
+ - Fewer runtime resolution issues (CDN/import-map/config drift)
53
+
35
54
  ## Usage
36
55
 
37
- ### ESM Player
56
+ ### Recommended: Node package integration
57
+
58
+ ```ts
59
+ import '@pie-element/element-player/players';
60
+ ```
61
+
62
+ Then render the host component and set `model`/`session` via properties in your framework/runtime.
63
+
64
+ ### Dynamic loading fallback (supported)
38
65
 
39
66
  For elements with import maps:
40
67
 
@@ -45,10 +72,11 @@ For elements with import maps:
45
72
  <title>PIE Element Demo</title>
46
73
  </head>
47
74
  <body>
48
- <pie-esm-element-player
75
+ <pie-element-player
49
76
  id="player"
50
77
  element-name="hotspot"
51
- ></pie-esm-element-player>
78
+ view="delivery"
79
+ ></pie-element-player>
52
80
 
53
81
  <!-- Import map for module resolution -->
54
82
  <script type="importmap">
@@ -60,7 +88,7 @@ For elements with import maps:
60
88
  </script>
61
89
 
62
90
  <!-- Load the player bundle -->
63
- <script type="module" src="/packages/shared/element-player/dist/pie-element-player.js"></script>
91
+ <script type="module" src="/packages/element-player/dist/pie-element-player.js"></script>
64
92
 
65
93
  <script type="module">
66
94
  const player = document.getElementById('player');
@@ -73,9 +101,9 @@ For elements with import maps:
73
101
 
74
102
  ## Architecture
75
103
 
76
- ### ESM Players
104
+ ### Unified Player
77
105
 
78
- **Interactive Player (`<pie-esm-element-player>`):**
106
+ **Delivery view (`<pie-element-player view="delivery">`):**
79
107
 
80
108
  - Loads elements via dynamic ESM imports: `import('@pie-element/hotspot')`
81
109
  - Handles session state and user interactions
@@ -83,7 +111,7 @@ For elements with import maps:
83
111
  - Emits `session-changed` events
84
112
  - Works with both React and Svelte elements
85
113
 
86
- **Print Player (`<pie-esm-print-player>`):**
114
+ **Print view (`<pie-element-player view="print">`):**
87
115
 
88
116
  - Loads print exports: `import('@pie-element/hotspot/print')`
89
117
  - Stateless (no session management)
@@ -91,7 +119,7 @@ For elements with import maps:
91
119
  - Manages math rendering internally (MathJax)
92
120
  - Role-based rendering (student/instructor)
93
121
 
94
- **Both players:**
122
+ **All views:**
95
123
 
96
124
  - Use import maps for module resolution
97
125
  - Self-contained (no external setup needed)
@@ -120,10 +148,10 @@ To test changes to player components:
120
148
 
121
149
  ```bash
122
150
  # Build element-player
123
- cd packages/shared/element-player
151
+ cd packages/element-player
124
152
  bun run build
125
153
 
126
154
  # Run element demo
127
- cd ../../../
155
+ cd ../..
128
156
  bun cli dev:demo hotspot
129
157
  ```
package/dist/index.d.ts CHANGED
@@ -5,11 +5,15 @@
5
5
  * Handles element loading, math rendering, and session management internally.
6
6
  *
7
7
  * Usage:
8
- * <pie-esm-element-player element-name="hotspot"></pie-esm-element-player>
9
- * <pie-esm-print-player element-name="hotspot" role="student"></pie-esm-print-player>
8
+ * <pie-element-player element-name="hotspot" view="delivery"></pie-element-player>
9
+ * <pie-element-player element-name="hotspot" view="print" role="student"></pie-element-player>
10
10
  */
11
11
  import './app.css';
12
- export { EsmElementPlayer, EsmPrintPlayer } from './players';
13
- import './players';
14
- export type { ElementPlayerProps, PieController, Tab } from './lib/types';
15
- //# sourceMappingURL=index.d.ts.map
12
+ import './players/index.js';
13
+ export type { ElementPlayerProps, PieController, Tab } from './lib/types.js';
14
+ export type { ElementPlayerStrategy, ElementPlayerView } from './lib/player-strategy.js';
15
+ export type { RuntimeSupportCheck, RuntimeSupportStrategy, RuntimeSupportView, PieElementRuntimeSupport, } from './lib/runtime-support.js';
16
+ export { normalizeRuntimeSupportCheck } from './lib/runtime-support.js';
17
+ export { normalizeElementPlayerStrategy, normalizeElementPlayerView, resolveElementPlayerView, } from './lib/player-strategy.js';
18
+ export { configureUnifiedPlayerResolver, type ControllerLoadDiagnostic, type RuntimeSupportDiagnostic, } from './lib/unified-player-loader.js';
19
+ export { configureIifeBundleLoader, IifeBundleLoadError, type IifeBuildClient, type IifeRegistryClient, type IifeBundleLoaderAdapters, type IifeBundleRetryConfig, type IifeBundleRetryStatus, DEFAULT_IIFE_BUNDLE_RETRY_CONFIG, } from './lib/iife-bundle-loader.js';
@@ -4,6 +4,17 @@
4
4
  * Dynamically loads PIE elements from CDN and registers them as custom elements.
5
5
  * Based on the ESM loader pattern from pie-players.
6
6
  */
7
+ import type { PieElementRuntimeSupport } from './runtime-support';
8
+ export type ElementModuleKind = 'delivery' | 'author' | 'print' | 'controller' | 'runtime-support';
9
+ export interface ElementModuleResolveRequest {
10
+ packagePath: string;
11
+ packageName: string;
12
+ elementName: string;
13
+ kind: ElementModuleKind;
14
+ cdnUrl: string;
15
+ }
16
+ export type ElementModuleResolver = (request: ElementModuleResolveRequest) => Promise<unknown | null | undefined> | unknown | null | undefined;
17
+ export declare function configureElementModuleResolver(resolver?: ElementModuleResolver): void;
7
18
  /**
8
19
  * Load and register a PIE element as a custom element
9
20
  *
@@ -23,4 +34,8 @@ export declare function loadElement(packagePath: string, tagName: string, cdnUrl
23
34
  * @returns Controller object with model/score/outcome methods
24
35
  */
25
36
  export declare function loadController(packageName: string, cdnUrl: string, debug?: boolean): Promise<any>;
26
- //# sourceMappingURL=element-loader.d.ts.map
37
+ /**
38
+ * Load optional runtime support metadata module.
39
+ * Missing module should be handled by caller as an optional capability.
40
+ */
41
+ export declare function loadRuntimeSupport(packageName: string, cdnUrl: string, debug?: boolean): Promise<PieElementRuntimeSupport>;
@@ -0,0 +1,98 @@
1
+ type IifeBundleTarget = 'player' | 'client-player' | 'editor';
2
+ export interface IifeBundleRetryConfig {
3
+ retryDelayMs?: number;
4
+ timeoutMs?: number;
5
+ }
6
+ export interface IifeBundleRetryStatus {
7
+ state: 'retrying' | 'completed' | 'timeout' | 'cancelled';
8
+ stage: 'build-start' | 'build-status' | 'script-load';
9
+ attempt: number;
10
+ elapsedMs: number;
11
+ retryDelayMs?: number;
12
+ timeoutMs: number;
13
+ reason?: string;
14
+ }
15
+ export declare const DEFAULT_IIFE_BUNDLE_RETRY_CONFIG: {
16
+ readonly retryDelayMs: 3000;
17
+ readonly timeoutMs: 120000;
18
+ };
19
+ export interface LocalBundleMeta {
20
+ hash?: string;
21
+ duration?: number;
22
+ cached?: boolean;
23
+ source: 'local' | 'hosted';
24
+ url: string;
25
+ }
26
+ export interface IifePackageExports {
27
+ Element?: CustomElementConstructor;
28
+ Print?: CustomElementConstructor;
29
+ controller?: any;
30
+ Configure?: CustomElementConstructor;
31
+ }
32
+ export interface IifeBuildResult {
33
+ success: boolean;
34
+ bundles?: {
35
+ player?: string;
36
+ clientPlayer?: string;
37
+ editor?: string;
38
+ };
39
+ hash: string;
40
+ duration: number;
41
+ cached?: boolean;
42
+ errors?: string[];
43
+ }
44
+ export declare class IifeBundleLoadError extends Error {
45
+ code: 'BUILD_START_FAILED' | 'BUILD_STATUS_FAILED' | 'BUILD_RESULT_FAILED' | 'BUNDLE_URL_MISSING' | 'SCRIPT_LOAD_FAILED' | 'REGISTRY_INVALID' | 'PACKAGE_MISSING' | 'LOAD_ABORTED';
46
+ metadata?: Record<string, unknown>;
47
+ constructor(code: 'BUILD_START_FAILED' | 'BUILD_STATUS_FAILED' | 'BUILD_RESULT_FAILED' | 'BUNDLE_URL_MISSING' | 'SCRIPT_LOAD_FAILED' | 'REGISTRY_INVALID' | 'PACKAGE_MISSING' | 'LOAD_ABORTED', message: string, metadata?: Record<string, unknown>);
48
+ }
49
+ export interface IifeBuildClient {
50
+ startBuild(request: {
51
+ endpoint: string;
52
+ packageName: string;
53
+ version: string;
54
+ bundleTarget: IifeBundleTarget;
55
+ forceRebuild: boolean;
56
+ clearCache: boolean;
57
+ }): Promise<{
58
+ buildId: string;
59
+ hash?: string;
60
+ }>;
61
+ waitForBuildResult(request: {
62
+ endpoint: string;
63
+ buildId: string;
64
+ onProgress?: (event: {
65
+ stage: string;
66
+ message?: string;
67
+ }) => void;
68
+ }): Promise<IifeBuildResult>;
69
+ }
70
+ export interface IifeRegistryClient {
71
+ load(url: string): Promise<Record<string, IifePackageExports>>;
72
+ }
73
+ export interface IifeBundleLoaderAdapters {
74
+ buildClient?: IifeBuildClient;
75
+ registryClient?: IifeRegistryClient;
76
+ }
77
+ export declare function configureIifeBundleLoader(adapters?: IifeBundleLoaderAdapters): void;
78
+ export declare function loadIifePackage(opts: {
79
+ packageName: string;
80
+ version: string;
81
+ endpoint?: string;
82
+ bundleHost?: string;
83
+ forceRebuild?: boolean;
84
+ clearCache?: boolean;
85
+ bundleTarget?: IifeBundleTarget;
86
+ iifeBundleRetry?: IifeBundleRetryConfig;
87
+ onProgress?: (event: {
88
+ stage: string;
89
+ message?: string;
90
+ }) => void;
91
+ onRetryStatus?: (status: IifeBundleRetryStatus) => void;
92
+ signal?: AbortSignal;
93
+ adapters?: IifeBundleLoaderAdapters;
94
+ }): Promise<{
95
+ pkg: IifePackageExports;
96
+ meta: LocalBundleMeta;
97
+ }>;
98
+ export {};
@@ -0,0 +1,7 @@
1
+ export type MathRenderer = (element: HTMLElement) => void | Promise<void>;
2
+ export interface MathRenderingAPI {
3
+ renderMath: MathRenderer;
4
+ wrapMath?: (latex: string) => string;
5
+ unWrapMath?: (wrapped: string) => string;
6
+ mmlToLatex?: (mathml: string) => string;
7
+ }
@@ -0,0 +1,9 @@
1
+ export type ElementPlayerStrategy = 'esm' | 'iife' | 'preloaded';
2
+ export type ElementPlayerView = 'delivery' | 'author' | 'print';
3
+ export interface ResolveElementPlayerViewInput {
4
+ mode?: string | null;
5
+ view?: ElementPlayerView | null;
6
+ }
7
+ export declare function normalizeElementPlayerStrategy(value: string | null | undefined, fallback?: ElementPlayerStrategy): ElementPlayerStrategy;
8
+ export declare function normalizeElementPlayerView(value: string | null | undefined, fallback?: ElementPlayerView): ElementPlayerView;
9
+ export declare function resolveElementPlayerView(input: ResolveElementPlayerViewInput, fallback?: ElementPlayerView): ElementPlayerView;
@@ -0,0 +1,12 @@
1
+ export type RuntimeSupportCheck = 'off' | 'on';
2
+ export type RuntimeSupportStrategy = 'esm' | 'iife';
3
+ export type RuntimeSupportView = 'delivery' | 'author' | 'print';
4
+ export interface PieElementRuntimeSupport {
5
+ schemaVersion: number;
6
+ packageName?: string;
7
+ version?: string;
8
+ supports?: Partial<Record<RuntimeSupportStrategy, Partial<Record<RuntimeSupportView, boolean>>>>;
9
+ }
10
+ export declare function normalizeRuntimeSupportCheck(value: string | null | undefined, fallback?: RuntimeSupportCheck): RuntimeSupportCheck;
11
+ export declare function isRuntimeSupportEnabled(mode: RuntimeSupportCheck): boolean;
12
+ export declare function isStrategySupportedForView(runtimeSupport: PieElementRuntimeSupport, strategy: RuntimeSupportStrategy, view: RuntimeSupportView): boolean;
@@ -4,6 +4,7 @@
4
4
  export interface ElementPlayerProps {
5
5
  elementName: string;
6
6
  cdnUrl?: string;
7
+ runtimeSupportCheck?: 'off' | 'on';
7
8
  model?: any;
8
9
  session?: any;
9
10
  mode?: 'gather' | 'view' | 'evaluate';
@@ -23,4 +24,3 @@ export interface Tab {
23
24
  description?: string;
24
25
  disabled?: boolean;
25
26
  }
26
- //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,51 @@
1
+ import { type ElementModuleResolver } from './element-loader';
2
+ import { type IifeBundleRetryConfig, type IifeBundleRetryStatus, type IifeBundleLoadError, type LocalBundleMeta } from './iife-bundle-loader';
3
+ import { type ElementPlayerStrategy, type ElementPlayerView } from './player-strategy';
4
+ import { type PieElementRuntimeSupport, type RuntimeSupportCheck } from './runtime-support';
5
+ export interface UnifiedPlayerLoadRequest {
6
+ strategy: string | null | undefined;
7
+ view: string | null | undefined;
8
+ elementName: string;
9
+ packageName: string;
10
+ elementVersion: string;
11
+ cdnUrl?: string;
12
+ iifeBundleEndpoint?: string;
13
+ iifeBundleHost?: string;
14
+ iifeBundleRetry?: IifeBundleRetryConfig;
15
+ onIifeBundleRetryStatus?: (status: IifeBundleRetryStatus) => void;
16
+ signal?: AbortSignal;
17
+ rebuildVersion?: number;
18
+ preloadedFallbackStrategy?: ElementPlayerStrategy;
19
+ runtimeSupportCheck?: RuntimeSupportCheck | string | null;
20
+ }
21
+ export interface ControllerLoadDiagnostic {
22
+ status: 'loaded' | 'missing' | 'failed' | 'not-required';
23
+ source: 'module' | 'bundle' | 'none';
24
+ packageName: string;
25
+ strategy: ElementPlayerStrategy;
26
+ view: ElementPlayerView;
27
+ message?: string;
28
+ }
29
+ export interface UnifiedPlayerLoadResult {
30
+ strategy: ElementPlayerStrategy;
31
+ requestedStrategy?: ElementPlayerStrategy;
32
+ view: ElementPlayerView;
33
+ tagName: string;
34
+ controller?: any;
35
+ bundleMeta?: LocalBundleMeta;
36
+ controllerDiagnostic?: ControllerLoadDiagnostic;
37
+ runtimeSupport?: PieElementRuntimeSupport;
38
+ runtimeSupportDiagnostic?: RuntimeSupportDiagnostic;
39
+ diagnostics?: {
40
+ iife?: IifeBundleLoadError;
41
+ };
42
+ }
43
+ export interface RuntimeSupportDiagnostic {
44
+ status: 'loaded' | 'missing' | 'failed' | 'skipped';
45
+ packageName: string;
46
+ strategy: ElementPlayerStrategy;
47
+ view: ElementPlayerView;
48
+ message?: string;
49
+ }
50
+ export declare function configureUnifiedPlayerResolver(resolver?: ElementModuleResolver): void;
51
+ export declare function loadUnifiedPlayer(request: UnifiedPlayerLoadRequest): Promise<UnifiedPlayerLoadResult>;
@@ -0,0 +1,59 @@
1
+ //#region ../shared/math-rendering-mathjax/dist/index.js
2
+ var e = null;
3
+ function t(t) {
4
+ return typeof window > "u" || window.MathJax?.typesetPromise ? Promise.resolve() : e || (e = new Promise((e, n) => {
5
+ let { useSingleDollar: r = !1, accessibility: i = !0, loadFonts: a = !0, srcUrl: o } = t, s = {
6
+ loader: { load: i ? ["a11y/assistive-mml"] : [] },
7
+ tex: {
8
+ packages: [
9
+ "base",
10
+ "ams",
11
+ "autoload"
12
+ ],
13
+ macros: {
14
+ parallelogram: "\\lower.2em{\\Huge\\unicode{x25B1}}",
15
+ overarc: "\\overparen",
16
+ napprox: "\\not\\approx",
17
+ longdiv: "\\enclose{longdiv}"
18
+ }
19
+ },
20
+ options: {
21
+ enableMenu: i,
22
+ enableExplorer: i,
23
+ enableAssistiveMml: i
24
+ },
25
+ startup: {
26
+ ready: () => {
27
+ window.MathJax?.startup.defaultReady && (window.MathJax.startup.defaultReady(), e());
28
+ },
29
+ defaultReady: () => {}
30
+ }
31
+ };
32
+ r && s.tex && (s.tex.inlineMath = [["$", "$"], ["\\(", "\\)"]], s.tex.processEscapes = !0), a || (s.chtml = { fontURL: "" }), window.MathJax = s;
33
+ let c = document.createElement("script");
34
+ c.src = o || "https://cdn.jsdelivr.net/npm/mathjax@4/tex-chtml.js", c.async = !0, c.onload = () => {
35
+ setTimeout(e, 100);
36
+ }, c.onerror = () => {
37
+ n(/* @__PURE__ */ Error("Failed to load MathJax"));
38
+ }, document.head.appendChild(c);
39
+ }), e);
40
+ }
41
+ function n() {
42
+ let e = window.MathJax?.startup?.document;
43
+ if (typeof e?.assistiveMml == "function") try {
44
+ e.assistiveMml().updateDocument?.();
45
+ } catch (e) {
46
+ console.warn("[mathjax-renderer] Failed to attach assistive MathML:", e);
47
+ }
48
+ }
49
+ function r(e = {}) {
50
+ return async (r) => {
51
+ if (await t(e), !window.MathJax?.typesetPromise) {
52
+ console.warn("[mathjax-renderer] MathJax not loaded or missing typesetPromise.");
53
+ return;
54
+ }
55
+ await window.MathJax.typesetPromise([r]), n();
56
+ };
57
+ }
58
+ //#endregion
59
+ export { r as t };