@pie-players/pie-players-shared 0.3.74 → 1.0.0-beta.0
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 +88 -75
- package/dist/components/vendor/nds/README.md +4 -5
- package/dist/config/profile.d.ts +1 -1
- package/dist/config/profile.js +1 -1
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/language-tags.d.ts +9 -1
- package/dist/i18n/language-tags.js +11 -1
- package/dist/i18n/messages/en-US.d.ts +33 -28
- package/dist/i18n/messages/en-US.js +34 -29
- package/dist/i18n/messages/nl-NL.d.ts +33 -28
- package/dist/i18n/messages/nl-NL.js +34 -29
- package/dist/i18n/provider.d.ts +14 -7
- package/dist/i18n/provider.js +26 -29
- package/dist/i18n/types.d.ts +4 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +0 -1
- package/dist/instrumentation/providers/BaseInstrumentationProvider.js +0 -14
- package/dist/loader-config.d.ts +0 -2
- package/dist/loader-config.js +0 -2
- package/dist/loaders/element-loader.js +13 -6
- package/dist/loaders/esm-adapter.d.ts +11 -0
- package/dist/loaders/esm-adapter.js +74 -45
- package/dist/loaders/iife-adapter.d.ts +3 -3
- package/dist/loaders/iife-adapter.js +36 -35
- package/dist/loaders/index.d.ts +4 -2
- package/dist/loaders/index.js +2 -1
- package/dist/loaders/mathjax-events.d.ts +22 -0
- package/dist/loaders/mathjax-events.js +65 -0
- package/dist/loaders/preloaded-registration.d.ts +18 -2
- package/dist/loaders/preloaded-registration.js +14 -2
- package/dist/media/index.d.ts +4 -6
- package/dist/media/index.js +6 -8
- package/dist/object/index.d.ts +8 -3
- package/dist/object/index.js +8 -6
- package/dist/pie/asset-handler.d.ts +0 -17
- package/dist/pie/asset-handler.js +1 -1
- package/dist/pie/authoring.js +5 -7
- package/dist/pie/elements-rendered.d.ts +23 -0
- package/dist/pie/elements-rendered.js +96 -0
- package/dist/pie/index.d.ts +4 -6
- package/dist/pie/index.js +4 -7
- package/dist/pie/initialization.d.ts +13 -14
- package/dist/pie/initialization.js +61 -75
- package/dist/pie/instrumentation-event-bridge.js +23 -1
- package/dist/pie/instrumentation-event-map.js +11 -18
- package/dist/pie/item-controller.js +4 -0
- package/dist/pie/item-session-contract.js +7 -9
- package/dist/pie/logger.d.ts +6 -0
- package/dist/pie/logger.js +10 -0
- package/dist/pie/math-assets.d.ts +48 -0
- package/dist/pie/math-assets.js +81 -0
- package/dist/pie/resource-monitor.d.ts +34 -32
- package/dist/pie/resource-monitor.js +152 -231
- package/dist/pie/scoring.d.ts +1 -6
- package/dist/pie/scoring.js +3 -8
- package/dist/pie/session-commit.js +1 -1
- package/dist/pie/stages.d.ts +11 -47
- package/dist/pie/stages.js +11 -47
- package/dist/pie/updates.js +5 -4
- package/dist/pie/utils.d.ts +0 -2
- package/dist/pie/utils.js +0 -2
- package/dist/security/sanitize-item-markup.d.ts +8 -4
- package/dist/security/sanitize-item-markup.js +52 -6
- package/dist/security/sanitize-svg-icon.js +2 -2
- package/dist/security/wrap-overwide-images.d.ts +1 -1
- package/dist/security/wrap-overwide-images.js +20 -1
- package/dist/security/wrap-overwide.d.ts +8 -0
- package/dist/security/wrap-overwide.js +47 -3
- package/dist/timed-media/media-element-source.js +1 -2
- package/dist/types/index.d.ts +88 -153
- package/dist/types/index.js +2 -2
- package/dist/ui/attribute-coercion.d.ts +5 -0
- package/dist/ui/attribute-coercion.js +6 -4
- package/dist/ui/content-styles.d.ts +6 -10
- package/dist/ui/content-styles.js +8 -13
- package/dist/ui/first-focusable.d.ts +0 -1
- package/dist/ui/first-focusable.js +0 -1
- package/dist/ui/focus-trap.js +2 -3
- package/dist/ui/scope-css.d.ts +23 -26
- package/dist/ui/scope-css.js +23 -26
- package/package.json +6 -4
- package/dist/loaders/mathjax-version-conflict.d.ts +0 -17
- package/dist/loaders/mathjax-version-conflict.js +0 -51
- package/dist/pie/stage-tracker.d.ts +0 -50
- package/dist/pie/stage-tracker.js +0 -105
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
export const TOOLKIT_INSTRUMENTATION_EVENT_MAP = [
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// `attached`, `runtime-bound`, and `ui-rendered` stages because they
|
|
6
|
-
// had zero internal or external consumers. Hosts listen for the
|
|
7
|
-
// DOM-prefixed name directly (`pie-stage-change`); the instrumentation
|
|
8
|
-
// bridge forwards the same name to telemetry.
|
|
9
|
-
{
|
|
10
|
-
sourceEventName: "pie-stage-change",
|
|
11
|
-
instrumentationEventName: "pie-toolkit-stage-change",
|
|
12
|
-
},
|
|
2
|
+
// The toolkit emits no stage events: the section player's runtime
|
|
3
|
+
// engine dispatches `pie-stage-change` on the layout element, above the
|
|
4
|
+
// toolkit, and the section map tracks it there.
|
|
13
5
|
{
|
|
14
6
|
sourceEventName: "runtime-owned",
|
|
15
7
|
instrumentationEventName: "pie-toolkit-runtime-owned",
|
|
@@ -18,6 +10,10 @@ export const TOOLKIT_INSTRUMENTATION_EVENT_MAP = [
|
|
|
18
10
|
sourceEventName: "runtime-inherited",
|
|
19
11
|
instrumentationEventName: "pie-toolkit-runtime-inherited",
|
|
20
12
|
},
|
|
13
|
+
{
|
|
14
|
+
sourceEventName: "runtime-ready",
|
|
15
|
+
instrumentationEventName: "pie-toolkit-runtime-ready",
|
|
16
|
+
},
|
|
21
17
|
{
|
|
22
18
|
sourceEventName: "toolkit-ready",
|
|
23
19
|
instrumentationEventName: "pie-toolkit-ready",
|
|
@@ -32,13 +28,10 @@ export const TOOLKIT_INSTRUMENTATION_EVENT_MAP = [
|
|
|
32
28
|
},
|
|
33
29
|
];
|
|
34
30
|
export const SECTION_INSTRUMENTATION_EVENT_MAP = [
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
// `ready`) and the `section-controller-ready` mapping were removed
|
|
40
|
-
// alongside their DOM-event surfaces. `session-changed` stays off the
|
|
41
|
-
// bridge for the reason the item map gives below.
|
|
31
|
+
// The runtime engine dispatches `pie-stage-change` and
|
|
32
|
+
// `pie-loading-complete` on the layout element; `framework-error`
|
|
33
|
+
// bubbles to it from the player's toolkit. `session-changed` stays off
|
|
34
|
+
// the bridge for the reason the item map gives below.
|
|
42
35
|
{
|
|
43
36
|
sourceEventName: "pie-stage-change",
|
|
44
37
|
instrumentationEventName: "pie-section-stage-change",
|
|
@@ -45,7 +45,11 @@ export class ItemController {
|
|
|
45
45
|
setSession(input, options = {}) {
|
|
46
46
|
const next = normalizeSessionContainer(input, this.sessionId);
|
|
47
47
|
const allowMetadataOverwrite = options.allowMetadataOverwrite ?? false;
|
|
48
|
+
// The guard keeps a response from metadata churn on the same session. A
|
|
49
|
+
// session with another id is a new attempt or item, and replaces it.
|
|
50
|
+
const sameSession = next.id === "" || this.session.id === "" || next.id === this.session.id;
|
|
48
51
|
if (!allowMetadataOverwrite &&
|
|
52
|
+
sameSession &&
|
|
49
53
|
hasResponseValue(this.session) &&
|
|
50
54
|
!hasResponseValue(next) &&
|
|
51
55
|
!hasResponseField(next)) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isPlainRecord } from "../object/index.js";
|
|
1
2
|
const DEFAULT_SESSION_ID = "";
|
|
2
3
|
const METADATA_ONLY_SESSION_KEYS = new Set([
|
|
3
4
|
"complete",
|
|
@@ -146,9 +147,6 @@ export function hasResponseField(value) {
|
|
|
146
147
|
}
|
|
147
148
|
return false;
|
|
148
149
|
}
|
|
149
|
-
function isPlainObject(value) {
|
|
150
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
151
|
-
}
|
|
152
150
|
function getMetadataComponent(sessionDetail, candidate) {
|
|
153
151
|
if (typeof sessionDetail.component === "string")
|
|
154
152
|
return sessionDetail.component;
|
|
@@ -194,7 +192,7 @@ function mergeSessionEntry(existing, incoming) {
|
|
|
194
192
|
for (const [key, value] of Object.entries(incoming)) {
|
|
195
193
|
const previous = merged[key];
|
|
196
194
|
merged[key] =
|
|
197
|
-
|
|
195
|
+
isPlainRecord(previous) && isPlainRecord(value)
|
|
198
196
|
? mergeSessionEntry(previous, value)
|
|
199
197
|
: value;
|
|
200
198
|
}
|
|
@@ -334,7 +332,7 @@ function classifyItemSessionChange(args) {
|
|
|
334
332
|
};
|
|
335
333
|
}
|
|
336
334
|
function hostContainerEntries(hostContainer) {
|
|
337
|
-
if (!
|
|
335
|
+
if (!isPlainRecord(hostContainer)) {
|
|
338
336
|
return null;
|
|
339
337
|
}
|
|
340
338
|
// A frozen container is not a live view of anything, and a shared immutable
|
|
@@ -355,7 +353,7 @@ function hostContainerEntries(hostContainer) {
|
|
|
355
353
|
return null;
|
|
356
354
|
}
|
|
357
355
|
function sessionEntryId(value) {
|
|
358
|
-
if (!
|
|
356
|
+
if (!isPlainRecord(value)) {
|
|
359
357
|
return null;
|
|
360
358
|
}
|
|
361
359
|
const id = value.id;
|
|
@@ -405,7 +403,7 @@ export function ensureHostSessionEntries(hostContainer, entryIds) {
|
|
|
405
403
|
*/
|
|
406
404
|
export function projectSessionIntoHostContainer(hostContainer, liveSession) {
|
|
407
405
|
const entries = hostContainerEntries(hostContainer);
|
|
408
|
-
if (!entries || !
|
|
406
|
+
if (!entries || !isPlainRecord(hostContainer)) {
|
|
409
407
|
return false;
|
|
410
408
|
}
|
|
411
409
|
const live = normalizeItemSessionContainer(liveSession);
|
|
@@ -417,11 +415,11 @@ export function projectSessionIntoHostContainer(hostContainer, liveSession) {
|
|
|
417
415
|
}
|
|
418
416
|
for (const nextEntry of live.data) {
|
|
419
417
|
const id = sessionEntryId(nextEntry);
|
|
420
|
-
if (!id || !
|
|
418
|
+
if (!id || !isPlainRecord(nextEntry)) {
|
|
421
419
|
continue;
|
|
422
420
|
}
|
|
423
421
|
const target = entries.find((entry) => sessionEntryId(entry) === id);
|
|
424
|
-
if (!
|
|
422
|
+
if (!isPlainRecord(target)) {
|
|
425
423
|
entries.push({ ...nextEntry });
|
|
426
424
|
wrote = true;
|
|
427
425
|
continue;
|
package/dist/pie/logger.d.ts
CHANGED
|
@@ -61,3 +61,9 @@ declare global {
|
|
|
61
61
|
* Check if debug mode is enabled globally
|
|
62
62
|
*/
|
|
63
63
|
export declare function isGlobalDebugEnabled(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Read-aloud's debug flag: `PIE_TTS_DEBUG=1` in the environment, or
|
|
66
|
+
* `globalThis.__PIE_TTS_DEBUG__ = true` in a page. Every read-aloud logger is
|
|
67
|
+
* created with it, and reads it on each debug line.
|
|
68
|
+
*/
|
|
69
|
+
export declare function isTtsDebugEnabled(): boolean;
|
package/dist/pie/logger.js
CHANGED
|
@@ -42,3 +42,13 @@ export function createPieLogger(namespace, debugEnabledFn) {
|
|
|
42
42
|
export function isGlobalDebugEnabled() {
|
|
43
43
|
return typeof window !== "undefined" && window.PIE_DEBUG === true;
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Read-aloud's debug flag: `PIE_TTS_DEBUG=1` in the environment, or
|
|
47
|
+
* `globalThis.__PIE_TTS_DEBUG__ = true` in a page. Every read-aloud logger is
|
|
48
|
+
* created with it, and reads it on each debug line.
|
|
49
|
+
*/
|
|
50
|
+
export function isTtsDebugEnabled() {
|
|
51
|
+
const scope = globalThis;
|
|
52
|
+
return (scope.process?.env?.PIE_TTS_DEBUG === "1" ||
|
|
53
|
+
scope.__PIE_TTS_DEBUG__ === true);
|
|
54
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the MathJax adapter's copies load MathJax's fonts, speech worker and,
|
|
3
|
+
* on its npm build, MathJax itself from, and whether math is in the tab order.
|
|
4
|
+
* Every copy of `@pie-element/shared-math-rendering-mathjax` reads these from
|
|
5
|
+
* the legacy renderer's page options as it starts MathJax, on its first render,
|
|
6
|
+
* so they are set before any element renders. See
|
|
7
|
+
* https://github.com/pie-framework/pie-elements-ng/blob/develop/docs/MATH-RENDERING.md#assets
|
|
8
|
+
*/
|
|
9
|
+
export interface MathAssetOptions {
|
|
10
|
+
/**
|
|
11
|
+
* An npm root: a URL under which `<package>@<version>/<path>` serves that
|
|
12
|
+
* file of the package, such as `https://cdn.jsdelivr.net/npm`. A relative URL
|
|
13
|
+
* resolves against the page.
|
|
14
|
+
*/
|
|
15
|
+
assetRoot?: string | URL;
|
|
16
|
+
/**
|
|
17
|
+
* The directory of `speech-worker.js` and its `mathmaps/`, by default
|
|
18
|
+
* `mathjax@<version>/sre` under the asset root.
|
|
19
|
+
*/
|
|
20
|
+
speechPath?: string | URL;
|
|
21
|
+
/**
|
|
22
|
+
* The URL of individual files by npm path, `<package>@<version>/<path>`: a
|
|
23
|
+
* listed file loads from its URL, the rest from the asset root. A bundle lists
|
|
24
|
+
* each file it ships as `new URL("./…", import.meta.url)`, which its host's
|
|
25
|
+
* bundler emits, and needs no root. Read by the adapter's browser build, for
|
|
26
|
+
* its fonts, speech worker and speech rules.
|
|
27
|
+
*/
|
|
28
|
+
assetUrls?: Readonly<Record<string, string | URL>>;
|
|
29
|
+
/**
|
|
30
|
+
* The speech locales the MathJax menu lists, by id (`["en", "es"]`), or by id
|
|
31
|
+
* with the label it shows. Unset, it lists every locale SRE ships.
|
|
32
|
+
*/
|
|
33
|
+
speechLocales?: readonly string[] | Readonly<Record<string, string>>;
|
|
34
|
+
/**
|
|
35
|
+
* Puts typeset math in the keyboard tab order, for the MathJax menu and its
|
|
36
|
+
* explorer. Off by default.
|
|
37
|
+
*/
|
|
38
|
+
inTabOrder?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/** Why `options` is not a `MathAssetOptions`, or `undefined` when it is. */
|
|
41
|
+
export declare function mathAssetOptionsError(options: unknown): string | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Writes `options` to the page options, keeping the ones it leaves unset and
|
|
44
|
+
* the files of `assetUrls` it does not list.
|
|
45
|
+
*/
|
|
46
|
+
export declare function setMathAssetOptions(options: MathAssetOptions): void;
|
|
47
|
+
/** The asset root the page options set, if any. */
|
|
48
|
+
export declare function pageMathAssetRoot(): string | undefined;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the MathJax adapter's copies load MathJax's fonts, speech worker and,
|
|
3
|
+
* on its npm build, MathJax itself from, and whether math is in the tab order.
|
|
4
|
+
* Every copy of `@pie-element/shared-math-rendering-mathjax` reads these from
|
|
5
|
+
* the legacy renderer's page options as it starts MathJax, on its first render,
|
|
6
|
+
* so they are set before any element renders. See
|
|
7
|
+
* https://github.com/pie-framework/pie-elements-ng/blob/develop/docs/MATH-RENDERING.md#assets
|
|
8
|
+
*/
|
|
9
|
+
/** The legacy renderer's page options, which the adapter reads as well. */
|
|
10
|
+
const PAGE_OPTIONS_KEY = "@pie-lib/math-rendering@2";
|
|
11
|
+
const isUrl = (value) => (typeof value === "string" && value !== "") || value instanceof URL;
|
|
12
|
+
/** Why `options` is not a `MathAssetOptions`, or `undefined` when it is. */
|
|
13
|
+
export function mathAssetOptionsError(options) {
|
|
14
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
15
|
+
return "must be an object";
|
|
16
|
+
}
|
|
17
|
+
const { assetRoot, speechPath, assetUrls, speechLocales, inTabOrder } = options;
|
|
18
|
+
if (assetRoot !== undefined && !isUrl(assetRoot)) {
|
|
19
|
+
return `assetRoot must be a URL, got ${JSON.stringify(assetRoot)}`;
|
|
20
|
+
}
|
|
21
|
+
if (speechPath !== undefined && !isUrl(speechPath)) {
|
|
22
|
+
return `speechPath must be a URL, got ${JSON.stringify(speechPath)}`;
|
|
23
|
+
}
|
|
24
|
+
if (assetUrls !== undefined &&
|
|
25
|
+
(!assetUrls ||
|
|
26
|
+
typeof assetUrls !== "object" ||
|
|
27
|
+
Array.isArray(assetUrls) ||
|
|
28
|
+
!Object.values(assetUrls).every(isUrl))) {
|
|
29
|
+
return "assetUrls must map npm paths to URLs";
|
|
30
|
+
}
|
|
31
|
+
if (speechLocales !== undefined) {
|
|
32
|
+
const listed = Array.isArray(speechLocales)
|
|
33
|
+
? speechLocales
|
|
34
|
+
: speechLocales && typeof speechLocales === "object"
|
|
35
|
+
? Object.values(speechLocales)
|
|
36
|
+
: null;
|
|
37
|
+
if (!listed || listed.some((entry) => typeof entry !== "string" || !entry)) {
|
|
38
|
+
return "speechLocales must be locale ids, or locale ids mapped to their labels";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (inTabOrder !== undefined && typeof inTabOrder !== "boolean") {
|
|
42
|
+
return `inTabOrder must be a boolean, got ${JSON.stringify(inTabOrder)}`;
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Writes `options` to the page options, keeping the ones it leaves unset and
|
|
48
|
+
* the files of `assetUrls` it does not list.
|
|
49
|
+
*/
|
|
50
|
+
export function setMathAssetOptions(options) {
|
|
51
|
+
if (typeof window === "undefined")
|
|
52
|
+
return;
|
|
53
|
+
const host = window;
|
|
54
|
+
const page = (host[PAGE_OPTIONS_KEY] ??= {});
|
|
55
|
+
const opts = (page.opts ??= {});
|
|
56
|
+
if (options.assetRoot !== undefined)
|
|
57
|
+
opts.assetRoot = String(options.assetRoot);
|
|
58
|
+
if (options.speechPath !== undefined)
|
|
59
|
+
opts.speechPath = String(options.speechPath);
|
|
60
|
+
if (options.assetUrls !== undefined) {
|
|
61
|
+
const listed = opts.assetUrls && typeof opts.assetUrls === "object" ? opts.assetUrls : {};
|
|
62
|
+
opts.assetUrls = {
|
|
63
|
+
...listed,
|
|
64
|
+
...Object.fromEntries(Object.entries(options.assetUrls).map(([path, url]) => [path, String(url)])),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (options.speechLocales !== undefined) {
|
|
68
|
+
opts.speechLocales = Array.isArray(options.speechLocales)
|
|
69
|
+
? [...options.speechLocales]
|
|
70
|
+
: { ...options.speechLocales };
|
|
71
|
+
}
|
|
72
|
+
if (options.inTabOrder !== undefined)
|
|
73
|
+
opts.inTabOrder = options.inTabOrder;
|
|
74
|
+
}
|
|
75
|
+
/** The asset root the page options set, if any. */
|
|
76
|
+
export function pageMathAssetRoot() {
|
|
77
|
+
if (typeof window === "undefined")
|
|
78
|
+
return undefined;
|
|
79
|
+
const root = window[PAGE_OPTIONS_KEY]?.opts?.assetRoot;
|
|
80
|
+
return typeof root === "string" && root ? root : undefined;
|
|
81
|
+
}
|
|
@@ -69,7 +69,9 @@ export interface MediaRetryReadyDetail extends ResourceMonitorEventDetail {
|
|
|
69
69
|
mediaTag: "audio" | "video";
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
|
-
* Tracks resource loads and
|
|
72
|
+
* Tracks the resource loads of one container and retries failed ones with
|
|
73
|
+
* exponential backoff and cache-busting URLs. The events it dispatches are
|
|
74
|
+
* listed in the event contract above.
|
|
73
75
|
*/
|
|
74
76
|
export declare class ResourceMonitor {
|
|
75
77
|
private config;
|
|
@@ -77,13 +79,20 @@ export declare class ResourceMonitor {
|
|
|
77
79
|
private observer;
|
|
78
80
|
private mutationObserver;
|
|
79
81
|
private errorHandler;
|
|
82
|
+
/** Retries scheduled so far, keyed by the URL without retry parameters. */
|
|
80
83
|
private retryAttempts;
|
|
84
|
+
/** Elements that failed to load each URL; a retry reloads the first one. */
|
|
81
85
|
private retryTargets;
|
|
82
86
|
private container;
|
|
83
|
-
private isBrowser;
|
|
87
|
+
private readonly isBrowser;
|
|
88
|
+
/** URLs referenced inside the container; timing entries for others are ignored. */
|
|
84
89
|
private containerResources;
|
|
85
90
|
private provider;
|
|
86
91
|
private started;
|
|
92
|
+
/**
|
|
93
|
+
* Bumped on every start and stop, so timers and listeners captured in an
|
|
94
|
+
* earlier lifecycle see themselves as stale.
|
|
95
|
+
*/
|
|
87
96
|
private lifecycleVersion;
|
|
88
97
|
private pendingRetryTimers;
|
|
89
98
|
private retryInFlight;
|
|
@@ -116,13 +125,10 @@ export declare class ResourceMonitor {
|
|
|
116
125
|
* Start monitoring resources in the given container
|
|
117
126
|
*/
|
|
118
127
|
start(container: HTMLElement): void;
|
|
119
|
-
/**
|
|
120
|
-
* Stop monitoring and clean up
|
|
121
|
-
*/
|
|
122
128
|
stop(): void;
|
|
123
129
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
130
|
+
* Tracks resources added to the container, or retargeted inside it, so
|
|
131
|
+
* timing entries can be attributed to this container.
|
|
126
132
|
*/
|
|
127
133
|
private setupMutationObserver;
|
|
128
134
|
/**
|
|
@@ -137,45 +143,38 @@ export declare class ResourceMonitor {
|
|
|
137
143
|
* Set up PerformanceObserver to track resource loading timing
|
|
138
144
|
*/
|
|
139
145
|
private setupPerformanceObserver;
|
|
140
|
-
/**
|
|
141
|
-
* Handle resource timing entry
|
|
142
|
-
*/
|
|
143
146
|
private handleResourceTiming;
|
|
147
|
+
private logResourceTiming;
|
|
144
148
|
private isLifecycleActive;
|
|
145
149
|
private clearRetryTracking;
|
|
146
150
|
private clearPendingMediaCheck;
|
|
147
151
|
private getRetryTargets;
|
|
148
152
|
private getPrimaryRetryTarget;
|
|
149
|
-
/**
|
|
150
|
-
* Handle successful resource load
|
|
151
|
-
*/
|
|
152
153
|
private handleSuccessfulLoad;
|
|
153
154
|
private resolveMediaTarget;
|
|
154
155
|
private resolveMediaTargetsForUrl;
|
|
155
156
|
private normalizeRetrySuccessResourceType;
|
|
156
157
|
private isMediaRetryRecovered;
|
|
157
158
|
private finalizeRetrySuccess;
|
|
159
|
+
/**
|
|
160
|
+
* A retried media fetch that succeeds does not mean the element recovered:
|
|
161
|
+
* it can still hold an error or no source. Success waits until a media
|
|
162
|
+
* target reports metadata, checked on `loadedmetadata`/`canplay` and by
|
|
163
|
+
* polling, and the reconciliation timeout bounds the wait.
|
|
164
|
+
*/
|
|
158
165
|
private reconcileMediaRetrySuccess;
|
|
166
|
+
private completeMediaRetry;
|
|
159
167
|
private handleMediaRetryReconciliationTimeout;
|
|
160
168
|
private dispatchMediaRetryReady;
|
|
161
|
-
/**
|
|
162
|
-
* Handle failed resource load
|
|
163
|
-
*/
|
|
164
169
|
private handleFailedLoad;
|
|
165
170
|
/**
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
171
|
+
* Whether a timing entry belongs to this container. Timing entries carry
|
|
172
|
+
* absolute URLs, so a suffix match against a tracked URL also counts. The
|
|
173
|
+
* buffered observer also reports resources that loaded before the scan
|
|
174
|
+
* tracked them; those are looked up in the container's DOM.
|
|
169
175
|
*/
|
|
170
176
|
private isRelevantResource;
|
|
171
|
-
/**
|
|
172
|
-
* Check if a resource URL actually belongs to our container by checking DOM elements
|
|
173
|
-
* This is a fallback for resources that loaded before MutationObserver scanned
|
|
174
|
-
*/
|
|
175
177
|
private isResourceInContainer;
|
|
176
|
-
/**
|
|
177
|
-
* Set up error event handler for resource loading failures
|
|
178
|
-
*/
|
|
179
178
|
private setupErrorHandler;
|
|
180
179
|
/**
|
|
181
180
|
* Check if element is a resource element
|
|
@@ -189,18 +188,21 @@ export declare class ResourceMonitor {
|
|
|
189
188
|
* Handle permanent resource failure after all retries exhausted
|
|
190
189
|
*/
|
|
191
190
|
private handlePermanentFailure;
|
|
192
|
-
/**
|
|
193
|
-
|
|
194
|
-
*/
|
|
191
|
+
/** Exponential backoff, capped at `maxRetryDelay`. */
|
|
192
|
+
private retryDelay;
|
|
195
193
|
private logRetrySchedule;
|
|
196
194
|
/**
|
|
197
|
-
*
|
|
195
|
+
* Reloads one element under a cache-busting URL. Media elements also need
|
|
196
|
+
* `load()`, since changing a `<source>` alone does not restart the fetch.
|
|
198
197
|
*/
|
|
199
198
|
private performRetryLoadAttempt;
|
|
200
|
-
private retryResourceLoad;
|
|
201
199
|
/**
|
|
202
|
-
*
|
|
200
|
+
* Schedules the next retry of a failed resource with exponential backoff,
|
|
201
|
+
* or fails it permanently once `maxRetries` is spent. Every failing element
|
|
202
|
+
* joins the URL's retry targets; concurrent errors for one URL share the
|
|
203
|
+
* retry already in flight.
|
|
203
204
|
*/
|
|
205
|
+
private retryResourceLoad;
|
|
204
206
|
private dispatchEvent;
|
|
205
207
|
/**
|
|
206
208
|
* Get current retry statistics
|