@field/cascade 0.10.0 → 0.11.0
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/AGENTS.md +20 -3
- package/CHANGELOG.md +187 -0
- package/README.md +1 -2
- package/dist/assets/{CodeEditor-DSZBpzdy.js → CodeEditor-4O7FQ__R.js} +4 -4
- package/dist/assets/{CodePanel-sY6sZa7B.js → CodePanel-BU-autmq.js} +2 -2
- package/dist/assets/{CustomNodeDialog-BRKnqZhp.js → CustomNodeDialog-BRpDfOV5.js} +1 -1
- package/dist/assets/{OpenGraphDialog-ZsgL-iwr.js → OpenGraphDialog-BwbRlC0X.js} +1 -1
- package/dist/assets/{ProjectSettings-Cw17nNe3.js → ProjectSettings-DLOXLxcA.js} +1 -1
- package/dist/assets/{SettingsDialog-p25h3tj0.js → SettingsDialog-Bz8JxISH.js} +1 -1
- package/dist/assets/{VersionHistoryDialog-DzFLUotB.js → VersionHistoryDialog-D5Z0nJ5-.js} +1 -1
- package/dist/assets/{core-BICrEt0y.js → core-Yqi0Ni61.js} +1 -1
- package/dist/assets/{cssMode-D7TXw57I.js → cssMode-CxUzc4vp.js} +1 -1
- package/dist/assets/{definitions-DUww2Rt-.js → definitions-GreEMXLV.js} +1 -1
- package/dist/assets/{editor.api-DvkCO3ko.js → editor.api-BNFb25CX.js} +1 -1
- package/dist/assets/{freemarker2-BA2lxsF1.js → freemarker2-0ZDnWxeM.js} +1 -1
- package/dist/assets/geo-u0n_jOsD.js +1 -0
- package/dist/assets/{handlebars-BcDiyPd8.js → handlebars-Cy18MoaD.js} +1 -1
- package/dist/assets/{html-C7O4TyhX.js → html-B-2Dx7nq.js} +1 -1
- package/dist/assets/{htmlMode-WaDGF3Mj.js → htmlMode-DUAc9B_d.js} +1 -1
- package/dist/assets/{image-DR4oeyJB.js → image-cAa-Nu9O.js} +1 -1
- package/dist/assets/{index-DyvDC6pS.js → index-5ZtDAuy2.js} +42 -41
- package/dist/assets/{javascript-CpIEK7tz.js → javascript-DeQsDqP5.js} +1 -1
- package/dist/assets/{jsonMode-B2FltW0f.js → jsonMode-BiFwJVSk.js} +1 -1
- package/dist/assets/{liquid-CN6FFHZE.js → liquid-BLoHH68a.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-QhV9XtLp.js → lspLanguageFeatures-CNFgm1Kv.js} +1 -1
- package/dist/assets/math-DioIQOPJ.js +1 -0
- package/dist/assets/{mdx-DE89pafV.js → mdx-CFXQVNfs.js} +1 -1
- package/dist/assets/pop-DC_TQG9t.js +1 -0
- package/dist/assets/{python-ByTllTB9.js → python-Cf7S7p2E.js} +1 -1
- package/dist/assets/{razor-USYlRRCE.js → razor-CMHBcG-g.js} +1 -1
- package/dist/assets/{tsMode-BXpN8iUz.js → tsMode-BEih0GDj.js} +1 -1
- package/dist/assets/{typescript-DInBjGQQ.js → typescript-COEKYD_a.js} +1 -1
- package/dist/assets/{workers-C7Ye5B7D.js → workers-BNhAhMNn.js} +1 -1
- package/dist/assets/{xml-U0Uocqyo.js → xml-CPiMpnPl.js} +1 -1
- package/dist/assets/{yaml-CBw_PVYf.js → yaml-Bgp1ITLR.js} +1 -1
- package/dist/cli/Graph-ZJJTRQTM.js +2975 -0
- package/dist/cli/chunk-2KXB47FP.js +115 -0
- package/dist/cli/chunk-35D343DC.js +1447 -0
- package/dist/cli/chunk-36P5K3SD.js +631 -0
- package/dist/cli/chunk-3JTJHF7V.js +267 -0
- package/dist/cli/chunk-4UDFYF5G.js +132 -0
- package/dist/cli/chunk-53NMBJAO.js +35 -0
- package/dist/cli/chunk-A4OAMOZH.js +310 -0
- package/dist/cli/chunk-BIJO5OFS.js +71 -0
- package/dist/cli/chunk-BP7UKF36.js +376 -0
- package/dist/cli/chunk-CKS2FQWR.js +89 -0
- package/dist/cli/chunk-CO22XHNG.js +593 -0
- package/dist/cli/chunk-D6BUOHUG.js +634 -0
- package/dist/cli/chunk-DEQSEFFH.js +153 -0
- package/dist/cli/chunk-DUIUFVU2.js +241 -0
- package/dist/cli/chunk-EUIAC3U3.js +3006 -0
- package/dist/cli/chunk-FCDXJ6EK.js +2208 -0
- package/dist/cli/chunk-GFS6W3C5.js +308 -0
- package/dist/cli/chunk-HFHWYL55.js +139 -0
- package/dist/cli/chunk-HSNOBIVT.js +263 -0
- package/dist/cli/chunk-ICH7N5PN.js +26 -0
- package/dist/cli/chunk-J7VK7MNF.js +418 -0
- package/dist/cli/chunk-KH4MUBKF.js +1551 -0
- package/dist/cli/chunk-MIIEFUGG.js +623 -0
- package/dist/cli/chunk-OWWBYLHC.js +136 -0
- package/dist/cli/chunk-POMMNKZZ.js +672 -0
- package/dist/cli/chunk-QBBKRNGY.js +90 -0
- package/dist/cli/chunk-QQPA2ZHH.js +273 -0
- package/dist/cli/chunk-RLCAJBVR.js +224 -0
- package/dist/cli/chunk-RQZ4SX5R.js +1125 -0
- package/dist/cli/chunk-RUU3YWXU.js +99 -0
- package/dist/cli/chunk-RXDIMXN5.js +98 -0
- package/dist/cli/chunk-SGJAET2L.js +197 -0
- package/dist/cli/chunk-VVGSLVSF.js +151 -0
- package/dist/cli/chunk-WD62JIP6.js +118 -0
- package/dist/cli/chunk-WIH4TEIS.js +104 -0
- package/dist/cli/chunk-WKURDVYP.js +1119 -0
- package/dist/cli/chunk-WPUDGEFY.js +20 -0
- package/dist/cli/chunk-XWDSKG7N.js +1301 -0
- package/dist/cli/chunk-YAT5Y25U.js +121 -0
- package/dist/cli/chunk-ZL4JTG5Y.js +37 -0
- package/dist/cli/cliCommands-UQSFGEHF.js +3464 -0
- package/dist/cli/commands-Q23M26QM.js +1292 -0
- package/dist/cli/definitions-HF2FTHYU.js +32 -0
- package/dist/cli/doctorCommand-B7BPQMN6.js +76 -0
- package/dist/cli/edit-JHCPTQFT.js +28 -0
- package/dist/cli/editorCommands-UIF5YLUZ.js +33 -0
- package/dist/cli/encode-HAUZTYPT.js +17 -0
- package/dist/cli/frames-LSAUBZ7P.js +16 -0
- package/dist/cli/geo-4RNK3QVN.js +43 -0
- package/dist/cli/graphCommands-6BMAKGQE.js +184 -0
- package/dist/cli/graphFile-VPSQ6OF7.js +286 -0
- package/dist/cli/headlessCanvas-5XLDZT7M.js +15 -0
- package/dist/cli/helpCommand-3VRE3KVO.js +155 -0
- package/dist/cli/index.js +100 -30756
- package/dist/cli/math-ZRMLKU2D.js +16 -0
- package/dist/cli/mcp-ZLEEMYGF.js +164 -0
- package/dist/cli/parity-KINARCP2.js +328 -0
- package/dist/cli/pop-USDFXB7H.js +39 -0
- package/dist/cli/project-K3QIPGBB.js +12 -0
- package/dist/cli/projectDefinition-DMTZN2NE.js +27 -0
- package/dist/cli/projectRuntime-Z5PJOH47.js +48 -0
- package/dist/cli/registerStandardNodes-S2VLMF6J.js +3081 -0
- package/dist/cli/render-YURAPPUI.js +436 -0
- package/dist/cli/runCommand-PI764LEG.js +198 -0
- package/dist/cli/runner-RA6UKEPD.js +37 -0
- package/dist/cli/runtime/image.ts +277 -0
- package/dist/cli/runtime/stage.ts +4 -1
- package/dist/cli/stageRunner-KUNIMQKJ.js +10 -0
- package/dist/cli/verbs-RCE3K4VQ.js +19 -0
- package/dist/cli/webBuild-GT4PZT5D.js +37 -0
- package/dist/contracts/documentFormat.d.ts +18 -0
- package/dist/contracts/documentFormat.js +195 -0
- package/dist/contracts/editor.d.ts +17 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.js +1 -0
- package/dist/image.d.ts +141 -0
- package/dist/image.js +127 -0
- package/dist/index.html +1 -1
- package/dist/player/editor.js +32 -7
- package/dist/runtime/builtins/headless.d.ts +19 -0
- package/dist/runtime/builtins/headless.js +25 -0
- package/dist/runtime/builtins/image/contactSheet.d.ts +226 -0
- package/dist/runtime/builtins/image/contactSheet.js +199 -0
- package/dist/runtime/builtins/image/index.d.ts +9 -0
- package/dist/runtime/builtins/image/index.js +9 -0
- package/dist/stage.js +4 -1
- package/doc/CLI_REFERENCE.md +73 -2
- package/doc/EDITOR_EXPORT.md +11 -2
- package/doc/MCP.md +17 -1
- package/doc/NODE_REFERENCE.md +142 -0
- package/doc/PROJECT_AUTHORING.md +127 -7
- package/package.json +16 -4
- package/dist/assets/ExportDialog-C7dVGua4.js +0 -358
- package/dist/assets/ExportDialog-DOq0flMV.css +0 -1
- package/dist/assets/geo-C2RHOVHC.js +0 -1
- package/dist/assets/math-DaDEgWKt.js +0 -1
- package/dist/assets/pop-pLH7L0PW.js +0 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// packages/runtime/src/camera/index.ts
|
|
2
|
+
var DEG = Math.PI / 180;
|
|
3
|
+
function cross(a, b) {
|
|
4
|
+
return [
|
|
5
|
+
a[1] * b[2] - a[2] * b[1],
|
|
6
|
+
a[2] * b[0] - a[0] * b[2],
|
|
7
|
+
a[0] * b[1] - a[1] * b[0]
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
function normalize(v) {
|
|
11
|
+
const length = Math.hypot(v[0], v[1], v[2]);
|
|
12
|
+
if (length === 0) return [0, 0, 0];
|
|
13
|
+
return [v[0] / length, v[1] / length, v[2] / length];
|
|
14
|
+
}
|
|
15
|
+
function subtract(a, b) {
|
|
16
|
+
return [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
|
|
17
|
+
}
|
|
18
|
+
function dot(a, b) {
|
|
19
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
20
|
+
}
|
|
21
|
+
function lookAtRotation(from, to, up = [0, 1, 0]) {
|
|
22
|
+
const forward = normalize(subtract(to, from));
|
|
23
|
+
if (forward[0] === 0 && forward[1] === 0 && forward[2] === 0) return [0, 0, 0];
|
|
24
|
+
const horizontal = Math.hypot(forward[0], forward[2]);
|
|
25
|
+
const pitch = Math.atan2(forward[1], horizontal);
|
|
26
|
+
const yaw = Math.atan2(-forward[0], -forward[2]);
|
|
27
|
+
return [pitch / DEG, yaw / DEG, rollTowards(forward, pitch, yaw, up) / DEG];
|
|
28
|
+
}
|
|
29
|
+
function rollTowards(forward, pitch, yaw, up) {
|
|
30
|
+
const desired = normalize([
|
|
31
|
+
up[0] - forward[0] * dot(up, forward),
|
|
32
|
+
up[1] - forward[1] * dot(up, forward),
|
|
33
|
+
up[2] - forward[2] * dot(up, forward)
|
|
34
|
+
]);
|
|
35
|
+
if (desired[0] === 0 && desired[1] === 0 && desired[2] === 0) return 0;
|
|
36
|
+
const locked = cameraBasis({
|
|
37
|
+
...CAMERA_ROTATION_ONLY,
|
|
38
|
+
rotate: [pitch / DEG, yaw / DEG, 0]
|
|
39
|
+
}).up;
|
|
40
|
+
return Math.atan2(dot(cross(desired, locked), forward), dot(locked, desired));
|
|
41
|
+
}
|
|
42
|
+
var CAMERA_ROTATION_ONLY = {
|
|
43
|
+
translate: [0, 0, 0],
|
|
44
|
+
focal: 50,
|
|
45
|
+
aperture: 41.4214,
|
|
46
|
+
near: 1e-3,
|
|
47
|
+
far: 1e4,
|
|
48
|
+
resolution: [1, 1],
|
|
49
|
+
aspect: 1,
|
|
50
|
+
projection: "perspective",
|
|
51
|
+
orthowidth: 2
|
|
52
|
+
};
|
|
53
|
+
function cameraBasis(camera) {
|
|
54
|
+
const [rx, ry, rz] = camera.rotate;
|
|
55
|
+
const sx = Math.sin(rx * DEG);
|
|
56
|
+
const cx = Math.cos(rx * DEG);
|
|
57
|
+
const sy = Math.sin(ry * DEG);
|
|
58
|
+
const cy = Math.cos(ry * DEG);
|
|
59
|
+
const sz = Math.sin(rz * DEG);
|
|
60
|
+
const cz = Math.cos(rz * DEG);
|
|
61
|
+
const m00 = cy * cz + sy * sx * sz;
|
|
62
|
+
const m01 = -cy * sz + sy * sx * cz;
|
|
63
|
+
const m02 = sy * cx;
|
|
64
|
+
const m10 = cx * sz;
|
|
65
|
+
const m11 = cx * cz;
|
|
66
|
+
const m12 = -sx;
|
|
67
|
+
const m20 = -sy * cz + cy * sx * sz;
|
|
68
|
+
const m21 = sy * sz + cy * sx * cz;
|
|
69
|
+
const m22 = cy * cx;
|
|
70
|
+
const right = [m00, m10, m20];
|
|
71
|
+
const up = [m01, m11, m21];
|
|
72
|
+
const forward = [-m02, -m12, -m22];
|
|
73
|
+
return { eye: camera.translate, forward, right, up };
|
|
74
|
+
}
|
|
75
|
+
function frameAspect(camera) {
|
|
76
|
+
const [width, height] = camera.resolution;
|
|
77
|
+
if (height === 0) return 1;
|
|
78
|
+
return width * camera.aspect / height;
|
|
79
|
+
}
|
|
80
|
+
function viewMatrix(camera) {
|
|
81
|
+
const { eye, forward, right, up } = cameraBasis(camera);
|
|
82
|
+
const back = [-forward[0], -forward[1], -forward[2]];
|
|
83
|
+
return [
|
|
84
|
+
right[0],
|
|
85
|
+
up[0],
|
|
86
|
+
back[0],
|
|
87
|
+
0,
|
|
88
|
+
right[1],
|
|
89
|
+
up[1],
|
|
90
|
+
back[1],
|
|
91
|
+
0,
|
|
92
|
+
right[2],
|
|
93
|
+
up[2],
|
|
94
|
+
back[2],
|
|
95
|
+
0,
|
|
96
|
+
-(right[0] * eye[0] + right[1] * eye[1] + right[2] * eye[2]),
|
|
97
|
+
-(up[0] * eye[0] + up[1] * eye[1] + up[2] * eye[2]),
|
|
98
|
+
-(back[0] * eye[0] + back[1] * eye[1] + back[2] * eye[2]),
|
|
99
|
+
1
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
function projectionMatrix(camera) {
|
|
103
|
+
const { near, far } = camera;
|
|
104
|
+
const aspect = frameAspect(camera);
|
|
105
|
+
if (camera.projection === "orthographic") {
|
|
106
|
+
const halfWidth = camera.orthowidth / 2;
|
|
107
|
+
const halfHeight = aspect === 0 ? halfWidth : halfWidth / aspect;
|
|
108
|
+
return [
|
|
109
|
+
1 / halfWidth,
|
|
110
|
+
0,
|
|
111
|
+
0,
|
|
112
|
+
0,
|
|
113
|
+
0,
|
|
114
|
+
1 / halfHeight,
|
|
115
|
+
0,
|
|
116
|
+
0,
|
|
117
|
+
0,
|
|
118
|
+
0,
|
|
119
|
+
-2 / (far - near),
|
|
120
|
+
0,
|
|
121
|
+
0,
|
|
122
|
+
0,
|
|
123
|
+
-(far + near) / (far - near),
|
|
124
|
+
1
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
const focalScale = 2 * camera.focal / camera.aperture;
|
|
128
|
+
return [
|
|
129
|
+
focalScale,
|
|
130
|
+
0,
|
|
131
|
+
0,
|
|
132
|
+
0,
|
|
133
|
+
0,
|
|
134
|
+
focalScale * aspect,
|
|
135
|
+
0,
|
|
136
|
+
0,
|
|
137
|
+
0,
|
|
138
|
+
0,
|
|
139
|
+
-(far + near) / (far - near),
|
|
140
|
+
-1,
|
|
141
|
+
0,
|
|
142
|
+
0,
|
|
143
|
+
-2 * far * near / (far - near),
|
|
144
|
+
0
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export {
|
|
149
|
+
lookAtRotation,
|
|
150
|
+
viewMatrix,
|
|
151
|
+
projectionMatrix
|
|
152
|
+
};
|
|
153
|
+
//# sourceMappingURL=chunk-DEQSEFFH.js.map
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RunTrace,
|
|
3
|
+
captureNodeConsole
|
|
4
|
+
} from "./chunk-4UDFYF5G.js";
|
|
5
|
+
import {
|
|
6
|
+
installProjectStages
|
|
7
|
+
} from "./chunk-QBBKRNGY.js";
|
|
8
|
+
import {
|
|
9
|
+
setEmbeddedCompiler,
|
|
10
|
+
setProjectModuleCompiler
|
|
11
|
+
} from "./chunk-2KXB47FP.js";
|
|
12
|
+
import {
|
|
13
|
+
parseFrameSpec
|
|
14
|
+
} from "./chunk-BP7UKF36.js";
|
|
15
|
+
import {
|
|
16
|
+
encodeMp4,
|
|
17
|
+
timelineFrameSpec
|
|
18
|
+
} from "./chunk-YAT5Y25U.js";
|
|
19
|
+
import {
|
|
20
|
+
applyEnv
|
|
21
|
+
} from "./chunk-ZL4JTG5Y.js";
|
|
22
|
+
import {
|
|
23
|
+
cascadeVersion,
|
|
24
|
+
compileEmbedded,
|
|
25
|
+
compileProjectModule,
|
|
26
|
+
formatStageTrace
|
|
27
|
+
} from "./chunk-MIIEFUGG.js";
|
|
28
|
+
import {
|
|
29
|
+
checkProjectGraph,
|
|
30
|
+
inspectProjectGraph,
|
|
31
|
+
installProjectIo,
|
|
32
|
+
renderDeterministicProjectFrames,
|
|
33
|
+
runDeterministicProjectGraph,
|
|
34
|
+
saveStillImages,
|
|
35
|
+
validateProjectGraph
|
|
36
|
+
} from "./chunk-EUIAC3U3.js";
|
|
37
|
+
import {
|
|
38
|
+
graphSeed
|
|
39
|
+
} from "./chunk-GFS6W3C5.js";
|
|
40
|
+
import {
|
|
41
|
+
ProjectRoot
|
|
42
|
+
} from "./chunk-RQZ4SX5R.js";
|
|
43
|
+
import {
|
|
44
|
+
installHeadlessCanvas
|
|
45
|
+
} from "./chunk-WIH4TEIS.js";
|
|
46
|
+
|
|
47
|
+
// src/cli/runner.ts
|
|
48
|
+
import * as fs from "fs/promises";
|
|
49
|
+
import * as path from "path";
|
|
50
|
+
import { existsSync } from "node:fs";
|
|
51
|
+
async function runGraph(options) {
|
|
52
|
+
const { file, entryNode, nodes, validateOnly, checkOnly, inspectOnly, strict, verbose, frames, fps, out } = options;
|
|
53
|
+
if (verbose) {
|
|
54
|
+
console.log(`Loading graph from: ${file}`);
|
|
55
|
+
}
|
|
56
|
+
let graphData;
|
|
57
|
+
try {
|
|
58
|
+
const filePath = path.resolve(file);
|
|
59
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
60
|
+
graphData = JSON.parse(content);
|
|
61
|
+
if (options.seed !== void 0) graphData.seed = options.seed;
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error(`Failed to load graph file: ${error.message}`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
const projectRoot = path.dirname(path.resolve(file));
|
|
67
|
+
if (validateOnly || checkOnly) {
|
|
68
|
+
const unresolved = checkOnly ? await checkProjectGraph(file, graphData, strict) : await validateProjectGraph(file, graphData, strict);
|
|
69
|
+
const headline = checkOnly ? "Static check passed" : "Graph validation passed";
|
|
70
|
+
console.log(
|
|
71
|
+
unresolved > 0 ? `${headline} with ${unresolved} unresolved ${unresolved === 1 ? "module" : "modules"} \u2014 run with --strict to fail on these` : `${headline}!`
|
|
72
|
+
);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (inspectOnly) {
|
|
76
|
+
console.log(JSON.stringify(await inspectProjectGraph(file, graphData), null, 2));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
let disposeStageBridge;
|
|
80
|
+
let disposeIoBridge;
|
|
81
|
+
let canvasHost;
|
|
82
|
+
let canvasError = null;
|
|
83
|
+
let project;
|
|
84
|
+
const trace = new RunTrace(path.resolve(file), cascadeVersion(), graphSeed(graphData));
|
|
85
|
+
const observe = (graph) => trace.attach(graph);
|
|
86
|
+
const writeTrace = () => {
|
|
87
|
+
if (!project || !existsSync(path.resolve(file))) return void 0;
|
|
88
|
+
try {
|
|
89
|
+
return trace.write(project.root);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.warn(`Could not write the run trace: ${error instanceof Error ? error.message : error}`);
|
|
92
|
+
return void 0;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
try {
|
|
96
|
+
project = new ProjectRoot(path.dirname(path.resolve(file)));
|
|
97
|
+
setProjectModuleCompiler(async (folderName) => (await compileProjectModule(project, folderName)).code);
|
|
98
|
+
setEmbeddedCompiler(async (code) => (await compileEmbedded(project, code)).code);
|
|
99
|
+
disposeStageBridge = installProjectStages(project, {
|
|
100
|
+
verbose,
|
|
101
|
+
onTrace: (stage) => {
|
|
102
|
+
trace.recordStage(stage);
|
|
103
|
+
if (verbose) console.log(`[stage] ${formatStageTrace(stage)}`);
|
|
104
|
+
},
|
|
105
|
+
// What a stage prints goes into the trace against the node that called
|
|
106
|
+
// it, always; on the terminal too with --verbose (the console capture
|
|
107
|
+
// below records that copy, so it is not recorded twice).
|
|
108
|
+
onOutput: (stage, stream, line) => {
|
|
109
|
+
const text = `[${stage ?? "stage-worker"}] ${line}`;
|
|
110
|
+
if (verbose) (stream === "stderr" ? console.warn : console.log)(text);
|
|
111
|
+
else trace.recordLog(stream, text);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
disposeIoBridge = installProjectIo(project);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (verbose) console.warn(`No project context for ${file}: ${error instanceof Error ? error.message : error}`);
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
canvasHost = await installHeadlessCanvas();
|
|
120
|
+
if (verbose) console.log(`Canvas: ${canvasHost.renderer}`);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
canvasError = error instanceof Error ? error : new Error(String(error));
|
|
123
|
+
if (verbose) console.warn(canvasError.message);
|
|
124
|
+
}
|
|
125
|
+
const frameSpec = frames ? frames === "timeline" ? timelineFrameSpec(graphData) : parseFrameSpec(frames) : null;
|
|
126
|
+
const restoreConsole = captureNodeConsole(trace);
|
|
127
|
+
const restoreEnv = applyEnv(options.env);
|
|
128
|
+
if (options.env) trace.setEnvNames(Object.keys(options.env));
|
|
129
|
+
let hostReleased = false;
|
|
130
|
+
const releaseHost = () => {
|
|
131
|
+
if (hostReleased) return;
|
|
132
|
+
hostReleased = true;
|
|
133
|
+
const errors = [];
|
|
134
|
+
for (const dispose of [
|
|
135
|
+
restoreConsole,
|
|
136
|
+
disposeStageBridge,
|
|
137
|
+
restoreEnv,
|
|
138
|
+
disposeIoBridge,
|
|
139
|
+
canvasHost ? () => canvasHost.dispose() : void 0,
|
|
140
|
+
() => setProjectModuleCompiler(null),
|
|
141
|
+
() => setEmbeddedCompiler(null)
|
|
142
|
+
]) {
|
|
143
|
+
try {
|
|
144
|
+
dispose?.();
|
|
145
|
+
} catch (error) {
|
|
146
|
+
errors.push(error);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (errors.length) throw errors[0];
|
|
150
|
+
};
|
|
151
|
+
try {
|
|
152
|
+
if (frameSpec) {
|
|
153
|
+
const rendered = await renderDeterministicProjectFrames(file, graphData, {
|
|
154
|
+
...frameSpec,
|
|
155
|
+
...fps === void 0 ? {} : { fps },
|
|
156
|
+
out: out ?? "renders",
|
|
157
|
+
...entryNode ? { entryNode } : {},
|
|
158
|
+
...nodes?.length ? { nodes } : {},
|
|
159
|
+
...options.outNodes?.length ? { outNodes: options.outNodes } : {},
|
|
160
|
+
...verbose ? { verbose } : {},
|
|
161
|
+
...options.fresh ? { fresh: true } : {},
|
|
162
|
+
...options.worker ? { frameSource: options.worker.frameSource, onFrame: options.worker.onFrame } : {},
|
|
163
|
+
observe
|
|
164
|
+
});
|
|
165
|
+
if (rendered && options.worker) {
|
|
166
|
+
releaseHost();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (rendered) {
|
|
170
|
+
releaseHost();
|
|
171
|
+
const tracePath = writeTrace();
|
|
172
|
+
const video = options.mp4 && !rendered.aborted ? await encodeMp4({ root: projectRoot, files: rendered.files, frames: rendered.frames, fps: rendered.fps, file: options.mp4, ...options.crf === void 0 ? {} : { crf: options.crf } }) : void 0;
|
|
173
|
+
if (options.json) {
|
|
174
|
+
process.stdout.write(JSON.stringify({
|
|
175
|
+
status: "completed",
|
|
176
|
+
graph: path.resolve(file),
|
|
177
|
+
...rendered,
|
|
178
|
+
...video ? { video } : {},
|
|
179
|
+
seed: graphSeed(graphData),
|
|
180
|
+
...tracePath ? { trace: tracePath } : {},
|
|
181
|
+
stages: trace.stages(),
|
|
182
|
+
logs: trace.logs()
|
|
183
|
+
}) + "\n");
|
|
184
|
+
} else {
|
|
185
|
+
console.log(`Rendered ${rendered.frames.length} frames, ${rendered.files.length} files -> ${out ?? "renders"}/`);
|
|
186
|
+
if (video) console.log(`Encoded ${video.file} (H.264 yuv420p, crf ${video.crf}, ${video.fps} fps)`);
|
|
187
|
+
}
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (options.json) throw new Error("--json rendering requires a fully definition-v1 graph");
|
|
191
|
+
} else {
|
|
192
|
+
const started = performance.now();
|
|
193
|
+
let images = [];
|
|
194
|
+
const target = options.outNodes?.length || (nodes?.length ?? 0) > 1 ? void 0 : nodes?.[0] ?? entryNode;
|
|
195
|
+
const saveImages = async (graph) => {
|
|
196
|
+
if (!project) return;
|
|
197
|
+
images = await saveStillImages(graph, project, {
|
|
198
|
+
...out ? { out } : {},
|
|
199
|
+
...nodes?.length ? { nodes } : entryNode ? { nodes: [entryNode] } : {},
|
|
200
|
+
...options.outNodes?.length ? { extra: options.outNodes } : {}
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
if (await runDeterministicProjectGraph(file, graphData, target, observe, saveImages)) {
|
|
204
|
+
if (verbose) console.log("Graph execution completed");
|
|
205
|
+
releaseHost();
|
|
206
|
+
const tracePath = writeTrace();
|
|
207
|
+
if (options.json) {
|
|
208
|
+
process.stdout.write(JSON.stringify({
|
|
209
|
+
status: "completed",
|
|
210
|
+
graph: path.resolve(file),
|
|
211
|
+
durationMs: performance.now() - started,
|
|
212
|
+
seed: graphSeed(graphData),
|
|
213
|
+
images,
|
|
214
|
+
...out ? { files: images.map((image) => image.file) } : {},
|
|
215
|
+
...tracePath ? { trace: tracePath } : {},
|
|
216
|
+
stages: trace.stages(),
|
|
217
|
+
logs: trace.logs()
|
|
218
|
+
}) + "\n");
|
|
219
|
+
} else if (out) {
|
|
220
|
+
console.log(`Saved ${images.length} ${images.length === 1 ? "image" : "images"} -> ${out}/`);
|
|
221
|
+
}
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
} catch (error) {
|
|
226
|
+
releaseHost();
|
|
227
|
+
const tracePath = options.worker ? void 0 : writeTrace();
|
|
228
|
+
if (tracePath && error instanceof Error) error.message += `
|
|
229
|
+
Run trace: ${tracePath}`;
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
releaseHost();
|
|
233
|
+
throw new Error(
|
|
234
|
+
`${path.resolve(file)} has no definition-v1 nodes, and the dynamic executor was removed in 0.7. Every node needs a static \`export const definition\` \u2014 see doc/NODE_AUTHORING.md.`
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export {
|
|
239
|
+
runGraph
|
|
240
|
+
};
|
|
241
|
+
//# sourceMappingURL=chunk-DUIUFVU2.js.map
|