@field/cascade 0.10.0 → 0.12.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 +25 -5
- package/ARCHITECTURE.md +5 -4
- package/CHANGELOG.md +382 -0
- package/README.md +1 -2
- package/dist/assets/AgentPanel-1JugFjE4.css +1 -0
- package/dist/assets/AgentPanel-BDL5MddA.js +5 -0
- package/dist/assets/{CodeEditor-DSZBpzdy.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-p25h3tj0.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-DzFLUotB.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-BICrEt0y.js → core-DB-MkGjj.js} +3 -4
- package/dist/assets/coreTypes-DtnDATZ7.js +1 -0
- package/dist/assets/{cssMode-D7TXw57I.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-DvkCO3ko.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-BA2lxsF1.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-BcDiyPd8.js → handlebars-CcD3aMeL.js} +1 -1
- package/dist/assets/{html-C7O4TyhX.js → html-DvZWGfqb.js} +1 -1
- package/dist/assets/{htmlMode-WaDGF3Mj.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-CpIEK7tz.js → javascript-Cap2ahgh.js} +1 -1
- package/dist/assets/{jsonMode-B2FltW0f.js → jsonMode-B0uLjp9C.js} +1 -1
- package/dist/assets/{liquid-CN6FFHZE.js → liquid-CnxwhfLn.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-QhV9XtLp.js → lspLanguageFeatures-Dn9hlKX6.js} +1 -1
- package/dist/assets/math-GeULS-sk.js +1 -0
- package/dist/assets/{mdx-DE89pafV.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-ByTllTB9.js → python-CGyFk4XK.js} +1 -1
- package/dist/assets/{razor-USYlRRCE.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-BXpN8iUz.js → tsMode-BOeXzO9H.js} +1 -1
- package/dist/assets/{typescript-DInBjGQQ.js → typescript-J1SnE_Tu.js} +1 -1
- package/dist/assets/{workers-C7Ye5B7D.js → workers-CYwwTiVF.js} +1 -1
- package/dist/assets/{xml-U0Uocqyo.js → xml-DnPRNzK9.js} +1 -1
- package/dist/assets/{yaml-CBw_PVYf.js → yaml-BmmYBNa9.js} +1 -1
- package/dist/cli/DefinitionNode-P7AA4TAU.js +15 -0
- package/dist/cli/Graph-OB6EWSGL.js +2975 -0
- package/dist/cli/assert-GROGQNCQ.js +25 -0
- package/dist/cli/checks-3WB44XBL.js +189 -0
- package/dist/cli/chunk-2JEU3MGB.js +1125 -0
- package/dist/cli/chunk-2KXB47FP.js +115 -0
- package/dist/cli/chunk-3RXL5GHB.js +816 -0
- package/dist/cli/chunk-53LGFPWX.js +138 -0
- package/dist/cli/chunk-5ORUQ6ES.js +267 -0
- package/dist/cli/chunk-73S4JZXK.js +336 -0
- package/dist/cli/chunk-7QE2ZNSN.js +121 -0
- package/dist/cli/chunk-BP7UKF36.js +376 -0
- package/dist/cli/chunk-BPODRH52.js +201 -0
- package/dist/cli/chunk-BZ63XQ3I.js +1301 -0
- package/dist/cli/chunk-CKS2FQWR.js +89 -0
- package/dist/cli/chunk-CO22XHNG.js +593 -0
- package/dist/cli/chunk-CTPLRSWF.js +2197 -0
- package/dist/cli/chunk-DEQSEFFH.js +153 -0
- package/dist/cli/chunk-EU4ZFZ7Y.js +122 -0
- package/dist/cli/chunk-EZRWJ4G2.js +104 -0
- package/dist/cli/chunk-FWMSGKEH.js +71 -0
- package/dist/cli/chunk-G23A2BZZ.js +705 -0
- package/dist/cli/chunk-GRIN2DDP.js +1465 -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-JVOCK5W4.js +83 -0
- package/dist/cli/chunk-KBGUO27Q.js +15 -0
- package/dist/cli/chunk-KH4MUBKF.js +1551 -0
- package/dist/cli/chunk-L6B6FUQP.js +330 -0
- package/dist/cli/chunk-LTXWBXOM.js +438 -0
- package/dist/cli/chunk-MI5JLQYA.js +220 -0
- package/dist/cli/chunk-MP653A5O.js +3766 -0
- package/dist/cli/chunk-NJFMDXHR.js +320 -0
- package/dist/cli/chunk-OM6BEME6.js +267 -0
- package/dist/cli/chunk-OWWBYLHC.js +136 -0
- package/dist/cli/chunk-QQPA2ZHH.js +273 -0
- package/dist/cli/chunk-RUU3YWXU.js +99 -0
- package/dist/cli/chunk-RXDIMXN5.js +98 -0
- package/dist/cli/chunk-ST6LROUG.js +267 -0
- package/dist/cli/chunk-TJW67QSI.js +225 -0
- package/dist/cli/chunk-WD62JIP6.js +118 -0
- package/dist/cli/chunk-WGKPJZDY.js +364 -0
- package/dist/cli/chunk-X4WKAOQP.js +634 -0
- package/dist/cli/chunk-X566FWBV.js +156 -0
- package/dist/cli/chunk-YH637PDL.js +317 -0
- package/dist/cli/chunk-ZL4JTG5Y.js +37 -0
- package/dist/cli/chunk-ZSCUZE6I.js +112 -0
- package/dist/cli/cliCommands-JJN5Z3ZC.js +3470 -0
- package/dist/cli/commands-PHYFYA3F.js +1374 -0
- package/dist/cli/contactSheet-2PQVRUFW.js +11 -0
- package/dist/cli/definitions-BPOPW52L.js +32 -0
- package/dist/cli/doctorCommand-ORWQRNYP.js +106 -0
- package/dist/cli/edit-S5KEQ5RA.js +28 -0
- package/dist/cli/editorCommands-NFR32JOY.js +41 -0
- package/dist/cli/encode-ICPEPMH5.js +17 -0
- package/dist/cli/file-3HTQHPYQ.js +41 -0
- package/dist/cli/filters-6ODFWYK4.js +379 -0
- package/dist/cli/frames-LSAUBZ7P.js +16 -0
- package/dist/cli/generators-YU7GB4MD.js +210 -0
- package/dist/cli/geo-6ZPGKZRU.js +43 -0
- package/dist/cli/graphCommands-EOUOBOIJ.js +184 -0
- package/dist/cli/graphFile-YTGJB5F5.js +292 -0
- package/dist/cli/headlessCanvas-ENRHC7GS.js +16 -0
- package/dist/cli/helpCommand-PULH6ZYB.js +157 -0
- package/dist/cli/image-TXELZZK5.js +55 -0
- package/dist/cli/index.js +100 -30756
- package/dist/cli/math-RSYRQ3C6.js +16 -0
- package/dist/cli/mcp-JVZFQOEX.js +164 -0
- package/dist/cli/parity-X6DEH2DV.js +334 -0
- package/dist/cli/pop-B7SIIYKN.js +39 -0
- package/dist/cli/project-VYGIA7JX.js +12 -0
- package/dist/cli/projectDefinition-F3D7UIHJ.js +27 -0
- package/dist/cli/projectRuntime-2Q4JKEH3.js +55 -0
- package/dist/cli/registerStandardNodes-BXJCB6E4.js +744 -0
- package/dist/cli/render-PT4MWI6U.js +438 -0
- package/dist/cli/runCommand-HNPQVZMS.js +198 -0
- package/dist/cli/runner-5XPXVW7J.js +43 -0
- package/dist/cli/runtime/image.ts +302 -0
- package/dist/cli/runtime/io.ts +78 -0
- package/dist/cli/runtime/stage.ts +4 -1
- package/dist/cli/share-MHF6TNRK.js +166 -0
- package/dist/cli/stageCache-TY2BFZJR.js +15 -0
- package/dist/cli/stageRunner-KY2EJP7X.js +10 -0
- package/dist/cli/text-MB3EKR4H.js +126 -0
- package/dist/cli/verbs-PI2JH5FI.js +19 -0
- package/dist/cli/webBuild-WPPMGGW7.js +44 -0
- package/dist/contracts/capabilities.d.ts +18 -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/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/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 +156 -0
- package/dist/image.js +161 -0
- package/dist/index.html +8 -2
- package/dist/io.d.ts +29 -0
- package/dist/io.js +40 -0
- package/dist/player/app.js +3 -2
- package/dist/player/editor.js +35 -9
- package/dist/player/editorEngine.js +3 -2
- 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 +64 -0
- package/dist/runtime/builtins/image/contactSheet.js +150 -0
- 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 +952 -0
- package/dist/runtime/builtins/image/index.js +44 -0
- 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/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/dist/stage.js +4 -1
- package/doc/CLI_REFERENCE.md +91 -2
- package/doc/EDITOR_EXPORT.md +37 -2
- package/doc/MCP.md +18 -1
- package/doc/NODE_REFERENCE.md +424 -10
- package/doc/PROJECT_AUTHORING.md +222 -7
- package/package.json +19 -4
- package/dist/assets/CodePanel-sY6sZa7B.js +0 -2
- package/dist/assets/CustomNodeDialog-BRKnqZhp.js +0 -1
- package/dist/assets/ExportDialog-C7dVGua4.js +0 -358
- package/dist/assets/ExportDialog-DOq0flMV.css +0 -1
- package/dist/assets/OpenGraphDialog-ZsgL-iwr.js +0 -1
- package/dist/assets/ProjectSettings-Cw17nNe3.js +0 -2
- package/dist/assets/definitions-DUww2Rt-.js +0 -1
- package/dist/assets/geo-C2RHOVHC.js +0 -1
- package/dist/assets/image-DR4oeyJB.js +0 -2062
- package/dist/assets/index-7vae6YFC.css +0 -1
- package/dist/assets/index-DyvDC6pS.js +0 -219
- package/dist/assets/math-DaDEgWKt.js +0 -1
- package/dist/assets/pop-pLH7L0PW.js +0 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import {
|
|
2
|
+
colorToCss,
|
|
3
|
+
normalizeColor,
|
|
4
|
+
readPixelsFromCanvas,
|
|
5
|
+
surface,
|
|
6
|
+
writePixels
|
|
7
|
+
} from "./chunk-WGKPJZDY.js";
|
|
8
|
+
|
|
9
|
+
// packages/runtime/src/builtins/image/text.ts
|
|
10
|
+
var FONT_FILE = /\.(otf|ttf|woff2?)$/i;
|
|
11
|
+
var HOST_KEY = "__cascadeImageHost";
|
|
12
|
+
var registered = /* @__PURE__ */ new Set();
|
|
13
|
+
function fingerprint(bytes) {
|
|
14
|
+
let hash = 2166136261;
|
|
15
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
16
|
+
hash ^= bytes[index];
|
|
17
|
+
hash = Math.imul(hash, 16777619);
|
|
18
|
+
}
|
|
19
|
+
return `${bytes.length}-${(hash >>> 0).toString(16)}`;
|
|
20
|
+
}
|
|
21
|
+
async function fontFamily(context, font) {
|
|
22
|
+
const path = font.trim();
|
|
23
|
+
if (!FONT_FILE.test(path)) return font;
|
|
24
|
+
let bytes;
|
|
25
|
+
try {
|
|
26
|
+
const assets = context.capabilities.assets;
|
|
27
|
+
if (!assets) throw new Error("no assets");
|
|
28
|
+
bytes = await assets.read({ path }, { signal: context.signal });
|
|
29
|
+
} catch {
|
|
30
|
+
return "sans-serif";
|
|
31
|
+
}
|
|
32
|
+
const family = `cascade-font-${fingerprint(bytes)}`;
|
|
33
|
+
const globals = globalThis;
|
|
34
|
+
const host = globals[HOST_KEY];
|
|
35
|
+
const fonts = host ? null : globals.fonts ?? globals.document?.fonts;
|
|
36
|
+
const key = `${host ? `headless:${host.renderer}` : "browser"}:${family}`;
|
|
37
|
+
if (registered.has(key)) return family;
|
|
38
|
+
if (host && typeof host.registerFont === "function") {
|
|
39
|
+
await host.registerFont(family, bytes, {});
|
|
40
|
+
} else if (typeof globals.FontFace === "function" && fonts) {
|
|
41
|
+
const face = new globals.FontFace(family, bytes.slice().buffer);
|
|
42
|
+
fonts.add(await face.load());
|
|
43
|
+
} else {
|
|
44
|
+
return "sans-serif";
|
|
45
|
+
}
|
|
46
|
+
registered.add(key);
|
|
47
|
+
return family;
|
|
48
|
+
}
|
|
49
|
+
async function executeText(context) {
|
|
50
|
+
const { props } = context;
|
|
51
|
+
const [width, height] = [props.resolution[0], props.resolution[1]];
|
|
52
|
+
const color = normalizeColor(props.color);
|
|
53
|
+
const background = normalizeColor(props.backgroundColor);
|
|
54
|
+
const [offsetX, offsetY] = props.offset;
|
|
55
|
+
const { fontSize, alignH, alignV, rotation, letterSpacing } = props;
|
|
56
|
+
const family = await fontFamily(context, props.font);
|
|
57
|
+
const { canvas, context: ctx } = surface(width, height);
|
|
58
|
+
if (background.a > 0) {
|
|
59
|
+
ctx.fillStyle = colorToCss(background);
|
|
60
|
+
ctx.fillRect(0, 0, width, height);
|
|
61
|
+
} else {
|
|
62
|
+
ctx.clearRect(0, 0, width, height);
|
|
63
|
+
}
|
|
64
|
+
ctx.save();
|
|
65
|
+
ctx.globalAlpha = props.opacity;
|
|
66
|
+
ctx.font = `${props.fontStyle} ${props.fontWeight} ${fontSize}px ${family}`;
|
|
67
|
+
ctx.fillStyle = colorToCss(color);
|
|
68
|
+
const lines = props.text.split("\n");
|
|
69
|
+
const lineHeightPx = fontSize * props.lineHeight;
|
|
70
|
+
const totalTextHeight = lines.length * lineHeightPx;
|
|
71
|
+
let anchorX;
|
|
72
|
+
let anchorY;
|
|
73
|
+
switch (alignH) {
|
|
74
|
+
case "left":
|
|
75
|
+
ctx.textAlign = "left";
|
|
76
|
+
anchorX = 0;
|
|
77
|
+
break;
|
|
78
|
+
case "right":
|
|
79
|
+
ctx.textAlign = "right";
|
|
80
|
+
anchorX = width;
|
|
81
|
+
break;
|
|
82
|
+
default:
|
|
83
|
+
ctx.textAlign = "center";
|
|
84
|
+
anchorX = width / 2;
|
|
85
|
+
}
|
|
86
|
+
switch (alignV) {
|
|
87
|
+
case "top":
|
|
88
|
+
anchorY = fontSize;
|
|
89
|
+
break;
|
|
90
|
+
case "bottom":
|
|
91
|
+
anchorY = height - totalTextHeight + fontSize;
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
anchorY = (height - totalTextHeight) / 2 + fontSize;
|
|
95
|
+
}
|
|
96
|
+
anchorX += offsetX;
|
|
97
|
+
anchorY += offsetY;
|
|
98
|
+
if (rotation !== 0) {
|
|
99
|
+
const pivotY = anchorY - fontSize / 2 + totalTextHeight / 2;
|
|
100
|
+
ctx.translate(anchorX, pivotY);
|
|
101
|
+
ctx.rotate(rotation * Math.PI / 180);
|
|
102
|
+
ctx.translate(-anchorX, -pivotY);
|
|
103
|
+
}
|
|
104
|
+
if (letterSpacing !== 0) {
|
|
105
|
+
ctx.textAlign = "left";
|
|
106
|
+
lines.forEach((line, index) => {
|
|
107
|
+
const y = anchorY + index * lineHeightPx;
|
|
108
|
+
let lineWidth = 0;
|
|
109
|
+
for (const char of line) lineWidth += ctx.measureText(char).width + letterSpacing;
|
|
110
|
+
lineWidth -= letterSpacing;
|
|
111
|
+
let x = alignH === "left" ? anchorX : alignH === "right" ? anchorX - lineWidth : anchorX - lineWidth / 2;
|
|
112
|
+
for (const char of line) {
|
|
113
|
+
ctx.fillText(char, x, y);
|
|
114
|
+
x += ctx.measureText(char).width + letterSpacing;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
lines.forEach((line, index) => ctx.fillText(line, anchorX, anchorY + index * lineHeightPx));
|
|
119
|
+
}
|
|
120
|
+
ctx.restore();
|
|
121
|
+
context.outputs.image.set(await writePixels(context, readPixelsFromCanvas(canvas)));
|
|
122
|
+
}
|
|
123
|
+
export {
|
|
124
|
+
executeText
|
|
125
|
+
};
|
|
126
|
+
//# sourceMappingURL=text-MB3EKR4H.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
VERBS,
|
|
3
|
+
graphCommandsHelp,
|
|
4
|
+
graphOptions,
|
|
5
|
+
isGraphCommand,
|
|
6
|
+
mainHelp,
|
|
7
|
+
mcpTools,
|
|
8
|
+
verbFor
|
|
9
|
+
} from "./chunk-G23A2BZZ.js";
|
|
10
|
+
export {
|
|
11
|
+
VERBS,
|
|
12
|
+
graphCommandsHelp,
|
|
13
|
+
graphOptions,
|
|
14
|
+
isGraphCommand,
|
|
15
|
+
mainHelp,
|
|
16
|
+
mcpTools,
|
|
17
|
+
verbFor
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=verbs-PI2JH5FI.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildPlayer,
|
|
3
|
+
canonicalFuturePath,
|
|
4
|
+
exists,
|
|
5
|
+
inside,
|
|
6
|
+
installRoot,
|
|
7
|
+
playerFile,
|
|
8
|
+
staticRuntimePlugin
|
|
9
|
+
} from "./chunk-OM6BEME6.js";
|
|
10
|
+
import "./chunk-MP653A5O.js";
|
|
11
|
+
import "./chunk-MI5JLQYA.js";
|
|
12
|
+
import "./chunk-GRIN2DDP.js";
|
|
13
|
+
import "./chunk-X4WKAOQP.js";
|
|
14
|
+
import "./chunk-DEQSEFFH.js";
|
|
15
|
+
import "./chunk-RXDIMXN5.js";
|
|
16
|
+
import "./chunk-QQPA2ZHH.js";
|
|
17
|
+
import "./chunk-KH4MUBKF.js";
|
|
18
|
+
import "./chunk-HSNOBIVT.js";
|
|
19
|
+
import "./chunk-L6B6FUQP.js";
|
|
20
|
+
import "./chunk-HFHWYL55.js";
|
|
21
|
+
import "./chunk-KBGUO27Q.js";
|
|
22
|
+
import "./chunk-ICH7N5PN.js";
|
|
23
|
+
import "./chunk-CO22XHNG.js";
|
|
24
|
+
import "./chunk-LTXWBXOM.js";
|
|
25
|
+
import "./chunk-BZ63XQ3I.js";
|
|
26
|
+
import "./chunk-YH637PDL.js";
|
|
27
|
+
import "./chunk-X566FWBV.js";
|
|
28
|
+
import "./chunk-WD62JIP6.js";
|
|
29
|
+
import "./chunk-5ORUQ6ES.js";
|
|
30
|
+
import "./chunk-2JEU3MGB.js";
|
|
31
|
+
import "./chunk-NJFMDXHR.js";
|
|
32
|
+
import "./chunk-J7VK7MNF.js";
|
|
33
|
+
import "./chunk-FWMSGKEH.js";
|
|
34
|
+
import "./chunk-JVOCK5W4.js";
|
|
35
|
+
export {
|
|
36
|
+
buildPlayer,
|
|
37
|
+
canonicalFuturePath,
|
|
38
|
+
exists,
|
|
39
|
+
inside,
|
|
40
|
+
installRoot,
|
|
41
|
+
playerFile,
|
|
42
|
+
staticRuntimePlugin
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=webBuild-WPPMGGW7.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AssetRef, ImageRef, JsonValue } from "./values.js";
|
|
1
|
+
import type { AssetRef, ImagePixels, ImageRef, JsonValue } from "./values.js";
|
|
2
2
|
export interface CascadeAbortSignal {
|
|
3
3
|
readonly aborted: boolean;
|
|
4
4
|
readonly reason?: unknown;
|
|
@@ -46,6 +46,23 @@ export interface AssetCapability {
|
|
|
46
46
|
signal: CascadeAbortSignal;
|
|
47
47
|
}): Promise<AssetRef>;
|
|
48
48
|
resolveUrl?(ref: AssetRef | ImageRef): Promise<ResourceLease<string>>;
|
|
49
|
+
/**
|
|
50
|
+
* Store an intermediate image from its pixels. Optional; a host without it
|
|
51
|
+
* gets encoded bytes through `write`. The host chooses how: the headless
|
|
52
|
+
* host holds the pixels in memory and writes a fast lossless PNG behind
|
|
53
|
+
* (zlib level 1), or encodes that PNG at once when the run does not keep
|
|
54
|
+
* pixels. The returned path is content-addressed like `write`'s and is a
|
|
55
|
+
* whole file before anything reads it from disk. Finals are not encoded
|
|
56
|
+
* here: a run's saved outputs are encoded at full compression when copied.
|
|
57
|
+
*/
|
|
58
|
+
keepImage?(pixels: ImagePixels, metadata: {
|
|
59
|
+
suggestedName?: string;
|
|
60
|
+
}, options: {
|
|
61
|
+
signal: CascadeAbortSignal;
|
|
62
|
+
}): Promise<AssetRef>;
|
|
63
|
+
/** The pixels behind a stored image while the host still holds them in
|
|
64
|
+
* memory, so a reader skips the read and the decode. */
|
|
65
|
+
imagePixels?(ref: AssetRef | ImageRef): ImagePixels | undefined;
|
|
49
66
|
}
|
|
50
67
|
export interface MediaCapability {
|
|
51
68
|
decodeImage(ref: ImageRef | AssetRef, options: {
|
|
@@ -57,6 +57,14 @@ export declare const Color: Readonly<{
|
|
|
57
57
|
alpha(color: Color): number;
|
|
58
58
|
/** The same colour at full alpha. */
|
|
59
59
|
opaque(color: Color): Color;
|
|
60
|
+
/**
|
|
61
|
+
* A colour saved in an older shape, as the one colour: `{ r, g, b, a? }`
|
|
62
|
+
* (the class-based image nodes stored that until 2026-11-07) or three
|
|
63
|
+
* components, with alpha 1. Components above 1 are read as 0–255, the way
|
|
64
|
+
* those nodes read them. Anything else comes back unchanged, so a reader can
|
|
65
|
+
* apply this to every stored `color` value and validate the result.
|
|
66
|
+
*/
|
|
67
|
+
upgrade(value: unknown): unknown;
|
|
60
68
|
/**
|
|
61
69
|
* Four unit components from anything indexable, clamping and defaulting a
|
|
62
70
|
* missing alpha to 1. The reader for a `Cd` attribute's flat array, and the
|
package/dist/contracts/color.js
CHANGED
|
@@ -70,6 +70,29 @@ export const Color = Object.freeze({
|
|
|
70
70
|
opaque(color) {
|
|
71
71
|
return [clamp(color[0]), clamp(color[1]), clamp(color[2]), 1];
|
|
72
72
|
},
|
|
73
|
+
/**
|
|
74
|
+
* A colour saved in an older shape, as the one colour: `{ r, g, b, a? }`
|
|
75
|
+
* (the class-based image nodes stored that until 2026-11-07) or three
|
|
76
|
+
* components, with alpha 1. Components above 1 are read as 0–255, the way
|
|
77
|
+
* those nodes read them. Anything else comes back unchanged, so a reader can
|
|
78
|
+
* apply this to every stored `color` value and validate the result.
|
|
79
|
+
*/
|
|
80
|
+
upgrade(value) {
|
|
81
|
+
const legacy = value !== null && typeof value === "object" && !Array.isArray(value) && "r" in value && "g" in value && "b" in value
|
|
82
|
+
? value
|
|
83
|
+
: Array.isArray(value) && value.length === 3
|
|
84
|
+
? { r: value[0], g: value[1], b: value[2] }
|
|
85
|
+
: null;
|
|
86
|
+
if (!legacy)
|
|
87
|
+
return value;
|
|
88
|
+
const parts = [legacy.r, legacy.g, legacy.b, legacy.a ?? 1];
|
|
89
|
+
if (!parts.every((part) => typeof part === "number" && Number.isFinite(part)))
|
|
90
|
+
return value;
|
|
91
|
+
const numbers = parts;
|
|
92
|
+
const unit = numbers.slice(0, 3).every((part) => part <= 1);
|
|
93
|
+
const read = (part) => (unit ? part : part / 255);
|
|
94
|
+
return [read(numbers[0]), read(numbers[1]), read(numbers[2]), legacy.a === undefined ? 1 : read(numbers[3])];
|
|
95
|
+
},
|
|
73
96
|
/**
|
|
74
97
|
* Four unit components from anything indexable, clamping and defaulting a
|
|
75
98
|
* missing alpha to 1. The reader for a `Cd` attribute's flat array, and the
|
|
@@ -190,6 +190,16 @@ export interface NodeDefinitionForEnvironment<E extends RuntimeEnvironment> {
|
|
|
190
190
|
*/
|
|
191
191
|
readonly container?: "subnet" | "feedback";
|
|
192
192
|
readonly capabilities?: readonly CapabilityForEnvironment<E>[];
|
|
193
|
+
/**
|
|
194
|
+
* GPU limits this node cannot run without, by WebGPU name, for a node that
|
|
195
|
+
* declares `gpu`: `{ maxStorageBufferBindingSize: 512 * 2 ** 20 }`. The host
|
|
196
|
+
* already asks for everything the adapter allows; this makes a GPU that
|
|
197
|
+
* allows less fail before the cook, naming the limit, instead of with a
|
|
198
|
+
* validation error from inside it. `max*` limits are minimums to reach,
|
|
199
|
+
* `min*Alignment` ones maximums. Read `context.capabilities.gpu.limits` for
|
|
200
|
+
* what the device actually gives.
|
|
201
|
+
*/
|
|
202
|
+
readonly gpuLimits?: Readonly<Record<string, number>>;
|
|
193
203
|
/**
|
|
194
204
|
* `live` marks a node that reads data from outside the graph — an archive,
|
|
195
205
|
* a CLI, a cache, body data, the filesystem or a network. `cascade export`
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact-array JSON formatting for .cascade files — ported unchanged
|
|
3
|
+
* from the original routes/projects.ts (real design work: keeps small
|
|
4
|
+
* arrays like [x, y] coordinates and [from, to] connections on one line
|
|
5
|
+
* instead of exploding them across many, so a saved graph stays readable
|
|
6
|
+
* and diffable in git — which matters now that every save is a commit.
|
|
7
|
+
*
|
|
8
|
+
* The one copy: Studio's save and download (src/utils/fileSystem.ts), the
|
|
9
|
+
* server's graph route and the CLI's graph edits all write through it, so a
|
|
10
|
+
* file saved by any of them diffs cleanly against the others.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Format JSON string with compact arrays (keeps small arrays on single lines)
|
|
14
|
+
* This function finds multi-line arrays with 2-4 elements and compacts them
|
|
15
|
+
* Handles both numeric arrays and arrays containing small arrays (like connections)
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatCompactJSON(jsonString: string, indent?: number): string;
|
|
18
|
+
//# sourceMappingURL=documentFormat.d.ts.map
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compact-array JSON formatting for .cascade files — ported unchanged
|
|
3
|
+
* from the original routes/projects.ts (real design work: keeps small
|
|
4
|
+
* arrays like [x, y] coordinates and [from, to] connections on one line
|
|
5
|
+
* instead of exploding them across many, so a saved graph stays readable
|
|
6
|
+
* and diffable in git — which matters now that every save is a commit.
|
|
7
|
+
*
|
|
8
|
+
* The one copy: Studio's save and download (src/utils/fileSystem.ts), the
|
|
9
|
+
* server's graph route and the CLI's graph edits all write through it, so a
|
|
10
|
+
* file saved by any of them diffs cleanly against the others.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Format JSON string with compact arrays (keeps small arrays on single lines)
|
|
14
|
+
* This function finds multi-line arrays with 2-4 elements and compacts them
|
|
15
|
+
* Handles both numeric arrays and arrays containing small arrays (like connections)
|
|
16
|
+
*/
|
|
17
|
+
export function formatCompactJSON(jsonString, indent = 2) {
|
|
18
|
+
// Process multiple passes to handle nested arrays
|
|
19
|
+
let result = jsonString;
|
|
20
|
+
let previousResult = '';
|
|
21
|
+
// Keep processing until no more changes (handles nested arrays)
|
|
22
|
+
while (result !== previousResult) {
|
|
23
|
+
previousResult = result;
|
|
24
|
+
result = formatCompactJSONPass(result, indent);
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Single pass of compact formatting
|
|
30
|
+
*/
|
|
31
|
+
function formatCompactJSONPass(jsonString, indent = 2) {
|
|
32
|
+
const lines = jsonString.split('\n');
|
|
33
|
+
const result = [];
|
|
34
|
+
let i = 0;
|
|
35
|
+
while (i < lines.length) {
|
|
36
|
+
const line = lines[i];
|
|
37
|
+
const trimmed = line.trim();
|
|
38
|
+
// Check if this line starts an array (pattern: "key": [ or just [)
|
|
39
|
+
if (trimmed.endsWith('[') && (trimmed.includes(':') || trimmed === '[')) {
|
|
40
|
+
// Collect lines until we find the closing bracket
|
|
41
|
+
let arrayLines = [line];
|
|
42
|
+
let bracketDepth = 1;
|
|
43
|
+
let j = i + 1;
|
|
44
|
+
while (j < lines.length && bracketDepth > 0) {
|
|
45
|
+
const currentLine = lines[j];
|
|
46
|
+
arrayLines.push(currentLine);
|
|
47
|
+
// Count bracket depth
|
|
48
|
+
for (const char of currentLine) {
|
|
49
|
+
if (char === '[')
|
|
50
|
+
bracketDepth++;
|
|
51
|
+
if (char === ']')
|
|
52
|
+
bracketDepth--;
|
|
53
|
+
}
|
|
54
|
+
j++;
|
|
55
|
+
}
|
|
56
|
+
// Extract array content (lines between opening and closing brackets)
|
|
57
|
+
// Handle nested arrays by extracting complete array elements
|
|
58
|
+
const arrayContent = [];
|
|
59
|
+
let k = 1;
|
|
60
|
+
while (k < arrayLines.length - 1) {
|
|
61
|
+
const currentLine = arrayLines[k].trim();
|
|
62
|
+
// Check if this line starts a nested array
|
|
63
|
+
if (currentLine.endsWith('[') || (currentLine.startsWith('[') && !currentLine.endsWith(']'))) {
|
|
64
|
+
// Extract the complete nested array
|
|
65
|
+
let nestedArrayLines = [arrayLines[k]];
|
|
66
|
+
let nestedDepth = 1;
|
|
67
|
+
let m = k + 1;
|
|
68
|
+
while (m < arrayLines.length - 1 && nestedDepth > 0) {
|
|
69
|
+
nestedArrayLines.push(arrayLines[m]);
|
|
70
|
+
for (const char of arrayLines[m]) {
|
|
71
|
+
if (char === '[')
|
|
72
|
+
nestedDepth++;
|
|
73
|
+
if (char === ']')
|
|
74
|
+
nestedDepth--;
|
|
75
|
+
}
|
|
76
|
+
m++;
|
|
77
|
+
}
|
|
78
|
+
// Join nested array lines into a single compact representation
|
|
79
|
+
const nestedContent = [];
|
|
80
|
+
for (let n = 1; n < nestedArrayLines.length - 1; n++) {
|
|
81
|
+
const nestedLine = nestedArrayLines[n].trim().replace(/,$/, '').trim();
|
|
82
|
+
if (nestedLine) {
|
|
83
|
+
nestedContent.push(nestedLine);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Create compact nested array string
|
|
87
|
+
const nestedArray = '[' + nestedContent.map(c => c.trim()).join(', ') + ']';
|
|
88
|
+
arrayContent.push(nestedArray);
|
|
89
|
+
k = m;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Simple element
|
|
93
|
+
const content = currentLine.replace(/,$/, '').trim();
|
|
94
|
+
if (content) {
|
|
95
|
+
arrayContent.push(content);
|
|
96
|
+
}
|
|
97
|
+
k++;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Check if it's a small numeric array (2-4 elements)
|
|
101
|
+
const isSmallNumericArray = arrayContent.length >= 2 &&
|
|
102
|
+
arrayContent.length <= 4 &&
|
|
103
|
+
arrayContent.every(item => {
|
|
104
|
+
const trimmed = item.trim();
|
|
105
|
+
return /^-?\d+(\.\d+)?([eE][+-]?\d+)?$/.test(trimmed);
|
|
106
|
+
});
|
|
107
|
+
// Check if it's an array containing small arrays (like connections: [[a, b], [c, d]])
|
|
108
|
+
// Look for patterns where each element is a small array (2-4 elements)
|
|
109
|
+
// This handles both already-compacted arrays and multi-line nested arrays
|
|
110
|
+
let isArrayOfSmallArrays = false;
|
|
111
|
+
if (arrayContent.length >= 2 && arrayContent.length <= 20) { // Reasonable limit for connections
|
|
112
|
+
// Check if elements are arrays (either compact or multi-line)
|
|
113
|
+
const allAreArrays = arrayContent.every(item => {
|
|
114
|
+
const trimmed = item.trim();
|
|
115
|
+
// Already compact array like [a, b] or ["a", 0]
|
|
116
|
+
if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
|
|
117
|
+
const inner = trimmed.slice(1, -1).trim();
|
|
118
|
+
const parts = inner.split(',').map(p => p.trim()).filter(p => p);
|
|
119
|
+
return parts.length >= 2 && parts.length <= 4;
|
|
120
|
+
}
|
|
121
|
+
// Multi-line array - check if this line starts an array
|
|
122
|
+
if (trimmed.endsWith('[')) {
|
|
123
|
+
return true; // This will be handled in a later pass
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
});
|
|
127
|
+
if (allAreArrays) {
|
|
128
|
+
// Check if inner arrays are small (2-4 elements each)
|
|
129
|
+
// For multi-line arrays, we'll need to extract their content
|
|
130
|
+
let allSmall = true;
|
|
131
|
+
for (const item of arrayContent) {
|
|
132
|
+
const trimmed = item.trim();
|
|
133
|
+
if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
|
|
134
|
+
// Already compact - check size
|
|
135
|
+
const inner = trimmed.slice(1, -1).trim();
|
|
136
|
+
const parts = inner.split(',').map(p => p.trim()).filter(p => p);
|
|
137
|
+
if (parts.length < 2 || parts.length > 4) {
|
|
138
|
+
allSmall = false;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else if (trimmed.endsWith('[')) {
|
|
143
|
+
// Multi-line array - will be compacted in next pass, assume it's small for now
|
|
144
|
+
// We'll handle this in the multi-pass approach
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
allSmall = false;
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
isArrayOfSmallArrays = allSmall;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (isSmallNumericArray || isArrayOfSmallArrays) {
|
|
155
|
+
// Compact format: put entire array on one line
|
|
156
|
+
const indentLevel = (line.match(/^(\s*)/)?.[1] || '').length;
|
|
157
|
+
// Extract the key part (everything before the opening bracket)
|
|
158
|
+
const keyMatch = trimmed.match(/^(.+?)\s*\[\s*$/);
|
|
159
|
+
const keyPart = keyMatch ? keyMatch[1] : '';
|
|
160
|
+
// Check if the closing bracket line has a comma (last line in arrayLines)
|
|
161
|
+
const closingLine = arrayLines[arrayLines.length - 1];
|
|
162
|
+
const hasComma = closingLine.trim().endsWith(',');
|
|
163
|
+
// Format array content
|
|
164
|
+
let formattedContent;
|
|
165
|
+
if (isArrayOfSmallArrays) {
|
|
166
|
+
// For arrays of arrays, each element should be compact
|
|
167
|
+
// If an element is a multi-line array (ends with [), we can't compact it yet
|
|
168
|
+
// Otherwise, use the already-compact form
|
|
169
|
+
formattedContent = arrayContent.map(c => {
|
|
170
|
+
const trimmed = c.trim();
|
|
171
|
+
// If it's already compact, use it as-is
|
|
172
|
+
if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
|
|
173
|
+
return trimmed;
|
|
174
|
+
}
|
|
175
|
+
// If it's a multi-line array start, we'll need another pass
|
|
176
|
+
// For now, return as-is (will be handled in next pass)
|
|
177
|
+
return trimmed;
|
|
178
|
+
}).join(', ');
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
// Simple numeric array
|
|
182
|
+
formattedContent = arrayContent.map(c => c.trim()).join(', ');
|
|
183
|
+
}
|
|
184
|
+
const compactArray = keyPart + ' [' + formattedContent + ']' + (hasComma ? ',' : '');
|
|
185
|
+
result.push(' '.repeat(indentLevel) + compactArray);
|
|
186
|
+
i = j; // Skip the processed lines
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
result.push(line);
|
|
191
|
+
i++;
|
|
192
|
+
}
|
|
193
|
+
return result.join('\n');
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=documentFormat.js.map
|
|
@@ -42,6 +42,13 @@ export interface EditorDeclaration {
|
|
|
42
42
|
readonly panel?: EditorPanelDeclaration;
|
|
43
43
|
/** The read-only stage view. On unless the author turns it off. */
|
|
44
44
|
readonly inspect?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Fonts the exported editor ships and loads, in the page and in the engine
|
|
47
|
+
* worker, so a panel or a canvas that names the family draws with it rather
|
|
48
|
+
* than the system fallback. Open-licensed only: each one states its licence
|
|
49
|
+
* (`OFL-1.1`), and a file under `licensed/` is refused like any other asset.
|
|
50
|
+
*/
|
|
51
|
+
readonly fonts?: readonly EditorFont[];
|
|
45
52
|
/**
|
|
46
53
|
* Parameter ids a phone keeps in reach at the bottom sheet's lowest snap
|
|
47
54
|
* point (the text, a Reroll). Defaults to the first text and seed parameters.
|
|
@@ -54,6 +61,16 @@ export interface EditorDeclaration {
|
|
|
54
61
|
*/
|
|
55
62
|
readonly draft?: Readonly<Record<string, JsonValue>>;
|
|
56
63
|
}
|
|
64
|
+
export interface EditorFont {
|
|
65
|
+
/** The CSS family name the project's code uses (`DM Mono`). */
|
|
66
|
+
readonly family: string;
|
|
67
|
+
/** Project-relative font file: `.woff2`, `.woff`, `.ttf` or `.otf`. */
|
|
68
|
+
readonly file: string;
|
|
69
|
+
/** SIL Open Font License. Anything else is refused at export. */
|
|
70
|
+
readonly license: "OFL-1.1";
|
|
71
|
+
readonly weight?: string | number;
|
|
72
|
+
readonly style?: "normal" | "italic";
|
|
73
|
+
}
|
|
57
74
|
export type PublishedControl = "number" | "slider" | "int" | "bool" | "select" | "text" | "textarea" | "color" | "file" | "seed" | "vec2";
|
|
58
75
|
export interface PublishedParameter {
|
|
59
76
|
/** Scene key. Stable across renames of the node or the prop it targets. */
|
|
@@ -5,6 +5,7 @@ export * from "./capabilities.js";
|
|
|
5
5
|
export * from "./color.js";
|
|
6
6
|
export * from "./definition.js";
|
|
7
7
|
export * from "./document.js";
|
|
8
|
+
export * from "./documentFormat.js";
|
|
8
9
|
export * from "./editor.js";
|
|
9
10
|
export * from "./geometry.js";
|
|
10
11
|
export * from "./particles.js";
|
package/dist/contracts/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./capabilities.js";
|
|
|
5
5
|
export * from "./color.js";
|
|
6
6
|
export * from "./definition.js";
|
|
7
7
|
export * from "./document.js";
|
|
8
|
+
export * from "./documentFormat.js";
|
|
8
9
|
export * from "./editor.js";
|
|
9
10
|
export * from "./geometry.js";
|
|
10
11
|
export * from "./particles.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const nodeDefinitionSchema: {
|
|
2
|
-
readonly allOf: readonly [Readonly<Record<string, unknown>>, Readonly<Record<string, unknown>>, Readonly<Record<string, unknown>>];
|
|
3
2
|
readonly $schema: "https://json-schema.org/draft/2020-12/schema";
|
|
4
3
|
readonly $id: "https://cascade.dev/schema/node-definition-v1.json";
|
|
4
|
+
readonly allOf: readonly [Readonly<Record<string, unknown>>, Readonly<Record<string, unknown>>, Readonly<Record<string, unknown>>];
|
|
5
5
|
};
|
|
6
6
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/contracts/schema.js
CHANGED
|
@@ -19,7 +19,7 @@ export const CAPABILITIES_BY_ENVIRONMENT = {
|
|
|
19
19
|
};
|
|
20
20
|
const ALLOWED = CAPABILITIES_BY_ENVIRONMENT;
|
|
21
21
|
const fields = (names) => new Set(names.split(" "));
|
|
22
|
-
const TOP_FIELDS = fields("apiVersion runsOn container capabilities source label description icon inputs outputs props");
|
|
22
|
+
const TOP_FIELDS = fields("apiVersion runsOn container capabilities gpuLimits source label description icon inputs outputs props");
|
|
23
23
|
const DATA_FIELDS = fields("kind type default description variadic min max step accept control options schema fields");
|
|
24
24
|
const OUTPUT_FIELDS = fields("kind type description schema fields");
|
|
25
25
|
const PROP_FIELDS = fields("type default label description min max step accept control options expression action");
|
|
@@ -111,6 +111,16 @@ export function validateNodeDefinition(value) {
|
|
|
111
111
|
add("duplicate-capability", `${String(capability)} is duplicated`, path);
|
|
112
112
|
seen.add(capability);
|
|
113
113
|
}
|
|
114
|
+
if (value.gpuLimits !== undefined) {
|
|
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
|
// Two namespaces, not one. An output is addressed in the other direction from
|
|
115
125
|
// an input, so `geometry` in and `geometry` out is not ambiguous anywhere: the
|
|
116
126
|
// document format names the two endpoints of a connection separately, the
|
|
@@ -51,6 +51,18 @@ export type Mat4 = readonly [
|
|
|
51
51
|
number,
|
|
52
52
|
number
|
|
53
53
|
];
|
|
54
|
+
/**
|
|
55
|
+
* The value on an `image` port: a path naming stored pixels, plus what they
|
|
56
|
+
* are. The port carries the reference, never the pixels, so a value stays
|
|
57
|
+
* small to snapshot, hash, trace and send to a Python stage.
|
|
58
|
+
*
|
|
59
|
+
* The path is always readable as a file by whoever needs a file. A host may
|
|
60
|
+
* still hold the pixels in memory and write the file behind (see
|
|
61
|
+
* {@link ImagePixels} and `AssetCapability.keepImage`): a reader in the same
|
|
62
|
+
* process gets the pixels without a decode, and the host makes the file whole
|
|
63
|
+
* before anything reads it from disk (a final copy, a Python stage, the end of
|
|
64
|
+
* a run).
|
|
65
|
+
*/
|
|
54
66
|
export interface ImageRef {
|
|
55
67
|
readonly path: string;
|
|
56
68
|
readonly size: Vec2i;
|
|
@@ -58,6 +70,18 @@ export interface ImageRef {
|
|
|
58
70
|
readonly depth: "u8" | "u16" | "f16" | "f32";
|
|
59
71
|
readonly space: "srgb" | "linear";
|
|
60
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* An image's pixels in memory: 8-bit RGBA, sRGB, unpremultiplied, row-major
|
|
75
|
+
* with the top row first. This is the layout of `ImageData` and of a PNG's
|
|
76
|
+
* decoded rows, so handing pixels on in memory and handing them on through a
|
|
77
|
+
* PNG give the next node the same numbers.
|
|
78
|
+
*/
|
|
79
|
+
export interface ImagePixels {
|
|
80
|
+
readonly width: number;
|
|
81
|
+
readonly height: number;
|
|
82
|
+
/** `width * height * 4` bytes. Owned by the host once kept: never mutate. */
|
|
83
|
+
readonly data: Uint8ClampedArray;
|
|
84
|
+
}
|
|
61
85
|
declare const textureHandleBrand: unique symbol;
|
|
62
86
|
export interface TextureHandle {
|
|
63
87
|
readonly [textureHandleBrand]: true;
|