@hyperframes/studio-server 0.8.98 → 0.8.100
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-WUHW3MWG.js → chunk-7ON477WG.js} +2 -4
- package/dist/chunk-7ON477WG.js.map +1 -0
- package/dist/{chunk-EQULRR3G.js → chunk-ZZCG4HGG.js} +6 -6
- package/dist/chunk-ZZCG4HGG.js.map +1 -0
- package/dist/helpers/hfIdPersist.js +1 -2
- package/dist/history/index.js +1 -2
- package/dist/index.js +42 -53
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-EQULRR3G.js.map +0 -1
- package/dist/chunk-PMXUKOC3.js +0 -22
- package/dist/chunk-PMXUKOC3.js.map +0 -1
- package/dist/chunk-WUHW3MWG.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
isCompositionSource,
|
|
19
19
|
stampProjectHfIds
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-7ON477WG.js";
|
|
21
21
|
import {
|
|
22
22
|
DEFAULT_HISTORY_ROOT,
|
|
23
23
|
DELETED_VERSION,
|
|
@@ -43,10 +43,7 @@ import {
|
|
|
43
43
|
resolveProjectAndSignature,
|
|
44
44
|
resolveProjectSignature,
|
|
45
45
|
settledFileTag
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import {
|
|
48
|
-
replaceFileAtomically
|
|
49
|
-
} from "./chunk-PMXUKOC3.js";
|
|
46
|
+
} from "./chunk-ZZCG4HGG.js";
|
|
50
47
|
import {
|
|
51
48
|
getElementScreenshotClip
|
|
52
49
|
} from "./chunk-W2SBTCO2.js";
|
|
@@ -155,8 +152,6 @@ import {
|
|
|
155
152
|
openSync,
|
|
156
153
|
readFileSync as readFileSync3,
|
|
157
154
|
readlinkSync,
|
|
158
|
-
writeFileSync as writeFileSync4,
|
|
159
|
-
writeSync,
|
|
160
155
|
unlinkSync as unlinkSync2,
|
|
161
156
|
rmSync as rmSync3,
|
|
162
157
|
statSync as statSync3,
|
|
@@ -212,6 +207,9 @@ function isAudioFile(name) {
|
|
|
212
207
|
return (getMimeType(name) ?? "").startsWith("audio/");
|
|
213
208
|
}
|
|
214
209
|
|
|
210
|
+
// src/routes/files.ts
|
|
211
|
+
import { createFileAtomically, replaceFileAtomically as replaceFileAtomically2 } from "@hyperframes/core/atomic-file";
|
|
212
|
+
|
|
215
213
|
// src/helpers/waveform.ts
|
|
216
214
|
import { spawn } from "child_process";
|
|
217
215
|
import {
|
|
@@ -471,6 +469,7 @@ function replaceWithProjectDirMissing(c, hostHeaders) {
|
|
|
471
469
|
|
|
472
470
|
// src/helpers/applyFileMutations.ts
|
|
473
471
|
import { readFileSync as readFileSync2, statSync as statSync2 } from "fs";
|
|
472
|
+
import { replaceFileAtomically } from "@hyperframes/core/atomic-file";
|
|
474
473
|
function applyFileMutations(projectDir, mutations, requestToken, writeFile = (path, content) => replaceFileAtomically(path, content, statSync2(path).mode)) {
|
|
475
474
|
const prepared = mutations.map((mutation) => ({
|
|
476
475
|
...mutation,
|
|
@@ -557,7 +556,7 @@ function assertExpectedVersion(mutation, current) {
|
|
|
557
556
|
|
|
558
557
|
// src/routes/files.ts
|
|
559
558
|
import { classifyPropertyGroup } from "@hyperframes/parsers/gsap-constants";
|
|
560
|
-
import { parseGsapScriptAcorn } from "@hyperframes/parsers/gsap-parser-acorn";
|
|
559
|
+
import { findTimelineScript, parseGsapScriptAcorn } from "@hyperframes/parsers/gsap-parser-acorn";
|
|
561
560
|
import { unrollComputedTimeline } from "@hyperframes/parsers";
|
|
562
561
|
import {
|
|
563
562
|
updateAnimationInScript,
|
|
@@ -585,7 +584,8 @@ import {
|
|
|
585
584
|
shiftPositionsInScript,
|
|
586
585
|
scalePositionsInScript,
|
|
587
586
|
dedupePositionWritesInScript,
|
|
588
|
-
syncPositionHoldsBeforeKeyframes
|
|
587
|
+
syncPositionHoldsBeforeKeyframes,
|
|
588
|
+
clipQueryRoot
|
|
589
589
|
} from "@hyperframes/parsers/gsap-writer-acorn";
|
|
590
590
|
import { parseHTML as parseHTML2 } from "linkedom";
|
|
591
591
|
import { ensureHfIds } from "@hyperframes/parsers/hf-ids";
|
|
@@ -962,7 +962,7 @@ function foldElementPatches(originalContent, patches) {
|
|
|
962
962
|
return { content, matched };
|
|
963
963
|
}
|
|
964
964
|
var PATCH_CONFLICT_ATTEMPTS = 3;
|
|
965
|
-
function commitElementPatchBatches(projectDir, batches, writeFile = (path, content) =>
|
|
965
|
+
function commitElementPatchBatches(projectDir, batches, writeFile = (path, content) => replaceFileAtomically2(path, content, statSync3(path).mode), requestToken) {
|
|
966
966
|
for (let attempt = 1; ; attempt += 1) {
|
|
967
967
|
try {
|
|
968
968
|
return foldAndCommitElementPatchBatches(projectDir, batches, writeFile, requestToken);
|
|
@@ -1040,7 +1040,7 @@ function commitElementPatchBatchesWithReceipts(c, projectDir, batches) {
|
|
|
1040
1040
|
}
|
|
1041
1041
|
function writeFileWithReceipt(c, filePath, absPath, html) {
|
|
1042
1042
|
const overwrote = readFileSync3(absPath);
|
|
1043
|
-
|
|
1043
|
+
replaceFileAtomically2(absPath, html, statSync3(absPath).mode);
|
|
1044
1044
|
const version = fileContentVersion(html);
|
|
1045
1045
|
const writeToken = createWriteToken(c.req.header("X-Hyperframes-Write-Token"));
|
|
1046
1046
|
recordFileWriteReceipt(absPath, { path: filePath, version, writeToken, overwrote });
|
|
@@ -1136,7 +1136,7 @@ function updateReferences(projectDir, oldPath, newPath) {
|
|
|
1136
1136
|
if (!content.includes(oldPath)) continue;
|
|
1137
1137
|
const updated = content.split(oldPath).join(newPath);
|
|
1138
1138
|
if (updated !== content) {
|
|
1139
|
-
|
|
1139
|
+
replaceFileAtomically2(file, updated, statSync3(file).mode);
|
|
1140
1140
|
updatedCount++;
|
|
1141
1141
|
}
|
|
1142
1142
|
}
|
|
@@ -1150,20 +1150,17 @@ function extractGsapScriptBlock(html) {
|
|
|
1150
1150
|
(tmpl) => Array.from(tmpl.querySelectorAll("script:not([src])"))
|
|
1151
1151
|
)
|
|
1152
1152
|
];
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
}
|
|
1163
|
-
};
|
|
1153
|
+
const script = findTimelineScript(scripts);
|
|
1154
|
+
if (!script) return null;
|
|
1155
|
+
return {
|
|
1156
|
+
scriptText: script.textContent || "",
|
|
1157
|
+
document,
|
|
1158
|
+
root: clipQueryRoot(script),
|
|
1159
|
+
replaceScript(newText) {
|
|
1160
|
+
script.textContent = newText;
|
|
1161
|
+
return document.toString();
|
|
1164
1162
|
}
|
|
1165
|
-
}
|
|
1166
|
-
return null;
|
|
1163
|
+
};
|
|
1167
1164
|
}
|
|
1168
1165
|
function stripGsapAnimationsForSelector(html, selector) {
|
|
1169
1166
|
const block = extractGsapScriptBlock(html);
|
|
@@ -1780,13 +1777,13 @@ function executeGsapMutationAcorn(body, block, respond) {
|
|
|
1780
1777
|
case "shift-positions": {
|
|
1781
1778
|
const { targetSelector, delta } = body;
|
|
1782
1779
|
if (!targetSelector || !Number.isFinite(delta) || delta === 0) return block.scriptText;
|
|
1783
|
-
return shiftPositionsInScript(block.scriptText, targetSelector, delta);
|
|
1780
|
+
return shiftPositionsInScript(block.scriptText, targetSelector, delta, block.root);
|
|
1784
1781
|
}
|
|
1785
1782
|
case "shift-positions-batch": {
|
|
1786
1783
|
let script = block.scriptText;
|
|
1787
1784
|
for (const s of body.shifts) {
|
|
1788
1785
|
if (!s.targetSelector || !Number.isFinite(s.delta) || s.delta === 0) continue;
|
|
1789
|
-
script = shiftPositionsInScript(script, s.targetSelector, s.delta);
|
|
1786
|
+
script = shiftPositionsInScript(script, s.targetSelector, s.delta, block.root);
|
|
1790
1787
|
}
|
|
1791
1788
|
return script;
|
|
1792
1789
|
}
|
|
@@ -1801,7 +1798,8 @@ function executeGsapMutationAcorn(body, block, respond) {
|
|
|
1801
1798
|
oldStart,
|
|
1802
1799
|
oldDuration,
|
|
1803
1800
|
newStart,
|
|
1804
|
-
newDuration
|
|
1801
|
+
newDuration,
|
|
1802
|
+
block.root
|
|
1805
1803
|
);
|
|
1806
1804
|
}
|
|
1807
1805
|
default:
|
|
@@ -2112,14 +2110,14 @@ async function executeGsapMutationRecast(body, block, respond) {
|
|
|
2112
2110
|
const { targetSelector, delta } = body;
|
|
2113
2111
|
if (!targetSelector || !Number.isFinite(delta) || delta === 0) return block.scriptText;
|
|
2114
2112
|
const { shiftPositionsInScript: shiftPositionsInScript2 } = parser;
|
|
2115
|
-
return shiftPositionsInScript2(block.scriptText, targetSelector, delta);
|
|
2113
|
+
return shiftPositionsInScript2(block.scriptText, targetSelector, delta, block.root);
|
|
2116
2114
|
}
|
|
2117
2115
|
case "shift-positions-batch": {
|
|
2118
2116
|
const { shiftPositionsInScript: shiftPositionsInScript2 } = parser;
|
|
2119
2117
|
let script = block.scriptText;
|
|
2120
2118
|
for (const s of body.shifts) {
|
|
2121
2119
|
if (!s.targetSelector || !Number.isFinite(s.delta) || s.delta === 0) continue;
|
|
2122
|
-
script = shiftPositionsInScript2(script, s.targetSelector, s.delta);
|
|
2120
|
+
script = shiftPositionsInScript2(script, s.targetSelector, s.delta, block.root);
|
|
2123
2121
|
}
|
|
2124
2122
|
return script;
|
|
2125
2123
|
}
|
|
@@ -2135,7 +2133,8 @@ async function executeGsapMutationRecast(body, block, respond) {
|
|
|
2135
2133
|
oldStart,
|
|
2136
2134
|
oldDuration,
|
|
2137
2135
|
newStart,
|
|
2138
|
-
newDuration
|
|
2136
|
+
newDuration,
|
|
2137
|
+
block.root
|
|
2139
2138
|
);
|
|
2140
2139
|
}
|
|
2141
2140
|
default:
|
|
@@ -2256,12 +2255,7 @@ async function processUploadedFiles(formData, targetDir, projectDir) {
|
|
|
2256
2255
|
let written = false;
|
|
2257
2256
|
while (n < MAX_COPY_INDEX && isSafePath(projectDir, finalPath)) {
|
|
2258
2257
|
try {
|
|
2259
|
-
|
|
2260
|
-
try {
|
|
2261
|
-
writeFileSync4(fd, buffer);
|
|
2262
|
-
} finally {
|
|
2263
|
-
closeSync(fd);
|
|
2264
|
-
}
|
|
2258
|
+
createFileAtomically(finalPath, buffer);
|
|
2265
2259
|
written = true;
|
|
2266
2260
|
break;
|
|
2267
2261
|
} catch (error) {
|
|
@@ -2355,9 +2349,8 @@ function registerFileRoutes(api, adapter) {
|
|
|
2355
2349
|
let overwrote;
|
|
2356
2350
|
if (createOnly) {
|
|
2357
2351
|
ensureDir(res.project.dir, res.absPath);
|
|
2358
|
-
let fd;
|
|
2359
2352
|
try {
|
|
2360
|
-
|
|
2353
|
+
createFileAtomically(res.absPath, body);
|
|
2361
2354
|
} catch (error) {
|
|
2362
2355
|
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") {
|
|
2363
2356
|
throw error;
|
|
@@ -2373,11 +2366,6 @@ function registerFileRoutes(api, adapter) {
|
|
|
2373
2366
|
409
|
|
2374
2367
|
);
|
|
2375
2368
|
}
|
|
2376
|
-
try {
|
|
2377
|
-
writeSync(fd, body, 0, body.length, 0);
|
|
2378
|
-
} finally {
|
|
2379
|
-
closeSync(fd);
|
|
2380
|
-
}
|
|
2381
2369
|
} else {
|
|
2382
2370
|
let fd;
|
|
2383
2371
|
try {
|
|
@@ -2416,7 +2404,7 @@ function registerFileRoutes(api, adapter) {
|
|
|
2416
2404
|
const mode = fstatSync(fd).mode;
|
|
2417
2405
|
closeSync(fd);
|
|
2418
2406
|
fd = null;
|
|
2419
|
-
|
|
2407
|
+
replaceFileAtomically2(res.absPath, body, mode);
|
|
2420
2408
|
} finally {
|
|
2421
2409
|
if (fd !== null) closeSync(fd);
|
|
2422
2410
|
}
|
|
@@ -2439,7 +2427,7 @@ function registerFileRoutes(api, adapter) {
|
|
|
2439
2427
|
ensureDir(res.project.dir, res.absPath);
|
|
2440
2428
|
const body = Buffer.from(await c.req.arrayBuffer());
|
|
2441
2429
|
try {
|
|
2442
|
-
|
|
2430
|
+
createFileAtomically(res.absPath, body);
|
|
2443
2431
|
} catch (error) {
|
|
2444
2432
|
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") {
|
|
2445
2433
|
throw error;
|
|
@@ -2646,7 +2634,7 @@ function registerFileRoutes(api, adapter) {
|
|
|
2646
2634
|
const written = [];
|
|
2647
2635
|
try {
|
|
2648
2636
|
for (const file of prepared) {
|
|
2649
|
-
|
|
2637
|
+
replaceFileAtomically2(file.absPath, file.after, statSync3(file.absPath).mode);
|
|
2650
2638
|
written.push(file);
|
|
2651
2639
|
recordFileWriteReceipt(file.absPath, {
|
|
2652
2640
|
path: file.path,
|
|
@@ -2664,7 +2652,7 @@ function registerFileRoutes(api, adapter) {
|
|
|
2664
2652
|
conflicts.push(file.path);
|
|
2665
2653
|
continue;
|
|
2666
2654
|
}
|
|
2667
|
-
|
|
2655
|
+
replaceFileAtomically2(file.absPath, file.before, statSync3(file.absPath).mode);
|
|
2668
2656
|
recordFileWriteReceipt(file.absPath, {
|
|
2669
2657
|
path: file.path,
|
|
2670
2658
|
version: fileContentVersion(file.before),
|
|
@@ -3000,7 +2988,7 @@ function registerFileRoutes(api, adapter) {
|
|
|
3000
2988
|
}
|
|
3001
2989
|
ensureDir(project.dir, destAbs);
|
|
3002
2990
|
try {
|
|
3003
|
-
|
|
2991
|
+
createFileAtomically(destAbs, readFileSync3(srcAbs));
|
|
3004
2992
|
} catch (error) {
|
|
3005
2993
|
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") {
|
|
3006
2994
|
throw error;
|
|
@@ -3104,7 +3092,7 @@ function registerFileRoutes(api, adapter) {
|
|
|
3104
3092
|
if (current !== body.expected) {
|
|
3105
3093
|
return c.json({ ok: true, restored: false, conflict: true });
|
|
3106
3094
|
}
|
|
3107
|
-
|
|
3095
|
+
replaceFileAtomically2(res.absPath, body.restore, statSync3(res.absPath).mode);
|
|
3108
3096
|
return c.json({ ok: true, restored: true, conflict: false });
|
|
3109
3097
|
});
|
|
3110
3098
|
}
|
|
@@ -4421,7 +4409,7 @@ import {
|
|
|
4421
4409
|
rmSync as rmSync4,
|
|
4422
4410
|
statSync as statSync6,
|
|
4423
4411
|
unlinkSync as unlinkSync4,
|
|
4424
|
-
writeFileSync as
|
|
4412
|
+
writeFileSync as writeFileSync4
|
|
4425
4413
|
} from "fs";
|
|
4426
4414
|
import { join as join11 } from "path";
|
|
4427
4415
|
import { createHash as createHash3, randomUUID as randomUUID2 } from "crypto";
|
|
@@ -4530,7 +4518,7 @@ function pruneThumbnailCache(cacheDir, protectedPaths, now = Date.now()) {
|
|
|
4530
4518
|
function writeThumbnailAtomically(path, buffer) {
|
|
4531
4519
|
const temporaryPath = `${path}.${process.pid}.${randomUUID2()}.tmp`;
|
|
4532
4520
|
try {
|
|
4533
|
-
|
|
4521
|
+
writeFileSync4(temporaryPath, buffer, { flag: "wx" });
|
|
4534
4522
|
renameSync3(temporaryPath, path);
|
|
4535
4523
|
} finally {
|
|
4536
4524
|
rmSync4(temporaryPath, { force: true });
|
|
@@ -5463,6 +5451,7 @@ function numericAttribute(element, name) {
|
|
|
5463
5451
|
import { createHash as createHash4 } from "crypto";
|
|
5464
5452
|
import { readFileSync as readFileSync12, readdirSync as readdirSync5, rmSync as rmSync5 } from "fs";
|
|
5465
5453
|
import { join as join15 } from "path";
|
|
5454
|
+
import { replaceFileAtomically as replaceFileAtomically3 } from "@hyperframes/core/atomic-file";
|
|
5466
5455
|
function createPreviewDocumentStore(projectDir, salt) {
|
|
5467
5456
|
const dir = join15(projectDir, ".hyperframes", "preview");
|
|
5468
5457
|
const fileFor = (key) => join15(dir, `${createHash4("sha256").update(`${salt}
|
|
@@ -5479,7 +5468,7 @@ ${key}`).digest("hex").slice(0, 32)}.html`);
|
|
|
5479
5468
|
try {
|
|
5480
5469
|
mkdirWithinProject(projectDir, dir);
|
|
5481
5470
|
const file = fileFor(key);
|
|
5482
|
-
|
|
5471
|
+
replaceFileAtomically3(file, html, 420);
|
|
5483
5472
|
for (const name of readdirSync5(dir)) {
|
|
5484
5473
|
if (join15(dir, name) !== file) rmSync5(join15(dir, name), { force: true });
|
|
5485
5474
|
}
|