diff --git a/.changeset/curvy-peaches-pump.md b/.changeset/curvy-peaches-pump.md
new file mode 100644
index 00000000..fa9ad60a
--- /dev/null
+++ b/.changeset/curvy-peaches-pump.md
@@ -0,0 +1,5 @@
+---
+"@tokens-studio/graph-engine": major
+---
+
+Removed .getInput and .getRawInput from the Node. Direct access to the underlying ports are preferred over these utility methods
diff --git a/.changeset/fresh-starfishes-sniff.md b/.changeset/fresh-starfishes-sniff.md
new file mode 100644
index 00000000..931b379b
--- /dev/null
+++ b/.changeset/fresh-starfishes-sniff.md
@@ -0,0 +1,5 @@
+---
+"@tokens-studio/graph-engine": minor
+---
+
+Add typing/hasValue node that lets you check if a value is present
diff --git a/.changeset/giant-impalas-greet.md b/.changeset/giant-impalas-greet.md
new file mode 100644
index 00000000..f727ab8a
--- /dev/null
+++ b/.changeset/giant-impalas-greet.md
@@ -0,0 +1,5 @@
+---
+"@tokens-studio/graph-engine": major
+---
+
+Removed .setOutput from the Node class, this should be replaced with direct port manipulation
diff --git a/.changeset/grumpy-donuts-sit.md b/.changeset/grumpy-donuts-sit.md
new file mode 100644
index 00000000..58f6aff7
--- /dev/null
+++ b/.changeset/grumpy-donuts-sit.md
@@ -0,0 +1,8 @@
+---
+"@tokens-studio/graph-engine-nodes-design-tokens": major
+"@tokens-studio/graph-engine-nodes-audio": major
+"@tokens-studio/graph-engine-nodes-image": major
+"@tokens-studio/graph-engine-nodes-fs": major
+---
+
+Update to use the latest exposed input manipulation from the engine via direct control
diff --git a/.changeset/khaki-jokes-sit.md b/.changeset/khaki-jokes-sit.md
new file mode 100644
index 00000000..3f94cfc3
--- /dev/null
+++ b/.changeset/khaki-jokes-sit.md
@@ -0,0 +1,5 @@
+---
+"@tokens-studio/graph-engine": minor
+---
+
+Add pad node that lets you fill a string to a certain lenght with a given character, like 25 to 025
diff --git a/.changeset/quiet-moose-drive.md b/.changeset/quiet-moose-drive.md
new file mode 100644
index 00000000..a8bb440c
--- /dev/null
+++ b/.changeset/quiet-moose-drive.md
@@ -0,0 +1,5 @@
+---
+"@tokens-studio/graph-editor": patch
+---
+
+Fix an issue where create subgraph did not make the create inputs deletable
diff --git a/.changeset/rude-tables-happen.md b/.changeset/rude-tables-happen.md
new file mode 100644
index 00000000..462cf511
--- /dev/null
+++ b/.changeset/rude-tables-happen.md
@@ -0,0 +1,5 @@
+---
+"tokens-studio-graph-engine": patch
+---
+
+Fixed an issue with memoization that should improve performance
diff --git a/.changeset/silver-carpets-kiss.md b/.changeset/silver-carpets-kiss.md
new file mode 100644
index 00000000..842f39f9
--- /dev/null
+++ b/.changeset/silver-carpets-kiss.md
@@ -0,0 +1,5 @@
+---
+"@tokens-studio/graph-engine": major
+---
+
+Removed .getOutput from the node. This was never used and can rather be implemented as a utility method
diff --git a/.changeset/slimy-ways-appear.md b/.changeset/slimy-ways-appear.md
new file mode 100644
index 00000000..c900e545
--- /dev/null
+++ b/.changeset/slimy-ways-appear.md
@@ -0,0 +1,5 @@
+---
+"@tokens-studio/graph-engine-nodes-image": patch
+---
+
+Fixed a lot of broken typescript types on the nodes
diff --git a/.changeset/wild-rice-kiss.md b/.changeset/wild-rice-kiss.md
new file mode 100644
index 00000000..4017d0cf
--- /dev/null
+++ b/.changeset/wild-rice-kiss.md
@@ -0,0 +1,5 @@
+---
+"@tokens-studio/graph-engine": major
+---
+
+Removed getAllOutputs from the Node definition, this was never used and can rather be implemented as a utility
diff --git a/packages/documentation/docs/guides/developers/engine/creating-a-node.md b/packages/documentation/docs/guides/developers/engine/creating-a-node.md
index 53782c01..1cd6f558 100644
--- a/packages/documentation/docs/guides/developers/engine/creating-a-node.md
+++ b/packages/documentation/docs/guides/developers/engine/creating-a-node.md
@@ -49,8 +49,9 @@ export default class MyCustomNode extends Node {
//This is the main logic of your node. The execute can be async or not.
execute() {
+ //These will be strongly typed if you used declarations
const { a, b } = this.getAllInputs();
- this.setOutput("value", a + b);
+ this.outputs.value.set(a + b);
}
}
```
diff --git a/packages/graph-editor/src/components/controls/floatCurve.tsx b/packages/graph-editor/src/components/controls/floatCurve.tsx
new file mode 100644
index 00000000..b5d458b0
--- /dev/null
+++ b/packages/graph-editor/src/components/controls/floatCurve.tsx
@@ -0,0 +1,14 @@
+import { FloatCurveEditor } from '../floatCurveEditor/index.js';
+import { IField } from './interface.js';
+import { Input } from '@tokens-studio/graph-engine';
+import { observer } from 'mobx-react-lite';
+import React from 'react';
+
+export const FloatCurveField = observer(({ port, readOnly }: IField) => {
+ const onChange = (curve) => {
+ if (!readOnly) {
+ (port as Input).setValue(curve);
+ }
+ };
+ return ;
+});
diff --git a/packages/graph-editor/src/components/floatCurveEditor/index.tsx b/packages/graph-editor/src/components/floatCurveEditor/index.tsx
new file mode 100644
index 00000000..09b77b31
--- /dev/null
+++ b/packages/graph-editor/src/components/floatCurveEditor/index.tsx
@@ -0,0 +1,249 @@
+import * as React from 'react';
+import {
+ ConstraintFunction,
+ Coordinates,
+ Line,
+ Mafs,
+ MovablePoint,
+ Plot,
+ Text,
+ Theme,
+ vec,
+} from 'mafs';
+import { FloatCurve, Vec2 } from '@tokens-studio/graph-engine';
+
+function xyFromBernsteinPolynomial(
+ p1: vec.Vector2,
+ c1: vec.Vector2,
+ c2: vec.Vector2,
+ p2: vec.Vector2,
+ x: number,
+) {
+ const t = (x - p1[0]) / (p2[0] - p1[0]);
+
+ return [
+ x,
+ (1 - t) ** 3 * p1[1] +
+ 3 * (1 - t) ** 2 * t * c1[1] +
+ 3 * (1 - t) * t ** 2 * c2[1] +
+ t ** 3 * p2[1],
+ ];
+}
+
+function inPairs(arr: T[]) {
+ const pairs: [T, T][] = [];
+ for (let i = 0; i < arr.length - 1; i++) {
+ pairs.push([arr[i], arr[i + 1]]);
+ }
+
+ return pairs;
+}
+
+const round = (n: number, precision: number = 2) =>
+ Math.round(n * 10 ** precision) / 10 ** precision;
+
+const defaultConstraintPoint: ConstraintFunction = ([x, y]) => {
+ return [Math.min(Math.max(x, 0), 1), y];
+};
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+const startConstraint: ConstraintFunction = ([_, y]) => {
+ return [0, Math.min(Math.max(y, 0), 1)];
+};
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+const endConstraint: ConstraintFunction = ([_, y]) => {
+ return [1, Math.min(Math.max(y, 0), 1)];
+};
+
+export interface ICurveEditor {
+ domain?: [number, number];
+ range?: [number, number];
+ onChange?: (FloatCurve) => void;
+ curve: FloatCurve;
+}
+
+const noop = () => {};
+
+const x = (vec: vec.Vector2) => vec[0];
+const y = (vec: vec.Vector2) => vec[1];
+
+function CubicSegment({ p1, p2, controls, onChange, index }) {
+ const [c1, c2] = controls;
+
+ const constraint: ConstraintFunction = React.useCallback(
+ ([x, y]) => {
+ return [Math.min(Math.max(x, p1[0]), p2[0]), y];
+ },
+ [p1, p2],
+ );
+
+ return (
+ <>
+
+
+
+ {round(x(c1))} {round(y(c1))}
+
+
+
+ {round(x(c2))} {round(y(c2))}
+
+ xyFromBernsteinPolynomial(p1, c1, c2, p2, t)}
+ />
+ {controls.map((point, i) => (
+ {
+ const newPoints = [...controls];
+ newPoints[i] = newPoint;
+ onChange(newPoints, index);
+ }}
+ />
+ ))}
+ >
+ );
+}
+
+const getConstraint = (index, length): ConstraintFunction => {
+ if (index == 0) {
+ return startConstraint;
+ }
+ if (index == length - 1) {
+ return endConstraint;
+ }
+ return defaultConstraintPoint;
+};
+
+export function FloatCurveEditor(props: ICurveEditor) {
+ const { domain = [0, 1], range = [0, 1], curve, onChange = noop } = props;
+
+ const onDblClick = React.useCallback(
+ (point, e: MouseEvent) => {
+ //Check the detail to make sure it was a double click
+ if (e.detail === 2) {
+ //Find the segment where the x value lines between the two x values
+
+ const startIndex = curve.segments.findIndex((segment, i) => {
+ const nextSegment = curve.segments[i + 1];
+ return segment[0] <= point[0] && point[0] <= nextSegment[0];
+ });
+ const newIndex = startIndex + 1;
+
+ //Now create a new point in between
+ const newSegments = [
+ ...curve.segments.slice(0, newIndex),
+ point,
+ ...curve.segments.slice(newIndex),
+ ];
+
+ //We are going to replace the control points at the clicked point
+ const existingControls = curve.controlPoints[startIndex];
+
+ //The existing one is going to now be split
+
+ //Create the new curve point values lets make them half the distance between the two points
+ const cp1 = [
+ point[0] - (point[0] + curve.segments[startIndex][0]) / 4,
+ (point[1] + curve.segments[startIndex][1]) / 2,
+ ];
+ const cp2 = [
+ point[0] + (point[0] + curve.segments[startIndex + 1][0]) / 4,
+ (point[1] + curve.segments[startIndex + 1][1]) / 2,
+ ];
+
+ const left = [existingControls[0], cp1];
+ const right = [cp2, existingControls[1]];
+
+ // We also need to create new control points
+ const controlPoints = [
+ ...curve.controlPoints.slice(0, startIndex),
+ left,
+ right,
+ ...curve.controlPoints.slice(startIndex + 1),
+ ] as [Vec2, Vec2][];
+ //We need to emit a new curve
+ onChange({
+ segments: newSegments,
+ controlPoints,
+ });
+ }
+ },
+ [curve.controlPoints, curve.segments, onChange],
+ );
+
+ const onControlChange = React.useCallback(
+ (controls, index) => {
+ const controlPoints = [...curve.controlPoints];
+ controlPoints[index] = controls;
+ onChange({
+ ...curve,
+ controlPoints,
+ });
+ },
+ [curve, onChange],
+ );
+
+ const length = curve.segments.length;
+ return (
+ <>
+
+
+ {/* Draw the segments */}
+ {inPairs(curve.segments).map(([p1, p2], i) => (
+
+ ))}
+ {curve.segments.map((point, i) => (
+
+ {' '}
+ {
+ //Create a new array with the new point
+ const newSegments = [...curve.segments];
+ newSegments[i] = newPoint;
+ onChange({
+ segments: newSegments.sort((a, b) => a[0] - b[0]),
+ controlPoints: curve.controlPoints,
+ });
+ }}
+ />
+
+ {round(x(point))} {round(y(point))}
+
+
+ ))}
+
+ >
+ );
+}
diff --git a/packages/graph-editor/src/registry/control.tsx b/packages/graph-editor/src/registry/control.tsx
index ddf4f0ba..75a53331 100644
--- a/packages/graph-editor/src/registry/control.tsx
+++ b/packages/graph-editor/src/registry/control.tsx
@@ -3,6 +3,7 @@ import {
BOOLEAN,
COLOR,
CURVE,
+ FLOATCURVE,
Input,
NUMBER,
Port,
@@ -17,6 +18,7 @@ import { ColorField } from '@/components/controls/color.js';
import { CurveField } from '@/components/controls/curve.js';
import { DefaultField } from '@/components/controls/default.js';
import { EnumeratedTextfield } from '@/components/controls/enumerated.js';
+import { FloatCurveField } from '@/components/controls/floatCurve.js';
import { NumericField } from '@/components/controls/numeric.js';
import { SliderField } from '@/components/controls/slider.js';
import { TextArea } from '@/components/controls/text.js';
@@ -40,10 +42,15 @@ export const defaultControls = [
matcher: (port: Port) => port.annotations['ui.control'] === 'slider',
component: SliderField,
},
+ {
+ matcher: (port: Port) => port.type.$id === FLOATCURVE,
+ component: FloatCurveField,
+ },
{
matcher: (port: Port) => port.type.$id === CURVE,
component: CurveField,
},
+
{
matcher: (port: Port) => port.type.$id === BOOLEAN,
component: BooleanField,
diff --git a/packages/graph-engine/src/nodes/accessibility/colorBlindness.ts b/packages/graph-engine/src/nodes/accessibility/colorBlindness.ts
index e0626734..39d46d74 100644
--- a/packages/graph-engine/src/nodes/accessibility/colorBlindness.ts
+++ b/packages/graph-engine/src/nodes/accessibility/colorBlindness.ts
@@ -1,5 +1,5 @@
-import { ColorSchema, StringSchema } from '../../schemas/index.js';
import {
+ Color,
INodeDefinition,
ToInput,
ToOutput,
@@ -7,6 +7,7 @@ import {
toColor,
toHex
} from '../../index.js';
+import { ColorSchema, StringSchema } from '../../schemas/index.js';
import { Node } from '../../programmatic/node.js';
import blinder from 'color-blind-esm';
@@ -31,7 +32,7 @@ export default class NodeDefinition extends Node {
'Converts provided colors to the colors as perceived by the specified color blindness type. The output is a hex color string. The color blindness types include protanopia, protanomaly, deuteranopia, deuteranomaly, tritanopia, tritanomaly, achromatopsia, and achromatomaly. The output is a hex color string.';
declare inputs: ToInput<{
- color: string;
+ color: Color;
type: ColorBlindnessTypes;
}>;
@@ -39,7 +40,7 @@ export default class NodeDefinition extends Node {
/**
* The calculated color contrast based on the input color and the specified color blindness type.
*/
- value: string;
+ value: Color;
}>;
constructor(props: INodeDefinition) {
@@ -102,6 +103,6 @@ export default class NodeDefinition extends Node {
const asCol = hexToColor(processed);
- this.setOutput('value', asCol);
+ this.outputs.value.set(asCol);
}
}
diff --git a/packages/graph-engine/src/nodes/array/arraySubgraph.ts b/packages/graph-engine/src/nodes/array/arraySubgraph.ts
index 52a94aec..ca964363 100644
--- a/packages/graph-engine/src/nodes/array/arraySubgraph.ts
+++ b/packages/graph-engine/src/nodes/array/arraySubgraph.ts
@@ -155,12 +155,12 @@ export default class ArraySubgraph extends Node {
}
async execute() {
- const input = this.getRawInput('array');
+ const input = this.inputs.array;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const otherInputs: [string, Input][] = Object.keys(this.inputs)
.filter(x => x !== 'array')
- .map(x => [x, this.getRawInput(x)]);
+ .map(x => [x, this.inputs[x]]);
const other = Object.fromEntries(
otherInputs.map(([name, x]) => [
name,
@@ -215,7 +215,7 @@ export default class ArraySubgraph extends Node {
items: type
};
- this.setOutput('value', flattened, dynamicTypeSchema);
+ this.outputs.value.set(flattened, dynamicTypeSchema);
}
override serialize() {
diff --git a/packages/graph-engine/src/nodes/array/arrify.ts b/packages/graph-engine/src/nodes/array/arrify.ts
index 442c093b..8a777a41 100644
--- a/packages/graph-engine/src/nodes/array/arrify.ts
+++ b/packages/graph-engine/src/nodes/array/arrify.ts
@@ -33,7 +33,8 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const items = this.getRawInput('items');
- this.setOutput('value', items.value, items.type);
+ const items = this.inputs.items;
+
+ this.outputs.value.set(items.value, items.type);
}
}
diff --git a/packages/graph-engine/src/nodes/array/concat.ts b/packages/graph-engine/src/nodes/array/concat.ts
index c537a666..3667d12b 100644
--- a/packages/graph-engine/src/nodes/array/concat.ts
+++ b/packages/graph-engine/src/nodes/array/concat.ts
@@ -28,13 +28,13 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const a = this.getRawInput('a');
- const b = this.getRawInput('b');
+ const a = this.inputs.a;
+ const b = this.inputs.b;
//Verify types
if (a.type.$id !== b.type.$id) throw new Error('Array types must match');
const calculated = a.value.concat(b.value);
- this.setOutput('value', calculated, a.type);
+ this.outputs.value.set(calculated, a.type);
}
}
diff --git a/packages/graph-engine/src/nodes/array/filter.ts b/packages/graph-engine/src/nodes/array/filter.ts
index f7bf2e19..c574fbd9 100644
--- a/packages/graph-engine/src/nodes/array/filter.ts
+++ b/packages/graph-engine/src/nodes/array/filter.ts
@@ -153,12 +153,12 @@ export default class ArraySubgraph extends Node {
}
async execute() {
- const input = this.getRawInput('array');
+ const input = this.inputs.array;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const otherInputs: [string, Input][] = Object.keys(this.inputs)
.filter(x => x !== 'array')
- .map(x => [x, this.getRawInput(x)]);
+ .map(x => [x, this.inputs[x]]);
const other = Object.fromEntries(
otherInputs.map(([name, x]) => [
name,
@@ -200,7 +200,7 @@ export default class ArraySubgraph extends Node {
return output;
}, Promise.resolve([]));
- this.setOutput('value', output, input.type);
+ this.outputs.value.set(output, input.type);
}
override serialize() {
diff --git a/packages/graph-engine/src/nodes/array/find.ts b/packages/graph-engine/src/nodes/array/find.ts
index be369991..5809a95c 100644
--- a/packages/graph-engine/src/nodes/array/find.ts
+++ b/packages/graph-engine/src/nodes/array/find.ts
@@ -21,15 +21,18 @@ export interface IArraySubgraph extends INodeDefinition {
innerGraph?: Graph;
}
-export default class ArraySubgraph extends Node {
+export default class ArraySubgraph extends Node {
static title = 'Array find';
static type = 'tokens.studio.array.find';
static description = 'Finds an item in an array';
_innerGraph: Graph;
- declare inputs: ToInput<{
- array: T[];
- }>;
+ declare inputs: ToInput<
+ {
+ array: T[];
+ //Other dynamic inputs
+ } & Record
+ >;
declare outputs: ToOutput<{
value: T;
@@ -163,12 +166,12 @@ export default class ArraySubgraph extends Node {
}
async execute() {
- const input = this.getRawInput('array');
+ const input = this.inputs.array;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const otherInputs: [string, Input][] = Object.keys(this.inputs)
.filter(x => x !== 'array')
- .map(x => [x, this.getRawInput(x)]);
+ .map(x => [x, this.inputs[x]]);
const other = Object.fromEntries(
otherInputs.map(([name, x]) => [
name,
@@ -182,7 +185,7 @@ export default class ArraySubgraph extends Node {
//Todo optimize this to run in parallel. We have to run this in series because the inner graph is not designed to run in parallel
const itemType = extractArray(input.type);
let found = false;
- let output = undefined;
+ let output: T | undefined = undefined;
let index = 0;
for (const element of input.value) {
const result = await this._innerGraph.execute({
@@ -210,10 +213,9 @@ export default class ArraySubgraph extends Node {
break;
}
}
-
- this.setOutput('found', found);
- this.setOutput('index', found ? index : -1);
- this.setOutput('value', output, input.type.items);
+ this.outputs.found.set(found);
+ this.outputs.index.set(found ? index : -1);
+ this.outputs.value.set(output!, input.type.items);
}
override serialize() {
diff --git a/packages/graph-engine/src/nodes/array/flatten.ts b/packages/graph-engine/src/nodes/array/flatten.ts
index 30c7f8c1..2c9b3bf6 100644
--- a/packages/graph-engine/src/nodes/array/flatten.ts
+++ b/packages/graph-engine/src/nodes/array/flatten.ts
@@ -30,7 +30,7 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const array = this.getRawInput('array');
+ const array = this.inputs.array;
//Attempt to determine the type of the array
const type = array.type.items;
@@ -40,6 +40,6 @@ export default class NodeDefinition extends Node {
}
const calculated = array.value.flat();
- this.setOutput('array', calculated, type);
+ this.outputs.array.set(calculated, type);
}
}
diff --git a/packages/graph-engine/src/nodes/array/indexArray.ts b/packages/graph-engine/src/nodes/array/indexArray.ts
index 1945b58c..37c34372 100644
--- a/packages/graph-engine/src/nodes/array/indexArray.ts
+++ b/packages/graph-engine/src/nodes/array/indexArray.ts
@@ -47,7 +47,7 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const array = this.getRawInput('array');
+ const array = this.inputs.array;
const { index } = this.getAllInputs();
//Get the value
const calculated = array.value[index];
@@ -60,6 +60,6 @@ export default class NodeDefinition extends Node {
itemType = array.type.items as SchemaObject;
}
- this.setOutput('value', calculated, itemType);
+ this.outputs.value.set(calculated, itemType);
}
}
diff --git a/packages/graph-engine/src/nodes/array/inject.ts b/packages/graph-engine/src/nodes/array/inject.ts
index e1307ee8..69227f17 100644
--- a/packages/graph-engine/src/nodes/array/inject.ts
+++ b/packages/graph-engine/src/nodes/array/inject.ts
@@ -18,7 +18,7 @@ export default class NodeDefinition extends Node {
}>;
declare outputs: ToOutput<{
- value: T[];
+ array: T[];
}>;
constructor(props: INodeDefinition) {
@@ -38,12 +38,12 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const { item, index } = this.getAllInputs();
- const array = this.getRawInput('array');
- this.inputs.item.setType(array.type.items);
+ const { item, index, array } = this.getAllInputs();
+ const arrayType = this.inputs.array.type;
+ this.inputs.item.setType(arrayType.items);
// Create a copy of the array value
- const result = [...array.value];
+ const result = [...array];
if (index >= 0) {
result.splice(index, 0, item);
@@ -53,6 +53,6 @@ export default class NodeDefinition extends Node {
}
// Set the output using the modified result and the original array type
- this.setOutput('array', result, array.type);
+ this.outputs.array.set(result, arrayType);
}
}
diff --git a/packages/graph-engine/src/nodes/array/push.ts b/packages/graph-engine/src/nodes/array/push.ts
index 157e0aad..019943ab 100644
--- a/packages/graph-engine/src/nodes/array/push.ts
+++ b/packages/graph-engine/src/nodes/array/push.ts
@@ -38,9 +38,9 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { item } = this.getAllInputs();
- const array = this.getRawInput('array');
+ const array = this.inputs.array;
const calculated = [...array.value, item];
- this.setOutput('value', calculated, array.type);
+ this.outputs.value.set(calculated, array.type);
}
}
diff --git a/packages/graph-engine/src/nodes/array/reverse.ts b/packages/graph-engine/src/nodes/array/reverse.ts
index dbf20f67..ceccf957 100644
--- a/packages/graph-engine/src/nodes/array/reverse.ts
+++ b/packages/graph-engine/src/nodes/array/reverse.ts
@@ -24,10 +24,10 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const array = this.getRawInput('array');
+ const array = this.inputs.array;
//Normal reverse mutates the array. We don't want that.
const reversed = [...array.value].reverse();
- this.setOutput('value', reversed, array.type);
+ this.outputs.value.set(reversed, array.type);
}
}
diff --git a/packages/graph-engine/src/nodes/array/slice.ts b/packages/graph-engine/src/nodes/array/slice.ts
index 10492814..f390854c 100644
--- a/packages/graph-engine/src/nodes/array/slice.ts
+++ b/packages/graph-engine/src/nodes/array/slice.ts
@@ -32,9 +32,9 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { start, end } = this.getAllInputs();
- const array = this.getRawInput('array');
+ const array = this.inputs.array;
const calculated = array.value.slice(start, end);
- this.setOutput('value', calculated, array.type);
+ this.outputs.value.set(calculated, array.type);
}
}
diff --git a/packages/graph-engine/src/nodes/array/sort.ts b/packages/graph-engine/src/nodes/array/sort.ts
index ca426052..afc9cb72 100644
--- a/packages/graph-engine/src/nodes/array/sort.ts
+++ b/packages/graph-engine/src/nodes/array/sort.ts
@@ -54,9 +54,9 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { sortBy, order } = this.getAllInputs();
- const array = this.getRawInput('array');
+ const array = this.inputs.array;
const sorted = orderBy(array.value, [sortBy], order);
- this.setOutput('value', sorted, array.type);
+ this.outputs.value.set(sorted, array.type);
}
}
diff --git a/packages/graph-engine/src/nodes/color/colorToString.ts b/packages/graph-engine/src/nodes/color/colorToString.ts
index bf1ca001..b03579a7 100644
--- a/packages/graph-engine/src/nodes/color/colorToString.ts
+++ b/packages/graph-engine/src/nodes/color/colorToString.ts
@@ -12,6 +12,7 @@ export default class NodeDefinition extends Node {
declare inputs: ToInput<{
color: ColorType;
+ space: 'srgb' | 'hsl' | 'hex';
}>;
declare outputs: ToOutput<{
value: string;
@@ -39,18 +40,20 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const color = this.getInput('color');
- let space = this.getInput('space');
+ // eslint-disable-next-line prefer-const
+ const { color, space } = this.getAllInputs();
+
+ let adjustedSpace: string = space;
let format: { format: string } | undefined = undefined;
if (space == 'hex') {
- space = 'srgb';
+ adjustedSpace = 'srgb';
format = {
format: 'hex'
};
}
- const col = toColor(color).to(space).toString(format);
- this.setOutput('value', col);
+ const col = toColor(color).to(adjustedSpace).toString(format);
+ this.outputs.value.set(col);
}
}
diff --git a/packages/graph-engine/src/nodes/color/contrast.ts b/packages/graph-engine/src/nodes/color/contrast.ts
index 6c5b8d04..bbb4654f 100644
--- a/packages/graph-engine/src/nodes/color/contrast.ts
+++ b/packages/graph-engine/src/nodes/color/contrast.ts
@@ -54,6 +54,6 @@ export default class NodeDefinition extends Node {
const calculated = background.contrast(color, algorithm);
- this.setOutput('value', absolute ? Math.abs(calculated) : calculated);
+ this.outputs.value.set(absolute ? Math.abs(calculated) : calculated);
}
}
diff --git a/packages/graph-engine/src/nodes/color/contrasting.ts b/packages/graph-engine/src/nodes/color/contrasting.ts
index e25d3e0e..4c028144 100644
--- a/packages/graph-engine/src/nodes/color/contrasting.ts
+++ b/packages/graph-engine/src/nodes/color/contrasting.ts
@@ -8,7 +8,7 @@ import {
import { Color as ColorType } from '../../types.js';
import { ContrastAlgorithm } from '../../types/index.js';
import { INodeDefinition, Node } from '../../programmatic/node.js';
-import { Output, ToInput, ToOutput } from '../../programmatic/index.js';
+import { ToInput, ToOutput } from '../../programmatic/index.js';
/**
* Performs a contrast calculation between two colors using APCA-W3 calcs
@@ -27,9 +27,9 @@ export default class NodeDefinition extends Node {
threshold: number;
}>;
declare outputs: ToOutput<{
- color: Output;
- sufficient: Output;
- contrast: Output;
+ color: ColorType;
+ sufficient: boolean;
+ contrast: number;
}>;
constructor(props: INodeDefinition) {
@@ -89,13 +89,13 @@ export default class NodeDefinition extends Node {
const contrastB = Math.abs(backgroundCol.contrast(colorB, algorithm));
if (contrastA > contrastB) {
- this.setOutput('color', a);
- this.setOutput('sufficient', contrastA >= threshold);
- this.setOutput('contrast', contrastA);
+ this.outputs.color.set(a);
+ this.outputs.sufficient.set(contrastA >= threshold);
+ this.outputs.contrast.set(contrastA);
} else {
- this.setOutput('color', b);
- this.setOutput('sufficient', contrastB >= threshold);
- this.setOutput('contrast', contrastB);
+ this.outputs.color.set(b);
+ this.outputs.sufficient.set(contrastB >= threshold);
+ this.outputs.contrast.set(contrastB);
}
}
}
diff --git a/packages/graph-engine/src/nodes/color/contrastingAlpha.ts b/packages/graph-engine/src/nodes/color/contrastingAlpha.ts
index a280ea6d..4e534f67 100644
--- a/packages/graph-engine/src/nodes/color/contrastingAlpha.ts
+++ b/packages/graph-engine/src/nodes/color/contrastingAlpha.ts
@@ -1,17 +1,14 @@
-/**
- * Performs a contrast calculation between two colors using APCA-W3 calcs
- *
- * @packageDocumentation
- */
import { Black, White, toColor, toColorObject } from './lib/utils.js';
import {
ColorSchema,
NumberSchema,
StringSchema
} from '../../schemas/index.js';
+import { Color as ColorType, ContrastAlgorithmType } from '../../types.js';
import { ContrastAlgorithm } from '../../types/index.js';
import { INodeDefinition, Node } from '../../programmatic/node.js';
-import { Input, Output } from '../../programmatic/index.js';
+import { ToInput } from '@/programmatic/input.js';
+import { ToOutput } from '@/programmatic/output.js';
import { flattenAlpha } from './lib/flattenAlpha.js';
import Color from 'colorjs.io';
@@ -28,18 +25,18 @@ export default class NodeDefinition extends Node {
static type = 'studio.tokens.color.contrastingAlpha';
static description = 'Reduce alpha until you are close to the threshold.';
- declare inputs: {
- a: Input;
- b: Input;
- background: Input;
- wcag: Input;
- threshold: Input;
- };
- declare outputs: {
- color: Output;
- sufficient: Output;
- contrast: Output;
- };
+ declare inputs: ToInput<{
+ foreground: ColorType;
+ background: ColorType;
+ algorithm: ContrastAlgorithmType;
+ threshold: number;
+ precision: number;
+ }>;
+ declare outputs: ToOutput<{
+ color: ColorType;
+ alpha: number;
+ contrast: number;
+ }>;
constructor(props: INodeDefinition) {
super(props);
@@ -145,12 +142,9 @@ export default class NodeDefinition extends Node {
);
if (currentContrast <= threshold) {
- this.setOutput('alpha', 1);
- this.setOutput(
- 'color',
- foregroundColor.to('srgb').toString({ format: 'hex' })
- );
- this.setOutput('contrast', currentContrast);
+ this.outputs.alpha.set(1);
+ this.outputs.color.set(toColorObject(foregroundColor));
+ this.outputs.contrast.set(currentContrast);
return;
}
@@ -169,8 +163,8 @@ export default class NodeDefinition extends Node {
finalColor.contrast(backgroundColor, algorithm)
);
- this.setOutput('alpha', finalAlpha);
- this.setOutput('color', toColorObject(finalColor));
- this.setOutput('contrast', finalContrast);
+ this.outputs.alpha.set(finalAlpha);
+ this.outputs.color.set(toColorObject(finalColor));
+ this.outputs.contrast.set(finalContrast);
}
}
diff --git a/packages/graph-engine/src/nodes/color/convert.ts b/packages/graph-engine/src/nodes/color/convert.ts
index fb1692df..2843496a 100644
--- a/packages/graph-engine/src/nodes/color/convert.ts
+++ b/packages/graph-engine/src/nodes/color/convert.ts
@@ -46,6 +46,6 @@ export default class NodeDefinition extends Node {
//Convert back to coords
- this.setOutput('color', toColorObject(colObj.to(space)));
+ this.outputs.color.set(toColorObject(colObj.to(space)));
}
}
diff --git a/packages/graph-engine/src/nodes/color/create.ts b/packages/graph-engine/src/nodes/color/create.ts
index 36e8a05d..3f9cf910 100644
--- a/packages/graph-engine/src/nodes/color/create.ts
+++ b/packages/graph-engine/src/nodes/color/create.ts
@@ -90,6 +90,6 @@ export default class NodeDefinition extends Node {
channels: [a, b, c],
alpha: alpha
} as Color;
- this.setOutput('value', color);
+ this.outputs.value.set(color);
}
}
diff --git a/packages/graph-engine/src/nodes/color/darken.ts b/packages/graph-engine/src/nodes/color/darken.ts
index 45986cfe..7940b7a6 100644
--- a/packages/graph-engine/src/nodes/color/darken.ts
+++ b/packages/graph-engine/src/nodes/color/darken.ts
@@ -49,6 +49,6 @@ export default class NodeDefinition extends Node {
sourceColor.oklch.l = newLightness;
const final = toColorObject(sourceColor);
- this.setOutput('value', final);
+ this.outputs.value.set(final);
}
}
diff --git a/packages/graph-engine/src/nodes/color/deconstruct.ts b/packages/graph-engine/src/nodes/color/deconstruct.ts
index 54fed491..8ec54650 100644
--- a/packages/graph-engine/src/nodes/color/deconstruct.ts
+++ b/packages/graph-engine/src/nodes/color/deconstruct.ts
@@ -74,16 +74,16 @@ export default class DestructColorNode extends Node {
throw new Error('Invalid color input');
}
- this.setOutput('space', color.space);
- this.setOutput('a', color.channels[0]);
- this.setOutput('b', color.channels[1]);
- this.setOutput('c', color.channels[2]);
+ this.outputs.space.set(color.space);
+ this.outputs.a.set(color.channels[0]);
+ this.outputs.b.set(color.channels[1]);
+ this.outputs.c.set(color.channels[2]);
// Only set alpha if it exists
if (color.alpha !== undefined) {
- this.setOutput('alpha', color.alpha);
+ this.outputs.alpha!.set(color.alpha);
} else {
- this.setOutput('alpha', undefined);
+ this.outputs.alpha!.set(undefined);
}
}
}
diff --git a/packages/graph-engine/src/nodes/color/deltaE.ts b/packages/graph-engine/src/nodes/color/deltaE.ts
index 719899a6..d649c2a9 100644
--- a/packages/graph-engine/src/nodes/color/deltaE.ts
+++ b/packages/graph-engine/src/nodes/color/deltaE.ts
@@ -59,6 +59,6 @@ export default class NodeDefinition extends Node {
const distance = a.deltaE(b, algorithm);
- this.setOutput('value', setToPrecision(distance, precision));
+ this.outputs.value.set(setToPrecision(distance, precision));
}
}
diff --git a/packages/graph-engine/src/nodes/color/distance.ts b/packages/graph-engine/src/nodes/color/distance.ts
index a354a336..c1020d86 100644
--- a/packages/graph-engine/src/nodes/color/distance.ts
+++ b/packages/graph-engine/src/nodes/color/distance.ts
@@ -22,11 +22,12 @@ export default class NodeDefinition extends Node {
declare inputs: ToInput<{
colorA: ColorType;
colorB: ColorType;
+ space: ColorSpace;
precision: number;
}>;
declare outputs: ToOutput<{
- value: ColorType;
+ value: number;
}>;
constructor(props: INodeDefinition) {
@@ -70,6 +71,6 @@ export default class NodeDefinition extends Node {
const distance = a.distance(b, space);
- this.setOutput('value', setToPrecision(distance, precision));
+ this.outputs.value.set(setToPrecision(distance, precision));
}
}
diff --git a/packages/graph-engine/src/nodes/color/flattenAlpha.ts b/packages/graph-engine/src/nodes/color/flattenAlpha.ts
index 67416003..1e6fdc29 100644
--- a/packages/graph-engine/src/nodes/color/flattenAlpha.ts
+++ b/packages/graph-engine/src/nodes/color/flattenAlpha.ts
@@ -36,6 +36,6 @@ export default class NodeDefinition extends Node {
const fg = toColor(foreground);
const resultColor = flattenAlpha(fg, bg);
- this.setOutput('value', toColorObject(resultColor));
+ this.outputs.value.set(toColorObject(resultColor));
}
}
diff --git a/packages/graph-engine/src/nodes/color/lighten.ts b/packages/graph-engine/src/nodes/color/lighten.ts
index c30316fb..36e1b8c2 100644
--- a/packages/graph-engine/src/nodes/color/lighten.ts
+++ b/packages/graph-engine/src/nodes/color/lighten.ts
@@ -50,6 +50,6 @@ export default class NodeDefinition extends Node {
sourceColor.oklch.l = newLightness;
const final = toColorObject(sourceColor);
- this.setOutput('value', final);
+ this.outputs.value.set(final);
}
}
diff --git a/packages/graph-engine/src/nodes/color/mix.ts b/packages/graph-engine/src/nodes/color/mix.ts
index 1fbb310e..4f61359b 100644
--- a/packages/graph-engine/src/nodes/color/mix.ts
+++ b/packages/graph-engine/src/nodes/color/mix.ts
@@ -75,6 +75,6 @@ export default class NodeDefinition extends Node {
const converted = Color.mix(colA, colB, mixValue);
const final = toColorObject(converted);
- this.setOutput('value', final);
+ this.outputs.value.set(final);
}
}
diff --git a/packages/graph-engine/src/nodes/color/name.ts b/packages/graph-engine/src/nodes/color/name.ts
index f3da404c..908ec6d7 100644
--- a/packages/graph-engine/src/nodes/color/name.ts
+++ b/packages/graph-engine/src/nodes/color/name.ts
@@ -194,6 +194,6 @@ export default class NodeDefinition extends Node {
};
}
});
- this.setOutput('value', closestName.key);
+ this.outputs.value.set(closestName.key);
}
}
diff --git a/packages/graph-engine/src/nodes/color/poline.ts b/packages/graph-engine/src/nodes/color/poline.ts
index f3f631b8..23f36655 100644
--- a/packages/graph-engine/src/nodes/color/poline.ts
+++ b/packages/graph-engine/src/nodes/color/poline.ts
@@ -110,6 +110,6 @@ export default class NodeDefinition extends Node {
channels: [h, s, l]
};
});
- this.setOutput('value', colors);
+ this.outputs.value.set(colors);
}
}
diff --git a/packages/graph-engine/src/nodes/color/scale.ts b/packages/graph-engine/src/nodes/color/scale.ts
index c393d797..f5cdc524 100644
--- a/packages/graph-engine/src/nodes/color/scale.ts
+++ b/packages/graph-engine/src/nodes/color/scale.ts
@@ -65,6 +65,6 @@ export default class NodeDefinition extends Node {
//Not need to modify
const final = ([] as Color[]).concat(lighter, darker) as Color[];
- this.setOutput('value', final);
+ this.outputs.value.set(final);
}
}
diff --git a/packages/graph-engine/src/nodes/color/sortByDistance.ts b/packages/graph-engine/src/nodes/color/sortByDistance.ts
index 0845320d..3da036d3 100644
--- a/packages/graph-engine/src/nodes/color/sortByDistance.ts
+++ b/packages/graph-engine/src/nodes/color/sortByDistance.ts
@@ -44,6 +44,6 @@ export default class SortByDistanceNode extends Node {
const sortedTokens = sortTokens(colors, compareColor, type, algorithm);
- this.setOutput('value', sortedTokens);
+ this.outputs.value.set(sortedTokens);
}
}
diff --git a/packages/graph-engine/src/nodes/color/stringToColor.ts b/packages/graph-engine/src/nodes/color/stringToColor.ts
index c26bf9bf..da9e1ae5 100644
--- a/packages/graph-engine/src/nodes/color/stringToColor.ts
+++ b/packages/graph-engine/src/nodes/color/stringToColor.ts
@@ -33,6 +33,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { color } = this.getAllInputs();
- this.setOutput('color', toColorObject(new Color(color as string)));
+ this.outputs.color.set(toColorObject(new Color(color as string)));
}
}
diff --git a/packages/graph-engine/src/nodes/color/wheel.ts b/packages/graph-engine/src/nodes/color/wheel.ts
index ec08b7d0..321364a2 100644
--- a/packages/graph-engine/src/nodes/color/wheel.ts
+++ b/packages/graph-engine/src/nodes/color/wheel.ts
@@ -67,6 +67,6 @@ export default class NodeDefinition extends Node {
colorList.push(toColorObject(color));
}
- this.setOutput('value', colorList);
+ this.outputs.value.set(colorList);
}
}
diff --git a/packages/graph-engine/src/nodes/css/box.ts b/packages/graph-engine/src/nodes/css/box.ts
index 2e89196c..331fe738 100644
--- a/packages/graph-engine/src/nodes/css/box.ts
+++ b/packages/graph-engine/src/nodes/css/box.ts
@@ -52,6 +52,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { top, right, bottom, left } = this.getAllInputs();
- this.setOutput('value', `${top} ${right} ${bottom} ${left}`);
+ this.outputs.value.set(`${top} ${right} ${bottom} ${left}`);
}
}
diff --git a/packages/graph-engine/src/nodes/css/cssFunction.ts b/packages/graph-engine/src/nodes/css/cssFunction.ts
index da8c8f47..65384caa 100644
--- a/packages/graph-engine/src/nodes/css/cssFunction.ts
+++ b/packages/graph-engine/src/nodes/css/cssFunction.ts
@@ -38,6 +38,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { functionName, value } = this.getAllInputs();
- this.setOutput('value', functionName.replace('()', `(${value})`));
+ this.outputs.value.set(functionName.replace('()', `(${value})`));
}
}
diff --git a/packages/graph-engine/src/nodes/css/map.ts b/packages/graph-engine/src/nodes/css/map.ts
index 33066b44..edb22b58 100644
--- a/packages/graph-engine/src/nodes/css/map.ts
+++ b/packages/graph-engine/src/nodes/css/map.ts
@@ -35,6 +35,6 @@ export default class NodeDefinition extends Node {
return acc;
}, {});
- this.setOutput('value', output);
+ this.outputs.value.set(output);
}
}
diff --git a/packages/graph-engine/src/nodes/curves/bezier.ts b/packages/graph-engine/src/nodes/curves/bezier.ts
index f4567746..162beeca 100644
--- a/packages/graph-engine/src/nodes/curves/bezier.ts
+++ b/packages/graph-engine/src/nodes/curves/bezier.ts
@@ -77,6 +77,6 @@ export default class BezierCurveNode extends Node {
]
};
- this.setOutput('curve', curve);
+ this.outputs.curve.set(curve);
}
}
diff --git a/packages/graph-engine/src/nodes/curves/constructFloatCurve.ts b/packages/graph-engine/src/nodes/curves/constructFloatCurve.ts
new file mode 100644
index 00000000..175436f3
--- /dev/null
+++ b/packages/graph-engine/src/nodes/curves/constructFloatCurve.ts
@@ -0,0 +1,59 @@
+import {
+ FloatCurve,
+ INodeDefinition,
+ ToInput,
+ ToOutput,
+ Vec2
+} from '../../index.js';
+import { FloatCurveSchema, Vec2Schema } from '../../schemas/index.js';
+import { Node } from '../../programmatic/node.js';
+
+export default class NodeDefinition extends Node {
+ static title = 'Construct Float Curve';
+ static type = 'studio.tokens.curve.constructFloat';
+ static description = 'Constructs a float curve from its parts';
+
+ declare inputs: ToInput<{
+ segments: Vec2[];
+ controlPoints: [Vec2, Vec2][];
+ }>;
+ declare outputs: ToOutput<{
+ curve: FloatCurve;
+ }>;
+
+ constructor(props: INodeDefinition) {
+ super(props);
+
+ this.addInput('segments', {
+ type: {
+ type: 'array',
+ items: Vec2Schema
+ }
+ });
+ this.addInput('controlPoints', {
+ type: {
+ type: 'array',
+ items: {
+ type: 'array',
+ items: Vec2Schema
+ }
+ }
+ });
+ this.addOutput('curve', {
+ type: FloatCurveSchema
+ });
+ }
+
+ execute(): void | Promise {
+ const { segments, controlPoints } = this.getAllInputs();
+
+ if (segments.length !== controlPoints.length + 1) {
+ throw new Error('Segments must be one more than control points');
+ }
+
+ this.outputs.curve.set({
+ controlPoints,
+ segments
+ });
+ }
+}
diff --git a/packages/graph-engine/src/nodes/curves/deconstructFloatCurve.ts b/packages/graph-engine/src/nodes/curves/deconstructFloatCurve.ts
new file mode 100644
index 00000000..7934adb1
--- /dev/null
+++ b/packages/graph-engine/src/nodes/curves/deconstructFloatCurve.ts
@@ -0,0 +1,52 @@
+import {
+ FloatCurve,
+ INodeDefinition,
+ ToInput,
+ ToOutput,
+ Vec2
+} from '../../index.js';
+import { FloatCurveSchema, Vec2Schema } from '../../schemas/index.js';
+import { Node } from '../../programmatic/node.js';
+
+export default class NodeDefinition extends Node {
+ static title = 'Deconstruct Float Curve';
+ static type = 'studio.tokens.curve.deconstructFloat';
+ static description = 'Deconstructs a float curve into its parts';
+
+ declare inputs: ToInput<{
+ curve: FloatCurve;
+ }>;
+ declare outputs: ToOutput<{
+ segments: Vec2[];
+ controlPoints: Vec2[][];
+ }>;
+
+ constructor(props: INodeDefinition) {
+ super(props);
+ this.addInput('curve', {
+ type: FloatCurveSchema
+ });
+ this.addOutput('segments', {
+ type: {
+ type: 'array',
+ items: Vec2Schema
+ }
+ });
+ this.addOutput('controlPoints', {
+ type: {
+ type: 'array',
+ items: {
+ type: 'array',
+ items: Vec2Schema
+ }
+ }
+ });
+ }
+
+ execute(): void | Promise {
+ const { curve } = this.getAllInputs();
+
+ this.outputs.segments.set(curve.segments);
+ this.outputs.controlPoints.set(curve.controlPoints);
+ }
+}
diff --git a/packages/graph-engine/src/nodes/curves/floatCurve.ts b/packages/graph-engine/src/nodes/curves/floatCurve.ts
new file mode 100644
index 00000000..a8357f32
--- /dev/null
+++ b/packages/graph-engine/src/nodes/curves/floatCurve.ts
@@ -0,0 +1,73 @@
+import { FloatCurve, INodeDefinition, ToInput, ToOutput } from '../../index.js';
+import { FloatCurveSchema, NumberSchema } from '../../schemas/index.js';
+import { Node } from '../../programmatic/node.js';
+
+export function cubicBezier(p0, c1, c2, p1, t) {
+ return (
+ (1 - t) ** 3 * p0 +
+ 3 * (1 - t) ** 2 * t * c1 +
+ 3 * (1 - t) * t ** 2 * c2 +
+ t ** 3 * p1
+ );
+}
+export default class NodeDefinition extends Node {
+ static title = 'Sample Float Curve';
+ static type = 'studio.tokens.curve.sampleFloat';
+ static description = 'Evaluates a float curve at a given x value';
+
+ declare inputs: ToInput<{
+ curve: FloatCurve;
+ //We assume this is a normalized value between 0 and 1
+ x: number;
+ }>;
+ declare outputs: ToOutput<{
+ y: number;
+ }>;
+
+ constructor(props: INodeDefinition) {
+ super(props);
+ this.addInput('curve', {
+ type: FloatCurveSchema
+ });
+ this.addInput('x', {
+ type: {
+ ...NumberSchema,
+ minimum: 0,
+ maximum: 1,
+ default: 0
+ }
+ });
+ this.addOutput('y', {
+ type: NumberSchema
+ });
+ }
+
+ execute(): void | Promise {
+ const { curve, x } = this.getAllInputs();
+
+ //Find the segment where the x value lines between the two x values
+
+ const startIndex = curve.segments.findIndex((segment, i) => {
+ const nextSegment = curve.segments[i + 1];
+ return segment[0] <= x && x <= nextSegment[0];
+ });
+ const p0 = curve.segments[startIndex];
+ const p1 = curve.segments[startIndex + 1];
+
+ const [c1, c2] = curve.controlPoints[startIndex];
+
+ const t = (x - p0[0]) / (p1[0] - p0[0]);
+
+ // Cubic Bézier formula
+ const y = cubicBezier(
+ //We need the y values of all of these control points
+ p0[1],
+ c1[1],
+ c2[1],
+ p1[1],
+ t
+ );
+
+ this.outputs.y.set(y);
+ }
+}
diff --git a/packages/graph-engine/src/nodes/curves/index.ts b/packages/graph-engine/src/nodes/curves/index.ts
index 377dcb9b..d30e26a7 100644
--- a/packages/graph-engine/src/nodes/curves/index.ts
+++ b/packages/graph-engine/src/nodes/curves/index.ts
@@ -1,5 +1,15 @@
import bezier from './bezier.js';
+import constructFloatCurve from './constructFloatCurve.js';
+import deconstructFloatCurve from './deconstructFloatCurve.js';
+import floatCurve from './floatCurve.js';
import presetBezier from './presetBeziers.js';
import sample from './sample.js';
-export const nodes = [bezier, presetBezier, sample];
+export const nodes = [
+ bezier,
+ floatCurve,
+ presetBezier,
+ sample,
+ deconstructFloatCurve,
+ constructFloatCurve
+];
diff --git a/packages/graph-engine/src/nodes/curves/presetBeziers.ts b/packages/graph-engine/src/nodes/curves/presetBeziers.ts
index e7864db3..3f3c6770 100644
--- a/packages/graph-engine/src/nodes/curves/presetBeziers.ts
+++ b/packages/graph-engine/src/nodes/curves/presetBeziers.ts
@@ -38,7 +38,7 @@ export default class BezierCurveNode extends Node {
static description = 'Allows you to choose from preset bezier curves';
declare inputs: ToInput<{
- name: string;
+ name: keyof typeof presetBeziers;
}>;
declare outputs: ToOutput<{
@@ -84,6 +84,6 @@ export default class BezierCurveNode extends Node {
]
};
- this.setOutput('curve', curve);
+ this.outputs.curve.set(curve);
}
}
diff --git a/packages/graph-engine/src/nodes/curves/sample.ts b/packages/graph-engine/src/nodes/curves/sample.ts
index 39cddd68..03d45b72 100644
--- a/packages/graph-engine/src/nodes/curves/sample.ts
+++ b/packages/graph-engine/src/nodes/curves/sample.ts
@@ -39,6 +39,8 @@ export default class NodeDefinition extends Node {
* A 2D vector representing the value of the curve at the sample point
*/
value: [number, number];
+ x: number;
+ y: number;
}>;
constructor(props: INodeDefinition) {
@@ -77,8 +79,8 @@ export default class NodeDefinition extends Node {
const output = sampleBezier(foundCurve, sample);
- this.setOutput('value', output);
- this.setOutput('x', output[0]);
- this.setOutput('y', output[1]);
+ this.outputs.value.set(output);
+ this.outputs.x.set(output[0]);
+ this.outputs.y.set(output[1]);
}
}
diff --git a/packages/graph-engine/src/nodes/generic/constant.ts b/packages/graph-engine/src/nodes/generic/constant.ts
index 8d144d84..1e4ee40c 100644
--- a/packages/graph-engine/src/nodes/generic/constant.ts
+++ b/packages/graph-engine/src/nodes/generic/constant.ts
@@ -36,7 +36,7 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const input = this.getRawInput('value');
- this.setOutput('value', input.value, input.type);
+ const input = this.inputs.value;
+ this.outputs.value.set(input.value, input.type);
}
}
diff --git a/packages/graph-engine/src/nodes/generic/delay.ts b/packages/graph-engine/src/nodes/generic/delay.ts
index 405ebc10..9b380d12 100644
--- a/packages/graph-engine/src/nodes/generic/delay.ts
+++ b/packages/graph-engine/src/nodes/generic/delay.ts
@@ -42,11 +42,11 @@ export default class NodeDefinition extends Node {
}
async execute() {
const { delay } = this.getAllInputs();
- const raw = this.getRawInput('value');
+ const raw = this.inputs.value;
return new Promise(resolve => {
setTimeout(() => {
- this.setOutput('value', raw.value, raw.type);
+ this.outputs.value.set(raw.value, raw.type);
resolve();
}, delay);
});
diff --git a/packages/graph-engine/src/nodes/generic/input.ts b/packages/graph-engine/src/nodes/generic/input.ts
index 722ac875..dea9d3e1 100644
--- a/packages/graph-engine/src/nodes/generic/input.ts
+++ b/packages/graph-engine/src/nodes/generic/input.ts
@@ -5,6 +5,7 @@ import {
annotatedDynamicInputs,
annotatedSingleton
} from '../../annotations/index.js';
+import { getAllOutputs } from '@/utils/node.js';
/**
* Acts as an output node for the graph. There can only be a single output node per graph.
@@ -33,7 +34,7 @@ export default class NodeDefinition extends Node {
const node = await super.deserialize(opts);
//Create the outputs immediately
Object.keys(node.inputs).forEach(input => {
- const rawInput = node.getRawInput(input);
+ const rawInput = node.inputs[input];
node.addOutput(input, {
type: rawInput.type
});
@@ -44,21 +45,21 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const inputs = this.getAllInputs();
- const outputs = this.getAllOutputs();
+ const outputs = getAllOutputs(this);
//Passthrough all
Object.keys(inputs).forEach(input => {
- const rawInput = this.getRawInput(input);
+ const rawInput = this.inputs[input];
if (!(input in outputs)) {
this.addOutput(input, {
type: rawInput.type
});
} else {
- this.setOutput(input, rawInput.value, rawInput.type);
+ this.outputs[input].set(rawInput.value, rawInput.type);
}
- this.setOutput(input, rawInput.value, rawInput.type);
+ this.outputs[input].set(rawInput.value, rawInput.type);
});
Object.keys(outputs).forEach(output => {
diff --git a/packages/graph-engine/src/nodes/generic/objectMerge.ts b/packages/graph-engine/src/nodes/generic/objectMerge.ts
index bcd42a5c..3f958dc9 100644
--- a/packages/graph-engine/src/nodes/generic/objectMerge.ts
+++ b/packages/graph-engine/src/nodes/generic/objectMerge.ts
@@ -70,6 +70,6 @@ export default class NodeDefinition extends Node {
}
const flattened = deepMerge.all(objects, opts);
- this.setOutput('value', flattened);
+ this.outputs.value.set(flattened);
}
}
diff --git a/packages/graph-engine/src/nodes/generic/objectProperty.ts b/packages/graph-engine/src/nodes/generic/objectProperty.ts
index 63def988..c176ff8c 100644
--- a/packages/graph-engine/src/nodes/generic/objectProperty.ts
+++ b/packages/graph-engine/src/nodes/generic/objectProperty.ts
@@ -74,11 +74,11 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const object = this.getRawInput('object');
- const path = this.getRawInput('path');
+ const object = this.inputs.object;
+ const path = this.inputs.path;
if (!path.value) {
- this.setOutput('missing', true);
+ this.outputs.missing.set(true);
throw new Error('Path is required');
}
@@ -86,7 +86,7 @@ export default class NodeDefinition extends Node {
const property = getNestedProperty(object.value, path.value);
const schema = getSchemaByPath(object.type, path.value);
- this.setOutput('value', property, schema);
- this.setOutput('missing', property == undefined);
+ this.outputs.value.set(property, schema);
+ this.outputs.missing.set(property == undefined);
}
}
diff --git a/packages/graph-engine/src/nodes/generic/objectify.ts b/packages/graph-engine/src/nodes/generic/objectify.ts
index 90cc4ad2..e5288704 100644
--- a/packages/graph-engine/src/nodes/generic/objectify.ts
+++ b/packages/graph-engine/src/nodes/generic/objectify.ts
@@ -44,6 +44,6 @@ export default class NodeDefinition extends Node {
schema: finalType
}
);
- this.setOutput('value', value, schema);
+ this.outputs.value.set(value, schema);
}
}
diff --git a/packages/graph-engine/src/nodes/generic/output.ts b/packages/graph-engine/src/nodes/generic/output.ts
index 8200bb97..d1ab599f 100644
--- a/packages/graph-engine/src/nodes/generic/output.ts
+++ b/packages/graph-engine/src/nodes/generic/output.ts
@@ -4,6 +4,7 @@ import {
annotatedDynamicInputs,
annotatedSingleton
} from '../../annotations/index.js';
+import { getAllOutputs } from '@/utils/node.js';
/**
* Acts as an output node for the graph. There should only be a single output node per graph.
@@ -24,7 +25,7 @@ export default class NodeDefinition extends Node {
//Create the outputs immediately as we are just a passthrough
Object.keys(node.inputs).forEach(input => {
- const rawInput = node.getRawInput(input);
+ const rawInput = node.inputs[input];
node.addOutput(input, {
visible: false,
type: rawInput.type
@@ -36,11 +37,11 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const inputs = this.getAllInputs();
- const outputs = this.getAllOutputs();
+ const outputs = getAllOutputs(this);
//Passthrough all
Object.keys(inputs).forEach(input => {
- const rawInput = this.getRawInput(input);
+ const rawInput = this.inputs[input];
if (!(input in outputs)) {
this.addOutput(input, {
@@ -49,7 +50,7 @@ export default class NodeDefinition extends Node {
});
}
- this.setOutput(input, rawInput.value, rawInput.type);
+ this.outputs[input].set(rawInput.value, rawInput.type);
});
Object.keys(outputs).forEach(output => {
diff --git a/packages/graph-engine/src/nodes/generic/passthrough.ts b/packages/graph-engine/src/nodes/generic/passthrough.ts
index 06ba2708..265778c7 100644
--- a/packages/graph-engine/src/nodes/generic/passthrough.ts
+++ b/packages/graph-engine/src/nodes/generic/passthrough.ts
@@ -27,7 +27,7 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const input = this.getRawInput('value');
- this.setOutput('value', input.value, input.type);
+ const input = this.inputs.value;
+ this.outputs.value.set(input.value, input.type);
}
}
diff --git a/packages/graph-engine/src/nodes/generic/subgraph.ts b/packages/graph-engine/src/nodes/generic/subgraph.ts
index e315c40d..d9edb3df 100644
--- a/packages/graph-engine/src/nodes/generic/subgraph.ts
+++ b/packages/graph-engine/src/nodes/generic/subgraph.ts
@@ -140,9 +140,9 @@ export default class SubgraphNode extends Node {
async execute() {
const inputs = Object.keys(this.inputs).reduce((acc, key) => {
- this.getRawInput(key);
+ this.inputs[key];
//Todo improve this for typing
- acc[key] = this.getRawInput(key);
+ acc[key] = this.inputs[key];
return acc;
}, {});
@@ -151,7 +151,7 @@ export default class SubgraphNode extends Node {
});
Object.entries(result.output || {}).forEach(([key, value]) => {
- this.setOutput(key, value.value, value.type);
+ this.outputs[key].set(value.value, value.type);
});
}
}
diff --git a/packages/graph-engine/src/nodes/generic/time.ts b/packages/graph-engine/src/nodes/generic/time.ts
index ef2b83b1..78c58082 100644
--- a/packages/graph-engine/src/nodes/generic/time.ts
+++ b/packages/graph-engine/src/nodes/generic/time.ts
@@ -39,6 +39,6 @@ export default class NodeDefinition extends Node {
};
execute(): void | Promise {
- this.setOutput('value', Date.now());
+ this.outputs.value.set(Date.now());
}
}
diff --git a/packages/graph-engine/src/nodes/gradient/gradientStop.ts b/packages/graph-engine/src/nodes/gradient/gradientStop.ts
index 8e192875..b67665e7 100644
--- a/packages/graph-engine/src/nodes/gradient/gradientStop.ts
+++ b/packages/graph-engine/src/nodes/gradient/gradientStop.ts
@@ -26,6 +26,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { color, position } = this.getAllInputs();
- this.setOutput('gradientStop', { color: color, position: position });
+ this.outputs.gradientStop.set({ color: color, position: position });
}
}
diff --git a/packages/graph-engine/src/nodes/logic/and.ts b/packages/graph-engine/src/nodes/logic/and.ts
index 72a09f42..7c7a9152 100644
--- a/packages/graph-engine/src/nodes/logic/and.ts
+++ b/packages/graph-engine/src/nodes/logic/and.ts
@@ -34,8 +34,8 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const inputs = this.getInput('inputs') as number[];
+ const inputs = this.inputs.inputs.value;
const output = inputs.reduce((acc, curr) => acc && !!curr, true);
- this.setOutput('value', output);
+ this.outputs.value.set(output);
}
}
diff --git a/packages/graph-engine/src/nodes/logic/compare.ts b/packages/graph-engine/src/nodes/logic/compare.ts
index cb4bd289..15587792 100644
--- a/packages/graph-engine/src/nodes/logic/compare.ts
+++ b/packages/graph-engine/src/nodes/logic/compare.ts
@@ -72,6 +72,6 @@ export default class NodeDefinition extends Node {
break;
}
- this.setOutput('value', answer);
+ this.outputs.value.set(answer);
}
}
diff --git a/packages/graph-engine/src/nodes/logic/if.ts b/packages/graph-engine/src/nodes/logic/if.ts
index 413e1499..9ad78b77 100644
--- a/packages/graph-engine/src/nodes/logic/if.ts
+++ b/packages/graph-engine/src/nodes/logic/if.ts
@@ -36,11 +36,11 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { condition } = this.getAllInputs();
- const a = this.getRawInput('a');
- const b = this.getRawInput('b');
+ const a = this.inputs.a;
+ const b = this.inputs.b;
const val = condition ? a : b;
- this.setOutput('value', val.value, val.type);
+ this.outputs.value.set(val.value, val.type);
}
}
diff --git a/packages/graph-engine/src/nodes/logic/not.ts b/packages/graph-engine/src/nodes/logic/not.ts
index c4c284a4..b82baed1 100644
--- a/packages/graph-engine/src/nodes/logic/not.ts
+++ b/packages/graph-engine/src/nodes/logic/not.ts
@@ -28,6 +28,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value } = this.getAllInputs();
- this.setOutput('value', !value);
+ this.outputs.value.set(!value);
}
}
diff --git a/packages/graph-engine/src/nodes/logic/or.ts b/packages/graph-engine/src/nodes/logic/or.ts
index 6bc4d31c..4bcf6e52 100644
--- a/packages/graph-engine/src/nodes/logic/or.ts
+++ b/packages/graph-engine/src/nodes/logic/or.ts
@@ -6,13 +6,13 @@ import {
import { INodeDefinition, ToInput, ToOutput } from '../../index.js';
import { Node } from '../../programmatic/node.js';
-export default class NodeDefinition extends Node {
+export default class NodeDefinition extends Node {
static title = 'Logical or';
static type = 'studio.tokens.logic.or';
static description = 'OR node allows you to check if all inputs are true.';
declare inputs: ToInput<{
- value: T;
+ inputs: T[];
}>;
declare outputs: ToOutput<{
@@ -34,8 +34,8 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const inputs = this.getInput('inputs') as number[];
+ const inputs = this.inputs.inputs.value;
const output = inputs.reduce((acc, curr) => acc || !!curr, false);
- this.setOutput('value', output);
+ this.outputs.value.set(output);
}
}
diff --git a/packages/graph-engine/src/nodes/logic/switch.ts b/packages/graph-engine/src/nodes/logic/switch.ts
index b49e4d02..15441423 100644
--- a/packages/graph-engine/src/nodes/logic/switch.ts
+++ b/packages/graph-engine/src/nodes/logic/switch.ts
@@ -56,15 +56,15 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { condition } = this.getAllInputs();
- const defaultVal = this.getRawInput('default');
+ const defaultVal = this.inputs.default;
//Check if an input matches the condition
- if (this.inputs[condition]) {
- const input = this.getRawInput(condition);
- this.setOutput('value', input.value, input.type);
+ if (this.inputs[condition as keyof typeof this.inputs]) {
+ const input = this.inputs[condition as keyof typeof this.inputs];
+ this.outputs.value.set(input.value, input.type);
return;
}
- this.setOutput('value', defaultVal.value, defaultVal.type);
+ this.outputs.value.set(defaultVal.value, defaultVal.type);
}
}
diff --git a/packages/graph-engine/src/nodes/math/abs.ts b/packages/graph-engine/src/nodes/math/abs.ts
index c093e6f7..92c002db 100644
--- a/packages/graph-engine/src/nodes/math/abs.ts
+++ b/packages/graph-engine/src/nodes/math/abs.ts
@@ -33,7 +33,7 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const input = this.getInput('input') as number;
- this.setOutput('value', Math.abs(input));
+ const input = this.inputs.input.value;
+ this.outputs.value.set(Math.abs(input));
}
}
diff --git a/packages/graph-engine/src/nodes/math/add.ts b/packages/graph-engine/src/nodes/math/add.ts
index 738f51e5..7d4f2e94 100644
--- a/packages/graph-engine/src/nodes/math/add.ts
+++ b/packages/graph-engine/src/nodes/math/add.ts
@@ -35,6 +35,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { a, b } = this.getAllInputs();
- this.setOutput('value', a + b);
+ this.outputs.value.set(a + b);
}
}
diff --git a/packages/graph-engine/src/nodes/math/addVariadic.ts b/packages/graph-engine/src/nodes/math/addVariadic.ts
index fd435a44..6b0c4c0e 100644
--- a/packages/graph-engine/src/nodes/math/addVariadic.ts
+++ b/packages/graph-engine/src/nodes/math/addVariadic.ts
@@ -36,8 +36,8 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const inputs = this.getInput('inputs') as number[];
+ const inputs = this.inputs.inputs.value;
const output = inputs.reduce((acc, curr) => acc + curr, 0);
- this.setOutput('value', output);
+ this.outputs.value.set(output);
}
}
diff --git a/packages/graph-engine/src/nodes/math/ceil.ts b/packages/graph-engine/src/nodes/math/ceil.ts
index 1b9408fa..f7eed202 100644
--- a/packages/graph-engine/src/nodes/math/ceil.ts
+++ b/packages/graph-engine/src/nodes/math/ceil.ts
@@ -29,6 +29,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value } = this.getAllInputs();
- this.setOutput('value', Math.ceil(value));
+ this.outputs.value.set(Math.ceil(value));
}
}
diff --git a/packages/graph-engine/src/nodes/math/clamp.ts b/packages/graph-engine/src/nodes/math/clamp.ts
index d8cdc926..2551fe5f 100644
--- a/packages/graph-engine/src/nodes/math/clamp.ts
+++ b/packages/graph-engine/src/nodes/math/clamp.ts
@@ -44,6 +44,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value, min, max } = this.getAllInputs();
- this.setOutput('value', value > max ? max : value < min ? min : value);
+ this.outputs.value.set(value > max ? max : value < min ? min : value);
}
}
diff --git a/packages/graph-engine/src/nodes/math/cos.ts b/packages/graph-engine/src/nodes/math/cos.ts
index 59b02324..9eb7dcb2 100644
--- a/packages/graph-engine/src/nodes/math/cos.ts
+++ b/packages/graph-engine/src/nodes/math/cos.ts
@@ -28,7 +28,6 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const value = this.getInput('value');
- this.setOutput('value', Math.cos(value));
+ this.outputs.value.set(Math.cos(this.inputs.value.value));
}
}
diff --git a/packages/graph-engine/src/nodes/math/count.ts b/packages/graph-engine/src/nodes/math/count.ts
index cfdca0de..fd165c2e 100644
--- a/packages/graph-engine/src/nodes/math/count.ts
+++ b/packages/graph-engine/src/nodes/math/count.ts
@@ -26,7 +26,6 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const value = this.getInput('value');
- this.setOutput('value', value.length);
+ this.outputs.value.set(this.inputs.value.value.length);
}
}
diff --git a/packages/graph-engine/src/nodes/math/divide.ts b/packages/graph-engine/src/nodes/math/divide.ts
index b8af83df..9ea8dd6c 100644
--- a/packages/graph-engine/src/nodes/math/divide.ts
+++ b/packages/graph-engine/src/nodes/math/divide.ts
@@ -28,6 +28,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { a, b } = this.getAllInputs();
- this.setOutput('value', a / b);
+ this.outputs.value.set(a / b);
}
}
diff --git a/packages/graph-engine/src/nodes/math/divideVariadic.ts b/packages/graph-engine/src/nodes/math/divideVariadic.ts
index 5ef9f666..543e5b15 100644
--- a/packages/graph-engine/src/nodes/math/divideVariadic.ts
+++ b/packages/graph-engine/src/nodes/math/divideVariadic.ts
@@ -28,9 +28,8 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const inputs = this.getInput('inputs') as number[];
- const [start, ...rest] = inputs;
+ const [start, ...rest] = this.inputs.inputs.value;
const output = rest.reduce((acc, x) => acc / x, start);
- this.setOutput('value', output);
+ this.outputs.value.set(output);
}
}
diff --git a/packages/graph-engine/src/nodes/math/eval.ts b/packages/graph-engine/src/nodes/math/eval.ts
index 0f5666a3..8aa9d034 100644
--- a/packages/graph-engine/src/nodes/math/eval.ts
+++ b/packages/graph-engine/src/nodes/math/eval.ts
@@ -18,6 +18,7 @@ export default class NodeDefinition extends Node {
}>;
declare outputs: ToOutput<{
+ expression: string;
value: number;
}>;
@@ -45,7 +46,7 @@ export default class NodeDefinition extends Node {
const output = parser.evaluate(expression, inputs);
- this.setOutput('expression', expression);
- this.setOutput('value', output);
+ this.outputs.expression.set(expression);
+ this.outputs.value.set(output);
}
}
diff --git a/packages/graph-engine/src/nodes/math/exp.ts b/packages/graph-engine/src/nodes/math/exp.ts
index 04a99f4e..c2272249 100644
--- a/packages/graph-engine/src/nodes/math/exp.ts
+++ b/packages/graph-engine/src/nodes/math/exp.ts
@@ -27,6 +27,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { exponent } = this.getAllInputs();
- this.setOutput('value', Math.exp(exponent));
+ this.outputs.value.set(Math.exp(exponent));
}
}
diff --git a/packages/graph-engine/src/nodes/math/floor.ts b/packages/graph-engine/src/nodes/math/floor.ts
index c6af7b9c..2d17a831 100644
--- a/packages/graph-engine/src/nodes/math/floor.ts
+++ b/packages/graph-engine/src/nodes/math/floor.ts
@@ -31,6 +31,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value } = this.getAllInputs();
- this.setOutput('value', ~~value);
+ this.outputs.value.set(~~value);
}
}
diff --git a/packages/graph-engine/src/nodes/math/fluid.ts b/packages/graph-engine/src/nodes/math/fluid.ts
index 6fb1cd7c..da72ce32 100644
--- a/packages/graph-engine/src/nodes/math/fluid.ts
+++ b/packages/graph-engine/src/nodes/math/fluid.ts
@@ -51,6 +51,6 @@ export default class NodeDefinition extends Node {
const fluid = (viewport / 100) * fontV + fontR;
const clamped = Math.min(maxSize, Math.max(minSize, fluid));
- this.setOutput('value', clamped);
+ this.outputs.value.set(clamped);
}
}
diff --git a/packages/graph-engine/src/nodes/math/lerp.ts b/packages/graph-engine/src/nodes/math/lerp.ts
index 3ae1b4b2..a6aea638 100644
--- a/packages/graph-engine/src/nodes/math/lerp.ts
+++ b/packages/graph-engine/src/nodes/math/lerp.ts
@@ -45,6 +45,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { a, b, t } = this.getAllInputs();
- this.setOutput('value', a + t * (b - a));
+ this.outputs.value.set(a + t * (b - a));
}
}
diff --git a/packages/graph-engine/src/nodes/math/mod.ts b/packages/graph-engine/src/nodes/math/mod.ts
index c8b8858f..c844af21 100644
--- a/packages/graph-engine/src/nodes/math/mod.ts
+++ b/packages/graph-engine/src/nodes/math/mod.ts
@@ -30,6 +30,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { a, b } = this.getAllInputs();
- this.setOutput('value', a % b);
+ this.outputs.value.set(a % b);
}
}
diff --git a/packages/graph-engine/src/nodes/math/multiply.ts b/packages/graph-engine/src/nodes/math/multiply.ts
index 275dc1a7..11b09a3c 100644
--- a/packages/graph-engine/src/nodes/math/multiply.ts
+++ b/packages/graph-engine/src/nodes/math/multiply.ts
@@ -29,6 +29,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { a, b } = this.getAllInputs();
- this.setOutput('value', a * b);
+ this.outputs.value.set(a * b);
}
}
diff --git a/packages/graph-engine/src/nodes/math/multiplyVariadic.ts b/packages/graph-engine/src/nodes/math/multiplyVariadic.ts
index dac48c0e..48506f71 100644
--- a/packages/graph-engine/src/nodes/math/multiplyVariadic.ts
+++ b/packages/graph-engine/src/nodes/math/multiplyVariadic.ts
@@ -29,8 +29,8 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const inputs = this.getInput('inputs') as number[];
+ const inputs = this.inputs.inputs.value;
const output = inputs.reduce((acc, curr) => acc * curr, 1);
- this.setOutput('value', output);
+ this.outputs.value.set(output);
}
}
diff --git a/packages/graph-engine/src/nodes/math/pow.ts b/packages/graph-engine/src/nodes/math/pow.ts
index 6545f163..85ac4eda 100644
--- a/packages/graph-engine/src/nodes/math/pow.ts
+++ b/packages/graph-engine/src/nodes/math/pow.ts
@@ -34,6 +34,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { base, exponent } = this.getAllInputs();
- this.setOutput('value', Math.pow(base, exponent));
+ this.outputs.value.set(Math.pow(base, exponent));
}
}
diff --git a/packages/graph-engine/src/nodes/math/rangeMapping.ts b/packages/graph-engine/src/nodes/math/rangeMapping.ts
index 2507652d..bb8460b8 100644
--- a/packages/graph-engine/src/nodes/math/rangeMapping.ts
+++ b/packages/graph-engine/src/nodes/math/rangeMapping.ts
@@ -88,6 +88,6 @@ export default class RangeMappingNode extends Node {
);
}
- this.setOutput('mappedValue', mappedValue);
+ this.outputs.mappedValue.set(mappedValue);
}
}
diff --git a/packages/graph-engine/src/nodes/math/round.ts b/packages/graph-engine/src/nodes/math/round.ts
index d1719eb5..79dc3149 100644
--- a/packages/graph-engine/src/nodes/math/round.ts
+++ b/packages/graph-engine/src/nodes/math/round.ts
@@ -39,6 +39,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { precision, value } = this.getAllInputs();
- this.setOutput('value', setToPrecision(value, precision));
+ this.outputs.value.set(setToPrecision(value, precision));
}
}
diff --git a/packages/graph-engine/src/nodes/math/sin.ts b/packages/graph-engine/src/nodes/math/sin.ts
index 64c1ac0c..68bac949 100644
--- a/packages/graph-engine/src/nodes/math/sin.ts
+++ b/packages/graph-engine/src/nodes/math/sin.ts
@@ -28,7 +28,7 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const value = this.getInput('value');
- this.setOutput('value', Math.sin(value));
+ const value = this.inputs.value.value;
+ this.outputs.value.set(Math.sin(value));
}
}
diff --git a/packages/graph-engine/src/nodes/math/sqrt.ts b/packages/graph-engine/src/nodes/math/sqrt.ts
index 256a9e75..c800690a 100644
--- a/packages/graph-engine/src/nodes/math/sqrt.ts
+++ b/packages/graph-engine/src/nodes/math/sqrt.ts
@@ -27,6 +27,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { radicand } = this.getAllInputs();
- this.setOutput('value', Math.sqrt(radicand));
+ this.outputs.value.set(Math.sqrt(radicand));
}
}
diff --git a/packages/graph-engine/src/nodes/math/subtract.ts b/packages/graph-engine/src/nodes/math/subtract.ts
index 62705104..93e0db9a 100644
--- a/packages/graph-engine/src/nodes/math/subtract.ts
+++ b/packages/graph-engine/src/nodes/math/subtract.ts
@@ -29,6 +29,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { a, b } = this.getAllInputs();
- this.setOutput('value', a - b);
+ this.outputs.value.set(a - b);
}
}
diff --git a/packages/graph-engine/src/nodes/math/subtractVariadic.ts b/packages/graph-engine/src/nodes/math/subtractVariadic.ts
index 9a8dc707..b8a50f7e 100644
--- a/packages/graph-engine/src/nodes/math/subtractVariadic.ts
+++ b/packages/graph-engine/src/nodes/math/subtractVariadic.ts
@@ -29,9 +29,9 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const inputs = this.getInput('inputs') as number[];
+ const inputs = this.inputs.inputs.value;
const [start, ...rest] = inputs;
const output = rest.reduce((acc, x) => acc - x, start);
- this.setOutput('value', output);
+ this.outputs.value.set(output);
}
}
diff --git a/packages/graph-engine/src/nodes/math/tan.ts b/packages/graph-engine/src/nodes/math/tan.ts
index aaa28d21..cfb131c9 100644
--- a/packages/graph-engine/src/nodes/math/tan.ts
+++ b/packages/graph-engine/src/nodes/math/tan.ts
@@ -27,7 +27,7 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const value = this.getInput('value');
- this.setOutput('value', Math.tan(value));
+ const value = this.inputs.value.value;
+ this.outputs.value.set(Math.tan(value));
}
}
diff --git a/packages/graph-engine/src/nodes/secret/retrieve.ts b/packages/graph-engine/src/nodes/secret/retrieve.ts
index 437de488..478d157e 100644
--- a/packages/graph-engine/src/nodes/secret/retrieve.ts
+++ b/packages/graph-engine/src/nodes/secret/retrieve.ts
@@ -35,6 +35,6 @@ export default class NodeDefinition extends Node {
const value = await secretCapability.getSecret({ secret, key });
- this.setOutput('value', value);
+ this.outputs.value.set(value);
}
}
diff --git a/packages/graph-engine/src/nodes/series/arithmetic.ts b/packages/graph-engine/src/nodes/series/arithmetic.ts
index cbf5ebd0..387aa927 100644
--- a/packages/graph-engine/src/nodes/series/arithmetic.ts
+++ b/packages/graph-engine/src/nodes/series/arithmetic.ts
@@ -111,10 +111,7 @@ export default class NodeDefinition extends Node {
});
}
- this.setOutput(
- 'array',
- values.map(x => x.value)
- );
- this.setOutput('indexed', values);
+ this.outputs.array.set(values.map(x => x.value));
+ this.outputs.indexed.set(values);
}
}
diff --git a/packages/graph-engine/src/nodes/series/geometric.ts b/packages/graph-engine/src/nodes/series/geometric.ts
index 7c26e913..6b35cb22 100644
--- a/packages/graph-engine/src/nodes/series/geometric.ts
+++ b/packages/graph-engine/src/nodes/series/geometric.ts
@@ -95,10 +95,7 @@ export default class NodeDefinition extends Node {
});
}
- this.setOutput(
- 'array',
- values.map(x => x.value)
- );
- this.setOutput('indexed', values);
+ this.outputs.array.set(values.map(x => x.value));
+ this.outputs.indexed.set(values);
}
}
diff --git a/packages/graph-engine/src/nodes/series/harmonic.ts b/packages/graph-engine/src/nodes/series/harmonic.ts
index 009acb4c..7ae49966 100644
--- a/packages/graph-engine/src/nodes/series/harmonic.ts
+++ b/packages/graph-engine/src/nodes/series/harmonic.ts
@@ -103,10 +103,7 @@ export default class NodeDefinition extends Node {
});
}
- this.setOutput(
- 'array',
- values.map(x => x.value)
- );
- this.setOutput('indexed', values);
+ this.outputs.array.set(values.map(x => x.value));
+ this.outputs.indexed.set(values);
}
}
diff --git a/packages/graph-engine/src/nodes/string/interpolate.ts b/packages/graph-engine/src/nodes/string/interpolate.ts
index 7cbdd6bf..fbf80034 100644
--- a/packages/graph-engine/src/nodes/string/interpolate.ts
+++ b/packages/graph-engine/src/nodes/string/interpolate.ts
@@ -49,7 +49,7 @@ export default class StringInterpolationNode extends Node {
}
);
- this.setOutput('value', interpolatedString);
+ this.outputs.value.set(interpolatedString);
} catch (error) {
this.error = new Error(
`Error during string interpolation: ${(error as Error).message}`
diff --git a/packages/graph-engine/src/nodes/string/join.ts b/packages/graph-engine/src/nodes/string/join.ts
index 415599b6..cb2b63a9 100644
--- a/packages/graph-engine/src/nodes/string/join.ts
+++ b/packages/graph-engine/src/nodes/string/join.ts
@@ -34,6 +34,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { delimiter, array } = this.getAllInputs();
- this.setOutput('value', array.join(delimiter));
+ this.outputs.value.set(array.join(delimiter));
}
}
diff --git a/packages/graph-engine/src/nodes/string/lowercase.ts b/packages/graph-engine/src/nodes/string/lowercase.ts
index 276537c6..430e78c9 100644
--- a/packages/graph-engine/src/nodes/string/lowercase.ts
+++ b/packages/graph-engine/src/nodes/string/lowercase.ts
@@ -29,6 +29,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value } = this.getAllInputs();
- this.setOutput('value', value.toLowerCase());
+ this.outputs.value.set(value.toLowerCase());
}
}
diff --git a/packages/graph-engine/src/nodes/string/pad.ts b/packages/graph-engine/src/nodes/string/pad.ts
index 3bf03187..890e93b8 100644
--- a/packages/graph-engine/src/nodes/string/pad.ts
+++ b/packages/graph-engine/src/nodes/string/pad.ts
@@ -59,6 +59,6 @@ export default class NodeDefinition extends Node {
paddedString = string.padEnd(length, character[0]);
}
- this.setOutput('string', paddedString);
+ this.outputs.string.set(paddedString);
}
}
diff --git a/packages/graph-engine/src/nodes/string/regex.ts b/packages/graph-engine/src/nodes/string/regex.ts
index 6646135e..6ea79027 100644
--- a/packages/graph-engine/src/nodes/string/regex.ts
+++ b/packages/graph-engine/src/nodes/string/regex.ts
@@ -53,6 +53,6 @@ export default class NodeDefinition extends Node {
const regex = new RegExp(match, flags);
const output = input.replace(regex, replace);
- this.setOutput('value', output);
+ this.outputs.value.set(output);
}
}
diff --git a/packages/graph-engine/src/nodes/string/split.ts b/packages/graph-engine/src/nodes/string/split.ts
index e53e8a30..a405bb37 100644
--- a/packages/graph-engine/src/nodes/string/split.ts
+++ b/packages/graph-engine/src/nodes/string/split.ts
@@ -12,7 +12,7 @@ export default class NodeDefinition extends Node {
separator: string;
}>;
declare outputs: ToOutput<{
- value: string;
+ value: string[];
}>;
static description = 'Converts a string to lowercase';
constructor(props: INodeDefinition) {
@@ -34,9 +34,9 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value, separator } = this.getAllInputs();
if (separator === undefined) {
- this.setOutput('value', [value]);
+ this.outputs.value.set([value]);
} else {
- this.setOutput('value', value.split(separator));
+ this.outputs.value.set(value.split(separator));
}
}
}
diff --git a/packages/graph-engine/src/nodes/string/stringify.ts b/packages/graph-engine/src/nodes/string/stringify.ts
index 8346b245..4f9c2422 100644
--- a/packages/graph-engine/src/nodes/string/stringify.ts
+++ b/packages/graph-engine/src/nodes/string/stringify.ts
@@ -26,6 +26,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value } = this.getAllInputs();
- this.setOutput('value', '' + value);
+ this.outputs.value.set('' + value);
}
}
diff --git a/packages/graph-engine/src/nodes/string/uppercase.ts b/packages/graph-engine/src/nodes/string/uppercase.ts
index a264057f..0a55c6e8 100644
--- a/packages/graph-engine/src/nodes/string/uppercase.ts
+++ b/packages/graph-engine/src/nodes/string/uppercase.ts
@@ -26,6 +26,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value } = this.getAllInputs();
- this.setOutput('value', value.toUpperCase());
+ this.outputs.value.set(value.toUpperCase());
}
}
diff --git a/packages/graph-engine/src/nodes/typing/assertDefined.ts b/packages/graph-engine/src/nodes/typing/assertDefined.ts
index 3894d30f..9c296ccb 100644
--- a/packages/graph-engine/src/nodes/typing/assertDefined.ts
+++ b/packages/graph-engine/src/nodes/typing/assertDefined.ts
@@ -26,10 +26,10 @@ export default class NodeDefinition extends Node {
}
execute(): void | Promise {
- const value = this.getRawInput('value');
+ const value = this.inputs.value;
if (value.value === undefined) {
throw new Error('Value is required');
}
- this.setOutput('value', value, value.type);
+ this.outputs.value.set(value, value.type);
}
}
diff --git a/packages/graph-engine/src/nodes/typing/hasValue.ts b/packages/graph-engine/src/nodes/typing/hasValue.ts
index 558aaa53..b689fa53 100644
--- a/packages/graph-engine/src/nodes/typing/hasValue.ts
+++ b/packages/graph-engine/src/nodes/typing/hasValue.ts
@@ -28,6 +28,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value } = this.getAllInputs();
- this.setOutput('undefined', value === null || value === undefined);
+ this.outputs.undefined.set(value === null || value === undefined);
}
}
diff --git a/packages/graph-engine/src/nodes/typing/parseUnit.ts b/packages/graph-engine/src/nodes/typing/parseUnit.ts
index 16a4b2a8..5add2c5b 100644
--- a/packages/graph-engine/src/nodes/typing/parseUnit.ts
+++ b/packages/graph-engine/src/nodes/typing/parseUnit.ts
@@ -37,12 +37,12 @@ export default class NodeDefinition extends Node {
const x = valueParser.unit(value);
if (!x) {
- this.setOutput('number', 0);
- this.setOutput('unit', '');
+ this.outputs.number.set(0);
+ this.outputs.unit.set('');
return;
}
- this.setOutput('number', x.number);
- this.setOutput('unit', x.unit);
+ this.outputs.number.set(Number.parseFloat(x.number));
+ this.outputs.unit.set(x.unit);
}
}
diff --git a/packages/graph-engine/src/nodes/typing/passUnit.ts b/packages/graph-engine/src/nodes/typing/passUnit.ts
index 1c93a2d9..941c2967 100644
--- a/packages/graph-engine/src/nodes/typing/passUnit.ts
+++ b/packages/graph-engine/src/nodes/typing/passUnit.ts
@@ -41,9 +41,9 @@ export default class NodeDefinition extends Node {
}
if (x.unit) {
- this.setOutput('value', value);
+ this.outputs.value.set(value);
} else {
- this.setOutput('value', `${value}${fallback || ''}`);
+ this.outputs.value.set(`${value}${fallback || ''}`);
}
}
}
diff --git a/packages/graph-engine/src/nodes/typography/baseFontSize.ts b/packages/graph-engine/src/nodes/typography/baseFontSize.ts
index 1d958c66..7834e22a 100644
--- a/packages/graph-engine/src/nodes/typography/baseFontSize.ts
+++ b/packages/graph-engine/src/nodes/typography/baseFontSize.ts
@@ -18,6 +18,7 @@ export default class NodeDefinition extends Node {
xHeightRatio: number;
ppi: number;
pixelDensity: number;
+ precision: number;
}>;
declare outputs: ToOutput<{
@@ -107,6 +108,6 @@ export default class NodeDefinition extends Node {
const xHeightPX = (xHeightMM / 25.4) * (ppi / pixelDensity);
const fontSizePX = (1 * xHeightPX) / xHeightRatio;
- this.setOutput('value', setToPrecision(fontSizePX, precision));
+ this.outputs.value.set(setToPrecision(fontSizePX, precision));
}
}
diff --git a/packages/graph-engine/src/nodes/vector2/create.ts b/packages/graph-engine/src/nodes/vector2/create.ts
index 45f4c307..5cd0bf0c 100644
--- a/packages/graph-engine/src/nodes/vector2/create.ts
+++ b/packages/graph-engine/src/nodes/vector2/create.ts
@@ -10,7 +10,7 @@ export default class NodeDefinition extends Node {
declare inputs: ToInput<{
x: number;
- y: string;
+ y: number;
}>;
declare outputs: ToOutput<{
@@ -33,6 +33,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { x, y } = this.getAllInputs();
- this.setOutput('value', [x, y]);
+ this.outputs.value.set([x, y]);
}
}
diff --git a/packages/graph-engine/src/nodes/vector2/destructure.ts b/packages/graph-engine/src/nodes/vector2/destructure.ts
index e9d1917a..f2748986 100644
--- a/packages/graph-engine/src/nodes/vector2/destructure.ts
+++ b/packages/graph-engine/src/nodes/vector2/destructure.ts
@@ -15,7 +15,7 @@ export default class NodeDefinition extends Node {
declare outputs: ToOutput<{
x: number;
- y: string;
+ y: number;
}>;
constructor(props: INodeDefinition) {
@@ -34,7 +34,7 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { value } = this.getAllInputs();
- this.setOutput('x', value[0]);
- this.setOutput('y', value[1]);
+ this.outputs.x.set(value[0]);
+ this.outputs.y.set(value[1]);
}
}
diff --git a/packages/graph-engine/src/programmatic/node.ts b/packages/graph-engine/src/programmatic/node.ts
index a2e5c8e1..31b2cdde 100644
--- a/packages/graph-engine/src/programmatic/node.ts
+++ b/packages/graph-engine/src/programmatic/node.ts
@@ -33,6 +33,18 @@ export interface TypeDefinition {
annotations?: Record;
}
+// Helper type to preserve literal types
+type Prettify = {
+ [K in keyof T]: T[K];
+ // eslint-disable-next-line @typescript-eslint/ban-types
+} & {};
+
+type InputValue = T extends Input ? U : never;
+// Updated UnwrapInput type
+type UnwrapInput = Prettify<{
+ [K in keyof T]: InputValue;
+}>;
+
export class Node {
/**
* Unique instance specific identifier
@@ -325,18 +337,10 @@ export class Node {
return this.type;
};
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- getAllInputs = >(): T => {
+ getAllInputs = (): UnwrapInput => {
return Object.fromEntries(
Object.entries(this.inputs).map(([key, value]) => [key, value.value])
- ) as T;
- };
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- getAllOutputs = >(): T => {
- return Object.fromEntries(
- Object.entries(this.outputs).map(([key, value]) => [key, value.value])
- ) as T;
+ ) as UnwrapInput;
};
/**
@@ -361,33 +365,6 @@ export class Node {
this._graph = undefined;
};
- /**
- * Set the output of the node
- * @param name
- * @param value
- * @param type
- */
-
- protected setOutput = (name: string, value: unknown, type?: GraphSchema) => {
- this.outputs[name]?.set(value, type);
- };
-
- protected getInput = (name: string) => {
- return this.inputs[name].value;
- };
- public getRawInput = (name: string) => {
- return this.inputs[name];
- };
- /**
- * Returns a JSON representation of the output values without calculating them
- * @returns
- */
- public getOutput() {
- return Object.fromEntries(
- Object.entries(this.outputs).map(([key, value]) => [key, value.value()])
- );
- }
-
/**
* Function to call when the graph has been started.
* This is only really necessary for nodes that need to do something when the graph is expected to be running continuously
diff --git a/packages/graph-engine/src/programmatic/port.ts b/packages/graph-engine/src/programmatic/port.ts
index 1b5f12a5..99bec7d6 100644
--- a/packages/graph-engine/src/programmatic/port.ts
+++ b/packages/graph-engine/src/programmatic/port.ts
@@ -62,7 +62,7 @@ export class Port {
get dynamicType() {
return this._dynamicType;
}
- get value() {
+ get value(): T {
return this._value;
}
diff --git a/packages/graph-engine/src/schemas/index.ts b/packages/graph-engine/src/schemas/index.ts
index 56260435..59c45825 100644
--- a/packages/graph-engine/src/schemas/index.ts
+++ b/packages/graph-engine/src/schemas/index.ts
@@ -99,6 +99,58 @@ export const ObjectSchema: SchemaObject = {
type: 'object'
};
+export const FLOATCURVE = 'https://schemas.tokens.studio/floatCurve.json';
+export const FloatCurveSchema: SchemaObject = {
+ $id: FLOATCURVE,
+ title: 'Float curve',
+ type: 'object',
+ default: {
+ controlPoints: [
+ [
+ [0.25, 0.25],
+ [0.75, 0.75]
+ ]
+ ],
+ segments: [
+ [0, 0],
+ [1, 1]
+ ]
+ },
+ properties: {
+ segments: {
+ type: 'array',
+ items: {
+ type: 'array',
+ items: {
+ type: 'array',
+ items: [
+ {
+ type: 'number'
+ },
+ {
+ type: 'number'
+ }
+ ]
+ }
+ }
+ },
+ controlPoints: {
+ type: 'array',
+ items: {
+ type: 'array',
+ items: [
+ {
+ type: 'number'
+ },
+ {
+ type: 'number'
+ }
+ ]
+ }
+ }
+ }
+};
+
export const CURVE = 'https://schemas.tokens.studio/curve.json';
export const CurveSchema: SchemaObject = {
$id: CURVE,
@@ -355,6 +407,7 @@ export const convertSchemaType = (
export type GraphSchema = SchemaObject;
export const AllSchemas = [
+ FloatCurveSchema,
NumberSchema,
StringSchema,
ColorSchema,
diff --git a/packages/graph-engine/src/types.ts b/packages/graph-engine/src/types.ts
index 3df18cae..734f7af7 100644
--- a/packages/graph-engine/src/types.ts
+++ b/packages/graph-engine/src/types.ts
@@ -38,6 +38,13 @@ export type NodeRun = {
end: number;
};
+export type FloatCurve = {
+ //The length of the control points array is always one less than the segments
+ controlPoints: [Vec2, Vec2][];
+ //The segments stored as monotonicly increasing x values
+ segments: Vec2[];
+};
+
export type Vec2 = [number, number];
export type Vec3 = [number, number, number];
//Alias for now, will be replaced with a proper type
diff --git a/packages/graph-engine/src/utils/node.ts b/packages/graph-engine/src/utils/node.ts
new file mode 100644
index 00000000..9a5ce72b
--- /dev/null
+++ b/packages/graph-engine/src/utils/node.ts
@@ -0,0 +1,14 @@
+import { Node } from '@/programmatic/node.js';
+import { Output } from '@/programmatic/output.js';
+
+type OutputValue = T extends Output ? U : never;
+
+type UnwrapOutput = {
+ [K in keyof T]: OutputValue;
+};
+
+export const getAllOutputs = (node: T) => {
+ return Object.fromEntries(
+ Object.entries(node.outputs).map(([key, value]) => [key, value.value])
+ ) as UnwrapOutput;
+};
diff --git a/packages/graph-engine/tests/suites/nodes/color/contrasting.test.ts b/packages/graph-engine/tests/suites/nodes/color/contrasting.test.ts
index 6b094bf1..8cc740ad 100644
--- a/packages/graph-engine/tests/suites/nodes/color/contrasting.test.ts
+++ b/packages/graph-engine/tests/suites/nodes/color/contrasting.test.ts
@@ -1,7 +1,7 @@
import { ContrastAlgorithm } from '../../../../src/types/index.js';
import { Graph } from '../../../../src/graph/graph.js';
import { describe, expect, test } from 'vitest';
-import { getAllOutputs } from '../utils.js';
+import { getAllOutputs } from '../../../../src/utils/node.js';
import Node from '../../../../src/nodes/color/contrasting.js';
describe('color/contrasting', () => {
diff --git a/packages/graph-engine/tests/suites/nodes/color/convert.test.ts b/packages/graph-engine/tests/suites/nodes/color/convert.test.ts
index 8a6fa4e7..98415e20 100644
--- a/packages/graph-engine/tests/suites/nodes/color/convert.test.ts
+++ b/packages/graph-engine/tests/suites/nodes/color/convert.test.ts
@@ -1,6 +1,6 @@
import { Graph } from '../../../../src/graph/graph.js';
import { describe, expect, test } from 'vitest';
-import { getAllOutputs } from '../utils.js';
+import { getAllOutputs } from '../../../../src/utils/node.js';
import Node from '../../../../src/nodes/color/convert.js';
describe('color/convert', () => {
diff --git a/packages/graph-engine/tests/suites/nodes/utils.ts b/packages/graph-engine/tests/suites/nodes/utils.ts
deleted file mode 100644
index f7a92023..00000000
--- a/packages/graph-engine/tests/suites/nodes/utils.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Node } from '../../../src/programmatic/node.js';
-
-export const getAllOutputs = (node: Node) => {
- const outputs = {};
- Object.keys(node.outputs).forEach(key => {
- outputs[key] = node.outputs[key].value;
- });
- return outputs;
-};
diff --git a/packages/nodes-audio/src/nodes/connect.ts b/packages/nodes-audio/src/nodes/connect.ts
index d4718087..225d3771 100644
--- a/packages/nodes-audio/src/nodes/connect.ts
+++ b/packages/nodes-audio/src/nodes/connect.ts
@@ -1,19 +1,20 @@
import { AudioBaseNode } from './base.js';
import {
INodeDefinition,
+ ToInput,
createVariadicSchema
} from '@tokens-studio/graph-engine';
import { NodeSchema } from '../schemas/index.js';
-type inputs = {
- source: AudioNode[];
- destination: AudioNode;
-};
-
export class AudioConnectNode extends AudioBaseNode {
static title = 'Audio Connect node';
static type = 'studio.tokens.audio.connect';
+ declare inputs: ToInput<{
+ source: AudioNode[];
+ destination: AudioNode;
+ }>;
+
static description = 'An explicit connection between audio nodes';
constructor(props: INodeDefinition) {
super(props);
@@ -33,13 +34,13 @@ export class AudioConnectNode extends AudioBaseNode {
}
execute(): void | Promise {
- const { destination, source } = this.getAllInputs();
+ const { destination, source } = this.getAllInputs();
source.map(sourceNode => {
sourceNode.disconnect();
sourceNode.connect(destination);
});
- this.setOutput('destination', destination);
+ this.outputs.destination.set(destination);
}
}
diff --git a/packages/nodes-audio/src/nodes/delay.ts b/packages/nodes-audio/src/nodes/delay.ts
index 517fad68..b76d720f 100644
--- a/packages/nodes-audio/src/nodes/delay.ts
+++ b/packages/nodes-audio/src/nodes/delay.ts
@@ -6,11 +6,6 @@ import {
} from '@tokens-studio/graph-engine';
import { NodeSchema } from '../schemas/index.js';
-type inputs = {
- delay: number;
- input: AudioNode | undefined;
-};
-
export class AudioDelayNode extends AudioBaseNode {
static title = 'Audio Delay node';
static type = 'studio.tokens.audio.delay';
@@ -18,7 +13,10 @@ export class AudioDelayNode extends AudioBaseNode {
audioNode: DelayNode | undefined;
_last: AudioNode | undefined;
- declare inputs: ToInput;
+ declare inputs: ToInput<{
+ delay: number;
+ input: AudioNode | undefined;
+ }>;
static description = 'Modifies an audio source to provide delay.';
constructor(props: INodeDefinition) {
super(props);
@@ -50,7 +48,7 @@ export class AudioDelayNode extends AudioBaseNode {
execute(): void | Promise {
const context = this.getAudioCtx();
- const { input, delay } = this.getAllInputs();
+ const { input, delay } = this.getAllInputs();
if (!this.audioNode) {
this.audioNode = context.createDelay(delay);
@@ -67,6 +65,6 @@ export class AudioDelayNode extends AudioBaseNode {
}
this.audioNode.delayTime.setValueAtTime(delay, context.currentTime);
- this.setOutput('node', this.audioNode);
+ this.outputs.node.set(this.audioNode);
}
}
diff --git a/packages/nodes-audio/src/nodes/gain.ts b/packages/nodes-audio/src/nodes/gain.ts
index af2d3812..58c247ef 100644
--- a/packages/nodes-audio/src/nodes/gain.ts
+++ b/packages/nodes-audio/src/nodes/gain.ts
@@ -3,11 +3,6 @@ import { INodeDefinition, NumberSchema } from '@tokens-studio/graph-engine';
import { NodeSchema } from '../schemas/index.js';
import type { ToInput } from '@tokens-studio/graph-engine';
-type inputs = {
- gain: number;
- input: AudioNode | undefined;
-};
-
export class AudioGainNode extends AudioBaseNode {
static title = 'Audio Gain node';
static type = 'studio.tokens.audio.gain';
@@ -15,7 +10,10 @@ export class AudioGainNode extends AudioBaseNode {
gainNode: GainNode | undefined;
_last: AudioNode | undefined;
- declare inputs: ToInput;
+ declare inputs: ToInput<{
+ gain: number;
+ input: AudioNode | undefined;
+ }>;
static description =
'Modifies an audio source to provide a gain (volume) control.';
constructor(props: INodeDefinition) {
@@ -47,7 +45,7 @@ export class AudioGainNode extends AudioBaseNode {
}
execute(): void | Promise {
- const { gain, input } = this.getAllInputs();
+ const { gain, input } = this.getAllInputs();
const context = this.getAudioCtx();
@@ -67,6 +65,6 @@ export class AudioGainNode extends AudioBaseNode {
this._last = input;
}
- this.setOutput('node', this.gainNode);
+ this.outputs.node.set(this.gainNode);
}
}
diff --git a/packages/nodes-audio/src/nodes/loadBuffer.ts b/packages/nodes-audio/src/nodes/loadBuffer.ts
index 6e82cb0a..cad995a3 100644
--- a/packages/nodes-audio/src/nodes/loadBuffer.ts
+++ b/packages/nodes-audio/src/nodes/loadBuffer.ts
@@ -6,15 +6,13 @@ import {
import { AudioBaseNode } from './base.js';
import { AudioBufferSchema } from '../schemas/index.js';
-export type inputs = {
- resource: Buffer;
-};
-
export class AudioLoadBufferNode extends AudioBaseNode {
static title = 'Audio Load Buffer node';
static type = 'studio.tokens.audio.loadBuffer';
- declare inputs: ToInput;
+ declare inputs: ToInput<{
+ resource: Buffer;
+ }>;
static description = 'Converts a buffer to an audio buffer';
constructor(props: INodeDefinition) {
@@ -30,14 +28,14 @@ export class AudioLoadBufferNode extends AudioBaseNode {
}
execute(): void | Promise {
- const { resource } = this.getAllInputs();
+ const { resource } = this.getAllInputs();
const context = this.getAudioCtx();
return new Promise((resolve, reject) => {
context.decodeAudioData(resource.buffer, res => {
try {
- this.setOutput('buffer', res);
+ this.outputs.buffer.set(res);
resolve();
} catch (err) {
reject(err);
diff --git a/packages/nodes-audio/src/nodes/oscillator.ts b/packages/nodes-audio/src/nodes/oscillator.ts
index 35cef5d4..d1029d75 100644
--- a/packages/nodes-audio/src/nodes/oscillator.ts
+++ b/packages/nodes-audio/src/nodes/oscillator.ts
@@ -66,7 +66,7 @@ export class AudioOscillatorNode extends AudioBaseNode {
);
}
- this.setOutput('node', this.audioNode);
+ this.outputs.node.set(this.audioNode);
}
onStart = () => {
diff --git a/packages/nodes-audio/src/nodes/source.ts b/packages/nodes-audio/src/nodes/source.ts
index b3c6394c..f413fc4c 100644
--- a/packages/nodes-audio/src/nodes/source.ts
+++ b/packages/nodes-audio/src/nodes/source.ts
@@ -6,14 +6,6 @@ import {
ToInput
} from '@tokens-studio/graph-engine';
-type inputs = {
- /**
- * The audio buffer
- */
- buffer: AudioBuffer;
- loop?: boolean;
-};
-
export class AudioSourceNode extends AudioBaseNode {
static title = 'Audio Source node';
static type = 'studio.tokens.audio.source';
@@ -21,7 +13,13 @@ export class AudioSourceNode extends AudioBaseNode {
audioNode: GainNode | undefined;
bufferNode: AudioBufferSourceNode | undefined;
- declare inputs: ToInput;
+ declare inputs: ToInput<{
+ /**
+ * The audio buffer
+ */
+ buffer: AudioBuffer;
+ loop?: boolean;
+ }>;
_values: { buffer?: AudioBuffer; loop?: boolean } = {};
@@ -46,7 +44,7 @@ export class AudioSourceNode extends AudioBaseNode {
async execute(): Promise {
const context = this.getAudioCtx();
- const { buffer, loop } = this.getAllInputs();
+ const { buffer, loop } = this.getAllInputs();
this._values = { buffer, loop };
@@ -54,7 +52,7 @@ export class AudioSourceNode extends AudioBaseNode {
this.audioNode = context.createGain();
}
- this.setOutput('node', this.audioNode);
+ this.outputs.node.set(this.audioNode);
}
onStart = () => {
diff --git a/packages/nodes-audio/src/nodes/whiteNoise.ts b/packages/nodes-audio/src/nodes/whiteNoise.ts
index 0ab47739..f3d8bd3c 100644
--- a/packages/nodes-audio/src/nodes/whiteNoise.ts
+++ b/packages/nodes-audio/src/nodes/whiteNoise.ts
@@ -6,22 +6,20 @@ import {
ToInput
} from '@tokens-studio/graph-engine';
-type inputs = {
- /**
- * The length of the sample
- */
- length: number;
- /**
- * The number of channels
- */
- channels: number;
-};
-
export class AudioWhiteNoiseNode extends AudioBaseNode {
static title = 'Audio whitenoise';
static type = 'studio.tokens.audio.whiteNoise';
- declare inputs: ToInput;
+ declare inputs: ToInput<{
+ /**
+ * The length of the sample
+ */
+ length: number;
+ /**
+ * The number of channels
+ */
+ channels: number;
+ }>;
constructor(props: INodeDefinition) {
super(props);
@@ -48,7 +46,7 @@ export class AudioWhiteNoiseNode extends AudioBaseNode {
async execute(): Promise {
const context = this.getAudioCtx();
- const { channels, length } = this.getAllInputs();
+ const { channels, length } = this.getAllInputs();
const buffer = context.createBuffer(
channels,
@@ -66,6 +64,6 @@ export class AudioWhiteNoiseNode extends AudioBaseNode {
}
}
- this.setOutput('buffer', buffer);
+ this.outputs.buffer.set(buffer);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/arrayToSet.ts b/packages/nodes-design-tokens/src/nodes/arrayToSet.ts
index f7dd9b33..af325715 100644
--- a/packages/nodes-design-tokens/src/nodes/arrayToSet.ts
+++ b/packages/nodes-design-tokens/src/nodes/arrayToSet.ts
@@ -13,6 +13,7 @@ export default class ArrayToSetNode extends Node {
static title = 'Array of Tokens to Set';
static type = 'studio.tokens.design.arrayToSet';
static description = 'Converts an array of tokens to a set';
+
constructor(props: INodeDefinition) {
super(props);
this.addInput('tokens', {
@@ -31,10 +32,10 @@ export default class ArrayToSetNode extends Node {
}>;
execute(): void | Promise {
- const tokens = this.getInput('tokens');
+ const tokens = this.inputs.tokens.value;
const asSet = flatTokensRestoreToMap(tokens as IResolvedToken[]);
- this.setOutput('tokenSet', asSet);
+ this.outputs.tokenSet.set(asSet);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/create.ts b/packages/nodes-design-tokens/src/nodes/create.ts
index 8530775c..09ee2519 100644
--- a/packages/nodes-design-tokens/src/nodes/create.ts
+++ b/packages/nodes-design-tokens/src/nodes/create.ts
@@ -57,7 +57,7 @@ export default class NodeDefinition extends Node {
this.addInput('$extensions', {
type: {
...ObjectSchema,
- default: undefined
+ default: null
}
});
@@ -78,6 +78,7 @@ export default class NodeDefinition extends Node {
throw new Error('Type is required');
}
- this.setOutput('token', props);
+ //@ts-expect-error
+ this.outputs.token.set(props);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/createBorder.ts b/packages/nodes-design-tokens/src/nodes/createBorder.ts
index aef7472d..7c745c2c 100644
--- a/packages/nodes-design-tokens/src/nodes/createBorder.ts
+++ b/packages/nodes-design-tokens/src/nodes/createBorder.ts
@@ -42,6 +42,6 @@ export default class CreateBorderNode extends Node {
execute(): void | Promise {
const props = this.getAllInputs();
- this.setOutput('value', props);
+ this.outputs.token.set(props as TokenBorderValue);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/createBorderToken.ts b/packages/nodes-design-tokens/src/nodes/createBorderToken.ts
index 9a664424..5ebab058 100644
--- a/packages/nodes-design-tokens/src/nodes/createBorderToken.ts
+++ b/packages/nodes-design-tokens/src/nodes/createBorderToken.ts
@@ -9,7 +9,11 @@ import {
import { TokenBorderSchema, TokenSchema } from '../schemas/index.js';
import { TokenTypes } from '@tokens-studio/types';
import { arrayOf } from '../schemas/utils.js';
-import type { SingleToken, TokenBorderValue } from '@tokens-studio/types';
+import type {
+ SingleBorderToken,
+ SingleToken,
+ TokenBorderValue
+} from '@tokens-studio/types';
export default class NodeDefinition extends Node {
static title = 'Create Border Design Token';
@@ -67,19 +71,19 @@ export default class NodeDefinition extends Node {
const obj = {
name,
type: TokenTypes.BORDER,
- value: undefined,
+ value: [] as TokenBorderValue[],
description,
$extensions
- };
+ } as SingleBorderToken;
if (value) {
- obj.value = value;
+ obj.value = value as TokenBorderValue;
} else if (reference) {
- obj.value = reference;
+ obj.value = reference as TokenBorderValue;
} else {
throw new Error('Value or reference is required');
}
- this.setOutput('token', obj);
+ this.outputs.token.set(obj);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/createBoxShadow.ts b/packages/nodes-design-tokens/src/nodes/createBoxShadow.ts
index 9799aee8..6da520f4 100644
--- a/packages/nodes-design-tokens/src/nodes/createBoxShadow.ts
+++ b/packages/nodes-design-tokens/src/nodes/createBoxShadow.ts
@@ -23,7 +23,7 @@ export default class CreateBoxShadowNode extends Node {
}>;
declare outputs: ToOutput<{
- token: TokenBoxshadowValue;
+ value: TokenBoxshadowValue;
}>;
constructor(props: INodeDefinition) {
@@ -53,6 +53,6 @@ export default class CreateBoxShadowNode extends Node {
execute(): void | Promise {
const props = this.getAllInputs();
- this.setOutput('value', props);
+ this.outputs.value.set(props as TokenBoxshadowValue);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/createBoxShadowToken.ts b/packages/nodes-design-tokens/src/nodes/createBoxShadowToken.ts
index e3d69c31..b2cf68ad 100644
--- a/packages/nodes-design-tokens/src/nodes/createBoxShadowToken.ts
+++ b/packages/nodes-design-tokens/src/nodes/createBoxShadowToken.ts
@@ -9,7 +9,11 @@ import {
import { TokenBoxShadowSchema, TokenSchema } from '../schemas/index.js';
import { TokenTypes } from '@tokens-studio/types';
import { arrayOf } from '../schemas/utils.js';
-import type { SingleToken, TokenBoxshadowValue } from '@tokens-studio/types';
+import type {
+ SingleBoxShadowToken,
+ SingleToken,
+ TokenBoxshadowValue
+} from '@tokens-studio/types';
export default class NodeDefinition extends Node {
static title = 'Create Box Shadow Design Token';
@@ -68,10 +72,10 @@ export default class NodeDefinition extends Node {
const obj = {
name,
type: TokenTypes.BOX_SHADOW,
- value: undefined,
+ value: [],
description,
$extensions
- };
+ } as SingleBoxShadowToken;
if (value) {
obj.value = value;
@@ -81,6 +85,6 @@ export default class NodeDefinition extends Node {
throw new Error('Value or reference is required');
}
- this.setOutput('token', obj);
+ this.outputs.token.set(obj);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/createTypography.ts b/packages/nodes-design-tokens/src/nodes/createTypography.ts
index 14c93f9b..a28ac257 100644
--- a/packages/nodes-design-tokens/src/nodes/createTypography.ts
+++ b/packages/nodes-design-tokens/src/nodes/createTypography.ts
@@ -25,7 +25,7 @@ export default class CreateTypographyNode extends Node {
}>;
declare outputs: ToOutput<{
- token: TokenTypographyValue;
+ value: TokenTypographyValue;
}>;
constructor(props: INodeDefinition) {
@@ -63,6 +63,6 @@ export default class CreateTypographyNode extends Node {
execute(): void | Promise {
const props = this.getAllInputs();
- this.setOutput('value', props);
+ this.outputs.value.set(props);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/createTypographyToken.ts b/packages/nodes-design-tokens/src/nodes/createTypographyToken.ts
index 6d2cd243..c612f857 100644
--- a/packages/nodes-design-tokens/src/nodes/createTypographyToken.ts
+++ b/packages/nodes-design-tokens/src/nodes/createTypographyToken.ts
@@ -8,6 +8,7 @@ import {
} from '@tokens-studio/graph-engine';
import {
SingleToken,
+ SingleTypographyToken,
TokenTypes,
TypographyValues
} from '@tokens-studio/types';
@@ -71,10 +72,10 @@ export default class NodeDefinition extends Node {
const obj = {
name,
type: TokenTypes.TYPOGRAPHY,
- value: undefined,
+ value: '',
description,
$extensions
- };
+ } as SingleTypographyToken;
if (value) {
obj.value = value;
@@ -84,6 +85,6 @@ export default class NodeDefinition extends Node {
throw new Error('Value or reference is required');
}
- this.setOutput('token', obj);
+ this.outputs.token.set(obj);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/destructToken.ts b/packages/nodes-design-tokens/src/nodes/destructToken.ts
index 8bfa4539..ba2276d8 100644
--- a/packages/nodes-design-tokens/src/nodes/destructToken.ts
+++ b/packages/nodes-design-tokens/src/nodes/destructToken.ts
@@ -32,13 +32,13 @@ export default class CreateBorderNode extends Node {
declare outputs: ToOutput<{
name: string;
- description?: string;
+ description: string | undefined;
type: string;
- $extensions?: Record;
- value?: string;
- border?: TokenBorderValue;
- typography?: TokenTypographyValue;
- boxShadow?: TokenBoxshadowValue[];
+ $extensions: Record | undefined;
+ value: string | undefined;
+ border: TokenBorderValue | undefined;
+ typography: TokenTypographyValue | undefined;
+ boxShadow: TokenBoxshadowValue[] | undefined;
}>;
constructor(props: INodeDefinition) {
@@ -77,37 +77,44 @@ export default class CreateBorderNode extends Node {
execute(): void | Promise {
const { token } = this.getAllInputs();
+ const outputs = this.outputs;
const { name, description, type, $extensions, value } = token;
- this.setOutput('name', name);
- this.setOutput('description', description);
- this.setOutput('type', type);
- this.setOutput('$extensions', $extensions);
+ outputs.name.set(name);
+ outputs.description.set(description);
+ outputs.type.set(type!);
+ outputs.$extensions.set($extensions);
//Make sure to reset all the values
- this.setOutput('value', undefined);
- this.setOutput('border', undefined);
- this.setOutput('typography', undefined);
- this.setOutput('boxShadow', undefined);
+ outputs.value.set(undefined);
+ outputs.border.set(undefined);
+ outputs.typography.set(undefined);
+ outputs.boxShadow.set(undefined);
switch (type) {
case TokenTypes.BORDER:
- this.setOutput(typeof value === 'object' ? 'border' : 'value', value);
+ if (typeof value === 'object') {
+ outputs.border.set(value as TokenBorderValue);
+ } else {
+ outputs.value.set(value);
+ }
break;
case TokenTypes.BOX_SHADOW:
- this.setOutput(
- typeof value === 'object' ? 'boxShadow' : 'value',
- value
- );
+ if (typeof value === 'object') {
+ outputs.boxShadow.set(value as TokenBoxshadowValue[]);
+ } else {
+ outputs.value.set(value);
+ }
break;
case TokenTypes.TYPOGRAPHY:
- this.setOutput(
- typeof value === 'object' ? 'typography' : 'value',
- value
- );
+ if (typeof value === 'object') {
+ outputs.typography.set(value as TokenTypographyValue);
+ } else {
+ outputs.value.set(value);
+ }
break;
default:
- this.setOutput('value', value);
+ this.outputs.value.set(value as string);
}
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/externalTokens.ts b/packages/nodes-design-tokens/src/nodes/externalTokens.ts
index 70ef04ba..74d6bd05 100644
--- a/packages/nodes-design-tokens/src/nodes/externalTokens.ts
+++ b/packages/nodes-design-tokens/src/nodes/externalTokens.ts
@@ -30,6 +30,6 @@ export default class ExternalTokensNode extends Node {
}
const tokens = await this.load(uri);
- this.setOutput('tokenSet', tokens);
+ this.outputs.tokenSet.set(tokens);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/extractSingleToken.ts b/packages/nodes-design-tokens/src/nodes/extractSingleToken.ts
index 3b748300..89275246 100644
--- a/packages/nodes-design-tokens/src/nodes/extractSingleToken.ts
+++ b/packages/nodes-design-tokens/src/nodes/extractSingleToken.ts
@@ -44,7 +44,7 @@ export default class ExtractTokenNode extends Node {
const { tokens, name } = this.getAllInputs();
const token = tokens.find((token: SingleToken) => token.name === name);
- this.setOutput('token', token);
- this.setOutput('found', !!token);
+ this.outputs.token.set(token);
+ this.outputs.found.set(!!token);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/flatten.ts b/packages/nodes-design-tokens/src/nodes/flatten.ts
index 16f01e03..67ded9b2 100644
--- a/packages/nodes-design-tokens/src/nodes/flatten.ts
+++ b/packages/nodes-design-tokens/src/nodes/flatten.ts
@@ -55,6 +55,6 @@ export default class FlattenNode extends Node {
lookup: {}
}
);
- this.setOutput('tokens', vals.reverse());
+ this.outputs.tokens.set(vals.reverse());
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/group.ts b/packages/nodes-design-tokens/src/nodes/group.ts
index ebaa221b..9da3eed4 100644
--- a/packages/nodes-design-tokens/src/nodes/group.ts
+++ b/packages/nodes-design-tokens/src/nodes/group.ts
@@ -39,6 +39,6 @@ export default class GroupNode extends Node {
const { name, tokenSet } = this.getAllInputs();
const output = { [name]: tokenSet };
- this.setOutput('tokenSet', output);
+ this.outputs.tokenSet.set(output);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/inlineTokens.ts b/packages/nodes-design-tokens/src/nodes/inlineTokens.ts
index 0bfc9db9..226a9e29 100644
--- a/packages/nodes-design-tokens/src/nodes/inlineTokens.ts
+++ b/packages/nodes-design-tokens/src/nodes/inlineTokens.ts
@@ -34,7 +34,7 @@ export default class InlineTokenNode extends Node {
}
execute(): void | Promise {
- const value = this.getInput('value');
- this.setOutput('tokens', value);
+ const value = this.inputs.value.value;
+ this.outputs.tokens.set(value);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/invert.ts b/packages/nodes-design-tokens/src/nodes/invert.ts
index 259dfd29..5c1848e1 100644
--- a/packages/nodes-design-tokens/src/nodes/invert.ts
+++ b/packages/nodes-design-tokens/src/nodes/invert.ts
@@ -4,7 +4,6 @@ import {
ToInput,
ToOutput
} from '@tokens-studio/graph-engine';
-import { IResolvedToken } from '../utils/index.js';
import { SingleToken } from '@tokens-studio/types';
import { TokenSchema } from '../schemas/index.js';
import { arrayOf } from '../schemas/utils.js';
@@ -32,7 +31,7 @@ export default class InvertNode extends Node {
}
execute(): void | Promise {
- const value = this.getInput('tokens') as IResolvedToken[];
+ const value = this.inputs.tokens.value;
const inverted = value.map((x, i) => {
const vals = inverted[inverted.length - i - 1];
@@ -42,6 +41,6 @@ export default class InvertNode extends Node {
};
});
- this.setOutput('tokens', value);
+ this.outputs.tokens.set(value);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/leonardoColor.ts b/packages/nodes-design-tokens/src/nodes/leonardoColor.ts
index 9426f40f..8ea05998 100644
--- a/packages/nodes-design-tokens/src/nodes/leonardoColor.ts
+++ b/packages/nodes-design-tokens/src/nodes/leonardoColor.ts
@@ -11,12 +11,13 @@ import {
toColor,
toHex
} from '@tokens-studio/graph-engine';
+import { CssColor } from '@adobe/leonardo-contrast-colors';
import { LeonardoColorSchema } from '../schemas/index.js';
import { arrayOf } from '../schemas/utils.js';
export type LeonardoColor = {
name: string;
- colorKeys: Color[];
+ colorKeys: CssColor[];
ratios: number[];
smooth: boolean;
};
@@ -62,10 +63,10 @@ export default class LeonardoColorNode extends Node {
//Because the color is mutated inside of the object, we create a plain object and expect downstream nodes to handle the mutation
const color = {
name,
- colorKeys: colorKeys.map(x => toHex(toColor(x))),
+ colorKeys: colorKeys.map(x => toHex(toColor(x)) as CssColor),
ratios,
smooth
};
- this.setOutput('value', color);
+ this.outputs.value.set(color);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/leonardoTheme.ts b/packages/nodes-design-tokens/src/nodes/leonardoTheme.ts
index 0c726734..5b4a6c7d 100644
--- a/packages/nodes-design-tokens/src/nodes/leonardoTheme.ts
+++ b/packages/nodes-design-tokens/src/nodes/leonardoTheme.ts
@@ -65,6 +65,6 @@ export default class LeonardoThemeNode extends Node {
const themeColors = theme.contrastColorValues.map(x => hexToColor(x));
- this.setOutput('colors', themeColors);
+ this.outputs.colors.set(themeColors);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/name.ts b/packages/nodes-design-tokens/src/nodes/name.ts
index ccccd07f..c5b8d1bd 100644
--- a/packages/nodes-design-tokens/src/nodes/name.ts
+++ b/packages/nodes-design-tokens/src/nodes/name.ts
@@ -41,6 +41,6 @@ export default class NameTokensNode extends Node {
};
});
- this.setOutput('tokens', renamed);
+ this.outputs.tokens.set(renamed);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/resolve.ts b/packages/nodes-design-tokens/src/nodes/resolve.ts
index 0c30ff35..eaeaa222 100644
--- a/packages/nodes-design-tokens/src/nodes/resolve.ts
+++ b/packages/nodes-design-tokens/src/nodes/resolve.ts
@@ -43,8 +43,8 @@ export default class ResolveNode extends Node {
static description = 'Resolves a set of tokens';
declare inputs: ToInput<{
- inputs: SingleToken[];
- context: SingleToken[];
+ inputs: SingleToken[][];
+ context: SingleToken[][];
}>;
declare outputs: ToOutput<{
value: IResolvedToken[];
@@ -66,7 +66,10 @@ export default class ResolveNode extends Node {
execute(): void | Promise {
const { inputs, context } = this.getAllInputs();
- const resolved = resolveValues(inputs.flat(), context.flat());
- this.setOutput('value', resolved);
+ const resolved = resolveValues(
+ inputs.flat() as IResolvedToken[],
+ context.flat() as IResolvedToken[]
+ );
+ this.outputs.value.set(resolved);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/setToArray.ts b/packages/nodes-design-tokens/src/nodes/setToArray.ts
index 1ae0439a..5330d004 100644
--- a/packages/nodes-design-tokens/src/nodes/setToArray.ts
+++ b/packages/nodes-design-tokens/src/nodes/setToArray.ts
@@ -33,10 +33,10 @@ export default class SetToArrayNode extends Node {
}
execute(): void | Promise {
- const set = this.getInput('tokenSet');
+ const set = this.inputs.tokenSet.value;
const tokens = flatten(set);
- this.setOutput('tokens', tokens);
+ this.outputs.tokens.set(tokens as SingleToken[]);
}
}
diff --git a/packages/nodes-design-tokens/src/nodes/ungroup.ts b/packages/nodes-design-tokens/src/nodes/ungroup.ts
index 88179b95..5d3d82f8 100644
--- a/packages/nodes-design-tokens/src/nodes/ungroup.ts
+++ b/packages/nodes-design-tokens/src/nodes/ungroup.ts
@@ -41,11 +41,11 @@ export default class UngroupNode extends Node {
const accessorParts = name.split('.');
//We assume that we will throw an error if we cannot find the values
- let output = tokenSet;
+ let output: DeepKeyTokenMap = tokenSet;
for (const accessor of accessorParts) {
- output = output[accessor];
+ output = output[accessor] as DeepKeyTokenMap;
}
- this.setOutput('tokenSet', output);
+ this.outputs.tokenSet.set(output);
}
}
diff --git a/packages/nodes-fs/src/nodes/getDirectoryListing.ts b/packages/nodes-fs/src/nodes/getDirectoryListing.ts
index 7812f3d2..6d182c30 100644
--- a/packages/nodes-fs/src/nodes/getDirectoryListing.ts
+++ b/packages/nodes-fs/src/nodes/getDirectoryListing.ts
@@ -7,15 +7,13 @@ import {
import { arrayOf } from '../schemas/utils.js';
import type { ToInput } from '@tokens-studio/graph-engine';
-type inputs = {
- path: string;
-};
-
export class GetDirectoryNode extends Node {
static title = 'Read directory';
static type = 'studio.tokens.fs.getDirectory';
- declare inputs: ToInput;
+ declare inputs: ToInput<{
+ path: string;
+ }>;
static description = 'Reads the directory of a path';
constructor(props: INodeDefinition) {
super(props);
@@ -52,7 +50,7 @@ export class GetDirectoryNode extends Node {
{ dirs: [] as string[], files: [] as string[] }
);
- this.setOutput('dirs', dirs);
- this.setOutput('files', files);
+ this.outputs.dirs.set(dirs);
+ this.outputs.files.set(files);
}
}
diff --git a/packages/nodes-fs/src/nodes/getFile.ts b/packages/nodes-fs/src/nodes/getFile.ts
index 6b1f4015..f8e5be0b 100644
--- a/packages/nodes-fs/src/nodes/getFile.ts
+++ b/packages/nodes-fs/src/nodes/getFile.ts
@@ -7,15 +7,13 @@ import {
} from '@tokens-studio/graph-engine';
import type { ToInput } from '@tokens-studio/graph-engine';
-type inputs = {
- path: string;
-};
-
export class GetFileNode extends Node {
static title = 'Get File';
static type = 'studio.tokens.fs.getFile';
- declare inputs: ToInput;
+ declare inputs: ToInput<{
+ path: string;
+ }>;
static description = 'Gets a file from the file system.';
constructor(props: INodeDefinition) {
super(props);
@@ -39,7 +37,7 @@ export class GetFileNode extends Node {
const file = await this.getFs().readFile(path);
- this.setOutput('file', file);
- this.setOutput('ext', path.split('.').pop());
+ this.outputs.file.set(file);
+ this.outputs.ext.set(path.split('.').pop());
}
}
diff --git a/packages/nodes-fs/src/nodes/getJson.ts b/packages/nodes-fs/src/nodes/getJson.ts
index a67649f2..167b4c59 100644
--- a/packages/nodes-fs/src/nodes/getJson.ts
+++ b/packages/nodes-fs/src/nodes/getJson.ts
@@ -6,15 +6,13 @@ import {
} from '@tokens-studio/graph-engine';
import type { ToInput } from '@tokens-studio/graph-engine';
-type inputs = {
- file: Uint8Array;
-};
-
export class GetJSONNode extends Node {
static title = 'Read file as json';
static type = 'studio.tokens.fs.getJson';
- declare inputs: ToInput;
+ declare inputs: ToInput<{
+ file: Uint8Array;
+ }>;
static description =
'Reads the context of a file from the file system as a JSON object.';
constructor(props: INodeDefinition) {
@@ -33,6 +31,6 @@ export class GetJSONNode extends Node {
const contents = JSON.parse(new TextDecoder().decode(file));
- this.setOutput('contents', contents);
+ this.outputs.contents.set(contents);
}
}
diff --git a/packages/nodes-fs/src/nodes/getText.ts b/packages/nodes-fs/src/nodes/getText.ts
index 1678e2b3..8623d1ba 100644
--- a/packages/nodes-fs/src/nodes/getText.ts
+++ b/packages/nodes-fs/src/nodes/getText.ts
@@ -6,15 +6,13 @@ import {
} from '@tokens-studio/graph-engine';
import type { ToInput } from '@tokens-studio/graph-engine';
-type inputs = {
- file: Uint8Array;
-};
-
export class GetTextNode extends Node {
static title = 'Read file as text';
static type = 'studio.tokens.fs.getText';
- declare inputs: ToInput;
+ declare inputs: ToInput<{
+ file: Uint8Array;
+ }>;
static description = 'Reads the text context of a file from the file system.';
constructor(props: INodeDefinition) {
super(props);
@@ -32,6 +30,6 @@ export class GetTextNode extends Node {
const contents = new TextDecoder().decode(file);
- this.setOutput('contents', contents);
+ this.outputs.contents.set(contents);
}
}
diff --git a/packages/nodes-image/src/nodes/autoLevel.ts b/packages/nodes-image/src/nodes/autoLevel.ts
index 61693270..ce6b4652 100644
--- a/packages/nodes-image/src/nodes/autoLevel.ts
+++ b/packages/nodes-image/src/nodes/autoLevel.ts
@@ -28,7 +28,7 @@ export class AutoLevelNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.autoLevel();
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/autoOrient.ts b/packages/nodes-image/src/nodes/autoOrient.ts
index d1a4ac51..7884af95 100644
--- a/packages/nodes-image/src/nodes/autoOrient.ts
+++ b/packages/nodes-image/src/nodes/autoOrient.ts
@@ -28,7 +28,7 @@ export class AutoOrient extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.autoOrient();
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/base.ts b/packages/nodes-image/src/nodes/base.ts
index a639e0c2..11f42003 100644
--- a/packages/nodes-image/src/nodes/base.ts
+++ b/packages/nodes-image/src/nodes/base.ts
@@ -10,7 +10,7 @@ export class BaseNode extends Node {
return this.getGraph().capabilities["imageMagick"];
}
- cloneImage = (image: Image) => {
+ cloneImage = (image: ImageData | Image) => {
const dst = new Uint8Array(image.data.byteLength);
dst.set(new Uint8Array(image.data));
return dst;
diff --git a/packages/nodes-image/src/nodes/blur.ts b/packages/nodes-image/src/nodes/blur.ts
index 58fde9ac..8e44fccd 100644
--- a/packages/nodes-image/src/nodes/blur.ts
+++ b/packages/nodes-image/src/nodes/blur.ts
@@ -7,6 +7,7 @@ import {
} from "@tokens-studio/graph-engine";
import { ImageSchema } from "../schemas/index.js";
+import { Image } from "../schemas/types.js";
import type { IMagickImage } from "@imagemagick/magick-wasm";
export class BlurNode extends BaseNode {
@@ -14,12 +15,12 @@ export class BlurNode extends BaseNode {
static type = "studio.tokens.image.blur";
declare inputs: ToInput<{
- image: ImageData;
+ image: Image;
sigma: number;
radius: number;
}>;
declare outputs: ToOutput<{
- image: ImageData;
+ image: Image;
}>;
constructor(props: INodeDefinition) {
@@ -46,7 +47,7 @@ export class BlurNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.blur(radius, sigma);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/charcoal.ts b/packages/nodes-image/src/nodes/charcoal.ts
index e3d2826c..f74ad3ff 100644
--- a/packages/nodes-image/src/nodes/charcoal.ts
+++ b/packages/nodes-image/src/nodes/charcoal.ts
@@ -14,6 +14,8 @@ export class CharcoalNode extends BaseNode {
declare inputs: ToInput<{
image: ImageData;
width: number;
+ radius: number;
+ sigma: number;
height: number;
}>;
@@ -46,7 +48,7 @@ export class CharcoalNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.charcoal(radius, sigma);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/compose.ts b/packages/nodes-image/src/nodes/compose.ts
index a3f7c2a5..4b9278b9 100644
--- a/packages/nodes-image/src/nodes/compose.ts
+++ b/packages/nodes-image/src/nodes/compose.ts
@@ -88,6 +88,7 @@ export class ComposeNode extends BaseNode {
declare inputs: ToInput<{
a: Image;
b: Image;
+ operator: keyof typeof CompositeOperatorLookup;
}>;
constructor(props: INodeDefinition) {
@@ -129,7 +130,7 @@ export class ComposeNode extends BaseNode {
image.composite(bbb, compositeOperator as CompositeOperator);
});
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/dither.ts b/packages/nodes-image/src/nodes/dither.ts
index b9319540..84b41b68 100644
--- a/packages/nodes-image/src/nodes/dither.ts
+++ b/packages/nodes-image/src/nodes/dither.ts
@@ -7,6 +7,7 @@ import {
ToInput,
ToOutput,
} from "@tokens-studio/graph-engine";
+import { Image } from "../schemas/types.js";
import { ImageSchema } from "../schemas/index.js";
export const colorSpaceLookup = {
@@ -55,12 +56,14 @@ export class Dither extends BaseNode {
static type = "studio.tokens.image.dither";
declare inputs: ToInput<{
- image: ImageData;
+ image: Image;
sigma: number;
- radius: number;
+ colors: number;
+ colorSpace: keyof typeof colorSpaceLookup;
+ ditherMethod: keyof typeof ditherMethodLookup;
}>;
declare outputs: ToOutput<{
- image: ImageData;
+ image: Image;
}>;
constructor(props: INodeDefinition) {
@@ -108,7 +111,7 @@ export class Dither extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.quantize(opts);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/flip.ts b/packages/nodes-image/src/nodes/flip.ts
index 6e705415..848b9064 100644
--- a/packages/nodes-image/src/nodes/flip.ts
+++ b/packages/nodes-image/src/nodes/flip.ts
@@ -28,7 +28,7 @@ export class FlipNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.flip();
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/flop.ts b/packages/nodes-image/src/nodes/flop.ts
index 75a1abf4..6a280d6f 100644
--- a/packages/nodes-image/src/nodes/flop.ts
+++ b/packages/nodes-image/src/nodes/flop.ts
@@ -27,7 +27,7 @@ export class FlopNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.flop();
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/gaussianBlur.ts b/packages/nodes-image/src/nodes/gaussianBlur.ts
index 23347f91..5a61cccc 100644
--- a/packages/nodes-image/src/nodes/gaussianBlur.ts
+++ b/packages/nodes-image/src/nodes/gaussianBlur.ts
@@ -5,6 +5,7 @@ import {
ToInput,
ToOutput,
} from "@tokens-studio/graph-engine";
+import { Image } from "../schemas/types.js";
import { ImageSchema } from "../schemas/index.js";
import type { IMagickImage } from "@imagemagick/magick-wasm";
@@ -18,7 +19,7 @@ export class GaussianBlurNode extends BaseNode {
radius: number;
}>;
declare outputs: ToOutput<{
- image: ImageData;
+ image: Image;
}>;
constructor(props: INodeDefinition) {
@@ -46,7 +47,7 @@ export class GaussianBlurNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.gaussianBlur(radius, sigma);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/grayscale.ts b/packages/nodes-image/src/nodes/grayscale.ts
index 93c0b7b1..24058b53 100644
--- a/packages/nodes-image/src/nodes/grayscale.ts
+++ b/packages/nodes-image/src/nodes/grayscale.ts
@@ -4,6 +4,7 @@ import {
ToInput,
ToOutput,
} from "@tokens-studio/graph-engine";
+import { Image } from "../schemas/types.js";
import { ImageSchema } from "../schemas/index.js";
import type { IMagickImage } from "@imagemagick/magick-wasm";
@@ -12,10 +13,10 @@ export class GrayscaleNode extends BaseNode {
static type = "studio.tokens.image.grayscale";
declare inputs: ToInput<{
- image: ImageData;
+ image: Image;
}>;
declare outputs: ToOutput<{
- image: ImageData;
+ image: Image;
}>;
constructor(props: INodeDefinition) {
@@ -37,7 +38,7 @@ export class GrayscaleNode extends BaseNode {
image.grayscale();
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/load.ts b/packages/nodes-image/src/nodes/load.ts
index a0cd8e24..a3830730 100644
--- a/packages/nodes-image/src/nodes/load.ts
+++ b/packages/nodes-image/src/nodes/load.ts
@@ -61,8 +61,9 @@ export class FetchNode extends BaseNode {
const { data } = await loadImageAsBuffer(url);
- this.setOutput("image", {
+ this.outputs.image.set({
data,
+ settings: new MagickReadSettings(),
});
}
}
diff --git a/packages/nodes-image/src/nodes/morphology.ts b/packages/nodes-image/src/nodes/morphology.ts
index e188b979..306d6457 100644
--- a/packages/nodes-image/src/nodes/morphology.ts
+++ b/packages/nodes-image/src/nodes/morphology.ts
@@ -6,6 +6,7 @@ import {
ToInput,
ToOutput,
} from "@tokens-studio/graph-engine";
+import { Image } from "../schemas/types.js";
import { ImageSchema } from "../schemas/index.js";
export const morphologyMethod = {
@@ -78,12 +79,12 @@ export class Morphology extends BaseNode {
static type = "studio.tokens.image.morphology";
declare inputs: ToInput<{
- image: ImageData;
+ image: Image;
kernel: typeof Kernel;
method: typeof morphologyMethod;
}>;
declare outputs: ToOutput<{
- image: ImageData;
+ image: Image;
}>;
constructor(props: INodeDefinition) {
@@ -123,7 +124,7 @@ export class Morphology extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.morphology(settings);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/negate.ts b/packages/nodes-image/src/nodes/negate.ts
index b9630909..2d6712e9 100644
--- a/packages/nodes-image/src/nodes/negate.ts
+++ b/packages/nodes-image/src/nodes/negate.ts
@@ -4,6 +4,7 @@ import {
ToInput,
ToOutput,
} from "@tokens-studio/graph-engine";
+import { Image } from "../schemas/types.js";
import { ImageSchema } from "../schemas/index.js";
import type { IMagickImage } from "@imagemagick/magick-wasm";
@@ -12,10 +13,10 @@ export class NegateNode extends BaseNode {
static type = "studio.tokens.image.negate";
declare inputs: ToInput<{
- image: ImageData;
+ image: Image;
}>;
declare outputs: ToOutput<{
- image: ImageData;
+ image: Image;
}>;
constructor(props: INodeDefinition) {
@@ -36,7 +37,7 @@ export class NegateNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.negate();
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/oilpaint.ts b/packages/nodes-image/src/nodes/oilpaint.ts
index 641a5f9e..24a7fb41 100644
--- a/packages/nodes-image/src/nodes/oilpaint.ts
+++ b/packages/nodes-image/src/nodes/oilpaint.ts
@@ -5,6 +5,7 @@ import {
ToInput,
ToOutput,
} from "@tokens-studio/graph-engine";
+import { Image } from "../schemas/types.js";
import { ImageSchema } from "../schemas/index.js";
import type { IMagickImage } from "@imagemagick/magick-wasm";
@@ -17,7 +18,7 @@ export class Oilpaint extends BaseNode {
radius: number;
}>;
declare outputs: ToOutput<{
- image: ImageData;
+ image: Image;
}>;
constructor(props: INodeDefinition) {
@@ -41,7 +42,7 @@ export class Oilpaint extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.oilPaint(radius);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/properties.ts b/packages/nodes-image/src/nodes/properties.ts
index 4f36d1a5..2c1ac337 100644
--- a/packages/nodes-image/src/nodes/properties.ts
+++ b/packages/nodes-image/src/nodes/properties.ts
@@ -7,8 +7,8 @@ import {
ToInput,
ToOutput,
} from "@tokens-studio/graph-engine";
+import { Image } from "../schemas/types.js";
import { ImageSchema } from "../schemas/index.js";
-
import type { IMagickImage } from "@imagemagick/magick-wasm";
export class ImageProperties extends BaseNode {
@@ -16,7 +16,10 @@ export class ImageProperties extends BaseNode {
static type = "studio.tokens.image.properties";
declare inputs: ToInput<{
- image: ImageData;
+ image: Image;
+ }>;
+ declare outputs: ToOutput<{
+ image: Image;
width: number;
height: number;
channelCount: number;
@@ -25,9 +28,6 @@ export class ImageProperties extends BaseNode {
hasAlpha: boolean;
quality: number;
}>;
- declare outputs: ToOutput<{
- image: ImageData;
- }>;
constructor(props: INodeDefinition) {
super(props);
@@ -64,13 +64,13 @@ export class ImageProperties extends BaseNode {
//No need to clone as this is a readonly operation
await ImageMagick.read(image.data, (image: IMagickImage) => {
- this.setOutput("width", image.width);
- this.setOutput("height", image.height);
- this.setOutput("channelCount", image.channelCount);
- this.setOutput("format", image.format);
- this.setOutput("gamma", image.gamma);
- this.setOutput("hasAlpha", image.hasAlpha);
- this.setOutput("quality", image.quality);
+ this.outputs.width.set(image.width);
+ this.outputs.height.set(image.height);
+ this.outputs.channelCount.set(image.channelCount);
+ this.outputs.format.set(image.format);
+ this.outputs.gamma.set(image.gamma);
+ this.outputs.hasAlpha.set(image.hasAlpha);
+ this.outputs.quality.set(image.quality);
});
}
}
diff --git a/packages/nodes-image/src/nodes/resize.ts b/packages/nodes-image/src/nodes/resize.ts
index 7ae2d0c5..9eb5d938 100644
--- a/packages/nodes-image/src/nodes/resize.ts
+++ b/packages/nodes-image/src/nodes/resize.ts
@@ -48,8 +48,8 @@ export class ResizeNode extends BaseNode {
const { image, width, height, asPercent } = this.getAllInputs();
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
- let targetWidth = width;
- let targetHeight = height;
+ let targetWidth: number = width;
+ let targetHeight: number = height;
if (asPercent) {
targetWidth = image.width * (width / 100);
@@ -58,7 +58,7 @@ export class ResizeNode extends BaseNode {
image.resize(targetWidth, targetHeight);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/rotate.ts b/packages/nodes-image/src/nodes/rotate.ts
index 593fe0e8..0746a069 100644
--- a/packages/nodes-image/src/nodes/rotate.ts
+++ b/packages/nodes-image/src/nodes/rotate.ts
@@ -35,7 +35,7 @@ export class RotateNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.rotate(degrees);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/seperate.ts b/packages/nodes-image/src/nodes/seperate.ts
index 1795f4a5..10035142 100644
--- a/packages/nodes-image/src/nodes/seperate.ts
+++ b/packages/nodes-image/src/nodes/seperate.ts
@@ -21,6 +21,7 @@ export class SeperateNode extends BaseNode {
declare inputs: ToInput<{
image: ImageData;
+ channel: keyof typeof ChannelLookup;
}>;
constructor(props: INodeDefinition) {
@@ -53,7 +54,7 @@ export class SeperateNode extends BaseNode {
async (image: IMagickImage) => {
await image.separate(ch as Channels, (collection) => {
collection.at(0)?.write(image.format, (data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/sepia.ts b/packages/nodes-image/src/nodes/sepia.ts
index dab36e04..7181598b 100644
--- a/packages/nodes-image/src/nodes/sepia.ts
+++ b/packages/nodes-image/src/nodes/sepia.ts
@@ -4,6 +4,7 @@ import {
ToInput,
ToOutput,
} from "@tokens-studio/graph-engine";
+import { Image } from "../schemas/types.js";
import { ImageSchema } from "../schemas/index.js";
import type { IMagickImage } from "@imagemagick/magick-wasm";
@@ -12,10 +13,10 @@ export class SepiaNode extends BaseNode {
static type = "studio.tokens.image.sepia";
declare inputs: ToInput<{
- image: ImageData;
+ image: Image;
}>;
declare outputs: ToOutput<{
- image: ImageData;
+ image: Image;
}>;
static description = "Applies sepia effect to an image.";
@@ -37,7 +38,7 @@ export class SepiaNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.sepiaTone();
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/sharpen.ts b/packages/nodes-image/src/nodes/sharpen.ts
index 17d67b15..684c6892 100644
--- a/packages/nodes-image/src/nodes/sharpen.ts
+++ b/packages/nodes-image/src/nodes/sharpen.ts
@@ -5,6 +5,7 @@ import {
ToInput,
ToOutput,
} from "@tokens-studio/graph-engine";
+import { Image } from "../schemas/types.js";
import { ImageSchema } from "../schemas/index.js";
import type { IMagickImage } from "@imagemagick/magick-wasm";
@@ -13,12 +14,12 @@ export class Sharpen extends BaseNode {
static type = "studio.tokens.image.sharpen";
declare inputs: ToInput<{
- image: ImageData;
+ image: Image;
sigma: number;
radius: number;
}>;
declare outputs: ToOutput<{
- image: ImageData;
+ image: Image;
}>;
constructor(props: INodeDefinition) {
@@ -45,7 +46,7 @@ export class Sharpen extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.sharpen(radius, sigma);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/solarize.ts b/packages/nodes-image/src/nodes/solarize.ts
index f899f028..cffa40d9 100644
--- a/packages/nodes-image/src/nodes/solarize.ts
+++ b/packages/nodes-image/src/nodes/solarize.ts
@@ -28,7 +28,7 @@ export class SolarizeNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.solarize();
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/nodes/vignette.ts b/packages/nodes-image/src/nodes/vignette.ts
index ba704a9a..438de3f3 100644
--- a/packages/nodes-image/src/nodes/vignette.ts
+++ b/packages/nodes-image/src/nodes/vignette.ts
@@ -13,7 +13,10 @@ export class VignetteNode extends BaseNode {
declare inputs: ToInput<{
image: ImageData;
- degrees: number;
+ radius: number;
+ sigma: number;
+ x: number;
+ y: number;
}>;
constructor(props: INodeDefinition) {
super(props);
@@ -23,9 +26,6 @@ export class VignetteNode extends BaseNode {
this.addInput("radius", {
type: NumberSchema,
});
- this.addInput("radius", {
- type: NumberSchema,
- });
this.addInput("sigma", {
type: NumberSchema,
});
@@ -47,7 +47,7 @@ export class VignetteNode extends BaseNode {
await ImageMagick.read(this.cloneImage(image), (image: IMagickImage) => {
image.vignette(radius, sigma, x, y);
image.write((data) =>
- this.setOutput("image", {
+ this.outputs.image.set({
data,
}),
);
diff --git a/packages/nodes-image/src/schemas/types.ts b/packages/nodes-image/src/schemas/types.ts
index ef4e63bf..d167a97e 100644
--- a/packages/nodes-image/src/schemas/types.ts
+++ b/packages/nodes-image/src/schemas/types.ts
@@ -1,6 +1,6 @@
import { MagickReadSettings } from "@imagemagick/magick-wasm";
export type Image = {
- data: Buffer;
- settings: MagickReadSettings;
+ data: Uint8Array;
+ settings?: MagickReadSettings;
};
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 3c7d3ca0..351f4ea9 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -26,6 +26,8 @@
"dependencies": {
"@anthropic-ai/sdk": "0.25.0",
"@auth/prisma-adapter": "2.4.1",
+ "@codesandbox/sandpack-react": "2.19.3",
+ "@monaco-editor/react": "4.6.0",
"@opentelemetry/api-logs": "0.50.0",
"@prisma/client": "5.16.1",
"@radix-ui/react-popover": "^1.0.7",
@@ -39,9 +41,10 @@
"@tokens-studio/graph-engine-nodes-image": "*",
"@tokens-studio/tokens": "0.0.24",
"@tokens-studio/ui": "0.6.9",
- "@ts-rest/open-api": "3.45.2",
- "@ts-rest/react-query": "3.45.2",
- "@ts-rest/serverless": "3.45.2",
+ "@ts-rest/core": "3.51.0",
+ "@ts-rest/open-api": "^3.51.0",
+ "@ts-rest/react-query": "^3.51.0",
+ "@ts-rest/serverless": "^3.51.0",
"@uiw/react-md-editor": "4.0.4",
"@vercel/otel": "1.8.1",
"classnames": "2.3.2",
@@ -69,11 +72,13 @@
"react-joyride": "2.8.1",
"react-no-ssr": "1.1.0",
"react-redux": "^8.0.5",
+ "react-reflex": "4.2.6",
"react-use": "17.4.0",
"redux": "4.2.1",
"rehype-sanitize": "6.0.0",
"reselect": "4.1.8",
"s-ago": "2.2.0",
+ "sandpack-file-explorer": "0.0.7",
"sanitize.css": "13.0.0",
"sass": "1.62.1",
"swagger-ui-react": "5.17.14",
diff --git a/packages/ui/src/api/schemas/graph.ts b/packages/ui/src/api/schemas/graph.ts
index 1b6c0902..3855e3c0 100644
--- a/packages/ui/src/api/schemas/graph.ts
+++ b/packages/ui/src/api/schemas/graph.ts
@@ -8,15 +8,17 @@ export const SerializedGraph = z.object({
annotations: z.record(z.string(), z.any()).optional(),
type: z.string(),
inputs: z.array(
- z.object({
- name: z.string(),
- value: z.any(),
- visible: z.boolean().optional(),
- variadic: z.boolean().optional(),
- dynamicType: z.object({}).optional(),
- type: z.object({}).optional(),
- annotations: z.record(z.any()).optional()
- })
+ z
+ .object({
+ name: z.string(),
+ value: z.any(),
+ visible: z.boolean().optional(),
+ variadic: z.boolean().optional(),
+ dynamicType: z.any().optional(),
+ type: z.any().optional(),
+ annotations: z.record(z.any()).optional()
+ })
+ .passthrough()
)
})
//Needed for innergraph to work
diff --git a/packages/ui/src/app/editor/[id]/clientPage.tsx b/packages/ui/src/app/editor/[id]/clientPage.tsx
index 98dd5eaa..b3c7f180 100644
--- a/packages/ui/src/app/editor/[id]/clientPage.tsx
+++ b/packages/ui/src/app/editor/[id]/clientPage.tsx
@@ -26,17 +26,22 @@ const Page = observer(({ id, refs }: { id: string; refs: RefState }) => {
const ref = useCallback(editor => {
refs.setEditor(editor);
}, []);
- const { data, error } = client.graph.getGraph.useQuery(['getGraph', id], {
- params: {
- id: id
+ const { data, error } = client.graph.getGraph.useQuery(
+ ['getGraph', id],
+ {
+ params: {
+ id: id
+ }
+ },
+ {
+ //Do not allow reloading during development
+ staleTime: Infinity
}
- });
+ );
useErrorToast(error);
useEffect(() => {
if (refs.editor && data?.body) {
- console.log(data);
-
refs.editor.loadRaw(data.body.graph as SerializedGraph);
setStillLoading(false);
}
diff --git a/packages/ui/src/app/preview/clientPage.tsx b/packages/ui/src/app/preview/clientPage.tsx
new file mode 100644
index 00000000..93c9b375
--- /dev/null
+++ b/packages/ui/src/app/preview/clientPage.tsx
@@ -0,0 +1,2 @@
+'use client';
+export { default } from '@/components/preview';
diff --git a/packages/ui/src/app/preview/page.tsx b/packages/ui/src/app/preview/page.tsx
new file mode 100644
index 00000000..b8017c56
--- /dev/null
+++ b/packages/ui/src/app/preview/page.tsx
@@ -0,0 +1,7 @@
+import Inner from './clientPage.tsx';
+
+const Page = async () => {
+ return ;
+};
+
+export default Page;
diff --git a/packages/ui/src/assets/svgs/angular.svg b/packages/ui/src/assets/svgs/angular.svg
new file mode 100644
index 00000000..dc335010
--- /dev/null
+++ b/packages/ui/src/assets/svgs/angular.svg
@@ -0,0 +1,16 @@
+
+
+
diff --git a/packages/ui/src/assets/svgs/js.svg b/packages/ui/src/assets/svgs/js.svg
new file mode 100644
index 00000000..af6cb348
--- /dev/null
+++ b/packages/ui/src/assets/svgs/js.svg
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/packages/ui/src/assets/svgs/react.svg b/packages/ui/src/assets/svgs/react.svg
new file mode 100644
index 00000000..cc6f1ef7
--- /dev/null
+++ b/packages/ui/src/assets/svgs/react.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/packages/ui/src/assets/svgs/solid.svg b/packages/ui/src/assets/svgs/solid.svg
new file mode 100644
index 00000000..3b9b41b8
--- /dev/null
+++ b/packages/ui/src/assets/svgs/solid.svg
@@ -0,0 +1,34 @@
+
+
diff --git a/packages/ui/src/assets/svgs/svelte.svg b/packages/ui/src/assets/svgs/svelte.svg
new file mode 100644
index 00000000..ba1dec2d
--- /dev/null
+++ b/packages/ui/src/assets/svgs/svelte.svg
@@ -0,0 +1,21 @@
+
+
+
+
diff --git a/packages/ui/src/assets/svgs/vue.svg b/packages/ui/src/assets/svgs/vue.svg
new file mode 100644
index 00000000..884b7549
--- /dev/null
+++ b/packages/ui/src/assets/svgs/vue.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/packages/ui/src/components/editor/panels/preview.tsx b/packages/ui/src/components/editor/panels/preview.tsx
new file mode 100644
index 00000000..77ed8ea7
--- /dev/null
+++ b/packages/ui/src/components/editor/panels/preview.tsx
@@ -0,0 +1,184 @@
+import { Button, Heading, Stack, Text } from '@tokens-studio/ui';
+import { Graph, Node } from '@tokens-studio/graph-engine';
+import { reaction } from 'mobx';
+import { useGraph } from '@tokens-studio/graph-editor';
+import { useParams } from 'next/navigation.js';
+import { v4 as uuid } from 'uuid';
+import Angular from '@/assets/svgs/angular.svg';
+import Link from 'next/link.js';
+import React, { useEffect, useState } from 'react';
+import ReactIcon from '@/assets/svgs/react.svg';
+import SolidIcon from '@/assets/svgs/solid.svg';
+import SvelteIcon from '@/assets/svgs/svelte.svg';
+import VanillaIcon from '@/assets/svgs/js.svg';
+import VueIcon from '@/assets/svgs/vue.svg';
+
+const findOutput = (graph: Graph) => {
+ return Object.values(graph.nodes).find(
+ x => x.factory.type == 'studio.tokens.generic.output'
+ );
+};
+
+const useFindOutput = (graph: Graph) => {
+ const [outputNode, setOutputNode] = useState();
+
+ useEffect(() => {
+ let unsub = () => {};
+ const foundOutput = outputNode || findOutput(graph);
+ //Add a subscription to wait till we find it
+ if (!foundOutput) {
+ const unsubscribe = graph.on('nodeAdded', x => {
+ if (x.factory.type == 'studio.tokens.generic.output') {
+ setOutputNode(x);
+ }
+ });
+
+ unsub = unsubscribe;
+ } else {
+ setOutputNode(foundOutput);
+ }
+ return unsub;
+ }, [graph]);
+
+ return outputNode;
+};
+
+const ImageIcon = ({ src }) => {
+ return ;
+};
+
+export const Listener = ({ previewId }) => {
+ const graph = useGraph();
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ const output = useFindOutput(graph!);
+
+ const [channel, setChannel] = useState(null);
+
+ useEffect(() => {
+ const bc = new BroadcastChannel(`preview:${previewId}`);
+ setChannel(bc);
+ return () => bc.close();
+ }, [previewId]);
+
+ useEffect(() => {
+ if (!output) {
+ return () => {
+ //nothing
+ };
+ }
+
+ function setupReactions(node: Node) {
+ const disposers = new Map();
+ const output = {};
+ let last = 'export default {}';
+
+ function serialize() {
+ last = 'export default ' + JSON.stringify(output, null, 4);
+ channel?.postMessage({
+ type: 'data',
+ data: last
+ });
+ }
+
+ channel!.onmessage = e => {
+ if (e.data.type === 'request') {
+ channel?.postMessage({
+ type: 'data',
+ data: last
+ });
+ }
+ };
+
+ const top = reaction(
+ () => Object.keys(node.inputs),
+ outputKeys => {
+ // Remove reactions for outputs that no longer exist
+ for (const [key, disposer] of disposers.entries()) {
+ if (!outputKeys.includes(key)) {
+ disposer();
+ delete output[key];
+ disposers.delete(key);
+ }
+ }
+
+ // Add reactions for new outputs
+ outputKeys.forEach(key => {
+ output[key] = node.inputs[key].value;
+ if (!disposers.has(key)) {
+ const disposer = reaction(
+ () => node.inputs[key].value,
+ value => {
+ output[key] = value;
+ serialize();
+ },
+ { fireImmediately: true }
+ );
+ disposers.set(key, disposer);
+ }
+ });
+ serialize();
+ },
+ { fireImmediately: true }
+ );
+
+ // Return a function to dispose all reactions
+ return () => {
+ for (const disposer of disposers.values()) {
+ disposer();
+ }
+ disposers.clear();
+ top();
+ };
+ }
+
+ const dispose = setupReactions(output);
+
+ return dispose;
+ }, [output, channel]);
+ return <>>;
+};
+
+export const Preview = () => {
+ const { id } = useParams();
+ //eslint-disable-line @typescript-eslint/no-unused-vars
+ const [previewId] = useState(id || uuid());
+
+ return (
+
+
+ Choose a framework
+
+
+ }>React
+
+
+ }>Angular
+
+
+ }>Vue
+
+
+ }>Svelte
+
+
+ }>Solid
+
+
+ }>Vanilla JS
+
+
+ Keep this panel open for previews to work
+
+ Previews are opened in a seperated tab, but any changes within this tab
+ will automatically update the preview values. You can have multiple
+ different previews open.
+
+
+ );
+};
diff --git a/packages/ui/src/components/editor/toolbar.tsx b/packages/ui/src/components/editor/toolbar.tsx
index 824f161c..90028f93 100644
--- a/packages/ui/src/components/editor/toolbar.tsx
+++ b/packages/ui/src/components/editor/toolbar.tsx
@@ -15,8 +15,9 @@ import {
} from '@tokens-studio/graph-editor';
import { AISummary } from './panels/aiSummary.tsx';
-import { FloppyDisk, ShareAndroidSolid, Sparks } from 'iconoir-react';
+import { FloppyDisk, ShareAndroidSolid, Sparks, XrayView } from 'iconoir-react';
import { IconButton, Tooltip } from '@tokens-studio/ui';
+import { Preview } from './panels/preview.tsx';
import { SharePopover } from '../share/index.tsx';
import { client } from '@/api/sdk/index.ts';
import { useErrorToast } from '@/hooks/useToast.tsx';
@@ -166,6 +167,7 @@ export const createToolbarButtons = (buttons?: React.ReactElement) => {
+
diff --git a/packages/ui/src/components/preview/index.tsx b/packages/ui/src/components/preview/index.tsx
new file mode 100644
index 00000000..d00e563f
--- /dev/null
+++ b/packages/ui/src/components/preview/index.tsx
@@ -0,0 +1,125 @@
+'use client';
+import './preview.css';
+import {
+ SandpackCodeEditor,
+ SandpackLayout,
+ SandpackPreview,
+ SandpackProvider,
+ SandpackProviderProps,
+ useSandpack
+} from '@codesandbox/sandpack-react';
+import { SandpackFileExplorer } from 'sandpack-file-explorer';
+
+import React, { useEffect, useMemo } from 'react';
+
+import 'react-reflex/styles.css';
+import { ReflexContainer, ReflexElement, ReflexSplitter } from 'react-reflex';
+import { useSearchParams } from 'next/navigation.js';
+
+//The format is @sandpack::
+
+const PERSISTED_KEY = '@sandpack';
+
+const Listener = ({ template, channelId }) => {
+ const { sandpack } = useSandpack();
+ const [channel, setChannel] = React.useState(null);
+
+ useEffect(() => {
+ const bc = new BroadcastChannel(`preview:${channelId}`);
+ //Ask for the initial data
+ bc.postMessage({
+ type: 'request'
+ });
+ setChannel(bc);
+ return () => bc.close();
+ }, [channelId]);
+
+ useEffect(() => {
+ if (channel) {
+ channel.onmessage = event => {
+ const data = event.data;
+
+ if (data.type == 'data') {
+ sandpack.updateFile('generated.js', data.data, true);
+ }
+ };
+ }
+ }, [channel, sandpack]);
+
+ useEffect(() => {
+ const x = setInterval(() => {
+ localStorage.setItem(
+ `${PERSISTED_KEY}:${channelId}:${template}`,
+ JSON.stringify(sandpack.files)
+ );
+ }, 8000);
+
+ return () => {
+ clearInterval(x);
+ };
+ }, [channelId, sandpack.files, template]);
+
+ return <>>;
+};
+
+const Editor = () => {
+ const search = useSearchParams();
+ const channelId = search.get('id');
+ const template = (search.get('template') ||
+ 'react') as SandpackProviderProps['template'];
+
+ const initialFiles = useMemo(() => {
+ const raw =
+ localStorage.getItem(`${PERSISTED_KEY}:${channelId}:${template}`) || '{}';
+ return JSON.parse(raw);
+ }, [channelId, template]);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Editor;
diff --git a/packages/ui/src/components/preview/preview.css b/packages/ui/src/components/preview/preview.css
new file mode 100644
index 00000000..6076e52d
--- /dev/null
+++ b/packages/ui/src/components/preview/preview.css
@@ -0,0 +1,22 @@
+.preview-layout{
+ height:100%;
+}
+
+.preview-wrapper{
+ height:100% !important;
+}
+
+.preview-layout>*{
+ height:100% !important
+}
+
+.sp-stack{
+ height: 100%;
+}
+.preview-explorer{
+ height: 100%;
+}
+.preview-explorer>*{
+ height: 100%;
+ max-width: unset !important;
+}
\ No newline at end of file
diff --git a/packages/vscode-example-workspace/nodes/example/index.ts b/packages/vscode-example-workspace/nodes/example/index.ts
index c55e4707..f75b91d6 100644
--- a/packages/vscode-example-workspace/nodes/example/index.ts
+++ b/packages/vscode-example-workspace/nodes/example/index.ts
@@ -31,6 +31,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { a, b } = this.getAllInputs();
- this.setOutput("value", a + b);
+ this.outputs.value.set(a + b);
}
}
diff --git a/packages/yo-generator/generators/app/templates/nodes/example/index.ts b/packages/yo-generator/generators/app/templates/nodes/example/index.ts
index 91a0670b..28a7fcf7 100644
--- a/packages/yo-generator/generators/app/templates/nodes/example/index.ts
+++ b/packages/yo-generator/generators/app/templates/nodes/example/index.ts
@@ -27,6 +27,6 @@ export default class NodeDefinition extends Node {
execute(): void | Promise {
const { a, b } = this.getAllInputs();
- this.setOutput('value', a + b);
+ this.outputs.value.set( a + b);
}
}
diff --git a/yarn.lock b/yarn.lock
index 18543d8e..d4fdef31 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1380,6 +1380,13 @@
core-js-pure "^3.30.2"
regenerator-runtime "^0.14.0"
+"@babel/runtime@^7.0.0":
+ version "7.25.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2"
+ integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.16.7", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.2.0", "@babel/runtime@^7.20.1", "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.22.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.24.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12"
@@ -1926,6 +1933,145 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
+"@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.4.0":
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.0.tgz#5f39b05daca04c95e990b70024144df47b2aa635"
+ integrity sha512-5DbOvBbY4qW5l57cjDsmmpDh3/TeK1vXfTHa+BUMrRzdWdcxKZ4U4V7vQaTtOpApNU4kLS4FQ6cINtLg245LXA==
+ dependencies:
+ "@codemirror/language" "^6.0.0"
+ "@codemirror/state" "^6.0.0"
+ "@codemirror/view" "^6.17.0"
+ "@lezer/common" "^1.0.0"
+
+"@codemirror/commands@^6.1.3":
+ version "6.6.1"
+ resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.6.1.tgz#6beaf2f94df1af1e7d4a811dff4fea2ac227b49c"
+ integrity sha512-iBfKbyIoXS1FGdsKcZmnrxmbc8VcbMrSgD7AVrsnX+WyAYjmUDWvE93dt5D874qS4CCVu4O1JpbagHdXbbLiOw==
+ dependencies:
+ "@codemirror/language" "^6.0.0"
+ "@codemirror/state" "^6.4.0"
+ "@codemirror/view" "^6.27.0"
+ "@lezer/common" "^1.1.0"
+
+"@codemirror/lang-css@^6.0.0", "@codemirror/lang-css@^6.0.1":
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/@codemirror/lang-css/-/lang-css-6.3.0.tgz#607628559f2471b385c6070ec795072a55cffc0b"
+ integrity sha512-CyR4rUNG9OYcXDZwMPvJdtb6PHbBDKUc/6Na2BIwZ6dKab1JQqKa4di+RNRY9Myn7JB81vayKwJeQ7jEdmNVDA==
+ dependencies:
+ "@codemirror/autocomplete" "^6.0.0"
+ "@codemirror/language" "^6.0.0"
+ "@codemirror/state" "^6.0.0"
+ "@lezer/common" "^1.0.2"
+ "@lezer/css" "^1.1.7"
+
+"@codemirror/lang-html@^6.4.0":
+ version "6.4.9"
+ resolved "https://registry.yarnpkg.com/@codemirror/lang-html/-/lang-html-6.4.9.tgz#d586f2cc9c341391ae07d1d7c545990dfa069727"
+ integrity sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==
+ dependencies:
+ "@codemirror/autocomplete" "^6.0.0"
+ "@codemirror/lang-css" "^6.0.0"
+ "@codemirror/lang-javascript" "^6.0.0"
+ "@codemirror/language" "^6.4.0"
+ "@codemirror/state" "^6.0.0"
+ "@codemirror/view" "^6.17.0"
+ "@lezer/common" "^1.0.0"
+ "@lezer/css" "^1.1.0"
+ "@lezer/html" "^1.3.0"
+
+"@codemirror/lang-javascript@^6.0.0", "@codemirror/lang-javascript@^6.1.2":
+ version "6.2.2"
+ resolved "https://registry.yarnpkg.com/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz#7141090b22994bef85bcc5608a3bc1257f2db2ad"
+ integrity sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==
+ dependencies:
+ "@codemirror/autocomplete" "^6.0.0"
+ "@codemirror/language" "^6.6.0"
+ "@codemirror/lint" "^6.0.0"
+ "@codemirror/state" "^6.0.0"
+ "@codemirror/view" "^6.17.0"
+ "@lezer/common" "^1.0.0"
+ "@lezer/javascript" "^1.0.0"
+
+"@codemirror/language@^6.0.0", "@codemirror/language@^6.3.2", "@codemirror/language@^6.4.0", "@codemirror/language@^6.6.0":
+ version "6.10.2"
+ resolved "https://registry.yarnpkg.com/@codemirror/language/-/language-6.10.2.tgz#4056dc219619627ffe995832eeb09cea6060be61"
+ integrity sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==
+ dependencies:
+ "@codemirror/state" "^6.0.0"
+ "@codemirror/view" "^6.23.0"
+ "@lezer/common" "^1.1.0"
+ "@lezer/highlight" "^1.0.0"
+ "@lezer/lr" "^1.0.0"
+ style-mod "^4.0.0"
+
+"@codemirror/lint@^6.0.0":
+ version "6.8.1"
+ resolved "https://registry.yarnpkg.com/@codemirror/lint/-/lint-6.8.1.tgz#6427848815baaf68c08e98c7673b804d3d8c0e7f"
+ integrity sha512-IZ0Y7S4/bpaunwggW2jYqwLuHj0QtESf5xcROewY6+lDNwZ/NzvR4t+vpYgg9m7V8UXLPYqG+lu3DF470E5Oxg==
+ dependencies:
+ "@codemirror/state" "^6.0.0"
+ "@codemirror/view" "^6.0.0"
+ crelt "^1.0.5"
+
+"@codemirror/state@^6.0.0", "@codemirror/state@^6.2.0", "@codemirror/state@^6.4.0":
+ version "6.4.1"
+ resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.4.1.tgz#da57143695c056d9a3c38705ed34136e2b68171b"
+ integrity sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==
+
+"@codemirror/view@^6.0.0", "@codemirror/view@^6.17.0", "@codemirror/view@^6.23.0", "@codemirror/view@^6.27.0", "@codemirror/view@^6.7.1":
+ version "6.33.0"
+ resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.33.0.tgz#51e270410fc3af92a6e38798e80ebf8add7dc3ec"
+ integrity sha512-AroaR3BvnjRW8fiZBalAaK+ZzB5usGgI014YKElYZvQdNH5ZIidHlO+cyf/2rWzyBFRkvG6VhiXeAEbC53P2YQ==
+ dependencies:
+ "@codemirror/state" "^6.4.0"
+ style-mod "^4.1.0"
+ w3c-keyname "^2.2.4"
+
+"@codesandbox/nodebox@0.1.8":
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/@codesandbox/nodebox/-/nodebox-0.1.8.tgz#2dc701005cedefac386f17a69a4c9a4f38c2325d"
+ integrity sha512-2VRS6JDSk+M+pg56GA6CryyUSGPjBEe8Pnae0QL3jJF1mJZJVMDKr93gJRtBbLkfZN6LD/DwMtf+2L0bpWrjqg==
+ dependencies:
+ outvariant "^1.4.0"
+ strict-event-emitter "^0.4.3"
+
+"@codesandbox/sandpack-client@^2.19.0":
+ version "2.19.0"
+ resolved "https://registry.yarnpkg.com/@codesandbox/sandpack-client/-/sandpack-client-2.19.0.tgz#6f2ca59a3b1d48789767437dda1d5017159b2148"
+ integrity sha512-a1D1/kJgyJRtqwiv2keX484RtgArOIBCj9NX/AqXWdVrHAn+yJtxP1RCqW0T0sfpYray/j2XD2WQn/6kz7VKMA==
+ dependencies:
+ "@codesandbox/nodebox" "0.1.8"
+ buffer "^6.0.3"
+ dequal "^2.0.2"
+ mime-db "^1.52.0"
+ outvariant "1.4.0"
+ static-browser-server "1.0.3"
+
+"@codesandbox/sandpack-react@2.19.3":
+ version "2.19.3"
+ resolved "https://registry.yarnpkg.com/@codesandbox/sandpack-react/-/sandpack-react-2.19.3.tgz#341e3dd8e96ab0af7885ea6b66e2eca0594cf64f"
+ integrity sha512-S/uyFfjlu2pyTTDoobm25RvxnfrRwp8fuXQWqrcxaCI7NkZ/aTAnIL+RC9Tf/AJJMMwcoTPKCi1g0f7zvnL+nA==
+ dependencies:
+ "@codemirror/autocomplete" "^6.4.0"
+ "@codemirror/commands" "^6.1.3"
+ "@codemirror/lang-css" "^6.0.1"
+ "@codemirror/lang-html" "^6.4.0"
+ "@codemirror/lang-javascript" "^6.1.2"
+ "@codemirror/language" "^6.3.2"
+ "@codemirror/state" "^6.2.0"
+ "@codemirror/view" "^6.7.1"
+ "@codesandbox/sandpack-client" "^2.19.0"
+ "@lezer/highlight" "^1.1.3"
+ "@react-hook/intersection-observer" "^3.1.1"
+ "@stitches/core" "^1.2.6"
+ anser "^2.1.1"
+ clean-set "^1.1.2"
+ dequal "^2.0.2"
+ escape-carriage "^1.3.1"
+ lz-string "^1.4.4"
+ react-devtools-inline "4.4.0"
+ react-is "^17.0.2"
+
"@colors/colors@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
@@ -2739,6 +2885,18 @@
dependencies:
"@emotion/memoize" "^0.8.1"
+"@emotion/is-prop-valid@^0.8.2":
+ version "0.8.8"
+ resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a"
+ integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
+ dependencies:
+ "@emotion/memoize" "0.7.4"
+
+"@emotion/memoize@0.7.4":
+ version "0.7.4"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
+ integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
+
"@emotion/memoize@^0.8.1":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17"
@@ -3415,6 +3573,52 @@
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1"
integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==
+"@lezer/common@^1.0.0", "@lezer/common@^1.0.2", "@lezer/common@^1.1.0", "@lezer/common@^1.2.0":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.2.1.tgz#198b278b7869668e1bebbe687586e12a42731049"
+ integrity sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==
+
+"@lezer/css@^1.1.0", "@lezer/css@^1.1.7":
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/@lezer/css/-/css-1.1.8.tgz#11fd456dac53bc899b266778794ed4ca9576a5a4"
+ integrity sha512-7JhxupKuMBaWQKjQoLtzhGj83DdnZY9MckEOG5+/iLKNK2ZJqKc6hf6uc0HjwCX7Qlok44jBNqZhHKDhEhZYLA==
+ dependencies:
+ "@lezer/common" "^1.2.0"
+ "@lezer/highlight" "^1.0.0"
+ "@lezer/lr" "^1.0.0"
+
+"@lezer/highlight@^1.0.0", "@lezer/highlight@^1.1.3":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@lezer/highlight/-/highlight-1.2.1.tgz#596fa8f9aeb58a608be0a563e960c373cbf23f8b"
+ integrity sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==
+ dependencies:
+ "@lezer/common" "^1.0.0"
+
+"@lezer/html@^1.3.0":
+ version "1.3.10"
+ resolved "https://registry.yarnpkg.com/@lezer/html/-/html-1.3.10.tgz#1be9a029a6fe835c823b20a98a449a630416b2af"
+ integrity sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w==
+ dependencies:
+ "@lezer/common" "^1.2.0"
+ "@lezer/highlight" "^1.0.0"
+ "@lezer/lr" "^1.0.0"
+
+"@lezer/javascript@^1.0.0":
+ version "1.4.17"
+ resolved "https://registry.yarnpkg.com/@lezer/javascript/-/javascript-1.4.17.tgz#8456e369f960c328b9e823342d0c72d704238c31"
+ integrity sha512-bYW4ctpyGK+JMumDApeUzuIezX01H76R1foD6LcRX224FWfyYit/HYxiPGDjXXe/wQWASjCvVGoukTH68+0HIA==
+ dependencies:
+ "@lezer/common" "^1.2.0"
+ "@lezer/highlight" "^1.1.3"
+ "@lezer/lr" "^1.3.0"
+
+"@lezer/lr@^1.0.0", "@lezer/lr@^1.3.0":
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-1.4.2.tgz#931ea3dea8e9de84e90781001dae30dea9ff1727"
+ integrity sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==
+ dependencies:
+ "@lezer/common" "^1.0.0"
+
"@lit-labs/ssr-dom-shim@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz#353ce4a76c83fadec272ea5674ede767650762fd"
@@ -3492,6 +3696,85 @@
dependencies:
"@types/mdx" "^2.0.0"
+"@minoru/react-dnd-treeview@^3.4.0":
+ version "3.4.4"
+ resolved "https://registry.yarnpkg.com/@minoru/react-dnd-treeview/-/react-dnd-treeview-3.4.4.tgz#3f9652ff02a06a7c22867310d6030e06fed2ffab"
+ integrity sha512-S5FRjQFag3cShU7rATx6UhaegYw+Uz3L/IXwBiD5snI+dW2Qm5Ey+8dKC+vpsVoHDYkgE/YKKWz+odGe1rNggA==
+ dependencies:
+ "@juggle/resize-observer" "^3.3.1"
+ dnd-multi-backend "^7.0.0-alpha.4"
+ framer-motion "^6.2.8"
+ react-dnd-html5-backend "^16.0.1"
+ react-dnd-touch-backend "^16.0.1"
+ react-use-measure "^2.1.1"
+
+"@monaco-editor/loader@^1.4.0":
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/@monaco-editor/loader/-/loader-1.4.0.tgz#f08227057331ec890fa1e903912a5b711a2ad558"
+ integrity sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==
+ dependencies:
+ state-local "^1.0.6"
+
+"@monaco-editor/react@4.6.0":
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-4.6.0.tgz#bcc68671e358a21c3814566b865a54b191e24119"
+ integrity sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==
+ dependencies:
+ "@monaco-editor/loader" "^1.4.0"
+
+"@motionone/animation@^10.12.0":
+ version "10.18.0"
+ resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.18.0.tgz#868d00b447191816d5d5cf24b1cafa144017922b"
+ integrity sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==
+ dependencies:
+ "@motionone/easing" "^10.18.0"
+ "@motionone/types" "^10.17.1"
+ "@motionone/utils" "^10.18.0"
+ tslib "^2.3.1"
+
+"@motionone/dom@10.12.0":
+ version "10.12.0"
+ resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.12.0.tgz#ae30827fd53219efca4e1150a5ff2165c28351ed"
+ integrity sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw==
+ dependencies:
+ "@motionone/animation" "^10.12.0"
+ "@motionone/generators" "^10.12.0"
+ "@motionone/types" "^10.12.0"
+ "@motionone/utils" "^10.12.0"
+ hey-listen "^1.0.8"
+ tslib "^2.3.1"
+
+"@motionone/easing@^10.18.0":
+ version "10.18.0"
+ resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.18.0.tgz#7b82f6010dfee3a1bb0ee83abfbaff6edae0c708"
+ integrity sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==
+ dependencies:
+ "@motionone/utils" "^10.18.0"
+ tslib "^2.3.1"
+
+"@motionone/generators@^10.12.0":
+ version "10.18.0"
+ resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.18.0.tgz#fe09ab5cfa0fb9a8884097feb7eb60abeb600762"
+ integrity sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==
+ dependencies:
+ "@motionone/types" "^10.17.1"
+ "@motionone/utils" "^10.18.0"
+ tslib "^2.3.1"
+
+"@motionone/types@^10.12.0", "@motionone/types@^10.17.1":
+ version "10.17.1"
+ resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.17.1.tgz#cf487badbbdc9da0c2cb86ffc1e5d11147c6e6fb"
+ integrity sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==
+
+"@motionone/utils@^10.12.0", "@motionone/utils@^10.18.0":
+ version "10.18.0"
+ resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.18.0.tgz#a59ff8932ed9009624bca07c56b28ef2bb2f885e"
+ integrity sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==
+ dependencies:
+ "@motionone/types" "^10.17.1"
+ hey-listen "^1.0.8"
+ tslib "^2.3.1"
+
"@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@@ -3592,6 +3875,11 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
+"@open-draft/deferred-promise@^2.1.0":
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz#4a822d10f6f0e316be4d67b4d4f8c9a124b073bd"
+ integrity sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==
+
"@opentelemetry/api-logs@0.50.0":
version "0.50.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.50.0.tgz#d46b76daab0bc18fa92dcdabacfc106c380d19a1"
@@ -4590,6 +4878,29 @@
rc-resize-observer "^1.3.1"
rc-util "^5.38.0"
+"@react-dnd/asap@^5.0.1":
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/@react-dnd/asap/-/asap-5.0.2.tgz#1f81f124c1cd6f39511c11a881cfb0f715343488"
+ integrity sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==
+
+"@react-dnd/invariant@^4.0.1":
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/@react-dnd/invariant/-/invariant-4.0.2.tgz#b92edffca10a26466643349fac7cdfb8799769df"
+ integrity sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==
+
+"@react-dnd/shallowequal@^4.0.1":
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz#d1b4befa423f692fa4abf1c79209702e7d8ae4b4"
+ integrity sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==
+
+"@react-hook/intersection-observer@^3.1.1":
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/@react-hook/intersection-observer/-/intersection-observer-3.1.2.tgz#f6f0e42588e03c4afeac0276889d97927d67edc7"
+ integrity sha512-mWU3BMkmmzyYMSuhO9wu3eJVP21N8TcgYm9bZnTrMwuM818bEk+0NRM3hP+c/TqA9Ln5C7qE53p1H0QMtzYdvQ==
+ dependencies:
+ "@react-hook/passive-layout-effect" "^1.2.0"
+ intersection-observer "^0.10.0"
+
"@react-hook/latest@^1.0.2":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@react-hook/latest/-/latest-1.0.3.tgz#c2d1d0b0af8b69ec6e2b3a2412ba0768ac82db80"
@@ -4912,6 +5223,11 @@
micromark-util-character "^1.1.0"
micromark-util-symbol "^1.0.1"
+"@stitches/core@^1.2.6":
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/@stitches/core/-/core-1.2.8.tgz#dce3b8fdc764fbc6dbea30c83b73bfb52cf96173"
+ integrity sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==
+
"@stitches/react@1.2.8", "@stitches/react@^1.2.8":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@stitches/react/-/react-1.2.8.tgz#954f8008be8d9c65c4e58efa0937f32388ce3a38"
@@ -6313,30 +6629,29 @@
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
-"@ts-rest/core@3.45.2":
- version "3.45.2"
- resolved "https://registry.yarnpkg.com/@ts-rest/core/-/core-3.45.2.tgz#9e2e1b8377bd88bfc326a01cc7599ea2199f2603"
- integrity sha512-Eiv+Sa23MbsAd1Gx9vNJ+IFCDyLZNdJ+UuGMKbFvb+/NmgcBR1VL1UIVtEkd5DJxpYMMd8SLvW91RgB2TS8iPw==
+"@ts-rest/core@3.51.0":
+ version "3.51.0"
+ resolved "https://registry.yarnpkg.com/@ts-rest/core/-/core-3.51.0.tgz#7e56fbae7abc4037a84396fb098a7eb24759d4a8"
+ integrity sha512-v6lnWEcpZj1UgN9wb84XQ+EORP1QEtncFumoXMJjno5ZUV6vdjKze3MYcQN0C6vjBpIJPQEaI/gab2jr4/0KzQ==
-"@ts-rest/open-api@3.45.2":
- version "3.45.2"
- resolved "https://registry.yarnpkg.com/@ts-rest/open-api/-/open-api-3.45.2.tgz#fa24730eac239c420f7e950fad9a787d0b706572"
- integrity sha512-TG5GvD0eyicMR3HjEAMTO2ulO7x/ADSn5bfLF/ZDdVXla48PiQdwhG4NsjVbsUDCghwx+6y5u2aTYjypzdiXQg==
+"@ts-rest/open-api@^3.51.0":
+ version "3.51.0"
+ resolved "https://registry.yarnpkg.com/@ts-rest/open-api/-/open-api-3.51.0.tgz#8f30e9a6d679143b199bc08fc9350b8b5f0ba4ae"
+ integrity sha512-fvpvRr6HIbAMNZR//QQQi75z5qTxMEBMRtmbaBXVi5e1WVVwOK7P6YBaGWTQp6DXSvsZVULX5VZXmsDd1Z1dew==
dependencies:
"@anatine/zod-openapi" "^1.12.0"
openapi3-ts "^2.0.2"
-"@ts-rest/react-query@3.45.2":
- version "3.45.2"
- resolved "https://registry.yarnpkg.com/@ts-rest/react-query/-/react-query-3.45.2.tgz#073d1728365fd6279b3bd37111fedd374973e2d4"
- integrity sha512-OFl54tb+d2vJsPENr0ehmb2KrXmXTbwEDMmoIW7iyAHEIbPiL03QreeiFykZpsRDdTUjQJY2TgOmFKCCtLozWA==
+"@ts-rest/react-query@^3.51.0":
+ version "3.51.0"
+ resolved "https://registry.yarnpkg.com/@ts-rest/react-query/-/react-query-3.51.0.tgz#fc30f2404008a8ce385a879ddd2a45a33ce42393"
+ integrity sha512-pWrbyRqvcvmjvm+ORu3zE3sPFqsS6CHOq5vra/UtyLEgXrcnEA+fu/7d9tj/+BLRwe0kOWvalu2S3/d3SDxvFQ==
-"@ts-rest/serverless@3.45.2":
- version "3.45.2"
- resolved "https://registry.yarnpkg.com/@ts-rest/serverless/-/serverless-3.45.2.tgz#d762db85d374a8e99a6345e56a5b909dc3232522"
- integrity sha512-7+37i9s9j/5OfdzLB17/PDQBco9v38WYn3fbYLr6x/zHYQqq8RfXXbmHYGvFdE+y3eizat2J0pM2Djqsb4Uppg==
+"@ts-rest/serverless@^3.51.0":
+ version "3.51.0"
+ resolved "https://registry.yarnpkg.com/@ts-rest/serverless/-/serverless-3.51.0.tgz#40b7e99dc4957473133b1473f1faa475702c3aa2"
+ integrity sha512-BjwmLPgnYifdDjSpSvhZk+v1P+3CiM/jpxKNUgdw8RfgnDy/+aaOPmAcSkjhBCOIu6ASChuv/sNpiuWx3YyPUw==
dependencies:
- "@ts-rest/core" "3.45.2"
itty-router "^5.0.9"
"@tsconfig/node10@^1.0.7":
@@ -7858,6 +8173,11 @@ algoliasearch@^4.18.0, algoliasearch@^4.19.1:
"@algolia/requester-node-http" "4.23.3"
"@algolia/transporter" "4.23.3"
+anser@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/anser/-/anser-2.1.1.tgz#8afae28d345424c82de89cc0e4d1348eb0c5af7c"
+ integrity sha512-nqLm4HxOTpeLOxcmB3QWmV5TcDFhW9y/fyQ+hivtDFcK4OQ+pQ5fzPnXHM1Mfcm0VkLtvVi1TCPr++Qy0Q/3EQ==
+
ansi-align@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
@@ -9279,6 +9599,11 @@ clean-css@^5.2.2, clean-css@^5.3.2, clean-css@~5.3.2:
dependencies:
source-map "~0.6.0"
+clean-set@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/clean-set/-/clean-set-1.1.2.tgz#76d8bf238c3e27827bfa73073ecdfdc767187070"
+ integrity sha512-cA8uCj0qSoG9e0kevyOWXwPaELRPVg5Pxp6WskLMwerx257Zfnh8Nl0JBH59d7wQzij2CK7qEfJQK3RjuKKIug==
+
clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
@@ -9873,6 +10198,11 @@ create-require@^1.1.0:
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
+crelt@^1.0.5:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.6.tgz#7cc898ea74e190fb6ef9dae57f8f81cf7302df72"
+ integrity sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==
+
critters@0.0.16:
version "0.0.16"
resolved "https://registry.yarnpkg.com/critters/-/critters-0.0.16.tgz#ffa2c5561a65b43c53b940036237ce72dcebfe93"
@@ -11057,6 +11387,20 @@ direction@^2.0.0:
resolved "https://registry.yarnpkg.com/direction/-/direction-2.0.1.tgz#71800dd3c4fa102406502905d3866e65bdebb985"
integrity sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==
+dnd-core@^16.0.1:
+ version "16.0.1"
+ resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-16.0.1.tgz#a1c213ed08961f6bd1959a28bb76f1a868360d19"
+ integrity sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==
+ dependencies:
+ "@react-dnd/asap" "^5.0.1"
+ "@react-dnd/invariant" "^4.0.1"
+ redux "^4.2.0"
+
+dnd-multi-backend@^7.0.0-alpha.4:
+ version "7.1.3"
+ resolved "https://registry.yarnpkg.com/dnd-multi-backend/-/dnd-multi-backend-7.1.3.tgz#401ba42bb4ee79246a966cd3c5bfafbc3ed6e57c"
+ integrity sha512-INOAt4p/5fkaAUpXu0I+ialm1Ewi9HmIhs/558RFrhBZ0s/XGL991w3A2GvBuaPQNsZJEzCJh0mv/0dswxfSfQ==
+
dns-packet@^5.2.2:
version "5.6.1"
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f"
@@ -11251,7 +11595,7 @@ dotenv@16.0.3:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07"
integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==
-dotenv@^16.0.0:
+dotenv@^16.0.0, dotenv@^16.0.3:
version "16.4.5"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
@@ -11622,7 +11966,7 @@ es6-promise@^3.2.1:
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613"
integrity sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==
-es6-symbol@^3.1.1, es6-symbol@^3.1.3:
+es6-symbol@^3, es6-symbol@^3.1.1, es6-symbol@^3.1.3:
version "3.1.4"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c"
integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==
@@ -11705,6 +12049,11 @@ escalade@^3.1.1, escalade@^3.1.2:
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
+escape-carriage@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/escape-carriage/-/escape-carriage-1.3.1.tgz#842658e5422497b1232585e517dc813fc6a86170"
+ integrity sha512-GwBr6yViW3ttx1kb7/Oh+gKQ1/TrhYwxKqVmg5gS+BK+Qe2KrOa/Vh7w3HPBvgGf0LfcDGoY9I6NHKoA5Hozhw==
+
escape-goat@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-4.0.0.tgz#9424820331b510b0666b98f7873fe11ac4aa8081"
@@ -12872,6 +13221,27 @@ fragment-cache@^0.2.1:
dependencies:
map-cache "^0.2.2"
+framer-motion@^6.2.8:
+ version "6.5.1"
+ resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.5.1.tgz#802448a16a6eb764124bf36d8cbdfa6dd6b931a7"
+ integrity sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==
+ dependencies:
+ "@motionone/dom" "10.12.0"
+ framesync "6.0.1"
+ hey-listen "^1.0.8"
+ popmotion "11.0.3"
+ style-value-types "5.0.0"
+ tslib "^2.1.0"
+ optionalDependencies:
+ "@emotion/is-prop-valid" "^0.8.2"
+
+framesync@6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.0.1.tgz#5e32fc01f1c42b39c654c35b16440e07a25d6f20"
+ integrity sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==
+ dependencies:
+ tslib "^2.1.0"
+
framework-utils@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/framework-utils/-/framework-utils-1.1.0.tgz#a3b528bce838dfd623148847dc92371b09d0da2d"
@@ -13032,6 +13402,11 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2, get-intrinsic@
has-symbols "^1.0.3"
hasown "^2.0.0"
+get-node-dimensions@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz#fb7b4bb57060fb4247dd51c9d690dfbec56b0823"
+ integrity sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ==
+
get-nonce@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3"
@@ -13931,6 +14306,11 @@ he@^1.2.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+hey-listen@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68"
+ integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
+
highlight.js@^10.4.1, highlight.js@~10.7.0:
version "10.7.3"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
@@ -14464,6 +14844,11 @@ interpret@^1.0.0:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
+intersection-observer@^0.10.0:
+ version "0.10.0"
+ resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.10.0.tgz#4d11d63c1ff67e21e62987be24d55218da1a1a69"
+ integrity sha512-fn4bQ0Xq8FTej09YC/jqKZwtijpvARlRp6wxL5WTA6yPe2YWSJ5RJh7Nm79rK2qB0wr6iDQzH60XGq5V/7u8YQ==
+
invariant@^2.2.2, invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
@@ -16249,6 +16634,11 @@ lodash.startcase@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8"
integrity sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==
+lodash.throttle@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
+ integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
+
lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
@@ -16389,7 +16779,7 @@ lunr@^2.3.9:
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
-lz-string@^1.5.0:
+lz-string@^1.4.4, lz-string@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==
@@ -17594,6 +17984,11 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2":
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
+mime-db@^1.52.0:
+ version "1.53.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.53.0.tgz#3cb63cd820fc29896d9d4e8c32ab4fcd74ccb447"
+ integrity sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==
+
mime-db@~1.33.0:
version "1.33.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
@@ -18723,6 +19118,16 @@ outdent@^0.5.0:
resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.5.0.tgz#9e10982fdc41492bb473ad13840d22f9655be2ff"
integrity sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==
+outvariant@1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.0.tgz#e742e4bda77692da3eca698ef5bfac62d9fba06e"
+ integrity sha512-AlWY719RF02ujitly7Kk/0QlV+pXGFDHrHf9O2OKqyqgBieaPOIeuSkL8sRK6j2WK+/ZAURq2kZsY0d8JapUiw==
+
+outvariant@^1.3.0, outvariant@^1.4.0:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.3.tgz#221c1bfc093e8fec7075497e7799fdbf43d14873"
+ integrity sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==
+
p-cancelable@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
@@ -19325,6 +19730,16 @@ polished@^4.1.3, polished@^4.2.2:
dependencies:
"@babel/runtime" "^7.17.8"
+popmotion@11.0.3:
+ version "11.0.3"
+ resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-11.0.3.tgz#565c5f6590bbcddab7a33a074bb2ba97e24b0cc9"
+ integrity sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==
+ dependencies:
+ framesync "6.0.1"
+ hey-listen "^1.0.8"
+ style-value-types "5.0.0"
+ tslib "^2.1.0"
+
popper.js@^1.16.0:
version "1.16.1"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
@@ -20377,7 +20792,7 @@ prompts@^2.0.1, prompts@^2.4.0, prompts@^2.4.2:
kleur "^3.0.3"
sisteransi "^1.0.5"
-prop-types@^15.5.0, prop-types@^15.5.7, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
+prop-types@^15.5.0, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -20806,6 +21221,39 @@ react-dev-utils@^12.0.1:
strip-ansi "^6.0.1"
text-table "^0.2.0"
+react-devtools-inline@4.4.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/react-devtools-inline/-/react-devtools-inline-4.4.0.tgz#e032a6eb17a9977b682306f84b46e683adf4bf68"
+ integrity sha512-ES0GolSrKO8wsKbsEkVeiR/ZAaHQTY4zDh1UW8DImVmm8oaGLl3ijJDvSGe+qDRKPZdPRnDtWWnSvvrgxXdThQ==
+ dependencies:
+ es6-symbol "^3"
+
+react-dnd-html5-backend@^16.0.1:
+ version "16.0.1"
+ resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz#87faef15845d512a23b3c08d29ecfd34871688b6"
+ integrity sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==
+ dependencies:
+ dnd-core "^16.0.1"
+
+react-dnd-touch-backend@^16.0.1:
+ version "16.0.1"
+ resolved "https://registry.yarnpkg.com/react-dnd-touch-backend/-/react-dnd-touch-backend-16.0.1.tgz#e73f8169e2b9fac0f687970f875cac0a4d02d6e2"
+ integrity sha512-NonoCABzzjyWGZuDxSG77dbgMZ2Wad7eQiCd/ECtsR2/NBLTjGksPUx9UPezZ1nQ/L7iD130Tz3RUshL/ClKLA==
+ dependencies:
+ "@react-dnd/invariant" "^4.0.1"
+ dnd-core "^16.0.1"
+
+react-dnd@^16.0.1:
+ version "16.0.1"
+ resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-16.0.1.tgz#2442a3ec67892c60d40a1559eef45498ba26fa37"
+ integrity sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==
+ dependencies:
+ "@react-dnd/invariant" "^4.0.1"
+ "@react-dnd/shallowequal" "^4.0.1"
+ dnd-core "^16.0.1"
+ fast-deep-equal "^3.1.3"
+ hoist-non-react-statics "^3.3.2"
+
react-docgen-typescript@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c"
@@ -20938,7 +21386,7 @@ react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-react-is@^17.0.1:
+react-is@^17.0.1, react-is@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
@@ -21014,6 +21462,16 @@ react-markdown@^9.0.1, react-markdown@~9.0.1:
unist-util-visit "^5.0.0"
vfile "^6.0.0"
+react-measure@^2.0.2:
+ version "2.5.2"
+ resolved "https://registry.yarnpkg.com/react-measure/-/react-measure-2.5.2.tgz#4ffc410e8b9cb836d9455a9ff18fc1f0fca67f89"
+ integrity sha512-M+rpbTLWJ3FD6FXvYV6YEGvQ5tMayQ3fGrZhRPHrE9bVlBYfDCLuDcgNttYfk8IqfOI03jz6cbpqMRTUclQnaA==
+ dependencies:
+ "@babel/runtime" "^7.2.0"
+ get-node-dimensions "^1.2.1"
+ prop-types "^15.6.2"
+ resize-observer-polyfill "^1.5.0"
+
react-no-ssr@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/react-no-ssr/-/react-no-ssr-1.1.0.tgz#313b48d2e26020f969ed98e472f10481604e3cc8"
@@ -21041,6 +21499,16 @@ react-redux@^9.1.2:
"@types/use-sync-external-store" "^0.0.3"
use-sync-external-store "^1.0.0"
+react-reflex@4.2.6:
+ version "4.2.6"
+ resolved "https://registry.yarnpkg.com/react-reflex/-/react-reflex-4.2.6.tgz#96923704102fe0baebe140968d770f4018715d79"
+ integrity sha512-MLGty/ii/BTipKZ47dfs8Ue5g1xqgCxUCDM34ruEr0UVJuXGDzcSX9wPMzRcv4dUR+1tw4hm4c3a6V6hLO2XcA==
+ dependencies:
+ "@babel/runtime" "^7.0.0"
+ lodash.throttle "^4.1.1"
+ prop-types "^15.5.8"
+ react-measure "^2.0.2"
+
react-remove-scroll-bar@^2.3.3, react-remove-scroll-bar@^2.3.4:
version "2.3.6"
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c"
@@ -21159,6 +21627,13 @@ react-universal-interface@^0.6.2:
resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b"
integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==
+react-use-measure@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/react-use-measure/-/react-use-measure-2.1.1.tgz#5824537f4ee01c9469c45d5f7a8446177c6cc4ba"
+ integrity sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==
+ dependencies:
+ debounce "^1.2.1"
+
react-use@17.4.0:
version "17.4.0"
resolved "https://registry.yarnpkg.com/react-use/-/react-use-17.4.0.tgz#cefef258b0a6c534a5c8021c2528ac6e1a4cdc6d"
@@ -21402,7 +21877,7 @@ redux-immutable@^4.0.0:
resolved "https://registry.yarnpkg.com/redux-immutable/-/redux-immutable-4.0.0.tgz#3a1a32df66366462b63691f0e1dc35e472bbc9f3"
integrity sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==
-redux@4.2.1, redux@^4.2.1:
+redux@4.2.1, redux@^4.2.0, redux@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197"
integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
@@ -21823,7 +22298,7 @@ reselect@^5.1.0:
resolved "https://registry.yarnpkg.com/reselect/-/reselect-5.1.1.tgz#c766b1eb5d558291e5e550298adb0becc24bb72e"
integrity sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==
-resize-observer-polyfill@^1.5.1:
+resize-observer-polyfill@^1.5.0, resize-observer-polyfill@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
@@ -22163,6 +22638,14 @@ samsam@1.3.0:
resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50"
integrity sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==
+sandpack-file-explorer@0.0.7:
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/sandpack-file-explorer/-/sandpack-file-explorer-0.0.7.tgz#28d1b16f866490c4a8b24c47d7eb1f27b50464d0"
+ integrity sha512-69Ytle9cC6VLtZ9ZX5Yf6Tup5lOjagQKfnsHpKOBsNQGKSVOGPEXOjkpeIncXONKdpCKOu7kAjrh3SgphUjpPg==
+ dependencies:
+ "@minoru/react-dnd-treeview" "^3.4.0"
+ react-dnd "^16.0.1"
+
sane@^4.0.3:
version "4.1.0"
resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded"
@@ -23019,6 +23502,21 @@ start-server-and-test@^2.0.4:
ps-tree "1.2.0"
wait-on "7.2.0"
+state-local@^1.0.6:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/state-local/-/state-local-1.0.7.tgz#da50211d07f05748d53009bee46307a37db386d5"
+ integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==
+
+static-browser-server@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/static-browser-server/-/static-browser-server-1.0.3.tgz#9030d141b99ed92c8eec1a7546b87548fd036f5d"
+ integrity sha512-ZUyfgGDdFRbZGGJQ1YhiM930Yczz5VlbJObrQLlk24+qNHVQx4OlLcYswEUo3bIyNAbQUIUR9Yr5/Hqjzqb4zA==
+ dependencies:
+ "@open-draft/deferred-promise" "^2.1.0"
+ dotenv "^16.0.3"
+ mime-db "^1.52.0"
+ outvariant "^1.3.0"
+
static-extend@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
@@ -23104,6 +23602,11 @@ streamsearch@^1.1.0:
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
+strict-event-emitter@^0.4.3:
+ version "0.4.6"
+ resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.4.6.tgz#ff347c8162b3e931e3ff5f02cfce6772c3b07eb3"
+ integrity sha512-12KWeb+wixJohmnwNFerbyiBrAlq5qJLwIt38etRtKtmmHyDSoGlIqFE9wx+4IwG0aDjI7GV8tc8ZccjWZZtTg==
+
string-argv@0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6"
@@ -23390,6 +23893,11 @@ style-dictionary@^4.0.0-prerelease.22, style-dictionary@^4.0.0-prerelease.38:
path-unified "^0.1.0"
tinycolor2 "^1.6.0"
+style-mod@^4.0.0, style-mod@^4.1.0:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.1.2.tgz#ca238a1ad4786520f7515a8539d5a63691d7bf67"
+ integrity sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==
+
style-to-object@^0.4.0:
version "0.4.4"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.4.tgz#266e3dfd56391a7eefb7770423612d043c3f33ec"
@@ -23404,6 +23912,14 @@ style-to-object@^1.0.0:
dependencies:
inline-style-parser "0.2.3"
+style-value-types@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-5.0.0.tgz#76c35f0e579843d523187989da866729411fc8ad"
+ integrity sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==
+ dependencies:
+ hey-listen "^1.0.8"
+ tslib "^2.1.0"
+
styled-components@^6.0.5:
version "6.1.11"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.1.11.tgz#01948e5195bf1d39e57e0a85b41958c80e40cfb8"
@@ -24108,6 +24624,11 @@ tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==
+tslib@^2.3.1:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b"
+ integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==
+
tsx@^4.9.3:
version "4.15.7"
resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.15.7.tgz#69d7499196a323507c4051d2ba10753edcc057e5"
@@ -24952,6 +25473,11 @@ w3c-hr-time@^1.0.2:
dependencies:
browser-process-hrtime "^1.0.0"
+w3c-keyname@^2.2.4:
+ version "2.2.8"
+ resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.8.tgz#7b17c8c6883d4e8b86ac8aba79d39e880f8869c5"
+ integrity sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==
+
w3c-xmlserializer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"