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 @@ + + + React Logo + + + + + + + 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 @@ + + + Solid + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + + + + + + + + + + + + + + + + + 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"