@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
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* PIE elements expect @pie-lib/math-rendering to be available on window.
|
|
5
5
|
* This module ensures required globals are populated from the upstream
|
|
6
6
|
* @pie-lib/math-rendering-module package, and also supports overriding with
|
|
7
|
-
* a custom renderer object
|
|
7
|
+
* a custom renderer object through setMathRenderer().
|
|
8
8
|
*/
|
|
9
9
|
export type MathRenderer = (element: HTMLElement) => void | Promise<void>;
|
|
10
10
|
export interface MathRenderingAPI {
|
|
@@ -14,32 +14,30 @@ export interface MathRenderingAPI {
|
|
|
14
14
|
mmlToLatex?: (mathml: string) => string;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* The page's renderer: the one `initializeMathRendering` installed, or a
|
|
18
|
+
* host's. IIFE elements render with it, and so do ESM elements when the page
|
|
19
|
+
* has one.
|
|
20
|
+
*/
|
|
21
|
+
export declare const getMathRenderer: () => MathRenderingAPI | null;
|
|
22
|
+
/**
|
|
23
|
+
* Initialize math rendering, defaulting to MathJax.
|
|
20
24
|
* For custom renderers, use setMathRenderer() before calling this function.
|
|
21
25
|
*
|
|
22
26
|
* Sets TWO window globals that PIE elements expect:
|
|
23
27
|
* - window["@pie-lib/math-rendering"] (standard key)
|
|
24
28
|
* - window["_dll_pie_lib__math_rendering"] (SystemJS/DLL key for IIFE bundles)
|
|
25
29
|
*
|
|
26
|
-
* @param customRenderer - Optional custom renderer to use instead of default MathJax
|
|
27
|
-
*
|
|
28
30
|
* @example
|
|
29
31
|
* ```typescript
|
|
30
32
|
* // Default MathJax
|
|
31
33
|
* await initializeMathRendering();
|
|
32
34
|
*
|
|
33
|
-
* // Custom renderer
|
|
34
|
-
* const customRenderer = await createCustomRenderer();
|
|
35
|
-
* await initializeMathRendering(customRenderer);
|
|
36
|
-
*
|
|
37
|
-
* // Or use setMathRenderer first
|
|
35
|
+
* // Custom renderer: install it first
|
|
38
36
|
* setMathRenderer(katexRenderer);
|
|
39
37
|
* await initializeMathRendering();
|
|
40
38
|
* ```
|
|
41
39
|
*/
|
|
42
|
-
export declare function initializeMathRendering(
|
|
40
|
+
export declare function initializeMathRendering(): Promise<void>;
|
|
43
41
|
/**
|
|
44
42
|
* Set custom math renderer programmatically
|
|
45
43
|
*
|
|
@@ -60,12 +58,3 @@ export declare function initializeMathRendering(customRenderer?: MathRenderingAP
|
|
|
60
58
|
* ```
|
|
61
59
|
*/
|
|
62
60
|
export declare function setMathRenderer(renderer: MathRenderingAPI): void;
|
|
63
|
-
/**
|
|
64
|
-
* Render math in the given element
|
|
65
|
-
*
|
|
66
|
-
* Convenience wrapper that calls the active renderer's renderMath() function.
|
|
67
|
-
* Typically called after PIE elements are rendered.
|
|
68
|
-
*
|
|
69
|
-
* @param element - The element to render math within
|
|
70
|
-
*/
|
|
71
|
-
export declare function renderMath(element: HTMLElement): void;
|
|
@@ -4,15 +4,23 @@
|
|
|
4
4
|
* PIE elements expect @pie-lib/math-rendering to be available on window.
|
|
5
5
|
* This module ensures required globals are populated from the upstream
|
|
6
6
|
* @pie-lib/math-rendering-module package, and also supports overriding with
|
|
7
|
-
* a custom renderer object
|
|
7
|
+
* a custom renderer object through setMathRenderer().
|
|
8
8
|
*/
|
|
9
9
|
/// <reference path="../shims.d.ts" />
|
|
10
10
|
import { createPieLogger, isGlobalDebugEnabled } from "./logger.js";
|
|
11
11
|
const GLOBAL_KEY = "@pie-lib/math-rendering";
|
|
12
12
|
const GLOBAL_DLL_KEY = "_dll_pie_lib__math_rendering";
|
|
13
|
+
// Every copy of @pie-lib/math-rendering on a page typesets through the MathJax
|
|
14
|
+
// instance kept here, and the first copy to typeset creates it.
|
|
15
|
+
const SHARED_INSTANCE_KEY = "@pie-lib/math-rendering@2";
|
|
13
16
|
let initPromise = null;
|
|
14
17
|
const logger = createPieLogger("math-rendering", () => isGlobalDebugEnabled());
|
|
15
|
-
|
|
18
|
+
/**
|
|
19
|
+
* The page's renderer: the one `initializeMathRendering` installed, or a
|
|
20
|
+
* host's. IIFE elements render with it, and so do ESM elements when the page
|
|
21
|
+
* has one.
|
|
22
|
+
*/
|
|
23
|
+
export const getMathRenderer = () => {
|
|
16
24
|
if (typeof window === "undefined") {
|
|
17
25
|
return null;
|
|
18
26
|
}
|
|
@@ -26,43 +34,55 @@ const setWindowRenderer = (renderer) => {
|
|
|
26
34
|
window[GLOBAL_DLL_KEY] = renderer;
|
|
27
35
|
};
|
|
28
36
|
/**
|
|
29
|
-
*
|
|
37
|
+
* Creates the shared MathJax instance from `renderer`, unless the page already
|
|
38
|
+
* holds one.
|
|
30
39
|
*
|
|
31
|
-
*
|
|
40
|
+
* Legacy element bundles carry their own copy of math-rendering. A copy that
|
|
41
|
+
* predates the assistive-MathML guard, such as the one in multiple-choice
|
|
42
|
+
* 9.9.1, re-typesets the hidden `<math>` inside `mjx-assistive-mml` on every
|
|
43
|
+
* pass, so if it creates the instance, each re-render nests the expression
|
|
44
|
+
* again for every element on the page. Typesetting a detached element makes the
|
|
45
|
+
* guarded module create it first. Failure leaves the instance to the first
|
|
46
|
+
* element, as before, so it is logged and never fails initialization.
|
|
47
|
+
*/
|
|
48
|
+
const createSharedInstance = (renderer) => {
|
|
49
|
+
if (window[SHARED_INSTANCE_KEY]?.instance)
|
|
50
|
+
return;
|
|
51
|
+
if (typeof document === "undefined" || !document.body)
|
|
52
|
+
return;
|
|
53
|
+
const warn = (error) => logger.warn("Could not create the shared MathJax instance:", error);
|
|
54
|
+
try {
|
|
55
|
+
Promise.resolve(renderer.renderMath(document.createElement("div"))).catch(warn);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
warn(error);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Initialize math rendering, defaulting to MathJax.
|
|
32
63
|
* For custom renderers, use setMathRenderer() before calling this function.
|
|
33
64
|
*
|
|
34
65
|
* Sets TWO window globals that PIE elements expect:
|
|
35
66
|
* - window["@pie-lib/math-rendering"] (standard key)
|
|
36
67
|
* - window["_dll_pie_lib__math_rendering"] (SystemJS/DLL key for IIFE bundles)
|
|
37
68
|
*
|
|
38
|
-
* @param customRenderer - Optional custom renderer to use instead of default MathJax
|
|
39
|
-
*
|
|
40
69
|
* @example
|
|
41
70
|
* ```typescript
|
|
42
71
|
* // Default MathJax
|
|
43
72
|
* await initializeMathRendering();
|
|
44
73
|
*
|
|
45
|
-
* // Custom renderer
|
|
46
|
-
* const customRenderer = await createCustomRenderer();
|
|
47
|
-
* await initializeMathRendering(customRenderer);
|
|
48
|
-
*
|
|
49
|
-
* // Or use setMathRenderer first
|
|
74
|
+
* // Custom renderer: install it first
|
|
50
75
|
* setMathRenderer(katexRenderer);
|
|
51
76
|
* await initializeMathRendering();
|
|
52
77
|
* ```
|
|
53
78
|
*/
|
|
54
|
-
export async function initializeMathRendering(
|
|
79
|
+
export async function initializeMathRendering() {
|
|
55
80
|
// Only run in browser
|
|
56
81
|
if (typeof window === "undefined") {
|
|
57
82
|
return;
|
|
58
83
|
}
|
|
59
|
-
// Explicit override always wins.
|
|
60
|
-
if (customRenderer) {
|
|
61
|
-
setWindowRenderer(customRenderer);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
84
|
// Already initialized - skip.
|
|
65
|
-
if (
|
|
85
|
+
if (getMathRenderer()) {
|
|
66
86
|
return;
|
|
67
87
|
}
|
|
68
88
|
if (initPromise) {
|
|
@@ -71,11 +91,20 @@ export async function initializeMathRendering(customRenderer) {
|
|
|
71
91
|
}
|
|
72
92
|
initPromise = (async () => {
|
|
73
93
|
try {
|
|
74
|
-
|
|
94
|
+
// The package has no exports map, so the file is named in full for
|
|
95
|
+
// resolvers that do not complete a directory, such as webpack's
|
|
96
|
+
// fully-specified ESM resolution.
|
|
97
|
+
const mathRenderingModule = await import("@pie-lib/math-rendering-module/module/index.js");
|
|
98
|
+
// The player builds defer the module's evaluation to this call (see
|
|
99
|
+
// math-rendering-module-deferral.mjs); unbundled, it evaluated on import.
|
|
100
|
+
const renderer = mathRenderingModule.evaluateMathRenderingModule
|
|
101
|
+
? mathRenderingModule.evaluateMathRenderingModule()
|
|
102
|
+
: mathRenderingModule._dll_pie_lib__math_rendering;
|
|
75
103
|
// A host may install its renderer while the default module is in flight.
|
|
76
104
|
// The explicit renderer remains authoritative when that happens.
|
|
77
|
-
if (!
|
|
78
|
-
setWindowRenderer(
|
|
105
|
+
if (!getMathRenderer()) {
|
|
106
|
+
setWindowRenderer(renderer);
|
|
107
|
+
createSharedInstance(renderer);
|
|
79
108
|
logger.debug("Math rendering module initialized (both globals set)");
|
|
80
109
|
}
|
|
81
110
|
}
|
|
@@ -113,17 +142,3 @@ export async function initializeMathRendering(customRenderer) {
|
|
|
113
142
|
export function setMathRenderer(renderer) {
|
|
114
143
|
setWindowRenderer(renderer);
|
|
115
144
|
}
|
|
116
|
-
/**
|
|
117
|
-
* Render math in the given element
|
|
118
|
-
*
|
|
119
|
-
* Convenience wrapper that calls the active renderer's renderMath() function.
|
|
120
|
-
* Typically called after PIE elements are rendered.
|
|
121
|
-
*
|
|
122
|
-
* @param element - The element to render math within
|
|
123
|
-
*/
|
|
124
|
-
export function renderMath(element) {
|
|
125
|
-
const renderer = getWindowRenderer();
|
|
126
|
-
if (renderer && typeof renderer.renderMath === "function") {
|
|
127
|
-
renderer.renderMath(element);
|
|
128
|
-
}
|
|
129
|
-
}
|
package/dist/pie/registry.d.ts
CHANGED
|
@@ -3,8 +3,20 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Manages the global PIE registry that tracks loaded elements.
|
|
5
5
|
*/
|
|
6
|
-
import type { PieRegistry } from "./types.js";
|
|
6
|
+
import type { Entry, PieRegistry } from "./types.js";
|
|
7
7
|
/**
|
|
8
8
|
* Get or create the global PIE registry
|
|
9
9
|
*/
|
|
10
10
|
export declare const pieRegistry: () => PieRegistry;
|
|
11
|
+
/**
|
|
12
|
+
* Record a tag in `window.PIE_REGISTRY`. Every registration path writes through
|
|
13
|
+
* here: the IIFE and ESM loaders, bundle initialization, and
|
|
14
|
+
* `registerPreloadedElements`.
|
|
15
|
+
*
|
|
16
|
+
* The first loaded entry for a tag `customElements` holds describes that
|
|
17
|
+
* definition, which no later load replaces, so it keeps its package and
|
|
18
|
+
* element. A later write fills only what it left empty: a controller, with the
|
|
19
|
+
* bundle type that supplied it, and a config. Any other entry is replaced.
|
|
20
|
+
* Returns the entry the registry holds afterwards.
|
|
21
|
+
*/
|
|
22
|
+
export declare function writeRegistryEntry(entry: Entry): Entry;
|
package/dist/pie/registry.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Manages the global PIE registry that tracks loaded elements.
|
|
5
5
|
*/
|
|
6
|
-
import { isPieRegistryAvailable } from "./types.js";
|
|
6
|
+
import { isPieRegistryAvailable, Status } from "./types.js";
|
|
7
7
|
/**
|
|
8
8
|
* Get or create the global PIE registry
|
|
9
9
|
*/
|
|
@@ -18,3 +18,41 @@ export const pieRegistry = () => {
|
|
|
18
18
|
}
|
|
19
19
|
return registry;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Record a tag in `window.PIE_REGISTRY`. Every registration path writes through
|
|
23
|
+
* here: the IIFE and ESM loaders, bundle initialization, and
|
|
24
|
+
* `registerPreloadedElements`.
|
|
25
|
+
*
|
|
26
|
+
* The first loaded entry for a tag `customElements` holds describes that
|
|
27
|
+
* definition, which no later load replaces, so it keeps its package and
|
|
28
|
+
* element. A later write fills only what it left empty: a controller, with the
|
|
29
|
+
* bundle type that supplied it, and a config. Any other entry is replaced.
|
|
30
|
+
* Returns the entry the registry holds afterwards.
|
|
31
|
+
*/
|
|
32
|
+
export function writeRegistryEntry(entry) {
|
|
33
|
+
const registry = pieRegistry();
|
|
34
|
+
const existing = registry[entry.tagName];
|
|
35
|
+
if (!existing ||
|
|
36
|
+
existing.status !== Status.loaded ||
|
|
37
|
+
!isDefinedTag(entry.tagName)) {
|
|
38
|
+
registry[entry.tagName] = entry;
|
|
39
|
+
return entry;
|
|
40
|
+
}
|
|
41
|
+
const fillsController = !existing.controller && !!entry.controller;
|
|
42
|
+
const fillsConfig = existing.config == null && entry.config != null;
|
|
43
|
+
if (!fillsController && !fillsConfig)
|
|
44
|
+
return existing;
|
|
45
|
+
const filled = { ...existing };
|
|
46
|
+
if (fillsController) {
|
|
47
|
+
filled.controller = entry.controller;
|
|
48
|
+
filled.bundleType = entry.bundleType;
|
|
49
|
+
}
|
|
50
|
+
if (fillsConfig)
|
|
51
|
+
filled.config = entry.config;
|
|
52
|
+
registry[entry.tagName] = filled;
|
|
53
|
+
return filled;
|
|
54
|
+
}
|
|
55
|
+
function isDefinedTag(tagName) {
|
|
56
|
+
return (typeof customElements !== "undefined" &&
|
|
57
|
+
customElements.get(tagName) !== undefined);
|
|
58
|
+
}
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
* Features:
|
|
8
8
|
* - Tracks resource load timing with PerformanceObserver
|
|
9
9
|
* - Detects and retries failed resource loads
|
|
10
|
-
* -
|
|
10
|
+
* - With `trackPageActions`, reports loads, retries and failures to the
|
|
11
|
+
* instrumentation provider it is given
|
|
11
12
|
* - Works with all resource types (audio, video, img, link)
|
|
12
13
|
*/
|
|
13
14
|
import type { InstrumentationProvider } from "../instrumentation/types.js";
|
|
14
|
-
import type { ComponentContext } from "./component-context.js";
|
|
15
15
|
export type ResourceMonitorConfig = {
|
|
16
16
|
/**
|
|
17
17
|
* Enable tracking page actions/events
|
|
@@ -22,29 +22,15 @@ export type ResourceMonitorConfig = {
|
|
|
22
22
|
/**
|
|
23
23
|
* Instrumentation provider for tracking events and errors
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* To use a different provider, pass it here:
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```typescript
|
|
33
|
-
* const provider = new ConsoleInstrumentationProvider();
|
|
34
|
-
* await provider.initialize({ debug: true });
|
|
35
|
-
*
|
|
36
|
-
* const monitor = new ResourceMonitor({
|
|
37
|
-
* trackPageActions: true,
|
|
38
|
-
* instrumentationProvider: provider
|
|
39
|
-
* });
|
|
40
|
-
* ```
|
|
25
|
+
* The monitor constructs no provider of its own: without one it only
|
|
26
|
+
* retries. Players pass what `resolveInstrumentationProvider` resolves from
|
|
27
|
+
* their `loaderConfig`.
|
|
41
28
|
*/
|
|
42
29
|
instrumentationProvider?: InstrumentationProvider;
|
|
43
30
|
/**
|
|
44
31
|
* Whether ResourceMonitor should initialize/destroy the instrumentation provider.
|
|
45
32
|
*
|
|
46
|
-
* Defaults to `
|
|
47
|
-
* `false` when a provider is injected by the host.
|
|
33
|
+
* Defaults to `false`: the provider belongs to whoever passed it in.
|
|
48
34
|
*/
|
|
49
35
|
manageProviderLifecycle?: boolean;
|
|
50
36
|
/**
|
|
@@ -97,8 +83,6 @@ export declare class ResourceMonitor {
|
|
|
97
83
|
private isBrowser;
|
|
98
84
|
private containerResources;
|
|
99
85
|
private provider;
|
|
100
|
-
private readonly ownsProvider;
|
|
101
|
-
private readonly manageProviderLifecycle;
|
|
102
86
|
private started;
|
|
103
87
|
private lifecycleVersion;
|
|
104
88
|
private pendingRetryTimers;
|
|
@@ -229,14 +213,3 @@ export declare class ResourceMonitor {
|
|
|
229
213
|
}>;
|
|
230
214
|
};
|
|
231
215
|
}
|
|
232
|
-
/**
|
|
233
|
-
* Create and start a resource monitor for a container
|
|
234
|
-
*/
|
|
235
|
-
export declare function createResourceMonitor(container: HTMLElement, config?: ResourceMonitorConfig): ResourceMonitor;
|
|
236
|
-
/**
|
|
237
|
-
* Initialize global resource request tracking (404s for fonts/images/etc.)
|
|
238
|
-
* Call this once when the app loads (client-side only).
|
|
239
|
-
*/
|
|
240
|
-
export declare function initializeResourceRequestTracking(): void;
|
|
241
|
-
export declare function getTrackedResourceRequests(): Map<string, ComponentContext[]>;
|
|
242
|
-
export declare function clearTrackedResourceRequests(): void;
|
|
@@ -7,17 +7,15 @@
|
|
|
7
7
|
* Features:
|
|
8
8
|
* - Tracks resource load timing with PerformanceObserver
|
|
9
9
|
* - Detects and retries failed resource loads
|
|
10
|
-
* -
|
|
10
|
+
* - With `trackPageActions`, reports loads, retries and failures to the
|
|
11
|
+
* instrumentation provider it is given
|
|
11
12
|
* - Works with all resource types (audio, video, img, link)
|
|
12
13
|
*/
|
|
13
|
-
import { NewRelicInstrumentationProvider } from "../instrumentation/providers/NewRelicInstrumentationProvider.js";
|
|
14
14
|
import { isInstrumentationProvider } from "../instrumentation/provider-guards.js";
|
|
15
|
-
import { getCurrentComponentContext } from "./component-context.js";
|
|
16
15
|
import { createPieLogger, isGlobalDebugEnabled } from "./logger.js";
|
|
17
16
|
const DEFAULT_CONFIG = {
|
|
18
17
|
trackPageActions: false,
|
|
19
|
-
|
|
20
|
-
manageProviderLifecycle: undefined,
|
|
18
|
+
manageProviderLifecycle: false,
|
|
21
19
|
maxRetries: 3,
|
|
22
20
|
initialRetryDelay: 500,
|
|
23
21
|
maxRetryDelay: 5000,
|
|
@@ -43,49 +41,39 @@ export class ResourceMonitor {
|
|
|
43
41
|
isBrowser;
|
|
44
42
|
containerResources = new Set(); // Track resources within our container
|
|
45
43
|
provider;
|
|
46
|
-
ownsProvider;
|
|
47
|
-
manageProviderLifecycle;
|
|
48
44
|
started = false;
|
|
49
45
|
lifecycleVersion = 0;
|
|
50
46
|
pendingRetryTimers = new Map();
|
|
51
47
|
retryInFlight = new Set();
|
|
52
48
|
pendingMediaChecks = new Map();
|
|
53
49
|
constructor(config = {}) {
|
|
54
|
-
const validInjectedProvider = isInstrumentationProvider(config.instrumentationProvider)
|
|
55
|
-
? config.instrumentationProvider
|
|
56
|
-
: undefined;
|
|
57
|
-
const hasInjectedProvider = !!validInjectedProvider;
|
|
58
|
-
const manageProviderLifecycle = config.manageProviderLifecycle ?? !hasInjectedProvider;
|
|
59
50
|
this.config = {
|
|
60
51
|
trackPageActions: config.trackPageActions ?? DEFAULT_CONFIG.trackPageActions,
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
manageProviderLifecycle: config.manageProviderLifecycle ??
|
|
53
|
+
DEFAULT_CONFIG.manageProviderLifecycle,
|
|
63
54
|
maxRetries: config.maxRetries ?? DEFAULT_CONFIG.maxRetries,
|
|
64
55
|
initialRetryDelay: config.initialRetryDelay ?? DEFAULT_CONFIG.initialRetryDelay,
|
|
65
56
|
maxRetryDelay: config.maxRetryDelay ?? DEFAULT_CONFIG.maxRetryDelay,
|
|
66
57
|
debug: config.debug ?? DEFAULT_CONFIG.debug,
|
|
67
58
|
};
|
|
68
59
|
this.logger = createPieLogger("resource-monitor", () => this.isDebugEnabled());
|
|
69
|
-
|
|
60
|
+
this.provider = isInstrumentationProvider(config.instrumentationProvider)
|
|
61
|
+
? config.instrumentationProvider
|
|
62
|
+
: undefined;
|
|
63
|
+
if (config.instrumentationProvider && !this.provider) {
|
|
70
64
|
if (this.isDebugEnabled()) {
|
|
71
65
|
this.logger.warn("Ignoring invalid instrumentation provider; expected InstrumentationProvider shape");
|
|
72
66
|
}
|
|
73
67
|
}
|
|
74
|
-
// Always use a provider - default to NewRelic if not specified
|
|
75
|
-
this.ownsProvider = !this.config.instrumentationProvider;
|
|
76
|
-
this.provider =
|
|
77
|
-
this.config.instrumentationProvider ??
|
|
78
|
-
new NewRelicInstrumentationProvider();
|
|
79
|
-
this.manageProviderLifecycle = this.config.manageProviderLifecycle;
|
|
80
68
|
// Initialize the provider (async, but don't block constructor)
|
|
81
|
-
if (this.manageProviderLifecycle) {
|
|
69
|
+
if (this.provider && this.config.manageProviderLifecycle) {
|
|
82
70
|
this.provider.initialize().catch((err) => {
|
|
83
71
|
if (this.isDebugEnabled()) {
|
|
84
72
|
this.logger.warn("Failed to initialize instrumentation provider:", err);
|
|
85
73
|
}
|
|
86
74
|
});
|
|
87
75
|
}
|
|
88
|
-
else if (this.isDebugEnabled()) {
|
|
76
|
+
else if (this.provider && this.isDebugEnabled()) {
|
|
89
77
|
this.logger.debug("Skipping provider lifecycle management for injected provider");
|
|
90
78
|
}
|
|
91
79
|
this.isBrowser =
|
|
@@ -186,7 +174,7 @@ export class ResourceMonitor {
|
|
|
186
174
|
* Track event with instrumentation provider if enabled
|
|
187
175
|
*/
|
|
188
176
|
trackInstrumentationEvent(eventName, attributes) {
|
|
189
|
-
if (!this.config.trackPageActions || !this.provider
|
|
177
|
+
if (!this.config.trackPageActions || !this.provider?.isReady()) {
|
|
190
178
|
return;
|
|
191
179
|
}
|
|
192
180
|
this.provider.trackEvent(eventName, {
|
|
@@ -199,7 +187,7 @@ export class ResourceMonitor {
|
|
|
199
187
|
* Track error with instrumentation provider if enabled
|
|
200
188
|
*/
|
|
201
189
|
trackInstrumentationError(error, attributes) {
|
|
202
|
-
if (!this.config.trackPageActions || !this.provider
|
|
190
|
+
if (!this.config.trackPageActions || !this.provider?.isReady()) {
|
|
203
191
|
return;
|
|
204
192
|
}
|
|
205
193
|
this.provider.trackError(error, {
|
|
@@ -264,7 +252,7 @@ export class ResourceMonitor {
|
|
|
264
252
|
this.containerResources.clear();
|
|
265
253
|
this.container = null;
|
|
266
254
|
this.started = false;
|
|
267
|
-
if (this.manageProviderLifecycle) {
|
|
255
|
+
if (this.provider && this.config.manageProviderLifecycle) {
|
|
268
256
|
try {
|
|
269
257
|
this.provider.destroy();
|
|
270
258
|
}
|
|
@@ -1162,190 +1150,3 @@ export class ResourceMonitor {
|
|
|
1162
1150
|
};
|
|
1163
1151
|
}
|
|
1164
1152
|
}
|
|
1165
|
-
/**
|
|
1166
|
-
* Create and start a resource monitor for a container
|
|
1167
|
-
*/
|
|
1168
|
-
export function createResourceMonitor(container, config = {}) {
|
|
1169
|
-
const monitor = new ResourceMonitor(config);
|
|
1170
|
-
monitor.start(container);
|
|
1171
|
-
return monitor;
|
|
1172
|
-
}
|
|
1173
|
-
// =============================================================================
|
|
1174
|
-
// Global resource request tracking (consolidated from the old font-request-tracker)
|
|
1175
|
-
// =============================================================================
|
|
1176
|
-
// Track failed resource requests (by URL)
|
|
1177
|
-
const failedRequests = new Map();
|
|
1178
|
-
function isResourceFile(url) {
|
|
1179
|
-
const resourceExtensions = [
|
|
1180
|
-
// Fonts
|
|
1181
|
-
".woff",
|
|
1182
|
-
".woff2",
|
|
1183
|
-
".ttf",
|
|
1184
|
-
".otf",
|
|
1185
|
-
".eot",
|
|
1186
|
-
// Images
|
|
1187
|
-
".gif",
|
|
1188
|
-
".jpg",
|
|
1189
|
-
".jpeg",
|
|
1190
|
-
".png",
|
|
1191
|
-
".svg",
|
|
1192
|
-
".webp",
|
|
1193
|
-
".ico",
|
|
1194
|
-
// Audio/Video
|
|
1195
|
-
".mp3",
|
|
1196
|
-
".mp4",
|
|
1197
|
-
".wav",
|
|
1198
|
-
".ogg",
|
|
1199
|
-
".webm",
|
|
1200
|
-
// Other assets
|
|
1201
|
-
".pdf",
|
|
1202
|
-
".css",
|
|
1203
|
-
".js",
|
|
1204
|
-
];
|
|
1205
|
-
return resourceExtensions.some((ext) => url.toLowerCase().includes(ext));
|
|
1206
|
-
}
|
|
1207
|
-
function getResourceType(url) {
|
|
1208
|
-
if (url.match(/\.(woff|woff2|ttf|otf|eot)/i))
|
|
1209
|
-
return "Font";
|
|
1210
|
-
if (url.match(/\.(gif|jpg|jpeg|png|svg|webp|ico)/i))
|
|
1211
|
-
return "Image";
|
|
1212
|
-
if (url.match(/\.(mp3|mp4|wav|ogg|webm)/i))
|
|
1213
|
-
return "Media";
|
|
1214
|
-
if (url.match(/\.(css)/i))
|
|
1215
|
-
return "Stylesheet";
|
|
1216
|
-
if (url.match(/\.(js)/i))
|
|
1217
|
-
return "Script";
|
|
1218
|
-
return "Resource";
|
|
1219
|
-
}
|
|
1220
|
-
function logFailedRequest(url, status, context) {
|
|
1221
|
-
// Only log 404s and other failures (status 0 for network errors)
|
|
1222
|
-
if (status !== 404 && status !== 0) {
|
|
1223
|
-
return;
|
|
1224
|
-
}
|
|
1225
|
-
const key = url;
|
|
1226
|
-
if (!failedRequests.has(key)) {
|
|
1227
|
-
failedRequests.set(key, []);
|
|
1228
|
-
}
|
|
1229
|
-
const contexts = failedRequests.get(key);
|
|
1230
|
-
contexts.push({
|
|
1231
|
-
...(context || { componentName: "Unknown", timestamp: Date.now() }),
|
|
1232
|
-
timestamp: Date.now(),
|
|
1233
|
-
});
|
|
1234
|
-
const resourceType = getResourceType(url);
|
|
1235
|
-
const filename = url.split("/").pop() || url;
|
|
1236
|
-
const itemId = context?.itemId || "Unknown";
|
|
1237
|
-
const componentName = context?.componentName || "Unknown component";
|
|
1238
|
-
const elementType = context?.elementType || "";
|
|
1239
|
-
console.warn(`Failed ${resourceType} request`, `\n Resource: ${filename}`, `\n URL: ${url}`, `\n Item ID: ${itemId}`, `\n Mini-Player: ${componentName}`, elementType ? `\n Element Type: ${elementType}` : "", `\n Status: ${status}`, context
|
|
1240
|
-
? ""
|
|
1241
|
-
: "\n Note: Component not tracked - may be from item markup or PIE element");
|
|
1242
|
-
}
|
|
1243
|
-
/**
|
|
1244
|
-
* Initialize global resource request tracking (404s for fonts/images/etc.)
|
|
1245
|
-
* Call this once when the app loads (client-side only).
|
|
1246
|
-
*/
|
|
1247
|
-
export function initializeResourceRequestTracking() {
|
|
1248
|
-
if (typeof window === "undefined")
|
|
1249
|
-
return;
|
|
1250
|
-
// Track fetch requests
|
|
1251
|
-
const originalFetch = window.fetch;
|
|
1252
|
-
window.fetch = async function (...args) {
|
|
1253
|
-
// Extract URL from first argument (can be string, URL, or Request)
|
|
1254
|
-
let url = "";
|
|
1255
|
-
if (typeof args[0] === "string") {
|
|
1256
|
-
url = args[0];
|
|
1257
|
-
}
|
|
1258
|
-
else if (args[0] instanceof URL) {
|
|
1259
|
-
url = args[0].toString();
|
|
1260
|
-
}
|
|
1261
|
-
else if (args[0] instanceof Request) {
|
|
1262
|
-
url = args[0].url;
|
|
1263
|
-
}
|
|
1264
|
-
if (isResourceFile(url) || url.startsWith("/")) {
|
|
1265
|
-
const context = getCurrentComponentContext();
|
|
1266
|
-
try {
|
|
1267
|
-
const response = await originalFetch(...args);
|
|
1268
|
-
if (response.status === 404) {
|
|
1269
|
-
logFailedRequest(url, response.status, context);
|
|
1270
|
-
}
|
|
1271
|
-
return response;
|
|
1272
|
-
}
|
|
1273
|
-
catch (error) {
|
|
1274
|
-
logFailedRequest(url, 0, context);
|
|
1275
|
-
throw error;
|
|
1276
|
-
}
|
|
1277
|
-
}
|
|
1278
|
-
return originalFetch(...args);
|
|
1279
|
-
};
|
|
1280
|
-
// Track XMLHttpRequest
|
|
1281
|
-
const originalXHROpen = XMLHttpRequest.prototype.open;
|
|
1282
|
-
XMLHttpRequest.prototype.open = function (method, url, async, username, password) {
|
|
1283
|
-
const urlString = typeof url === "string" ? url : url.toString();
|
|
1284
|
-
if (isResourceFile(urlString) || urlString.startsWith("/")) {
|
|
1285
|
-
const context = getCurrentComponentContext();
|
|
1286
|
-
this.addEventListener("load", function () {
|
|
1287
|
-
if (this.status === 404) {
|
|
1288
|
-
logFailedRequest(urlString, this.status, context);
|
|
1289
|
-
}
|
|
1290
|
-
});
|
|
1291
|
-
this.addEventListener("error", function () {
|
|
1292
|
-
logFailedRequest(urlString, 0, context);
|
|
1293
|
-
});
|
|
1294
|
-
}
|
|
1295
|
-
return originalXHROpen.call(this, method, url, async ?? true, username ?? null, password ?? null);
|
|
1296
|
-
};
|
|
1297
|
-
// Intercept img tag error events (most reliable way to catch failed image loads)
|
|
1298
|
-
const errorHandler = (event) => {
|
|
1299
|
-
const target = event.target;
|
|
1300
|
-
if (target instanceof HTMLImageElement && target.src) {
|
|
1301
|
-
const url = target.src;
|
|
1302
|
-
if (isResourceFile(url) ||
|
|
1303
|
-
url.startsWith("/") ||
|
|
1304
|
-
url.startsWith(window.location.origin + "/")) {
|
|
1305
|
-
const context = getCurrentComponentContext();
|
|
1306
|
-
const relativeUrl = url.startsWith(window.location.origin)
|
|
1307
|
-
? url.replace(window.location.origin, "")
|
|
1308
|
-
: url;
|
|
1309
|
-
logFailedRequest(relativeUrl, 404, context);
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
};
|
|
1313
|
-
document.addEventListener("error", errorHandler, true);
|
|
1314
|
-
// Track resource requests via PerformanceObserver (fonts, CSS resources, etc.)
|
|
1315
|
-
const observer = new PerformanceObserver((list) => {
|
|
1316
|
-
for (const entry of list.getEntries()) {
|
|
1317
|
-
if (entry.entryType !== "resource")
|
|
1318
|
-
continue;
|
|
1319
|
-
const resourceEntry = entry;
|
|
1320
|
-
const url = resourceEntry.name;
|
|
1321
|
-
if (isResourceFile(url) ||
|
|
1322
|
-
url.startsWith("/") ||
|
|
1323
|
-
url.startsWith(window.location.origin + "/")) {
|
|
1324
|
-
const perf = resourceEntry;
|
|
1325
|
-
const failed = perf.responseEnd === 0 && perf.duration > 0;
|
|
1326
|
-
const mightBe404 = perf.transferSize === 0 &&
|
|
1327
|
-
perf.responseEnd > 0 &&
|
|
1328
|
-
perf.responseStart === 0;
|
|
1329
|
-
if (failed || mightBe404) {
|
|
1330
|
-
const context = getCurrentComponentContext();
|
|
1331
|
-
const relativeUrl = url.startsWith(window.location.origin)
|
|
1332
|
-
? url.replace(window.location.origin, "")
|
|
1333
|
-
: url;
|
|
1334
|
-
logFailedRequest(relativeUrl, 404, context);
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
});
|
|
1339
|
-
try {
|
|
1340
|
-
observer.observe({ type: "resource", buffered: true });
|
|
1341
|
-
}
|
|
1342
|
-
catch (e) {
|
|
1343
|
-
console.warn("Failed to set up PerformanceObserver for resource tracking:", e);
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
export function getTrackedResourceRequests() {
|
|
1347
|
-
return new Map(failedRequests);
|
|
1348
|
-
}
|
|
1349
|
-
export function clearTrackedResourceRequests() {
|
|
1350
|
-
failedRequests.clear();
|
|
1351
|
-
}
|
package/dist/pie/scoring.d.ts
CHANGED
|
@@ -4,10 +4,17 @@
|
|
|
4
4
|
* Scoring and outcome calculation for PIE elements.
|
|
5
5
|
*/
|
|
6
6
|
import type { ConfigEntity, Env, OutcomeResponse, PieController, PieModel } from "../types/index.js";
|
|
7
|
+
import { BundleType } from "./types.js";
|
|
7
8
|
/**
|
|
8
|
-
* Find the controller for a PIE element
|
|
9
|
+
* Find the controller for a PIE element.
|
|
10
|
+
*
|
|
11
|
+
* `deliveryBundleType` is the bundle type of the player asking. A `player.js`
|
|
12
|
+
* delivery, which is what a hosted player is, resolves no controller: its
|
|
13
|
+
* models and scores come from the server, and the registry is shared with
|
|
14
|
+
* every other loader on the page, so a registered controller is no evidence
|
|
15
|
+
* that this player may run one.
|
|
9
16
|
*/
|
|
10
|
-
export declare const findPieController: (elementName: string) => PieController | undefined;
|
|
17
|
+
export declare const findPieController: (elementName: string, deliveryBundleType?: BundleType) => PieController | undefined;
|
|
11
18
|
export type ScorePieItemOptions = {
|
|
12
19
|
/** Scope element lookup to a specific player/root. Defaults to document for existing callers. */
|
|
13
20
|
container?: Pick<ParentNode, "querySelector">;
|
|
@@ -23,6 +30,8 @@ export type ScorePieItemOptions = {
|
|
|
23
30
|
* Existing scorePieItem callers keep the filtered result shape by default.
|
|
24
31
|
*/
|
|
25
32
|
includeMissingResults?: boolean;
|
|
33
|
+
/** The scoring player's bundle type; `player.js` scores nothing locally. */
|
|
34
|
+
bundleType?: BundleType;
|
|
26
35
|
};
|
|
27
36
|
export declare function scorePieItem(config: ConfigEntity, sessionData: any[], options: ScorePieItemOptions & {
|
|
28
37
|
includeMissingResults: true;
|