@pie-players/pie-players-shared 0.3.73 → 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 +4 -4
- package/dist/pie/index.js +5 -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 +8 -0
- package/dist/pie/item-session-contract.js +30 -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 +16 -0
- package/dist/pie/session-commit.js +33 -5
- 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
package/dist/loader-config.d.ts
CHANGED
|
@@ -24,13 +24,16 @@ export type LoaderConfig = {
|
|
|
24
24
|
/**
|
|
25
25
|
* Instrumentation provider for tracking events and errors.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* - Unset or `undefined`: nothing is reported unless `trackPageActions` is
|
|
28
|
+
* `true`, in which case players fall back to a
|
|
29
|
+
* `NewRelicInstrumentationProvider`, which reports while the New Relic
|
|
30
|
+
* browser agent is on the page.
|
|
31
|
+
* - A provider: players report to it. A value that fails the
|
|
32
|
+
* `InstrumentationProvider` contract is treated as `null`.
|
|
33
|
+
* - `null`: disables instrumentation, whatever `trackPageActions` says.
|
|
30
34
|
*
|
|
31
|
-
* @example Using New Relic (
|
|
35
|
+
* @example Using New Relic (the fallback, no provider needed)
|
|
32
36
|
* ```typescript
|
|
33
|
-
* // Just enable tracking - will use New Relic if window.newrelic is available
|
|
34
37
|
* const loaderConfig = {
|
|
35
38
|
* trackPageActions: true
|
|
36
39
|
* };
|
|
@@ -47,8 +50,15 @@ export type LoaderConfig = {
|
|
|
47
50
|
* instrumentationProvider: provider
|
|
48
51
|
* };
|
|
49
52
|
* ```
|
|
53
|
+
* @example Disabling instrumentation
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const loaderConfig = {
|
|
56
|
+
* trackPageActions: true,
|
|
57
|
+
* instrumentationProvider: null
|
|
58
|
+
* };
|
|
59
|
+
* ```
|
|
50
60
|
*/
|
|
51
|
-
instrumentationProvider?: InstrumentationProvider;
|
|
61
|
+
instrumentationProvider?: InstrumentationProvider | null;
|
|
52
62
|
/**
|
|
53
63
|
* Maximum number of retry attempts for failed resources (images/audio/video).
|
|
54
64
|
*/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a player's ESM backend fetches controller modules
|
|
3
|
+
* (`EsmBackendConfig.loadControllers`).
|
|
4
|
+
*
|
|
5
|
+
* The host's `loaderOptions.loadControllers` decides when set. Otherwise an
|
|
6
|
+
* author view loads them, and a delivery loads them unless it is hosted: a
|
|
7
|
+
* hosted player takes models and scores from the server and resolves no
|
|
8
|
+
* controller (`findPieController`), so fetching one is wasted.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveLoadControllers(args: {
|
|
11
|
+
loadControllers?: boolean;
|
|
12
|
+
author: boolean;
|
|
13
|
+
hosted: boolean;
|
|
14
|
+
}): boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a player's ESM backend fetches controller modules
|
|
3
|
+
* (`EsmBackendConfig.loadControllers`).
|
|
4
|
+
*
|
|
5
|
+
* The host's `loaderOptions.loadControllers` decides when set. Otherwise an
|
|
6
|
+
* author view loads them, and a delivery loads them unless it is hosted: a
|
|
7
|
+
* hosted player takes models and scores from the server and resolves no
|
|
8
|
+
* controller (`findPieController`), so fetching one is wasted.
|
|
9
|
+
*/
|
|
10
|
+
export function resolveLoadControllers(args) {
|
|
11
|
+
return args.loadControllers ?? (args.author || !args.hosted);
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default PIE bundle service base URL. Exported so widgets can use it as
|
|
3
|
+
* the fallback when the host does not supply `loaderOptions.bundleHost`.
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_BUNDLE_HOST = "https://proxy.pie-api.com/bundles/";
|
|
6
|
+
/**
|
|
7
|
+
* Default ESM CDN base URL, the fallback when the host does not supply
|
|
8
|
+
* `loaderOptions.esmCdnUrl`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_ESM_CDN_URL = "https://cdn.jsdelivr.net/npm";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default PIE bundle service base URL. Exported so widgets can use it as
|
|
3
|
+
* the fallback when the host does not supply `loaderOptions.bundleHost`.
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_BUNDLE_HOST = "https://proxy.pie-api.com/bundles/";
|
|
6
|
+
/**
|
|
7
|
+
* Default ESM CDN base URL, the fallback when the host does not supply
|
|
8
|
+
* `loaderOptions.esmCdnUrl`.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_ESM_CDN_URL = "https://cdn.jsdelivr.net/npm";
|
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
* unregistered tags and a per-tag `RegistrationFailureReason` map.
|
|
11
11
|
*
|
|
12
12
|
* The primitive delegates the actual fetch/register work to a backend
|
|
13
|
-
* adapter (IIFE or ESM)
|
|
13
|
+
* adapter (IIFE or ESM) and verifies the outcome via
|
|
14
14
|
* `customElements.whenDefined`. An adapter cannot silently under-register
|
|
15
|
-
* — the primitive will catch it and surface a timeout reason.
|
|
15
|
+
* — the primitive will catch it and surface a timeout reason. A tag the
|
|
16
|
+
* adapter reports a failed load for is not waited on.
|
|
16
17
|
*
|
|
17
18
|
* See packages/players-shared/tests/element-loader-contract.test.ts for
|
|
18
19
|
* the executable specification of every failure mode this primitive is
|
|
@@ -29,7 +30,7 @@ export type { IifeBackendConfig } from "./iife-adapter.js";
|
|
|
29
30
|
export type { EsmBackendConfig } from "./esm-adapter.js";
|
|
30
31
|
/**
|
|
31
32
|
* Aggregate error thrown by `ensureRegistered` when one or more requested
|
|
32
|
-
* tags were not registered
|
|
33
|
+
* tags were not registered: their loads failed, or verification timed out.
|
|
33
34
|
*/
|
|
34
35
|
export declare class ElementLoaderError extends Error {
|
|
35
36
|
readonly name = "ElementLoaderError";
|
|
@@ -37,17 +38,24 @@ export declare class ElementLoaderError extends Error {
|
|
|
37
38
|
readonly reasons: Map<ElementTag, RegistrationFailureReason>;
|
|
38
39
|
constructor(message: string, unregisteredTags: Set<ElementTag>, reasons: Map<ElementTag, RegistrationFailureReason>);
|
|
39
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Why each tag of an `ElementLoaderError` failed to register, one clause per
|
|
43
|
+
* tag; `undefined` for any other error. Players report it as the `cause` of a
|
|
44
|
+
* load error.
|
|
45
|
+
*/
|
|
46
|
+
export declare function describeRegistrationFailures(error: unknown): string | undefined;
|
|
40
47
|
/**
|
|
41
48
|
* Thrown by `assertRegistered` when any requested tag is missing from
|
|
42
|
-
* `customElements`.
|
|
43
|
-
*
|
|
49
|
+
* `customElements`. The message names, for each missing tag, the tags its
|
|
50
|
+
* package (or, without one, its base tag) is registered under.
|
|
44
51
|
*/
|
|
45
52
|
export declare class ElementAssertionError extends Error {
|
|
46
53
|
readonly name = "ElementAssertionError";
|
|
47
54
|
readonly expectedTags: readonly ElementTag[];
|
|
48
55
|
readonly missingTags: readonly ElementTag[];
|
|
56
|
+
/** The `window.PIE_REGISTRY` tags `customElements` holds. */
|
|
49
57
|
readonly currentlyRegisteredTags: readonly ElementTag[];
|
|
50
|
-
constructor(expected: ElementTag[], missing: ElementTag[], currentlyRegistered: ElementTag[]);
|
|
58
|
+
constructor(expected: ElementTag[], missing: ElementTag[], currentlyRegistered: ElementTag[], packages?: ElementMap);
|
|
51
59
|
}
|
|
52
60
|
export type BackendOption = IifeBackendConfig | EsmBackendConfig | ElementLoaderBackend;
|
|
53
61
|
export type EnsureRegisteredOptions = {
|
|
@@ -85,6 +93,8 @@ export type EnsureRegisteredOptions = {
|
|
|
85
93
|
* - After the adapter's `load` settles, a post-load verification pass
|
|
86
94
|
* (bounded `customElements.whenDefined`) checks every tag. Any missing
|
|
87
95
|
* tag becomes a rejection.
|
|
96
|
+
* - Verification does not wait on a tag the adapter reports a failed load
|
|
97
|
+
* for, so when that covers every missing tag the rejection is immediate.
|
|
88
98
|
*/
|
|
89
99
|
export declare function ensureRegistered(elements: ElementMap, options: EnsureRegisteredOptions): Promise<void>;
|
|
90
100
|
/**
|
|
@@ -92,6 +102,8 @@ export declare function ensureRegistered(elements: ElementMap, options: EnsureRe
|
|
|
92
102
|
* Throws `ElementAssertionError` with diagnostic detail otherwise.
|
|
93
103
|
*
|
|
94
104
|
* Used by hosts that opt into the "preloaded" strategy — they pre-register
|
|
95
|
-
* elements out-of-band and want a loud failure if anything is missing.
|
|
105
|
+
* elements out-of-band and want a loud failure if anything is missing. An
|
|
106
|
+
* element map, tag to package spec, lets the error name what each missing
|
|
107
|
+
* tag's package is registered as.
|
|
96
108
|
*/
|
|
97
|
-
export declare function assertRegistered(tags: ElementTag[]): void;
|
|
109
|
+
export declare function assertRegistered(tags: ElementTag[] | ElementMap): void;
|
|
@@ -10,23 +10,28 @@
|
|
|
10
10
|
* unregistered tags and a per-tag `RegistrationFailureReason` map.
|
|
11
11
|
*
|
|
12
12
|
* The primitive delegates the actual fetch/register work to a backend
|
|
13
|
-
* adapter (IIFE or ESM)
|
|
13
|
+
* adapter (IIFE or ESM) and verifies the outcome via
|
|
14
14
|
* `customElements.whenDefined`. An adapter cannot silently under-register
|
|
15
|
-
* — the primitive will catch it and surface a timeout reason.
|
|
15
|
+
* — the primitive will catch it and surface a timeout reason. A tag the
|
|
16
|
+
* adapter reports a failed load for is not waited on.
|
|
16
17
|
*
|
|
17
18
|
* See packages/players-shared/tests/element-loader-contract.test.ts for
|
|
18
19
|
* the executable specification of every failure mode this primitive is
|
|
19
20
|
* required to catch.
|
|
20
21
|
*/
|
|
21
22
|
import { DEFAULT_IIFE_BUNDLE_RETRY_CONFIG } from "../loader-config.js";
|
|
23
|
+
import { pieRegistry } from "../pie/registry.js";
|
|
24
|
+
import { Status } from "../pie/types.js";
|
|
25
|
+
import { parsePackageName } from "../pie/utils.js";
|
|
26
|
+
import { parseVersionedTagName } from "../pie/versioned-tag.js";
|
|
22
27
|
import { AdapterFailure, } from "./element-loader-types.js";
|
|
23
|
-
import { createEsmBackend } from "./esm-adapter.js";
|
|
28
|
+
import { clearPackageMetadataRequests, createEsmBackend, } from "./esm-adapter.js";
|
|
24
29
|
import { createIifeBackend } from "./iife-adapter.js";
|
|
25
30
|
import { assertElementPackagesAllowed, } from "./element-package-policy.js";
|
|
26
31
|
export { AdapterFailure } from "./element-loader-types.js";
|
|
27
32
|
/**
|
|
28
33
|
* Aggregate error thrown by `ensureRegistered` when one or more requested
|
|
29
|
-
* tags were not registered
|
|
34
|
+
* tags were not registered: their loads failed, or verification timed out.
|
|
30
35
|
*/
|
|
31
36
|
export class ElementLoaderError extends Error {
|
|
32
37
|
name = "ElementLoaderError";
|
|
@@ -38,31 +43,85 @@ export class ElementLoaderError extends Error {
|
|
|
38
43
|
this.reasons = reasons;
|
|
39
44
|
}
|
|
40
45
|
}
|
|
46
|
+
const describeRegistrationFailure = (reason) => {
|
|
47
|
+
switch (reason.kind) {
|
|
48
|
+
case "timeout":
|
|
49
|
+
return `not defined within ${reason.timeoutMs} ms`;
|
|
50
|
+
case "module-load-failed":
|
|
51
|
+
return `${reason.specifier} failed to load: ${reason.cause}`;
|
|
52
|
+
case "bundle-load-failed":
|
|
53
|
+
return `${reason.url} failed to load: ${reason.cause}`;
|
|
54
|
+
case "define-failed":
|
|
55
|
+
case "backend-rejected":
|
|
56
|
+
return reason.cause;
|
|
57
|
+
case "not-a-constructor":
|
|
58
|
+
return `${reason.packageName ?? "its package"} exports no element constructor`;
|
|
59
|
+
case "no-element-class":
|
|
60
|
+
return `${reason.packageName} exports no element class`;
|
|
61
|
+
case "package-not-in-bundle":
|
|
62
|
+
return `${reason.packageName} is not in the bundle, which holds ${reason.availablePackages.join(", ") || "no packages"}`;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Why each tag of an `ElementLoaderError` failed to register, one clause per
|
|
67
|
+
* tag; `undefined` for any other error. Players report it as the `cause` of a
|
|
68
|
+
* load error.
|
|
69
|
+
*/
|
|
70
|
+
export function describeRegistrationFailures(error) {
|
|
71
|
+
if (!(error instanceof ElementLoaderError))
|
|
72
|
+
return undefined;
|
|
73
|
+
return [...error.reasons]
|
|
74
|
+
.map(([tag, reason]) => `${tag} (${reason.kind}): ${describeRegistrationFailure(reason)}`)
|
|
75
|
+
.join("; ");
|
|
76
|
+
}
|
|
41
77
|
/**
|
|
42
78
|
* Thrown by `assertRegistered` when any requested tag is missing from
|
|
43
|
-
* `customElements`.
|
|
44
|
-
*
|
|
79
|
+
* `customElements`. The message names, for each missing tag, the tags its
|
|
80
|
+
* package (or, without one, its base tag) is registered under.
|
|
45
81
|
*/
|
|
46
82
|
export class ElementAssertionError extends Error {
|
|
47
83
|
name = "ElementAssertionError";
|
|
48
84
|
expectedTags;
|
|
49
85
|
missingTags;
|
|
86
|
+
/** The `window.PIE_REGISTRY` tags `customElements` holds. */
|
|
50
87
|
currentlyRegisteredTags;
|
|
51
|
-
constructor(expected, missing, currentlyRegistered) {
|
|
52
|
-
super(buildAssertionMessage(expected, missing, currentlyRegistered));
|
|
88
|
+
constructor(expected, missing, currentlyRegistered, packages = {}) {
|
|
89
|
+
super(buildAssertionMessage(expected, missing, currentlyRegistered, packages));
|
|
53
90
|
this.expectedTags = expected;
|
|
54
91
|
this.missingTags = missing;
|
|
55
92
|
this.currentlyRegisteredTags = currentlyRegistered;
|
|
56
93
|
}
|
|
57
94
|
}
|
|
58
|
-
function buildAssertionMessage(expected, missing, registered) {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
95
|
+
function buildAssertionMessage(expected, missing, registered, packages) {
|
|
96
|
+
const details = missing.map((tag) => {
|
|
97
|
+
const packageName = packageNameOf(packages[tag]);
|
|
98
|
+
const baseName = parseVersionedTagName(tag).baseName;
|
|
99
|
+
const related = packageName
|
|
100
|
+
? registered.filter((other) => registeredPackageName(other) === packageName)
|
|
101
|
+
: registered.filter((other) => parseVersionedTagName(other).baseName === baseName);
|
|
102
|
+
if (!related.includes(baseName) && isRegistered(baseName)) {
|
|
103
|
+
related.push(baseName);
|
|
104
|
+
}
|
|
105
|
+
const subject = packageName ?? baseName;
|
|
106
|
+
return related.length > 0
|
|
107
|
+
? `${subject} is registered as [${related.join(", ")}]`
|
|
108
|
+
: `nothing is registered for ${subject}`;
|
|
109
|
+
});
|
|
110
|
+
return (`ElementLoader.assertRegistered: missing [${missing.join(", ")}] ` +
|
|
111
|
+
`of [${expected.join(", ")}]; ${details.join("; ")}.`);
|
|
112
|
+
}
|
|
113
|
+
function packageNameOf(spec) {
|
|
114
|
+
if (!spec)
|
|
115
|
+
return undefined;
|
|
116
|
+
try {
|
|
117
|
+
return parsePackageName(spec).name || undefined;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function registeredPackageName(tag) {
|
|
124
|
+
return packageNameOf(pieRegistry()[tag]?.package);
|
|
66
125
|
}
|
|
67
126
|
const DEFAULT_WHEN_DEFINED_TIMEOUT_MS = 5000;
|
|
68
127
|
const DEFAULT_LOAD_TIMEOUT_MS = DEFAULT_IIFE_BUNDLE_RETRY_CONFIG.timeoutMs;
|
|
@@ -82,6 +141,8 @@ const resolvedBackendOverrides = new Map();
|
|
|
82
141
|
* - After the adapter's `load` settles, a post-load verification pass
|
|
83
142
|
* (bounded `customElements.whenDefined`) checks every tag. Any missing
|
|
84
143
|
* tag becomes a rejection.
|
|
144
|
+
* - Verification does not wait on a tag the adapter reports a failed load
|
|
145
|
+
* for, so when that covers every missing tag the rejection is immediate.
|
|
85
146
|
*/
|
|
86
147
|
export async function ensureRegistered(elements, options) {
|
|
87
148
|
if (!elements || Object.keys(elements).length === 0)
|
|
@@ -121,9 +182,15 @@ async function runEnsureRegistered(elements, tags, backend, context, timeoutMs,
|
|
|
121
182
|
catch (err) {
|
|
122
183
|
adapterError = err instanceof Error ? err : new Error(String(err));
|
|
123
184
|
}
|
|
185
|
+
// A tag whose load failed cannot register any more, so verification waits
|
|
186
|
+
// only on the others. A timed-out load can still register, so its tag waits.
|
|
124
187
|
const verification = await Promise.all(tags.map(async (tag) => {
|
|
125
188
|
if (isRegistered(tag))
|
|
126
189
|
return { tag, ok: true };
|
|
190
|
+
const adapterReason = extractAdapterReason(adapterError, tag);
|
|
191
|
+
if (adapterReason && adapterReason.kind !== "timeout") {
|
|
192
|
+
return { tag, ok: false };
|
|
193
|
+
}
|
|
127
194
|
try {
|
|
128
195
|
await whenDefinedWithTimeout(tag, timeoutMs);
|
|
129
196
|
return { tag, ok: true };
|
|
@@ -184,15 +251,19 @@ async function raceWithLoadTimeout(loadPromise, tags, loadTimeoutMs) {
|
|
|
184
251
|
* Throws `ElementAssertionError` with diagnostic detail otherwise.
|
|
185
252
|
*
|
|
186
253
|
* Used by hosts that opt into the "preloaded" strategy — they pre-register
|
|
187
|
-
* elements out-of-band and want a loud failure if anything is missing.
|
|
254
|
+
* elements out-of-band and want a loud failure if anything is missing. An
|
|
255
|
+
* element map, tag to package spec, lets the error name what each missing
|
|
256
|
+
* tag's package is registered as.
|
|
188
257
|
*/
|
|
189
258
|
export function assertRegistered(tags) {
|
|
190
|
-
|
|
259
|
+
const packages = Array.isArray(tags) ? {} : (tags ?? {});
|
|
260
|
+
const expected = Array.isArray(tags) ? tags : Object.keys(packages);
|
|
261
|
+
if (expected.length === 0)
|
|
191
262
|
return;
|
|
192
|
-
const missing =
|
|
263
|
+
const missing = expected.filter((tag) => !isRegistered(tag));
|
|
193
264
|
if (missing.length === 0)
|
|
194
265
|
return;
|
|
195
|
-
throw new ElementAssertionError(
|
|
266
|
+
throw new ElementAssertionError(expected, missing, snapshotRegisteredTags(), packages);
|
|
196
267
|
}
|
|
197
268
|
// ─── Internals ───────────────────────────────────────────────────────────────
|
|
198
269
|
function resolveBackend(backend) {
|
|
@@ -363,24 +434,18 @@ async function whenDefinedWithTimeout(tag, timeoutMs) {
|
|
|
363
434
|
clearTimeout(timer);
|
|
364
435
|
}
|
|
365
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* `customElements` cannot be enumerated, so the registered tags are the
|
|
439
|
+
* `window.PIE_REGISTRY` entries it holds.
|
|
440
|
+
*/
|
|
366
441
|
function snapshotRegisteredTags() {
|
|
367
|
-
if (typeof
|
|
442
|
+
if (typeof window === "undefined")
|
|
368
443
|
return [];
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
const reg = customElements;
|
|
375
|
-
if (typeof reg.__pieSnapshot === "function") {
|
|
376
|
-
try {
|
|
377
|
-
return reg.__pieSnapshot();
|
|
378
|
-
}
|
|
379
|
-
catch {
|
|
380
|
-
return [];
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return [];
|
|
444
|
+
return Object.values(pieRegistry())
|
|
445
|
+
.filter((entry) => entry?.status === Status.loaded)
|
|
446
|
+
.map((entry) => entry.tagName)
|
|
447
|
+
.filter((tag) => typeof tag === "string" && isRegistered(tag))
|
|
448
|
+
.sort();
|
|
384
449
|
}
|
|
385
450
|
function extractAdapterReason(err, tag) {
|
|
386
451
|
if (!err)
|
|
@@ -401,6 +466,7 @@ export const __testing = {
|
|
|
401
466
|
inFlightRequests.clear();
|
|
402
467
|
resolvedEsmBackends.clear();
|
|
403
468
|
resolvedBackendOverrides.clear();
|
|
469
|
+
clearPackageMetadataRequests();
|
|
404
470
|
},
|
|
405
471
|
inFlightCount() {
|
|
406
472
|
return inFlightRequests.size;
|
|
@@ -12,6 +12,8 @@ export declare class ElementPackagePolicyError extends Error {
|
|
|
12
12
|
readonly name = "ElementPackagePolicyError";
|
|
13
13
|
constructor(tagName: string, packageSpec: string, message: string);
|
|
14
14
|
}
|
|
15
|
+
/** Exact semver: no range, tag, `v` prefix or build metadata. */
|
|
16
|
+
export declare function isExactSemver(version: string): boolean;
|
|
15
17
|
/**
|
|
16
18
|
* Validate an element map only when a host explicitly supplies a policy.
|
|
17
19
|
* Omitting the policy preserves the existing trusted-application behavior.
|
|
@@ -10,7 +10,8 @@ export class ElementPackagePolicyError extends Error {
|
|
|
10
10
|
this.packageSpec = packageSpec;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
/** Exact semver: no range, tag, `v` prefix or build metadata. */
|
|
14
|
+
export function isExactSemver(version) {
|
|
14
15
|
return validSemver(version) === version;
|
|
15
16
|
}
|
|
16
17
|
function parsePolicyPackageSpec(spec) {
|
|
@@ -27,9 +27,18 @@ export type EsmCdnProviderName = BuiltInEsmCdnProviderName | (string & {});
|
|
|
27
27
|
export type EsmCdnProvider = {
|
|
28
28
|
name: EsmCdnProviderName;
|
|
29
29
|
packageJsonUrl(packageVersion: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* URL of `dist/browser/<view>/index.js`. `view` can be a nested path: an
|
|
32
|
+
* element's editor-runtime variant is `editor-runtime/<view>`.
|
|
33
|
+
*/
|
|
30
34
|
browserViewUrl(packageVersion: string, view: string): string;
|
|
31
35
|
browserControllerUrl(packageVersion: string): string;
|
|
32
36
|
sharedDependencyUrl(dependencyName: string, version: string, subpath?: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* URL of the package's `./runtime-support` module. Without it, the file
|
|
39
|
+
* `dist/runtime-support.js` beside `packageJsonUrl`.
|
|
40
|
+
*/
|
|
41
|
+
runtimeSupportUrl?(packageVersion: string): string;
|
|
33
42
|
};
|
|
34
43
|
export type EsmCdnProviderOption = EsmCdnProviderName | EsmCdnProvider;
|
|
35
44
|
export type EsmBackendConfig = {
|
|
@@ -56,3 +65,12 @@ export type EsmBackendConfig = {
|
|
|
56
65
|
export type EsmBackend = ElementLoaderBackend & {};
|
|
57
66
|
export declare function createEsmBackend(config: EsmBackendConfig): EsmBackend;
|
|
58
67
|
export declare function mapEsmViewElements(elements: ElementMap, view?: string, viewConfig?: ViewConfig): ElementMap;
|
|
68
|
+
/**
|
|
69
|
+
* URL of a package's `./runtime-support` module on the ESM CDN the players load
|
|
70
|
+
* elements from, or `undefined` when a custom provider names no package root.
|
|
71
|
+
*/
|
|
72
|
+
export declare function resolveEsmRuntimeSupportUrl(packageVersion: string, options: {
|
|
73
|
+
cdnBaseUrl: string;
|
|
74
|
+
cdnProvider?: EsmCdnProviderOption;
|
|
75
|
+
}): string | undefined;
|
|
76
|
+
export declare function pickElementClass(module: any, view: string): unknown;
|