@pie-framework/pie-fixed-player-static 1.0.0-351df72.9 → 1.0.0-d5819f3.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
@@ -1,6 +1,6 @@
1
1
  # @pie-framework/pie-fixed-player-static
2
2
 
3
- Version: 1.0.0-351df72.9
3
+ Version: 1.0.0-d5819f3.1
4
4
 
5
5
  Pre-bundled PIE fixed player with static element versions for production use.
6
6
 
@@ -9,15 +9,17 @@ in Pieoneer, use `pie-inline-player` instead.
9
9
 
10
10
  ## Included Elements
11
11
 
12
- - @pie-element/drag-in-the-blank@8.1.0
13
- - @pie-element/hotspot@9.1.0
14
- - @pie-element/image-cloze-association@8.1.0
15
- - @pie-element/multiple-choice@11.1.0
12
+ - @pie-element/categorize@11.3.2
13
+ - @pie-element/drag-in-the-blank@8.3.2
14
+ - @pie-element/hotspot@9.3.2
15
+ - @pie-element/image-cloze-association@8.3.2
16
+ - @pie-element/multiple-choice@11.4.3
17
+ - @pie-element/passage@5.3.3
16
18
 
17
19
  ## Installation
18
20
 
19
21
  ```bash
20
- npm install @pie-framework/pie-fixed-player-static@1.0.0-351df72.9
22
+ npm install @pie-framework/pie-fixed-player-static@1.0.0-d5819f3.1
21
23
  ```
22
24
 
23
25
  ## Usage
@@ -44,8 +46,51 @@ npm install @pie-framework/pie-fixed-player-static@1.0.0-351df72.9
44
46
  - `session` - Session data array
45
47
  - `add-correct-response` - Show correct answers
46
48
  - `external-style-urls` - Additional CSS URLs
49
+ - `loader-config` - Loader configuration (JSON string, see below)
47
50
  - Custom styling attributes
48
51
 
52
+ ## Loader Configuration
53
+
54
+ Control resource loading behavior and New Relic tracking via the `loader-config` attribute:
55
+
56
+ ```html
57
+ <pie-fixed-player
58
+ item-id="your-item-id"
59
+ loader-config='{"trackPageActions": true, "maxResourceRetries": 3}'>
60
+ </pie-fixed-player>
61
+ ```
62
+
63
+ **Options:**
64
+ - `trackPageActions` (boolean, default: false) - Enable New Relic instrumentation for module imports and resource loading
65
+ - `maxResourceRetries` (number, default: 3) - Maximum retry attempts for failed resources
66
+ - `resourceRetryDelay` (number, default: 500) - Initial delay in ms before retrying
67
+
68
+ **Global Configuration:**
69
+
70
+ Alternatively, set configuration globally before importing the package:
71
+
72
+ ```html
73
+ <script>
74
+ window.PIE_LOADER_CONFIG = {
75
+ trackPageActions: true,
76
+ maxResourceRetries: 3,
77
+ resourceRetryDelay: 500
78
+ };
79
+ </script>
80
+ <script type="module">
81
+ import '@pie-framework/pie-fixed-player-static';
82
+ </script>
83
+ ```
84
+
85
+ ## Resilient Loading
86
+
87
+ This package includes automatic retry logic for module imports and resource loading:
88
+
89
+ - **Module imports** (math-rendering, bundle, player): 4 attempts with exponential backoff (200ms, 400ms, 800ms)
90
+ - **Runtime resources** (images, audio, video): Configurable retry attempts with exponential backoff
91
+ - Console logging: warnings for retries, errors only for permanent failures
92
+ - New Relic tracking (when enabled): tracks import timing, retries, and failures
93
+
49
94
  ## Events
50
95
 
51
96
  - `load-complete` - Fired when item loads successfully
package/dist/index.d.ts CHANGED
@@ -1,11 +1,36 @@
1
1
  declare module '@pie-framework/pie-fixed-player-static' {
2
- // Add type definitions if needed
3
2
  export {};
4
- }
5
3
 
6
- // Custom element type augmentation
7
- declare global {
8
- interface HTMLElementTagNameMap {
9
- 'pie-fixed-player': HTMLElement;
4
+ // Custom element type augmentation
5
+ global {
6
+ interface HTMLElementTagNameMap {
7
+ 'pie-fixed-player': HTMLElement;
8
+ }
9
+
10
+ interface Window {
11
+ /**
12
+ * Global debug flag for PIE components
13
+ * Set to true to enable debug logging
14
+ */
15
+ PIE_DEBUG?: boolean;
16
+
17
+ /**
18
+ * Global loader configuration for PIE components
19
+ * Alternative to setting loader-config attribute on individual elements
20
+ */
21
+ PIE_LOADER_CONFIG?: {
22
+ trackPageActions?: boolean;
23
+ maxResourceRetries?: number;
24
+ resourceRetryDelay?: number;
25
+ };
26
+
27
+ /**
28
+ * New Relic Browser Agent
29
+ */
30
+ newrelic?: {
31
+ addPageAction(name: string, attributes?: Record<string, any>): void;
32
+ noticeError(error: Error, attributes?: Record<string, any>): void;
33
+ };
34
+ }
10
35
  }
11
36
  }
package/dist/index.js CHANGED
@@ -5,11 +5,216 @@
5
5
  // Use async IIFE to ensure sequential loading without top-level await
6
6
  // (Top-level await has bundler compatibility issues with some build tools)
7
7
  (async function initializePieFixedPlayer() {
8
+
9
+ // Cache tracking enabled state to avoid repeated DOM queries and JSON parsing
10
+ let trackingEnabled = null;
11
+
12
+ const isTrackingEnabled = () => {
13
+ // Return cached value if already determined
14
+ if (trackingEnabled !== null) {
15
+ return trackingEnabled;
16
+ }
17
+
18
+ try {
19
+ // Check multiple sources for tracking configuration
20
+ // 1. Check if pie-fixed-player element exists with loader-config attribute
21
+ const playerElement = typeof document !== 'undefined' ? document.querySelector('pie-fixed-player') : null;
22
+ if (playerElement) {
23
+ const loaderConfigAttr = playerElement.getAttribute('loader-config');
24
+ if (loaderConfigAttr) {
25
+ try {
26
+ const loaderConfig = JSON.parse(loaderConfigAttr);
27
+ if (loaderConfig?.trackPageActions === true) {
28
+ trackingEnabled = true;
29
+ return true;
30
+ }
31
+ } catch {
32
+ // Invalid JSON, continue to other checks
33
+ }
34
+ }
35
+ }
36
+
37
+ // 2. Check for global PIE_LOADER_CONFIG
38
+ if (typeof window !== 'undefined' && window.PIE_LOADER_CONFIG?.trackPageActions === true) {
39
+ trackingEnabled = true;
40
+ return true;
41
+ }
42
+ } catch {
43
+ // DOM operations failed, disable tracking
44
+ }
45
+
46
+ // No tracking enabled or error occurred
47
+ trackingEnabled = false;
48
+ return false;
49
+ };
50
+
51
+ // Helper to track with New Relic if enabled
52
+ const trackNewRelicAction = (actionName, attributes) => {
53
+ if (!isTrackingEnabled() || typeof window === 'undefined' || !window.newrelic) {
54
+ return;
55
+ }
56
+
57
+ try {
58
+ window.newrelic.addPageAction(actionName, {
59
+ ...attributes,
60
+ component: 'pie-fixed-player-static',
61
+ timestamp: new Date().toISOString()
62
+ });
63
+ } catch (err) {
64
+ // Silently fail if New Relic throws - don't break the app
65
+ if (typeof window !== 'undefined' && window.PIE_DEBUG) {
66
+ console.debug('[pie-fixed-player-static] New Relic tracking failed:', err);
67
+ }
68
+ }
69
+ };
70
+
71
+ const trackNewRelicError = (error, attributes) => {
72
+ if (!isTrackingEnabled() || typeof window === 'undefined' || !window.newrelic) {
73
+ return;
74
+ }
75
+
76
+ try {
77
+ window.newrelic.noticeError(error, {
78
+ ...attributes,
79
+ component: 'pie-fixed-player-static'
80
+ });
81
+ } catch (err) {
82
+ // Silently fail if New Relic throws - don't break the app
83
+ if (typeof window !== 'undefined' && window.PIE_DEBUG) {
84
+ console.debug('[pie-fixed-player-static] New Relic error tracking failed:', err);
85
+ }
86
+ }
87
+ };
88
+
89
+ const importWithRetry = async (specifier, attempts = 3, baseDelayMs = 200) => {
90
+ const startTime = Date.now();
91
+ let lastError;
92
+
93
+ // Track import start (never throws due to internal try/catch)
94
+ trackNewRelicAction('pie-import-started', {
95
+ specifier,
96
+ maxAttempts: attempts
97
+ });
98
+
99
+ for (let attempt = 1; attempt <= attempts; attempt++) {
100
+ try {
101
+ // Safe debug logging
102
+ try {
103
+ if (typeof window !== 'undefined' && window.PIE_DEBUG) {
104
+ console.debug(`[pie-fixed-player-static] importWithRetry: attempt ${attempt} -> ${specifier}`);
105
+ }
106
+ } catch {
107
+ // Logging failed, continue anyway
108
+ }
109
+
110
+ const result = await import(specifier);
111
+
112
+ // Track successful import (never throws due to internal try/catch)
113
+ const duration = Date.now() - startTime;
114
+ trackNewRelicAction('pie-import-success', {
115
+ specifier,
116
+ attempt,
117
+ duration,
118
+ wasRetried: attempt > 1
119
+ });
120
+
121
+ return result;
122
+ } catch (err) {
123
+ lastError = err;
124
+ const isLastAttempt = attempt === attempts;
125
+
126
+ if (isLastAttempt) {
127
+ // Final attempt failed - safe error logging
128
+ try {
129
+ console.error(`[pie-fixed-player-static] Failed to load ${specifier} after ${attempts} attempts:`, err);
130
+ } catch {
131
+ // Even error logging failed, but continue
132
+ }
133
+
134
+ // Track final failure (never throws due to internal try/catch)
135
+ try {
136
+ const duration = Date.now() - startTime;
137
+ const errorMessage = err && err.message ? err.message : String(err || 'Unknown error');
138
+ trackNewRelicError(new Error(`Import failed: ${specifier}`), {
139
+ specifier,
140
+ attempts,
141
+ duration,
142
+ errorMessage
143
+ });
144
+
145
+ // Dispatch the event failed load event
146
+ document.dispatchEvent(new CustomEvent('PiePlayerLoadEvent', {
147
+ detail: 'PIE-Fixed-Player-Load-Failed',
148
+ bubbles: true,
149
+ cancelable: true
150
+ }));
151
+ } catch {
152
+ // Tracking failed, continue anyway
153
+ }
154
+ } else {
155
+ // Intermediate failure - safe warning logging
156
+ try {
157
+ console.warn(`[pie-fixed-player-static] Import failed (attempt ${attempt}/${attempts}) for ${specifier}, will retry:`, err);
158
+ } catch {
159
+ // Logging failed, continue anyway
160
+ }
161
+
162
+ // Track retry attempt (never throws due to internal try/catch)
163
+ try {
164
+ const errorMessage = err && err.message ? err.message : String(err || 'Unknown error');
165
+ trackNewRelicAction('pie-import-retry', {
166
+ specifier,
167
+ attempt,
168
+ remainingAttempts: attempts - attempt,
169
+ errorMessage
170
+ });
171
+ } catch {
172
+ // Tracking failed, continue anyway
173
+ }
174
+
175
+ const delay = baseDelayMs * Math.pow(2, attempt - 1);
176
+
177
+ // Safe debug logging for retry
178
+ try {
179
+ if (typeof window !== 'undefined' && window.PIE_DEBUG) {
180
+ console.debug(`[pie-fixed-player-static] retrying ${specifier} in ${delay}ms`);
181
+ }
182
+ } catch {
183
+ // Logging failed, continue anyway
184
+ }
185
+
186
+ await new Promise((res) => setTimeout(res, delay));
187
+ }
188
+ }
189
+ }
190
+ throw lastError;
191
+ };
192
+ try {
193
+
194
+ // Initialize global debug flag from URL params (checked BEFORE any imports)
195
+ // Can also be set via: <script>window.PIE_DEBUG = true;</script> before importing this module
196
+ if (typeof window !== 'undefined' && typeof window.PIE_DEBUG === 'undefined') {
197
+ try {
198
+ const params = new URLSearchParams(window.location?.search || '');
199
+ const urlFlag = params.get('pie_debug') || params.get('PIE_DEBUG') || params.get('debug');
200
+ if (urlFlag != null) {
201
+ window.PIE_DEBUG = urlFlag === '' || String(urlFlag).toLowerCase() === 'true' || urlFlag === '1';
202
+ }
203
+ } catch {}
204
+ }
205
+
206
+ // Log debug state if enabled
8
207
  try {
9
- // 1. Dynamically import math-rendering module (bundled with package)
10
- const mathRenderingModule = await import('./math-rendering.js');
208
+ if (typeof window !== 'undefined' && window.PIE_DEBUG) {
209
+ console.debug('[pie-fixed-player-static] Debug logging enabled');
210
+ }
211
+ } catch {}
212
+
11
213
 
12
- // 2. Set globals BEFORE any PIE elements execute
214
+ // 2. Dynamically import math-rendering module (bundled with package)
215
+ const mathRenderingModule = await importWithRetry('./math-rendering.js', 4, 200);
216
+
217
+ // Set globals BEFORE any PIE elements execute
13
218
  if (typeof window !== 'undefined') {
14
219
  // Set BOTH globals:
15
220
  // - @pie-lib/math-rendering: Standard key used by pie-player
@@ -18,24 +223,55 @@
18
223
  window['_dll_pie_lib__math_rendering'] = mathRenderingModule._dll_pie_lib__math_rendering;
19
224
 
20
225
  // Debug logging (only if window.PIE_DEBUG is true)
21
- if (window.PIE_DEBUG) {
22
- console.debug('[pie-fixed-player-static] Math rendering initialized (both globals set)');
23
- }
226
+ try {
227
+ if (window.PIE_DEBUG) {
228
+ console.debug('[pie-fixed-player-static] Math rendering initialized (both globals set)');
229
+ }
230
+ } catch {}
24
231
  }
25
232
 
26
233
  // 3. NOW load PIE element bundles (IIFE) - these execute immediately
27
234
  // The IIFE must find math-rendering globals already set (which they now are)
28
- await import('./pie-elements-bundle-351df72.js');
235
+ await importWithRetry('./pie-elements-bundle-d5819f3.js', 4, 200);
29
236
 
30
237
  // 4. Load pie-fixed-player custom element
31
- await import('./pie-fixed-player.js');
238
+ await importWithRetry('./pie-fixed-player.js', 4, 200);
32
239
 
33
- // 5. Confirm ready (debug logging)
34
- if (typeof window !== 'undefined' && window.PIE_DEBUG) {
35
- console.debug('[pie-fixed-player-static] Package loaded. PIE elements available via window.pie');
240
+ // 5. Mark load completion (performance tracking - never throws)
241
+ try {
242
+ if (typeof window !== 'undefined' && typeof window.performance !== 'undefined') {
243
+ window.performance.mark('PIE-Fixed-Player-Load-Complete');
244
+
245
+ // Dispatch the event load complete event
246
+ document.dispatchEvent(new CustomEvent('PiePlayerLoadEvent', {
247
+ detail: 'PIE-Fixed-Player-Load-Complete',
248
+ bubbles: true,
249
+ cancelable: true
250
+ }));
251
+
252
+ // Set global flag so Star knows PIE has loaded if PIE loads before Star and the dispatch isn't captured
253
+ window.pieFixedPlayerLoaded = true;
254
+ }
255
+ } catch {
256
+ // Performance marking failed, continue anyway
257
+ }
258
+
259
+ // Confirm ready (debug logging - never throws)
260
+ try {
261
+ if (typeof window !== 'undefined' && window.PIE_DEBUG) {
262
+ console.debug('[pie-fixed-player-static] Package loaded. PIE elements available via window.pie');
263
+ }
264
+ } catch {
265
+ // Logging failed, continue anyway
36
266
  }
37
267
  } catch (error) {
38
- console.error('[pie-fixed-player-static] Failed to initialize:', error);
268
+ // Note: Individual import failures are already logged as errors above
269
+ // This catch provides a final safety net for unexpected errors
270
+ try {
271
+ console.error('[pie-fixed-player-static] Initialization failed - pie-fixed-player is not available. See errors above for details.');
272
+ } catch {
273
+ // Even final error logging failed - nothing more we can do
274
+ }
39
275
  }
40
276
  })();
41
277