@field/cascade 0.7.1 → 0.10.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 +17 -1
- package/CHANGELOG.md +260 -0
- package/DESIGN.md +14 -0
- package/README.md +41 -25
- package/dist/assets/CodeEditor-DSZBpzdy.js +623 -0
- package/dist/assets/CodePanel-sY6sZa7B.js +2 -0
- package/dist/assets/CustomNodeDialog-BRKnqZhp.js +1 -0
- package/dist/assets/{ExportDialog-BJu2Bpvv.js → ExportDialog-C7dVGua4.js} +2 -2
- package/dist/assets/OpenGraphDialog-ZsgL-iwr.js +1 -0
- package/dist/assets/ProjectSettings-Cw17nNe3.js +2 -0
- package/dist/assets/SettingsDialog-p25h3tj0.js +1 -0
- package/dist/assets/VersionHistoryDialog-DzFLUotB.js +3 -0
- package/dist/assets/{core-DlkL34JF.js → core-BICrEt0y.js} +8 -8
- package/dist/assets/{cssMode-DaSSFZYi.js → cssMode-D7TXw57I.js} +1 -1
- package/dist/assets/definitions-DUww2Rt-.js +1 -0
- package/dist/assets/{editor.api-CHUMRaMm.js → editor.api-DvkCO3ko.js} +1 -1
- package/dist/assets/{freemarker2-DQ604q2A.js → freemarker2-BA2lxsF1.js} +1 -1
- package/dist/assets/geo-C2RHOVHC.js +1 -0
- package/dist/assets/{handlebars-09pcWz8x.js → handlebars-BcDiyPd8.js} +1 -1
- package/dist/assets/{html-DtIKrZiD.js → html-C7O4TyhX.js} +1 -1
- package/dist/assets/{htmlMode-DgJ_4m1_.js → htmlMode-WaDGF3Mj.js} +1 -1
- package/dist/assets/{image-CtUE4_I-.js → image-DR4oeyJB.js} +3 -3
- package/dist/assets/index-7vae6YFC.css +1 -0
- package/dist/assets/index-DyvDC6pS.js +219 -0
- package/dist/assets/index-client-DqYmKstU.js +1 -0
- package/dist/assets/{javascript-kbIBYYGo.js → javascript-CpIEK7tz.js} +1 -1
- package/dist/assets/{jsonMode-DblCG64t.js → jsonMode-B2FltW0f.js} +1 -1
- package/dist/assets/legacy-CTEeXeqF.js +2 -0
- package/dist/assets/{liquid-D-qdTGhQ.js → liquid-CN6FFHZE.js} +1 -1
- package/dist/assets/{lspLanguageFeatures-Bc6azcFQ.js → lspLanguageFeatures-QhV9XtLp.js} +1 -1
- package/dist/assets/math-DaDEgWKt.js +1 -0
- package/dist/assets/{mdx-TXg4xsyD.js → mdx-DE89pafV.js} +1 -1
- package/dist/assets/pop-pLH7L0PW.js +1 -0
- package/dist/assets/{python-C4SGyXJW.js → python-ByTllTB9.js} +1 -1
- package/dist/assets/{razor-BZ-lEgY9.js → razor-USYlRRCE.js} +1 -1
- package/dist/assets/studioScenes-8sq9FfFg.js +1 -0
- package/dist/assets/{tsMode-BoaO1D7x.js → tsMode-BXpN8iUz.js} +1 -1
- package/dist/assets/{typescript-D87dYk9k.js → typescript-DInBjGQQ.js} +1 -1
- package/dist/assets/{workers-ZrST7klJ.js → workers-C7Ye5B7D.js} +1 -1
- package/dist/assets/{xml-DT6r4F7G.js → xml-U0Uocqyo.js} +1 -1
- package/dist/assets/{yaml-DxmQ8XYb.js → yaml-CBw_PVYf.js} +1 -1
- package/dist/cli/index.js +20070 -3487
- package/dist/cli/runtime/stage.ts +70 -10
- package/dist/contracts/bundle.d.ts +75 -0
- package/dist/contracts/bundle.js +112 -0
- package/dist/contracts/definition.d.ts +67 -4
- package/dist/contracts/document.d.ts +29 -0
- package/dist/contracts/editor.d.ts +172 -0
- package/dist/contracts/editor.js +2 -0
- package/dist/contracts/index.d.ts +2 -0
- package/dist/contracts/index.js +2 -0
- package/dist/contracts/validate.js +59 -3
- package/dist/contracts/values.d.ts +3 -3
- package/dist/contracts/values.js +1 -0
- package/dist/index.html +6 -4
- package/dist/player/app.js +17 -5
- package/dist/player/editor.js +1894 -0
- package/dist/player/editorEngine.js +477 -0
- package/dist/runtime/builtins/core/bundle.d.ts +70 -0
- package/dist/runtime/builtins/core/bundle.js +81 -0
- package/dist/runtime/builtins/core/index.d.ts +3 -2
- package/dist/runtime/builtins/core/index.js +6 -2
- package/dist/runtime/builtins/core/routing.d.ts +27 -0
- package/dist/runtime/builtins/core/routing.js +28 -0
- package/dist/runtime/edit/document.d.ts +94 -0
- package/dist/runtime/edit/document.js +194 -0
- package/dist/runtime/edit/graphEditor.d.ts +223 -0
- package/dist/runtime/edit/graphEditor.js +893 -0
- package/dist/runtime/edit/index.d.ts +12 -0
- package/dist/runtime/edit/index.js +6 -0
- package/dist/runtime/edit/layout.d.ts +50 -0
- package/dist/runtime/edit/layout.js +126 -0
- package/dist/runtime/edit/operations.d.ts +65 -0
- package/dist/runtime/edit/operations.js +57 -0
- package/dist/runtime/edit/parameters.d.ts +75 -0
- package/dist/runtime/edit/parameters.js +284 -0
- package/dist/runtime/edit/read.d.ts +35 -0
- package/dist/runtime/edit/read.js +65 -0
- package/dist/runtime/editor/index.d.ts +104 -0
- package/dist/runtime/editor/index.js +439 -0
- package/dist/runtime/expressions/bundlePaths.d.ts +37 -0
- package/dist/runtime/expressions/bundlePaths.js +55 -0
- package/dist/runtime/expressions/index.d.ts +2 -0
- package/dist/runtime/expressions/index.js +1 -0
- package/dist/runtime/index.d.ts +2 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/params/animator.d.ts +5 -0
- package/dist/runtime/params/animator.js +16 -0
- package/dist/runtime/runtime.js +238 -12
- package/dist/runtime/seed.d.ts +29 -0
- package/dist/runtime/seed.js +52 -0
- package/dist/runtime/types.d.ts +12 -0
- package/dist/stage.js +40 -9
- package/dist/studio/panel.d.ts +2 -0
- package/doc/CLI_REFERENCE.md +100 -0
- package/doc/EDITOR_EXPORT.md +226 -0
- package/doc/HEADLESS_GPU.md +27 -0
- package/doc/MCP.md +53 -0
- package/doc/NODE_REFERENCE.md +66 -0
- package/doc/PROJECT_AUTHORING.md +137 -0
- package/package.json +15 -6
- package/dist/assets/CodeEditor-D-N0C2jT.js +0 -623
- package/dist/assets/CodePanel-EN411mp5.js +0 -2
- package/dist/assets/CustomNodeDialog-6z2n27VV.js +0 -1
- package/dist/assets/OpenGraphDialog-fMZjzIR3.js +0 -1
- package/dist/assets/ProjectSettings-BQ8PGNqo.js +0 -2
- package/dist/assets/SettingsDialog-IbYLm8Bx.js +0 -1
- package/dist/assets/VersionHistoryDialog-Bgh-q5Jg.js +0 -3
- package/dist/assets/definitions-CQBdsJYJ.js +0 -1
- package/dist/assets/geo-DcmMAcqM.js +0 -1
- package/dist/assets/index-CnylT98t.js +0 -212
- package/dist/assets/index-client-BoJgsN9M.js +0 -1
- package/dist/assets/index-ilgbOu6G.css +0 -1
- package/dist/assets/legacy-CAj2_7QE.js +0 -2
- package/dist/assets/math-CY11tkoN.js +0 -1
- package/dist/assets/pop-Dr5-ARqQ.js +0 -1
- package/dist/assets/projectSettingsApi-C1WvIwfP.js +0 -1
|
@@ -17,12 +17,52 @@
|
|
|
17
17
|
* carries a project-relative path, never pixels.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
export interface StageCallOptions {
|
|
21
|
+
/**
|
|
22
|
+
* Abandons the stage. In Studio the request is withdrawn — dropped if it is
|
|
23
|
+
* still queued for the worker, interrupted if it is running — and the call
|
|
24
|
+
* rejects at once, so a superseded cook stops costing anything the moment it
|
|
25
|
+
* is superseded rather than when the stage happens to finish.
|
|
26
|
+
*
|
|
27
|
+
* Optional: when it is absent the signal of the cook in flight is used (see
|
|
28
|
+
* `COOK_SIGNAL_KEY`), so a node that never heard of this still cancels.
|
|
29
|
+
*/
|
|
30
|
+
readonly signal?: AbortSignal;
|
|
31
|
+
}
|
|
32
|
+
|
|
20
33
|
export interface StageBridge {
|
|
21
|
-
(stage: string, args: Record<string, unknown
|
|
34
|
+
(stage: string, args: Record<string, unknown>, options?: StageCallOptions): Promise<unknown>;
|
|
22
35
|
}
|
|
23
36
|
|
|
24
37
|
const BRIDGE_KEY = '__cascadeStageBridge';
|
|
25
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Where the scheduler publishes the signal of the interactive cook in flight.
|
|
41
|
+
*
|
|
42
|
+
* On `globalThis` for the same reason as the bridge: every project module is
|
|
43
|
+
* compiled with its own copy of this file, so module state would not be shared
|
|
44
|
+
* with the scheduler that sets it. The interactive lane runs one node at a
|
|
45
|
+
* time, which is what makes a single ambient value correct: a stage started
|
|
46
|
+
* while node N cooks belongs to node N's cook. Read at call time, never later.
|
|
47
|
+
*/
|
|
48
|
+
export const COOK_SIGNAL_KEY = '__cascadeCookSignal';
|
|
49
|
+
|
|
50
|
+
function ambientCookSignal(): AbortSignal | undefined {
|
|
51
|
+
const read = (globalThis as Record<string, unknown>)[COOK_SIGNAL_KEY];
|
|
52
|
+
if (typeof read !== 'function') return undefined;
|
|
53
|
+
const signal = (read as () => AbortSignal | null | undefined)();
|
|
54
|
+
return signal ?? undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The rejection a withdrawn stage produces, recognisable without importing a
|
|
58
|
+
* class across module copies. */
|
|
59
|
+
function cancelledError(stage: string, signal: AbortSignal): Error {
|
|
60
|
+
const reason = signal.reason instanceof Error ? signal.reason.message : 'superseded';
|
|
61
|
+
const error = new Error(`stage "${stage}" was cancelled: ${reason}`);
|
|
62
|
+
error.name = 'AbortError';
|
|
63
|
+
return error;
|
|
64
|
+
}
|
|
65
|
+
|
|
26
66
|
/**
|
|
27
67
|
* Install the local transport. Called by a host that can reach the filesystem —
|
|
28
68
|
* the CLI does this before running a graph. Returns a disposer so a host can
|
|
@@ -71,20 +111,27 @@ async function capability(): Promise<string> {
|
|
|
71
111
|
return token;
|
|
72
112
|
}
|
|
73
113
|
|
|
74
|
-
async function overHttp<T>(stage: string, args: Record<string, unknown
|
|
114
|
+
async function overHttp<T>(stage: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<T> {
|
|
75
115
|
const postStage = async () => fetch('/api/exec', {
|
|
76
116
|
method: 'POST',
|
|
77
117
|
headers: { 'Content-Type': 'application/json', 'X-Cascade-Exec-Capability': await capability() },
|
|
78
118
|
body: JSON.stringify({ stage, args }),
|
|
119
|
+
signal,
|
|
79
120
|
});
|
|
80
121
|
|
|
81
|
-
let response
|
|
82
|
-
|
|
83
|
-
|
|
122
|
+
let response: Response;
|
|
123
|
+
let body: { ok?: boolean; stdout?: string; stderr?: string; error?: string };
|
|
124
|
+
try {
|
|
84
125
|
response = await postStage();
|
|
126
|
+
if (response.status === 403) {
|
|
127
|
+
capabilityPromise = undefined;
|
|
128
|
+
response = await postStage();
|
|
129
|
+
}
|
|
130
|
+
body = await response.json() as typeof body;
|
|
131
|
+
} catch (error) {
|
|
132
|
+
if (signal?.aborted) throw cancelledError(stage, signal);
|
|
133
|
+
throw error;
|
|
85
134
|
}
|
|
86
|
-
|
|
87
|
-
const body = await response.json() as { ok?: boolean; stdout?: string; stderr?: string; error?: string };
|
|
88
135
|
if (!response.ok || !body.ok) {
|
|
89
136
|
throw new Error(`stage "${stage}" failed: ${body.stderr || body.error || 'unknown error'}`);
|
|
90
137
|
}
|
|
@@ -113,16 +160,29 @@ export async function stageAvailable(): Promise<boolean> {
|
|
|
113
160
|
* rather than a URL parse error from a fetch that was never going to work —
|
|
114
161
|
* which is what this whole file exists to stop happening.
|
|
115
162
|
*/
|
|
116
|
-
export async function runStage<T = unknown>(
|
|
163
|
+
export async function runStage<T = unknown>(
|
|
164
|
+
stage: string,
|
|
165
|
+
args: Record<string, unknown> = {},
|
|
166
|
+
options: StageCallOptions = {},
|
|
167
|
+
): Promise<T> {
|
|
168
|
+
const signal = options.signal ?? ambientCookSignal();
|
|
169
|
+
if (signal?.aborted) throw cancelledError(stage, signal);
|
|
117
170
|
const bridge = localBridge();
|
|
118
|
-
if (bridge)
|
|
171
|
+
if (bridge) {
|
|
172
|
+
try {
|
|
173
|
+
return await bridge(stage, args, signal ? { signal } : undefined) as T;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
if (signal?.aborted) throw cancelledError(stage, signal);
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
119
179
|
if (typeof document === 'undefined') {
|
|
120
180
|
throw new Error(
|
|
121
181
|
`Cannot run stage "${stage}": no host bridge is installed and there is no page to post from. ` +
|
|
122
182
|
'A headless host must call installStageBridge() from cascade/stage before executing the graph.',
|
|
123
183
|
);
|
|
124
184
|
}
|
|
125
|
-
return overHttp<T>(stage, args);
|
|
185
|
+
return overHttp<T>(stage, args, signal);
|
|
126
186
|
}
|
|
127
187
|
|
|
128
188
|
/** A scratch path for a node's output, scoped by node id so re-running a graph
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundles: one port carrying a set of named fields.
|
|
3
|
+
*
|
|
4
|
+
* Marcus, 2026-10-10, looking at a graph where one node fanned out a dozen
|
|
5
|
+
* outputs wired everywhere: *"Instead of having these nodes with many different
|
|
6
|
+
* outputs (more than 3 or 4 outputs), can we just export some kind of JSON
|
|
7
|
+
* object, a sort of multi-object, instead of outputting 12 different outputs?"*
|
|
8
|
+
*
|
|
9
|
+
* A bundle value is a plain object of fields. Each field is any ordinary
|
|
10
|
+
* Cascade value; an image or a cache entry travels as its reference (an
|
|
11
|
+
* `ImageRef`, an `AssetRef`), never as pixels, so a bundle is as cheap to pass
|
|
12
|
+
* as the fields it names.
|
|
13
|
+
*
|
|
14
|
+
* What makes it more than `object`:
|
|
15
|
+
*
|
|
16
|
+
* - a producer declares its fields (`fields: { dpi: "float", ... }`), so a
|
|
17
|
+
* checker can name an unknown field and suggest the right one;
|
|
18
|
+
* - an optional `schema` name (`format`, `signals`, `marks`) keeps two
|
|
19
|
+
* unrelated bundles from being wired together;
|
|
20
|
+
* - a consumer may declare the fields it reads (`fields: ["dpi"]`). It then
|
|
21
|
+
* sees only those, and Studio re-cooks it only when one of them changed;
|
|
22
|
+
* - expressions read a wired bundle's fields: `ch("format.dpi")`.
|
|
23
|
+
*
|
|
24
|
+
* Everything here is pure and dependency-free so the runtime, Studio and the
|
|
25
|
+
* CLI checker share one reading of the rules.
|
|
26
|
+
*/
|
|
27
|
+
import type { CascadeType } from "./values.js";
|
|
28
|
+
/** A declared field: its type, or its type with words for whoever reads it. */
|
|
29
|
+
export type BundleFieldDefinition = CascadeType | Readonly<{
|
|
30
|
+
type: CascadeType;
|
|
31
|
+
description?: string;
|
|
32
|
+
}>;
|
|
33
|
+
/** A producer's declaration: field name to type. */
|
|
34
|
+
export type BundleFieldDefinitions = Readonly<Record<string, BundleFieldDefinition>>;
|
|
35
|
+
export type Bundle = Readonly<Record<string, unknown>>;
|
|
36
|
+
/** The type a field declaration names. */
|
|
37
|
+
export declare function bundleFieldType(definition: BundleFieldDefinition | undefined): string;
|
|
38
|
+
/** The description a field declaration carries, if any. */
|
|
39
|
+
export declare function bundleFieldDescription(definition: BundleFieldDefinition | undefined): string | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Whether two bundle ports may be wired. A port without a schema is generic and
|
|
42
|
+
* takes any bundle; two named schemas must agree.
|
|
43
|
+
*/
|
|
44
|
+
export declare function bundleSchemasCompatible(output: string | undefined, input: string | undefined): boolean;
|
|
45
|
+
/** True for a value a bundle port can carry: a plain, non-array object. */
|
|
46
|
+
export declare function isBundleValue(value: unknown): value is Bundle;
|
|
47
|
+
/**
|
|
48
|
+
* A field path as an expression writes it: `format.dpi` is field `dpi` of the
|
|
49
|
+
* port `format`. Only the first dot splits, so a field name never needs
|
|
50
|
+
* escaping. Null when there is no dot to split on.
|
|
51
|
+
*/
|
|
52
|
+
export declare function splitBundlePath(name: string): {
|
|
53
|
+
port: string;
|
|
54
|
+
field: string;
|
|
55
|
+
} | null;
|
|
56
|
+
/**
|
|
57
|
+
* A bundle narrowed to the fields a consumer declared. A field the producer
|
|
58
|
+
* did not set is absent rather than `undefined`, the same as on the full value.
|
|
59
|
+
*/
|
|
60
|
+
export declare function selectBundleFields(value: unknown, fields: readonly string[]): Bundle | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* The closest candidate to a misspelt name, for "did you mean". Edit distance
|
|
63
|
+
* with a threshold that scales with the length, so `dpu` finds `dpi` and
|
|
64
|
+
* `colour` does not find `count`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function suggestName(name: string, candidates: Iterable<string>): string | undefined;
|
|
67
|
+
/** "unknown field X — did you mean Y? (fields: a, b, c)" */
|
|
68
|
+
export declare function unknownFieldMessage(field: string, known: readonly string[], where: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* What is wrong with a value a producer committed to a bundle port, or null.
|
|
71
|
+
* With declared fields, every key must be declared; a declared field may be
|
|
72
|
+
* absent. Field types are not checked here; the runtime does that per type.
|
|
73
|
+
*/
|
|
74
|
+
export declare function bundleValueProblem(value: unknown, fields: BundleFieldDefinitions | undefined): string | null;
|
|
75
|
+
//# sourceMappingURL=bundle.d.ts.map
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/** The type a field declaration names. */
|
|
2
|
+
export function bundleFieldType(definition) {
|
|
3
|
+
if (!definition)
|
|
4
|
+
return "any";
|
|
5
|
+
return typeof definition === "string" ? definition : definition.type;
|
|
6
|
+
}
|
|
7
|
+
/** The description a field declaration carries, if any. */
|
|
8
|
+
export function bundleFieldDescription(definition) {
|
|
9
|
+
return typeof definition === "object" && definition ? definition.description : undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Whether two bundle ports may be wired. A port without a schema is generic and
|
|
13
|
+
* takes any bundle; two named schemas must agree.
|
|
14
|
+
*/
|
|
15
|
+
export function bundleSchemasCompatible(output, input) {
|
|
16
|
+
return !output || !input || output === input;
|
|
17
|
+
}
|
|
18
|
+
/** True for a value a bundle port can carry: a plain, non-array object. */
|
|
19
|
+
export function isBundleValue(value) {
|
|
20
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
21
|
+
return false;
|
|
22
|
+
const prototype = Object.getPrototypeOf(value);
|
|
23
|
+
return prototype === Object.prototype || prototype === null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A field path as an expression writes it: `format.dpi` is field `dpi` of the
|
|
27
|
+
* port `format`. Only the first dot splits, so a field name never needs
|
|
28
|
+
* escaping. Null when there is no dot to split on.
|
|
29
|
+
*/
|
|
30
|
+
export function splitBundlePath(name) {
|
|
31
|
+
const dot = name.indexOf(".");
|
|
32
|
+
if (dot <= 0 || dot === name.length - 1)
|
|
33
|
+
return null;
|
|
34
|
+
return { port: name.slice(0, dot), field: name.slice(dot + 1) };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A bundle narrowed to the fields a consumer declared. A field the producer
|
|
38
|
+
* did not set is absent rather than `undefined`, the same as on the full value.
|
|
39
|
+
*/
|
|
40
|
+
export function selectBundleFields(value, fields) {
|
|
41
|
+
if (!isBundleValue(value))
|
|
42
|
+
return value;
|
|
43
|
+
const selected = {};
|
|
44
|
+
for (const field of fields)
|
|
45
|
+
if (Object.prototype.hasOwnProperty.call(value, field))
|
|
46
|
+
selected[field] = value[field];
|
|
47
|
+
return Object.freeze(selected);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The closest candidate to a misspelt name, for "did you mean". Edit distance
|
|
51
|
+
* with a threshold that scales with the length, so `dpu` finds `dpi` and
|
|
52
|
+
* `colour` does not find `count`.
|
|
53
|
+
*/
|
|
54
|
+
export function suggestName(name, candidates) {
|
|
55
|
+
let best;
|
|
56
|
+
let bestDistance = Infinity;
|
|
57
|
+
const lower = name.toLowerCase();
|
|
58
|
+
for (const candidate of candidates) {
|
|
59
|
+
const distance = editDistance(lower, candidate.toLowerCase());
|
|
60
|
+
if (distance < bestDistance) {
|
|
61
|
+
best = candidate;
|
|
62
|
+
bestDistance = distance;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (best === undefined)
|
|
66
|
+
return undefined;
|
|
67
|
+
const limit = Math.max(1, Math.floor(Math.max(name.length, best.length) / 3));
|
|
68
|
+
return bestDistance <= limit ? best : undefined;
|
|
69
|
+
}
|
|
70
|
+
/** "unknown field X — did you mean Y? (fields: a, b, c)" */
|
|
71
|
+
export function unknownFieldMessage(field, known, where) {
|
|
72
|
+
const suggestion = suggestName(field, known);
|
|
73
|
+
return `${where} reads unknown bundle field "${field}"`
|
|
74
|
+
+ (suggestion ? ` — did you mean "${suggestion}"?` : "")
|
|
75
|
+
+ (known.length ? ` (fields: ${known.join(", ")})` : " (the bundle declares no fields)");
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* What is wrong with a value a producer committed to a bundle port, or null.
|
|
79
|
+
* With declared fields, every key must be declared; a declared field may be
|
|
80
|
+
* absent. Field types are not checked here; the runtime does that per type.
|
|
81
|
+
*/
|
|
82
|
+
export function bundleValueProblem(value, fields) {
|
|
83
|
+
if (value === undefined || value === null)
|
|
84
|
+
return null;
|
|
85
|
+
if (!isBundleValue(value))
|
|
86
|
+
return "a bundle must be a plain object of fields";
|
|
87
|
+
if (!fields)
|
|
88
|
+
return null;
|
|
89
|
+
const known = Object.keys(fields);
|
|
90
|
+
for (const key of Object.keys(value))
|
|
91
|
+
if (!Object.prototype.hasOwnProperty.call(fields, key)) {
|
|
92
|
+
const suggestion = suggestName(key, known);
|
|
93
|
+
return `sets undeclared bundle field "${key}"`
|
|
94
|
+
+ (suggestion ? ` — did you mean "${suggestion}"?` : "")
|
|
95
|
+
+ ` (declared: ${known.join(", ") || "none"})`;
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
function editDistance(a, b) {
|
|
100
|
+
const previous = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
101
|
+
for (let i = 1; i <= a.length; i++) {
|
|
102
|
+
let diagonal = previous[0];
|
|
103
|
+
previous[0] = i;
|
|
104
|
+
for (let j = 1; j <= b.length; j++) {
|
|
105
|
+
const above = previous[j];
|
|
106
|
+
previous[j] = Math.min(previous[j] + 1, previous[j - 1] + 1, diagonal + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
107
|
+
diagonal = above;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return previous[b.length];
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CapabilityMap, CascadeAbortSignal, NodeCapabilityName, ProgressReporter } from "./capabilities.js";
|
|
2
|
+
import type { BundleFieldDefinition, BundleFieldDefinitions } from "./bundle.js";
|
|
2
3
|
import type { CascadeType, CoreType, JsonValue, NamespacedType, SerializableValueForType, ValueForType } from "./values.js";
|
|
3
4
|
export type RuntimeEnvironment = "portable" | "browser" | "server";
|
|
4
5
|
export type CapabilityForEnvironment<E extends RuntimeEnvironment> = E extends "portable" ? "assets" | "media" | "gpu" : E extends "browser" ? "assets" | "media" | "gpu" : "files" | "assets" | "media" | "python" | "shell" | "gpu";
|
|
@@ -70,6 +71,27 @@ type SelectMetadata<T extends CascadeType> = {
|
|
|
70
71
|
readonly control: Extract<ControlFor<T>, "select">;
|
|
71
72
|
readonly options?: readonly SelectOption<T>[];
|
|
72
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Bundle ports name an optional `schema`, and declare fields from both ends:
|
|
76
|
+
* a producer declares what it carries (`fields: { dpi: "float" }`), a consumer
|
|
77
|
+
* the fields it reads (`fields: ["dpi"]`). A consumer that declares its fields
|
|
78
|
+
* sees only those and, in Studio, re-cooks only when one of them changed. See
|
|
79
|
+
* `bundle.ts`.
|
|
80
|
+
*/
|
|
81
|
+
type BundleInputMetadata<T extends CascadeType> = T extends "bundle" ? {
|
|
82
|
+
readonly schema?: string;
|
|
83
|
+
readonly fields?: readonly string[];
|
|
84
|
+
} : {
|
|
85
|
+
readonly schema?: never;
|
|
86
|
+
readonly fields?: never;
|
|
87
|
+
};
|
|
88
|
+
type BundleOutputMetadata<T extends CascadeType> = T extends "bundle" ? {
|
|
89
|
+
readonly schema?: string;
|
|
90
|
+
readonly fields?: BundleFieldDefinitions;
|
|
91
|
+
} : {
|
|
92
|
+
readonly schema?: never;
|
|
93
|
+
readonly fields?: never;
|
|
94
|
+
};
|
|
73
95
|
export interface TriggerInputDefinition {
|
|
74
96
|
readonly kind: "trigger";
|
|
75
97
|
readonly description?: string;
|
|
@@ -80,7 +102,7 @@ export type DataInputDefinition<T extends CascadeType> = {
|
|
|
80
102
|
readonly default?: SerializableValueForType<T>;
|
|
81
103
|
readonly description?: string;
|
|
82
104
|
readonly variadic?: boolean;
|
|
83
|
-
} & NumericMetadata<T> & AcceptMetadata<T> & SelectMetadata<T>;
|
|
105
|
+
} & NumericMetadata<T> & AcceptMetadata<T> & SelectMetadata<T> & BundleInputMetadata<T>;
|
|
84
106
|
export type InputDefinitionFor<E extends RuntimeEnvironment> = TriggerInputDefinition | {
|
|
85
107
|
[T in DataTypeForEnvironment<E>]: DataInputDefinition<T>;
|
|
86
108
|
}[DataTypeForEnvironment<E>];
|
|
@@ -88,11 +110,11 @@ export interface TriggerOutputDefinition {
|
|
|
88
110
|
readonly kind: "trigger";
|
|
89
111
|
readonly description?: string;
|
|
90
112
|
}
|
|
91
|
-
export
|
|
113
|
+
export type DataOutputDefinition<T extends CascadeType> = {
|
|
92
114
|
readonly kind: "data";
|
|
93
115
|
readonly type: T;
|
|
94
116
|
readonly description?: string;
|
|
95
|
-
}
|
|
117
|
+
} & BundleOutputMetadata<T>;
|
|
96
118
|
export type OutputDefinitionFor<E extends RuntimeEnvironment> = TriggerOutputDefinition | {
|
|
97
119
|
[T in DataTypeForEnvironment<E>]: DataOutputDefinition<T>;
|
|
98
120
|
}[DataTypeForEnvironment<E>];
|
|
@@ -168,6 +190,14 @@ export interface NodeDefinitionForEnvironment<E extends RuntimeEnvironment> {
|
|
|
168
190
|
*/
|
|
169
191
|
readonly container?: "subnet" | "feedback";
|
|
170
192
|
readonly capabilities?: readonly CapabilityForEnvironment<E>[];
|
|
193
|
+
/**
|
|
194
|
+
* `live` marks a node that reads data from outside the graph — an archive,
|
|
195
|
+
* a CLI, a cache, body data, the filesystem or a network. `cascade export`
|
|
196
|
+
* never ships one: the author freezes it into a snapshot of chosen values or
|
|
197
|
+
* the export fails. Server nodes and nodes declaring `files`, `python` or
|
|
198
|
+
* `shell` are treated as live whether or not they say so.
|
|
199
|
+
*/
|
|
200
|
+
readonly source?: "live";
|
|
171
201
|
readonly label?: string;
|
|
172
202
|
readonly description?: string;
|
|
173
203
|
readonly icon?: string;
|
|
@@ -191,11 +221,32 @@ export interface TriggerEvent {
|
|
|
191
221
|
}>;
|
|
192
222
|
}
|
|
193
223
|
type Entries<D, K extends "inputs" | "outputs" | "props"> = D extends Record<K, infer R> ? R : Record<never, never>;
|
|
194
|
-
|
|
224
|
+
/** The value a declared bundle field holds. */
|
|
225
|
+
type BundleFieldValue<F> = F extends CascadeType ? ValueForType<F> : F extends {
|
|
226
|
+
readonly type: infer T extends CascadeType;
|
|
227
|
+
} ? ValueForType<T> : unknown;
|
|
228
|
+
/** A bundle output's value, typed from its declared fields. Every field is
|
|
229
|
+
* optional: a producer may leave one unset, and a consumer then reads none. */
|
|
230
|
+
type BundleOutputValue<O> = O extends {
|
|
231
|
+
readonly fields: infer F extends Readonly<Record<string, BundleFieldDefinition>>;
|
|
232
|
+
} ? {
|
|
233
|
+
readonly [K in keyof F]?: BundleFieldValue<F[K]>;
|
|
234
|
+
} : Readonly<Record<string, unknown>>;
|
|
235
|
+
/** A bundle input's value: only the declared fields, when it declares any. */
|
|
236
|
+
type BundleInputValue<I> = I extends {
|
|
237
|
+
readonly fields: readonly (infer K extends string)[];
|
|
238
|
+
} ? {
|
|
239
|
+
readonly [P in K]?: unknown;
|
|
240
|
+
} : Readonly<Record<string, unknown>>;
|
|
241
|
+
type InputValue<I> = I extends TriggerInputDefinition ? TriggerEvent | undefined : I extends DataInputDefinition<"bundle"> ? I extends {
|
|
242
|
+
readonly default: unknown;
|
|
243
|
+
} ? BundleInputValue<I> : BundleInputValue<I> | undefined : I extends DataInputDefinition<infer T> ? I extends {
|
|
195
244
|
readonly variadic: true;
|
|
196
245
|
} ? readonly ValueForType<T>[] : "default" extends keyof I ? ValueForType<T> : ValueForType<T> | undefined : never;
|
|
197
246
|
type OutputValue<O> = O extends TriggerOutputDefinition ? {
|
|
198
247
|
trigger(payload?: JsonValue): void;
|
|
248
|
+
} : O extends DataOutputDefinition<"bundle"> ? {
|
|
249
|
+
set(value: BundleOutputValue<O>): void;
|
|
199
250
|
} : O extends DataOutputDefinition<infer T> ? {
|
|
200
251
|
set(value: ValueForType<T>): void;
|
|
201
252
|
} : never;
|
|
@@ -228,6 +279,18 @@ export interface NodeExecutionContext<D extends NodeDefinition> {
|
|
|
228
279
|
readonly capabilities: DeclaredCapabilities<D>;
|
|
229
280
|
readonly signal: CascadeAbortSignal;
|
|
230
281
|
readonly progress: ProgressReporter;
|
|
282
|
+
/**
|
|
283
|
+
* This node's seed, derived from the graph's `seed` and the node id
|
|
284
|
+
* (`nodeSeed` in `@cascade/runtime`). Every host computes it the same way,
|
|
285
|
+
* so a seeded node draws the same thing headless and in Studio. Pass it on
|
|
286
|
+
* to anything random, including a Python stage's args.
|
|
287
|
+
*/
|
|
288
|
+
readonly seed: number;
|
|
289
|
+
/**
|
|
290
|
+
* A stream of floats in [0, 1) seeded with `seed`, starting afresh at every
|
|
291
|
+
* cook. Use it instead of `Math.random`, which no host can reproduce.
|
|
292
|
+
*/
|
|
293
|
+
readonly random: () => number;
|
|
231
294
|
}
|
|
232
295
|
export type NodeExecute<D extends NodeDefinition = NodeDefinition> = (context: NodeExecutionContext<D>) => void | Promise<void>;
|
|
233
296
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EditorDeclaration } from "./editor.js";
|
|
1
2
|
import type { SerializableValue } from "./values.js";
|
|
2
3
|
export interface CascadeDocumentNode {
|
|
3
4
|
readonly id: string;
|
|
@@ -54,6 +55,34 @@ export interface CascadeDocument {
|
|
|
54
55
|
readonly nodes: readonly CascadeDocumentNode[];
|
|
55
56
|
readonly annotations?: readonly CascadeDocumentAnnotation[];
|
|
56
57
|
readonly connections?: readonly CascadeDocumentConnection[];
|
|
58
|
+
/** The shareable editor this graph declares; ignored by the runtime. See `editor.ts`. */
|
|
59
|
+
readonly editor?: EditorDeclaration;
|
|
60
|
+
/**
|
|
61
|
+
* The graph seed, an unsigned 32-bit integer; 0 when absent. Each node's
|
|
62
|
+
* `context.seed` is derived from it and the node id, so changing it
|
|
63
|
+
* reshuffles every seeded node at once.
|
|
64
|
+
*/
|
|
65
|
+
readonly seed?: number;
|
|
66
|
+
/** The timeline the graph is played and rendered over. See `TimelineSettings`. */
|
|
67
|
+
readonly timeline?: TimelineSettings;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The frame rate, range and looping a graph is made for, saved with it.
|
|
71
|
+
*
|
|
72
|
+
* Without it every graph opened at 30 fps and frames 1-250, and a piece made
|
|
73
|
+
* for 24 fps over 594 frames (cloud-wall's H1 flipbook) had to be set up by
|
|
74
|
+
* hand on every open. Studio's timeline reads and writes it, the runtime takes
|
|
75
|
+
* its `fps` as the graph's own rate, and `cascade run --frames timeline`
|
|
76
|
+
* renders `start`-`end`. Every field is optional; absent ones keep the
|
|
77
|
+
* defaults (30 fps, 1-250, looping).
|
|
78
|
+
*/
|
|
79
|
+
export interface TimelineSettings {
|
|
80
|
+
readonly fps?: number;
|
|
81
|
+
/** First frame, inclusive. */
|
|
82
|
+
readonly start?: number;
|
|
83
|
+
/** Last frame, inclusive. */
|
|
84
|
+
readonly end?: number;
|
|
85
|
+
readonly loop?: boolean;
|
|
57
86
|
}
|
|
58
87
|
export interface CascadePreset {
|
|
59
88
|
readonly version: 1;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { SelectOption } from "./definition.js";
|
|
2
|
+
import type { JsonValue } from "./values.js";
|
|
3
|
+
/**
|
|
4
|
+
* The shareable editor a graph declares: which parameters someone else may
|
|
5
|
+
* change, which outputs they may export, the presets they may start from, and
|
|
6
|
+
* the assets that are allowed to leave the project with it.
|
|
7
|
+
*
|
|
8
|
+
* It sits beside `nodes` in the document, like Houdini's parameter interface on
|
|
9
|
+
* a digital asset sits beside its network. The runtime ignores it: a published
|
|
10
|
+
* parameter is an ordinary prop with a label, so a headless render, Studio and
|
|
11
|
+
* the exported editor cook the same graph. Only `cascade export`, the editor
|
|
12
|
+
* shell and scene files read it.
|
|
13
|
+
*
|
|
14
|
+
* Everything here is an allowlist. A parameter, output or asset that is not
|
|
15
|
+
* named does not reach the exported site, and a scene file carries values for
|
|
16
|
+
* named parameters only. That is the boundary a share relies on: an export is
|
|
17
|
+
* the selected subgraph plus the selected assets, never the project.
|
|
18
|
+
*/
|
|
19
|
+
export interface EditorDeclaration {
|
|
20
|
+
/** Stable identity of the editor, written into every scene. `cloud-type`. */
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly title?: string;
|
|
23
|
+
readonly description?: string;
|
|
24
|
+
/** Group names in display order. Groups not listed follow, in first-use order. */
|
|
25
|
+
readonly groups?: readonly string[];
|
|
26
|
+
readonly parameters?: readonly PublishedParameter[];
|
|
27
|
+
readonly outputs?: readonly PublishedOutput[];
|
|
28
|
+
readonly presets?: readonly EditorPreset[];
|
|
29
|
+
/**
|
|
30
|
+
* Project-relative files the author selects to ship. Literal asset values of
|
|
31
|
+
* published parameters are included too; nothing else is. A path inside a
|
|
32
|
+
* `licensed/` directory, a hidden file, or a gitignored file is refused.
|
|
33
|
+
*/
|
|
34
|
+
readonly assets?: readonly string[];
|
|
35
|
+
/**
|
|
36
|
+
* Data-source nodes replaced by a snapshot of chosen values. A live source
|
|
37
|
+
* (server, files, Python, shell or a `source: "live"` definition) still wired
|
|
38
|
+
* into the exported subgraph fails the export.
|
|
39
|
+
*/
|
|
40
|
+
readonly freeze?: readonly FrozenSource[];
|
|
41
|
+
/** Optional project panel module that extends or replaces the generated UI. */
|
|
42
|
+
readonly panel?: EditorPanelDeclaration;
|
|
43
|
+
/** The read-only stage view. On unless the author turns it off. */
|
|
44
|
+
readonly inspect?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Parameter ids a phone keeps in reach at the bottom sheet's lowest snap
|
|
47
|
+
* point (the text, a Reroll). Defaults to the first text and seed parameters.
|
|
48
|
+
*/
|
|
49
|
+
readonly peek?: readonly string[];
|
|
50
|
+
/**
|
|
51
|
+
* Values cooked while a slider is being dragged on a phone, for a quicker
|
|
52
|
+
* preview: a lower density, say. They never enter a scene or an export, and
|
|
53
|
+
* the real values cook again on release.
|
|
54
|
+
*/
|
|
55
|
+
readonly draft?: Readonly<Record<string, JsonValue>>;
|
|
56
|
+
}
|
|
57
|
+
export type PublishedControl = "number" | "slider" | "int" | "bool" | "select" | "text" | "textarea" | "color" | "file" | "seed" | "vec2";
|
|
58
|
+
export interface PublishedParameter {
|
|
59
|
+
/** Scene key. Stable across renames of the node or the prop it targets. */
|
|
60
|
+
readonly id: string;
|
|
61
|
+
/** The node and prop whose value this parameter sets. */
|
|
62
|
+
readonly node: string;
|
|
63
|
+
readonly prop: string;
|
|
64
|
+
readonly label?: string;
|
|
65
|
+
readonly group?: string;
|
|
66
|
+
readonly order?: number;
|
|
67
|
+
readonly help?: string;
|
|
68
|
+
readonly unit?: string;
|
|
69
|
+
/** Overrides the control the prop's type implies. */
|
|
70
|
+
readonly control?: PublishedControl;
|
|
71
|
+
readonly min?: number;
|
|
72
|
+
readonly max?: number;
|
|
73
|
+
readonly step?: number;
|
|
74
|
+
readonly options?: readonly SelectOption<"string">[] | readonly SelectOption<"float">[];
|
|
75
|
+
/** File parameters: accepted extensions or media types (`.otf`, `image/*`). */
|
|
76
|
+
readonly accept?: readonly string[];
|
|
77
|
+
/**
|
|
78
|
+
* File parameters: whether a dropped file may travel inside a scene.
|
|
79
|
+
* `never` keeps it to a name and a hash (licensed fonts); `auto` embeds files
|
|
80
|
+
* up to 2 MB. Dropped files never leave the viewer's browser otherwise.
|
|
81
|
+
*/
|
|
82
|
+
readonly embed?: "never" | "auto";
|
|
83
|
+
/** Shown only when other parameters have these values; a list must all hold. */
|
|
84
|
+
readonly visibleWhen?: VisibleWhen | readonly VisibleWhen[];
|
|
85
|
+
}
|
|
86
|
+
export type VisibleWhen = Readonly<{
|
|
87
|
+
param: string;
|
|
88
|
+
equals?: JsonValue;
|
|
89
|
+
in?: readonly JsonValue[];
|
|
90
|
+
not?: readonly JsonValue[];
|
|
91
|
+
}>;
|
|
92
|
+
export type PublishedOutputFormat = "png" | "svg" | "json" | "text";
|
|
93
|
+
export interface PublishedOutput {
|
|
94
|
+
readonly id: string;
|
|
95
|
+
readonly node: string;
|
|
96
|
+
readonly port: string;
|
|
97
|
+
readonly label?: string;
|
|
98
|
+
readonly format: PublishedOutputFormat;
|
|
99
|
+
/** Download name; `{id}` and `{scene}` are replaced. */
|
|
100
|
+
readonly filename?: string;
|
|
101
|
+
/** Published parameter ids shown beside this output's button (dpi, ground). */
|
|
102
|
+
readonly parameters?: readonly string[];
|
|
103
|
+
/** The output shown in the viewer. One output should set it. */
|
|
104
|
+
readonly view?: boolean;
|
|
105
|
+
}
|
|
106
|
+
export interface EditorPreset {
|
|
107
|
+
readonly id: string;
|
|
108
|
+
readonly label: string;
|
|
109
|
+
/** Published parameter id to value. Missing parameters take their defaults. */
|
|
110
|
+
readonly values: Readonly<Record<string, JsonValue>>;
|
|
111
|
+
/** Parameters the preset leaves as they are (colour, pen) instead of resetting them. */
|
|
112
|
+
readonly keep?: readonly string[];
|
|
113
|
+
}
|
|
114
|
+
export interface FrozenSource {
|
|
115
|
+
/** The live node the snapshot replaces. Everything upstream of it is dropped. */
|
|
116
|
+
readonly node: string;
|
|
117
|
+
readonly output: string;
|
|
118
|
+
/** Project-relative snapshot written by `cascade freeze`. */
|
|
119
|
+
readonly snapshot: string;
|
|
120
|
+
}
|
|
121
|
+
export interface EditorPanelDeclaration {
|
|
122
|
+
/** Project-relative module exporting `mount(target, api)`. */
|
|
123
|
+
readonly module: string;
|
|
124
|
+
/** `extend` (default) mounts it above the generated parameters. */
|
|
125
|
+
readonly placement?: "extend" | "replace";
|
|
126
|
+
}
|
|
127
|
+
/** What `cascade freeze` writes: exactly the chosen values, nothing else. */
|
|
128
|
+
export interface FrozenSnapshot {
|
|
129
|
+
readonly format: "cascade.frozen";
|
|
130
|
+
readonly version: 1;
|
|
131
|
+
readonly node: string;
|
|
132
|
+
readonly output: string;
|
|
133
|
+
readonly fields: readonly string[];
|
|
134
|
+
/** Fields the author marked as personal, flagged in every export plan. */
|
|
135
|
+
readonly personal?: readonly string[];
|
|
136
|
+
readonly value: JsonValue;
|
|
137
|
+
/** Project-relative files the value refers to, copied beside the snapshot. */
|
|
138
|
+
readonly files?: readonly string[];
|
|
139
|
+
readonly frozenAt: string;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* A scene: what someone changed in an editor, as a file that opens onto the
|
|
143
|
+
* same graph in Studio, the CLI or the exported editor.
|
|
144
|
+
*
|
|
145
|
+
* It holds published parameter values and the files the person dropped, and
|
|
146
|
+
* nothing from the project. Version mismatches degrade: unknown parameters are
|
|
147
|
+
* ignored with a warning, missing ones take the graph's defaults.
|
|
148
|
+
*/
|
|
149
|
+
export interface CascadeScene {
|
|
150
|
+
readonly format: "cascade.scene";
|
|
151
|
+
readonly version: 1;
|
|
152
|
+
readonly graph: Readonly<{
|
|
153
|
+
id: string;
|
|
154
|
+
version: string;
|
|
155
|
+
}>;
|
|
156
|
+
readonly name?: string;
|
|
157
|
+
readonly values: Readonly<Record<string, JsonValue>>;
|
|
158
|
+
/** Files for `file` parameters, by parameter id. */
|
|
159
|
+
readonly files?: Readonly<Record<string, SceneFile>>;
|
|
160
|
+
readonly savedAt?: string;
|
|
161
|
+
}
|
|
162
|
+
export interface SceneFile {
|
|
163
|
+
readonly name: string;
|
|
164
|
+
readonly mediaType?: string;
|
|
165
|
+
readonly size: number;
|
|
166
|
+
/** Hex SHA-256 of the bytes, to match a file the receiver already has. */
|
|
167
|
+
readonly sha256: string;
|
|
168
|
+
/** Base64 bytes, present only when the parameter allows embedding. */
|
|
169
|
+
readonly data?: string;
|
|
170
|
+
}
|
|
171
|
+
export declare const SCENE_EMBED_LIMIT: number;
|
|
172
|
+
//# sourceMappingURL=editor.d.ts.map
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export * from "./animation.js";
|
|
2
|
+
export * from "./bundle.js";
|
|
2
3
|
export * from "./camera.js";
|
|
3
4
|
export * from "./capabilities.js";
|
|
4
5
|
export * from "./color.js";
|
|
5
6
|
export * from "./definition.js";
|
|
6
7
|
export * from "./document.js";
|
|
8
|
+
export * from "./editor.js";
|
|
7
9
|
export * from "./geometry.js";
|
|
8
10
|
export * from "./particles.js";
|
|
9
11
|
export * from "./scene.js";
|
package/dist/contracts/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export * from "./animation.js";
|
|
2
|
+
export * from "./bundle.js";
|
|
2
3
|
export * from "./camera.js";
|
|
3
4
|
export * from "./capabilities.js";
|
|
4
5
|
export * from "./color.js";
|
|
5
6
|
export * from "./definition.js";
|
|
6
7
|
export * from "./document.js";
|
|
8
|
+
export * from "./editor.js";
|
|
7
9
|
export * from "./geometry.js";
|
|
8
10
|
export * from "./particles.js";
|
|
9
11
|
export * from "./scene.js";
|