@hyperframes/studio-server 0.9.2 → 0.9.4
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-6HAB346W.js +11 -0
- package/dist/{chunk-FJBJJURY.js → chunk-7ROCGO5U.js} +35 -19
- package/dist/helpers/hfIdPersist.d.ts +3 -1
- package/dist/helpers/hfIdPersist.js +5 -3
- package/dist/helpers/mediaRange.d.ts +4 -0
- package/dist/helpers/mediaRange.js +8 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +11 -3
- package/package.json +7 -3
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/helpers/mediaRange.ts
|
|
2
|
+
var MAX_OPEN_MEDIA_RANGE_BYTES = 4 * 1024 * 1024;
|
|
3
|
+
var isMedia = (contentType) => /^(audio|video)\//i.test(contentType);
|
|
4
|
+
function openRangeEnd(start, last, contentType) {
|
|
5
|
+
return isMedia(contentType) ? Math.min(last, start + MAX_OPEN_MEDIA_RANGE_BYTES - 1) : last;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
MAX_OPEN_MEDIA_RANGE_BYTES,
|
|
10
|
+
openRangeEnd
|
|
11
|
+
};
|
|
@@ -14,36 +14,51 @@ var isCompositionSource = (html) => /data-composition-id\s*=/.test(html);
|
|
|
14
14
|
var STAMP_RECORD = join(".hyperframes", "hf-ids-stamped.json");
|
|
15
15
|
var contentHash = (text) => createHash("sha1").update(text).digest("base64url");
|
|
16
16
|
function stampProjectHfIds(projectDir) {
|
|
17
|
+
const pass = stampPass(projectDir);
|
|
18
|
+
while (!pass.next().done) ;
|
|
19
|
+
}
|
|
20
|
+
async function stampProjectHfIdsAsync(projectDir) {
|
|
21
|
+
const pass = stampPass(projectDir);
|
|
22
|
+
while (!pass.next().done) await new Promise((resolve) => setImmediate(resolve));
|
|
23
|
+
}
|
|
24
|
+
function* stampPass(projectDir) {
|
|
17
25
|
const recordPath = join(projectDir, STAMP_RECORD);
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
last = JSON.parse(readFileSync(recordPath, "utf-8"));
|
|
21
|
-
} catch {
|
|
22
|
-
}
|
|
26
|
+
const last = readStampRecord(recordPath);
|
|
23
27
|
const next = {};
|
|
24
28
|
for (const file of walkDir(projectDir)) {
|
|
25
29
|
if (!file.endsWith(".html") || isInHiddenOrVendorDir(file)) continue;
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
html = readFileSync(absPath, "utf-8");
|
|
30
|
-
} catch {
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
let hash = contentHash(html);
|
|
34
|
-
if (last[file] !== hash && isCompositionSource(html)) {
|
|
35
|
-
const stamped = stampFileHfIds(absPath);
|
|
36
|
-
if (stamped === null) continue;
|
|
37
|
-
hash = contentHash(stamped);
|
|
38
|
-
}
|
|
39
|
-
next[file] = hash;
|
|
30
|
+
const hash = hashAfterStamp(join(projectDir, file), last[file]);
|
|
31
|
+
if (hash !== null) next[file] = hash;
|
|
32
|
+
yield;
|
|
40
33
|
}
|
|
34
|
+
writeStampRecord(projectDir, recordPath, next);
|
|
35
|
+
}
|
|
36
|
+
function readStampRecord(recordPath) {
|
|
37
|
+
try {
|
|
38
|
+
return JSON.parse(readFileSync(recordPath, "utf-8"));
|
|
39
|
+
} catch {
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function writeStampRecord(projectDir, recordPath, next) {
|
|
41
44
|
try {
|
|
42
45
|
mkdirWithinProject(projectDir, dirname(recordPath));
|
|
43
46
|
writeFileSync(recordPath, JSON.stringify(next));
|
|
44
47
|
} catch {
|
|
45
48
|
}
|
|
46
49
|
}
|
|
50
|
+
function hashAfterStamp(absPath, recorded) {
|
|
51
|
+
let html;
|
|
52
|
+
try {
|
|
53
|
+
html = readFileSync(absPath, "utf-8");
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const hash = contentHash(html);
|
|
58
|
+
if (recorded === hash || !isCompositionSource(html)) return hash;
|
|
59
|
+
const stamped = stampFileHfIds(absPath);
|
|
60
|
+
return stamped === null ? null : contentHash(stamped);
|
|
61
|
+
}
|
|
47
62
|
function openNoFollow(filePath, flags) {
|
|
48
63
|
const noFollow = constants.O_NOFOLLOW ?? 0;
|
|
49
64
|
try {
|
|
@@ -93,5 +108,6 @@ function stampFileHfIds(filePath) {
|
|
|
93
108
|
export {
|
|
94
109
|
isCompositionSource,
|
|
95
110
|
stampProjectHfIds,
|
|
111
|
+
stampProjectHfIdsAsync,
|
|
96
112
|
stampFileHfIds
|
|
97
113
|
};
|
|
@@ -3,6 +3,8 @@ declare const isCompositionSource: (html: string) => boolean;
|
|
|
3
3
|
* watches the project: an id write during a session reaches Studio as an outside edit and reloads it.
|
|
4
4
|
* A file whose content hash matches the last run's (kept in `.hyperframes`) is not parsed again. */
|
|
5
5
|
declare function stampProjectHfIds(projectDir: string): void;
|
|
6
|
+
/** stampProjectHfIds for a host whose event loop must keep answering: it yields to the loop after each file. */
|
|
7
|
+
declare function stampProjectHfIdsAsync(projectDir: string): Promise<void>;
|
|
6
8
|
/**
|
|
7
9
|
* Read `filePath`, mint any missing `data-hf-id`s, write the stamped content
|
|
8
10
|
* back if new ids were added, and return the stamped content. Every open of the path is
|
|
@@ -20,4 +22,4 @@ declare function stampProjectHfIds(projectDir: string): void;
|
|
|
20
22
|
*/
|
|
21
23
|
declare function stampFileHfIds(filePath: string): string | null;
|
|
22
24
|
|
|
23
|
-
export { isCompositionSource, stampFileHfIds, stampProjectHfIds };
|
|
25
|
+
export { isCompositionSource, stampFileHfIds, stampProjectHfIds, stampProjectHfIdsAsync };
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isCompositionSource,
|
|
3
3
|
stampFileHfIds,
|
|
4
|
-
stampProjectHfIds
|
|
5
|
-
|
|
4
|
+
stampProjectHfIds,
|
|
5
|
+
stampProjectHfIdsAsync
|
|
6
|
+
} from "../chunk-7ROCGO5U.js";
|
|
6
7
|
import "../chunk-QF7MFJJU.js";
|
|
7
8
|
import "../chunk-SVQFE44C.js";
|
|
8
9
|
import "../chunk-L3HJVTQE.js";
|
|
9
10
|
export {
|
|
10
11
|
isCompositionSource,
|
|
11
12
|
stampFileHfIds,
|
|
12
|
-
stampProjectHfIds
|
|
13
|
+
stampProjectHfIds,
|
|
14
|
+
stampProjectHfIdsAsync
|
|
13
15
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -5,9 +5,10 @@ export { C as ClosedWindow, D as DEFAULT_HISTORY_ROOT, S as HISTORY_START, H as
|
|
|
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';
|
|
7
7
|
export { walkDir } from './helpers/safePath.js';
|
|
8
|
-
export { stampProjectHfIds } from './helpers/hfIdPersist.js';
|
|
8
|
+
export { stampProjectHfIds, stampProjectHfIdsAsync } from './helpers/hfIdPersist.js';
|
|
9
9
|
import { SourceMutationTarget } from './helpers/sourceMutation.js';
|
|
10
10
|
export { PatchOperation, dedupeClonedCompositionId, findTargetElement, parseSourceDocument, patchElementInHtml, removeElementFromHtml, splitElementInHtml } from './helpers/sourceMutation.js';
|
|
11
|
+
export { MAX_OPEN_MEDIA_RANGE_BYTES, openRangeEnd } from './helpers/mediaRange.js';
|
|
11
12
|
export { ScreenshotClip, clearElementScreenshotIsolation, getElementScreenshotClip } from './helpers/screenshotClip.js';
|
|
12
13
|
export { STUDIO_MANUAL_EDITS_PATH, StudioManualEditsRenderScriptOptions, createStudioManualEditsRenderBodyScript, createStudioPositionSeekReapplyScript } from './helpers/manualEditsRenderScript.js';
|
|
13
14
|
export { STUDIO_MOTION_PATH, StudioMotionRenderScriptOptions, createStudioMotionRenderBodyScript } from './helpers/studioMotionRenderScript.js';
|
package/dist/index.js
CHANGED
|
@@ -20,11 +20,16 @@ import {
|
|
|
20
20
|
} from "./chunk-LRTNNDXS.js";
|
|
21
21
|
import {
|
|
22
22
|
isCompositionSource,
|
|
23
|
-
stampProjectHfIds
|
|
24
|
-
|
|
23
|
+
stampProjectHfIds,
|
|
24
|
+
stampProjectHfIdsAsync
|
|
25
|
+
} from "./chunk-7ROCGO5U.js";
|
|
25
26
|
import {
|
|
26
27
|
parseEncoderOptions
|
|
27
28
|
} from "./chunk-H5AB5322.js";
|
|
29
|
+
import {
|
|
30
|
+
MAX_OPEN_MEDIA_RANGE_BYTES,
|
|
31
|
+
openRangeEnd
|
|
32
|
+
} from "./chunk-6HAB346W.js";
|
|
28
33
|
import {
|
|
29
34
|
DEFAULT_HISTORY_ROOT,
|
|
30
35
|
DELETED_VERSION,
|
|
@@ -4674,7 +4679,7 @@ ${etag}`;
|
|
|
4674
4679
|
const match = rangeHeader ? /bytes=(\d+)-(\d*)/.exec(rangeHeader) : null;
|
|
4675
4680
|
if (match) {
|
|
4676
4681
|
const start = parseInt(match[1], 10);
|
|
4677
|
-
const end = match[2] ? parseInt(match[2], 10) : totalSize - 1;
|
|
4682
|
+
const end = match[2] ? parseInt(match[2], 10) : openRangeEnd(start, totalSize - 1, servedContentType);
|
|
4678
4683
|
const safeEnd = Math.min(end, totalSize - 1);
|
|
4679
4684
|
if (start > safeEnd) {
|
|
4680
4685
|
return new Response(null, {
|
|
@@ -6971,6 +6976,7 @@ export {
|
|
|
6971
6976
|
HistoryClosedError,
|
|
6972
6977
|
HistoryIdError,
|
|
6973
6978
|
HistoryRefusedError,
|
|
6979
|
+
MAX_OPEN_MEDIA_RANGE_BYTES,
|
|
6974
6980
|
MAX_UPLOAD_BYTES,
|
|
6975
6981
|
MAX_WINDOW_IDLE_MS,
|
|
6976
6982
|
MIME_TYPES,
|
|
@@ -7014,6 +7020,7 @@ export {
|
|
|
7014
7020
|
listProjectHistories,
|
|
7015
7021
|
onRestoredInPlace,
|
|
7016
7022
|
openProjectHistory,
|
|
7023
|
+
openRangeEnd,
|
|
7017
7024
|
parseSourceDocument,
|
|
7018
7025
|
patchElementInHtml,
|
|
7019
7026
|
pruneGoneProjectHistories,
|
|
@@ -7029,6 +7036,7 @@ export {
|
|
|
7029
7036
|
settledFileTag,
|
|
7030
7037
|
splitElementInHtml,
|
|
7031
7038
|
stampProjectHfIds,
|
|
7039
|
+
stampProjectHfIdsAsync,
|
|
7032
7040
|
thumbnailDeviceScaleFactor,
|
|
7033
7041
|
walkDir
|
|
7034
7042
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/studio-server",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
@@ -74,6 +74,10 @@
|
|
|
74
74
|
"./encoder-options": {
|
|
75
75
|
"import": "./dist/helpers/encoderOptions.js",
|
|
76
76
|
"types": "./dist/helpers/encoderOptions.d.ts"
|
|
77
|
+
},
|
|
78
|
+
"./media-range": {
|
|
79
|
+
"import": "./dist/helpers/mediaRange.js",
|
|
80
|
+
"types": "./dist/helpers/mediaRange.d.ts"
|
|
77
81
|
}
|
|
78
82
|
},
|
|
79
83
|
"publishConfig": {
|
|
@@ -84,8 +88,8 @@
|
|
|
84
88
|
"linkedom": "^0.18.12",
|
|
85
89
|
"postcss": "^8.5.8",
|
|
86
90
|
"postcss-selector-parser": "^7.1.2",
|
|
87
|
-
"@hyperframes/core": "0.9.
|
|
88
|
-
"@hyperframes/parsers": "0.9.
|
|
91
|
+
"@hyperframes/core": "0.9.4",
|
|
92
|
+
"@hyperframes/parsers": "0.9.4"
|
|
89
93
|
},
|
|
90
94
|
"devDependencies": {
|
|
91
95
|
"@types/node": "^25.0.10",
|