@hyperframes/producer 0.8.145 → 0.8.146
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/distributed.js +44 -36
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +214 -68
- package/dist/index.js +60 -52
- package/dist/public-server.js +54 -46
- package/dist/services/htmlCompiler.d.ts +1 -0
- package/package.json +7 -7
package/dist/distributed.js
CHANGED
|
@@ -288,7 +288,7 @@ function buildVirtualTimeShim(options) {
|
|
|
288
288
|
const seedRandomFromFrame = options.seedRandomFromFrame === true;
|
|
289
289
|
const seededRandomBlock = seedRandomFromFrame ? String.raw`
|
|
290
290
|
// Seeded Math.random / crypto.getRandomValues, keyed by virtual time.
|
|
291
|
-
// Mulberry32
|
|
291
|
+
// Mulberry32: single uint32 state, deterministic, fast.
|
|
292
292
|
var rngState = 0;
|
|
293
293
|
function mulberry32() {
|
|
294
294
|
rngState |= 0; rngState = (rngState + 0x6D2B79F5) | 0;
|
|
@@ -299,7 +299,7 @@ function buildVirtualTimeShim(options) {
|
|
|
299
299
|
}
|
|
300
300
|
function reseedRngFromTime(ms) {
|
|
301
301
|
var ms32 = Math.max(0, Math.floor(Number(ms) || 0)) | 0;
|
|
302
|
-
// Knuth's multiplicative hash + golden-ratio offset
|
|
302
|
+
// Knuth's multiplicative hash + golden-ratio offset gives a well-
|
|
303
303
|
// distributed seed even for frame 0 (otherwise rngState=0 degenerates
|
|
304
304
|
// the PRNG's first few outputs).
|
|
305
305
|
rngState = (Math.imul(ms32, -1640531527) + 0x9E3779B9) | 0;
|
|
@@ -541,7 +541,7 @@ function buildRenderModeScript(fps) {
|
|
|
541
541
|
};
|
|
542
542
|
window.__playerReady = true;
|
|
543
543
|
// Media-fallback player has no timeline to bind, so render-ready is immediate.
|
|
544
|
-
// init.ts defers __renderReady until the timeline is bound
|
|
544
|
+
// init.ts defers __renderReady until the timeline is bound (a different runtime).
|
|
545
545
|
window.__renderReady = true;
|
|
546
546
|
return true;
|
|
547
547
|
}
|
|
@@ -2243,7 +2243,7 @@ async function resolveMediaDuration(src, mediaStart, playbackRate, baseDir, down
|
|
|
2243
2243
|
if (tagName !== "video") {
|
|
2244
2244
|
if (error instanceof NotMediaPayloadError2) {
|
|
2245
2245
|
log?.warn(
|
|
2246
|
-
`[compile] Audio "${elementIdentity}" (${src}) is a text document, not a media file
|
|
2246
|
+
`[compile] Audio "${elementIdentity}" (${src}) is a text document, not a media file, so the element is dropped from the render. Point it at a rendered media file.`
|
|
2247
2247
|
);
|
|
2248
2248
|
}
|
|
2249
2249
|
return { duration: null, resolvedPath: filePath };
|
|
@@ -2332,7 +2332,7 @@ async function compileHtmlFile(html, baseDir, downloadDir, log) {
|
|
|
2332
2332
|
if (r.maxDuration != null && shouldClampResolvedMediaDuration(r.tagName, r.duration, r.maxDuration)) {
|
|
2333
2333
|
clampList.push({ id: r.id, duration: r.maxDuration });
|
|
2334
2334
|
log?.warn(
|
|
2335
|
-
`[compile] Audio "${r.id}" (${r.src}) is ${r.maxDuration.toFixed(2)}s but its data-duration is ${r.duration.toFixed(2)}s
|
|
2335
|
+
`[compile] Audio "${r.id}" (${r.src}) is ${r.maxDuration.toFixed(2)}s but its data-duration is ${r.duration.toFixed(2)}s, so the slot is shortened to the media length. Set data-duration to ~${r.maxDuration.toFixed(2)}s, trim data-media-start, or use a longer/looping source if that isn't intended.`
|
|
2336
2336
|
);
|
|
2337
2337
|
}
|
|
2338
2338
|
}
|
|
@@ -2721,7 +2721,7 @@ ${safeText}
|
|
|
2721
2721
|
} else {
|
|
2722
2722
|
if (download.reason instanceof ScriptIntegrityError) throw download.reason;
|
|
2723
2723
|
defaultLogger.warn(
|
|
2724
|
-
`[Compiler] WARNING: Failed to download CDN script: ${src}
|
|
2724
|
+
`[Compiler] WARNING: Failed to download CDN script: ${src} (${download.reason}). The render may fail if this script is required (e.g. GSAP). Consider bundling it locally in your project.`
|
|
2725
2725
|
);
|
|
2726
2726
|
}
|
|
2727
2727
|
}
|
|
@@ -2773,7 +2773,7 @@ function collectExternalAssets(html, projectDir) {
|
|
|
2773
2773
|
}
|
|
2774
2774
|
if (externalAssets.size > 0) {
|
|
2775
2775
|
defaultLogger.info(
|
|
2776
|
-
`[Compiler] Found ${externalAssets.size} asset(s) outside project directory
|
|
2776
|
+
`[Compiler] Found ${externalAssets.size} asset(s) outside project directory, will copy to render output`
|
|
2777
2777
|
);
|
|
2778
2778
|
}
|
|
2779
2779
|
return {
|
|
@@ -2798,7 +2798,7 @@ async function downloadAndRewriteUrls(urlSet, html, remoteDir, warnLabel, logLab
|
|
|
2798
2798
|
urlToLocal.set(url, localPath);
|
|
2799
2799
|
} catch (err) {
|
|
2800
2800
|
const identity = safeDownloadUrlIdentity(url);
|
|
2801
|
-
defaultLogger.warn(`[Compiler] ${warnLabel}
|
|
2801
|
+
defaultLogger.warn(`[Compiler] ${warnLabel}, using original URL as fallback.`, {
|
|
2802
2802
|
urlFingerprint: identity.urlFingerprint,
|
|
2803
2803
|
host: identity.host,
|
|
2804
2804
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -2891,7 +2891,7 @@ async function fetchExternalStylesheetCss(href) {
|
|
|
2891
2891
|
timeoutMs: 15e3
|
|
2892
2892
|
});
|
|
2893
2893
|
} catch (err) {
|
|
2894
|
-
defaultLogger.warn("[Compiler] External stylesheet fetch failed
|
|
2894
|
+
defaultLogger.warn("[Compiler] External stylesheet fetch failed, preserving link tag.", {
|
|
2895
2895
|
urlFingerprint: identity.urlFingerprint,
|
|
2896
2896
|
host: identity.host,
|
|
2897
2897
|
error: err instanceof Error ? err.message : String(err)
|
|
@@ -3535,12 +3535,15 @@ async function resolveCompositionDurations(page, unresolved) {
|
|
|
3535
3535
|
const resolved = [];
|
|
3536
3536
|
for (const id of compIds) {
|
|
3537
3537
|
const tl = timelines[id];
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3538
|
+
let dur = 0;
|
|
3539
|
+
try {
|
|
3540
|
+
dur = typeof tl?.duration === "function" ? Number(tl.duration()) : 0;
|
|
3541
|
+
} catch {
|
|
3542
|
+
dur = 0;
|
|
3543
|
+
}
|
|
3544
|
+
if (dur > 0) {
|
|
3545
|
+
resolved.push({ id, duration: dur, source: "__timelines" });
|
|
3546
|
+
continue;
|
|
3544
3547
|
}
|
|
3545
3548
|
const el = document.getElementById(id);
|
|
3546
3549
|
if (el) {
|
|
@@ -3636,28 +3639,28 @@ async function runCompileStage(input) {
|
|
|
3636
3639
|
cfg.useDrawElement = false;
|
|
3637
3640
|
deCompileGate = "3d";
|
|
3638
3641
|
log.info(
|
|
3639
|
-
"[Render] Fast capture: composition uses a CSS 3D rendering context (perspective / preserve-3d / backface-visibility)
|
|
3642
|
+
"[Render] Fast capture: composition uses a CSS 3D rendering context (perspective / preserve-3d / backface-visibility), so disabling drawElementImage for this render. Capture uses the platform's baseline route."
|
|
3640
3643
|
);
|
|
3641
3644
|
}
|
|
3642
3645
|
if (cfg.useDrawElement && process.env.HF_FAST_CAPTURE_BLEND !== "true" && compiled.usesMixBlendMode) {
|
|
3643
3646
|
cfg.useDrawElement = false;
|
|
3644
3647
|
deCompileGate = "mix_blend_mode";
|
|
3645
3648
|
log.info(
|
|
3646
|
-
"[Render] Fast capture: composition uses mix-blend-mode
|
|
3649
|
+
"[Render] Fast capture: composition uses mix-blend-mode, so disabling drawElementImage for this render. Capture uses the platform's baseline route."
|
|
3647
3650
|
);
|
|
3648
3651
|
}
|
|
3649
3652
|
if (cfg.useDrawElement && process.env.HF_FAST_CAPTURE_ANCESTOR_BG !== "true" && compiled.hasAncestorBackgroundImage) {
|
|
3650
3653
|
cfg.useDrawElement = false;
|
|
3651
3654
|
deCompileGate = "ancestor_background_image";
|
|
3652
3655
|
log.info(
|
|
3653
|
-
"[Render] Fast capture: composition root's ancestors (body/html/wrapper) carry a background-image
|
|
3656
|
+
"[Render] Fast capture: composition root's ancestors (body/html/wrapper) carry a background-image, so disabling drawElementImage for this render. Capture uses the platform's baseline route."
|
|
3654
3657
|
);
|
|
3655
3658
|
}
|
|
3656
3659
|
if (cfg.useDrawElement && process.env.PRODUCER_EXPERIMENTAL_FAST_CAPTURE !== "true" && compiled.hasShaderTransitions) {
|
|
3657
3660
|
cfg.useDrawElement = false;
|
|
3658
3661
|
deCompileGate = "shader_transitions";
|
|
3659
3662
|
log.info(
|
|
3660
|
-
"[Render] Fast capture: composition uses shader transitions
|
|
3663
|
+
"[Render] Fast capture: composition uses shader transitions, so disabling drawElementImage so page-side compositing stays available."
|
|
3661
3664
|
);
|
|
3662
3665
|
}
|
|
3663
3666
|
if (!cfg.useDrawElement && cfg.pageSideCompositingAutoDisabled) {
|
|
@@ -3985,7 +3988,7 @@ async function runProbeStage(input) {
|
|
|
3985
3988
|
} else {
|
|
3986
3989
|
beginFrameStalled = true;
|
|
3987
3990
|
log.warn(
|
|
3988
|
-
"[Render] BeginFrame liveness probe timed out
|
|
3991
|
+
"[Render] BeginFrame liveness probe timed out: this composition stalls BeginFrame on this host (SwiftShader heavy-layer pattern). Relaunching the probe browser in screenshot capture mode; the render will use screenshot capture throughout.",
|
|
3989
3992
|
{ probeTimeoutMs }
|
|
3990
3993
|
);
|
|
3991
3994
|
lastBrowserConsole = probeSession.browserConsoleBuffer;
|
|
@@ -4199,7 +4202,7 @@ async function runProbeStage(input) {
|
|
|
4199
4202
|
video.start = win.visibleStart;
|
|
4200
4203
|
video.end = win.visibleEnd;
|
|
4201
4204
|
log.info(
|
|
4202
|
-
`[Probe] Runtime video discovery: ${video.id} visible ${win.visibleStart.toFixed(2)}s
|
|
4205
|
+
`[Probe] Runtime video discovery: ${video.id} visible ${win.visibleStart.toFixed(2)}s to ${win.visibleEnd.toFixed(2)}s`
|
|
4203
4206
|
);
|
|
4204
4207
|
}
|
|
4205
4208
|
}
|
|
@@ -4247,7 +4250,7 @@ async function runProbeStage(input) {
|
|
|
4247
4250
|
});
|
|
4248
4251
|
if (!timelinesInfo.gsapLoaded) {
|
|
4249
4252
|
diagnostics.push(
|
|
4250
|
-
"GSAP is not loaded
|
|
4253
|
+
"GSAP is not loaded. The CDN script may have failed to download. Bundle GSAP locally in your project instead of using a CDN <script src>."
|
|
4251
4254
|
);
|
|
4252
4255
|
} else if (timelinesInfo.timelineKeys.length === 0) {
|
|
4253
4256
|
diagnostics.push(
|
|
@@ -4264,10 +4267,10 @@ async function runProbeStage(input) {
|
|
|
4264
4267
|
log.warn("Failed to gather browser diagnostics for zero-duration composition", {
|
|
4265
4268
|
error: err instanceof Error ? err.message : String(err)
|
|
4266
4269
|
});
|
|
4267
|
-
diagnostics.push("(Could not gather browser diagnostics
|
|
4270
|
+
diagnostics.push("(Could not gather browser diagnostics. The page may have crashed.)");
|
|
4268
4271
|
}
|
|
4269
4272
|
const hint = diagnostics.length > 0 ? "\n\nDiagnostics:\n - " + diagnostics.join("\n - ") : "\n\nCheck that GSAP timelines are registered on window.__timelines.";
|
|
4270
|
-
throw new Error("Composition duration is 0
|
|
4273
|
+
throw new Error("Composition duration is 0, so this would produce a black video." + hint);
|
|
4271
4274
|
}
|
|
4272
4275
|
if (probeSession) {
|
|
4273
4276
|
const failedRequests = probeSession.browserConsoleBuffer.filter(isActionableProbeFailure);
|
|
@@ -4332,7 +4335,7 @@ function validateNoGpuEncode(config) {
|
|
|
4332
4335
|
if (config.useGpu === true) {
|
|
4333
4336
|
throw new PlanValidationError(
|
|
4334
4337
|
BROWSER_GPU_NOT_SOFTWARE,
|
|
4335
|
-
"[planValidation] GPU encode is banned in distributed mode: config.useGpu === true. Distributed retries must be byte-identical, but NVENC/QSV/VAAPI produce different output across machines. Set useGpu=false (the default)
|
|
4338
|
+
"[planValidation] GPU encode is banned in distributed mode: config.useGpu === true. Distributed retries must be byte-identical, but NVENC/QSV/VAAPI produce different output across machines. Set useGpu=false (the default): software libx264/libx265 is the only supported encoder in distributed mode."
|
|
4336
4339
|
);
|
|
4337
4340
|
}
|
|
4338
4341
|
if (config.browserGpuMode !== void 0 && config.browserGpuMode !== "software") {
|
|
@@ -4379,6 +4382,7 @@ import {
|
|
|
4379
4382
|
detectTransfer,
|
|
4380
4383
|
extractAllVideoFrames,
|
|
4381
4384
|
extractMediaMetadata as extractMediaMetadata3,
|
|
4385
|
+
isVideoPastTimelineEnd,
|
|
4382
4386
|
isHdrColorSpace as isHdrColorSpace2,
|
|
4383
4387
|
resolveProjectRelativeSrc as resolveProjectRelativeSrc3,
|
|
4384
4388
|
runVideoExtractionWithRetry,
|
|
@@ -4598,6 +4602,9 @@ async function runExtractVideosStage(input) {
|
|
|
4598
4602
|
} = input;
|
|
4599
4603
|
const stage2Start = Date.now();
|
|
4600
4604
|
const extractionPolicy = resolveVideoExtractionPolicy();
|
|
4605
|
+
composition.videos = composition.videos.filter(
|
|
4606
|
+
(video) => !isVideoPastTimelineEnd(video, composition.duration)
|
|
4607
|
+
);
|
|
4601
4608
|
let frameLookup = null;
|
|
4602
4609
|
let extractionResult = null;
|
|
4603
4610
|
let failureToEnforce = null;
|
|
@@ -4684,7 +4691,8 @@ async function runExtractVideosStage(input) {
|
|
|
4684
4691
|
timelineEnd: composition.duration,
|
|
4685
4692
|
maxTransientRetries: extractionPolicy.maxTransientRetries,
|
|
4686
4693
|
collectProbeFailures: extractionPolicy.failureMode === "enforce",
|
|
4687
|
-
deferRangeExtraction
|
|
4694
|
+
deferRangeExtraction,
|
|
4695
|
+
contentKeyedDirs: [join8(compiledDir, REMOTE_MEDIA_SUBDIR)]
|
|
4688
4696
|
},
|
|
4689
4697
|
abortSignal,
|
|
4690
4698
|
cfg,
|
|
@@ -6143,7 +6151,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
6143
6151
|
const madeProgress = captureAttemptMadeProgress(frameCount, remainingCount);
|
|
6144
6152
|
if (!madeProgress) {
|
|
6145
6153
|
options.log.warn(
|
|
6146
|
-
"[Render] Capture attempt made no forward progress; composition is likely structurally broken
|
|
6154
|
+
"[Render] Capture attempt made no forward progress; composition is likely structurally broken, not retrying.",
|
|
6147
6155
|
{ attempt, frameCount, remainingCount, workers: currentWorkers }
|
|
6148
6156
|
);
|
|
6149
6157
|
}
|
|
@@ -6212,7 +6220,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
6212
6220
|
}
|
|
6213
6221
|
if (!madeProgress) {
|
|
6214
6222
|
options.log.warn(
|
|
6215
|
-
"[Render] Capture attempt made no forward progress; composition is likely structurally broken
|
|
6223
|
+
"[Render] Capture attempt made no forward progress; composition is likely structurally broken, not retrying.",
|
|
6216
6224
|
{ attempt, frameCount, remainingCount, workers: currentWorkers }
|
|
6217
6225
|
);
|
|
6218
6226
|
}
|
|
@@ -6461,7 +6469,7 @@ function collectPlanAssetShas(planDir) {
|
|
|
6461
6469
|
}
|
|
6462
6470
|
if (compositionHtml === null) {
|
|
6463
6471
|
throw new Error(
|
|
6464
|
-
`[freezePlan] compiled HTML missing at ${COMPILED_INDEX_RELATIVE_PATH}
|
|
6472
|
+
`[freezePlan] compiled HTML missing at ${COMPILED_INDEX_RELATIVE_PATH} (upstream compile stage did not materialize the expected file).`
|
|
6465
6473
|
);
|
|
6466
6474
|
}
|
|
6467
6475
|
return { compositionHtml, assets };
|
|
@@ -7052,7 +7060,7 @@ var PlanTooLargeError = class extends Error {
|
|
|
7052
7060
|
const breakdownSuffix = breakdown ? ` Breakdown: video-frames=${formatBytes(breakdown.videoFramesBytes)}, compiled=${formatBytes(breakdown.compiledBytes)} (source-media=${formatBytes(breakdown.sourceMediaBytes)}), audio=${formatBytes(breakdown.audioBytes)}, metadata=${formatBytes(breakdown.metadataBytes)}, other=${formatBytes(breakdown.otherBytes)}, files=${breakdown.fileCount}.` : "";
|
|
7053
7061
|
const observationSuffix = observedAt ? ` Observed at ${observedAt}.` : "";
|
|
7054
7062
|
super(
|
|
7055
|
-
`[plan] planDir size ${formatBytes(sizeBytes)} exceeds the configured ceiling ${formatBytes(limitBytes)} (PLAN_TOO_LARGE). The default 2 GB cap fits inside AWS Lambda's 10 GB /tmp budget alongside the chunk worker's frame buffer and ffmpeg's working set. To unblock: use the content-addressed \`planV2()\` transport, shorten the composition, lower the framerate, or use the in-process renderer (\`executeRenderJob\`)
|
|
7063
|
+
`[plan] planDir size ${formatBytes(sizeBytes)} exceeds the configured ceiling ${formatBytes(limitBytes)} (PLAN_TOO_LARGE). The default 2 GB cap fits inside AWS Lambda's 10 GB /tmp budget alongside the chunk worker's frame buffer and ffmpeg's working set. To unblock: use the content-addressed \`planV2()\` transport, shorten the composition, lower the framerate, or use the in-process renderer (\`executeRenderJob\`), which has no planDir size cap.` + observationSuffix + breakdownSuffix
|
|
7056
7064
|
);
|
|
7057
7065
|
this.name = "PlanTooLargeError";
|
|
7058
7066
|
this.sizeBytes = sizeBytes;
|
|
@@ -7069,7 +7077,7 @@ var FormatNotSupportedInDistributedError = class extends Error {
|
|
|
7069
7077
|
reason;
|
|
7070
7078
|
constructor(format, reason) {
|
|
7071
7079
|
super(
|
|
7072
|
-
`[plan] format ${JSON.stringify(format)} is not supported in distributed mode: ${reason}. Render with the in-process renderer (\`executeRenderJob\`)
|
|
7080
|
+
`[plan] format ${JSON.stringify(format)} is not supported in distributed mode: ${reason}. Render with the in-process renderer (\`executeRenderJob\`), which has full format support, or pick a distributed-supported format: mp4 SDR, mov ProRes 4444, png-sequence, or webm VP9.`
|
|
7073
7081
|
);
|
|
7074
7082
|
this.name = "FormatNotSupportedInDistributedError";
|
|
7075
7083
|
this.format = format;
|
|
@@ -7161,7 +7169,7 @@ async function readFontSnapshotSha() {
|
|
|
7161
7169
|
const data = module.EMBEDDED_FONT_DATA;
|
|
7162
7170
|
if (!data || typeof data !== "object") {
|
|
7163
7171
|
throw new Error(
|
|
7164
|
-
"[plan] EMBEDDED_FONT_DATA missing from @hyperframes/core/fonts/embedded-data
|
|
7172
|
+
"[plan] EMBEDDED_FONT_DATA missing from @hyperframes/core/fonts/embedded-data. Was `bun run build:fonts` run?"
|
|
7165
7173
|
);
|
|
7166
7174
|
}
|
|
7167
7175
|
const dataObj = data;
|
|
@@ -7211,7 +7219,7 @@ function resolveEncoderTriple(config) {
|
|
|
7211
7219
|
}
|
|
7212
7220
|
if (config.codec !== void 0) {
|
|
7213
7221
|
throw new Error(
|
|
7214
|
-
`[plan] DistributedRenderConfig.codec is only valid for format="mp4"; received codec=${JSON.stringify(config.codec)} with format=${JSON.stringify(config.format)}. Omit codec for non-mp4 formats
|
|
7222
|
+
`[plan] DistributedRenderConfig.codec is only valid for format="mp4"; received codec=${JSON.stringify(config.codec)} with format=${JSON.stringify(config.format)}. Omit codec for non-mp4 formats: mov is always ProRes 4444, webm is always libvpx-vp9, and png-sequence has no encoder.`
|
|
7215
7223
|
);
|
|
7216
7224
|
}
|
|
7217
7225
|
return resolveNonMp4EncoderTriple(config.format, config.quality ?? "standard");
|
|
@@ -9563,10 +9571,10 @@ function validateJsonSafeValue(value, field) {
|
|
|
9563
9571
|
walkVariables(value, field, /* @__PURE__ */ new WeakSet());
|
|
9564
9572
|
}
|
|
9565
9573
|
var LEAF_REJECTIONS = {
|
|
9566
|
-
undefined: "undefined leaves are silently dropped by JSON.stringify
|
|
9574
|
+
undefined: "undefined leaves are silently dropped by JSON.stringify. Use null if you mean an absent value",
|
|
9567
9575
|
function: "functions are not JSON-serializable",
|
|
9568
9576
|
symbol: "Symbols are not JSON-serializable",
|
|
9569
|
-
bigint: "BigInt values throw at JSON.stringify
|
|
9577
|
+
bigint: "BigInt values throw at JSON.stringify. Encode as a string if you need 64-bit integers"
|
|
9570
9578
|
};
|
|
9571
9579
|
function walkVariables(value, path, seen) {
|
|
9572
9580
|
const t = typeof value;
|
|
@@ -9587,7 +9595,7 @@ function walkVariables(value, path, seen) {
|
|
|
9587
9595
|
if (seen.has(value)) {
|
|
9588
9596
|
throw new InvalidConfigError(
|
|
9589
9597
|
path,
|
|
9590
|
-
"circular reference detected
|
|
9598
|
+
"circular reference detected: JSON.stringify cannot serialize cycles"
|
|
9591
9599
|
);
|
|
9592
9600
|
}
|
|
9593
9601
|
seen.add(value);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.1.0",
|
|
3
3
|
"buildId": "dev",
|
|
4
|
-
"sha256": "
|
|
4
|
+
"sha256": "40ff09519c86046d23d0f53d7a6254fb83edc24267cbe13296b6bb185e3b1fa1",
|
|
5
5
|
"artifacts": {
|
|
6
6
|
"iife": "hyperframe.runtime.iife.js",
|
|
7
7
|
"esm": "hyperframe.runtime.mjs"
|