@hyperframes/studio-server 0.9.7 → 0.9.9
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/{chunk-3GSVCYB4.js → chunk-Z6G2NBCQ.js} +3 -3
- package/dist/helpers/mediaProxyPreview.d.ts +1 -1
- package/dist/history/index.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +55 -40
- package/dist/{mediaProxyPreview-BnQDzKj1.d.ts → mediaProxyPreview-Ds5TElPq.d.ts} +1 -1
- package/package.json +3 -3
|
@@ -523,13 +523,13 @@ function listProjectFiles(projectDir) {
|
|
|
523
523
|
ctimeMs: entry.ctimeMs
|
|
524
524
|
}));
|
|
525
525
|
}
|
|
526
|
-
function resolveProjectSignature(adapter, projectDir) {
|
|
527
|
-
return adapter.getProjectSignature?.(projectDir) ??
|
|
526
|
+
async function resolveProjectSignature(adapter, projectDir) {
|
|
527
|
+
return await adapter.getProjectSignature?.(projectDir) ?? createProjectSignatureAsync(projectDir);
|
|
528
528
|
}
|
|
529
529
|
async function resolveProjectAndSignature(adapter, projectId) {
|
|
530
530
|
const project = await adapter.resolveProject(projectId);
|
|
531
531
|
if (!project) return null;
|
|
532
|
-
return { project, signature: resolveProjectSignature(adapter, project.dir) };
|
|
532
|
+
return { project, signature: await resolveProjectSignature(adapter, project.dir) };
|
|
533
533
|
}
|
|
534
534
|
function planSignature(dir, collected, excluding, signedAt) {
|
|
535
535
|
const files = collected.filter(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@hyperframes/core';
|
|
2
|
-
export { a as PreviewApiAdapter, P as PreviewDocumentStore, i as injectMediaCodecMap, f as injectMediaCodecMapIntoHtml, g as isAutoProxyEnabled, p as proxyEtagSalt, r as resolvePreviewMediaCodecProbeCache } from '../mediaProxyPreview-
|
|
2
|
+
export { a as PreviewApiAdapter, P as PreviewDocumentStore, i as injectMediaCodecMap, f as injectMediaCodecMapIntoHtml, g as isAutoProxyEnabled, p as proxyEtagSalt, r as resolvePreviewMediaCodecProbeCache } from '../mediaProxyPreview-Ds5TElPq.js';
|
|
3
3
|
import './mediaCodecMap.js';
|
|
4
4
|
import 'sharp';
|
|
5
5
|
import '@hyperframes/parsers';
|
package/dist/history/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
|
-
import { S as StudioApiAdapter, P as PreviewDocumentStore, M as MediaProcessingJobState } from './mediaProxyPreview-
|
|
3
|
-
export { L as LintResult, a as PreviewApiAdapter, R as RenderJobState, b as ResolvedProject, c as StudioSelectionResponse, d as StudioSelectionSnapshot, e as StudioSelectionTextField } from './mediaProxyPreview-
|
|
2
|
+
import { S as StudioApiAdapter, P as PreviewDocumentStore, M as MediaProcessingJobState } from './mediaProxyPreview-Ds5TElPq.js';
|
|
3
|
+
export { L as LintResult, a as PreviewApiAdapter, R as RenderJobState, b as ResolvedProject, c as StudioSelectionResponse, d as StudioSelectionSnapshot, e as StudioSelectionTextField } from './mediaProxyPreview-Ds5TElPq.js';
|
|
4
4
|
export { C as ClosedWindow, D as DEFAULT_HISTORY_ROOT, S as HISTORY_START, H as HistoryClosedError, a as HistoryEntry, b as HistoryEntrySide, c as HistoryFileChange, d as HistoryListItem, e as HistoryRefusedError, f as HistoryResult, g as HistoryTarget, h as HistoryWho, i as HistoryWindow, M as MAX_WINDOW_IDLE_MS, P as ProjectHistory, j as ProjectHistoryOptions, k as ProjectHistoryView, U as UNDO_MODES, l as UndoMode, o as openProjectHistory, r as readProjectHistory } from './projectHistory-C18HDvac.js';
|
|
5
5
|
export { ArtifactCapture, ArtifactInput, ArtifactRecord, HistoryBusyError, HistoryIdError, InPlaceOutcome, ProjectHistoryRecord, PrunedHistory, ReclaimedHistory, RenderRecord, VideoState, artifactDirectory, beginArtifactCapture, finishSnapshotRun, forgetRecordedArtifacts, historyCache, isUncopiedMedia, listProjectHistories, onRestoredInPlace, pruneGoneProjectHistories, reclaimUncopiedBlobs, recordArtifact, recordArtifacts, recordRenderSuccess, registerRenderOutput, retainSnapshotOutput } from './history/index.js';
|
|
6
6
|
export { CACHE_DIR_NAME as PROXY_CACHE_DIR_NAME } from './helpers/proxyTranscoder.js';
|
package/dist/index.js
CHANGED
|
@@ -71,7 +71,7 @@ import {
|
|
|
71
71
|
retainSnapshotOutput,
|
|
72
72
|
serveWhileOpen,
|
|
73
73
|
settledFileTag
|
|
74
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-Z6G2NBCQ.js";
|
|
75
75
|
import {
|
|
76
76
|
clearElementScreenshotIsolation,
|
|
77
77
|
getElementScreenshotClip
|
|
@@ -179,7 +179,7 @@ function registerProjectRoutes(api, adapter) {
|
|
|
179
179
|
api.get("/projects/:id/signature", async (c) => {
|
|
180
180
|
const project = await adapter.resolveProject(c.req.param("id"));
|
|
181
181
|
if (!project) return c.json({ error: "not found" }, 404);
|
|
182
|
-
return c.json({ signature: resolveProjectSignature(adapter, project.dir) });
|
|
182
|
+
return c.json({ signature: await resolveProjectSignature(adapter, project.dir) });
|
|
183
183
|
});
|
|
184
184
|
api.get("/projects/:id", async (c) => {
|
|
185
185
|
const project = await adapter.resolveProject(c.req.param("id"));
|
|
@@ -280,7 +280,7 @@ import {
|
|
|
280
280
|
RUNTIME_BOOTSTRAP_ATTR,
|
|
281
281
|
stripEmbeddedRuntimeScripts
|
|
282
282
|
} from "@hyperframes/core/compiler";
|
|
283
|
-
import { isFullHtmlDocument } from "@hyperframes/core/compiler/html-document";
|
|
283
|
+
import { findStartTags as findStartTags2, isFullHtmlDocument } from "@hyperframes/core/compiler/html-document";
|
|
284
284
|
import { gsapCdnDist } from "@hyperframes/core/gsap-cdn";
|
|
285
285
|
|
|
286
286
|
// src/helpers/gsapCoreScript.ts
|
|
@@ -529,7 +529,7 @@ ${rewrittenContent}
|
|
|
529
529
|
</html>`;
|
|
530
530
|
}
|
|
531
531
|
function hasBaseElement(html) {
|
|
532
|
-
return
|
|
532
|
+
return findStartTags2(html, "base").length > 0;
|
|
533
533
|
}
|
|
534
534
|
|
|
535
535
|
// src/helpers/compositionInsertion.ts
|
|
@@ -801,7 +801,7 @@ function rootHashes(read) {
|
|
|
801
801
|
const source = read(ROOT_COMPOSITION) ?? "";
|
|
802
802
|
return { root: sha1(source), head: sha1(rootHeadContent(source)) };
|
|
803
803
|
}
|
|
804
|
-
function compositionInputSignature(projectDir, compPath, projectSignature) {
|
|
804
|
+
async function compositionInputSignature(projectDir, compPath, projectSignature) {
|
|
805
805
|
const key = `${projectDir}\0${compPath}`;
|
|
806
806
|
const known = inputSignatures.get(key);
|
|
807
807
|
if (known?.projectSignature === projectSignature) return known.inputSignature;
|
|
@@ -813,11 +813,12 @@ function compositionInputSignature(projectDir, compPath, projectSignature) {
|
|
|
813
813
|
);
|
|
814
814
|
let inputSignature;
|
|
815
815
|
if (comp === ROOT_COMPOSITION) {
|
|
816
|
-
inputSignature =
|
|
816
|
+
inputSignature = await createProjectSignatureAsync(projectDir, excluded);
|
|
817
817
|
} else {
|
|
818
818
|
const hashes = rootHashes(read);
|
|
819
819
|
if (!rootMemos.has(projectDir)) rootMemos.set(projectDir, { ...hashes, affected: null });
|
|
820
|
-
|
|
820
|
+
const rest = await createProjectSignatureAsync(projectDir, excluded.add(ROOT_COMPOSITION));
|
|
821
|
+
inputSignature = `${rest}:${hashes.head}`;
|
|
821
822
|
}
|
|
822
823
|
inputSignatures.set(key, { projectSignature, inputSignature });
|
|
823
824
|
return inputSignature;
|
|
@@ -3933,6 +3934,7 @@ import {
|
|
|
3933
3934
|
import {
|
|
3934
3935
|
STUDIO_PREVIEW_CAPTURE_MODE,
|
|
3935
3936
|
STUDIO_PREVIEW_MARK_META,
|
|
3937
|
+
STUDIO_PREVIEW_ERROR_KINDS,
|
|
3936
3938
|
STUDIO_PREVIEW_ERRORS
|
|
3937
3939
|
} from "@hyperframes/core/studio-preview-mark";
|
|
3938
3940
|
import {
|
|
@@ -3951,14 +3953,14 @@ import {
|
|
|
3951
3953
|
normalizeGsapBaseUrl,
|
|
3952
3954
|
normalizeGsapLocalRoot
|
|
3953
3955
|
} from "@hyperframes/core/gsap-cdn";
|
|
3954
|
-
import { findStartTags as
|
|
3956
|
+
import { findStartTags as findStartTags5, injectTagsAtHeadStart as injectTagsAtHeadStart2 } from "@hyperframes/core/compiler/html-document";
|
|
3955
3957
|
import { isWithinProjectRoot } from "@hyperframes/parsers/asset-resolution";
|
|
3956
3958
|
|
|
3957
3959
|
// src/helpers/rootImportMap.ts
|
|
3958
|
-
import { findStartTags as
|
|
3960
|
+
import { findStartTags as findStartTags3, injectTagsAtHeadStart } from "@hyperframes/core/compiler/html-document";
|
|
3959
3961
|
var IMPORT_MAP_TYPE = /\btype\s*=\s*["']?importmap["']?(?=[\s/>])/i;
|
|
3960
3962
|
function findImportMap(html) {
|
|
3961
|
-
for (const at of
|
|
3963
|
+
for (const at of findStartTags3(html, "script")) {
|
|
3962
3964
|
const open2 = /^<script\b[^>]*>/i.exec(html.slice(at));
|
|
3963
3965
|
if (!open2 || !IMPORT_MAP_TYPE.test(open2[0])) continue;
|
|
3964
3966
|
const start = at + open2[0].length;
|
|
@@ -4128,7 +4130,7 @@ function injectPreviewVariables(html, values) {
|
|
|
4128
4130
|
}
|
|
4129
4131
|
|
|
4130
4132
|
// src/helpers/lazyPreviewImages.ts
|
|
4131
|
-
import { findStartTags as
|
|
4133
|
+
import { findStartTags as findStartTags4 } from "@hyperframes/core/compiler/html-document";
|
|
4132
4134
|
import { parseHTML as parseHTML6 } from "linkedom";
|
|
4133
4135
|
import { STUDIO_PREVIEW_LAZY_ATTR } from "@hyperframes/core/studio-preview-mark";
|
|
4134
4136
|
function startsAfterZero(el) {
|
|
@@ -4140,8 +4142,9 @@ function startsAfterZero(el) {
|
|
|
4140
4142
|
var hasLoading = (img) => Array.from(img.attributes).some((attr) => attr.name.toLowerCase() === "loading");
|
|
4141
4143
|
function lazyPreviewImages(html) {
|
|
4142
4144
|
if (!/<!doctype|<html[\s>]/i.test(html)) return html;
|
|
4145
|
+
const tags = findStartTags4(html, "img");
|
|
4146
|
+
if (tags.length === 0) return html;
|
|
4143
4147
|
const images = [...parseHTML6(html).document.querySelectorAll("img")];
|
|
4144
|
-
const tags = findStartTags3(html, "img");
|
|
4145
4148
|
if (tags.length !== images.length) return html;
|
|
4146
4149
|
const parts = [];
|
|
4147
4150
|
let from = 0;
|
|
@@ -4227,7 +4230,7 @@ function injectMotionPathPluginIfNeeded(html, baseUrl) {
|
|
|
4227
4230
|
}
|
|
4228
4231
|
function findGsapCoreScript(html) {
|
|
4229
4232
|
const scripts = [...parseHTML7(html).document.querySelectorAll("script")];
|
|
4230
|
-
const starts =
|
|
4233
|
+
const starts = findStartTags5(html, "script");
|
|
4231
4234
|
if (starts.length !== scripts.length) return null;
|
|
4232
4235
|
const at = scripts.findIndex(
|
|
4233
4236
|
(script) => isGsapCoreUrl(lowerCaseAttributes(script).get("src") ?? "")
|
|
@@ -4280,7 +4283,7 @@ var GSAP_FALLBACK_ATTR = "data-hf-gsap-fallback";
|
|
|
4280
4283
|
function gsapCdnFallbackScript(baseUrl) {
|
|
4281
4284
|
return `<script ${GSAP_FALLBACK_ATTR}>
|
|
4282
4285
|
(function(){
|
|
4283
|
-
var cdnBase=${
|
|
4286
|
+
var cdnBase=${scriptJson(gsapCdnDist2(void 0, baseUrl))};
|
|
4284
4287
|
var loaded={};
|
|
4285
4288
|
function loadFallback(file){
|
|
4286
4289
|
if(loaded[file])return loaded[file];
|
|
@@ -4330,15 +4333,21 @@ function previewVariablesFromRequest(rawVariables) {
|
|
|
4330
4333
|
return { raw: rawVariables, values: parse2.values };
|
|
4331
4334
|
}
|
|
4332
4335
|
var PREVIEW_CAPTURE_PARAM = "hf-capture";
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
+
function scriptJson(value) {
|
|
4337
|
+
return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
4338
|
+
}
|
|
4339
|
+
var earlyErrorsScript = (runtimeUrl) => `<script>(function(){var seen=window.${STUDIO_PREVIEW_ERRORS}=[],kinds=window.${STUDIO_PREVIEW_ERROR_KINDS}=[],known={SyntaxError:1,TypeError:1,ReferenceError:1,RangeError:1},runtime=${scriptJson(new URL(runtimeUrl, "http://x").pathname)};
|
|
4340
|
+
addEventListener("error",function(e){seen.push(e.message||String(e));
|
|
4341
|
+
var name=e.error&&e.error.constructor&&e.error.constructor.name,path="";
|
|
4342
|
+
try{var url=e.filename&&new URL(e.filename,window.location.href);if(url&&url.origin===window.location.origin)path=url.pathname}catch(_){}
|
|
4343
|
+
kinds.push({name:known[name]===1?name:"other",origin:!path?"unknown":path===runtime?"runtime":path.indexOf("/api/projects/")===0?"project":"studio"})});})();</script>`;
|
|
4344
|
+
function injectStudioPreviewAugmentations(html, adapter, signature, projectDir, activeCompositionPath, options) {
|
|
4336
4345
|
const marked = options.capture ? injectTagsAtHeadStart2(
|
|
4337
4346
|
html,
|
|
4338
4347
|
`<meta name="${STUDIO_PREVIEW_MARK_META}" content="${STUDIO_PREVIEW_CAPTURE_MODE}">`
|
|
4339
4348
|
) : injectTagsAtHeadStart2(
|
|
4340
4349
|
lazyPreviewImages(html),
|
|
4341
|
-
`<meta name="${STUDIO_PREVIEW_MARK_META}">${
|
|
4350
|
+
`<meta name="${STUDIO_PREVIEW_MARK_META}">${earlyErrorsScript(adapter.runtimeUrl)}`
|
|
4342
4351
|
);
|
|
4343
4352
|
const withFallback = injectGsapCdnFallback(
|
|
4344
4353
|
injectProjectSignature(
|
|
@@ -4346,7 +4355,7 @@ function injectStudioPreviewAugmentations(html, adapter, projectDir, activeCompo
|
|
|
4346
4355
|
marked,
|
|
4347
4356
|
`<meta name="${GSAP_BASE_URL_META}" content="${escapeGsapUrl(options.gsapBaseUrl)}">`
|
|
4348
4357
|
),
|
|
4349
|
-
|
|
4358
|
+
signature
|
|
4350
4359
|
),
|
|
4351
4360
|
options.gsapBaseUrl
|
|
4352
4361
|
);
|
|
@@ -4451,6 +4460,7 @@ function registerPreviewRoutes(api, adapter) {
|
|
|
4451
4460
|
bundled = injectStudioPreviewAugmentations(
|
|
4452
4461
|
ensureHfIds2(await transformPreviewHtml(bundled, adapter, project, mainCompositionPath)),
|
|
4453
4462
|
adapter,
|
|
4463
|
+
signature,
|
|
4454
4464
|
project.dir,
|
|
4455
4465
|
mainCompositionPath,
|
|
4456
4466
|
{ capture, gsapBaseUrl }
|
|
@@ -4464,7 +4474,7 @@ function registerPreviewRoutes(api, adapter) {
|
|
|
4464
4474
|
mediaCodecProbeCache
|
|
4465
4475
|
);
|
|
4466
4476
|
bundled = addScenePartsManifest(bundled, [`meta[name="${PROJECT_SIGNATURE_META}"]`]);
|
|
4467
|
-
if (
|
|
4477
|
+
if (await createProjectSignatureAsync(project.dir) === signature) {
|
|
4468
4478
|
rememberPreview(builtKey, bundled);
|
|
4469
4479
|
if (!capture) adapter.previewDocuments?.write(builtKey, bundled);
|
|
4470
4480
|
}
|
|
@@ -4479,6 +4489,7 @@ function registerPreviewRoutes(api, adapter) {
|
|
|
4479
4489
|
let fallbackAugmented = injectStudioPreviewAugmentations(
|
|
4480
4490
|
await transformPreviewHtml(fallbackHtml, adapter, project, fallback.compositionPath),
|
|
4481
4491
|
adapter,
|
|
4492
|
+
signature,
|
|
4482
4493
|
project.dir,
|
|
4483
4494
|
fallback.compositionPath,
|
|
4484
4495
|
{ capture, gsapBaseUrl }
|
|
@@ -4579,7 +4590,7 @@ ${etag}`;
|
|
|
4579
4590
|
html = withRootImportMap(html, baseHref);
|
|
4580
4591
|
recordPreviewReferences(project.dir, html);
|
|
4581
4592
|
html = ensureHfIds2(await transformPreviewHtml(html, adapter, project, compPath));
|
|
4582
|
-
html = injectStudioPreviewAugmentations(html, adapter, project.dir, compPath, {
|
|
4593
|
+
html = injectStudioPreviewAugmentations(html, adapter, signature, project.dir, compPath, {
|
|
4583
4594
|
capture,
|
|
4584
4595
|
gsapBaseUrl
|
|
4585
4596
|
});
|
|
@@ -4797,6 +4808,19 @@ import { dirname as dirname5, join as join10 } from "path";
|
|
|
4797
4808
|
import { Readable as Readable2 } from "stream";
|
|
4798
4809
|
import { VALID_CANVAS_RESOLUTIONS } from "@hyperframes/parsers";
|
|
4799
4810
|
import { formatRenderOutputTimestamp, parseFps, fpsToNumber } from "@hyperframes/core";
|
|
4811
|
+
|
|
4812
|
+
// src/helpers/finishedJobs.ts
|
|
4813
|
+
var firstSeenFinishedAt = /* @__PURE__ */ new WeakMap();
|
|
4814
|
+
function forgetJobsFinishedLongerThan(ttlMs, jobs, isFinished, now = Date.now()) {
|
|
4815
|
+
for (const [id, job] of jobs) {
|
|
4816
|
+
if (!isFinished(job)) continue;
|
|
4817
|
+
const finishedAt = firstSeenFinishedAt.get(job) ?? now;
|
|
4818
|
+
firstSeenFinishedAt.set(job, finishedAt);
|
|
4819
|
+
if (now - finishedAt > ttlMs) jobs.delete(id);
|
|
4820
|
+
}
|
|
4821
|
+
}
|
|
4822
|
+
|
|
4823
|
+
// src/routes/render.ts
|
|
4800
4824
|
var VALID_RESOLUTIONS = new Set(VALID_CANVAS_RESOLUTIONS);
|
|
4801
4825
|
var RENDER_MIME = {
|
|
4802
4826
|
".mp4": "video/mp4",
|
|
@@ -4836,12 +4860,7 @@ function registerRenderRoutes(api, adapter) {
|
|
|
4836
4860
|
let cleanupTimer = null;
|
|
4837
4861
|
const cleanupEnabled = () => typeof process !== "undefined" && process.env.NODE_ENV !== "production" && !process.argv.includes("build");
|
|
4838
4862
|
const cleanupFinishedJobs = () => {
|
|
4839
|
-
|
|
4840
|
-
for (const [key, job] of renderJobs) {
|
|
4841
|
-
if (job.status !== "rendering" && now - job.createdAt > TTL_MS) {
|
|
4842
|
-
renderJobs.delete(key);
|
|
4843
|
-
}
|
|
4844
|
-
}
|
|
4863
|
+
forgetJobsFinishedLongerThan(TTL_MS, renderJobs, (job) => job.status !== "rendering");
|
|
4845
4864
|
if (renderJobs.size === 0 && cleanupTimer) {
|
|
4846
4865
|
clearInterval(cleanupTimer);
|
|
4847
4866
|
cleanupTimer = null;
|
|
@@ -4919,7 +4938,6 @@ function registerRenderRoutes(api, adapter) {
|
|
|
4919
4938
|
telemetryOptOut: body.telemetryOptOut === true,
|
|
4920
4939
|
...pageMotionBlur === void 0 ? {} : { pageMotionBlur }
|
|
4921
4940
|
});
|
|
4922
|
-
jobState.createdAt = Date.now();
|
|
4923
4941
|
renderJobs.set(jobId, jobState);
|
|
4924
4942
|
ensureCleanupTimer();
|
|
4925
4943
|
return c.json({ jobId, status: "rendering" });
|
|
@@ -5069,8 +5087,7 @@ function registerRenderRoutes(api, adapter) {
|
|
|
5069
5087
|
id: file.id,
|
|
5070
5088
|
status: file.status,
|
|
5071
5089
|
progress: 100,
|
|
5072
|
-
outputPath: file.path
|
|
5073
|
-
createdAt: file.createdAt
|
|
5090
|
+
outputPath: file.path
|
|
5074
5091
|
});
|
|
5075
5092
|
}
|
|
5076
5093
|
}
|
|
@@ -5389,7 +5406,7 @@ function registerThumbnailRoutes(api, adapter) {
|
|
|
5389
5406
|
const htmlFile = resolveWithinProject(project.dir, compPath);
|
|
5390
5407
|
const source = htmlFile ? readFileOnce(htmlFile) : "not-a-file";
|
|
5391
5408
|
if (source === "not-a-file") return c.json({ error: "not found" }, 404);
|
|
5392
|
-
const inputSignature = compositionInputSignature(project.dir, compPath, projectSignature);
|
|
5409
|
+
const inputSignature = await compositionInputSignature(project.dir, compPath, projectSignature);
|
|
5393
5410
|
const url = new URL(c.req.url, `http://${c.req.header("host") || "localhost"}`);
|
|
5394
5411
|
const rawSeekTime = url.searchParams.get("t");
|
|
5395
5412
|
const parsedSeekTime = rawSeekTime == null ? Number.NaN : parseFloat(rawSeekTime);
|
|
@@ -5472,8 +5489,8 @@ function registerThumbnailRoutes(api, adapter) {
|
|
|
5472
5489
|
if (!generated) return null;
|
|
5473
5490
|
const previewCopiesAtEnd = proxyActivityMark(project.dir);
|
|
5474
5491
|
const afterGeneration = await resolveProjectAndSignature(adapter, project.id);
|
|
5475
|
-
const inputsUnchanged = (signature) => compositionInputSignature(project.dir, compPath, signature) === inputSignature;
|
|
5476
|
-
if (previewCopiesAtStart === null || previewCopiesAtEnd !== previewCopiesAtStart || afterGeneration?.project.dir !== project.dir || !inputsUnchanged(afterGeneration.signature) || !inputsUnchanged(
|
|
5492
|
+
const inputsUnchanged = async (signature) => await compositionInputSignature(project.dir, compPath, signature) === inputSignature;
|
|
5493
|
+
if (previewCopiesAtStart === null || previewCopiesAtEnd !== previewCopiesAtStart || afterGeneration?.project.dir !== project.dir || !await inputsUnchanged(afterGeneration.signature) || !await inputsUnchanged(await createProjectSignatureAsync(project.dir))) {
|
|
5477
5494
|
return generated;
|
|
5478
5495
|
}
|
|
5479
5496
|
mkdirWithinProject(project.dir, cacheDir);
|
|
@@ -6412,12 +6429,11 @@ function registerMediaRoutes(api, adapter, options = {}) {
|
|
|
6412
6429
|
const TTL_MS = 3e5;
|
|
6413
6430
|
const readMediaMetadata = options.probeMediaMetadata ?? probeMediaMetadata;
|
|
6414
6431
|
function cleanupFinishedJobs() {
|
|
6415
|
-
|
|
6416
|
-
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
}
|
|
6432
|
+
forgetJobsFinishedLongerThan(
|
|
6433
|
+
TTL_MS,
|
|
6434
|
+
mediaJobs,
|
|
6435
|
+
(job) => job.status === "complete" || job.status === "failed"
|
|
6436
|
+
);
|
|
6421
6437
|
}
|
|
6422
6438
|
api.get("/projects/:id/media/metadata", async (c) => {
|
|
6423
6439
|
const project = await adapter.resolveProject(c.req.param("id"));
|
|
@@ -6503,7 +6519,6 @@ function registerMediaRoutes(api, adapter, options = {}) {
|
|
|
6503
6519
|
device: normalizeDevice(body.device),
|
|
6504
6520
|
jobId
|
|
6505
6521
|
});
|
|
6506
|
-
state.createdAt = Date.now();
|
|
6507
6522
|
mediaJobs.set(jobId, state);
|
|
6508
6523
|
return c.json({
|
|
6509
6524
|
jobId,
|
|
@@ -118,7 +118,7 @@ interface StudioApiAdapter {
|
|
|
118
118
|
/** Bundle a project directory into a single HTML string, forwarding `options` over the host's own. */
|
|
119
119
|
bundle(projectDir: string, options?: Pick<BundleOptions, "stampHfIds" | "onRead">): Promise<string | null>;
|
|
120
120
|
/** Optional: a cached `createProjectSignature(dir)`; preview caching checks builds against it. */
|
|
121
|
-
getProjectSignature?: (projectDir: string) => string
|
|
121
|
+
getProjectSignature?: (projectDir: string) => string | Promise<string>;
|
|
122
122
|
invalidateProjectSignature?: (projectDir: string) => void;
|
|
123
123
|
loadSharp?: () => Promise<typeof sharp.default>;
|
|
124
124
|
/** Lint a single HTML string. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/studio-server",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.9",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
@@ -88,8 +88,8 @@
|
|
|
88
88
|
"linkedom": "^0.18.12",
|
|
89
89
|
"postcss": "^8.5.8",
|
|
90
90
|
"postcss-selector-parser": "^7.1.2",
|
|
91
|
-
"@hyperframes/parsers": "0.9.
|
|
92
|
-
"@hyperframes/core": "0.9.
|
|
91
|
+
"@hyperframes/parsers": "0.9.9",
|
|
92
|
+
"@hyperframes/core": "0.9.9"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@types/node": "^25.0.10",
|