@field/cascade 0.11.0 → 0.13.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 +8 -5
- package/ARCHITECTURE.md +5 -4
- package/CHANGELOG.md +245 -0
- package/README.md +1 -1
- package/dist/assets/AgentPanel-1JugFjE4.css +1 -0
- package/dist/assets/AgentPanel-BDL5MddA.js +5 -0
- package/dist/assets/{CodeEditor-4O7FQ__R.js → CodeEditor-C-xYG-Wn.js} +120 -120
- package/dist/assets/CodePanel-CtXd50m6.js +2 -0
- package/dist/assets/CookInfoPanel-B3NMhKJF.css +1 -0
- package/dist/assets/CookInfoPanel-DG4_TRsX.js +2 -0
- package/dist/assets/CustomNodeDialog-CHfZUs-r.js +1 -0
- package/dist/assets/DefinitionNode-CaRTXQ_b.js +1 -0
- package/dist/assets/DefinitionPanel-C3CxZY9r.js +1 -0
- package/dist/assets/DefinitionPanel-VNLnAiQD.css +1 -0
- package/dist/assets/OpenGraphDialog-BLdr6k_q.js +1 -0
- package/dist/assets/ProjectSettings-ZnvmIAir.js +2 -0
- package/dist/assets/{SettingsDialog-Bz8JxISH.js → SettingsDialog-CBX3Wa87.js} +1 -1
- package/dist/assets/TimelinePanel-CDeR0arY.css +1 -0
- package/dist/assets/TimelinePanel-CWgnFH1e.js +1 -0
- package/dist/assets/{VersionHistoryDialog-D5Z0nJ5-.js → VersionHistoryDialog-BOSoW1R-.js} +1 -1
- package/dist/assets/assert-BO2_erPD.js +1 -0
- package/dist/assets/assert-hvykGCnP.js +1 -0
- package/dist/assets/builder-BmBKcDix.js +1 -0
- package/dist/assets/camera-DFF7YA3F.js +1 -0
- package/dist/assets/checks-DAvyO9Gf.js +1 -0
- package/dist/assets/contactSheet-N1NcaWxw.js +2 -0
- package/dist/assets/{core-Yqi0Ni61.js → core-DB-MkGjj.js} +3 -4
- package/dist/assets/coreTypes-DtnDATZ7.js +1 -0
- package/dist/assets/{cssMode-CxUzc4vp.js → cssMode-DPVckSOc.js} +1 -1
- package/dist/assets/definitions-B227e7f_.js +1 -0
- package/dist/assets/definitions-D0WOUJd7.js +1 -0
- package/dist/assets/{editor.api-BNFb25CX.js → editor.api-Dkutg_Z1.js} +1 -1
- package/dist/assets/expressions-X-Z-GrgW.js +5 -0
- package/dist/assets/file-DAL6IfjV.js +1 -0
- package/dist/assets/filters-D3k1LRMa.js +1 -0
- package/dist/assets/{freemarker2-0ZDnWxeM.js → freemarker2-CLiLKk3B.js} +1 -1
- package/dist/assets/generators-BhDxRAFC.js +1 -0
- package/dist/assets/geo-BsMImJIJ.js +1 -0
- package/dist/assets/geo-C4YngDob.js +2 -0
- package/dist/assets/{handlebars-Cy18MoaD.js → handlebars-CcD3aMeL.js} +1 -1
- package/dist/assets/{html-B-2Dx7nq.js → html-DvZWGfqb.js} +1 -1
- package/dist/assets/{htmlMode-DUAc9B_d.js → htmlMode-DUD3VaoN.js} +1 -1
- package/dist/assets/image-0SfH-snh.js +1 -0
- package/dist/assets/image-Ck-RdGU4.js +2 -0
- package/dist/assets/index-BWnrmIB9.js +137 -0
- package/dist/assets/index-DIaxEONI.css +1 -0
- package/dist/assets/io-BGmt2g0D.js +1 -0
- package/dist/assets/{javascript-DeQsDqP5.js → javascript-Cap2ahgh.js} +1 -1
- package/dist/assets/{jsonMode-BiFwJVSk.js → jsonMode-B0uLjp9C.js} +1 -1
- package/dist/assets/{liquid-BLoHH68a.js → liquid-CnxwhfLn.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-CNFgm1Kv.js → lspLanguageFeatures-Dn9hlKX6.js} +1 -1
- package/dist/assets/math-GeULS-sk.js +1 -0
- package/dist/assets/{mdx-CFXQVNfs.js → mdx-BV3jbrVa.js} +1 -1
- package/dist/assets/pop-KMF_qloi.js +1 -0
- package/dist/assets/preload-helper-Czpn1I53.js +1 -0
- package/dist/assets/{python-Cf7S7p2E.js → python-CGyFk4XK.js} +1 -1
- package/dist/assets/{razor-CMHBcG-g.js → razor-CQfzX3-N.js} +1 -1
- package/dist/assets/remap-5SjXQU-q.js +1 -0
- package/dist/assets/renderMarkdown-ork0Oir7.js +67 -0
- package/dist/assets/studioImages-CAyH-0Pl.js +1 -0
- package/dist/assets/text-ZpX7qNkx.js +2 -0
- package/dist/assets/time-P_OiBhcf.js +1 -0
- package/dist/assets/{tsMode-BEih0GDj.js → tsMode-BOeXzO9H.js} +1 -1
- package/dist/assets/{typescript-COEKYD_a.js → typescript-J1SnE_Tu.js} +1 -1
- package/dist/assets/{workers-BNhAhMNn.js → workers-CYwwTiVF.js} +1 -1
- package/dist/assets/{xml-CPiMpnPl.js → xml-DnPRNzK9.js} +1 -1
- package/dist/assets/{yaml-Bgp1ITLR.js → yaml-BmmYBNa9.js} +1 -1
- package/dist/cli/DefinitionNode-P7AA4TAU.js +15 -0
- package/dist/cli/{Graph-ZJJTRQTM.js → Graph-OB6EWSGL.js} +12 -12
- package/dist/cli/assert-GROGQNCQ.js +25 -0
- package/dist/cli/checks-3WB44XBL.js +189 -0
- package/dist/cli/{chunk-3JTJHF7V.js → chunk-2L34ERS2.js} +4 -4
- package/dist/cli/chunk-53LGFPWX.js +138 -0
- package/dist/cli/chunk-5ORUQ6ES.js +267 -0
- package/dist/cli/{chunk-YAT5Y25U.js → chunk-7QE2ZNSN.js} +3 -3
- package/dist/cli/{chunk-SGJAET2L.js → chunk-BPODRH52.js} +8 -4
- package/dist/cli/{chunk-XWDSKG7N.js → chunk-BZ63XQ3I.js} +2 -2
- package/dist/cli/{chunk-FCDXJ6EK.js → chunk-CTPLRSWF.js} +2 -13
- package/dist/cli/{chunk-WIH4TEIS.js → chunk-EZRWJ4G2.js} +1 -1
- package/dist/cli/{chunk-BIJO5OFS.js → chunk-FWMSGKEH.js} +1 -1
- package/dist/cli/{chunk-POMMNKZZ.js → chunk-G23A2BZZ.js} +38 -5
- package/dist/cli/{chunk-35D343DC.js → chunk-GRIN2DDP.js} +19 -1
- package/dist/cli/{chunk-WKURDVYP.js → chunk-JEW5MPGI.js} +28 -331
- package/dist/cli/chunk-JVOCK5W4.js +83 -0
- package/dist/cli/chunk-KBGUO27Q.js +15 -0
- package/dist/cli/{chunk-GFS6W3C5.js → chunk-L6B6FUQP.js} +54 -32
- package/dist/cli/chunk-LTXWBXOM.js +438 -0
- package/dist/cli/chunk-MI5JLQYA.js +220 -0
- package/dist/cli/{chunk-A4OAMOZH.js → chunk-NJFMDXHR.js} +13 -3
- package/dist/cli/{chunk-DUIUFVU2.js → chunk-OBZAP3GG.js} +49 -23
- package/dist/cli/chunk-QAGATJGE.js +336 -0
- package/dist/cli/{chunk-EUIAC3U3.js → chunk-QKL7CCRS.js} +966 -132
- package/dist/cli/{chunk-RLCAJBVR.js → chunk-TJW67QSI.js} +8 -7
- package/dist/cli/{chunk-RQZ4SX5R.js → chunk-W5PJ5RMP.js} +156 -84
- package/dist/cli/chunk-W7OUAT7J.js +122 -0
- package/dist/cli/chunk-WGKPJZDY.js +364 -0
- package/dist/cli/{chunk-D6BUOHUG.js → chunk-X4WKAOQP.js} +4 -4
- package/dist/cli/{chunk-VVGSLVSF.js → chunk-X566FWBV.js} +6 -1
- package/dist/cli/chunk-YH637PDL.js +317 -0
- package/dist/cli/chunk-ZSCUZE6I.js +112 -0
- package/dist/cli/{cliCommands-UQSFGEHF.js → cliCommands-XVFRD7CF.js} +23 -17
- package/dist/cli/{commands-Q23M26QM.js → commands-M2XLTPTZ.js} +129 -47
- package/dist/cli/contactSheet-2PQVRUFW.js +11 -0
- package/dist/cli/{definitions-HF2FTHYU.js → definitions-BPOPW52L.js} +7 -7
- package/dist/cli/{doctorCommand-B7BPQMN6.js → doctorCommand-RAEI7GVY.js} +36 -6
- package/dist/cli/{edit-JHCPTQFT.js → edit-S5KEQ5RA.js} +3 -3
- package/dist/cli/editorCommands-5BBG4S6V.js +41 -0
- package/dist/cli/{encode-HAUZTYPT.js → encode-ICPEPMH5.js} +2 -2
- package/dist/cli/file-3HTQHPYQ.js +41 -0
- package/dist/cli/filters-6ODFWYK4.js +379 -0
- package/dist/cli/generators-YU7GB4MD.js +210 -0
- package/dist/cli/{geo-4RNK3QVN.js → geo-6ZPGKZRU.js} +7 -7
- package/dist/cli/{graphCommands-6BMAKGQE.js → graphCommands-MULQ7VD2.js} +4 -4
- package/dist/cli/{graphFile-VPSQ6OF7.js → graphFile-CITF36ZM.js} +25 -19
- package/dist/cli/{headlessCanvas-5XLDZT7M.js → headlessCanvas-ENRHC7GS.js} +3 -2
- package/dist/cli/{helpCommand-3VRE3KVO.js → helpCommand-X2QDANM3.js} +9 -7
- package/dist/cli/image-TXELZZK5.js +55 -0
- package/dist/cli/index.js +14 -14
- package/dist/cli/{math-ZRMLKU2D.js → math-RSYRQ3C6.js} +5 -5
- package/dist/cli/{mcp-ZLEEMYGF.js → mcp-YRIGRLYQ.js} +4 -4
- package/dist/cli/{parity-KINARCP2.js → parity-3N3HTKWX.js} +42 -36
- package/dist/cli/{pop-USDFXB7H.js → pop-B7SIIYKN.js} +5 -5
- package/dist/cli/project-SJF5ZF3F.js +12 -0
- package/dist/cli/{projectDefinition-DMTZN2NE.js → projectDefinition-F3D7UIHJ.js} +8 -8
- package/dist/cli/{projectRuntime-Z5PJOH47.js → projectRuntime-NY4XMDFH.js} +19 -12
- package/dist/cli/registerStandardNodes-BXJCB6E4.js +744 -0
- package/dist/cli/{render-YURAPPUI.js → render-Y23W6MY6.js} +29 -22
- package/dist/cli/{runCommand-PI764LEG.js → runCommand-XOG7AVC5.js} +3 -3
- package/dist/cli/runner-DNJO5WO2.js +43 -0
- package/dist/cli/runtime/image.ts +27 -2
- package/dist/cli/runtime/io.ts +78 -0
- package/dist/cli/share-B7HTCOJX.js +166 -0
- package/dist/cli/stageCache-TY2BFZJR.js +15 -0
- package/dist/cli/{stageRunner-KUNIMQKJ.js → stageRunner-KY2EJP7X.js} +2 -2
- package/dist/cli/text-MB3EKR4H.js +126 -0
- package/dist/cli/{verbs-RCE3K4VQ.js → verbs-PI2JH5FI.js} +2 -2
- package/dist/cli/webBuild-2K4COCGY.js +44 -0
- package/dist/contracts/capabilities.d.ts +39 -1
- package/dist/contracts/color.d.ts +8 -0
- package/dist/contracts/color.js +23 -0
- package/dist/contracts/definition.d.ts +10 -0
- package/dist/contracts/schema.d.ts +1 -1
- package/dist/contracts/schema.js +1 -0
- package/dist/contracts/validate.js +11 -1
- package/dist/contracts/values.d.ts +24 -0
- package/dist/image.d.ts +15 -0
- package/dist/image.js +36 -2
- package/dist/index.html +8 -2
- package/dist/io.d.ts +29 -0
- package/dist/io.js +40 -0
- package/dist/player/app.js +11 -7
- package/dist/player/editor.js +3 -2
- package/dist/player/editorEngine.js +3 -2
- package/dist/player/embed.js +2 -0
- package/dist/player/types.d.ts +6 -0
- package/dist/runtime/builtins/assert/checks.d.ts +18 -0
- package/dist/runtime/builtins/assert/checks.js +207 -0
- package/dist/runtime/builtins/assert/definitions.d.ts +130 -0
- package/dist/runtime/builtins/assert/definitions.js +54 -0
- package/dist/runtime/builtins/assert/index.d.ts +152 -0
- package/dist/runtime/builtins/assert/index.js +36 -0
- package/dist/runtime/builtins/image/contactSheet.d.ts +3 -165
- package/dist/runtime/builtins/image/contactSheet.js +0 -49
- package/dist/runtime/builtins/image/definitions.d.ts +950 -0
- package/dist/runtime/builtins/image/definitions.js +343 -0
- package/dist/runtime/builtins/image/file.d.ts +8 -0
- package/dist/runtime/builtins/image/file.js +37 -0
- package/dist/runtime/builtins/image/filters.d.ts +8 -0
- package/dist/runtime/builtins/image/filters.js +394 -0
- package/dist/runtime/builtins/image/generators.d.ts +7 -0
- package/dist/runtime/builtins/image/generators.js +144 -0
- package/dist/runtime/builtins/image/index.d.ts +947 -4
- package/dist/runtime/builtins/image/index.js +41 -6
- package/dist/runtime/builtins/image/io.d.ts +100 -0
- package/dist/runtime/builtins/image/io.js +142 -0
- package/dist/runtime/builtins/image/planar.d.ts +55 -0
- package/dist/runtime/builtins/image/planar.js +274 -0
- package/dist/runtime/builtins/image/simplex.d.ts +22 -0
- package/dist/runtime/builtins/image/simplex.js +92 -0
- package/dist/runtime/builtins/image/text.d.ts +4 -0
- package/dist/runtime/builtins/image/text.js +141 -0
- package/dist/runtime/builtins/index.d.ts +3 -0
- package/dist/runtime/builtins/index.js +7 -0
- package/dist/runtime/definition/architecture.js +89 -0
- package/dist/runtime/gpu.d.ts +25 -0
- package/dist/runtime/gpu.js +40 -0
- package/dist/runtime/runtime.d.ts +2 -0
- package/dist/runtime/runtime.js +268 -44
- package/dist/runtime/types.d.ts +30 -0
- package/doc/CLI_REFERENCE.md +21 -3
- package/doc/EDITOR_EXPORT.md +26 -0
- package/doc/MCP.md +2 -1
- package/doc/NODE_REFERENCE.md +286 -14
- package/doc/PROJECT_AUTHORING.md +158 -4
- package/doc/WEB_PLAYER.md +9 -1
- package/package.json +4 -1
- package/dist/assets/CodePanel-BU-autmq.js +0 -2
- package/dist/assets/CustomNodeDialog-BRpDfOV5.js +0 -1
- package/dist/assets/OpenGraphDialog-BwbRlC0X.js +0 -1
- package/dist/assets/ProjectSettings-DLOXLxcA.js +0 -2
- package/dist/assets/definitions-GreEMXLV.js +0 -1
- package/dist/assets/geo-u0n_jOsD.js +0 -1
- package/dist/assets/image-cAa-Nu9O.js +0 -2062
- package/dist/assets/index-5ZtDAuy2.js +0 -220
- package/dist/assets/index-7vae6YFC.css +0 -1
- package/dist/assets/math-DioIQOPJ.js +0 -1
- package/dist/assets/pop-DC_TQG9t.js +0 -1
- package/dist/cli/chunk-36P5K3SD.js +0 -631
- package/dist/cli/chunk-4UDFYF5G.js +0 -132
- package/dist/cli/chunk-53NMBJAO.js +0 -35
- package/dist/cli/chunk-MIIEFUGG.js +0 -623
- package/dist/cli/chunk-QBBKRNGY.js +0 -90
- package/dist/cli/chunk-WPUDGEFY.js +0 -20
- package/dist/cli/editorCommands-UIF5YLUZ.js +0 -33
- package/dist/cli/project-K3QIPGBB.js +0 -12
- package/dist/cli/registerStandardNodes-S2VLMF6J.js +0 -3081
- package/dist/cli/runner-RA6UKEPD.js +0 -37
- package/dist/cli/webBuild-GT4PZT5D.js +0 -37
- package/dist/runtime/builtins/headless.d.ts +0 -19
- package/dist/runtime/builtins/headless.js +0 -25
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-J7VK7MNF.js";
|
|
4
4
|
import {
|
|
5
5
|
CORE_TYPES
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FWMSGKEH.js";
|
|
7
7
|
|
|
8
8
|
// packages/contracts/src/validate.ts
|
|
9
9
|
var IDENTIFIER = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
@@ -19,7 +19,7 @@ var CAPABILITIES_BY_ENVIRONMENT = {
|
|
|
19
19
|
var ALLOWED = CAPABILITIES_BY_ENVIRONMENT;
|
|
20
20
|
var fields = (names) => new Set(names.split(" "));
|
|
21
21
|
var TOP_FIELDS = fields(
|
|
22
|
-
"apiVersion runsOn container capabilities source label description icon inputs outputs props"
|
|
22
|
+
"apiVersion runsOn container capabilities gpuLimits source label description icon inputs outputs props"
|
|
23
23
|
);
|
|
24
24
|
var DATA_FIELDS = fields(
|
|
25
25
|
"kind type default description variadic min max step accept control options schema fields"
|
|
@@ -111,6 +111,16 @@ function validateNodeDefinition(value) {
|
|
|
111
111
|
add("duplicate-capability", `${String(capability)} is duplicated`, path);
|
|
112
112
|
seen.add(capability);
|
|
113
113
|
}
|
|
114
|
+
if (value.gpuLimits !== void 0) {
|
|
115
|
+
if (!seen.has("gpu"))
|
|
116
|
+
add("gpu-limits-without-gpu", "gpuLimits needs the gpu capability", "gpuLimits");
|
|
117
|
+
if (!isRecord(value.gpuLimits))
|
|
118
|
+
add("invalid-gpu-limits", "gpuLimits must be an object of WebGPU limit names to numbers", "gpuLimits");
|
|
119
|
+
else
|
|
120
|
+
for (const [name, limit] of Object.entries(value.gpuLimits))
|
|
121
|
+
if (typeof limit !== "number" || !Number.isFinite(limit) || limit < 0)
|
|
122
|
+
add("invalid-gpu-limits", `gpuLimits.${name} must be a non-negative number`, `gpuLimits.${name}`);
|
|
123
|
+
}
|
|
114
124
|
const inward = /* @__PURE__ */ new Map();
|
|
115
125
|
const outward = /* @__PURE__ */ new Map();
|
|
116
126
|
for (const section of ["inputs", "outputs", "props"]) {
|
|
@@ -307,4 +317,4 @@ export {
|
|
|
307
317
|
CAPABILITIES_BY_ENVIRONMENT,
|
|
308
318
|
validateNodeDefinition
|
|
309
319
|
};
|
|
310
|
-
//# sourceMappingURL=chunk-
|
|
320
|
+
//# sourceMappingURL=chunk-NJFMDXHR.js.map
|
|
@@ -1,53 +1,60 @@
|
|
|
1
|
-
import {
|
|
2
|
-
RunTrace,
|
|
3
|
-
captureNodeConsole
|
|
4
|
-
} from "./chunk-4UDFYF5G.js";
|
|
5
|
-
import {
|
|
6
|
-
installProjectStages
|
|
7
|
-
} from "./chunk-QBBKRNGY.js";
|
|
8
1
|
import {
|
|
9
2
|
setEmbeddedCompiler,
|
|
10
3
|
setProjectModuleCompiler
|
|
11
4
|
} from "./chunk-2KXB47FP.js";
|
|
5
|
+
import {
|
|
6
|
+
installHeadlessCanvas
|
|
7
|
+
} from "./chunk-EZRWJ4G2.js";
|
|
12
8
|
import {
|
|
13
9
|
parseFrameSpec
|
|
14
10
|
} from "./chunk-BP7UKF36.js";
|
|
15
11
|
import {
|
|
16
12
|
encodeMp4,
|
|
17
13
|
timelineFrameSpec
|
|
18
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-7QE2ZNSN.js";
|
|
19
15
|
import {
|
|
20
16
|
applyEnv
|
|
21
17
|
} from "./chunk-ZL4JTG5Y.js";
|
|
22
18
|
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
compileProjectModule,
|
|
26
|
-
formatStageTrace
|
|
27
|
-
} from "./chunk-MIIEFUGG.js";
|
|
28
|
-
import {
|
|
19
|
+
RunTrace,
|
|
20
|
+
captureNodeConsole,
|
|
29
21
|
checkProjectGraph,
|
|
22
|
+
cookingNode,
|
|
30
23
|
inspectProjectGraph,
|
|
31
24
|
installProjectIo,
|
|
25
|
+
installProjectStages,
|
|
32
26
|
renderDeterministicProjectFrames,
|
|
33
27
|
runDeterministicProjectGraph,
|
|
34
28
|
saveStillImages,
|
|
35
29
|
validateProjectGraph
|
|
36
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-QKL7CCRS.js";
|
|
37
31
|
import {
|
|
38
32
|
graphSeed
|
|
39
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-L6B6FUQP.js";
|
|
40
34
|
import {
|
|
41
|
-
|
|
42
|
-
} from "./chunk-
|
|
35
|
+
frameRange
|
|
36
|
+
} from "./chunk-CO22XHNG.js";
|
|
43
37
|
import {
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
compileEmbedded,
|
|
39
|
+
compileProjectModule
|
|
40
|
+
} from "./chunk-W7OUAT7J.js";
|
|
41
|
+
import {
|
|
42
|
+
cascadeVersion,
|
|
43
|
+
formatStageTrace
|
|
44
|
+
} from "./chunk-5ORUQ6ES.js";
|
|
45
|
+
import {
|
|
46
|
+
ProjectRoot
|
|
47
|
+
} from "./chunk-W5PJ5RMP.js";
|
|
46
48
|
|
|
47
49
|
// src/cli/runner.ts
|
|
48
50
|
import * as fs from "fs/promises";
|
|
49
51
|
import * as path from "path";
|
|
50
52
|
import { existsSync } from "node:fs";
|
|
53
|
+
var RENDER_SUGGESTION_FRAMES = 30;
|
|
54
|
+
function renderSuggestion(file, frames, count) {
|
|
55
|
+
if (count < RENDER_SUGGESTION_FRAMES) return null;
|
|
56
|
+
return `${count} frames in one process. cascade render ${file} --frames ${frames} renders them across worker processes (and encodes a preview mp4; --no-video for frames only).`;
|
|
57
|
+
}
|
|
51
58
|
async function runGraph(options) {
|
|
52
59
|
const { file, entryNode, nodes, validateOnly, checkOnly, inspectOnly, strict, verbose, frames, fps, out } = options;
|
|
53
60
|
if (verbose) {
|
|
@@ -98,6 +105,10 @@ async function runGraph(options) {
|
|
|
98
105
|
setEmbeddedCompiler(async (code) => (await compileEmbedded(project, code)).code);
|
|
99
106
|
disposeStageBridge = installProjectStages(project, {
|
|
100
107
|
verbose,
|
|
108
|
+
// A render worker starts Python while the probe frames run.
|
|
109
|
+
prewarm: Boolean(options.worker),
|
|
110
|
+
// A render worker is already one of several processes: one Python each.
|
|
111
|
+
...options.worker ? { poolSize: 1 } : {},
|
|
101
112
|
onTrace: (stage) => {
|
|
102
113
|
trace.recordStage(stage);
|
|
103
114
|
if (verbose) console.log(`[stage] ${formatStageTrace(stage)}`);
|
|
@@ -108,10 +119,11 @@ async function runGraph(options) {
|
|
|
108
119
|
onOutput: (stage, stream, line) => {
|
|
109
120
|
const text = `[${stage ?? "stage-worker"}] ${line}`;
|
|
110
121
|
if (verbose) (stream === "stderr" ? console.warn : console.log)(text);
|
|
122
|
+
else if (stage === null) cookingNode.exit(() => trace.recordLog(stream, text));
|
|
111
123
|
else trace.recordLog(stream, text);
|
|
112
124
|
}
|
|
113
125
|
});
|
|
114
|
-
disposeIoBridge = installProjectIo(project);
|
|
126
|
+
disposeIoBridge = installProjectIo(project, { resident: true });
|
|
115
127
|
} catch (error) {
|
|
116
128
|
if (verbose) console.warn(`No project context for ${file}: ${error instanceof Error ? error.message : error}`);
|
|
117
129
|
}
|
|
@@ -123,6 +135,10 @@ async function runGraph(options) {
|
|
|
123
135
|
if (verbose) console.warn(canvasError.message);
|
|
124
136
|
}
|
|
125
137
|
const frameSpec = frames ? frames === "timeline" ? timelineFrameSpec(graphData) : parseFrameSpec(frames) : null;
|
|
138
|
+
if (frameSpec && frames && !options.worker) {
|
|
139
|
+
const hint = renderSuggestion(file, frames, frameRange(frameSpec.start, frameSpec.end, frameSpec.step ?? 1).length);
|
|
140
|
+
if (hint) (options.json ? console.error : console.log)(hint);
|
|
141
|
+
}
|
|
126
142
|
const restoreConsole = captureNodeConsole(trace);
|
|
127
143
|
const restoreEnv = applyEnv(options.env);
|
|
128
144
|
if (options.env) trace.setEnvNames(Object.keys(options.env));
|
|
@@ -159,7 +175,11 @@ async function runGraph(options) {
|
|
|
159
175
|
...options.outNodes?.length ? { outNodes: options.outNodes } : {},
|
|
160
176
|
...verbose ? { verbose } : {},
|
|
161
177
|
...options.fresh ? { fresh: true } : {},
|
|
162
|
-
...options.worker ? { frameSource: options.worker.frameSource
|
|
178
|
+
...options.worker ? { frameSource: options.worker.frameSource } : {},
|
|
179
|
+
onFrame: async (frame) => {
|
|
180
|
+
trace.recordSaved(frame.durationMs);
|
|
181
|
+
await options.worker?.onFrame(frame);
|
|
182
|
+
},
|
|
163
183
|
observe
|
|
164
184
|
});
|
|
165
185
|
if (rendered && options.worker) {
|
|
@@ -194,11 +214,15 @@ async function runGraph(options) {
|
|
|
194
214
|
const target = options.outNodes?.length || (nodes?.length ?? 0) > 1 ? void 0 : nodes?.[0] ?? entryNode;
|
|
195
215
|
const saveImages = async (graph) => {
|
|
196
216
|
if (!project) return;
|
|
217
|
+
const saving = performance.now();
|
|
197
218
|
images = await saveStillImages(graph, project, {
|
|
198
219
|
...out ? { out } : {},
|
|
199
220
|
...nodes?.length ? { nodes } : entryNode ? { nodes: [entryNode] } : {},
|
|
200
221
|
...options.outNodes?.length ? { extra: options.outNodes } : {}
|
|
201
222
|
});
|
|
223
|
+
const runs = trace.toJSON().runs;
|
|
224
|
+
const cook = runs[runs.length - 1]?.ms;
|
|
225
|
+
if (cook !== void 0) trace.recordSaved(cook + performance.now() - saving);
|
|
202
226
|
};
|
|
203
227
|
if (await runDeterministicProjectGraph(file, graphData, target, observe, saveImages)) {
|
|
204
228
|
if (verbose) console.log("Graph execution completed");
|
|
@@ -236,6 +260,8 @@ Run trace: ${tracePath}`;
|
|
|
236
260
|
}
|
|
237
261
|
|
|
238
262
|
export {
|
|
263
|
+
RENDER_SUGGESTION_FRAMES,
|
|
264
|
+
renderSuggestion,
|
|
239
265
|
runGraph
|
|
240
266
|
};
|
|
241
|
-
//# sourceMappingURL=chunk-
|
|
267
|
+
//# sourceMappingURL=chunk-OBZAP3GG.js.map
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import {
|
|
2
|
+
installHeadlessCanvas
|
|
3
|
+
} from "./chunk-EZRWJ4G2.js";
|
|
4
|
+
import {
|
|
5
|
+
applyScene,
|
|
6
|
+
exportEditor,
|
|
7
|
+
formatPlan,
|
|
8
|
+
fromBase64,
|
|
9
|
+
parseScene
|
|
10
|
+
} from "./chunk-JEW5MPGI.js";
|
|
11
|
+
import {
|
|
12
|
+
cookProjectGraph,
|
|
13
|
+
installProjectIo
|
|
14
|
+
} from "./chunk-QKL7CCRS.js";
|
|
15
|
+
import {
|
|
16
|
+
ProjectRoot
|
|
17
|
+
} from "./chunk-W5PJ5RMP.js";
|
|
18
|
+
|
|
19
|
+
// src/cli/editorCommands.ts
|
|
20
|
+
import fs from "node:fs/promises";
|
|
21
|
+
import path from "node:path";
|
|
22
|
+
var EDITOR_COMMANDS = ["export", "share", "freeze", "publish", "scene"];
|
|
23
|
+
var EDITOR_HELP = `
|
|
24
|
+
Shareable editors (see doc/EDITOR_EXPORT.md):
|
|
25
|
+
cascade export <graph> --plan Print what would ship, build nothing
|
|
26
|
+
cascade export <graph> --out <dir> [--deploy vercel [--project <name>] [--scope <team>] [--public]]
|
|
27
|
+
cascade share <graph | site-dir> [--name <slug>] [--scope <team>] [--protected] Deploy as cascade-<slug>, print the link
|
|
28
|
+
cascade publish <graph> <node>.<prop> [--id <id>] [--label <text>] [--group <name>]
|
|
29
|
+
[--control <kind>] [--min n] [--max n] [--step n] [--help <text>] [--remove]
|
|
30
|
+
cascade freeze <graph> <node> --fields <a,b.c> [--output <port>] [--personal <a,..>]
|
|
31
|
+
cascade scene <graph> <scene.json> --out <new-graph.cascade>
|
|
32
|
+
cascade run <graph> --scene <scene.json> [--write <node>.<port>=<file>]...
|
|
33
|
+
`;
|
|
34
|
+
async function runEditorCommand(args) {
|
|
35
|
+
const [command, graph] = args;
|
|
36
|
+
if (command === "share") {
|
|
37
|
+
const { runShareCommand } = await import("./share-B7HTCOJX.js");
|
|
38
|
+
return runShareCommand(args);
|
|
39
|
+
}
|
|
40
|
+
if (!graph || graph.startsWith("-")) throw new Error(`cascade ${command} requires a graph file`);
|
|
41
|
+
const flags = parseFlags(args.slice(2));
|
|
42
|
+
switch (command) {
|
|
43
|
+
case "export":
|
|
44
|
+
return exportCommand(graph, flags);
|
|
45
|
+
case "publish":
|
|
46
|
+
return publishCommand(graph, flags);
|
|
47
|
+
case "freeze":
|
|
48
|
+
return freezeCommand(graph, flags);
|
|
49
|
+
case "scene":
|
|
50
|
+
return sceneCommand(graph, flags);
|
|
51
|
+
case "run":
|
|
52
|
+
return runWithScene(graph, flags);
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`Unknown command ${command}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
var SWITCHES = /* @__PURE__ */ new Set(["--plan", "--remove", "--json", "--public"]);
|
|
58
|
+
function parseFlags(args) {
|
|
59
|
+
const positional = [];
|
|
60
|
+
const values = /* @__PURE__ */ new Map();
|
|
61
|
+
const switches = /* @__PURE__ */ new Set();
|
|
62
|
+
for (let index = 0; index < args.length; index++) {
|
|
63
|
+
const arg = args[index];
|
|
64
|
+
if (!arg.startsWith("--")) {
|
|
65
|
+
positional.push(arg);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (SWITCHES.has(arg)) {
|
|
69
|
+
switches.add(arg);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const value = args[index + 1];
|
|
73
|
+
if (value === void 0 || value.startsWith("--") && !/^--?\d/.test(value)) throw new Error(`${arg} needs a value`);
|
|
74
|
+
values.set(arg, [...values.get(arg) ?? [], value]);
|
|
75
|
+
index++;
|
|
76
|
+
}
|
|
77
|
+
return { positional, values, switches };
|
|
78
|
+
}
|
|
79
|
+
var one = (flags, name) => {
|
|
80
|
+
const list = flags.values.get(name);
|
|
81
|
+
return list?.[list.length - 1];
|
|
82
|
+
};
|
|
83
|
+
async function exportCommand(graph, flags) {
|
|
84
|
+
const deploy = one(flags, "--deploy");
|
|
85
|
+
if (deploy && deploy !== "vercel") throw new Error("--deploy supports vercel only");
|
|
86
|
+
const result = await exportEditor(graph, {
|
|
87
|
+
plan: flags.switches.has("--plan"),
|
|
88
|
+
out: one(flags, "--out"),
|
|
89
|
+
...deploy ? { deploy: "vercel" } : {},
|
|
90
|
+
project: one(flags, "--project"),
|
|
91
|
+
scope: one(flags, "--scope"),
|
|
92
|
+
...flags.switches.has("--public") ? { public: true } : {}
|
|
93
|
+
});
|
|
94
|
+
if (flags.switches.has("--json")) console.log(JSON.stringify(result.plan, null, 2));
|
|
95
|
+
else console.log(formatPlan(result.plan));
|
|
96
|
+
if (result.directory) console.log(`
|
|
97
|
+
Editor exported: ${result.directory}
|
|
98
|
+
Manifest: ${path.join(result.directory, "export-manifest.json")}`);
|
|
99
|
+
if (result.url) console.log(`Deployed: ${result.url}`);
|
|
100
|
+
}
|
|
101
|
+
async function readGraph(file) {
|
|
102
|
+
return JSON.parse(await fs.readFile(file, "utf8"));
|
|
103
|
+
}
|
|
104
|
+
async function writeEditor(file, document, editor) {
|
|
105
|
+
const next = { ...document, editor };
|
|
106
|
+
await fs.writeFile(file, `${JSON.stringify(next, null, 2)}
|
|
107
|
+
`);
|
|
108
|
+
}
|
|
109
|
+
async function publishCommand(graph, flags) {
|
|
110
|
+
const target = flags.positional[0];
|
|
111
|
+
const match = target ? /^([^.]+)\.(.+)$/.exec(target) : null;
|
|
112
|
+
if (!match) throw new Error("cascade publish needs <node>.<prop>");
|
|
113
|
+
const [, node, prop] = match;
|
|
114
|
+
const document = await readGraph(graph);
|
|
115
|
+
if (!document.nodes.some((item) => item.id === node)) throw new Error(`No node ${node} in ${graph}`);
|
|
116
|
+
const editor = document.editor ?? { id: path.basename(graph).replace(/\.cascade$/, "") };
|
|
117
|
+
const parameters = [...editor.parameters ?? []];
|
|
118
|
+
const id = one(flags, "--id") ?? prop;
|
|
119
|
+
const existing = parameters.findIndex((item) => item.node === node && item.prop === prop);
|
|
120
|
+
if (flags.switches.has("--remove")) {
|
|
121
|
+
if (existing < 0) throw new Error(`${node}.${prop} is not published`);
|
|
122
|
+
parameters.splice(existing, 1);
|
|
123
|
+
await writeEditor(graph, document, { ...editor, parameters });
|
|
124
|
+
console.log(`Unpublished ${node}.${prop}`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const number = (name) => {
|
|
128
|
+
const value = one(flags, name);
|
|
129
|
+
if (value === void 0) return void 0;
|
|
130
|
+
const parsed = Number(value);
|
|
131
|
+
if (!Number.isFinite(parsed)) throw new Error(`${name} must be a number`);
|
|
132
|
+
return parsed;
|
|
133
|
+
};
|
|
134
|
+
const previous = existing >= 0 ? parameters[existing] : void 0;
|
|
135
|
+
const parameter = {
|
|
136
|
+
...previous,
|
|
137
|
+
id: previous?.id ?? id,
|
|
138
|
+
node,
|
|
139
|
+
prop,
|
|
140
|
+
...one(flags, "--label") ? { label: one(flags, "--label") } : {},
|
|
141
|
+
...one(flags, "--group") ? { group: one(flags, "--group") } : {},
|
|
142
|
+
...one(flags, "--control") ? { control: one(flags, "--control") } : {},
|
|
143
|
+
...number("--min") !== void 0 ? { min: number("--min") } : {},
|
|
144
|
+
...number("--max") !== void 0 ? { max: number("--max") } : {},
|
|
145
|
+
...number("--step") !== void 0 ? { step: number("--step") } : {},
|
|
146
|
+
...number("--order") !== void 0 ? { order: number("--order") } : {},
|
|
147
|
+
...one(flags, "--help") ? { help: one(flags, "--help") } : {},
|
|
148
|
+
...one(flags, "--unit") ? { unit: one(flags, "--unit") } : {}
|
|
149
|
+
};
|
|
150
|
+
if (existing >= 0) parameters[existing] = parameter;
|
|
151
|
+
else {
|
|
152
|
+
if (parameters.some((item) => item.id === parameter.id)) throw new Error(`Parameter id ${parameter.id} is taken; pass --id`);
|
|
153
|
+
parameters.push(parameter);
|
|
154
|
+
}
|
|
155
|
+
await writeEditor(graph, document, { ...editor, parameters });
|
|
156
|
+
console.log(`${existing >= 0 ? "Updated" : "Published"} ${node}.${prop} as "${parameter.id}"`);
|
|
157
|
+
}
|
|
158
|
+
async function freezeCommand(graph, flags) {
|
|
159
|
+
const node = flags.positional[0];
|
|
160
|
+
if (!node) throw new Error("cascade freeze needs a node id");
|
|
161
|
+
const fields = (one(flags, "--fields") ?? "").split(",").map((item) => item.trim()).filter(Boolean);
|
|
162
|
+
if (!fields.length) throw new Error("cascade freeze needs --fields: name exactly the values to keep");
|
|
163
|
+
const personal = (one(flags, "--personal") ?? "").split(",").map((item) => item.trim()).filter(Boolean);
|
|
164
|
+
const document = await readGraph(graph);
|
|
165
|
+
if (!document.nodes.some((item) => item.id === node)) throw new Error(`No node ${node} in ${graph}`);
|
|
166
|
+
const graphFile = path.resolve(graph);
|
|
167
|
+
const project = new ProjectRoot(path.dirname(graphFile));
|
|
168
|
+
await installHeadlessCanvas().catch(() => void 0);
|
|
169
|
+
const removeIo = installProjectIo(project);
|
|
170
|
+
const { outputs } = await cookProjectGraph(graphFile, document, node).finally(removeIo);
|
|
171
|
+
const produced = outputs.get(node);
|
|
172
|
+
if (!produced) throw new Error(`${node} produced nothing`);
|
|
173
|
+
const output = one(flags, "--output") ?? [...produced.keys()][0];
|
|
174
|
+
if (!produced.has(output)) throw new Error(`${node} has no output ${output}; it has ${[...produced.keys()].join(", ")}`);
|
|
175
|
+
const full = toJson(produced.get(output));
|
|
176
|
+
const directory = path.join("frozen", node);
|
|
177
|
+
await fs.mkdir(project.resolve(directory), { recursive: true });
|
|
178
|
+
const files = [];
|
|
179
|
+
const pick = async (value) => {
|
|
180
|
+
if (value && typeof value === "object" && !Array.isArray(value) && typeof value.path === "string") {
|
|
181
|
+
const from = value.path;
|
|
182
|
+
const source = project.resolve(from.replace(/^\.\//, ""));
|
|
183
|
+
const name = `${directory}/${path.basename(from)}`;
|
|
184
|
+
await fs.copyFile(source, project.resolve(name));
|
|
185
|
+
files.push(name);
|
|
186
|
+
return { ...value, path: name };
|
|
187
|
+
}
|
|
188
|
+
if (Array.isArray(value)) return Promise.all(value.map(pick));
|
|
189
|
+
if (value && typeof value === "object")
|
|
190
|
+
return Object.fromEntries(await Promise.all(Object.entries(value).map(async ([key, item]) => [key, await pick(item)])));
|
|
191
|
+
return value;
|
|
192
|
+
};
|
|
193
|
+
const chosen = {};
|
|
194
|
+
for (const field of fields) {
|
|
195
|
+
const value = getPath(full, field);
|
|
196
|
+
if (value === void 0) throw new Error(`${node}.${output} has no field ${field}`);
|
|
197
|
+
setPath(chosen, field, await pick(value));
|
|
198
|
+
}
|
|
199
|
+
if (fields.includes("path") && typeof chosen.path === "string" && full && typeof full === "object" && !Array.isArray(full)) {
|
|
200
|
+
const { path: copied } = await pick({ path: chosen.path });
|
|
201
|
+
chosen.path = copied;
|
|
202
|
+
}
|
|
203
|
+
const snapshot = {
|
|
204
|
+
format: "cascade.frozen",
|
|
205
|
+
version: 1,
|
|
206
|
+
node,
|
|
207
|
+
output,
|
|
208
|
+
fields,
|
|
209
|
+
...personal.length ? { personal } : {},
|
|
210
|
+
value: chosen,
|
|
211
|
+
...files.length ? { files } : {},
|
|
212
|
+
frozenAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
213
|
+
};
|
|
214
|
+
const snapshotFile = `${directory}.json`;
|
|
215
|
+
await fs.writeFile(project.resolve(snapshotFile), `${JSON.stringify(snapshot, null, 2)}
|
|
216
|
+
`);
|
|
217
|
+
const editor = document.editor ?? { id: path.basename(graph).replace(/\.cascade$/, "") };
|
|
218
|
+
const freeze = (editor.freeze ?? []).filter((item) => item.node !== node);
|
|
219
|
+
freeze.push({ node, output, snapshot: snapshotFile });
|
|
220
|
+
await writeEditor(graph, document, { ...editor, freeze });
|
|
221
|
+
console.log(`Froze ${node}.${output}: ${fields.join(", ")} \u2192 ${snapshotFile}${files.length ? ` (+${files.length} file${files.length > 1 ? "s" : ""})` : ""}`);
|
|
222
|
+
}
|
|
223
|
+
async function sceneCommand(graph, flags) {
|
|
224
|
+
const sceneFile = flags.positional[0];
|
|
225
|
+
const out = one(flags, "--out");
|
|
226
|
+
if (!sceneFile || !out) throw new Error("cascade scene needs <scene.json> --out <new-graph.cascade>");
|
|
227
|
+
if (path.resolve(out) === path.resolve(graph)) throw new Error("--out must be a new file; the source graph is never overwritten");
|
|
228
|
+
const { document, warnings } = await sceneDocument(graph, sceneFile);
|
|
229
|
+
await fs.writeFile(out, `${JSON.stringify(document, null, 2)}
|
|
230
|
+
`);
|
|
231
|
+
for (const warning of warnings) console.warn(`Warning: ${warning}`);
|
|
232
|
+
console.log(`Scene applied: ${out}`);
|
|
233
|
+
}
|
|
234
|
+
async function sceneDocument(graph, sceneFile) {
|
|
235
|
+
const document = await readGraph(graph);
|
|
236
|
+
const scene = parseScene(await fs.readFile(sceneFile, "utf8"));
|
|
237
|
+
const project = new ProjectRoot(path.dirname(path.resolve(graph)));
|
|
238
|
+
const located = /* @__PURE__ */ new Map();
|
|
239
|
+
for (const [id, file] of Object.entries(scene.files ?? {})) {
|
|
240
|
+
const found = await locateSceneFile(project, file);
|
|
241
|
+
if (found) located.set(id, { path: found, ...file.mediaType ? { mediaType: file.mediaType } : {} });
|
|
242
|
+
}
|
|
243
|
+
return applyScene(document, scene, { resolveFile: (parameter) => located.get(parameter.id) });
|
|
244
|
+
}
|
|
245
|
+
async function locateSceneFile(project, file) {
|
|
246
|
+
const { createHash } = await import("node:crypto");
|
|
247
|
+
const safe = path.basename(file.name).replace(/[^A-Za-z0-9._-]/g, "_");
|
|
248
|
+
if (file.data) {
|
|
249
|
+
const bytes = fromBase64(file.data);
|
|
250
|
+
const digest = createHash("sha256").update(bytes).digest("hex");
|
|
251
|
+
if (digest !== file.sha256) throw new Error(`Scene file ${file.name} does not match its hash`);
|
|
252
|
+
const name = `assets/scenes/${digest.slice(0, 12)}-${safe}`;
|
|
253
|
+
await fs.mkdir(path.dirname(project.resolve(name)), { recursive: true });
|
|
254
|
+
await fs.writeFile(project.resolve(name), bytes);
|
|
255
|
+
return name;
|
|
256
|
+
}
|
|
257
|
+
for (const candidate of await filesNamed(project.root, path.basename(file.name))) {
|
|
258
|
+
const digest = createHash("sha256").update(await fs.readFile(candidate)).digest("hex");
|
|
259
|
+
if (digest === file.sha256) return path.relative(project.root, candidate).split(path.sep).join("/");
|
|
260
|
+
}
|
|
261
|
+
return void 0;
|
|
262
|
+
}
|
|
263
|
+
async function filesNamed(root, name) {
|
|
264
|
+
const found = [];
|
|
265
|
+
const walk = async (directory, depth) => {
|
|
266
|
+
if (depth > 6) return;
|
|
267
|
+
for (const entry of await fs.readdir(directory, { withFileTypes: true }).catch(() => [])) {
|
|
268
|
+
if (entry.name === "node_modules" || entry.name === ".git" || entry.name === ".cascade-cache") continue;
|
|
269
|
+
const file = path.join(directory, entry.name);
|
|
270
|
+
if (entry.isDirectory()) await walk(file, depth + 1);
|
|
271
|
+
else if (entry.name === name) found.push(file);
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
await walk(path.join(root, "assets"), 0);
|
|
275
|
+
await walk(path.join(root, "licensed"), 0);
|
|
276
|
+
return found;
|
|
277
|
+
}
|
|
278
|
+
async function runWithScene(graph, flags) {
|
|
279
|
+
const graphFile = path.resolve(graph);
|
|
280
|
+
let document = await readGraph(graph);
|
|
281
|
+
const scene = one(flags, "--scene");
|
|
282
|
+
if (scene) {
|
|
283
|
+
const applied = await sceneDocument(graph, scene);
|
|
284
|
+
document = applied.document;
|
|
285
|
+
for (const warning of applied.warnings) console.warn(`Warning: ${warning}`);
|
|
286
|
+
}
|
|
287
|
+
await installHeadlessCanvas().catch(() => void 0);
|
|
288
|
+
const project = new ProjectRoot(path.dirname(graphFile));
|
|
289
|
+
const removeIo = installProjectIo(project);
|
|
290
|
+
const { outputs } = await cookProjectGraph(graphFile, document).finally(removeIo);
|
|
291
|
+
for (const spec of flags.values.get("--write") ?? []) {
|
|
292
|
+
const match = /^([^.=]+)\.([^=]+)=(.+)$/.exec(spec);
|
|
293
|
+
if (!match) throw new Error(`--write expects <node>.<port>=<file>, got ${spec}`);
|
|
294
|
+
const [, node, port, file] = match;
|
|
295
|
+
const value = outputs.get(node)?.get(port);
|
|
296
|
+
if (value === void 0) throw new Error(`${node}.${port} produced nothing`);
|
|
297
|
+
if (typeof value === "string") await fs.writeFile(file, value);
|
|
298
|
+
else if (value && typeof value === "object" && typeof value.path === "string")
|
|
299
|
+
await fs.copyFile(project.resolve(value.path.replace(/^\.\//, "")), file);
|
|
300
|
+
else await fs.writeFile(file, JSON.stringify(toJson(value)));
|
|
301
|
+
console.log(`Wrote ${node}.${port} \u2192 ${file}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
function toJson(value) {
|
|
305
|
+
return JSON.parse(JSON.stringify(value, (_key, item) => ArrayBuffer.isView(item) ? Array.from(item) : item) ?? "null");
|
|
306
|
+
}
|
|
307
|
+
function getPath(value, field) {
|
|
308
|
+
let current = value;
|
|
309
|
+
for (const part of field.split(".").flatMap((item) => item.split(/\[(\d+)\]/).filter(Boolean))) {
|
|
310
|
+
if (current === null || typeof current !== "object") return void 0;
|
|
311
|
+
current = current[part];
|
|
312
|
+
}
|
|
313
|
+
return current;
|
|
314
|
+
}
|
|
315
|
+
function setPath(target, field, value) {
|
|
316
|
+
const parts = field.split(".").flatMap((item) => item.split(/\[(\d+)\]/).filter(Boolean));
|
|
317
|
+
let current = target;
|
|
318
|
+
parts.forEach((part, index) => {
|
|
319
|
+
const last = index === parts.length - 1;
|
|
320
|
+
const container = current;
|
|
321
|
+
if (last) {
|
|
322
|
+
container[part] = value;
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (container[part] === void 0) container[part] = /^\d+$/.test(parts[index + 1]) ? [] : {};
|
|
326
|
+
current = container[part];
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export {
|
|
331
|
+
EDITOR_COMMANDS,
|
|
332
|
+
EDITOR_HELP,
|
|
333
|
+
runEditorCommand,
|
|
334
|
+
sceneDocument
|
|
335
|
+
};
|
|
336
|
+
//# sourceMappingURL=chunk-QAGATJGE.js.map
|