hyperframes 0.8.74 → 0.8.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2083 -1458
- package/dist/fontLocalizeCli.js +255 -108
- package/dist/hyperframe-runtime.js +70 -62
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +70 -62
- package/dist/hyperframes-player.global.js +3 -3
- package/dist/renderSetupWorker.js +113 -119
- package/dist/skills/hyperframes-cli/SKILL.md +2 -2
- package/dist/studio/assets/hyperframes-player-BkDxgSKG.js +464 -0
- package/dist/studio/assets/{index-vccPjvCl.js → index-COX0scwJ.js} +1 -1
- package/dist/studio/assets/{index-DhTyI9zH.js → index-DeHir1up.js} +178 -178
- package/dist/studio/assets/{index-B86QTmD2.js → index-FmKUmYhC.js} +1 -1
- package/dist/studio/{chunk-7BP32G62.js → chunk-IYDE66BY.js} +6 -1
- package/dist/studio/chunk-IYDE66BY.js.map +1 -0
- package/dist/studio/{domEditingLayers-UKMVYXT6.js → domEditingLayers-2XBFXXSW.js} +4 -2
- package/dist/studio/index.d.ts +35 -70
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +4518 -4568
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/studio/assets/hyperframes-player-Bs9qG2hg.js +0 -464
- package/dist/studio/chunk-7BP32G62.js.map +0 -1
- /package/dist/studio/{domEditingLayers-UKMVYXT6.js.map → domEditingLayers-2XBFXXSW.js.map} +0 -0
package/dist/fontLocalizeCli.js
CHANGED
|
@@ -66166,6 +66166,8 @@ function readExternalScriptAttributes(el) {
|
|
|
66166
66166
|
attributes2.integrity = el.getAttribute("integrity") || "";
|
|
66167
66167
|
if (el.hasAttribute("crossorigin"))
|
|
66168
66168
|
attributes2.crossorigin = el.getAttribute("crossorigin") || "";
|
|
66169
|
+
if ((el.getAttribute("type") || "").trim().toLowerCase() === "module")
|
|
66170
|
+
attributes2.type = "module";
|
|
66169
66171
|
return attributes2;
|
|
66170
66172
|
}
|
|
66171
66173
|
function ensureExternalScriptTag(doc, src, attributes2 = {}) {
|
|
@@ -66181,6 +66183,8 @@ function ensureExternalScriptTag(doc, src, attributes2 = {}) {
|
|
|
66181
66183
|
el.setAttribute("integrity", integrity);
|
|
66182
66184
|
if (attributes2.crossorigin !== void 0)
|
|
66183
66185
|
el.setAttribute("crossorigin", attributes2.crossorigin);
|
|
66186
|
+
if (attributes2.type)
|
|
66187
|
+
el.setAttribute("type", attributes2.type);
|
|
66184
66188
|
}
|
|
66185
66189
|
if (!existing.length) {
|
|
66186
66190
|
const el = elements[0];
|
|
@@ -66194,6 +66198,80 @@ var init_externalScripts = __esm({
|
|
|
66194
66198
|
}
|
|
66195
66199
|
});
|
|
66196
66200
|
|
|
66201
|
+
// ../core/dist/compiler/importMaps.js
|
|
66202
|
+
function parseImportMap(json, rebase) {
|
|
66203
|
+
let parsed;
|
|
66204
|
+
try {
|
|
66205
|
+
parsed = JSON.parse(json);
|
|
66206
|
+
} catch {
|
|
66207
|
+
return null;
|
|
66208
|
+
}
|
|
66209
|
+
if (!parsed || typeof parsed !== "object")
|
|
66210
|
+
return null;
|
|
66211
|
+
const { imports, scopes } = parsed;
|
|
66212
|
+
return {
|
|
66213
|
+
imports: rebaseEntries(imports, rebase),
|
|
66214
|
+
scopes: scopes && Object.fromEntries(Object.entries(scopes).map(([prefix, entries2]) => [
|
|
66215
|
+
rebase(prefix),
|
|
66216
|
+
rebaseEntries(entries2, rebase) ?? {}
|
|
66217
|
+
]))
|
|
66218
|
+
};
|
|
66219
|
+
}
|
|
66220
|
+
function mergeEntries(into, from, where) {
|
|
66221
|
+
for (const [specifier, url] of Object.entries(from ?? {})) {
|
|
66222
|
+
if (!(specifier in into))
|
|
66223
|
+
into[specifier] = url;
|
|
66224
|
+
else if (into[specifier] !== url) {
|
|
66225
|
+
console.warn(`[HyperFrames] import map conflict for "${specifier}"${where}: keeping ${into[specifier]}, ignoring ${url}.`);
|
|
66226
|
+
}
|
|
66227
|
+
}
|
|
66228
|
+
}
|
|
66229
|
+
function mergeImportMapsIntoDocument(doc, maps) {
|
|
66230
|
+
if (maps.length === 0)
|
|
66231
|
+
return;
|
|
66232
|
+
let el = doc.querySelector('script[type="importmap"]');
|
|
66233
|
+
let page = {};
|
|
66234
|
+
try {
|
|
66235
|
+
page = el ? JSON.parse(el.textContent || "{}") : {};
|
|
66236
|
+
} catch {
|
|
66237
|
+
console.warn("[HyperFrames] the page's import map is not valid JSON; replacing it.");
|
|
66238
|
+
}
|
|
66239
|
+
const imports = { ...page.imports };
|
|
66240
|
+
const scopes = { ...page.scopes };
|
|
66241
|
+
for (const map of maps) {
|
|
66242
|
+
mergeEntries(imports, map.imports, "");
|
|
66243
|
+
for (const [prefix, entries2] of Object.entries(map.scopes ?? {})) {
|
|
66244
|
+
mergeEntries(scopes[prefix] ??= {}, entries2, ` in scope ${prefix}`);
|
|
66245
|
+
}
|
|
66246
|
+
}
|
|
66247
|
+
if (!el) {
|
|
66248
|
+
el = doc.createElement("script");
|
|
66249
|
+
el.setAttribute("type", "importmap");
|
|
66250
|
+
doc.head.prepend(el);
|
|
66251
|
+
}
|
|
66252
|
+
el.textContent = JSON.stringify({
|
|
66253
|
+
...page,
|
|
66254
|
+
imports,
|
|
66255
|
+
...Object.keys(scopes).length ? { scopes } : {}
|
|
66256
|
+
}).replace(/</g, "\\u003c");
|
|
66257
|
+
}
|
|
66258
|
+
function emitMountedModuleScripts(doc, importMaps, moduleScripts) {
|
|
66259
|
+
mergeImportMapsIntoDocument(doc, importMaps);
|
|
66260
|
+
for (const content of moduleScripts) {
|
|
66261
|
+
const el = doc.createElement("script");
|
|
66262
|
+
el.setAttribute("type", "module");
|
|
66263
|
+
el.textContent = content;
|
|
66264
|
+
doc.body.appendChild(el);
|
|
66265
|
+
}
|
|
66266
|
+
}
|
|
66267
|
+
var rebaseEntries;
|
|
66268
|
+
var init_importMaps = __esm({
|
|
66269
|
+
"../core/dist/compiler/importMaps.js"() {
|
|
66270
|
+
"use strict";
|
|
66271
|
+
rebaseEntries = (entries2, rebase) => entries2 && Object.fromEntries(Object.entries(entries2).map(([specifier, url]) => [specifier, rebase(url)]));
|
|
66272
|
+
}
|
|
66273
|
+
});
|
|
66274
|
+
|
|
66197
66275
|
// ../core/dist/runtime/flattenedRoot.js
|
|
66198
66276
|
function markFlattenedInnerRoot(prepared) {
|
|
66199
66277
|
const authoredRootId = prepared.getAttribute("id")?.trim();
|
|
@@ -66642,7 +66720,13 @@ function scopeCssToComposition(css, compositionId, scopeSelectorOverride, author
|
|
|
66642
66720
|
function jsonScriptLiteral(value) {
|
|
66643
66721
|
return JSON.stringify(value).replace(/</g, "\\u003c");
|
|
66644
66722
|
}
|
|
66645
|
-
function
|
|
66723
|
+
function scopedModulePrelude(timelineCompositionId, compositionSrc) {
|
|
66724
|
+
return `const __hyperframes = (function(__hfBaseHyperframes, __hfTimelineCompId, __hfCompositionSrc) {
|
|
66725
|
+
return ${SCOPED_HYPERFRAMES_EXPRESSION};
|
|
66726
|
+
})(window.__hyperframes, ${jsonScriptLiteral(timelineCompositionId)}, ${jsonScriptLiteral(compositionSrc?.trim() || null)});
|
|
66727
|
+
`;
|
|
66728
|
+
}
|
|
66729
|
+
function wrapScopedCompositionScript(source, compositionId, errorLabel = "[HyperFrames] composition script error:", scopeSelectorOverride, timelineCompositionId = compositionId, authoredRootId, compositionSrc) {
|
|
66646
66730
|
const compositionIdLiteral = jsonScriptLiteral(compositionId);
|
|
66647
66731
|
const timelineCompositionIdLiteral = jsonScriptLiteral(timelineCompositionId);
|
|
66648
66732
|
const errorLabelLiteral = jsonScriptLiteral(errorLabel);
|
|
@@ -66657,6 +66741,7 @@ function wrapScopedCompositionScript(source, compositionId, errorLabel = "[Hyper
|
|
|
66657
66741
|
var __hfTimelineCompId = ${timelineCompositionIdLiteral};
|
|
66658
66742
|
var __hfErrorLabel = ${errorLabelLiteral};
|
|
66659
66743
|
var __hfAuthoredRootId = ${authoredRootIdLiteral};
|
|
66744
|
+
var __hfCompositionSrc = ${jsonScriptLiteral(compositionSrc?.trim() || null)};
|
|
66660
66745
|
var __hfAuthoredRootAttr = ${jsonScriptLiteral(AUTHORED_ROOT_ID_ATTR)};
|
|
66661
66746
|
var __hfEscapeAttr = function(value) {
|
|
66662
66747
|
return (value + "").replace(/\\\\/g, "\\\\\\\\").replace(/"/g, "\\\\\\"");
|
|
@@ -66962,15 +67047,7 @@ function wrapScopedCompositionScript(source, compositionId, errorLabel = "[Hyper
|
|
|
66962
67047
|
},
|
|
66963
67048
|
});
|
|
66964
67049
|
var __hfBaseHyperframes = window.__hyperframes;
|
|
66965
|
-
var __hfScopedHyperframes =
|
|
66966
|
-
? __hfBaseHyperframes
|
|
66967
|
-
: Object.assign({}, __hfBaseHyperframes, {
|
|
66968
|
-
getVariables: function() {
|
|
66969
|
-
var byComp = window.__hfVariablesByComp;
|
|
66970
|
-
var scoped = byComp && __hfTimelineCompId ? byComp[__hfTimelineCompId] : null;
|
|
66971
|
-
return scoped ? Object.assign({}, scoped) : {};
|
|
66972
|
-
},
|
|
66973
|
-
});
|
|
67050
|
+
var __hfScopedHyperframes = ${SCOPED_HYPERFRAMES_EXPRESSION};
|
|
66974
67051
|
var __hfRun = function() {
|
|
66975
67052
|
try {
|
|
66976
67053
|
(function(document, gsap, window, __hyperframes) {
|
|
@@ -66993,13 +67070,26 @@ function buildVariablesByCompScript(variablesByComp) {
|
|
|
66993
67070
|
const json = jsonScriptLiteral(variablesByComp);
|
|
66994
67071
|
return `window.__hfVariablesByComp = Object.assign({}, window.__hfVariablesByComp || {}, ${json});`;
|
|
66995
67072
|
}
|
|
66996
|
-
var AUTHORED_ROOT_ID_ATTR, INNER_ROOT_ATTR, GLOBAL_AT_RULES;
|
|
67073
|
+
var AUTHORED_ROOT_ID_ATTR, INNER_ROOT_ATTR, GLOBAL_AT_RULES, SCOPED_HYPERFRAMES_EXPRESSION;
|
|
66997
67074
|
var init_compositionScoping = __esm({
|
|
66998
67075
|
"../core/dist/compiler/compositionScoping.js"() {
|
|
66999
67076
|
"use strict";
|
|
67000
67077
|
AUTHORED_ROOT_ID_ATTR = "data-hf-authored-id";
|
|
67001
67078
|
INNER_ROOT_ATTR = "data-hf-inner-root";
|
|
67002
67079
|
GLOBAL_AT_RULES = /* @__PURE__ */ new Set(["keyframes", "-webkit-keyframes", "font-face"]);
|
|
67080
|
+
SCOPED_HYPERFRAMES_EXPRESSION = `!__hfBaseHyperframes
|
|
67081
|
+
? __hfBaseHyperframes
|
|
67082
|
+
: Object.assign({}, __hfBaseHyperframes, {
|
|
67083
|
+
assetUrl: function(path) {
|
|
67084
|
+
var page = window.document.baseURI;
|
|
67085
|
+
return new URL(path, __hfCompositionSrc ? new URL(__hfCompositionSrc, page) : page).href;
|
|
67086
|
+
},
|
|
67087
|
+
getVariables: function() {
|
|
67088
|
+
var byComp = window.__hfVariablesByComp;
|
|
67089
|
+
var scoped = byComp && __hfTimelineCompId ? byComp[__hfTimelineCompId] : null;
|
|
67090
|
+
return scoped ? Object.assign({}, scoped) : {};
|
|
67091
|
+
},
|
|
67092
|
+
})`;
|
|
67003
67093
|
}
|
|
67004
67094
|
});
|
|
67005
67095
|
|
|
@@ -72428,6 +72518,13 @@ function parseGsapScriptAcornForWrite(script) {
|
|
|
72428
72518
|
}
|
|
72429
72519
|
}
|
|
72430
72520
|
function parseGsapScriptAcorn(script) {
|
|
72521
|
+
const parsed = parseMemo.get(script) ?? parseGsapScriptAcornUncached(script);
|
|
72522
|
+
parseMemo.delete(script);
|
|
72523
|
+
parseMemo.set(script, parsed);
|
|
72524
|
+
if (parseMemo.size > PARSE_MEMO_ENTRIES) parseMemo.delete(parseMemo.keys().next().value);
|
|
72525
|
+
return structuredClone(parsed);
|
|
72526
|
+
}
|
|
72527
|
+
function parseGsapScriptAcornUncached(script) {
|
|
72431
72528
|
try {
|
|
72432
72529
|
const ast = parseProgram3(script);
|
|
72433
72530
|
const scope = collectScopeBindings(ast);
|
|
@@ -72575,7 +72672,7 @@ function extractGsapLabels(script) {
|
|
|
72575
72672
|
return [];
|
|
72576
72673
|
}
|
|
72577
72674
|
}
|
|
72578
|
-
var PROPERTY_GROUPS2, PROP_TO_GROUP2, SKIP_KEYS, FUNCTION_TYPES, GSAP_METHODS, MAX_DEPTH, MAX_ITERS, SAFE_DEFAULT_NODES, SUPPORTED_PARAMS_CACHE, roundPercentage, GSAP_METHODS2, QUERY_METHODS, ITERATION_METHODS, SCOPE_NODE_TYPES, CONST_NODES, MATH_FNS, MATH_CONSTS, BUILTIN_VAR_KEYS, DROPPED_VAR_KEYS, EXTRAS_KEYS, PERCENTAGE_KEY_RE, GSAP_DEFAULT_DURATION;
|
|
72675
|
+
var PROPERTY_GROUPS2, PROP_TO_GROUP2, SKIP_KEYS, FUNCTION_TYPES, GSAP_METHODS, MAX_DEPTH, MAX_ITERS, SAFE_DEFAULT_NODES, SUPPORTED_PARAMS_CACHE, roundPercentage, GSAP_METHODS2, QUERY_METHODS, ITERATION_METHODS, SCOPE_NODE_TYPES, CONST_NODES, MATH_FNS, MATH_CONSTS, BUILTIN_VAR_KEYS, DROPPED_VAR_KEYS, EXTRAS_KEYS, PERCENTAGE_KEY_RE, GSAP_DEFAULT_DURATION, PARSE_MEMO_ENTRIES, parseMemo;
|
|
72579
72676
|
var init_gsapParserAcorn = __esm({
|
|
72580
72677
|
"../parsers/dist/gsapParserAcorn.js"() {
|
|
72581
72678
|
"use strict";
|
|
@@ -72655,6 +72752,8 @@ var init_gsapParserAcorn = __esm({
|
|
|
72655
72752
|
]);
|
|
72656
72753
|
PERCENTAGE_KEY_RE = /^(\d+(?:\.\d+)?)%$/;
|
|
72657
72754
|
GSAP_DEFAULT_DURATION = 0.5;
|
|
72755
|
+
PARSE_MEMO_ENTRIES = 4;
|
|
72756
|
+
parseMemo = /* @__PURE__ */ new Map();
|
|
72658
72757
|
}
|
|
72659
72758
|
});
|
|
72660
72759
|
|
|
@@ -74206,6 +74305,81 @@ function collectDeclaredVariableIds(htmlTagRaw) {
|
|
|
74206
74305
|
}
|
|
74207
74306
|
return declared;
|
|
74208
74307
|
}
|
|
74308
|
+
function variablesDeclarationFindings(tag, tags) {
|
|
74309
|
+
const raw = readJsonAttr(tag.raw, "data-composition-variables");
|
|
74310
|
+
if (!raw) return [];
|
|
74311
|
+
let parsed;
|
|
74312
|
+
try {
|
|
74313
|
+
parsed = JSON.parse(raw);
|
|
74314
|
+
} catch (err) {
|
|
74315
|
+
const reason = err instanceof Error ? err.message : "unknown";
|
|
74316
|
+
return [
|
|
74317
|
+
{
|
|
74318
|
+
code: "invalid_composition_variables_declaration",
|
|
74319
|
+
severity: "error",
|
|
74320
|
+
message: `data-composition-variables is not valid JSON (${reason}).`,
|
|
74321
|
+
fixHint: `Provide a JSON array of variable declarations: data-composition-variables='[{"id":"title","type":"string","label":"Title","default":"Hello"}]'.`,
|
|
74322
|
+
snippet: truncateSnippet(tag.raw)
|
|
74323
|
+
}
|
|
74324
|
+
];
|
|
74325
|
+
}
|
|
74326
|
+
if (!Array.isArray(parsed)) {
|
|
74327
|
+
return [
|
|
74328
|
+
{
|
|
74329
|
+
code: "invalid_composition_variables_declaration",
|
|
74330
|
+
severity: "error",
|
|
74331
|
+
message: "data-composition-variables must be a JSON array of variable declarations.",
|
|
74332
|
+
fixHint: `Wrap declarations in [] and give each an id, type, label, and default: '[{"id":"title","type":"string","label":"Title","default":"Hello"}]'.`,
|
|
74333
|
+
snippet: truncateSnippet(tag.raw)
|
|
74334
|
+
}
|
|
74335
|
+
];
|
|
74336
|
+
}
|
|
74337
|
+
const findings = [];
|
|
74338
|
+
const knownTypes = new Set(COMPOSITION_VARIABLE_TYPES2);
|
|
74339
|
+
const varSrcIds = /* @__PURE__ */ new Set();
|
|
74340
|
+
for (const other of tags) {
|
|
74341
|
+
const bound = readAttr(other.raw, "data-var-src");
|
|
74342
|
+
if (bound) varSrcIds.add(bound);
|
|
74343
|
+
}
|
|
74344
|
+
for (let i = 0; i < parsed.length; i += 1) {
|
|
74345
|
+
const entry = parsed[i];
|
|
74346
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
74347
|
+
findings.push({
|
|
74348
|
+
code: "invalid_composition_variables_declaration",
|
|
74349
|
+
severity: "error",
|
|
74350
|
+
message: `data-composition-variables entry [${i}] must be an object with id, type, label, and default.`,
|
|
74351
|
+
snippet: truncateSnippet(tag.raw)
|
|
74352
|
+
});
|
|
74353
|
+
continue;
|
|
74354
|
+
}
|
|
74355
|
+
const e = entry;
|
|
74356
|
+
const missing = [];
|
|
74357
|
+
if (typeof e.id !== "string") missing.push("id");
|
|
74358
|
+
if (typeof e.type !== "string" || !knownTypes.has(e.type)) missing.push("type");
|
|
74359
|
+
if (typeof e.label !== "string") missing.push("label");
|
|
74360
|
+
if (!("default" in e)) missing.push("default");
|
|
74361
|
+
if (missing.length > 0) {
|
|
74362
|
+
findings.push({
|
|
74363
|
+
code: "invalid_composition_variables_declaration",
|
|
74364
|
+
severity: "error",
|
|
74365
|
+
message: `data-composition-variables entry [${i}] is missing or has invalid: ${missing.join(", ")}. Type must be one of string, number, color, boolean, enum, font, image.`,
|
|
74366
|
+
snippet: truncateSnippet(tag.raw)
|
|
74367
|
+
});
|
|
74368
|
+
continue;
|
|
74369
|
+
}
|
|
74370
|
+
const id = String(e.id);
|
|
74371
|
+
if ((e.type === "image" || varSrcIds.has(id)) && typeof e.default === "string" && e.default.length > 0 && !isSafeMediaUrl(e.default)) {
|
|
74372
|
+
findings.push({
|
|
74373
|
+
code: "unloadable_media_variable_default",
|
|
74374
|
+
severity: "error",
|
|
74375
|
+
message: `Variable "${id}" defaults to a URL the runtime will refuse to load, so any element bound to it renders its authored fallback src instead and the render still exits 0.`,
|
|
74376
|
+
fixHint: `Media URLs must be relative, http(s), blob:, or a data:image/* URI. Copy the file into the project and reference it relatively (e.g. "assets/bg.png") rather than by absolute path.`,
|
|
74377
|
+
snippet: truncateSnippet(tag.raw)
|
|
74378
|
+
});
|
|
74379
|
+
}
|
|
74380
|
+
}
|
|
74381
|
+
return findings;
|
|
74382
|
+
}
|
|
74209
74383
|
function collectAllDeclaredVariableIds(tags) {
|
|
74210
74384
|
const all = /* @__PURE__ */ new Set();
|
|
74211
74385
|
for (const tag of tags) {
|
|
@@ -76664,84 +76838,8 @@ var init_dist3 = __esm({
|
|
|
76664
76838
|
// on any structural problem. Surface JSON / shape failures so authors
|
|
76665
76839
|
// catch them at lint time rather than wondering why their `getVariables()`
|
|
76666
76840
|
// defaults aren't applied.
|
|
76667
|
-
//
|
|
76668
|
-
({ tags }) =>
|
|
76669
|
-
const htmlTag = findHtmlTag(tags);
|
|
76670
|
-
if (!htmlTag) return [];
|
|
76671
|
-
const raw = readJsonAttr(htmlTag.raw, "data-composition-variables");
|
|
76672
|
-
if (!raw) return [];
|
|
76673
|
-
let parsed;
|
|
76674
|
-
try {
|
|
76675
|
-
parsed = JSON.parse(raw);
|
|
76676
|
-
} catch (err) {
|
|
76677
|
-
const reason = err instanceof Error ? err.message : "unknown";
|
|
76678
|
-
return [
|
|
76679
|
-
{
|
|
76680
|
-
code: "invalid_composition_variables_declaration",
|
|
76681
|
-
severity: "error",
|
|
76682
|
-
message: `data-composition-variables is not valid JSON (${reason}).`,
|
|
76683
|
-
fixHint: `Provide a JSON array of variable declarations: data-composition-variables='[{"id":"title","type":"string","label":"Title","default":"Hello"}]'.`,
|
|
76684
|
-
snippet: truncateSnippet(htmlTag.raw)
|
|
76685
|
-
}
|
|
76686
|
-
];
|
|
76687
|
-
}
|
|
76688
|
-
if (!Array.isArray(parsed)) {
|
|
76689
|
-
return [
|
|
76690
|
-
{
|
|
76691
|
-
code: "invalid_composition_variables_declaration",
|
|
76692
|
-
severity: "error",
|
|
76693
|
-
message: "data-composition-variables must be a JSON array of variable declarations.",
|
|
76694
|
-
fixHint: `Wrap declarations in [] and give each an id, type, label, and default: '[{"id":"title","type":"string","label":"Title","default":"Hello"}]'.`,
|
|
76695
|
-
snippet: truncateSnippet(htmlTag.raw)
|
|
76696
|
-
}
|
|
76697
|
-
];
|
|
76698
|
-
}
|
|
76699
|
-
const findings = [];
|
|
76700
|
-
const knownTypes = new Set(COMPOSITION_VARIABLE_TYPES2);
|
|
76701
|
-
const varSrcIds = /* @__PURE__ */ new Set();
|
|
76702
|
-
for (const tag of tags) {
|
|
76703
|
-
const bound = readAttr(tag.raw, "data-var-src");
|
|
76704
|
-
if (bound) varSrcIds.add(bound);
|
|
76705
|
-
}
|
|
76706
|
-
for (let i = 0; i < parsed.length; i += 1) {
|
|
76707
|
-
const entry = parsed[i];
|
|
76708
|
-
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
76709
|
-
findings.push({
|
|
76710
|
-
code: "invalid_composition_variables_declaration",
|
|
76711
|
-
severity: "error",
|
|
76712
|
-
message: `data-composition-variables entry [${i}] must be an object with id, type, label, and default.`,
|
|
76713
|
-
snippet: truncateSnippet(htmlTag.raw)
|
|
76714
|
-
});
|
|
76715
|
-
continue;
|
|
76716
|
-
}
|
|
76717
|
-
const e = entry;
|
|
76718
|
-
const missing = [];
|
|
76719
|
-
if (typeof e.id !== "string") missing.push("id");
|
|
76720
|
-
if (typeof e.type !== "string" || !knownTypes.has(e.type)) missing.push("type");
|
|
76721
|
-
if (typeof e.label !== "string") missing.push("label");
|
|
76722
|
-
if (!("default" in e)) missing.push("default");
|
|
76723
|
-
if (missing.length > 0) {
|
|
76724
|
-
findings.push({
|
|
76725
|
-
code: "invalid_composition_variables_declaration",
|
|
76726
|
-
severity: "error",
|
|
76727
|
-
message: `data-composition-variables entry [${i}] is missing or has invalid: ${missing.join(", ")}. Type must be one of string, number, color, boolean, enum, font, image.`,
|
|
76728
|
-
snippet: truncateSnippet(htmlTag.raw)
|
|
76729
|
-
});
|
|
76730
|
-
continue;
|
|
76731
|
-
}
|
|
76732
|
-
const id = String(e.id);
|
|
76733
|
-
if ((e.type === "image" || varSrcIds.has(id)) && typeof e.default === "string" && e.default.length > 0 && !isSafeMediaUrl(e.default)) {
|
|
76734
|
-
findings.push({
|
|
76735
|
-
code: "unloadable_media_variable_default",
|
|
76736
|
-
severity: "error",
|
|
76737
|
-
message: `Variable "${id}" defaults to a URL the runtime will refuse to load, so any element bound to it renders its authored fallback src instead and the render still exits 0.`,
|
|
76738
|
-
fixHint: `Media URLs must be relative, http(s), blob:, or a data:image/* URI. Copy the file into the project and reference it relatively (e.g. "assets/bg.png") rather than by absolute path.`,
|
|
76739
|
-
snippet: truncateSnippet(htmlTag.raw)
|
|
76740
|
-
});
|
|
76741
|
-
}
|
|
76742
|
-
}
|
|
76743
|
-
return findings;
|
|
76744
|
-
},
|
|
76841
|
+
// Checked on every element that declares: <html>, or the composition root.
|
|
76842
|
+
({ tags }) => tags.filter((tag) => readJsonAttr(tag.raw, "data-composition-variables")).flatMap((tag) => variablesDeclarationFindings(tag, tags)),
|
|
76745
76843
|
// html_dir_attribute_breaks_render — valid non-LTR dir values on
|
|
76746
76844
|
// <html> renders correctly in preview/snapshot but produces a fully
|
|
76747
76845
|
// blank/black video from render, with no other lint/validate/inspect
|
|
@@ -78753,6 +78851,8 @@ function inlineSubCompositions(document2, hosts, options) {
|
|
|
78753
78851
|
const scripts = [];
|
|
78754
78852
|
const externalScriptSrcs = [];
|
|
78755
78853
|
const scriptItems = [];
|
|
78854
|
+
const importMaps = [];
|
|
78855
|
+
const moduleScripts = [];
|
|
78756
78856
|
const externalLinks = [];
|
|
78757
78857
|
const seenLinkHrefs = /* @__PURE__ */ new Set();
|
|
78758
78858
|
const variablesByComp = {};
|
|
@@ -78840,7 +78940,24 @@ function inlineSubCompositions(document2, hosts, options) {
|
|
|
78840
78940
|
}
|
|
78841
78941
|
for (const scriptEl of plan2.scriptSources) {
|
|
78842
78942
|
const externalSrc = resolveSubAssetPath(scriptEl.getAttribute("src"));
|
|
78843
|
-
|
|
78943
|
+
const type = (scriptEl.getAttribute("type") || "").trim().toLowerCase();
|
|
78944
|
+
if (type === "importmap") {
|
|
78945
|
+
const map = parseImportMap(scriptEl.textContent || "", (url) => {
|
|
78946
|
+
const authored = url.trim();
|
|
78947
|
+
const rebased = resolveSubAssetPath(authored);
|
|
78948
|
+
if (rebased === authored)
|
|
78949
|
+
return rebased;
|
|
78950
|
+
const urlLike = /^(\/|\.\.?\/|[a-z][a-z\d+.-]*:)/i.test(rebased) ? rebased : `./${rebased}`;
|
|
78951
|
+
return authored.endsWith("/") && !urlLike.endsWith("/") ? `${urlLike}/` : urlLike;
|
|
78952
|
+
});
|
|
78953
|
+
if (map)
|
|
78954
|
+
importMaps.push(map);
|
|
78955
|
+
else
|
|
78956
|
+
console.warn(`[HyperFrames] ${src}: import map is not valid JSON, so it is skipped.`);
|
|
78957
|
+
} else if (type === "module" && !externalSrc) {
|
|
78958
|
+
const prelude = scriptCompositionId ? scopedModulePrelude(runtimeCompId || scopeCompId || scriptCompositionId, src) : "";
|
|
78959
|
+
moduleScripts.push(prelude + (scriptEl.textContent || ""));
|
|
78960
|
+
} else if (externalSrc) {
|
|
78844
78961
|
if (!externalScriptSrcs.includes(externalSrc)) {
|
|
78845
78962
|
externalScriptSrcs.push(externalSrc);
|
|
78846
78963
|
}
|
|
@@ -78850,7 +78967,7 @@ function inlineSubCompositions(document2, hosts, options) {
|
|
|
78850
78967
|
...readExternalScriptAttributes(scriptEl)
|
|
78851
78968
|
});
|
|
78852
78969
|
} else {
|
|
78853
|
-
const wrappedScript = scriptCompositionId ? wrapScopedCompositionScript(scriptEl.textContent || "", scriptCompositionId, scriptErrorLabel, runtimeScope || void 0, runtimeCompId || scopeCompId || scriptCompositionId, authoredRootId) : wrapInlineScriptWithErrorBoundary(scriptEl.textContent || "", scriptErrorLabel);
|
|
78970
|
+
const wrappedScript = scriptCompositionId ? wrapScopedCompositionScript(scriptEl.textContent || "", scriptCompositionId, scriptErrorLabel, runtimeScope || void 0, runtimeCompId || scopeCompId || scriptCompositionId, authoredRootId, src) : wrapInlineScriptWithErrorBoundary(scriptEl.textContent || "", scriptErrorLabel);
|
|
78854
78971
|
scripts.push(wrappedScript);
|
|
78855
78972
|
scriptItems.push({ kind: "inline", content: wrappedScript });
|
|
78856
78973
|
}
|
|
@@ -78911,12 +79028,22 @@ function inlineSubCompositions(document2, hosts, options) {
|
|
|
78911
79028
|
queue.push({ element: nestedHost.host, ancestry: nestedAncestry });
|
|
78912
79029
|
}
|
|
78913
79030
|
}
|
|
78914
|
-
return {
|
|
79031
|
+
return {
|
|
79032
|
+
styles,
|
|
79033
|
+
scripts,
|
|
79034
|
+
externalScriptSrcs,
|
|
79035
|
+
scriptItems,
|
|
79036
|
+
externalLinks,
|
|
79037
|
+
variablesByComp,
|
|
79038
|
+
importMaps,
|
|
79039
|
+
moduleScripts
|
|
79040
|
+
};
|
|
78915
79041
|
}
|
|
78916
79042
|
var init_inlineSubCompositions = __esm({
|
|
78917
79043
|
"../core/dist/compiler/inlineSubCompositions.js"() {
|
|
78918
79044
|
"use strict";
|
|
78919
79045
|
init_externalScripts();
|
|
79046
|
+
init_importMaps();
|
|
78920
79047
|
init_rewriteSubCompPaths();
|
|
78921
79048
|
init_getVariables();
|
|
78922
79049
|
init_compositionScoping();
|
|
@@ -79108,6 +79235,7 @@ var init_htmlBundler = __esm({
|
|
|
79108
79235
|
"use strict";
|
|
79109
79236
|
init_scriptRuns();
|
|
79110
79237
|
init_externalScripts();
|
|
79238
|
+
init_importMaps();
|
|
79111
79239
|
init_flattenedRoot();
|
|
79112
79240
|
init_flattenedRoot();
|
|
79113
79241
|
init_getVariables();
|
|
@@ -79155,6 +79283,7 @@ var init_compiler = __esm({
|
|
|
79155
79283
|
init_assetPaths();
|
|
79156
79284
|
init_mediaRenderIds();
|
|
79157
79285
|
init_externalScripts();
|
|
79286
|
+
init_importMaps();
|
|
79158
79287
|
}
|
|
79159
79288
|
});
|
|
79160
79289
|
|
|
@@ -85258,6 +85387,7 @@ __export(src_exports, {
|
|
|
85258
85387
|
scaleProtocolTimeoutForComposition: () => scaleProtocolTimeoutForComposition,
|
|
85259
85388
|
selectVerifySampleIndicesForTask: () => selectVerifySampleIndicesForTask,
|
|
85260
85389
|
shouldClampToScreenshotForConcreteGpu: () => shouldClampToScreenshotForConcreteGpu,
|
|
85390
|
+
shouldDisableBrowserPoolForParallelWorker: () => shouldDisableBrowserPoolForParallelWorker,
|
|
85261
85391
|
showVideoElements: () => showVideoElements,
|
|
85262
85392
|
spawnStreamingEncoder: () => spawnStreamingEncoder,
|
|
85263
85393
|
syncVideoFrameVisibility: () => syncVideoFrameVisibility,
|
|
@@ -92366,13 +92496,19 @@ function defaultSessionFactory(input) {
|
|
|
92366
92496
|
let probeSession = input.probeSession;
|
|
92367
92497
|
return {
|
|
92368
92498
|
create: async () => {
|
|
92369
|
-
const session = probeSession
|
|
92499
|
+
const session = probeSession ?? await openSegmentedSession(input);
|
|
92370
92500
|
if (probeSession) {
|
|
92371
92501
|
openSegmentedSessionReuse(input, probeSession);
|
|
92372
92502
|
probeSession = null;
|
|
92373
92503
|
}
|
|
92374
|
-
|
|
92375
|
-
|
|
92504
|
+
try {
|
|
92505
|
+
if (!session.isInitialized) await initializeSession(session);
|
|
92506
|
+
await completeDeferredDrawElementInit(session);
|
|
92507
|
+
} catch (error) {
|
|
92508
|
+
await closeCaptureSession(session).catch(() => {
|
|
92509
|
+
});
|
|
92510
|
+
throw error;
|
|
92511
|
+
}
|
|
92376
92512
|
return session;
|
|
92377
92513
|
}
|
|
92378
92514
|
};
|
|
@@ -92383,16 +92519,19 @@ function openSegmentedSessionReuse(input, session) {
|
|
|
92383
92519
|
async function openSegmentedSession(input) {
|
|
92384
92520
|
const captureCfg = input.cfg.forceScreenshot === input.plan.forceScreenshot ? input.cfg : { ...input.cfg, forceScreenshot: input.plan.forceScreenshot };
|
|
92385
92521
|
const videoInjector = input.createRenderVideoFrameInjector();
|
|
92386
|
-
|
|
92387
|
-
|
|
92388
|
-
|
|
92389
|
-
|
|
92522
|
+
const captureOptions = input.buildCaptureOptions();
|
|
92523
|
+
const ownBrowser = shouldDisableBrowserPoolForParallelWorker({
|
|
92524
|
+
parallel: (input.workerCount ?? 1) > 1,
|
|
92525
|
+
platform: process.platform,
|
|
92526
|
+
deviceScaleFactor: captureOptions.deviceScaleFactor,
|
|
92527
|
+
headlessShellPath: resolveHeadlessShellPath(captureCfg)
|
|
92528
|
+
});
|
|
92390
92529
|
return createCaptureSession(
|
|
92391
92530
|
input.fileServer.url,
|
|
92392
92531
|
input.framesDir,
|
|
92393
|
-
|
|
92532
|
+
captureOptions,
|
|
92394
92533
|
videoInjector,
|
|
92395
|
-
captureCfg
|
|
92534
|
+
ownBrowser ? { ...captureCfg, enableBrowserPool: false } : captureCfg
|
|
92396
92535
|
);
|
|
92397
92536
|
}
|
|
92398
92537
|
async function concatSegments(concat, segmentPaths, videoOnlyPath, abortSignal, cfg) {
|
|
@@ -92405,7 +92544,7 @@ async function concatSegments(concat, segmentPaths, videoOnlyPath, abortSignal,
|
|
|
92405
92544
|
}
|
|
92406
92545
|
async function createSegmentWorker(run, id) {
|
|
92407
92546
|
const { input, deps } = run;
|
|
92408
|
-
const factory = input.sessionFactoryForWorker?.(id) ??
|
|
92547
|
+
const factory = input.sessionFactoryForWorker?.(id) ?? run.sessionFactory;
|
|
92409
92548
|
return {
|
|
92410
92549
|
id,
|
|
92411
92550
|
factory,
|
|
@@ -92527,16 +92666,16 @@ async function runCaptureSegmentedStage(input) {
|
|
|
92527
92666
|
segmentDir,
|
|
92528
92667
|
skipSize: skip.size,
|
|
92529
92668
|
workerCount: Math.max(1, input.workerCount ?? 1),
|
|
92530
|
-
recycleEvery: input.browserRecycleEverySegments ?? 0
|
|
92669
|
+
recycleEvery: input.browserRecycleEverySegments ?? 0,
|
|
92670
|
+
sessionFactory: input.sessionFactory ?? defaultSessionFactory(input)
|
|
92531
92671
|
};
|
|
92532
92672
|
const queue = createSegmentQueue(pending);
|
|
92533
92673
|
const segmentPaths = segments.map((s) => segmentOutputPath(segmentDir, s.index));
|
|
92534
92674
|
if (pending.length === 0) return concatResumedRun(run, segmentPaths);
|
|
92535
92675
|
let fellBackToStreaming = false;
|
|
92536
92676
|
const workers = [];
|
|
92537
|
-
for (let id = 0; id < run.workerCount; id++) workers.push(await createSegmentWorker(run, id));
|
|
92538
92677
|
const consoleOf = () => workers[0]?.ctx.session.browserConsoleBuffer ?? [];
|
|
92539
|
-
let lastBrowserConsole =
|
|
92678
|
+
let lastBrowserConsole = [];
|
|
92540
92679
|
const runWorkerLoop = async (worker) => {
|
|
92541
92680
|
for (; ; ) {
|
|
92542
92681
|
if (fellBackToStreaming) return;
|
|
@@ -92551,6 +92690,7 @@ async function runCaptureSegmentedStage(input) {
|
|
|
92551
92690
|
};
|
|
92552
92691
|
try {
|
|
92553
92692
|
assertNotAborted();
|
|
92693
|
+
for (let id = 0; id < run.workerCount; id++) workers.push(await createSegmentWorker(run, id));
|
|
92554
92694
|
const outcomes = await Promise.allSettled(workers.map((w) => runWorkerLoop(w)));
|
|
92555
92695
|
for (const worker of workers) dedupPerfs.push(getCapturePerfSummary(worker.ctx.session));
|
|
92556
92696
|
const failure = outcomes.find((o) => o.status === "rejected");
|
|
@@ -96174,6 +96314,13 @@ function inlineSubCompositions2(html, subCompositions, projectDir, variableOverr
|
|
|
96174
96314
|
}
|
|
96175
96315
|
flushInline();
|
|
96176
96316
|
}
|
|
96317
|
+
if (body) {
|
|
96318
|
+
emitMountedModuleScripts(
|
|
96319
|
+
document2,
|
|
96320
|
+
result.importMaps,
|
|
96321
|
+
result.moduleScripts
|
|
96322
|
+
);
|
|
96323
|
+
}
|
|
96177
96324
|
emitRootCompositionVariableStyles(
|
|
96178
96325
|
document2,
|
|
96179
96326
|
result.variablesByComp,
|
|
@@ -104290,8 +104437,8 @@ async function runFontLocalize(io, localize) {
|
|
|
104290
104437
|
}
|
|
104291
104438
|
|
|
104292
104439
|
// src/version.ts
|
|
104293
|
-
var VERSION = true ? "0.8.
|
|
104294
|
-
var PRODUCER_VERSION = true ? "0.8.
|
|
104440
|
+
var VERSION = true ? "0.8.76" : "0.0.0-dev";
|
|
104441
|
+
var PRODUCER_VERSION = true ? "0.8.76" : "0.0.0-dev";
|
|
104295
104442
|
|
|
104296
104443
|
// src/fontLocalizeCli.ts
|
|
104297
104444
|
async function readStdin() {
|