@pie-players/pie-players-shared 0.3.57 → 0.3.59

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.
Files changed (33) hide show
  1. package/dist/components/vendor/nds/README.md +120 -0
  2. package/dist/components/vendor/nds/nds-icon-button.d.ts +19 -0
  3. package/dist/components/vendor/nds/nds-icon-button.js +826 -0
  4. package/dist/loaders/ElementLoader.d.ts +6 -5
  5. package/dist/loaders/ElementLoader.js +11 -45
  6. package/dist/loaders/ElementLoader.js.map +1 -1
  7. package/dist/loaders/element-loader.d.ts +6 -0
  8. package/dist/loaders/element-loader.js +4 -0
  9. package/dist/loaders/element-loader.js.map +1 -1
  10. package/dist/loaders/element-package-policy.d.ts +19 -0
  11. package/dist/loaders/element-package-policy.js +68 -0
  12. package/dist/loaders/element-package-policy.js.map +1 -0
  13. package/dist/loaders/iife-adapter.js +35 -1
  14. package/dist/loaders/iife-adapter.js.map +1 -1
  15. package/dist/loaders/index.d.ts +2 -0
  16. package/dist/loaders/index.js +1 -0
  17. package/dist/loaders/index.js.map +1 -1
  18. package/dist/pie/authoring-tag.d.ts +6 -0
  19. package/dist/pie/authoring-tag.js +13 -0
  20. package/dist/pie/authoring-tag.js.map +1 -0
  21. package/dist/pie/config.d.ts +5 -6
  22. package/dist/pie/config.js +26 -45
  23. package/dist/pie/config.js.map +1 -1
  24. package/dist/pie/overrides.d.ts +2 -1
  25. package/dist/pie/overrides.js +49 -32
  26. package/dist/pie/overrides.js.map +1 -1
  27. package/dist/pie/versioned-tag.d.ts +15 -0
  28. package/dist/pie/versioned-tag.js +43 -0
  29. package/dist/pie/versioned-tag.js.map +1 -0
  30. package/dist/ui/zoom-compensation.d.ts +44 -0
  31. package/dist/ui/zoom-compensation.js +44 -0
  32. package/dist/ui/zoom-compensation.js.map +1 -0
  33. package/package.json +10 -2
@@ -18,12 +18,13 @@ export type ElementMap = {
18
18
  /**
19
19
  * Aggregate unique elements from multiple items
20
20
  *
21
- * Extracts elements from all item configs and deduplicates them.
22
- * Throws an error if items require different versions of the same element.
21
+ * Extracts elements from all item configs, versions their full tag names, and
22
+ * deduplicates identical tag/package pairs. Multiple package versions of the
23
+ * same original tag remain distinct through their versioned tag names.
23
24
  *
24
25
  * @param items - Array of items to aggregate elements from
25
26
  * @returns Map of unique element tag names to package versions
26
- * @throws Error if element version conflicts are detected
27
+ * @throws Error if two package specs resolve to the same versioned tag
27
28
  *
28
29
  * @example
29
30
  * ```typescript
@@ -35,8 +36,8 @@ export type ElementMap = {
35
36
  *
36
37
  * const elements = aggregateElements(items);
37
38
  * // Result: {
38
- * // "pie-mc": "@pie-element/mc@11.0.1",
39
- * // "pie-hotspot": "@pie-element/hotspot@9.0.0"
39
+ * // "pie-mc--version-11-0-1": "@pie-element/mc@11.0.1",
40
+ * // "pie-hotspot--version-9-0-0": "@pie-element/hotspot@9.0.0"
40
41
  * // }
41
42
  * ```
42
43
  */
@@ -7,16 +7,17 @@
7
7
  * deduplicated, version-aware map (used by the section-player to
8
8
  * pre-warm in one shot).
9
9
  */
10
- import { parsePackageName } from "../pie/utils.js";
10
+ import { toPackageVersionedTag } from "../pie/versioned-tag.js";
11
11
  /**
12
12
  * Aggregate unique elements from multiple items
13
13
  *
14
- * Extracts elements from all item configs and deduplicates them.
15
- * Throws an error if items require different versions of the same element.
14
+ * Extracts elements from all item configs, versions their full tag names, and
15
+ * deduplicates identical tag/package pairs. Multiple package versions of the
16
+ * same original tag remain distinct through their versioned tag names.
16
17
  *
17
18
  * @param items - Array of items to aggregate elements from
18
19
  * @returns Map of unique element tag names to package versions
19
- * @throws Error if element version conflicts are detected
20
+ * @throws Error if two package specs resolve to the same versioned tag
20
21
  *
21
22
  * @example
22
23
  * ```typescript
@@ -28,61 +29,26 @@ import { parsePackageName } from "../pie/utils.js";
28
29
  *
29
30
  * const elements = aggregateElements(items);
30
31
  * // Result: {
31
- * // "pie-mc": "@pie-element/mc@11.0.1",
32
- * // "pie-hotspot": "@pie-element/hotspot@9.0.0"
32
+ * // "pie-mc--version-11-0-1": "@pie-element/mc@11.0.1",
33
+ * // "pie-hotspot--version-9-0-0": "@pie-element/hotspot@9.0.0"
33
34
  * // }
34
35
  * ```
35
36
  */
36
37
  export function aggregateElements(items) {
37
38
  const elementMap = {};
38
- const seenOriginalTags = {};
39
- const VERSION_DELIMITER = "--version-";
40
- const TAG_VERSION_PATTERN = "[0-9A-Za-z-]+";
41
- const encodeVersionForTag = (version) => version
42
- .trim()
43
- .replace(/[.+]/g, "-")
44
- .replace(/[^0-9A-Za-z-]/g, "-")
45
- .replace(/-{2,}/g, "-");
46
- const parseTagName = (tagName) => {
47
- const versionMatch = tagName.match(new RegExp(`${VERSION_DELIMITER}(${TAG_VERSION_PATTERN})$`));
48
- return versionMatch
49
- ? {
50
- baseName: tagName.replace(`${VERSION_DELIMITER}${versionMatch[1]}`, ""),
51
- existingEncodedVersion: versionMatch[1],
52
- }
53
- : { baseName: tagName };
54
- };
55
- const normalizeElementTag = (tagName, packageSpec) => {
56
- const { baseName, existingEncodedVersion } = parseTagName(tagName);
57
- const { version } = parsePackageName(packageSpec);
58
- if (!version)
59
- return tagName;
60
- const targetEncodedVersion = encodeVersionForTag(version);
61
- if (!targetEncodedVersion ||
62
- existingEncodedVersion === targetEncodedVersion) {
63
- return tagName;
64
- }
65
- return `${baseName}${VERSION_DELIMITER}${targetEncodedVersion}`;
66
- };
67
39
  items.forEach((item) => {
68
40
  const itemElements = item.config?.elements || {};
69
41
  Object.entries(itemElements).forEach(([tag, pkg]) => {
70
42
  const packageSpec = String(pkg);
71
- if (!seenOriginalTags[tag]) {
72
- seenOriginalTags[tag] = packageSpec;
73
- }
74
- else if (seenOriginalTags[tag] !== packageSpec) {
75
- // Preserve existing conflict behavior for repeated original tags.
76
- throw new Error(`Element version conflict: ${tag} requires both ${seenOriginalTags[tag]} and ${packageSpec}. ` +
77
- `All items in a section must use the same version of each element.`);
78
- }
79
- const normalizedTag = normalizeElementTag(tag, packageSpec);
43
+ const normalizedTag = toPackageVersionedTag(tag, packageSpec, {
44
+ preserveUnversionedTag: true,
45
+ });
80
46
  if (!elementMap[normalizedTag]) {
81
47
  elementMap[normalizedTag] = packageSpec;
82
48
  }
83
49
  else if (elementMap[normalizedTag] !== packageSpec) {
84
50
  throw new Error(`Element version conflict: ${normalizedTag} requires both ${elementMap[normalizedTag]} and ${packageSpec}. ` +
85
- `All items in a section must use the same version of each element.`);
51
+ `Each full versioned tag must map to exactly one package spec.`);
86
52
  }
87
53
  });
88
54
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ElementLoader.js","sourceRoot":"","sources":["../../src/loaders/ElementLoader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Element Loader — element aggregation utilities.\n *\n * The deep `ElementLoader` primitive lives in `./element-loader.ts`. This\n * module owns the shared `ElementMap` type and the `aggregateElements`\n * helper that reduces many items' element declarations into a single\n * deduplicated, version-aware map (used by the section-player to\n * pre-warm in one shot).\n */\n\nimport { parsePackageName } from \"../pie/utils.js\";\nimport type { ItemEntity } from \"../types/index.js\";\n\n/**\n * Map of element tag names to their package versions\n * Example: { \"pie-multiple-choice\": \"@pie-element/multiple-choice@11.0.1\" }\n */\nexport type ElementMap = { [tagName: string]: string };\n\n/**\n * Aggregate unique elements from multiple items\n *\n * Extracts elements from all item configs and deduplicates them.\n * Throws an error if items require different versions of the same element.\n *\n * @param items - Array of items to aggregate elements from\n * @returns Map of unique element tag names to package versions\n * @throws Error if element version conflicts are detected\n *\n * @example\n * ```typescript\n * const items = [\n * { config: { elements: { \"pie-mc\": \"@pie-element/mc@11.0.1\" } } },\n * { config: { elements: { \"pie-mc\": \"@pie-element/mc@11.0.1\" } } },\n * { config: { elements: { \"pie-hotspot\": \"@pie-element/hotspot@9.0.0\" } } }\n * ];\n *\n * const elements = aggregateElements(items);\n * // Result: {\n * // \"pie-mc\": \"@pie-element/mc@11.0.1\",\n * // \"pie-hotspot\": \"@pie-element/hotspot@9.0.0\"\n * // }\n * ```\n */\nexport function aggregateElements(items: ItemEntity[]): ElementMap {\n\tconst elementMap: Record<string, string> = {};\n\tconst seenOriginalTags: Record<string, string> = {};\n\n\tconst VERSION_DELIMITER = \"--version-\";\n\tconst TAG_VERSION_PATTERN = \"[0-9A-Za-z-]+\";\n\tconst encodeVersionForTag = (version: string): string =>\n\t\tversion\n\t\t\t.trim()\n\t\t\t.replace(/[.+]/g, \"-\")\n\t\t\t.replace(/[^0-9A-Za-z-]/g, \"-\")\n\t\t\t.replace(/-{2,}/g, \"-\");\n\tconst parseTagName = (\n\t\ttagName: string,\n\t): { baseName: string; existingEncodedVersion?: string } => {\n\t\tconst versionMatch = tagName.match(\n\t\t\tnew RegExp(`${VERSION_DELIMITER}(${TAG_VERSION_PATTERN})$`),\n\t\t);\n\t\treturn versionMatch\n\t\t\t? {\n\t\t\t\t\tbaseName: tagName.replace(\n\t\t\t\t\t\t`${VERSION_DELIMITER}${versionMatch[1]}`,\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t),\n\t\t\t\t\texistingEncodedVersion: versionMatch[1],\n\t\t\t\t}\n\t\t\t: { baseName: tagName };\n\t};\n\tconst normalizeElementTag = (\n\t\ttagName: string,\n\t\tpackageSpec: string,\n\t): string => {\n\t\tconst { baseName, existingEncodedVersion } = parseTagName(tagName);\n\t\tconst { version } = parsePackageName(packageSpec);\n\t\tif (!version) return tagName;\n\t\tconst targetEncodedVersion = encodeVersionForTag(version);\n\t\tif (\n\t\t\t!targetEncodedVersion ||\n\t\t\texistingEncodedVersion === targetEncodedVersion\n\t\t) {\n\t\t\treturn tagName;\n\t\t}\n\t\treturn `${baseName}${VERSION_DELIMITER}${targetEncodedVersion}`;\n\t};\n\n\titems.forEach((item) => {\n\t\tconst itemElements = item.config?.elements || {};\n\n\t\tObject.entries(itemElements).forEach(([tag, pkg]) => {\n\t\t\tconst packageSpec = String(pkg);\n\t\t\tif (!seenOriginalTags[tag]) {\n\t\t\t\tseenOriginalTags[tag] = packageSpec;\n\t\t\t} else if (seenOriginalTags[tag] !== packageSpec) {\n\t\t\t\t// Preserve existing conflict behavior for repeated original tags.\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Element version conflict: ${tag} requires both ${seenOriginalTags[tag]} and ${packageSpec}. ` +\n\t\t\t\t\t\t`All items in a section must use the same version of each element.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst normalizedTag = normalizeElementTag(tag, packageSpec);\n\t\t\tif (!elementMap[normalizedTag]) {\n\t\t\t\telementMap[normalizedTag] = packageSpec;\n\t\t\t} else if (elementMap[normalizedTag] !== packageSpec) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Element version conflict: ${normalizedTag} requires both ${elementMap[normalizedTag]} and ${packageSpec}. ` +\n\t\t\t\t\t\t`All items in a section must use the same version of each element.`,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t});\n\n\treturn elementMap;\n}\n"]}
1
+ {"version":3,"file":"ElementLoader.js","sourceRoot":"","sources":["../../src/loaders/ElementLoader.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAShE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAmB;IACpD,MAAM,UAAU,GAA2B,EAAE,CAAC;IAE9C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACtB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAC;QAEjD,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE;YACnD,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAChC,MAAM,aAAa,GAAG,qBAAqB,CAAC,GAAG,EAAE,WAAW,EAAE;gBAC7D,sBAAsB,EAAE,IAAI;aAC5B,CAAC,CAAC;YACH,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;gBAChC,UAAU,CAAC,aAAa,CAAC,GAAG,WAAW,CAAC;YACzC,CAAC;iBAAM,IAAI,UAAU,CAAC,aAAa,CAAC,KAAK,WAAW,EAAE,CAAC;gBACtD,MAAM,IAAI,KAAK,CACd,6BAA6B,aAAa,kBAAkB,UAAU,CAAC,aAAa,CAAC,QAAQ,WAAW,IAAI;oBAC3G,+DAA+D,CAChE,CAAC;YACH,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC;AACnB,CAAC","sourcesContent":["/**\n * Element Loader — element aggregation utilities.\n *\n * The deep `ElementLoader` primitive lives in `./element-loader.ts`. This\n * module owns the shared `ElementMap` type and the `aggregateElements`\n * helper that reduces many items' element declarations into a single\n * deduplicated, version-aware map (used by the section-player to\n * pre-warm in one shot).\n */\n\nimport { toPackageVersionedTag } from \"../pie/versioned-tag.js\";\nimport type { ItemEntity } from \"../types/index.js\";\n\n/**\n * Map of element tag names to their package versions\n * Example: { \"pie-multiple-choice\": \"@pie-element/multiple-choice@11.0.1\" }\n */\nexport type ElementMap = { [tagName: string]: string };\n\n/**\n * Aggregate unique elements from multiple items\n *\n * Extracts elements from all item configs, versions their full tag names, and\n * deduplicates identical tag/package pairs. Multiple package versions of the\n * same original tag remain distinct through their versioned tag names.\n *\n * @param items - Array of items to aggregate elements from\n * @returns Map of unique element tag names to package versions\n * @throws Error if two package specs resolve to the same versioned tag\n *\n * @example\n * ```typescript\n * const items = [\n * { config: { elements: { \"pie-mc\": \"@pie-element/mc@11.0.1\" } } },\n * { config: { elements: { \"pie-mc\": \"@pie-element/mc@11.0.1\" } } },\n * { config: { elements: { \"pie-hotspot\": \"@pie-element/hotspot@9.0.0\" } } }\n * ];\n *\n * const elements = aggregateElements(items);\n * // Result: {\n * // \"pie-mc--version-11-0-1\": \"@pie-element/mc@11.0.1\",\n * // \"pie-hotspot--version-9-0-0\": \"@pie-element/hotspot@9.0.0\"\n * // }\n * ```\n */\nexport function aggregateElements(items: ItemEntity[]): ElementMap {\n\tconst elementMap: Record<string, string> = {};\n\n\titems.forEach((item) => {\n\t\tconst itemElements = item.config?.elements || {};\n\n\t\tObject.entries(itemElements).forEach(([tag, pkg]) => {\n\t\t\tconst packageSpec = String(pkg);\n\t\t\tconst normalizedTag = toPackageVersionedTag(tag, packageSpec, {\n\t\t\t\tpreserveUnversionedTag: true,\n\t\t\t});\n\t\t\tif (!elementMap[normalizedTag]) {\n\t\t\t\telementMap[normalizedTag] = packageSpec;\n\t\t\t} else if (elementMap[normalizedTag] !== packageSpec) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Element version conflict: ${normalizedTag} requires both ${elementMap[normalizedTag]} and ${packageSpec}. ` +\n\t\t\t\t\t\t`Each full versioned tag must map to exactly one package spec.`,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t});\n\n\treturn elementMap;\n}\n"]}
@@ -22,6 +22,7 @@ import type { ElementMap } from "./ElementLoader.js";
22
22
  import { type ElementLoaderBackend, type ElementTag, type RegistrationFailureReason } from "./element-loader-types.js";
23
23
  import { type EsmBackendConfig } from "./esm-adapter.js";
24
24
  import { type IifeBackendConfig } from "./iife-adapter.js";
25
+ import { type ElementPackagePolicy } from "./element-package-policy.js";
25
26
  export type { BackendContext, ElementLoaderBackend, ElementMap, ElementTag, RegistrationFailureReason, } from "./element-loader-types.js";
26
27
  export { AdapterFailure } from "./element-loader-types.js";
27
28
  export type { IifeBackendConfig } from "./iife-adapter.js";
@@ -51,6 +52,11 @@ export declare class ElementAssertionError extends Error {
51
52
  export type BackendOption = IifeBackendConfig | EsmBackendConfig | ElementLoaderBackend;
52
53
  export type EnsureRegisteredOptions = {
53
54
  backend: BackendOption;
55
+ /**
56
+ * Optional host-controlled allow-list for executable `config.elements`
57
+ * packages. Omit to preserve the trusted-application behavior.
58
+ */
59
+ elementPackagePolicy?: ElementPackagePolicy;
54
60
  doc?: Document;
55
61
  whenDefinedTimeoutMs?: number;
56
62
  /**
@@ -22,6 +22,7 @@ import { DEFAULT_IIFE_BUNDLE_RETRY_CONFIG } from "../loader-config.js";
22
22
  import { AdapterFailure, } from "./element-loader-types.js";
23
23
  import { createEsmBackend } from "./esm-adapter.js";
24
24
  import { createIifeBackend } from "./iife-adapter.js";
25
+ import { assertElementPackagesAllowed, } from "./element-package-policy.js";
25
26
  export { AdapterFailure } from "./element-loader-types.js";
26
27
  /**
27
28
  * Aggregate error thrown by `ensureRegistered` when one or more requested
@@ -85,6 +86,9 @@ const resolvedBackendOverrides = new Map();
85
86
  export async function ensureRegistered(elements, options) {
86
87
  if (!elements || Object.keys(elements).length === 0)
87
88
  return;
89
+ // Enforce policy before the already-registered fast path: a matching tag in
90
+ // the registry must not turn a disallowed authored package into valid input.
91
+ assertElementPackagesAllowed(elements, options.elementPackagePolicy);
88
92
  const tags = Object.keys(elements);
89
93
  const timeoutMs = options.whenDefinedTimeoutMs ?? DEFAULT_WHEN_DEFINED_TIMEOUT_MS;
90
94
  const loadTimeoutMs = options.loadTimeoutMs ?? DEFAULT_LOAD_TIMEOUT_MS;
@@ -1 +1 @@
1
- {"version":3,"file":"element-loader.js","sourceRoot":"","sources":["../../src/loaders/element-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,gCAAgC,EAAE,MAAM,qBAAqB,CAAC;AAEvE,OAAO,EACN,cAAc,GAKd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAyB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAA0B,MAAM,mBAAmB,CAAC;AAS9E,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D;;;GAGG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC1B,IAAI,GAAG,oBAAoB,CAAC;IACrC,gBAAgB,CAAkB;IAClC,OAAO,CAA6C;IAE7D,YACC,OAAe,EACf,gBAAiC,EACjC,OAAmD;QAEnD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;CACD;AAED;;;;GAIG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC7B,IAAI,GAAG,uBAAuB,CAAC;IACxC,YAAY,CAAwB;IACpC,WAAW,CAAwB;IACnC,uBAAuB,CAAwB;IAExD,YACC,QAAsB,EACtB,OAAqB,EACrB,mBAAiC;QAEjC,KAAK,CAAC,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;QAC3B,IAAI,CAAC,uBAAuB,GAAG,mBAAmB,CAAC;IACpD,CAAC;CACD;AAED,SAAS,qBAAqB,CAC7B,QAAsB,EACtB,OAAqB,EACrB,UAAwB;IAExB,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM;QACtC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QACvB,CAAC,CAAC,mBAAmB,CAAC;IACvB,OAAO,CACN,6CAA6C,WAAW,KAAK;QAC7D,YAAY,UAAU,gCAAgC,aAAa,IAAI,CACvE,CAAC;AACH,CAAC;AA2BD,MAAM,+BAA+B,GAAG,IAAI,CAAC;AAC7C,MAAM,uBAAuB,GAAG,gCAAgC,CAAC,SAAS,CAAC;AAE3E,2EAA2E;AAC3E,qEAAqE;AACrE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAyB,CAAC;AAC1D,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAgC,CAAC;AACpE,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAgC,CAAC;AAEzE;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACrC,QAAoB,EACpB,OAAgC;IAEhC,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE5D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,SAAS,GACd,OAAO,CAAC,oBAAoB,IAAI,+BAA+B,CAAC;IACjE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,uBAAuB,CAAC;IAEvE,mEAAmE;IACnE,wBAAwB;IACxB,IAAI,oBAAoB,CAAC,IAAI,CAAC;QAAE,OAAO;IAEvC,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAEpC,MAAM,OAAO,GAAG,mBAAmB,CAClC,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,EAAE,GAAG,EAAE,oBAAoB,EAAE,SAAS,EAAE,EACxC,SAAS,EACT,aAAa,CACb,CAAC;IAEF,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC;QACJ,MAAM,OAAO,CAAC;IACf,CAAC;YAAS,CAAC;QACV,IAAI,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,OAAO,EAAE,CAAC;YAChD,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;AACF,CAAC;AAED,KAAK,UAAU,mBAAmB,CACjC,QAAoB,EACpB,IAAkB,EAClB,OAA6B,EAC7B,OAAuB,EACvB,SAAiB,EACjB,aAAqB;IAErB,IAAI,YAA+B,CAAC;IACpC,IAAI,CAAC;QACJ,MAAM,mBAAmB,CACxB,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,EAC/B,IAAI,EACJ,aAAa,CACb,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,YAAY,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CACrC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,YAAY,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,IAAa,EAAE,CAAC;QACzD,IAAI,CAAC;YACJ,MAAM,sBAAsB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC7C,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,IAAa,EAAE,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,KAAc,EAAE,CAAC;QACpC,CAAC;IACF,CAAC,CAAC,CACF,CAAC;IAEF,MAAM,YAAY,GAAG,IAAI,GAAG,EAAc,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyC,CAAC;IACjE,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,EAAE;YAAE,SAAS;QACnB,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACxB,MAAM,aAAa,GAAG,oBAAoB,CAAC,YAAY,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CACV,CAAC,CAAC,GAAG,EACL,aAAa,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,CAC3D,CAAC;IACH,CAAC;IAED,IAAI,YAAY,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,kBAAkB,CAC3B,8CAA8C,CAAC,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC5E,YAAY,EACZ,OAAO,CACP,CAAC;IACH,CAAC;AACF,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,mBAAmB,CACjC,WAA0B,EAC1B,IAAkB,EAClB,aAAqB;IAErB,IAAI,KAAgD,CAAC;IACrD,IAAI,CAAC;QACJ,MAAM,OAAO,CAAC,IAAI,CAAC;YAClB,WAAW;YACX,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;gBAC/B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyC,CAAC;oBACjE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;wBACxB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE;4BAChB,IAAI,EAAE,SAAS;4BACf,GAAG;4BACH,SAAS,EAAE,aAAa;yBACxB,CAAC,CAAC;oBACJ,CAAC;oBACD,MAAM,CAAC,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;gBACrC,CAAC,EAAE,aAAa,CAAC,CAAC;YACnB,CAAC,CAAC;SACF,CAAC,CAAC;IACJ,CAAC;YAAS,CAAC;QACV,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAkB;IAClD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,MAAM,IAAI,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,gFAAgF;AAEhF,SAAS,cAAc,CAAC,OAAsB;IAC7C,IAAI,eAAe,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC7C,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;QACvB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC/D,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,wBAAwB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC1D,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;YAC9B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;YAC9B,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAC1C,mBAAmB,CAAC,GAAG,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAC7C,OAAO,OAAO,CAAC;QAChB,CAAC;IACF,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,eAAe,CACvB,OAAsB;IAEtB,OAAO,CACN,OAAQ,OAA8B,CAAC,IAAI,KAAK,UAAU;QAC1D,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CACpB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,GAAyB;IAC5C,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IACpB,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,QAAQ,CAAC;IACrD,MAAM,IAAI,KAAK,CACd,mEAAmE,CACnE,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,OAAsB,EAAE,QAAoB;IAClE,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC1D,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAClB,CAAC;IACF,OAAO,GAAG,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,GAAG,IAAI,OAAO,EAAgC,CAAC;AAC/D,IAAI,aAAa,GAAG,CAAC,CAAC;AACtB,MAAM,WAAW,GAAG,IAAI,OAAO,EAAoB,CAAC;AACpD,IAAI,cAAc,GAAG,CAAC,CAAC;AACvB,MAAM,eAAe,GAAG,IAAI,OAAO,EAAkB,CAAC;AACtD,IAAI,kBAAkB,GAAG,CAAC,CAAC;AAE3B,SAAS,YAAY,CAAC,OAAsB;IAC3C,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,IAAI,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,EAAE,CAAC;YACT,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,CAAC;YAC3B,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,WAAW,EAAE,EAAE,CAAC;IACxB,CAAC;IACD,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;QACvB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC7B,OAAO,QAAQ,gBAAgB,CAAC;gBAC/B,IAAI,EAAE,MAAM;gBACZ,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,EAAE;gBACpC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,IAAI;gBAClD,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;gBACtC,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI;gBAC1C,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;gBACxC,mBAAmB,EAAE,OAAO,CAAC,mBAAmB,IAAI,IAAI;gBACxD,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK;gBACnD,uBAAuB,EAAE,OAAO,CAAC,uBAAuB,IAAI,IAAI;aAChE,CAAC,EAAE,CAAC;QACN,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC5B,OAAO,OAAO,gBAAgB,CAAC;gBAC9B,IAAI,EAAE,KAAK;gBACX,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI;gBACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK;gBACnD,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,UAAU;gBAChC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;gBACtC,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,IAAI;gBAChD,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,IAAI;gBAC1C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,KAAK;gBACnD,uBAAuB,EAAE,OAAO,CAAC,uBAAuB,IAAI,IAAI;aAChE,CAAC,EAAE,CAAC;QACN,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACvC,OAAO,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,uBAAuB,CAC/B,KAAc,EACd,IAAyB;IAEzB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxD,MAAM,aAAa,GAAG,OAAO,KAAK,CAAC;IACnC,IACC,aAAa,KAAK,QAAQ;QAC1B,aAAa,KAAK,QAAQ;QAC1B,aAAa,KAAK,SAAS,EAC1B,CAAC;QACF,OAAO,KAAK,CAAC;IACd,CAAC;IACD,IAAI,aAAa,KAAK,UAAU,EAAE,CAAC;QAClC,OAAO,EAAE,aAAa,EAAE,gBAAgB,CAAC,KAAiB,CAAC,EAAE,CAAC;IAC/D,CAAC;IACD,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,MAAM,WAAW,GAAG,KAAe,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,QAAQ;QAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;IAC9C,MAAM,UAAU,GAAG,SAAS,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;IAC5C,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAElC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,WAAW,EAAE,oBAAoB,CAAC,WAAW,CAAC,EAAE,CAAC;IAC3D,CAAC;IAED,MAAM,UAAU,GAA4B,EAAE,CAAC;IAC/C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7C,UAAU,CAAC,GAAG,CAAC,GAAG,uBAAuB,CACvC,KAAiC,CAAC,GAAG,CAAC,EACvC,IAAI,CACJ,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACpC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC/C,OAAO,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,CAAC;AAC7D,CAAC;AAED,SAAS,gBAAgB,CAAC,EAAY;IACrC,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,EAAE,CAAC;QACT,EAAE,GAAG,MAAM,EAAE,cAAc,EAAE,CAAC;QAC9B,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAa;IAC1C,IAAI,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,EAAE,CAAC;QACT,EAAE,GAAG,OAAO,EAAE,kBAAkB,EAAE,CAAC;QACnC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAkB;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,YAAY,CAAC,GAAe;IACpC,IAAI,OAAO,cAAc,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACxD,OAAO,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;AAC9C,CAAC;AAED,KAAK,UAAU,sBAAsB,CACpC,GAAe,EACf,SAAiB;IAEjB,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,KAAgD,CAAC;IACrD,IAAI,CAAC;QACJ,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;YACzB,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;YACrD,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;gBAC/B,KAAK,GAAG,UAAU,CACjB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC,EACrD,SAAS,CACT,CAAC;YACH,CAAC,CAAC;SACF,CAAC,CAAC;IACJ,CAAC;YAAS,CAAC;QACV,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;AACF,CAAC;AAED,SAAS,sBAAsB;IAC9B,IAAI,OAAO,cAAc,KAAK,WAAW;QAAE,OAAO,EAAE,CAAC;IACrD,4EAA4E;IAC5E,0EAA0E;IAC1E,mEAAmE;IACnE,yEAAyE;IACzE,4BAA4B;IAC5B,MAAM,GAAG,GAAG,cAEX,CAAC;IACF,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;QAC7C,IAAI,CAAC;YACJ,OAAO,GAAG,CAAC,aAAa,EAAE,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,CAAC;QACX,CAAC;IACF,CAAC;IACD,OAAO,EAAE,CAAC;AACX,CAAC;AAED,SAAS,oBAAoB,CAC5B,GAAsB,EACtB,GAAe;IAEf,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,IAAI,GAAG,YAAY,cAAc;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/D,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;AAC9D,CAAC;AAED,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACxB,eAAe;QACd,gBAAgB,CAAC,KAAK,EAAE,CAAC;QACzB,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAC5B,wBAAwB,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;IACD,aAAa;QACZ,OAAO,gBAAgB,CAAC,IAAI,CAAC;IAC9B,CAAC;IACD,WAAW,CAAC,QAAoB,EAAE,OAAsB;QACvD,OAAO,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACzC,CAAC;IACD,gCAAgC,CAC/B,OAAsB,EACtB,eAAqC;QAErC,wBAAwB,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,CAAC;IACtE,CAAC;IACD,iCAAiC;QAChC,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAC5B,wBAAwB,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;CACD,CAAC","sourcesContent":["/**\n * ElementLoader primitive — the one place where \"these tags are registered\n * with customElements\" is decided.\n *\n * Owns the truthful promise contract end-to-end:\n *\n * ensureRegistered(elements, options) resolves iff every requested tag\n * is in `customElements` at the moment of resolution. On partial\n * success it rejects with an `ElementLoaderError` carrying the set of\n * unregistered tags and a per-tag `RegistrationFailureReason` map.\n *\n * The primitive delegates the actual fetch/register work to a backend\n * adapter (IIFE or ESM) but always verifies the outcome via\n * `customElements.whenDefined`. An adapter cannot silently under-register\n * — the primitive will catch it and surface a timeout reason.\n *\n * See packages/players-shared/tests/element-loader-contract.test.ts for\n * the executable specification of every failure mode this primitive is\n * required to catch.\n */\n\nimport { DEFAULT_IIFE_BUNDLE_RETRY_CONFIG } from \"../loader-config.js\";\nimport type { ElementMap } from \"./ElementLoader.js\";\nimport {\n\tAdapterFailure,\n\ttype BackendContext,\n\ttype ElementLoaderBackend,\n\ttype ElementTag,\n\ttype RegistrationFailureReason,\n} from \"./element-loader-types.js\";\nimport { createEsmBackend, type EsmBackendConfig } from \"./esm-adapter.js\";\nimport { createIifeBackend, type IifeBackendConfig } from \"./iife-adapter.js\";\n\nexport type {\n\tBackendContext,\n\tElementLoaderBackend,\n\tElementMap,\n\tElementTag,\n\tRegistrationFailureReason,\n} from \"./element-loader-types.js\";\nexport { AdapterFailure } from \"./element-loader-types.js\";\nexport type { IifeBackendConfig } from \"./iife-adapter.js\";\nexport type { EsmBackendConfig } from \"./esm-adapter.js\";\n\n/**\n * Aggregate error thrown by `ensureRegistered` when one or more requested\n * tags were not registered by the time verification timed out.\n */\nexport class ElementLoaderError extends Error {\n\toverride readonly name = \"ElementLoaderError\";\n\treadonly unregisteredTags: Set<ElementTag>;\n\treadonly reasons: Map<ElementTag, RegistrationFailureReason>;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tunregisteredTags: Set<ElementTag>,\n\t\treasons: Map<ElementTag, RegistrationFailureReason>,\n\t) {\n\t\tsuper(message);\n\t\tthis.unregisteredTags = unregisteredTags;\n\t\tthis.reasons = reasons;\n\t}\n}\n\n/**\n * Thrown by `assertRegistered` when any requested tag is missing from\n * `customElements`. Carries enough detail for the host to diagnose what\n * pre-registration step was skipped.\n */\nexport class ElementAssertionError extends Error {\n\toverride readonly name = \"ElementAssertionError\";\n\treadonly expectedTags: readonly ElementTag[];\n\treadonly missingTags: readonly ElementTag[];\n\treadonly currentlyRegisteredTags: readonly ElementTag[];\n\n\tconstructor(\n\t\texpected: ElementTag[],\n\t\tmissing: ElementTag[],\n\t\tcurrentlyRegistered: ElementTag[],\n\t) {\n\t\tsuper(buildAssertionMessage(expected, missing, currentlyRegistered));\n\t\tthis.expectedTags = expected;\n\t\tthis.missingTags = missing;\n\t\tthis.currentlyRegisteredTags = currentlyRegistered;\n\t}\n}\n\nfunction buildAssertionMessage(\n\texpected: ElementTag[],\n\tmissing: ElementTag[],\n\tregistered: ElementTag[],\n): string {\n\tconst expectedStr = expected.join(\", \");\n\tconst missingStr = missing.join(\", \");\n\tconst registeredStr = registered.length\n\t\t? registered.join(\", \")\n\t\t: \"(none enumerable)\";\n\treturn (\n\t\t`ElementLoader.assertRegistered: expected [${expectedStr}], ` +\n\t\t`missing [${missingStr}]. customElements contains: [${registeredStr}].`\n\t);\n}\n\nexport type BackendOption =\n\t| IifeBackendConfig\n\t| EsmBackendConfig\n\t| ElementLoaderBackend;\n\nexport type EnsureRegisteredOptions = {\n\tbackend: BackendOption;\n\tdoc?: Document;\n\twhenDefinedTimeoutMs?: number;\n\t/**\n\t * Outer cumulative deadline for the backend's `load()` call.\n\t *\n\t * Closes the \"promise never settles\" seam for adapters whose underlying\n\t * fetch can stall indefinitely (e.g. ESM `import()` against a frozen\n\t * CDN). When the deadline elapses, the primitive synthesizes an\n\t * `AdapterFailure` with `kind: \"timeout\"` reasons for every requested\n\t * tag — surfacing as a normal `ElementLoaderError` to the caller.\n\t *\n\t * Defaults to `DEFAULT_IIFE_BUNDLE_RETRY_CONFIG.timeoutMs` so\n\t * adapter-internal retry windows (IIFE bundle-build polling) fit\n\t * inside the same overall budget.\n\t */\n\tloadTimeoutMs?: number;\n};\n\nconst DEFAULT_WHEN_DEFINED_TIMEOUT_MS = 5000;\nconst DEFAULT_LOAD_TIMEOUT_MS = DEFAULT_IIFE_BUNDLE_RETRY_CONFIG.timeoutMs;\n\n// Module-scoped in-flight cache. Key: backend signature + sorted elements.\n// Keeps concurrent identical requests collapsed to one backend call.\nconst inFlightRequests = new Map<string, Promise<void>>();\nconst resolvedEsmBackends = new Map<string, ElementLoaderBackend>();\nconst resolvedBackendOverrides = new Map<string, ElementLoaderBackend>();\n\n/**\n * Resolve iff every tag in `elements` is registered with `customElements`.\n * Reject with `ElementLoaderError` otherwise.\n *\n * The primitive is the sole authority on registration state:\n * - Empty element map resolves immediately (no backend call).\n * - Already-registered tags resolve immediately (no backend call).\n * - Concurrent identical requests share one backend call.\n * - After the adapter's `load` settles, a post-load verification pass\n * (bounded `customElements.whenDefined`) checks every tag. Any missing\n * tag becomes a rejection.\n */\nexport async function ensureRegistered(\n\telements: ElementMap,\n\toptions: EnsureRegisteredOptions,\n): Promise<void> {\n\tif (!elements || Object.keys(elements).length === 0) return;\n\n\tconst tags = Object.keys(elements);\n\tconst timeoutMs =\n\t\toptions.whenDefinedTimeoutMs ?? DEFAULT_WHEN_DEFINED_TIMEOUT_MS;\n\tconst loadTimeoutMs = options.loadTimeoutMs ?? DEFAULT_LOAD_TIMEOUT_MS;\n\n\t// Fast path: everything already registered. Skip backend and dedup\n\t// bookkeeping entirely.\n\tif (allAlreadyRegistered(tags)) return;\n\n\tconst dedupKey = buildDedupKey(options.backend, elements);\n\tconst existing = inFlightRequests.get(dedupKey);\n\tif (existing) return existing;\n\n\tconst backend = resolveBackend(options.backend);\n\tconst doc = resolveDoc(options.doc);\n\n\tconst promise = runEnsureRegistered(\n\t\telements,\n\t\ttags,\n\t\tbackend,\n\t\t{ doc, whenDefinedTimeoutMs: timeoutMs },\n\t\ttimeoutMs,\n\t\tloadTimeoutMs,\n\t);\n\n\tinFlightRequests.set(dedupKey, promise);\n\ttry {\n\t\tawait promise;\n\t} finally {\n\t\tif (inFlightRequests.get(dedupKey) === promise) {\n\t\t\tinFlightRequests.delete(dedupKey);\n\t\t}\n\t}\n}\n\nasync function runEnsureRegistered(\n\telements: ElementMap,\n\ttags: ElementTag[],\n\tbackend: ElementLoaderBackend,\n\tcontext: BackendContext,\n\ttimeoutMs: number,\n\tloadTimeoutMs: number,\n): Promise<void> {\n\tlet adapterError: Error | undefined;\n\ttry {\n\t\tawait raceWithLoadTimeout(\n\t\t\tbackend.load(elements, context),\n\t\t\ttags,\n\t\t\tloadTimeoutMs,\n\t\t);\n\t} catch (err) {\n\t\tadapterError = err instanceof Error ? err : new Error(String(err));\n\t}\n\n\tconst verification = await Promise.all(\n\t\ttags.map(async (tag) => {\n\t\t\tif (isRegistered(tag)) return { tag, ok: true as const };\n\t\t\ttry {\n\t\t\t\tawait whenDefinedWithTimeout(tag, timeoutMs);\n\t\t\t\treturn { tag, ok: true as const };\n\t\t\t} catch {\n\t\t\t\treturn { tag, ok: false as const };\n\t\t\t}\n\t\t}),\n\t);\n\n\tconst unregistered = new Set<ElementTag>();\n\tconst reasons = new Map<ElementTag, RegistrationFailureReason>();\n\tfor (const v of verification) {\n\t\tif (v.ok) continue;\n\t\tunregistered.add(v.tag);\n\t\tconst adapterReason = extractAdapterReason(adapterError, v.tag);\n\t\treasons.set(\n\t\t\tv.tag,\n\t\t\tadapterReason ?? { kind: \"timeout\", tag: v.tag, timeoutMs },\n\t\t);\n\t}\n\n\tif (unregistered.size > 0) {\n\t\tthrow new ElementLoaderError(\n\t\t\t`Element registration failed; missing tags: ${[...unregistered].join(\", \")}`,\n\t\t\tunregistered,\n\t\t\treasons,\n\t\t);\n\t}\n}\n\n/**\n * Race the backend's `load()` against a cumulative deadline.\n *\n * On timeout, synthesize an `AdapterFailure` whose `reasons` map carries\n * a `kind: \"timeout\"` entry per requested tag. The verification pass in\n * `runEnsureRegistered` will then produce a normal `ElementLoaderError`\n * with structured per-tag reasons — same surface shape as any other\n * adapter rejection.\n */\nasync function raceWithLoadTimeout(\n\tloadPromise: Promise<void>,\n\ttags: ElementTag[],\n\tloadTimeoutMs: number,\n): Promise<void> {\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\ttry {\n\t\tawait Promise.race([\n\t\t\tloadPromise,\n\t\t\tnew Promise<void>((_, reject) => {\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\tconst reasons = new Map<ElementTag, RegistrationFailureReason>();\n\t\t\t\t\tfor (const tag of tags) {\n\t\t\t\t\t\treasons.set(tag, {\n\t\t\t\t\t\t\tkind: \"timeout\",\n\t\t\t\t\t\t\ttag,\n\t\t\t\t\t\t\ttimeoutMs: loadTimeoutMs,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treject(new AdapterFailure(reasons));\n\t\t\t\t}, loadTimeoutMs);\n\t\t\t}),\n\t\t]);\n\t} finally {\n\t\tif (timer) clearTimeout(timer);\n\t}\n}\n\n/**\n * Synchronously assert that every tag is already in `customElements`.\n * Throws `ElementAssertionError` with diagnostic detail otherwise.\n *\n * Used by hosts that opt into the \"preloaded\" strategy — they pre-register\n * elements out-of-band and want a loud failure if anything is missing.\n */\nexport function assertRegistered(tags: ElementTag[]): void {\n\tif (!tags || tags.length === 0) return;\n\tconst missing = tags.filter((tag) => !isRegistered(tag));\n\tif (missing.length === 0) return;\n\tthrow new ElementAssertionError(tags, missing, snapshotRegisteredTags());\n}\n\n// ─── Internals ───────────────────────────────────────────────────────────────\n\nfunction resolveBackend(backend: BackendOption): ElementLoaderBackend {\n\tif (isDirectBackend(backend)) return backend;\n\tif (\"kind\" in backend) {\n\t\tif (backend.kind === \"iife\") return createIifeBackend(backend);\n\t\tif (backend.kind === \"esm\") {\n\t\t\tconst backendKey = backendKeyOf(backend);\n\t\t\tconst override = resolvedBackendOverrides.get(backendKey);\n\t\t\tif (override) return override;\n\t\t\tconst existing = resolvedEsmBackends.get(backendKey);\n\t\t\tif (existing) return existing;\n\t\t\tconst created = createEsmBackend(backend);\n\t\t\tresolvedEsmBackends.set(backendKey, created);\n\t\t\treturn created;\n\t\t}\n\t}\n\tthrow new Error(\"ElementLoader: invalid backend option\");\n}\n\nfunction isDirectBackend(\n\tbackend: BackendOption,\n): backend is ElementLoaderBackend {\n\treturn (\n\t\ttypeof (backend as { load?: unknown }).load === \"function\" &&\n\t\t!(\"kind\" in backend)\n\t);\n}\n\nfunction resolveDoc(doc: Document | undefined): Document {\n\tif (doc) return doc;\n\tif (typeof document !== \"undefined\") return document;\n\tthrow new Error(\n\t\t\"ElementLoader: no Document available; pass options.doc explicitly\",\n\t);\n}\n\nfunction buildDedupKey(backend: BackendOption, elements: ElementMap): string {\n\tconst backendKey = backendKeyOf(backend);\n\tconst entries = Object.entries(elements).sort(([a], [b]) =>\n\t\ta.localeCompare(b),\n\t);\n\treturn `${backendKey}|${JSON.stringify(entries)}`;\n}\n\nconst backendIds = new WeakMap<ElementLoaderBackend, string>();\nlet nextBackendId = 0;\nconst functionIds = new WeakMap<Function, string>();\nlet nextFunctionId = 0;\nconst opaqueObjectIds = new WeakMap<object, string>();\nlet nextOpaqueObjectId = 0;\n\nfunction backendKeyOf(backend: BackendOption): string {\n\tif (isDirectBackend(backend)) {\n\t\tlet id = backendIds.get(backend);\n\t\tif (!id) {\n\t\t\tid = `b${++nextBackendId}`;\n\t\t\tbackendIds.set(backend, id);\n\t\t}\n\t\treturn `backend#${id}`;\n\t}\n\tif (\"kind\" in backend) {\n\t\tif (backend.kind === \"iife\") {\n\t\t\treturn `iife#${fingerprintValue({\n\t\t\t\tkind: \"iife\",\n\t\t\t\tbundleHost: backend.bundleHost,\n\t\t\t\tbundleType: backend.bundleType ?? \"\",\n\t\t\t\tneedsControllers: backend.needsControllers ?? true,\n\t\t\t\tbundleInfo: backend.bundleInfo ?? null,\n\t\t\t\tdebugEnabled: backend.debugEnabled ?? null,\n\t\t\t\tbundleRetry: backend.bundleRetry ?? null,\n\t\t\t\tonBundleRetryStatus: backend.onBundleRetryStatus ?? null,\n\t\t\t\ttrackPageActions: backend.trackPageActions ?? false,\n\t\t\t\tinstrumentationProvider: backend.instrumentationProvider ?? null,\n\t\t\t})}`;\n\t\t}\n\t\tif (backend.kind === \"esm\") {\n\t\t\treturn `esm#${fingerprintValue({\n\t\t\t\tkind: \"esm\",\n\t\t\t\tcdnBaseUrl: backend.cdnBaseUrl,\n\t\t\t\tcdnProvider: backend.cdnProvider ?? null,\n\t\t\t\tmoduleResolution: backend.moduleResolution ?? \"url\",\n\t\t\t\tview: backend.view ?? \"delivery\",\n\t\t\t\tviewConfig: backend.viewConfig ?? null,\n\t\t\t\tloadControllers: backend.loadControllers ?? true,\n\t\t\t\tdebugEnabled: backend.debugEnabled ?? null,\n\t\t\t\ttrackPageActions: backend.trackPageActions ?? false,\n\t\t\t\tinstrumentationProvider: backend.instrumentationProvider ?? null,\n\t\t\t})}`;\n\t\t}\n\t}\n\treturn \"unknown\";\n}\n\nfunction fingerprintValue(value: unknown): string {\n\treturn JSON.stringify(normalizeForFingerprint(value, new Map()));\n}\n\nfunction normalizeForFingerprint(\n\tvalue: unknown,\n\tseen: Map<object, string>,\n): unknown {\n\tif (value === null || value === undefined) return value;\n\tconst primitiveType = typeof value;\n\tif (\n\t\tprimitiveType === \"string\" ||\n\t\tprimitiveType === \"number\" ||\n\t\tprimitiveType === \"boolean\"\n\t) {\n\t\treturn value;\n\t}\n\tif (primitiveType === \"function\") {\n\t\treturn { __functionRef: getFunctionRefId(value as Function) };\n\t}\n\tif (primitiveType !== \"object\") {\n\t\treturn String(value);\n\t}\n\n\tconst objectValue = value as object;\n\tconst existing = seen.get(objectValue);\n\tif (existing) return { __cycleRef: existing };\n\tconst cycleRefId = `cycle#${seen.size + 1}`;\n\tseen.set(objectValue, cycleRefId);\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => normalizeForFingerprint(entry, seen));\n\t}\n\n\tif (!isPlainObject(value)) {\n\t\treturn { __objectRef: getOpaqueObjectRefId(objectValue) };\n\t}\n\n\tconst normalized: Record<string, unknown> = {};\n\tfor (const key of Object.keys(value).sort()) {\n\t\tnormalized[key] = normalizeForFingerprint(\n\t\t\t(value as Record<string, unknown>)[key],\n\t\t\tseen,\n\t\t);\n\t}\n\treturn normalized;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === Object.prototype || prototype === null;\n}\n\nfunction getFunctionRefId(fn: Function): string {\n\tlet id = functionIds.get(fn);\n\tif (!id) {\n\t\tid = `fn#${++nextFunctionId}`;\n\t\tfunctionIds.set(fn, id);\n\t}\n\treturn id;\n}\n\nfunction getOpaqueObjectRefId(value: object): string {\n\tlet id = opaqueObjectIds.get(value);\n\tif (!id) {\n\t\tid = `obj#${++nextOpaqueObjectId}`;\n\t\topaqueObjectIds.set(value, id);\n\t}\n\treturn id;\n}\n\nfunction allAlreadyRegistered(tags: ElementTag[]): boolean {\n\treturn tags.every((tag) => isRegistered(tag));\n}\n\nfunction isRegistered(tag: ElementTag): boolean {\n\tif (typeof customElements === \"undefined\") return false;\n\treturn customElements.get(tag) !== undefined;\n}\n\nasync function whenDefinedWithTimeout(\n\ttag: ElementTag,\n\ttimeoutMs: number,\n): Promise<void> {\n\tif (typeof customElements === \"undefined\") {\n\t\tthrow new Error(`no customElements to await ${tag}`);\n\t}\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\ttry {\n\t\treturn await Promise.race([\n\t\t\tcustomElements.whenDefined(tag).then(() => undefined),\n\t\t\tnew Promise<void>((_, reject) => {\n\t\t\t\ttimer = setTimeout(\n\t\t\t\t\t() => reject(new Error(`Timeout waiting for ${tag}`)),\n\t\t\t\t\ttimeoutMs,\n\t\t\t\t);\n\t\t\t}),\n\t\t]);\n\t} finally {\n\t\tif (timer) clearTimeout(timer);\n\t}\n}\n\nfunction snapshotRegisteredTags(): ElementTag[] {\n\tif (typeof customElements === \"undefined\") return [];\n\t// Standard `CustomElementRegistry` does not expose iteration. Tests install\n\t// a scripted registry with a `__pieSnapshot` extension to make diagnostic\n\t// messages assertable. Production falls through to an empty list —\n\t// still strictly better than today's \"missing tags: X\" error which leaks\n\t// no registry state at all.\n\tconst reg = customElements as unknown as {\n\t\t__pieSnapshot?: () => ElementTag[];\n\t};\n\tif (typeof reg.__pieSnapshot === \"function\") {\n\t\ttry {\n\t\t\treturn reg.__pieSnapshot();\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\treturn [];\n}\n\nfunction extractAdapterReason(\n\terr: Error | undefined,\n\ttag: ElementTag,\n): RegistrationFailureReason | undefined {\n\tif (!err) return undefined;\n\tif (err instanceof AdapterFailure) return err.reasons.get(tag);\n\treturn { kind: \"backend-rejected\", tag, cause: err.message };\n}\n\n// ─── Test-only helpers ───────────────────────────────────────────────────────\n\n/**\n * Internal helpers for test harnesses. Not part of the public runtime API;\n * production code should never reach for these.\n *\n * @internal\n */\nexport const __testing = {\n\tresetDedupState(): void {\n\t\tinFlightRequests.clear();\n\t\tresolvedEsmBackends.clear();\n\t\tresolvedBackendOverrides.clear();\n\t},\n\tinFlightCount(): number {\n\t\treturn inFlightRequests.size;\n\t},\n\tdedupKeyFor(elements: ElementMap, backend: BackendOption): string {\n\t\treturn buildDedupKey(backend, elements);\n\t},\n\treplaceResolvedBackendForTesting(\n\t\tbackend: BackendOption,\n\t\tresolvedBackend: ElementLoaderBackend,\n\t): void {\n\t\tresolvedBackendOverrides.set(backendKeyOf(backend), resolvedBackend);\n\t},\n\trestoreResolvedBackendsForTesting(): void {\n\t\tresolvedEsmBackends.clear();\n\t\tresolvedBackendOverrides.clear();\n\t},\n};\n"]}
1
+ {"version":3,"file":"element-loader.js","sourceRoot":"","sources":["../../src/loaders/element-loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ElementLoader primitive — the one place where \"these tags are registered\n * with customElements\" is decided.\n *\n * Owns the truthful promise contract end-to-end:\n *\n * ensureRegistered(elements, options) resolves iff every requested tag\n * is in `customElements` at the moment of resolution. On partial\n * success it rejects with an `ElementLoaderError` carrying the set of\n * unregistered tags and a per-tag `RegistrationFailureReason` map.\n *\n * The primitive delegates the actual fetch/register work to a backend\n * adapter (IIFE or ESM) but always verifies the outcome via\n * `customElements.whenDefined`. An adapter cannot silently under-register\n * — the primitive will catch it and surface a timeout reason.\n *\n * See packages/players-shared/tests/element-loader-contract.test.ts for\n * the executable specification of every failure mode this primitive is\n * required to catch.\n */\n\nimport { DEFAULT_IIFE_BUNDLE_RETRY_CONFIG } from \"../loader-config.js\";\nimport type { ElementMap } from \"./ElementLoader.js\";\nimport {\n\tAdapterFailure,\n\ttype BackendContext,\n\ttype ElementLoaderBackend,\n\ttype ElementTag,\n\ttype RegistrationFailureReason,\n} from \"./element-loader-types.js\";\nimport { createEsmBackend, type EsmBackendConfig } from \"./esm-adapter.js\";\nimport { createIifeBackend, type IifeBackendConfig } from \"./iife-adapter.js\";\nimport {\n\tassertElementPackagesAllowed,\n\ttype ElementPackagePolicy,\n} from \"./element-package-policy.js\";\n\nexport type {\n\tBackendContext,\n\tElementLoaderBackend,\n\tElementMap,\n\tElementTag,\n\tRegistrationFailureReason,\n} from \"./element-loader-types.js\";\nexport { AdapterFailure } from \"./element-loader-types.js\";\nexport type { IifeBackendConfig } from \"./iife-adapter.js\";\nexport type { EsmBackendConfig } from \"./esm-adapter.js\";\n\n/**\n * Aggregate error thrown by `ensureRegistered` when one or more requested\n * tags were not registered by the time verification timed out.\n */\nexport class ElementLoaderError extends Error {\n\toverride readonly name = \"ElementLoaderError\";\n\treadonly unregisteredTags: Set<ElementTag>;\n\treadonly reasons: Map<ElementTag, RegistrationFailureReason>;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tunregisteredTags: Set<ElementTag>,\n\t\treasons: Map<ElementTag, RegistrationFailureReason>,\n\t) {\n\t\tsuper(message);\n\t\tthis.unregisteredTags = unregisteredTags;\n\t\tthis.reasons = reasons;\n\t}\n}\n\n/**\n * Thrown by `assertRegistered` when any requested tag is missing from\n * `customElements`. Carries enough detail for the host to diagnose what\n * pre-registration step was skipped.\n */\nexport class ElementAssertionError extends Error {\n\toverride readonly name = \"ElementAssertionError\";\n\treadonly expectedTags: readonly ElementTag[];\n\treadonly missingTags: readonly ElementTag[];\n\treadonly currentlyRegisteredTags: readonly ElementTag[];\n\n\tconstructor(\n\t\texpected: ElementTag[],\n\t\tmissing: ElementTag[],\n\t\tcurrentlyRegistered: ElementTag[],\n\t) {\n\t\tsuper(buildAssertionMessage(expected, missing, currentlyRegistered));\n\t\tthis.expectedTags = expected;\n\t\tthis.missingTags = missing;\n\t\tthis.currentlyRegisteredTags = currentlyRegistered;\n\t}\n}\n\nfunction buildAssertionMessage(\n\texpected: ElementTag[],\n\tmissing: ElementTag[],\n\tregistered: ElementTag[],\n): string {\n\tconst expectedStr = expected.join(\", \");\n\tconst missingStr = missing.join(\", \");\n\tconst registeredStr = registered.length\n\t\t? registered.join(\", \")\n\t\t: \"(none enumerable)\";\n\treturn (\n\t\t`ElementLoader.assertRegistered: expected [${expectedStr}], ` +\n\t\t`missing [${missingStr}]. customElements contains: [${registeredStr}].`\n\t);\n}\n\nexport type BackendOption =\n\t| IifeBackendConfig\n\t| EsmBackendConfig\n\t| ElementLoaderBackend;\n\nexport type EnsureRegisteredOptions = {\n\tbackend: BackendOption;\n\t/**\n\t * Optional host-controlled allow-list for executable `config.elements`\n\t * packages. Omit to preserve the trusted-application behavior.\n\t */\n\telementPackagePolicy?: ElementPackagePolicy;\n\tdoc?: Document;\n\twhenDefinedTimeoutMs?: number;\n\t/**\n\t * Outer cumulative deadline for the backend's `load()` call.\n\t *\n\t * Closes the \"promise never settles\" seam for adapters whose underlying\n\t * fetch can stall indefinitely (e.g. ESM `import()` against a frozen\n\t * CDN). When the deadline elapses, the primitive synthesizes an\n\t * `AdapterFailure` with `kind: \"timeout\"` reasons for every requested\n\t * tag — surfacing as a normal `ElementLoaderError` to the caller.\n\t *\n\t * Defaults to `DEFAULT_IIFE_BUNDLE_RETRY_CONFIG.timeoutMs` so\n\t * adapter-internal retry windows (IIFE bundle-build polling) fit\n\t * inside the same overall budget.\n\t */\n\tloadTimeoutMs?: number;\n};\n\nconst DEFAULT_WHEN_DEFINED_TIMEOUT_MS = 5000;\nconst DEFAULT_LOAD_TIMEOUT_MS = DEFAULT_IIFE_BUNDLE_RETRY_CONFIG.timeoutMs;\n\n// Module-scoped in-flight cache. Key: backend signature + sorted elements.\n// Keeps concurrent identical requests collapsed to one backend call.\nconst inFlightRequests = new Map<string, Promise<void>>();\nconst resolvedEsmBackends = new Map<string, ElementLoaderBackend>();\nconst resolvedBackendOverrides = new Map<string, ElementLoaderBackend>();\n\n/**\n * Resolve iff every tag in `elements` is registered with `customElements`.\n * Reject with `ElementLoaderError` otherwise.\n *\n * The primitive is the sole authority on registration state:\n * - Empty element map resolves immediately (no backend call).\n * - Already-registered tags resolve immediately (no backend call).\n * - Concurrent identical requests share one backend call.\n * - After the adapter's `load` settles, a post-load verification pass\n * (bounded `customElements.whenDefined`) checks every tag. Any missing\n * tag becomes a rejection.\n */\nexport async function ensureRegistered(\n\telements: ElementMap,\n\toptions: EnsureRegisteredOptions,\n): Promise<void> {\n\tif (!elements || Object.keys(elements).length === 0) return;\n\t// Enforce policy before the already-registered fast path: a matching tag in\n\t// the registry must not turn a disallowed authored package into valid input.\n\tassertElementPackagesAllowed(elements, options.elementPackagePolicy);\n\n\tconst tags = Object.keys(elements);\n\tconst timeoutMs =\n\t\toptions.whenDefinedTimeoutMs ?? DEFAULT_WHEN_DEFINED_TIMEOUT_MS;\n\tconst loadTimeoutMs = options.loadTimeoutMs ?? DEFAULT_LOAD_TIMEOUT_MS;\n\n\t// Fast path: everything already registered. Skip backend and dedup\n\t// bookkeeping entirely.\n\tif (allAlreadyRegistered(tags)) return;\n\n\tconst dedupKey = buildDedupKey(options.backend, elements);\n\tconst existing = inFlightRequests.get(dedupKey);\n\tif (existing) return existing;\n\n\tconst backend = resolveBackend(options.backend);\n\tconst doc = resolveDoc(options.doc);\n\n\tconst promise = runEnsureRegistered(\n\t\telements,\n\t\ttags,\n\t\tbackend,\n\t\t{ doc, whenDefinedTimeoutMs: timeoutMs },\n\t\ttimeoutMs,\n\t\tloadTimeoutMs,\n\t);\n\n\tinFlightRequests.set(dedupKey, promise);\n\ttry {\n\t\tawait promise;\n\t} finally {\n\t\tif (inFlightRequests.get(dedupKey) === promise) {\n\t\t\tinFlightRequests.delete(dedupKey);\n\t\t}\n\t}\n}\n\nasync function runEnsureRegistered(\n\telements: ElementMap,\n\ttags: ElementTag[],\n\tbackend: ElementLoaderBackend,\n\tcontext: BackendContext,\n\ttimeoutMs: number,\n\tloadTimeoutMs: number,\n): Promise<void> {\n\tlet adapterError: Error | undefined;\n\ttry {\n\t\tawait raceWithLoadTimeout(\n\t\t\tbackend.load(elements, context),\n\t\t\ttags,\n\t\t\tloadTimeoutMs,\n\t\t);\n\t} catch (err) {\n\t\tadapterError = err instanceof Error ? err : new Error(String(err));\n\t}\n\n\tconst verification = await Promise.all(\n\t\ttags.map(async (tag) => {\n\t\t\tif (isRegistered(tag)) return { tag, ok: true as const };\n\t\t\ttry {\n\t\t\t\tawait whenDefinedWithTimeout(tag, timeoutMs);\n\t\t\t\treturn { tag, ok: true as const };\n\t\t\t} catch {\n\t\t\t\treturn { tag, ok: false as const };\n\t\t\t}\n\t\t}),\n\t);\n\n\tconst unregistered = new Set<ElementTag>();\n\tconst reasons = new Map<ElementTag, RegistrationFailureReason>();\n\tfor (const v of verification) {\n\t\tif (v.ok) continue;\n\t\tunregistered.add(v.tag);\n\t\tconst adapterReason = extractAdapterReason(adapterError, v.tag);\n\t\treasons.set(\n\t\t\tv.tag,\n\t\t\tadapterReason ?? { kind: \"timeout\", tag: v.tag, timeoutMs },\n\t\t);\n\t}\n\n\tif (unregistered.size > 0) {\n\t\tthrow new ElementLoaderError(\n\t\t\t`Element registration failed; missing tags: ${[...unregistered].join(\", \")}`,\n\t\t\tunregistered,\n\t\t\treasons,\n\t\t);\n\t}\n}\n\n/**\n * Race the backend's `load()` against a cumulative deadline.\n *\n * On timeout, synthesize an `AdapterFailure` whose `reasons` map carries\n * a `kind: \"timeout\"` entry per requested tag. The verification pass in\n * `runEnsureRegistered` will then produce a normal `ElementLoaderError`\n * with structured per-tag reasons — same surface shape as any other\n * adapter rejection.\n */\nasync function raceWithLoadTimeout(\n\tloadPromise: Promise<void>,\n\ttags: ElementTag[],\n\tloadTimeoutMs: number,\n): Promise<void> {\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\ttry {\n\t\tawait Promise.race([\n\t\t\tloadPromise,\n\t\t\tnew Promise<void>((_, reject) => {\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\tconst reasons = new Map<ElementTag, RegistrationFailureReason>();\n\t\t\t\t\tfor (const tag of tags) {\n\t\t\t\t\t\treasons.set(tag, {\n\t\t\t\t\t\t\tkind: \"timeout\",\n\t\t\t\t\t\t\ttag,\n\t\t\t\t\t\t\ttimeoutMs: loadTimeoutMs,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treject(new AdapterFailure(reasons));\n\t\t\t\t}, loadTimeoutMs);\n\t\t\t}),\n\t\t]);\n\t} finally {\n\t\tif (timer) clearTimeout(timer);\n\t}\n}\n\n/**\n * Synchronously assert that every tag is already in `customElements`.\n * Throws `ElementAssertionError` with diagnostic detail otherwise.\n *\n * Used by hosts that opt into the \"preloaded\" strategy — they pre-register\n * elements out-of-band and want a loud failure if anything is missing.\n */\nexport function assertRegistered(tags: ElementTag[]): void {\n\tif (!tags || tags.length === 0) return;\n\tconst missing = tags.filter((tag) => !isRegistered(tag));\n\tif (missing.length === 0) return;\n\tthrow new ElementAssertionError(tags, missing, snapshotRegisteredTags());\n}\n\n// ─── Internals ───────────────────────────────────────────────────────────────\n\nfunction resolveBackend(backend: BackendOption): ElementLoaderBackend {\n\tif (isDirectBackend(backend)) return backend;\n\tif (\"kind\" in backend) {\n\t\tif (backend.kind === \"iife\") return createIifeBackend(backend);\n\t\tif (backend.kind === \"esm\") {\n\t\t\tconst backendKey = backendKeyOf(backend);\n\t\t\tconst override = resolvedBackendOverrides.get(backendKey);\n\t\t\tif (override) return override;\n\t\t\tconst existing = resolvedEsmBackends.get(backendKey);\n\t\t\tif (existing) return existing;\n\t\t\tconst created = createEsmBackend(backend);\n\t\t\tresolvedEsmBackends.set(backendKey, created);\n\t\t\treturn created;\n\t\t}\n\t}\n\tthrow new Error(\"ElementLoader: invalid backend option\");\n}\n\nfunction isDirectBackend(\n\tbackend: BackendOption,\n): backend is ElementLoaderBackend {\n\treturn (\n\t\ttypeof (backend as { load?: unknown }).load === \"function\" &&\n\t\t!(\"kind\" in backend)\n\t);\n}\n\nfunction resolveDoc(doc: Document | undefined): Document {\n\tif (doc) return doc;\n\tif (typeof document !== \"undefined\") return document;\n\tthrow new Error(\n\t\t\"ElementLoader: no Document available; pass options.doc explicitly\",\n\t);\n}\n\nfunction buildDedupKey(backend: BackendOption, elements: ElementMap): string {\n\tconst backendKey = backendKeyOf(backend);\n\tconst entries = Object.entries(elements).sort(([a], [b]) =>\n\t\ta.localeCompare(b),\n\t);\n\treturn `${backendKey}|${JSON.stringify(entries)}`;\n}\n\nconst backendIds = new WeakMap<ElementLoaderBackend, string>();\nlet nextBackendId = 0;\nconst functionIds = new WeakMap<Function, string>();\nlet nextFunctionId = 0;\nconst opaqueObjectIds = new WeakMap<object, string>();\nlet nextOpaqueObjectId = 0;\n\nfunction backendKeyOf(backend: BackendOption): string {\n\tif (isDirectBackend(backend)) {\n\t\tlet id = backendIds.get(backend);\n\t\tif (!id) {\n\t\t\tid = `b${++nextBackendId}`;\n\t\t\tbackendIds.set(backend, id);\n\t\t}\n\t\treturn `backend#${id}`;\n\t}\n\tif (\"kind\" in backend) {\n\t\tif (backend.kind === \"iife\") {\n\t\t\treturn `iife#${fingerprintValue({\n\t\t\t\tkind: \"iife\",\n\t\t\t\tbundleHost: backend.bundleHost,\n\t\t\t\tbundleType: backend.bundleType ?? \"\",\n\t\t\t\tneedsControllers: backend.needsControllers ?? true,\n\t\t\t\tbundleInfo: backend.bundleInfo ?? null,\n\t\t\t\tdebugEnabled: backend.debugEnabled ?? null,\n\t\t\t\tbundleRetry: backend.bundleRetry ?? null,\n\t\t\t\tonBundleRetryStatus: backend.onBundleRetryStatus ?? null,\n\t\t\t\ttrackPageActions: backend.trackPageActions ?? false,\n\t\t\t\tinstrumentationProvider: backend.instrumentationProvider ?? null,\n\t\t\t})}`;\n\t\t}\n\t\tif (backend.kind === \"esm\") {\n\t\t\treturn `esm#${fingerprintValue({\n\t\t\t\tkind: \"esm\",\n\t\t\t\tcdnBaseUrl: backend.cdnBaseUrl,\n\t\t\t\tcdnProvider: backend.cdnProvider ?? null,\n\t\t\t\tmoduleResolution: backend.moduleResolution ?? \"url\",\n\t\t\t\tview: backend.view ?? \"delivery\",\n\t\t\t\tviewConfig: backend.viewConfig ?? null,\n\t\t\t\tloadControllers: backend.loadControllers ?? true,\n\t\t\t\tdebugEnabled: backend.debugEnabled ?? null,\n\t\t\t\ttrackPageActions: backend.trackPageActions ?? false,\n\t\t\t\tinstrumentationProvider: backend.instrumentationProvider ?? null,\n\t\t\t})}`;\n\t\t}\n\t}\n\treturn \"unknown\";\n}\n\nfunction fingerprintValue(value: unknown): string {\n\treturn JSON.stringify(normalizeForFingerprint(value, new Map()));\n}\n\nfunction normalizeForFingerprint(\n\tvalue: unknown,\n\tseen: Map<object, string>,\n): unknown {\n\tif (value === null || value === undefined) return value;\n\tconst primitiveType = typeof value;\n\tif (\n\t\tprimitiveType === \"string\" ||\n\t\tprimitiveType === \"number\" ||\n\t\tprimitiveType === \"boolean\"\n\t) {\n\t\treturn value;\n\t}\n\tif (primitiveType === \"function\") {\n\t\treturn { __functionRef: getFunctionRefId(value as Function) };\n\t}\n\tif (primitiveType !== \"object\") {\n\t\treturn String(value);\n\t}\n\n\tconst objectValue = value as object;\n\tconst existing = seen.get(objectValue);\n\tif (existing) return { __cycleRef: existing };\n\tconst cycleRefId = `cycle#${seen.size + 1}`;\n\tseen.set(objectValue, cycleRefId);\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((entry) => normalizeForFingerprint(entry, seen));\n\t}\n\n\tif (!isPlainObject(value)) {\n\t\treturn { __objectRef: getOpaqueObjectRefId(objectValue) };\n\t}\n\n\tconst normalized: Record<string, unknown> = {};\n\tfor (const key of Object.keys(value).sort()) {\n\t\tnormalized[key] = normalizeForFingerprint(\n\t\t\t(value as Record<string, unknown>)[key],\n\t\t\tseen,\n\t\t);\n\t}\n\treturn normalized;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst prototype = Object.getPrototypeOf(value);\n\treturn prototype === Object.prototype || prototype === null;\n}\n\nfunction getFunctionRefId(fn: Function): string {\n\tlet id = functionIds.get(fn);\n\tif (!id) {\n\t\tid = `fn#${++nextFunctionId}`;\n\t\tfunctionIds.set(fn, id);\n\t}\n\treturn id;\n}\n\nfunction getOpaqueObjectRefId(value: object): string {\n\tlet id = opaqueObjectIds.get(value);\n\tif (!id) {\n\t\tid = `obj#${++nextOpaqueObjectId}`;\n\t\topaqueObjectIds.set(value, id);\n\t}\n\treturn id;\n}\n\nfunction allAlreadyRegistered(tags: ElementTag[]): boolean {\n\treturn tags.every((tag) => isRegistered(tag));\n}\n\nfunction isRegistered(tag: ElementTag): boolean {\n\tif (typeof customElements === \"undefined\") return false;\n\treturn customElements.get(tag) !== undefined;\n}\n\nasync function whenDefinedWithTimeout(\n\ttag: ElementTag,\n\ttimeoutMs: number,\n): Promise<void> {\n\tif (typeof customElements === \"undefined\") {\n\t\tthrow new Error(`no customElements to await ${tag}`);\n\t}\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\ttry {\n\t\treturn await Promise.race([\n\t\t\tcustomElements.whenDefined(tag).then(() => undefined),\n\t\t\tnew Promise<void>((_, reject) => {\n\t\t\t\ttimer = setTimeout(\n\t\t\t\t\t() => reject(new Error(`Timeout waiting for ${tag}`)),\n\t\t\t\t\ttimeoutMs,\n\t\t\t\t);\n\t\t\t}),\n\t\t]);\n\t} finally {\n\t\tif (timer) clearTimeout(timer);\n\t}\n}\n\nfunction snapshotRegisteredTags(): ElementTag[] {\n\tif (typeof customElements === \"undefined\") return [];\n\t// Standard `CustomElementRegistry` does not expose iteration. Tests install\n\t// a scripted registry with a `__pieSnapshot` extension to make diagnostic\n\t// messages assertable. Production falls through to an empty list —\n\t// still strictly better than today's \"missing tags: X\" error which leaks\n\t// no registry state at all.\n\tconst reg = customElements as unknown as {\n\t\t__pieSnapshot?: () => ElementTag[];\n\t};\n\tif (typeof reg.__pieSnapshot === \"function\") {\n\t\ttry {\n\t\t\treturn reg.__pieSnapshot();\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\treturn [];\n}\n\nfunction extractAdapterReason(\n\terr: Error | undefined,\n\ttag: ElementTag,\n): RegistrationFailureReason | undefined {\n\tif (!err) return undefined;\n\tif (err instanceof AdapterFailure) return err.reasons.get(tag);\n\treturn { kind: \"backend-rejected\", tag, cause: err.message };\n}\n\n// ─── Test-only helpers ───────────────────────────────────────────────────────\n\n/**\n * Internal helpers for test harnesses. Not part of the public runtime API;\n * production code should never reach for these.\n *\n * @internal\n */\nexport const __testing = {\n\tresetDedupState(): void {\n\t\tinFlightRequests.clear();\n\t\tresolvedEsmBackends.clear();\n\t\tresolvedBackendOverrides.clear();\n\t},\n\tinFlightCount(): number {\n\t\treturn inFlightRequests.size;\n\t},\n\tdedupKeyFor(elements: ElementMap, backend: BackendOption): string {\n\t\treturn buildDedupKey(backend, elements);\n\t},\n\treplaceResolvedBackendForTesting(\n\t\tbackend: BackendOption,\n\t\tresolvedBackend: ElementLoaderBackend,\n\t): void {\n\t\tresolvedBackendOverrides.set(backendKeyOf(backend), resolvedBackend);\n\t},\n\trestoreResolvedBackendsForTesting(): void {\n\t\tresolvedEsmBackends.clear();\n\t\tresolvedBackendOverrides.clear();\n\t},\n};\n"]}
@@ -0,0 +1,19 @@
1
+ import type { ElementMap } from "./ElementLoader.js";
2
+ /** Optional host policy for executable packages named by `config.elements`. */
3
+ export type ElementPackagePolicy = {
4
+ /** Exact package names, or exact `name@version` specs, that may execute. */
5
+ allowedPackages: readonly string[];
6
+ /** Require exact semver without build metadata. Defaults to true. */
7
+ requireExactVersions?: boolean;
8
+ };
9
+ export declare class ElementPackagePolicyError extends Error {
10
+ readonly tagName: string;
11
+ readonly packageSpec: string;
12
+ readonly name = "ElementPackagePolicyError";
13
+ constructor(tagName: string, packageSpec: string, message: string);
14
+ }
15
+ /**
16
+ * Validate an element map only when a host explicitly supplies a policy.
17
+ * Omitting the policy preserves the existing trusted-application behavior.
18
+ */
19
+ export declare function assertElementPackagesAllowed(elements: ElementMap, policy?: ElementPackagePolicy): void;
@@ -0,0 +1,68 @@
1
+ import { valid as validSemver } from "semver";
2
+ import { parsePackageName } from "../pie/utils.js";
3
+ export class ElementPackagePolicyError extends Error {
4
+ tagName;
5
+ packageSpec;
6
+ name = "ElementPackagePolicyError";
7
+ constructor(tagName, packageSpec, message) {
8
+ super(message);
9
+ this.tagName = tagName;
10
+ this.packageSpec = packageSpec;
11
+ }
12
+ }
13
+ function isExactSemver(version) {
14
+ return validSemver(version) === version;
15
+ }
16
+ function parsePolicyPackageSpec(spec) {
17
+ const parsed = parsePackageName(spec);
18
+ return {
19
+ packageName: parsed.name,
20
+ packagePath: parsed.path ? `${parsed.name}/${parsed.path}` : parsed.name,
21
+ version: parsed.version,
22
+ };
23
+ }
24
+ /**
25
+ * Validate an element map only when a host explicitly supplies a policy.
26
+ * Omitting the policy preserves the existing trusted-application behavior.
27
+ */
28
+ export function assertElementPackagesAllowed(elements, policy) {
29
+ if (!policy)
30
+ return;
31
+ const allowed = policy.allowedPackages
32
+ .filter((entry) => typeof entry === "string")
33
+ .map((entry) => entry.trim())
34
+ .filter(Boolean);
35
+ for (const [tagName, rawSpec] of Object.entries(elements)) {
36
+ const packageSpec = String(rawSpec).trim();
37
+ let parsed;
38
+ try {
39
+ parsed = parsePolicyPackageSpec(packageSpec);
40
+ }
41
+ catch {
42
+ throw new ElementPackagePolicyError(tagName, packageSpec, `Element package policy rejected invalid package spec "${packageSpec}" for ${tagName}.`);
43
+ }
44
+ if ((policy.requireExactVersions ?? true) &&
45
+ !isExactSemver(parsed.version)) {
46
+ const restriction = parsed.version.includes("+")
47
+ ? "does not allow semver build metadata because legacy IIFE bundle routes use + as a package separator"
48
+ : "requires an exact version";
49
+ throw new ElementPackagePolicyError(tagName, packageSpec, `Element package policy ${restriction} for ${tagName}; received "${packageSpec}".`);
50
+ }
51
+ const permitted = allowed.some((entry) => {
52
+ if (entry === packageSpec)
53
+ return true;
54
+ try {
55
+ const allowedSpec = parsePolicyPackageSpec(entry);
56
+ return (allowedSpec.version.length === 0 &&
57
+ allowedSpec.packagePath === parsed.packagePath);
58
+ }
59
+ catch {
60
+ return false;
61
+ }
62
+ });
63
+ if (!permitted) {
64
+ throw new ElementPackagePolicyError(tagName, packageSpec, `Element package policy does not allow "${packageSpec}" for ${tagName}.`);
65
+ }
66
+ }
67
+ }
68
+ //# sourceMappingURL=element-package-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"element-package-policy.js","sourceRoot":"","sources":["../../src/loaders/element-package-policy.ts"],"names":[],"mappings":"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","sourcesContent":["import { valid as validSemver } from \"semver\";\n\nimport { parsePackageName } from \"../pie/utils.js\";\nimport type { ElementMap } from \"./ElementLoader.js\";\n\n/** Optional host policy for executable packages named by `config.elements`. */\nexport type ElementPackagePolicy = {\n\t/** Exact package names, or exact `name@version` specs, that may execute. */\n\tallowedPackages: readonly string[];\n\t/** Require exact semver without build metadata. Defaults to true. */\n\trequireExactVersions?: boolean;\n};\n\nexport class ElementPackagePolicyError extends Error {\n\toverride readonly name = \"ElementPackagePolicyError\";\n\n\tconstructor(\n\t\treadonly tagName: string,\n\t\treadonly packageSpec: string,\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t}\n}\n\nfunction isExactSemver(version: string): boolean {\n\treturn validSemver(version) === version;\n}\n\nfunction parsePolicyPackageSpec(spec: string): {\n\tpackageName: string;\n\tpackagePath: string;\n\tversion: string;\n} {\n\tconst parsed = parsePackageName(spec);\n\treturn {\n\t\tpackageName: parsed.name,\n\t\tpackagePath: parsed.path ? `${parsed.name}/${parsed.path}` : parsed.name,\n\t\tversion: parsed.version,\n\t};\n}\n\n/**\n * Validate an element map only when a host explicitly supplies a policy.\n * Omitting the policy preserves the existing trusted-application behavior.\n */\nexport function assertElementPackagesAllowed(\n\telements: ElementMap,\n\tpolicy?: ElementPackagePolicy,\n): void {\n\tif (!policy) return;\n\tconst allowed = policy.allowedPackages\n\t\t.filter((entry): entry is string => typeof entry === \"string\")\n\t\t.map((entry) => entry.trim())\n\t\t.filter(Boolean);\n\n\tfor (const [tagName, rawSpec] of Object.entries(elements)) {\n\t\tconst packageSpec = String(rawSpec).trim();\n\t\tlet parsed: ReturnType<typeof parsePolicyPackageSpec>;\n\t\ttry {\n\t\t\tparsed = parsePolicyPackageSpec(packageSpec);\n\t\t} catch {\n\t\t\tthrow new ElementPackagePolicyError(\n\t\t\t\ttagName,\n\t\t\t\tpackageSpec,\n\t\t\t\t`Element package policy rejected invalid package spec \"${packageSpec}\" for ${tagName}.`,\n\t\t\t);\n\t\t}\n\n\t\tif (\n\t\t\t(policy.requireExactVersions ?? true) &&\n\t\t\t!isExactSemver(parsed.version)\n\t\t) {\n\t\t\tconst restriction = parsed.version.includes(\"+\")\n\t\t\t\t? \"does not allow semver build metadata because legacy IIFE bundle routes use + as a package separator\"\n\t\t\t\t: \"requires an exact version\";\n\t\t\tthrow new ElementPackagePolicyError(\n\t\t\t\ttagName,\n\t\t\t\tpackageSpec,\n\t\t\t\t`Element package policy ${restriction} for ${tagName}; received \"${packageSpec}\".`,\n\t\t\t);\n\t\t}\n\n\t\tconst permitted = allowed.some((entry) => {\n\t\t\tif (entry === packageSpec) return true;\n\t\t\ttry {\n\t\t\t\tconst allowedSpec = parsePolicyPackageSpec(entry);\n\t\t\t\treturn (\n\t\t\t\t\tallowedSpec.version.length === 0 &&\n\t\t\t\t\tallowedSpec.packagePath === parsed.packagePath\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\n\t\tif (!permitted) {\n\t\t\tthrow new ElementPackagePolicyError(\n\t\t\t\ttagName,\n\t\t\t\tpackageSpec,\n\t\t\t\t`Element package policy does not allow \"${packageSpec}\" for ${tagName}.`,\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
@@ -24,13 +24,35 @@ import { defineCustomElementSafely } from "../pie/custom-element-define.js";
24
24
  import { pieRegistry } from "../pie/registry.js";
25
25
  import { validateCustomElementTag } from "../pie/tag-names.js";
26
26
  import { BundleType, isCustomElementConstructor, Status, } from "../pie/types.js";
27
- import { getPackageWithoutVersion } from "../pie/utils.js";
27
+ import { getPackageWithoutVersion, parsePackageName } from "../pie/utils.js";
28
28
  import { AdapterFailure, } from "./element-loader-types.js";
29
29
  /**
30
30
  * Default PIE bundle service base URL. Exported so widgets can use it as
31
31
  * the fallback when the host does not supply `loaderOptions.bundleHost`.
32
32
  */
33
33
  export const DEFAULT_BUNDLE_HOST = "https://proxy.pie-api.com/bundles/";
34
+ /**
35
+ * The legacy IIFE bundle global is keyed by unversioned package name. Two
36
+ * distinct specs for one package therefore cannot coexist in a single bundle:
37
+ * one constructor would silently be reused for both requested versioned tags.
38
+ */
39
+ function findIifeElementMapConflict(elements) {
40
+ const specsByPackageName = new Map();
41
+ for (const packageSpecValue of Object.values(elements)) {
42
+ const packageSpec = String(packageSpecValue);
43
+ const packageName = parsePackageName(packageSpec).name;
44
+ const specs = specsByPackageName.get(packageName) ?? new Set();
45
+ specs.add(packageSpec);
46
+ specsByPackageName.set(packageName, specs);
47
+ }
48
+ const conflictingPackages = [...specsByPackageName.entries()]
49
+ .filter(([, specs]) => specs.size > 1)
50
+ .map(([packageName]) => packageName)
51
+ .sort();
52
+ return conflictingPackages.length > 0
53
+ ? `IIFE bundles cannot load multiple package specs for: ${conflictingPackages.join(", ")}`
54
+ : undefined;
55
+ }
34
56
  export function createIifeBackend(config) {
35
57
  const bundleType = config.bundleType ?? BundleType.clientPlayer;
36
58
  const needsControllers = config.needsControllers ?? true;
@@ -182,6 +204,18 @@ export function createIifeBackend(config) {
182
204
  async function load(elements, context) {
183
205
  if (!elements || Object.keys(elements).length === 0)
184
206
  return;
207
+ const conflict = findIifeElementMapConflict(elements);
208
+ if (conflict) {
209
+ const reasons = new Map();
210
+ for (const tag of Object.keys(elements)) {
211
+ reasons.set(tag, {
212
+ kind: "backend-rejected",
213
+ tag,
214
+ cause: conflict,
215
+ });
216
+ }
217
+ throw new AdapterFailure(reasons);
218
+ }
185
219
  const bundleUrl = buildBundleUrl(elements, bundleType, config);
186
220
  try {
187
221
  await ensureBundleLoaded(bundleUrl, context.doc);