@hyperframes/core 0.8.142 → 0.8.144

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 (57) hide show
  1. package/dist/beats/beatFile.d.ts +1 -1
  2. package/dist/beats/beatFile.d.ts.map +1 -1
  3. package/dist/beats/beatFile.js +11 -10
  4. package/dist/beats/beatFile.js.map +1 -1
  5. package/dist/compiler/compositionAssembly.d.ts +7 -2
  6. package/dist/compiler/compositionAssembly.d.ts.map +1 -1
  7. package/dist/compiler/compositionAssembly.js +53 -5
  8. package/dist/compiler/compositionAssembly.js.map +1 -1
  9. package/dist/compiler/htmlBundler.d.ts +1 -0
  10. package/dist/compiler/htmlBundler.d.ts.map +1 -1
  11. package/dist/compiler/htmlBundler.js +85 -39
  12. package/dist/compiler/htmlBundler.js.map +1 -1
  13. package/dist/compiler/htmlCompiler.d.ts.map +1 -1
  14. package/dist/compiler/htmlCompiler.js +7 -1
  15. package/dist/compiler/htmlCompiler.js.map +1 -1
  16. package/dist/compiler/index.d.ts +3 -2
  17. package/dist/compiler/index.d.ts.map +1 -1
  18. package/dist/compiler/index.js +3 -2
  19. package/dist/compiler/index.js.map +1 -1
  20. package/dist/compiler/inlineSubCompositions.js +5 -3
  21. package/dist/compiler/inlineSubCompositions.js.map +1 -1
  22. package/dist/compiler/scriptRuns.d.ts +0 -1
  23. package/dist/compiler/scriptRuns.d.ts.map +1 -1
  24. package/dist/compiler/scriptRuns.js +1 -23
  25. package/dist/compiler/scriptRuns.js.map +1 -1
  26. package/dist/compiler/timingCompiler.d.ts +1 -1
  27. package/dist/compiler/timingCompiler.d.ts.map +1 -1
  28. package/dist/compiler/timingCompiler.js +57 -128
  29. package/dist/compiler/timingCompiler.js.map +1 -1
  30. package/dist/generated/runtime-inline.js +1 -1
  31. package/dist/generated/runtime-inline.js.map +1 -1
  32. package/dist/hyperframe.runtime.iife.js +56 -56
  33. package/dist/media/gif.d.ts.map +1 -1
  34. package/dist/media/gif.js +7 -2
  35. package/dist/media/gif.js.map +1 -1
  36. package/dist/runtime/compositionLength.d.ts +3 -2
  37. package/dist/runtime/compositionLength.d.ts.map +1 -1
  38. package/dist/runtime/compositionLength.js +11 -5
  39. package/dist/runtime/compositionLength.js.map +1 -1
  40. package/dist/runtime/stackingContext.d.ts.map +1 -1
  41. package/dist/runtime/stackingContext.js +3 -0
  42. package/dist/runtime/stackingContext.js.map +1 -1
  43. package/dist/runtime/timeline.d.ts +0 -4
  44. package/dist/runtime/timeline.d.ts.map +1 -1
  45. package/dist/runtime/timeline.js +1 -4
  46. package/dist/runtime/timeline.js.map +1 -1
  47. package/dist/studioPreviewMark.d.ts +2 -0
  48. package/dist/studioPreviewMark.d.ts.map +1 -1
  49. package/dist/studioPreviewMark.js +6 -0
  50. package/dist/studioPreviewMark.js.map +1 -1
  51. package/dist/text/fitTextFontSize.d.ts.map +1 -1
  52. package/dist/text/fitTextFontSize.js +3 -1
  53. package/dist/text/fitTextFontSize.js.map +1 -1
  54. package/dist/timelineAssetId.d.ts.map +1 -1
  55. package/dist/timelineAssetId.js +3 -2
  56. package/dist/timelineAssetId.js.map +1 -1
  57. package/package.json +5 -4
@@ -13,7 +13,7 @@ export declare function parseBeats(content: string): {
13
13
  * the FIRST `<audio>`, or `<video data-has-audio="true">` without `muted` (in
14
14
  * document order) where data-timeline-role="music", or —
15
15
  * when no role is set — whose id matches the music regex. An explicit non-music
16
- * role excludes the element. Returns the raw src attribute, or null.
16
+ * role excludes the element. Returns the decoded src attribute, or null.
17
17
  */
18
18
  export declare function findMusicAudioSrc(html: string): string | null;
19
19
  //# sourceMappingURL=beatFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"beatFile.d.ts","sourceRoot":"","sources":["../../src/beats/beatFile.ts"],"names":[],"mappings":"AAUA,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CA8BhF;AAED,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAGhF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO1F;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAsB3F;AAcD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiB7D"}
1
+ {"version":3,"file":"beatFile.d.ts","sourceRoot":"","sources":["../../src/beats/beatFile.ts"],"names":[],"mappings":"AAgBA,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CA8BhF;AAED,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAGhF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO1F;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAsB3F;AAoBD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc7D"}
@@ -1,6 +1,7 @@
1
1
  // Persistence for beat data: one JSON file per audio file, matched by the
2
2
  // audio's project-relative path. Lives under `beats/` in the project so it
3
3
  // survives the audio being removed and re-added.
4
+ import { decodeAuthoredAttribute, scanHtmlOpeningTags, } from "@hyperframes/parsers";
4
5
  /** Project-relative path of the audio file behind a (possibly absolute) src URL. */
5
6
  export function audioRelPathForSrc(src) {
6
7
  if (!src)
@@ -79,12 +80,15 @@ export function parseBeats(content) {
79
80
  }
80
81
  const MUSIC_ID_RE = /\b(music|bgm|soundtrack|background[-_]?music)\b/i;
81
82
  function attr(tag, name) {
82
- const m = tag.match(new RegExp(`\\b${name}\\s*=\\s*["']([^"']*)["']`, "i"));
83
- return m ? m[1] : null;
83
+ const attribute = tag.attributes.find((value) => value.name === name);
84
+ return attribute?.kind === "value" ? decodeAuthoredAttribute(attribute.value) : null;
84
85
  }
85
86
  function isSoundingVideoTag(tag) {
86
- const unquoted = tag.replace(/"[^"]*"|'[^']*'/g, '""');
87
- return attr(tag, "data-has-audio") === "true" && !/\smuted(?=[\s/>=])/i.test(unquoted);
87
+ return (attr(tag, "data-has-audio") === "true" &&
88
+ !tag.attributes.some((attribute) => attribute.name === "muted"));
89
+ }
90
+ function isMusicSourceTag(tag) {
91
+ return tag.closed && (tag.name === "audio" || (tag.name === "video" && isSoundingVideoTag(tag)));
88
92
  }
89
93
  /**
90
94
  * Find the music track's src in composition HTML, applying the SAME rules as the
@@ -92,14 +96,11 @@ function isSoundingVideoTag(tag) {
92
96
  * the FIRST `<audio>`, or `<video data-has-audio="true">` without `muted` (in
93
97
  * document order) where data-timeline-role="music", or —
94
98
  * when no role is set — whose id matches the music regex. An explicit non-music
95
- * role excludes the element. Returns the raw src attribute, or null.
99
+ * role excludes the element. Returns the decoded src attribute, or null.
96
100
  */
97
101
  export function findMusicAudioSrc(html) {
98
- // `[^>]*` spans newlines (it's a negated class, not `.`), so multi-line opening
99
- // tags are handled. HyperFrames authors src as an attribute on <audio>.
100
- const tags = html.match(/<(?:audio|video)\b[^>]*>/gi) ?? [];
101
- for (const tag of tags) {
102
- if (/^<video/i.test(tag) && !isSoundingVideoTag(tag))
102
+ for (const tag of scanHtmlOpeningTags(html)) {
103
+ if (!isMusicSourceTag(tag))
103
104
  continue;
104
105
  const src = attr(tag, "src");
105
106
  if (!src)
@@ -1 +1 @@
1
- {"version":3,"file":"beatFile.js","sourceRoot":"","sources":["../../src/beats/beatFile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"beatFile.js","sourceRoot":"","sources":["../../src/beats/beatFile.ts"],"names":[],"mappings":"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"}
@@ -20,7 +20,10 @@
20
20
  * takes strings — so both a linkedom document and a live browser document
21
21
  * satisfy it without an `as T` cast at either call site.
22
22
  */
23
- export declare const EXTRACTED_COMPOSITION_ASSET_SELECTOR = "style, script, link[rel=\"stylesheet\"], link[rel=\"preconnect\"]";
23
+ export declare function isJavaScriptType(el: AssemblyAttributed): boolean;
24
+ export declare function executableScripts<TElement extends AssemblyAttributed>(node: AssemblyQueryable<TElement> | null | undefined): TElement[];
25
+ /** The styles, scripts and links both paths extract, so the mounted copy must drop them. */
26
+ export declare function extractedCompositionAssets<TElement extends AssemblyAttributed>(node: AssemblyQueryable<TElement>): TElement[];
24
27
  /**
25
28
  * The compiler's nesting cap, enforced against the ancestry chain rather than a
26
29
  * counter so a wide tree is not penalised for a deep sibling.
@@ -102,6 +105,8 @@ export interface CompositionAssemblyPlan<TElement extends AssemblyAttributed> {
102
105
  scriptSources: TElement[];
103
106
  /** Head and content links to hoist into the host document. */
104
107
  linkSources: TElement[];
108
+ /** Inert scripts the mounted root would leave behind; both paths mount them next to it. */
109
+ inertScriptsOutsideRoot: TElement[];
105
110
  /**
106
111
  * Nodes that may declare the composition's variable defaults, in precedence
107
112
  * order — later wins. Full-document compositions declare on `<html>`;
@@ -116,7 +121,7 @@ export interface CompositionAssemblyPlan<TElement extends AssemblyAttributed> {
116
121
  * how it is identified. Pure: it reads attributes and runs selectors, and does
117
122
  * not mutate, fetch, or touch a filesystem.
118
123
  */
119
- export declare function planCompositionAssembly<TElement extends AssemblyAttributed>(input: CompositionAssemblyInput<TElement>): CompositionAssemblyPlan<TElement>;
124
+ export declare function planCompositionAssembly<TElement extends AssemblyAttributed & AssemblyQueryable<TElement>>(input: CompositionAssemblyInput<TElement>): CompositionAssemblyPlan<TElement>;
120
125
  export type NestedHostSkipReason = "circular composition reference" | "nesting depth exceeded";
121
126
  export interface NestedCompositionHost<TElement> {
122
127
  host: TElement;
@@ -1 +1 @@
1
- {"version":3,"file":"compositionAssembly.d.ts","sourceRoot":"","sources":["../../src/compiler/compositionAssembly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAeH,eAAO,MAAM,oCAAoC,sEAAoE,CAAC;AAEtH;;;GAGG;AACH,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAM5C,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,iEAAiE;AACjE,MAAM,WAAW,iBAAiB,CAAC,QAAQ;IACzC,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,wBAAwB,CAAC,QAAQ,SAAS,kBAAkB;IAC3E;;;;;;;;OAQG;IACH,WAAW,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAEzC;;;;OAIG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAE1C;;;OAGG;IACH,eAAe,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAElC;;;;OAIG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB,CAAC,QAAQ,SAAS,kBAAkB;IAC1E;;;;;;OAMG;IACH,SAAS,EAAE,QAAQ,GAAG,IAAI,CAAC;IAE3B;;;OAGG;IACH,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IAErC;;;;;;OAMG;IACH,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnC,mEAAmE;IACnE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B,8EAA8E;IAC9E,YAAY,EAAE,QAAQ,EAAE,CAAC;IAEzB;;;;OAIG;IACH,aAAa,EAAE,QAAQ,EAAE,CAAC;IAE1B,8DAA8D;IAC9D,WAAW,EAAE,QAAQ,EAAE,CAAC;IAExB;;;;;;OAMG;IACH,uBAAuB,EAAE,QAAQ,EAAE,CAAC;CACrC;AAUD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,SAAS,kBAAkB,EACzE,KAAK,EAAE,wBAAwB,CAAC,QAAQ,CAAC,GACxC,uBAAuB,CAAC,QAAQ,CAAC,CAsCnC;AAMD,MAAM,MAAM,oBAAoB,GAAG,gCAAgC,GAAG,wBAAwB,CAAC;AAE/F,MAAM,WAAW,qBAAqB,CAAC,QAAQ;IAC7C,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB,CAAC,QAAQ;IAC9C,KAAK,EAAE,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;IACzC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,oBAAoB,CAAA;KAAE,EAAE,CAAC;CAC1D;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,QAAQ,SAAS,kBAAkB,EACjF,aAAa,EAAE,iBAAiB,CAAC,QAAQ,CAAC,EAC1C,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,sBAAsB,CAAC,QAAQ,CAAC,CAmBlC"}
1
+ {"version":3,"file":"compositionAssembly.d.ts","sourceRoot":"","sources":["../../src/compiler/compositionAssembly.ts"],"names":[],"mappings":"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"}
@@ -31,7 +31,53 @@ const SCRIPT_SELECTOR = "script";
31
31
  * webfonts a composition's CSS depends on; preconnects are their latency hint.
32
32
  */
33
33
  const HOISTED_LINK_SELECTOR = 'link[rel="stylesheet"], link[rel="preconnect"]';
34
- export const EXTRACTED_COMPOSITION_ASSET_SELECTOR = `${STYLE_SELECTOR}, ${SCRIPT_SELECTOR}, ${HOISTED_LINK_SELECTOR}`;
34
+ // The HTML spec's JavaScript MIME type essence matches: a script with any of these types runs as classic.
35
+ const JAVASCRIPT_TYPES = new Set([
36
+ "",
37
+ "application/ecmascript",
38
+ "application/javascript",
39
+ "application/x-ecmascript",
40
+ "application/x-javascript",
41
+ "text/ecmascript",
42
+ "text/javascript",
43
+ "text/javascript1.0",
44
+ "text/javascript1.1",
45
+ "text/javascript1.2",
46
+ "text/javascript1.3",
47
+ "text/javascript1.4",
48
+ "text/javascript1.5",
49
+ "text/jscript",
50
+ "text/livescript",
51
+ "text/x-ecmascript",
52
+ "text/x-javascript",
53
+ ]);
54
+ const scriptType = (el) => (el.getAttribute("type") || "").trim().toLowerCase();
55
+ export function isJavaScriptType(el) {
56
+ return JAVASCRIPT_TYPES.has(scriptType(el));
57
+ }
58
+ /**
59
+ * A data block (application/json, text/template, ...) or a classic nomodule script never runs,
60
+ * so it is mounted as authored.
61
+ */
62
+ function isExecutableScript(el) {
63
+ const type = scriptType(el);
64
+ if (type === "module" || type === "importmap")
65
+ return true;
66
+ return JAVASCRIPT_TYPES.has(type) && el.getAttribute("nomodule") === null;
67
+ }
68
+ function inertScripts(node) {
69
+ return toArray(node?.querySelectorAll(SCRIPT_SELECTOR)).filter((el) => !isExecutableScript(el));
70
+ }
71
+ export function executableScripts(node) {
72
+ return toArray(node?.querySelectorAll(SCRIPT_SELECTOR)).filter(isExecutableScript);
73
+ }
74
+ /** The styles, scripts and links both paths extract, so the mounted copy must drop them. */
75
+ export function extractedCompositionAssets(node) {
76
+ return [
77
+ ...toArray(node.querySelectorAll(`${STYLE_SELECTOR}, ${HOISTED_LINK_SELECTOR}`)),
78
+ ...executableScripts(node),
79
+ ];
80
+ }
35
81
  /**
36
82
  * The compiler's nesting cap, enforced against the ancestry chain rather than a
37
83
  * counter so a wide tree is not penalised for a deep sibling.
@@ -60,6 +106,7 @@ export function planCompositionAssembly(input) {
60
106
  const declaredCompositionId = (innerRoot ?? compositionRoots[0])?.getAttribute(COMPOSITION_ID_ATTR)?.trim() || "";
61
107
  // A templated composition's <head> belongs to its host page, not to it.
62
108
  const assetHead = hasTemplate ? null : (head ?? null);
109
+ const mountedInert = innerRoot ? inertScripts(innerRoot) : [];
63
110
  return {
64
111
  innerRoot,
65
112
  authoredCompositionId: compositionId || declaredCompositionId || null,
@@ -69,14 +116,15 @@ export function planCompositionAssembly(input) {
69
116
  ...toArray(assetHead?.querySelectorAll(STYLE_SELECTOR)),
70
117
  ...toArray(contentNode.querySelectorAll(STYLE_SELECTOR)),
71
118
  ],
72
- scriptSources: [
73
- ...toArray(assetHead?.querySelectorAll(SCRIPT_SELECTOR)),
74
- ...toArray(contentNode.querySelectorAll(SCRIPT_SELECTOR)),
75
- ],
119
+ scriptSources: [...executableScripts(assetHead), ...executableScripts(contentNode)],
76
120
  linkSources: [
77
121
  ...toArray(head?.querySelectorAll(HOISTED_LINK_SELECTOR)),
78
122
  ...toArray(contentNode.querySelectorAll(HOISTED_LINK_SELECTOR)),
79
123
  ],
124
+ inertScriptsOutsideRoot: [
125
+ ...inertScripts(assetHead),
126
+ ...(innerRoot ? inertScripts(contentNode).filter((el) => !mountedInert.includes(el)) : []),
127
+ ],
80
128
  variableDefaultCarriers: [documentElement, innerRoot].filter((carrier) => carrier != null),
81
129
  };
82
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compositionAssembly.js","sourceRoot":"","sources":["../../src/compiler/compositionAssembly.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compositionAssembly.js","sourceRoot":"","sources":["../../src/compiler/compositionAssembly.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ export type BundledHostCompositionIdentity = {
6
6
  };
7
7
  export declare function assignBundledRuntimeCompositionIds(hosts: Element[], counts?: Map<string, number>): Map<Element, BundledHostCompositionIdentity>;
8
8
  export declare function prepareFlattenedInnerRoot(innerRoot: Element): Element;
9
+ export declare function parsesAsScript(source: string): boolean;
9
10
  export interface BundleOptions {
10
11
  /** Project-relative HTML entry to bundle. Defaults to `index.html`. */
11
12
  entryFile?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"htmlBundler.d.ts","sourceRoot":"","sources":["../../src/compiler/htmlBundler.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,gCAAgC,EAAE,MAAM,0BAA0B,CAAC;AAS5E,OAAO,EAAe,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAodvE,MAAM,MAAM,8BAA8B,GAAG;IAC3C,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AA4CF,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,OAAO,EAAE,EAChB,MAAM,GAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAA6C,GACtE,GAAG,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAyC9C;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAWrE;AA0MD,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oGAAoG;IACpG,kBAAkB,CAAC,EAAE,mBAAmB,CAAC;IACzC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IACnC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uGAAuG;IACvG,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AA8GD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/F;AAmaD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,QAAQ,EAClB,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,EAC7D,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACtC,OAAO,CAcT"}
1
+ {"version":3,"file":"htmlBundler.d.ts","sourceRoot":"","sources":["../../src/compiler/htmlBundler.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,gCAAgC,EAAE,MAAM,0BAA0B,CAAC;AAiB5E,OAAO,EAAe,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAqdvE,MAAM,MAAM,8BAA8B,GAAG;IAC3C,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AA4CF,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,OAAO,EAAE,EAChB,MAAM,GAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAA6C,GACtE,GAAG,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAyC9C;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAWrE;AAsMD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOtD;AAgBD,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oGAAoG;IACpG,kBAAkB,CAAC,EAAE,mBAAmB,CAAC;IACzC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IACnC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uGAAuG;IACvG,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AA6HD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/F;AAkbD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,QAAQ,EAClB,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,EAC7D,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACtC,OAAO,CAcT"}
@@ -1,7 +1,8 @@
1
- import { compositionStyle, cssStyleMergeKey, deferScriptsUntilFonts, UNCONDITIONAL_CSS_KEY, headStyleRuns, INLINED_FILE_ATTR, inlineScriptRuns, isJavaScriptType, styleElementsFor, } from "./scriptRuns.js";
1
+ import { compositionStyle, cssStyleMergeKey, deferScriptsUntilFonts, UNCONDITIONAL_CSS_KEY, headStyleRuns, INLINED_FILE_ATTR, inlineScriptRuns, styleElementsFor, } from "./scriptRuns.js";
2
+ import { executableScripts, isJavaScriptType, planCompositionAssembly, } from "./compositionAssembly.js";
2
3
  import { SCENE_PART_ATTR } from "../sceneParts.js";
3
4
  import { ensureExternalScriptTag, readExternalScriptAttributes, } from "./externalScripts.js";
4
- import { emitMountedModuleScripts } from "./importMaps.js";
5
+ import { emitMountedModuleScripts, parseImportMap } from "./importMaps.js";
5
6
  import { markFlattenedInnerRoot } from "../runtime/flattenedRoot.js";
6
7
  export { FLATTENED_INNER_ROOT_STRIP_ATTRS } from "../runtime/flattenedRoot.js";
7
8
  import { parseHostVariableValues, warnUnknownEnumValues } from "../runtime/getVariables.js";
@@ -9,18 +10,19 @@ import { sanitizeCssValue } from "../runtime/applyVariableBindings.js";
9
10
  import { cssVariableName } from "../tokenSlug.js";
10
11
  import { AsyncLocalStorage } from "async_hooks";
11
12
  import { readFileSync, existsSync, statSync } from "fs";
13
+ import { parse as parseJs } from "acorn";
12
14
  import { resolve, relative, dirname, isAbsolute, sep } from "path";
15
+ import { decodeCssEscapes, decodeWellFormedEscapes, encodeUrlPath, decodedUrlPath, splitUrlSuffix, } from "@hyperframes/parsers/asset-paths";
13
16
  import { CSS_URL_RE, isNonRelativeUrl } from "./assetPaths.js";
14
17
  import { transformSync } from "esbuild";
15
18
  import { compileHtml } from "./htmlCompiler.js";
16
19
  import { RUNTIME_BOOTSTRAP_ATTR, escapeInlineScriptSource, insertRuntimeTag, parseHTMLContent, stripEmbeddedRuntimeScripts, } from "./htmlDocument.js";
17
20
  // rewriteSubCompPaths functions are used by inlineSubCompositions (shared module)
18
- import { buildVariablesByCompScript, dedupeFontFaceRules, scopeCssToComposition, wrapInlineScriptWithErrorBoundary, wrapScopedCompositionScript, } from "./compositionScoping.js";
21
+ import { buildVariablesByCompScript, dedupeFontFaceRules, scopeCssToComposition, wrapInlineScriptWithErrorBoundary, scopedModulePrelude, wrapScopedCompositionScript, } from "./compositionScoping.js";
19
22
  import { validateHyperframeHtmlContract } from "./staticGuard.js";
20
23
  import { getHyperframeRuntimeScript } from "../generated/runtime-inline.js";
21
24
  import { readDeclaredDefaults } from "../runtime/getVariables.js";
22
25
  import { ensureExternalLinkTag, inlineSubCompositions, refuseSwapsReachedByRootScripts, } from "./inlineSubCompositions.js";
23
- import { queryByAttr } from "../utils/cssSelector.js";
24
26
  import { isSafePath, resolveWithinProject } from "../safePath.js";
25
27
  import { ensureHfIds } from "@hyperframes/parsers/hf-ids";
26
28
  import { HF_COLOR_GRADING_ATTR } from "../colorGrading.js";
@@ -90,30 +92,35 @@ function withCommentsStripped(css, fn) {
90
92
  };
91
93
  return { result, restore };
92
94
  }
95
+ function resolveRelativeUrlPath(fromDir, basePath) {
96
+ return resolve(fromDir, decodeWellFormedEscapes(basePath.replaceAll("\\", "/")));
97
+ }
93
98
  function rebaseCssUrls(css, cssFileDir, projectDir) {
94
99
  const resolvedRoot = resolve(projectDir);
95
100
  const resolvedDir = resolve(cssFileDir);
96
101
  if (resolvedDir === resolvedRoot)
97
102
  return css;
98
103
  return css.replace(CSS_URL_RE, (full, quote, urlValue) => {
99
- if (!urlValue || !isRelativeUrl(urlValue))
104
+ const decoded = decodeCssEscapes(urlValue);
105
+ if (!decoded || !isRelativeUrl(decoded))
100
106
  return full;
101
- const { basePath, suffix } = splitUrlSuffix(urlValue.trim());
107
+ const { basePath, suffix } = splitUrlSuffix(decoded);
102
108
  if (!basePath)
103
109
  return full;
104
- const absolutePath = resolve(resolvedDir, basePath);
105
- const rebased = relative(resolvedRoot, absolutePath).split(sep).join("/");
110
+ const absolutePath = resolveRelativeUrlPath(resolvedDir, basePath);
111
+ const rebased = encodeUrlPath(relative(resolvedRoot, absolutePath).split(sep).join("/"));
106
112
  if (rebased === basePath)
107
113
  return full;
108
- return `url(${quote || ""}${rebased}${suffix}${quote || ""})`;
114
+ const escapedSuffix = suffix.replace(/[\s\p{Cc}"'()\\<>]/gu, (char) => `\\${char.codePointAt(0).toString(16).padStart(6, "0")}`);
115
+ return `url(${quote || ""}${rebased}${escapedSuffix}${quote || ""})`;
109
116
  });
110
117
  }
111
118
  function rebaseRelativePath(urlValue, fromDir, toDir) {
112
119
  const { basePath, suffix } = splitUrlSuffix(urlValue.trim());
113
120
  if (!basePath)
114
121
  return urlValue;
115
- const absolutePath = resolve(fromDir, basePath);
116
- const rebased = relative(resolve(toDir), absolutePath).split(sep).join("/");
122
+ const absolutePath = resolveRelativeUrlPath(fromDir, basePath);
123
+ const rebased = encodeUrlPath(relative(resolve(toDir), absolutePath).split(sep).join("/"));
117
124
  return appendSuffixToUrl(rebased, suffix);
118
125
  }
119
126
  function rebaseSrcsetPaths(srcsetValue, fromDir, toDir) {
@@ -200,7 +207,7 @@ function inlineCssFile(css, cssFileDir, projectDir, visited = new Set()) {
200
207
  const importPath = urlPath ?? barePath;
201
208
  if (!importPath || !isRelativeUrl(importPath))
202
209
  return full;
203
- const resolved = resolve(cssFileDir, importPath);
210
+ const resolved = resolve(cssFileDir, decodedUrlPath(importPath));
204
211
  // @import is resolved relative to the CSS file, but must stay within the
205
212
  // project root; isSafePath also blocks symlink escapes (content is inlined).
206
213
  if (!isSafePath(projectDir, resolved))
@@ -236,14 +243,6 @@ function safeReadFileBuffer(filePath) {
236
243
  return null;
237
244
  }
238
245
  }
239
- function splitUrlSuffix(urlValue) {
240
- const queryIdx = urlValue.indexOf("?");
241
- const hashIdx = urlValue.indexOf("#");
242
- if (queryIdx < 0 && hashIdx < 0)
243
- return { basePath: urlValue, suffix: "" };
244
- const cutIdx = queryIdx < 0 ? hashIdx : hashIdx < 0 ? queryIdx : Math.min(queryIdx, hashIdx);
245
- return { basePath: urlValue.slice(0, cutIdx), suffix: urlValue.slice(cutIdx) };
246
- }
247
246
  function appendSuffixToUrl(baseUrl, suffix) {
248
247
  if (!suffix)
249
248
  return baseUrl;
@@ -320,7 +319,7 @@ function maybeInlineRelativeAssetUrl(urlValue, projectDir, inlineAssets) {
320
319
  const { basePath, suffix } = splitUrlSuffix(urlValue.trim());
321
320
  if (!basePath)
322
321
  return null;
323
- const filePath = resolveWithinProject(projectDir, basePath);
322
+ const filePath = resolveWithinProject(projectDir, decodeWellFormedEscapes(basePath));
324
323
  if (!filePath)
325
324
  return null;
326
325
  const ext = filePath.toLowerCase().match(/\.[^.]+$/)?.[0] ?? "";
@@ -666,12 +665,17 @@ function coalesceHeadStylesAndBodyScripts(document) {
666
665
  const isPinned = (el) => el.hasAttribute(RUNTIME_BOOTSTRAP_ATTR) || el.hasAttribute(SCENE_PART_ATTR);
667
666
  for (const { members, anchor } of inlineScriptRuns([...document.querySelectorAll("body script")], isPinned)) {
668
667
  const mergedJs = joinJsChunks(members.map((el) => el.textContent || ""));
668
+ if (mergedJs && !parsesAsScript(mergedJs)) {
669
+ for (const el of members)
670
+ el.textContent = inlineScriptSource(el.textContent || "");
671
+ continue;
672
+ }
669
673
  for (const el of members)
670
674
  el.remove();
671
675
  if (!mergedJs)
672
676
  continue;
673
677
  const inlineScript = document.createElement("script");
674
- inlineScript.textContent = escapeInlineScriptSource(stripJsCommentsParserSafe(mergedJs));
678
+ inlineScript.textContent = inlineScriptSource(mergedJs);
675
679
  if (anchor)
676
680
  anchor.before(inlineScript);
677
681
  else
@@ -723,6 +727,17 @@ function joinJsChunks(chunks) {
723
727
  .map((chunk) => (chunk.endsWith(";") ? chunk : chunk + "\n;"))
724
728
  .join("\n");
725
729
  }
730
+ // acorn in script mode, not the host engine: Bun 1.3's vm.Script compiles lazily and accepts anything.
731
+ // esbuild accepts export, top-level await and return, which a <script> rejects; acorn does not.
732
+ export function parsesAsScript(source) {
733
+ try {
734
+ parseJs(source, { ecmaVersion: "latest", sourceType: "script" });
735
+ return true;
736
+ }
737
+ catch {
738
+ return false;
739
+ }
740
+ }
726
741
  function stripJsCommentsParserSafe(source) {
727
742
  if (!source)
728
743
  return source;
@@ -734,6 +749,9 @@ function stripJsCommentsParserSafe(source) {
734
749
  return source;
735
750
  }
736
751
  }
752
+ function inlineScriptSource(js) {
753
+ return escapeInlineScriptSource(stripJsCommentsParserSafe(js));
754
+ }
737
755
  function preserveLocalScriptIntegrity(doc, src, resolvePath) {
738
756
  const path = resolvePath(src);
739
757
  if (!path)
@@ -758,10 +776,10 @@ function hoistExternalScript(src, projectDir, doc, seenSrcs, chunks, attributes)
758
776
  return;
759
777
  seenSrcs.add(src);
760
778
  if (!isNonRelativeUrl(src) && !isAbsolute(src) && attributes.type !== "module") {
761
- const jsPath = resolveWithinProject(projectDir, src);
779
+ const jsPath = resolveWithinProject(projectDir, decodedUrlPath(src));
762
780
  const js = jsPath ? safeReadFile(jsPath) : null;
763
781
  if (js != null) {
764
- chunks.push(() => preserveLocalScriptIntegrity(doc, src, (value) => resolveWithinProject(projectDir, value))
782
+ chunks.push(() => preserveLocalScriptIntegrity(doc, src, (value) => resolveWithinProject(projectDir, decodedUrlPath(value)))
765
783
  ? ""
766
784
  : js);
767
785
  return;
@@ -770,9 +788,21 @@ function hoistExternalScript(src, projectDir, doc, seenSrcs, chunks, attributes)
770
788
  ensureExternalScriptTag(doc, src, attributes);
771
789
  }
772
790
  function hoistCompositionScripts(container, opts) {
773
- for (const scriptEl of [...container.querySelectorAll("script")]) {
791
+ for (const scriptEl of executableScripts(container)) {
774
792
  const externalSrc = (scriptEl.getAttribute("src") || "").trim();
775
- if (externalSrc) {
793
+ const type = (scriptEl.getAttribute("type") || "").trim().toLowerCase();
794
+ if (!externalSrc && type === "importmap") {
795
+ const map = parseImportMap(scriptEl.textContent || "", (url) => url);
796
+ if (map)
797
+ opts.importMaps.push(map);
798
+ else
799
+ console.warn(`[HyperFrames] ${opts.compId}: import map is not valid JSON, so it is skipped.`);
800
+ }
801
+ else if (!externalSrc && type === "module") {
802
+ const prelude = opts.compId ? scopedModulePrelude(opts.runtimeCompId || opts.compId) : "";
803
+ opts.moduleScripts.push(prelude + (scriptEl.textContent || ""));
804
+ }
805
+ else if (externalSrc) {
776
806
  hoistExternalScript(externalSrc, opts.projectDir, opts.document, opts.seenCompScriptSrcs, opts.compScriptChunks, readExternalScriptAttributes(scriptEl));
777
807
  }
778
808
  else {
@@ -798,6 +828,7 @@ async function bundleProject(projectDir, options) {
798
828
  const resolved = resolve(sourceDir, relativePath);
799
829
  return isSafePath(projectDir, resolved) ? resolved : null;
800
830
  };
831
+ const resolveEntryUrl = (url) => resolveEntryPath(decodedUrlPath(url));
801
832
  const readSource = options?.stampHfIds ? ensureHfIds : (html) => html;
802
833
  noteRead(indexPath);
803
834
  const rawHtml = readSource(readFileSync(indexPath, "utf-8"));
@@ -819,7 +850,7 @@ async function bundleProject(projectDir, options) {
819
850
  continue;
820
851
  if (el.hasAttribute("disabled"))
821
852
  continue;
822
- const cssPath = resolveEntryPath(href);
853
+ const cssPath = resolveEntryUrl(href);
823
854
  if (!cssPath)
824
855
  continue;
825
856
  const css = safeReadFile(cssPath);
@@ -843,7 +874,7 @@ async function bundleProject(projectDir, options) {
843
874
  ]),
844
875
  ].map((el) => {
845
876
  const src = el.getAttribute("src");
846
- const path = src && isRelativeUrl(src) ? resolveEntryPath(src) : null;
877
+ const path = src && isRelativeUrl(src) ? resolveEntryUrl(src) : null;
847
878
  return src ? (path && safeReadFile(path)) || "" : el.textContent || "";
848
879
  })
849
880
  : [];
@@ -907,10 +938,10 @@ async function bundleProject(projectDir, options) {
907
938
  continue;
908
939
  seenCompScriptSrcs.add(extSrc);
909
940
  if (isRelativeUrl(extSrc) && scriptItem.type !== "module") {
910
- const jsPath = resolveEntryPath(extSrc);
941
+ const jsPath = resolveEntryUrl(extSrc);
911
942
  const js = jsPath ? safeReadFile(jsPath) : null;
912
943
  if (js != null) {
913
- const chunk = () => preserveLocalScriptIntegrity(document, extSrc, resolveEntryPath) ? "" : js;
944
+ const chunk = () => preserveLocalScriptIntegrity(document, extSrc, resolveEntryUrl) ? "" : js;
914
945
  pushRun(scriptRuns, scriptItem.scene, chunk);
915
946
  continue;
916
947
  }
@@ -937,8 +968,12 @@ async function bundleProject(projectDir, options) {
937
968
  const hostIdentity = hostIdentityByElement.get(host);
938
969
  const runtimeCompId = hostIdentity?.runtimeCompositionId || compId;
939
970
  const innerDoc = parseHTMLContent(templateHtml);
940
- const innerRoot = queryByAttr(innerDoc, "data-composition-id", compId);
941
- const authoredRootId = innerRoot?.getAttribute("id")?.trim() || null;
971
+ const plan = planCompositionAssembly({
972
+ contentNode: innerDoc,
973
+ hasTemplate: true,
974
+ compositionId: compId,
975
+ });
976
+ const { innerRoot, authoredRootId } = plan;
942
977
  const runtimeScope = runtimeCompId
943
978
  ? cssAttributeSelector("data-composition-id", runtimeCompId)
944
979
  : "";
@@ -976,6 +1011,8 @@ async function bundleProject(projectDir, options) {
976
1011
  authoredRootId: authoredRootId ?? undefined,
977
1012
  seenCompScriptSrcs,
978
1013
  compScriptChunks,
1014
+ importMaps: subCompResult.importMaps,
1015
+ moduleScripts: subCompResult.moduleScripts,
979
1016
  });
980
1017
  // Copy dimension attributes from inner root to host if not already set
981
1018
  const innerW = innerRoot.getAttribute("data-width");
@@ -1009,9 +1046,13 @@ async function bundleProject(projectDir, options) {
1009
1046
  authoredRootId: undefined,
1010
1047
  seenCompScriptSrcs,
1011
1048
  compScriptChunks,
1049
+ importMaps: subCompResult.importMaps,
1050
+ moduleScripts: subCompResult.moduleScripts,
1012
1051
  });
1013
1052
  host.innerHTML = innerDoc.body.innerHTML || "";
1014
1053
  }
1054
+ for (const el of plan.inertScriptsOutsideRoot)
1055
+ host.insertAdjacentHTML("beforeend", el.outerHTML);
1015
1056
  }
1016
1057
  // Remove the template element from the document
1017
1058
  templateEl.remove();
@@ -1020,14 +1061,14 @@ async function bundleProject(projectDir, options) {
1020
1061
  const src = el.getAttribute("src");
1021
1062
  if (!src || !isRelativeUrl(src))
1022
1063
  continue;
1023
- if (preserveLocalScriptIntegrity(document, src, resolveEntryPath))
1064
+ if (preserveLocalScriptIntegrity(document, src, resolveEntryUrl))
1024
1065
  continue;
1025
1066
  // Module scripts can contain static imports whose resolution is relative
1026
1067
  // to the script URL. Folding their source into a classic inline script
1027
1068
  // both drops module semantics and changes the import base URL.
1028
1069
  if ((el.getAttribute("type") || "").trim().toLowerCase() === "module")
1029
1070
  continue;
1030
- const jsPath = resolveEntryPath(src);
1071
+ const jsPath = resolveEntryUrl(src);
1031
1072
  const js = jsPath ? safeReadFile(jsPath) : null;
1032
1073
  if (js == null)
1033
1074
  continue;
@@ -1057,11 +1098,16 @@ async function bundleProject(projectDir, options) {
1057
1098
  }
1058
1099
  }
1059
1100
  for (const { scene, chunks } of scriptRuns) {
1060
- const script = document.createElement("script");
1061
- if (scene)
1062
- script.setAttribute(SCENE_PART_ATTR, scene);
1063
- script.textContent = joinJsChunks(chunks.map((chunk) => (typeof chunk === "string" ? chunk : chunk())));
1064
- document.body.appendChild(script);
1101
+ const texts = chunks.map((chunk) => (typeof chunk === "string" ? chunk : chunk()));
1102
+ const joined = joinJsChunks(texts);
1103
+ const skipsRunMerge = Boolean(scene);
1104
+ for (const text of parsesAsScript(joined) ? [joined] : texts.filter(Boolean)) {
1105
+ const script = document.createElement("script");
1106
+ if (scene)
1107
+ script.setAttribute(SCENE_PART_ATTR, scene);
1108
+ script.textContent = skipsRunMerge ? inlineScriptSource(text) : text;
1109
+ document.body.appendChild(script);
1110
+ }
1065
1111
  }
1066
1112
  emitMountedModuleScripts(document, subCompResult.importMaps, subCompResult.moduleScripts);
1067
1113
  emitRootCompositionVariableStyles(document, compVariablesByComp);