@hyperframes/producer 0.9.20 → 0.9.22
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 +103 -12
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +74 -74
- package/dist/index.js +106 -12
- package/dist/public-server.js +79 -7
- package/dist/renderRequest.d.ts +1 -0
- package/dist/services/distributed/chunkFrames.d.ts +3 -0
- package/dist/services/distributed/plan.d.ts +7 -5
- package/dist/services/fileServer.d.ts +3 -3
- package/package.json +7 -7
package/dist/distributed.js
CHANGED
|
@@ -351,7 +351,7 @@ function buildVirtualTimeShim(options) {
|
|
|
351
351
|
} catch (e) {}
|
|
352
352
|
}
|
|
353
353
|
` : "";
|
|
354
|
-
const seekToTimeReseedCall = seedRandomFromFrame ? "reseedRngFromTime(safeTimeMs);\n
|
|
354
|
+
const seekToTimeReseedCall = seedRandomFromFrame ? "reseedRngFromTime(safeTimeMs);\n " : "";
|
|
355
355
|
return String.raw`(function() {
|
|
356
356
|
if (window.__HF_VIRTUAL_TIME__) return;
|
|
357
357
|
|
|
@@ -430,6 +430,82 @@ ${seededRandomBlock}
|
|
|
430
430
|
}
|
|
431
431
|
};
|
|
432
432
|
|
|
433
|
+
// Timers set once rendering has started run on film time: each seek fires every timer due by then, in
|
|
434
|
+
// due order. Until a seek after the page reports ready, timers keep the wall clock: setup code waits on
|
|
435
|
+
// them while the renderer may already be seeking.
|
|
436
|
+
var rendering = false;
|
|
437
|
+
var timerQueue = [];
|
|
438
|
+
var nextTimerId = 1000000000;
|
|
439
|
+
var firingDepth = 0;
|
|
440
|
+
function addTimer(callback, delay, args, repeats) {
|
|
441
|
+
// A timer set from a firing timer waits at least 1 ms, so a zero-delay chain cannot stall a seek.
|
|
442
|
+
var ms = Math.max(firingDepth > 0 ? 1 : 0, Number(delay) || 0);
|
|
443
|
+
var entry = { id: nextTimerId++, callback: callback, args: args, due: virtualNowMs + ms, every: repeats ? Math.max(1, ms) : 0, cancelled: false };
|
|
444
|
+
timerQueue.push(entry);
|
|
445
|
+
return entry.id;
|
|
446
|
+
}
|
|
447
|
+
function cancelTimer(id) {
|
|
448
|
+
for (var i = 0; i < timerQueue.length; i++) {
|
|
449
|
+
if (timerQueue[i].id === id) {
|
|
450
|
+
timerQueue[i].cancelled = true;
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
function fireDueTimers(untilMs) {
|
|
457
|
+
// Frame times are fractional, so a timer due on a frame lands a rounding error past it; it still fires on it.
|
|
458
|
+
untilMs += 0.000001;
|
|
459
|
+
while (true) {
|
|
460
|
+
var next = null;
|
|
461
|
+
for (var i = 0; i < timerQueue.length; i++) {
|
|
462
|
+
var candidate = timerQueue[i];
|
|
463
|
+
if (!candidate.cancelled && candidate.due <= untilMs && (next === null || candidate.due < next.due)) next = candidate;
|
|
464
|
+
}
|
|
465
|
+
if (next === null) break;
|
|
466
|
+
var dueMs = next.due;
|
|
467
|
+
if (next.every) next.due += next.every;
|
|
468
|
+
else next.cancelled = true;
|
|
469
|
+
virtualNowMs = dueMs;
|
|
470
|
+
firingDepth++;
|
|
471
|
+
try {
|
|
472
|
+
next.callback.apply(window, next.args);
|
|
473
|
+
} catch (err) {
|
|
474
|
+
originalSetTimeout(function() { throw err; }, 0);
|
|
475
|
+
}
|
|
476
|
+
firingDepth--;
|
|
477
|
+
}
|
|
478
|
+
timerQueue = timerQueue.filter(function(entry) { return !entry.cancelled; });
|
|
479
|
+
}
|
|
480
|
+
window.setTimeout = function(callback, delay) {
|
|
481
|
+
if (!rendering || typeof callback !== "function") return originalSetTimeout.apply(null, arguments);
|
|
482
|
+
return addTimer(callback, delay, Array.prototype.slice.call(arguments, 2), false);
|
|
483
|
+
};
|
|
484
|
+
window.setInterval = function(callback, delay) {
|
|
485
|
+
if (!rendering || typeof callback !== "function") return originalSetInterval.apply(null, arguments);
|
|
486
|
+
return addTimer(callback, delay, Array.prototype.slice.call(arguments, 2), true);
|
|
487
|
+
};
|
|
488
|
+
window.clearTimeout = function(id) {
|
|
489
|
+
if (!cancelTimer(id)) originalClearTimeout(id);
|
|
490
|
+
};
|
|
491
|
+
window.clearInterval = function(id) {
|
|
492
|
+
if (!cancelTimer(id)) originalClearInterval(id);
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
function seekToTime(nextTimeMs) {
|
|
496
|
+
var safeTimeMs = Math.max(0, Number(nextTimeMs) || 0);
|
|
497
|
+
if (!rendering && window.__renderReady === true) {
|
|
498
|
+
rendering = true;
|
|
499
|
+
// A worker whose first frame is past the start plays the film's first frame first, so timers the
|
|
500
|
+
// page starts there keep the schedule a one-worker render gives them.
|
|
501
|
+
if (safeTimeMs > 0) seekToTime(0);
|
|
502
|
+
}
|
|
503
|
+
${seekToTimeReseedCall}fireDueTimers(safeTimeMs);
|
|
504
|
+
virtualNowMs = safeTimeMs;
|
|
505
|
+
flushAnimationFrame();
|
|
506
|
+
return virtualNowMs;
|
|
507
|
+
}
|
|
508
|
+
|
|
433
509
|
window.__HF_VIRTUAL_TIME__ = {
|
|
434
510
|
originalSetTimeout: originalSetTimeout,
|
|
435
511
|
originalClearTimeout: originalClearTimeout,
|
|
@@ -437,12 +513,7 @@ ${seededRandomBlock}
|
|
|
437
513
|
originalClearInterval: originalClearInterval,
|
|
438
514
|
originalRequestAnimationFrame: originalRequestAnimationFrame,
|
|
439
515
|
originalCancelAnimationFrame: originalCancelAnimationFrame,
|
|
440
|
-
seekToTime:
|
|
441
|
-
var safeTimeMs = Math.max(0, Number(nextTimeMs) || 0);
|
|
442
|
-
virtualNowMs = safeTimeMs;
|
|
443
|
-
${seekToTimeReseedCall}flushAnimationFrame();
|
|
444
|
-
return virtualNowMs;
|
|
445
|
-
},
|
|
516
|
+
seekToTime: seekToTime,
|
|
446
517
|
getTime: function() {
|
|
447
518
|
return virtualNowMs;
|
|
448
519
|
},
|
|
@@ -8372,13 +8443,14 @@ var RenderChunkValidationError = class extends Error {
|
|
|
8372
8443
|
this.code = code;
|
|
8373
8444
|
}
|
|
8374
8445
|
};
|
|
8446
|
+
var chunkFrameInjectorDependencies = { createVideoFrameInjector: createVideoFrameInjector3 };
|
|
8375
8447
|
function createChunkVideoFrameInjectorFactory(frameLookup, options) {
|
|
8376
8448
|
if (!(frameLookup instanceof Promise))
|
|
8377
|
-
return () =>
|
|
8449
|
+
return () => chunkFrameInjectorDependencies.createVideoFrameInjector(frameLookup, options);
|
|
8378
8450
|
return () => {
|
|
8379
8451
|
let hook;
|
|
8380
8452
|
return async (page, time, heldVideoTime) => {
|
|
8381
|
-
hook ??=
|
|
8453
|
+
hook ??= chunkFrameInjectorDependencies.createVideoFrameInjector(await frameLookup, options);
|
|
8382
8454
|
await hook?.(page, time, heldVideoTime);
|
|
8383
8455
|
};
|
|
8384
8456
|
};
|
|
@@ -9939,7 +10011,7 @@ function assertPlanSizeWithinLimit(input) {
|
|
|
9939
10011
|
});
|
|
9940
10012
|
throw new PlanTooLargeError(breakdown.totalBytes, input.limitBytes, breakdown, input.observedAt);
|
|
9941
10013
|
}
|
|
9942
|
-
function resolveChunkPlan(totalFrames, configChunkSize, maxParallelChunks, targetChunkFrames) {
|
|
10014
|
+
function resolveChunkPlan(totalFrames, configChunkSize, maxParallelChunks, targetChunkFrames, minParallelChunks = 1) {
|
|
9943
10015
|
assertPositiveInteger("totalFrames", totalFrames);
|
|
9944
10016
|
assertPositiveInteger("maxParallelChunks", maxParallelChunks);
|
|
9945
10017
|
if (configChunkSize !== void 0) {
|
|
@@ -9948,7 +10020,11 @@ function resolveChunkPlan(totalFrames, configChunkSize, maxParallelChunks, targe
|
|
|
9948
10020
|
if (targetChunkFrames !== void 0) {
|
|
9949
10021
|
assertPositiveInteger("targetChunkFrames", targetChunkFrames);
|
|
9950
10022
|
}
|
|
9951
|
-
|
|
10023
|
+
assertPositiveInteger("minParallelChunks", minParallelChunks);
|
|
10024
|
+
const autoSizeParallel = targetChunkFrames === void 0 ? maxParallelChunks : Math.min(
|
|
10025
|
+
maxParallelChunks,
|
|
10026
|
+
Math.max(minParallelChunks, Math.ceil(totalFrames / targetChunkFrames))
|
|
10027
|
+
);
|
|
9952
10028
|
const resolvedChunkSize = configChunkSize ?? Math.max(MIN_CHUNK_SIZE, Math.ceil(totalFrames / autoSizeParallel));
|
|
9953
10029
|
const naiveCount = Math.ceil(totalFrames / resolvedChunkSize);
|
|
9954
10030
|
const chunkCount = Math.min(maxParallelChunks, Math.max(1, naiveCount));
|
|
@@ -10527,7 +10603,8 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
10527
10603
|
totalFrames,
|
|
10528
10604
|
config.chunkSize,
|
|
10529
10605
|
maxParallel,
|
|
10530
|
-
config.targetChunkFrames
|
|
10606
|
+
config.targetChunkFrames,
|
|
10607
|
+
config.minParallelChunks
|
|
10531
10608
|
);
|
|
10532
10609
|
const chunks = buildPlanChunkSlices(
|
|
10533
10610
|
frameWeights,
|
|
@@ -12803,6 +12880,20 @@ function validateDistributedRenderConfig(config) {
|
|
|
12803
12880
|
);
|
|
12804
12881
|
}
|
|
12805
12882
|
}
|
|
12883
|
+
if (config.minParallelChunks !== void 0) {
|
|
12884
|
+
if (!Number.isInteger(config.minParallelChunks) || config.minParallelChunks < 1) {
|
|
12885
|
+
throw new InvalidConfigError(
|
|
12886
|
+
"config.minParallelChunks",
|
|
12887
|
+
`must be a positive integer; got ${config.minParallelChunks}`
|
|
12888
|
+
);
|
|
12889
|
+
}
|
|
12890
|
+
if (config.minParallelChunks > MAX_PARALLEL_CHUNKS_CEILING) {
|
|
12891
|
+
throw new InvalidConfigError(
|
|
12892
|
+
"config.minParallelChunks",
|
|
12893
|
+
`must be <= ${MAX_PARALLEL_CHUNKS_CEILING}; got ${config.minParallelChunks}`
|
|
12894
|
+
);
|
|
12895
|
+
}
|
|
12896
|
+
}
|
|
12806
12897
|
for (const field of ["workerTimeoutSeconds", "workerConcurrency"]) {
|
|
12807
12898
|
const value = config[field];
|
|
12808
12899
|
if (value !== void 0 && (!Number.isInteger(value) || value < 1)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "0.1.0",
|
|
3
3
|
"buildId": "dev",
|
|
4
|
-
"sha256": "
|
|
4
|
+
"sha256": "a42261c262fc9a936c9626d8dabb6459afdde52a8d51986331f622f0e815b4dd",
|
|
5
5
|
"artifacts": {
|
|
6
6
|
"iife": "hyperframe.runtime.iife.js",
|
|
7
7
|
"esm": "hyperframe.runtime.mjs"
|