@hyperframes/studio-server 0.8.220 → 0.8.222
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-UMPRW7BV.js → chunk-CZ2QLV2C.js} +125 -52
- package/dist/{chunk-OF4B2ILS.js → chunk-V6K3WWWU.js} +6 -2
- package/dist/helpers/sourceMutation.js +1 -1
- package/dist/history/index.d.ts +3 -1
- package/dist/history/index.js +3 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +29 -27
- package/package.json +3 -3
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
|
|
8
8
|
// src/history/projectHistory.ts
|
|
9
9
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
10
|
-
import { mkdir as mkdir2, readdir as
|
|
10
|
+
import { mkdir as mkdir2, readdir as readdir4, rm as rm3, rmdir, stat as stat2, writeFile } from "fs/promises";
|
|
11
11
|
import {
|
|
12
12
|
existsSync as existsSync3,
|
|
13
13
|
lstatSync as lstatSync4,
|
|
@@ -358,6 +358,7 @@ async function registerRenderOutput(projectDir, output) {
|
|
|
358
358
|
// src/helpers/projectSignature.ts
|
|
359
359
|
import { createHash as createHash2 } from "crypto";
|
|
360
360
|
import { lstatSync, readFileSync as readFileSync3, readdirSync } from "fs";
|
|
361
|
+
import { lstat, readFile, readdir } from "fs/promises";
|
|
361
362
|
import { extname, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2, sep as sep2 } from "path";
|
|
362
363
|
import { isAtomicTempPath } from "@hyperframes/core/atomic-file";
|
|
363
364
|
import { isProjectIgnoredDir } from "@hyperframes/core/project-folders";
|
|
@@ -408,6 +409,15 @@ function signatureEntryStat(projectDir, entry, file, outputs) {
|
|
|
408
409
|
return null;
|
|
409
410
|
}
|
|
410
411
|
}
|
|
412
|
+
function signatureFileOf(file, stat4) {
|
|
413
|
+
return {
|
|
414
|
+
file,
|
|
415
|
+
mtimeMs: stat4.mtimeMs,
|
|
416
|
+
ctimeMs: stat4.ctimeMs,
|
|
417
|
+
size: stat4.size,
|
|
418
|
+
textContentEligible: isTextContentEligible(file, stat4.size)
|
|
419
|
+
};
|
|
420
|
+
}
|
|
411
421
|
function collectProjectSignatureFiles(projectDir, dir, files, outputs = readRenderOutputsOrNone(projectDir)) {
|
|
412
422
|
let entries;
|
|
413
423
|
try {
|
|
@@ -422,13 +432,7 @@ function collectProjectSignatureFiles(projectDir, dir, files, outputs = readRend
|
|
|
422
432
|
if (stat4.isDirectory()) {
|
|
423
433
|
collectProjectSignatureFiles(projectDir, file, files, outputs);
|
|
424
434
|
} else if (stat4.isFile()) {
|
|
425
|
-
files.push(
|
|
426
|
-
file,
|
|
427
|
-
mtimeMs: stat4.mtimeMs,
|
|
428
|
-
ctimeMs: stat4.ctimeMs,
|
|
429
|
-
size: stat4.size,
|
|
430
|
-
textContentEligible: isTextContentEligible(file, stat4.size)
|
|
431
|
-
});
|
|
435
|
+
files.push(signatureFileOf(file, stat4));
|
|
432
436
|
}
|
|
433
437
|
}
|
|
434
438
|
}
|
|
@@ -444,16 +448,40 @@ function collectProjectSignatureManifestFiles(projectDir, files) {
|
|
|
444
448
|
continue;
|
|
445
449
|
}
|
|
446
450
|
if (stat4.isSymbolicLink() || !stat4.isFile()) continue;
|
|
447
|
-
files.push(
|
|
448
|
-
file,
|
|
449
|
-
mtimeMs: stat4.mtimeMs,
|
|
450
|
-
ctimeMs: stat4.ctimeMs,
|
|
451
|
-
size: stat4.size,
|
|
452
|
-
textContentEligible: isTextContentEligible(file, stat4.size)
|
|
453
|
-
});
|
|
451
|
+
files.push(signatureFileOf(file, stat4));
|
|
454
452
|
seen.add(file);
|
|
455
453
|
}
|
|
456
454
|
}
|
|
455
|
+
async function signatureEntryStatAsync(projectDir, entry, file, outputs) {
|
|
456
|
+
if (isSkippedEntry(entry) || !isPathWithin(projectDir, file)) return null;
|
|
457
|
+
if (isRenderOutput(projectDir, file, outputs)) return null;
|
|
458
|
+
try {
|
|
459
|
+
const stat4 = await lstat(file);
|
|
460
|
+
return stat4.isSymbolicLink() ? null : stat4;
|
|
461
|
+
} catch {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
async function collectProjectSignatureFilesAsync(projectDir, dir, files, outputs) {
|
|
466
|
+
let entries;
|
|
467
|
+
try {
|
|
468
|
+
entries = (await readdir(dir)).sort();
|
|
469
|
+
} catch {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const paths = entries.map((entry) => resolve2(dir, entry));
|
|
473
|
+
const stats = await Promise.all(
|
|
474
|
+
entries.map((entry, i) => signatureEntryStatAsync(projectDir, entry, paths[i], outputs))
|
|
475
|
+
);
|
|
476
|
+
for (const [i, stat4] of stats.entries()) {
|
|
477
|
+
if (!stat4) continue;
|
|
478
|
+
if (stat4.isDirectory()) {
|
|
479
|
+
await collectProjectSignatureFilesAsync(projectDir, paths[i], files, outputs);
|
|
480
|
+
} else if (stat4.isFile()) {
|
|
481
|
+
files.push(signatureFileOf(paths[i], stat4));
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
457
485
|
function createProjectFingerprint(projectDir, files) {
|
|
458
486
|
const hash = createHash2("sha256");
|
|
459
487
|
for (const entry of files) {
|
|
@@ -476,6 +504,17 @@ function collectProjectFiles(normalizedProjectDir) {
|
|
|
476
504
|
collectProjectSignatureManifestFiles(normalizedProjectDir, collected);
|
|
477
505
|
return collected;
|
|
478
506
|
}
|
|
507
|
+
async function collectProjectFilesAsync(normalizedProjectDir) {
|
|
508
|
+
const collected = [];
|
|
509
|
+
await collectProjectSignatureFilesAsync(
|
|
510
|
+
normalizedProjectDir,
|
|
511
|
+
normalizedProjectDir,
|
|
512
|
+
collected,
|
|
513
|
+
readRenderOutputsOrNone(normalizedProjectDir)
|
|
514
|
+
);
|
|
515
|
+
collectProjectSignatureManifestFiles(normalizedProjectDir, collected);
|
|
516
|
+
return collected;
|
|
517
|
+
}
|
|
479
518
|
function listProjectFiles(projectDir) {
|
|
480
519
|
const normalizedProjectDir = resolve2(projectDir);
|
|
481
520
|
return collectProjectFiles(normalizedProjectDir).map((entry) => ({
|
|
@@ -493,48 +532,79 @@ async function resolveProjectAndSignature(adapter, projectId) {
|
|
|
493
532
|
if (!project) return null;
|
|
494
533
|
return { project, signature: resolveProjectSignature(adapter, project.dir) };
|
|
495
534
|
}
|
|
496
|
-
function
|
|
497
|
-
const normalizedProjectDir = resolve2(projectDir);
|
|
498
|
-
const signedAt = Date.now();
|
|
499
|
-
const collected = collectProjectFiles(normalizedProjectDir);
|
|
535
|
+
function planSignature(dir, collected, excluding, signedAt) {
|
|
500
536
|
const files = collected.filter(
|
|
501
|
-
(entry) => !excluding.has(relative2(
|
|
537
|
+
(entry) => !excluding.has(relative2(dir, entry.file).split(sep2).join("/"))
|
|
502
538
|
);
|
|
503
539
|
files.sort((a, b) => a.file.localeCompare(b.file));
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
540
|
+
const cacheKey = excluding.size ? `${dir}\0${createHash2("sha256").update([...excluding].sort().join("\0")).digest("hex")}` : dir;
|
|
541
|
+
return { dir, files, cacheKey, fingerprint: createProjectFingerprint(dir, files), signedAt };
|
|
542
|
+
}
|
|
543
|
+
function hashSignatureEntry(hash, dir, entry, content) {
|
|
544
|
+
hash.update(relative2(dir, entry.file));
|
|
545
|
+
hash.update("\0");
|
|
546
|
+
hash.update(String(entry.size));
|
|
547
|
+
hash.update("\0");
|
|
548
|
+
hash.update(content ?? String(entry.mtimeMs));
|
|
549
|
+
hash.update("\0");
|
|
550
|
+
}
|
|
551
|
+
function finishSignature(plan, hash) {
|
|
552
|
+
const signature = hash.digest("hex").slice(0, 24);
|
|
553
|
+
const settledATickBeforeSigning = plan.files.every(
|
|
554
|
+
(entry) => Math.max(entry.mtimeMs, entry.ctimeMs) < plan.signedAt - COARSEST_FILE_TIME_TICK_MS
|
|
555
|
+
);
|
|
556
|
+
if (settledATickBeforeSigning) {
|
|
557
|
+
projectSignatureCache.set(plan.cacheKey, { fingerprint: plan.fingerprint, signature });
|
|
558
|
+
}
|
|
559
|
+
return signature;
|
|
560
|
+
}
|
|
561
|
+
var cachedSignature = (plan) => {
|
|
562
|
+
const cached = projectSignatureCache.get(plan.cacheKey);
|
|
563
|
+
return cached?.fingerprint === plan.fingerprint ? cached.signature : void 0;
|
|
564
|
+
};
|
|
565
|
+
function createProjectSignature(projectDir, excluding = /* @__PURE__ */ new Set()) {
|
|
566
|
+
const dir = resolve2(projectDir);
|
|
567
|
+
const plan = planSignature(dir, collectProjectFiles(dir), excluding, Date.now());
|
|
568
|
+
const cached = cachedSignature(plan);
|
|
569
|
+
if (cached !== void 0) return cached;
|
|
508
570
|
const hash = createHash2("sha256");
|
|
509
|
-
for (const entry of files) {
|
|
510
|
-
|
|
511
|
-
hash.update(relativePath);
|
|
512
|
-
hash.update("\0");
|
|
513
|
-
hash.update(String(entry.size));
|
|
514
|
-
hash.update("\0");
|
|
571
|
+
for (const entry of plan.files) {
|
|
572
|
+
let content = null;
|
|
515
573
|
if (entry.textContentEligible) {
|
|
516
574
|
try {
|
|
517
|
-
|
|
575
|
+
content = readFileSync3(entry.file);
|
|
518
576
|
} catch {
|
|
519
|
-
|
|
577
|
+
content = null;
|
|
520
578
|
}
|
|
521
|
-
} else {
|
|
522
|
-
hash.update(String(entry.mtimeMs));
|
|
523
579
|
}
|
|
524
|
-
hash
|
|
580
|
+
hashSignatureEntry(hash, dir, entry, content);
|
|
525
581
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
582
|
+
return finishSignature(plan, hash);
|
|
583
|
+
}
|
|
584
|
+
var SIGNATURE_READ_BATCH = 32;
|
|
585
|
+
async function createProjectSignatureAsync(projectDir, excluding = /* @__PURE__ */ new Set()) {
|
|
586
|
+
const dir = resolve2(projectDir);
|
|
587
|
+
const signedAt = Date.now();
|
|
588
|
+
const plan = planSignature(dir, await collectProjectFilesAsync(dir), excluding, signedAt);
|
|
589
|
+
const cached = cachedSignature(plan);
|
|
590
|
+
if (cached !== void 0) return cached;
|
|
591
|
+
const hash = createHash2("sha256");
|
|
592
|
+
for (let at = 0; at < plan.files.length; at += SIGNATURE_READ_BATCH) {
|
|
593
|
+
const batch = plan.files.slice(at, at + SIGNATURE_READ_BATCH);
|
|
594
|
+
const contents = await Promise.all(
|
|
595
|
+
batch.map(
|
|
596
|
+
(entry) => entry.textContentEligible ? readFile(entry.file).catch(() => null) : null
|
|
597
|
+
)
|
|
598
|
+
);
|
|
599
|
+
for (const [i, entry] of batch.entries()) hashSignatureEntry(hash, dir, entry, contents[i]);
|
|
600
|
+
}
|
|
601
|
+
return finishSignature(plan, hash);
|
|
532
602
|
}
|
|
533
603
|
|
|
534
604
|
// src/history/blobStore.ts
|
|
535
605
|
import { createHash as createHash3, randomUUID as randomUUID3 } from "crypto";
|
|
536
606
|
import { constants, createReadStream, createWriteStream } from "fs";
|
|
537
|
-
import { copyFile, mkdir, open, readdir, readFile, rm, stat } from "fs/promises";
|
|
607
|
+
import { copyFile, mkdir, open, readdir as readdir2, readFile as readFile2, rm, stat } from "fs/promises";
|
|
538
608
|
import { dirname, join as join2 } from "path";
|
|
539
609
|
import { pipeline } from "stream/promises";
|
|
540
610
|
import { atomicTempPath } from "@hyperframes/core/atomic-file";
|
|
@@ -577,7 +647,7 @@ function blobPath(dir, hash) {
|
|
|
577
647
|
if (!BLOB_HASH.test(hash)) throw new Error("That is not a history blob.");
|
|
578
648
|
return join2(dir, hash.slice(0, 2), hash);
|
|
579
649
|
}
|
|
580
|
-
var readBlob = (dir, hash) =>
|
|
650
|
+
var readBlob = (dir, hash) => readFile2(blobPath(dir, hash));
|
|
581
651
|
async function hashFile(path) {
|
|
582
652
|
const hash = createHash3("sha256");
|
|
583
653
|
for await (const chunk of createReadStream(path)) hash.update(chunk);
|
|
@@ -630,7 +700,7 @@ async function writeInPlace(temp, to, hash) {
|
|
|
630
700
|
if (outcome === "mismatch")
|
|
631
701
|
throw new Error("The file was written in place, but it does not match the copy history kept.");
|
|
632
702
|
}
|
|
633
|
-
var listDir = (path) =>
|
|
703
|
+
var listDir = (path) => readdir2(path, { withFileTypes: true }).catch((error) => {
|
|
634
704
|
if (error.code === "ENOENT") return [];
|
|
635
705
|
throw error;
|
|
636
706
|
});
|
|
@@ -687,7 +757,7 @@ async function openBlobStore(dir) {
|
|
|
687
757
|
},
|
|
688
758
|
reference: (absPath) => hashFile(absPath),
|
|
689
759
|
has: (hash) => sizes.has(hash) || asideSizes.has(hash),
|
|
690
|
-
read: (hash) =>
|
|
760
|
+
read: (hash) => readFile2(pathOf(hash)),
|
|
691
761
|
writeTo: async (hash, absPath, beforeReplace) => cloneOrCopy(pathOf(hash), absPath, hash, beforeReplace),
|
|
692
762
|
async release(held) {
|
|
693
763
|
for (const [hash, path] of held) {
|
|
@@ -751,7 +821,8 @@ var MEDIA_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
751
821
|
".opus"
|
|
752
822
|
]);
|
|
753
823
|
var COPY_NOTHING_ABOVE_BYTES = 64 * 1024 ** 2;
|
|
754
|
-
var
|
|
824
|
+
var isUncopiedMedia = (path) => MEDIA_EXTENSIONS.has(extname2(path).toLowerCase());
|
|
825
|
+
var isUncopied = (path, size) => size > COPY_NOTHING_ABOVE_BYTES || isUncopiedMedia(path);
|
|
755
826
|
function uncopiedOnlyHashes(log, sizeOf) {
|
|
756
827
|
const copied = /* @__PURE__ */ new Set();
|
|
757
828
|
const uncopied = /* @__PURE__ */ new Set();
|
|
@@ -770,7 +841,7 @@ function uncopiedOnlyHashes(log, sizeOf) {
|
|
|
770
841
|
// src/history/pruneHistories.ts
|
|
771
842
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
772
843
|
import { readdirSync as readdirSync2, readFileSync as readFileSync5, renameSync, statSync as statSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
773
|
-
import { lstat, readdir as
|
|
844
|
+
import { lstat as lstat2, readdir as readdir3, rm as rm2 } from "fs/promises";
|
|
774
845
|
import { tmpdir } from "os";
|
|
775
846
|
import { dirname as dirname2, join as join4 } from "path";
|
|
776
847
|
|
|
@@ -966,9 +1037,9 @@ function lastUsed(home) {
|
|
|
966
1037
|
}
|
|
967
1038
|
async function bytesIn(dir) {
|
|
968
1039
|
let total = 0;
|
|
969
|
-
for (const entry of await
|
|
1040
|
+
for (const entry of await readdir3(dir, { withFileTypes: true })) {
|
|
970
1041
|
const path = join4(dir, entry.name);
|
|
971
|
-
total += entry.isDirectory() ? await bytesIn(path) : (await
|
|
1042
|
+
total += entry.isDirectory() ? await bytesIn(path) : (await lstat2(path)).size;
|
|
972
1043
|
}
|
|
973
1044
|
return total;
|
|
974
1045
|
}
|
|
@@ -1781,7 +1852,7 @@ var isMissingFolder = (error) => ["ENOENT", "ENOTDIR"].includes(error.code ?? ""
|
|
|
1781
1852
|
async function removeEmptyFolders(dir) {
|
|
1782
1853
|
let entries;
|
|
1783
1854
|
try {
|
|
1784
|
-
entries = await
|
|
1855
|
+
entries = await readdir4(dir, { withFileTypes: true });
|
|
1785
1856
|
} catch (error) {
|
|
1786
1857
|
if (isMissingFolder(error)) return;
|
|
1787
1858
|
throw error;
|
|
@@ -2653,7 +2724,7 @@ var Engine = class {
|
|
|
2653
2724
|
const dest = resolve8(emptyDir);
|
|
2654
2725
|
if (isWithin(this.dir, dest))
|
|
2655
2726
|
throw new Error(`Checkout writes outside the project only: ${dest}`);
|
|
2656
|
-
if ((await
|
|
2727
|
+
if ((await readdir4(dest).catch(missingIsEmpty)).length > 0)
|
|
2657
2728
|
throw new Error(`Checkout writes into an empty folder only: ${dest}`);
|
|
2658
2729
|
const files = manifestAround(this.log, entryId, side);
|
|
2659
2730
|
for (const [path, hash] of files)
|
|
@@ -2662,7 +2733,7 @@ var Engine = class {
|
|
|
2662
2733
|
try {
|
|
2663
2734
|
for (const [path, hash] of files) await this.blobs.writeTo(hash, join8(dest, path));
|
|
2664
2735
|
} catch (error) {
|
|
2665
|
-
for (const name of await
|
|
2736
|
+
for (const name of await readdir4(dest).catch(() => []))
|
|
2666
2737
|
await rm3(join8(dest, name), { recursive: true, force: true });
|
|
2667
2738
|
throw error;
|
|
2668
2739
|
}
|
|
@@ -2862,6 +2933,7 @@ export {
|
|
|
2862
2933
|
resolveProjectSignature,
|
|
2863
2934
|
resolveProjectAndSignature,
|
|
2864
2935
|
createProjectSignature,
|
|
2936
|
+
createProjectSignatureAsync,
|
|
2865
2937
|
fileContentVersion,
|
|
2866
2938
|
DELETED_VERSION,
|
|
2867
2939
|
settledFileTag,
|
|
@@ -2872,6 +2944,7 @@ export {
|
|
|
2872
2944
|
consumeFileWriteReceipt,
|
|
2873
2945
|
serveWhileOpen,
|
|
2874
2946
|
onRestoredInPlace,
|
|
2947
|
+
isUncopiedMedia,
|
|
2875
2948
|
HistoryIdError,
|
|
2876
2949
|
listProjectHistories,
|
|
2877
2950
|
pruneGoneProjectHistories,
|
|
@@ -13,7 +13,11 @@ import {
|
|
|
13
13
|
mintHfId,
|
|
14
14
|
walkCompositionDescendants
|
|
15
15
|
} from "@hyperframes/parsers/hf-ids";
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
readClipTiming,
|
|
18
|
+
SPLIT_BOUNDARY_EPSILON_S,
|
|
19
|
+
writeClipTiming
|
|
20
|
+
} from "@hyperframes/core/composition-contract";
|
|
17
21
|
import { relinkSplitHalves } from "@hyperframes/core/media-link";
|
|
18
22
|
|
|
19
23
|
// src/helpers/sourceStyleMutation.ts
|
|
@@ -334,7 +338,7 @@ function splitElementInHtml(source, target, splitTime, newId, fallbackTiming) {
|
|
|
334
338
|
start = fallbackTiming.start;
|
|
335
339
|
duration = fallbackTiming.duration;
|
|
336
340
|
}
|
|
337
|
-
if (duration <= 0 || splitTime
|
|
341
|
+
if (duration <= 0 || splitTime < start + SPLIT_BOUNDARY_EPSILON_S || splitTime > start + duration - SPLIT_BOUNDARY_EPSILON_S) {
|
|
338
342
|
return { html: source, matched: false, newId: null };
|
|
339
343
|
}
|
|
340
344
|
newId = nextUniqueId(document, newId);
|
package/dist/history/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ declare function reclaimUncopiedBlobs(historyRoot: string, { dryRun, onError }?:
|
|
|
11
11
|
onError?: (error: unknown) => void;
|
|
12
12
|
}): Promise<ReclaimedHistory[]>;
|
|
13
13
|
|
|
14
|
+
declare const isUncopiedMedia: (path: string) => boolean;
|
|
15
|
+
|
|
14
16
|
declare class HistoryBusyError extends Error {
|
|
15
17
|
readonly pid: number;
|
|
16
18
|
readonly url?: string | undefined;
|
|
@@ -152,4 +154,4 @@ declare function registerRenderOutput(projectDir: string, output: string): Promi
|
|
|
152
154
|
/** Explicit outputs remain user evidence even when reusing a managed UUID folder. */
|
|
153
155
|
declare function retainSnapshotOutput(project: string, path: string): void;
|
|
154
156
|
|
|
155
|
-
export { type ArtifactCapture, type ArtifactInput, type ArtifactRecord, HistoryBusyError, HistoryIdError, HistoryTarget, HistoryWho, type InPlaceOutcome, ProjectHistory, type ProjectHistoryRecord, type PrunedHistory, type ReclaimedHistory, type RenderRecord, type VideoState, artifactDirectory, beginArtifactCapture, finishSnapshotRun, forgetRecordedArtifacts, historyCache, listProjectHistories, onRestoredInPlace, pruneGoneProjectHistories, reclaimUncopiedBlobs, recordArtifact, recordArtifacts, recordRenderSuccess, registerRenderOutput, retainSnapshotOutput };
|
|
157
|
+
export { type ArtifactCapture, type ArtifactInput, type ArtifactRecord, HistoryBusyError, HistoryIdError, HistoryTarget, HistoryWho, type InPlaceOutcome, ProjectHistory, type ProjectHistoryRecord, type PrunedHistory, type ReclaimedHistory, type RenderRecord, type VideoState, artifactDirectory, beginArtifactCapture, finishSnapshotRun, forgetRecordedArtifacts, historyCache, isUncopiedMedia, listProjectHistories, onRestoredInPlace, pruneGoneProjectHistories, reclaimUncopiedBlobs, recordArtifact, recordArtifacts, recordRenderSuccess, registerRenderOutput, retainSnapshotOutput };
|
package/dist/history/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
finishSnapshotRun,
|
|
13
13
|
forgetRecordedArtifacts,
|
|
14
14
|
historyCache,
|
|
15
|
+
isUncopiedMedia,
|
|
15
16
|
listProjectHistories,
|
|
16
17
|
onRestoredInPlace,
|
|
17
18
|
openProjectHistory,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
recordRenderSuccess,
|
|
24
25
|
registerRenderOutput,
|
|
25
26
|
retainSnapshotOutput
|
|
26
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-CZ2QLV2C.js";
|
|
27
28
|
import "../chunk-QF7MFJJU.js";
|
|
28
29
|
import "../chunk-SVQFE44C.js";
|
|
29
30
|
import "../chunk-L3HJVTQE.js";
|
|
@@ -41,6 +42,7 @@ export {
|
|
|
41
42
|
finishSnapshotRun,
|
|
42
43
|
forgetRecordedArtifacts,
|
|
43
44
|
historyCache,
|
|
45
|
+
isUncopiedMedia,
|
|
44
46
|
listProjectHistories,
|
|
45
47
|
onRestoredInPlace,
|
|
46
48
|
openProjectHistory,
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Hono } from 'hono';
|
|
|
2
2
|
import { S as StudioApiAdapter, P as PreviewDocumentStore, M as MediaProcessingJobState } from './mediaProxyPreview-BnQDzKj1.js';
|
|
3
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-BnQDzKj1.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
|
-
export { ArtifactCapture, ArtifactInput, ArtifactRecord, HistoryBusyError, HistoryIdError, InPlaceOutcome, ProjectHistoryRecord, PrunedHistory, ReclaimedHistory, RenderRecord, VideoState, artifactDirectory, beginArtifactCapture, finishSnapshotRun, forgetRecordedArtifacts, historyCache, listProjectHistories, onRestoredInPlace, pruneGoneProjectHistories, reclaimUncopiedBlobs, recordArtifact, recordArtifacts, recordRenderSuccess, registerRenderOutput, retainSnapshotOutput } from './history/index.js';
|
|
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';
|
|
7
7
|
export { walkDir } from './helpers/safePath.js';
|
|
8
8
|
export { stampProjectHfIds } from './helpers/hfIdPersist.js';
|
|
@@ -54,6 +54,8 @@ declare function affectsProjectSignature(projectDir: string, changedPath: string
|
|
|
54
54
|
* `excluding` (project-relative paths) leaves those files out.
|
|
55
55
|
*/
|
|
56
56
|
declare function createProjectSignature(projectDir: string, excluding?: ReadonlySet<string>): string;
|
|
57
|
+
/** `createProjectSignature` without blocking the event loop: the same signature, with the walk and reads awaited. */
|
|
58
|
+
declare function createProjectSignatureAsync(projectDir: string, excluding?: ReadonlySet<string>): Promise<string>;
|
|
57
59
|
|
|
58
60
|
/**
|
|
59
61
|
* Compositions whose rendered frames a write at `changedPath` can change, or `null` for all
|
|
@@ -230,4 +232,4 @@ type BackgroundRemovalRender = (options: {
|
|
|
230
232
|
}>;
|
|
231
233
|
declare function createBackgroundRemovalJob(opts: BackgroundRemovalJobOptions, render: BackgroundRemovalRender): MediaProcessingJobState;
|
|
232
234
|
|
|
233
|
-
export { type AppliedFileMutation, type BackgroundRemovalRender, DELETED_VERSION, type DuplicateElementResult, type FileMutationInput, type FileWriteReceipt, MAX_UPLOAD_BYTES, MIME_TYPES, MediaProcessingJobState, PREVIEW_BUNDLE_OPTIONS, STUDIO_SIGNATURE_MANIFEST_PATHS, SourceMutationTarget, StudioApiAdapter, type ThumbnailOutputDimensions, affectsPreview, affectsProjectSignature, applyFileMutations, buildSubCompositionHtml, cleanupProxyCache, compositionsAffectedBy, consumeFileWriteReceipt, createBackgroundRemovalJob, createPreviewDocumentStore, createProjectSignature, createStudioApi, duplicateElementInHtml, fileContentVersion, getMimeType, identifyFileWrite, requestSubPath, settledFileTag, thumbnailDeviceScaleFactor };
|
|
235
|
+
export { type AppliedFileMutation, type BackgroundRemovalRender, DELETED_VERSION, type DuplicateElementResult, type FileMutationInput, type FileWriteReceipt, MAX_UPLOAD_BYTES, MIME_TYPES, MediaProcessingJobState, PREVIEW_BUNDLE_OPTIONS, STUDIO_SIGNATURE_MANIFEST_PATHS, SourceMutationTarget, StudioApiAdapter, type ThumbnailOutputDimensions, affectsPreview, affectsProjectSignature, applyFileMutations, buildSubCompositionHtml, cleanupProxyCache, compositionsAffectedBy, consumeFileWriteReceipt, createBackgroundRemovalJob, createPreviewDocumentStore, createProjectSignature, createProjectSignatureAsync, createStudioApi, duplicateElementInHtml, fileContentVersion, getMimeType, identifyFileWrite, requestSubPath, settledFileTag, thumbnailDeviceScaleFactor };
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
splitElementInHtml,
|
|
18
18
|
unwrapElementsFromHtml,
|
|
19
19
|
wrapElementsInHtml
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-V6K3WWWU.js";
|
|
21
21
|
import {
|
|
22
22
|
isCompositionSource,
|
|
23
23
|
stampProjectHfIds
|
|
@@ -42,12 +42,14 @@ import {
|
|
|
42
42
|
clearFileWriteReceipt,
|
|
43
43
|
consumeFileWriteReceipt,
|
|
44
44
|
createProjectSignature,
|
|
45
|
+
createProjectSignatureAsync,
|
|
45
46
|
createWriteToken,
|
|
46
47
|
fileContentVersion,
|
|
47
48
|
finishSnapshotRun,
|
|
48
49
|
forgetRecordedArtifacts,
|
|
49
50
|
historyCache,
|
|
50
51
|
identifyFileWrite,
|
|
52
|
+
isUncopiedMedia,
|
|
51
53
|
listProjectHistories,
|
|
52
54
|
onRestoredInPlace,
|
|
53
55
|
openProjectHistory,
|
|
@@ -64,7 +66,7 @@ import {
|
|
|
64
66
|
retainSnapshotOutput,
|
|
65
67
|
serveWhileOpen,
|
|
66
68
|
settledFileTag
|
|
67
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-CZ2QLV2C.js";
|
|
68
70
|
import {
|
|
69
71
|
clearElementScreenshotIsolation,
|
|
70
72
|
getElementScreenshotClip
|
|
@@ -351,7 +353,7 @@ function withRootPathsRelative(html, base) {
|
|
|
351
353
|
function rewriteRelativePaths(root, compPath, projectDir) {
|
|
352
354
|
const assetExists = (path) => existsSync(join2(projectDir, path));
|
|
353
355
|
rewriteAssetPaths(
|
|
354
|
-
root.querySelectorAll("[src], [href]"),
|
|
356
|
+
root.querySelectorAll("[src], [href], [srcset]"),
|
|
355
357
|
compPath,
|
|
356
358
|
(el, attr) => el.getAttribute(attr),
|
|
357
359
|
(el, attr, value) => el.setAttribute(attr, value),
|
|
@@ -1020,11 +1022,9 @@ function validateUploadedMediaBuffer(fileName, buffer, runner = defaultRunner) {
|
|
|
1020
1022
|
// src/helpers/backupJournal.ts
|
|
1021
1023
|
import { readdirSync, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
1022
1024
|
import { Buffer as Buffer2 } from "buffer";
|
|
1025
|
+
import { createHash as createHash2 } from "crypto";
|
|
1023
1026
|
import { join as join5, relative as relative2 } from "path";
|
|
1024
1027
|
var DEFAULT_KEEP_PER_FILE = 10;
|
|
1025
|
-
function backupKeyForPath(path) {
|
|
1026
|
-
return Buffer2.from(path, "utf-8").toString("base64url");
|
|
1027
|
-
}
|
|
1028
1028
|
function timestampPrefix() {
|
|
1029
1029
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
1030
1030
|
}
|
|
@@ -1041,10 +1041,11 @@ function snapshotBeforeWrite(projectDir, absPath, options = {}) {
|
|
|
1041
1041
|
const relativePath = relative2(projectDir, absPath);
|
|
1042
1042
|
const backupDir = join5(projectDir, ".hyperframes", "backup");
|
|
1043
1043
|
mkdirWithinProject(projectDir, backupDir);
|
|
1044
|
-
const
|
|
1044
|
+
const pathKey2 = Buffer2.from(relativePath, "utf-8").toString("base64url");
|
|
1045
|
+
const backupKey = pathKey2.length <= 200 ? pathKey2 : `sha256~${createHash2("sha256").update(relativePath).digest("hex")}`;
|
|
1045
1046
|
const backupPath = nextBackupPath(backupDir, backupKey);
|
|
1046
1047
|
writeFileSync3(backupPath, content);
|
|
1047
|
-
pruneBackups(backupDir, backupKey, options.keepPerFile ?? DEFAULT_KEEP_PER_FILE);
|
|
1048
|
+
pruneBackups(backupDir, [pathKey2, backupKey], options.keepPerFile ?? DEFAULT_KEEP_PER_FILE);
|
|
1048
1049
|
return { backupPath };
|
|
1049
1050
|
} catch (error) {
|
|
1050
1051
|
if (isProjectRootMissing(error)) throw error;
|
|
@@ -1071,11 +1072,10 @@ function nextBackupPath(backupDir, backupKey) {
|
|
|
1071
1072
|
counter += 1;
|
|
1072
1073
|
}
|
|
1073
1074
|
}
|
|
1074
|
-
function pruneBackups(backupDir,
|
|
1075
|
+
function pruneBackups(backupDir, backupKeys, keepPerFile) {
|
|
1075
1076
|
const keep = Math.max(1, Math.floor(keepPerFile));
|
|
1076
|
-
const suffix =
|
|
1077
|
-
const
|
|
1078
|
-
const matches = readdirSync(backupDir).filter((name) => name.endsWith(suffix) || numberedSuffix.test(name)).map((name) => join5(backupDir, name)).sort((a, b) => {
|
|
1077
|
+
const suffix = new RegExp(`-(?:${backupKeys.join("|")})(?:-\\d+)?$`);
|
|
1078
|
+
const matches = readdirSync(backupDir).filter((name) => suffix.test(name)).map((name) => join5(backupDir, name)).sort((a, b) => {
|
|
1079
1079
|
return b.localeCompare(a);
|
|
1080
1080
|
});
|
|
1081
1081
|
for (const file of matches.slice(keep)) {
|
|
@@ -3915,7 +3915,7 @@ import { createReadStream, existsSync as existsSync5, readFileSync as readFileSy
|
|
|
3915
3915
|
import { stripSdrPngColourTags } from "@hyperframes/core/compiler/png-colour-tags";
|
|
3916
3916
|
import { Readable } from "stream";
|
|
3917
3917
|
import { join as join8, resolve as resolve4 } from "path";
|
|
3918
|
-
import { createHash as
|
|
3918
|
+
import { createHash as createHash3 } from "crypto";
|
|
3919
3919
|
import {
|
|
3920
3920
|
AFTER_FONTS_SCRIPT_TYPE,
|
|
3921
3921
|
addScenePartsManifest,
|
|
@@ -4315,7 +4315,7 @@ function parsePreviewVariablesParam(raw) {
|
|
|
4315
4315
|
}
|
|
4316
4316
|
function variablesEtagSalt(raw) {
|
|
4317
4317
|
if (!raw) return "";
|
|
4318
|
-
return `:vars:${
|
|
4318
|
+
return `:vars:${createHash3("sha1").update(raw).digest("hex").slice(0, 12)}`;
|
|
4319
4319
|
}
|
|
4320
4320
|
function previewVariablesFromRequest(rawVariables) {
|
|
4321
4321
|
const parse2 = parsePreviewVariablesParam(rawVariables);
|
|
@@ -4412,7 +4412,7 @@ function resolvePreviewGsapBaseUrl(adapter) {
|
|
|
4412
4412
|
}
|
|
4413
4413
|
function registerPreviewRoutes(api, adapter) {
|
|
4414
4414
|
const gsapBaseUrl = resolvePreviewGsapBaseUrl(adapter);
|
|
4415
|
-
const gsapEtagSalt = `:gsap:${
|
|
4415
|
+
const gsapEtagSalt = `:gsap:${createHash3("sha1").update(gsapBaseUrl).digest("hex").slice(0, 12)}`;
|
|
4416
4416
|
const previewCacheHeaders = (etag) => ({
|
|
4417
4417
|
"Cache-Control": "private, no-cache",
|
|
4418
4418
|
ETag: etag
|
|
@@ -4547,7 +4547,7 @@ ${etag}`;
|
|
|
4547
4547
|
if (!compFile || !existsSync5(compFile) || !statSync4(compFile).isFile()) {
|
|
4548
4548
|
return c.text("not found", 404);
|
|
4549
4549
|
}
|
|
4550
|
-
const compPathHash =
|
|
4550
|
+
const compPathHash = createHash3("sha1").update(compPath).digest("hex");
|
|
4551
4551
|
const capture = c.req.query(PREVIEW_CAPTURE_PARAM) !== void 0;
|
|
4552
4552
|
const etag = `"comp:v2:${compPathHash}:${signature}${gsapEtagSalt}${variablesEtagSalt(vars.raw)}${capture ? ":capture" : ""}"`;
|
|
4553
4553
|
const ifNoneMatch = c.req.header("If-None-Match");
|
|
@@ -5052,7 +5052,7 @@ function registerRenderRoutes(api, adapter) {
|
|
|
5052
5052
|
// src/routes/imageThumbnail.ts
|
|
5053
5053
|
import { HTTPException } from "hono/http-exception";
|
|
5054
5054
|
import { open, stat } from "fs/promises";
|
|
5055
|
-
import { createHash as
|
|
5055
|
+
import { createHash as createHash4 } from "crypto";
|
|
5056
5056
|
|
|
5057
5057
|
// src/routes/thumbnailGenerationCoordinator.ts
|
|
5058
5058
|
var ThumbnailGenerationCoordinator = class {
|
|
@@ -5230,7 +5230,7 @@ function registerImageThumbnailRoutes(api, adapter) {
|
|
|
5230
5230
|
api.get("/projects/:id/image-thumbnail/*", async (c) => {
|
|
5231
5231
|
try {
|
|
5232
5232
|
const { path, info } = await resolveSource(adapter, c.req.param("id"), c.req.url);
|
|
5233
|
-
const key =
|
|
5233
|
+
const key = createHash4("sha256").update(JSON.stringify([path, info.dev, info.ino, info.size, info.mtimeMs, info.ctimeMs])).digest("hex");
|
|
5234
5234
|
const etag = `"${key}"`;
|
|
5235
5235
|
c.header("ETag", etag);
|
|
5236
5236
|
c.header("Cache-Control", "private, no-cache");
|
|
@@ -5270,7 +5270,7 @@ import {
|
|
|
5270
5270
|
writeFileSync as writeFileSync4
|
|
5271
5271
|
} from "fs";
|
|
5272
5272
|
import { join as join11 } from "path";
|
|
5273
|
-
import { createHash as
|
|
5273
|
+
import { createHash as createHash5, randomUUID as randomUUID2 } from "crypto";
|
|
5274
5274
|
var THUMBNAIL_CACHE_VERSION = "v5";
|
|
5275
5275
|
var THUMBNAIL_MAX_OUTPUT_WIDTH = 240;
|
|
5276
5276
|
var THUMBNAIL_MAX_OUTPUT_HEIGHT = 135;
|
|
@@ -5344,7 +5344,7 @@ function readFileOnce(file) {
|
|
|
5344
5344
|
function manifestKey(file) {
|
|
5345
5345
|
const manifest = readFileOnce(file);
|
|
5346
5346
|
if (typeof manifest === "string") return { key: "", mtimeMs: -Infinity };
|
|
5347
|
-
const hash =
|
|
5347
|
+
const hash = createHash5("sha1").update(manifest.data).digest("hex").slice(0, 16);
|
|
5348
5348
|
return { key: `_${hash}`, mtimeMs: Math.round(manifest.mtimeMs) };
|
|
5349
5349
|
}
|
|
5350
5350
|
function registerThumbnailRoutes(api, adapter) {
|
|
@@ -5381,7 +5381,7 @@ function registerThumbnailRoutes(api, adapter) {
|
|
|
5381
5381
|
let sourceKey = "";
|
|
5382
5382
|
if (source !== "missing") {
|
|
5383
5383
|
const html = source.data.toString("utf-8");
|
|
5384
|
-
sourceKey = `_${
|
|
5384
|
+
sourceKey = `_${createHash5("sha1").update(html).digest("hex").slice(0, 16)}`;
|
|
5385
5385
|
sourceMtime = Math.round(source.mtimeMs);
|
|
5386
5386
|
if (!vpWidth) {
|
|
5387
5387
|
const wMatch = html.match(/data-width=["'](\d+)["']/);
|
|
@@ -5397,9 +5397,9 @@ function registerThumbnailRoutes(api, adapter) {
|
|
|
5397
5397
|
const previewPath = compPath === "index.html" ? `${projectUrl}/preview` : `${projectUrl}/preview/comp/${compPath.split("/").map(encodeURIComponent).join("/")}`;
|
|
5398
5398
|
const previewUrl = `${previewPath}?${PREVIEW_CAPTURE_PARAM}=1`;
|
|
5399
5399
|
const cacheDir = join11(project.dir, ".thumbnails");
|
|
5400
|
-
const selectorKey = selector ? `_${
|
|
5400
|
+
const selectorKey = selector ? `_${createHash5("sha1").update(selector).digest("hex").slice(0, 16)}_${selectorIndex ?? 0}` : "";
|
|
5401
5401
|
const urlVersionKey = urlVersion ? `_${urlVersion.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32)}` : "";
|
|
5402
|
-
const inputSignatureKey = `_${
|
|
5402
|
+
const inputSignatureKey = `_${createHash5("sha1").update(inputSignature).digest("hex").slice(0, 16)}`;
|
|
5403
5403
|
const outputScale = outputMode === "source" ? 1 : Math.min(1, THUMBNAIL_MAX_OUTPUT_WIDTH / compW, THUMBNAIL_MAX_OUTPUT_HEIGHT / compH);
|
|
5404
5404
|
const outputWidth = Math.max(1, Math.round(compW * outputScale));
|
|
5405
5405
|
const outputHeight = Math.max(1, Math.round(compH * outputScale));
|
|
@@ -5523,7 +5523,7 @@ import {
|
|
|
5523
5523
|
} from "@hyperframes/core/atomic-file";
|
|
5524
5524
|
|
|
5525
5525
|
// src/helpers/freezeFrame.ts
|
|
5526
|
-
import { createHash as
|
|
5526
|
+
import { createHash as createHash6, randomBytes } from "crypto";
|
|
5527
5527
|
import { ensureHfIds as ensureHfIds3 } from "@hyperframes/parsers/hf-ids";
|
|
5528
5528
|
import { readMediaOffsetSeconds } from "@hyperframes/parsers/media-duration";
|
|
5529
5529
|
import { resolveRateSpec, sourceTimeAt } from "@hyperframes/core/speed-ramp";
|
|
@@ -5565,7 +5565,7 @@ function freezeExtractArgs(src, mediaTime, output) {
|
|
|
5565
5565
|
var randomStillToken = () => randomBytes(4).toString("hex");
|
|
5566
5566
|
function freezeStillFileName(clipId, playhead, token = randomStillToken()) {
|
|
5567
5567
|
const stem = clipId.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 48) || "clip";
|
|
5568
|
-
const idHash =
|
|
5568
|
+
const idHash = createHash6("sha256").update(clipId).digest("hex").slice(0, 10);
|
|
5569
5569
|
return `${stem}-${idHash}-${Math.round(playhead * 1e3)}-${token}.png`;
|
|
5570
5570
|
}
|
|
5571
5571
|
function readFreezeSource(html, target, playhead) {
|
|
@@ -6870,13 +6870,13 @@ function numericAttribute(element, name) {
|
|
|
6870
6870
|
}
|
|
6871
6871
|
|
|
6872
6872
|
// src/helpers/previewDocumentStore.ts
|
|
6873
|
-
import { createHash as
|
|
6873
|
+
import { createHash as createHash7 } from "crypto";
|
|
6874
6874
|
import { readFileSync as readFileSync14, readdirSync as readdirSync5, rmSync as rmSync6 } from "fs";
|
|
6875
6875
|
import { join as join17 } from "path";
|
|
6876
6876
|
import { replaceFileAtomically as replaceFileAtomically4 } from "@hyperframes/core/atomic-file";
|
|
6877
6877
|
function createPreviewDocumentStore(projectDir, salt) {
|
|
6878
6878
|
const dir = join17(projectDir, ".hyperframes", "preview");
|
|
6879
|
-
const fileFor = (key) => join17(dir, `${
|
|
6879
|
+
const fileFor = (key) => join17(dir, `${createHash7("sha256").update(`${salt}
|
|
6880
6880
|
${key}`).digest("hex").slice(0, 32)}.html`);
|
|
6881
6881
|
return {
|
|
6882
6882
|
read(key) {
|
|
@@ -6997,6 +6997,7 @@ export {
|
|
|
6997
6997
|
createBackgroundRemovalJob,
|
|
6998
6998
|
createPreviewDocumentStore,
|
|
6999
6999
|
createProjectSignature,
|
|
7000
|
+
createProjectSignatureAsync,
|
|
7000
7001
|
createStudioApi,
|
|
7001
7002
|
createStudioManualEditsRenderBodyScript,
|
|
7002
7003
|
createStudioMotionRenderBodyScript,
|
|
@@ -7013,6 +7014,7 @@ export {
|
|
|
7013
7014
|
historyCache,
|
|
7014
7015
|
identifyFileWrite,
|
|
7015
7016
|
isSafePath,
|
|
7017
|
+
isUncopiedMedia,
|
|
7016
7018
|
listProjectHistories,
|
|
7017
7019
|
onRestoredInPlace,
|
|
7018
7020
|
openProjectHistory,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/studio-server",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.222",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
"linkedom": "^0.18.12",
|
|
85
85
|
"postcss": "^8.5.8",
|
|
86
86
|
"postcss-selector-parser": "^7.1.2",
|
|
87
|
-
"@hyperframes/
|
|
88
|
-
"@hyperframes/
|
|
87
|
+
"@hyperframes/parsers": "0.8.222",
|
|
88
|
+
"@hyperframes/core": "0.8.222"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@types/node": "^25.0.10",
|