From fc5a6d711964606ccc362d6de4cd9f0a0b05e6c4 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 16:16:58 -0800 Subject: [PATCH 01/31] Remove need for weird TS iterable thingy --- core/src/plugins/debuggerPlugin/index.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/plugins/debuggerPlugin/index.ts b/core/src/plugins/debuggerPlugin/index.ts index 87354c8a2..94f0a3cc0 100644 --- a/core/src/plugins/debuggerPlugin/index.ts +++ b/core/src/plugins/debuggerPlugin/index.ts @@ -48,9 +48,12 @@ function install( if (!server) { node.data.error = true - const nodeView = [...editor.view.nodes.values()].find( - n => n.node.id === node.id - ) + const nodeValues = Array.from(editor.view.nodes) + const foundNode = nodeValues.find(([, n]) => n.node.id === node.id) + + if (!foundNode) return + + const nodeView = foundNode[1] nodeView?.onStart() nodeView?.node.update() From 7e588a8d387e46460bacb3ed8d3bec895c2f1f0c Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 16:17:11 -0800 Subject: [PATCH 02/31] Remove downlevel iteration from tsconfig --- tsconfig.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 48e1d6471..68ff11207 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,8 +19,7 @@ "strictNullChecks": true, "strict": false, "rootDir": ".", - "noEmit": true, - "downlevelIteration": true + "noEmit": true }, "exclude": ["node_modules", "dist", "*.d.ts"], "typeRoots": ["@types/@thoth"] From b83bef01b44150f6bc7184323030daf531622c06 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 16:17:18 -0800 Subject: [PATCH 03/31] Clean up scripts --- client/scripts/engine.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/client/scripts/engine.ts b/client/scripts/engine.ts index e50e6c4f0..01f43d336 100644 --- a/client/scripts/engine.ts +++ b/client/scripts/engine.ts @@ -1,13 +1,7 @@ import thothCore from '@latitudegames/thoth-core/dist/server' const { - components: { - moduleInput, - moduleOutput, - moduleTriggerIn, - moduleTriggerOut, - tenseTransformer, - }, + components: { moduleInput, moduleOutput, tenseTransformer }, } = thothCore export const components = [ @@ -26,8 +20,6 @@ export const components = [ // new ModuleComponent(), moduleInput(), moduleOutput(), - moduleTriggerOut(), - moduleTriggerIn(), // new PlaytestPrint(), // new PlaytestInput(), // new RunInputComponent(), From b1b45a5884b159dc59fbd29f5f4528872ea365c2 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 16:31:34 -0800 Subject: [PATCH 04/31] Add engine context to root core type --- core/types.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/types.ts b/core/types.ts index 138a6f846..2aeef0cc9 100644 --- a/core/types.ts +++ b/core/types.ts @@ -1,5 +1,5 @@ /* eslint-disable camelcase */ -import { Component, Connection, Input, Output } from 'rete' +import { Component, Connection, Input, Output, NodeEditor } from 'rete' import { Node } from 'rete/types' //@seang todo: convert inspector plugin fully to typescript // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -14,6 +14,7 @@ import { Inspector } from './src/plugins/inspectorPlugin/Inspector' import { ModuleGraphData } from './src/plugins/modulePlugin/module-manager' import { TaskOutputTypes } from './src/plugins/taskPlugin/task' import { SocketNameType, SocketType } from './src/sockets' +import { EngineContext } from './src/engine' import { ThothTask } from './src/thoth-component' export type EventsTypes = { @@ -31,6 +32,11 @@ export type EventsTypes = { resetconnection: void } +export interface IRunContextEditor extends NodeEditor { + thoth: EngineContext + abort: Function +} + export type DataSocketType = { name: SocketNameType taskType: 'output' | 'option' From 357ed15748d7e7ac4799f8779a704b50d4772e7f Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 16:33:33 -0800 Subject: [PATCH 05/31] Use engine context from root types in debugger plugin --- core/src/plugins/debuggerPlugin/index.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/core/src/plugins/debuggerPlugin/index.ts b/core/src/plugins/debuggerPlugin/index.ts index 94f0a3cc0..5e3e5b378 100644 --- a/core/src/plugins/debuggerPlugin/index.ts +++ b/core/src/plugins/debuggerPlugin/index.ts @@ -1,10 +1,5 @@ -import { NodeEditor } from 'rete/types' -import { EngineContext } from '../../engine' +import { IRunContextEditor } from '../../../types' import { ThothComponent } from '../../thoth-component' -interface IRunContextEditor extends NodeEditor { - thoth: EngineContext - abort: Function -} function install( editor: IRunContextEditor, From 842ef7f1fd127b0047443b4c3a52feb832180eec Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 16:37:33 -0800 Subject: [PATCH 06/31] Update engine context --- core/src/engine.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/engine.ts b/core/src/engine.ts index 097416198..aafb61c4f 100644 --- a/core/src/engine.ts +++ b/core/src/engine.ts @@ -58,6 +58,9 @@ export type EngineContext = { onAddModule?: Function onUpdateModule?: Function sendToPlaytest?: Function + onInspector?: Function + sendToInspector?: Function + clearTextEditor?: Function } export type InitEngineArguments = { From 24ff9059258a39b1d4fa3444d00bd40a3ce35b7c Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 16:42:43 -0800 Subject: [PATCH 07/31] Add more types to thoth node --- core/types.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/types.ts b/core/types.ts index 2aeef0cc9..25f4bf848 100644 --- a/core/types.ts +++ b/core/types.ts @@ -49,6 +49,11 @@ export type ThothNode = Node & { inspector: Inspector display: (content: string) => void outputs: { name: string; [key: string]: unknown }[] + category?: string + deprecated?: boolean + displayName?: string + info: string + subscription: Function } export type ModuleType = { From 3c50e876895cc85b84a964edf09cd50e2f412035 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 16:42:53 -0800 Subject: [PATCH 08/31] Add todo to engine context type --- core/src/engine.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/engine.ts b/core/src/engine.ts index aafb61c4f..259ab8d00 100644 --- a/core/src/engine.ts +++ b/core/src/engine.ts @@ -38,6 +38,8 @@ export abstract class ThothEngineComponent { ...args: unknown[] ): WorkerReturnType } + +// TODO separate the engine context out from the editor context for cleaner typing. export type EngineContext = { completion: ( body: ModelCompletionOpts From 986379d37ec9b3dad953bcbdc30f2174baf5e579 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 16:43:07 -0800 Subject: [PATCH 09/31] Convert inspector plugin to typescript --- .../plugins/inspectorPlugin/{index.js => index.ts} | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) rename core/src/plugins/inspectorPlugin/{index.js => index.ts} (82%) diff --git a/core/src/plugins/inspectorPlugin/index.js b/core/src/plugins/inspectorPlugin/index.ts similarity index 82% rename from core/src/plugins/inspectorPlugin/index.js rename to core/src/plugins/inspectorPlugin/index.ts index 03efd8b19..162706130 100644 --- a/core/src/plugins/inspectorPlugin/index.js +++ b/core/src/plugins/inspectorPlugin/index.ts @@ -1,9 +1,10 @@ +import { IRunContextEditor, ThothNode } from '../../../types' // @seang todo: convert data controls to typescript to remove this // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore import { Inspector } from './Inspector' -function install(editor) { +function install(editor: IRunContextEditor) { const { onInspector, sendToInspector, clearTextEditor } = editor.thoth editor.on('componentregister', component => { @@ -15,7 +16,7 @@ function install(editor) { ) // we are going to override the default builder with our own, and will invoke the original builder inside it. - component.builder = node => { + component.builder = (node: ThothNode) => { // This will unsubscribe us // if (node.subscription) node.subscription() // Inspector class which will handle regsistering data controls, serializing, etc. @@ -33,7 +34,9 @@ function install(editor) { // here we attach the default info control to the component which will show up in the inspector - node.subscription = onInspector(node, data => { + if (!onInspector) return + + node.subscription = onInspector(node, (data: unknown) => { node.inspector.handleData(data) editor.trigger('nodecreated') // NOTE might still need this. Keep an eye out. @@ -44,11 +47,12 @@ function install(editor) { } }) - let currentNode + let currentNode: ThothNode | undefined // handle publishing and subscribing to inspector - editor.on('nodeselect', node => { + editor.on('nodeselect', (node: ThothNode) => { if (currentNode && node.id === currentNode.id) return + if (!clearTextEditor || !sendToInspector) return currentNode = node clearTextEditor() sendToInspector(node.inspector.data()) From 64d0d6feca0d77b9f0ca599eccef2f919dbb5bb0 Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 16:56:07 -0800 Subject: [PATCH 10/31] change StateWrite to ts --- core/src/components/StateWrite.ts | 76 +++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 core/src/components/StateWrite.ts diff --git a/core/src/components/StateWrite.ts b/core/src/components/StateWrite.ts new file mode 100644 index 000000000..79a4e2355 --- /dev/null +++ b/core/src/components/StateWrite.ts @@ -0,0 +1,76 @@ +import Rete from 'rete' + +import { SocketGeneratorControl } from '../dataControls/SocketGenerator' +import { triggerSocket } from '../sockets' +import { ThothComponent } from '../thoth-component' + +const info = `The State Write component allows you to define any number of inputs, and to write values to the state manager which correspond to the names of those inputs. If the value does not exist in the state, it will be written. + +Note here that there are a few assumptions made, which will be changed once we have selectable socket types when generating inputs. If the key already exists in the state and it is an array, whatever value you insert will be added to the array. If the existing value is an object, the object will be updated by the incoming value.` + +export class StateWrite extends ThothComponent { + constructor() { + // Name of the component + super('State Write') + + this.task = { + outputs: {}, + } + + this.workspaceType = 'spell' + this.category = 'State' + this.info = info + } + + builder(node) { + const dataInput = new Rete.Input('trigger', 'Trigger', triggerSocket, true) + + const inputGenerator = new SocketGeneratorControl({ + connectionType: 'input', + ignored: ['trigger'], + name: 'Input Sockets', + }) + + node.inspector.add(inputGenerator) + node.addInput(dataInput) + + return node + } + + async worker(node, inputs, outputs, { thoth }) { + const { getCurrentGameState, updateCurrentGameState } = thoth + + try { + const gameState = await getCurrentGameState() + let value + + const updates = Object.entries(inputs).reduce((acc, [key, val]) => { + // Check here what type of data structure the gameState for the key is + switch (typeof gameState[key]) { + case 'object': + // if we have an array, add the value to the array and reassign to the state + if (Array.isArray(gameState[key])) { + value = [...gameState[key], val[0]] + break + } + + // if it is an object, we assume that the incoming data is an object update + value = { ...gameState[key], ...val[0] } + + break + default: + // default is to just overwrite whatever value is there with a new one. + value = val[0] + } + + acc[key] = value + + return acc + }, {}) + + await updateCurrentGameState(updates) + } catch (err) { + throw new Error('Error in State Write component') + } + } +} From 4caa1a3fb9dd9218886dc1c6f6d6350c29137dac Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 16:57:10 -0800 Subject: [PATCH 11/31] add type to builder in state write --- core/src/components/StateWrite.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/components/StateWrite.ts b/core/src/components/StateWrite.ts index 79a4e2355..9b479afb8 100644 --- a/core/src/components/StateWrite.ts +++ b/core/src/components/StateWrite.ts @@ -1,4 +1,5 @@ import Rete from 'rete' +import { ThothNode } from '../../types' import { SocketGeneratorControl } from '../dataControls/SocketGenerator' import { triggerSocket } from '../sockets' @@ -22,7 +23,7 @@ export class StateWrite extends ThothComponent { this.info = info } - builder(node) { + builder(node: ThothNode) { const dataInput = new Rete.Input('trigger', 'Trigger', triggerSocket, true) const inputGenerator = new SocketGeneratorControl({ From d78fd2489a6859c023c15273cb754ba1ee7ec68d Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 16:58:38 -0800 Subject: [PATCH 12/31] add types to worker arguments in state write --- core/src/components/StateWrite.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/core/src/components/StateWrite.ts b/core/src/components/StateWrite.ts index 9b479afb8..6d504f0ee 100644 --- a/core/src/components/StateWrite.ts +++ b/core/src/components/StateWrite.ts @@ -1,7 +1,13 @@ import Rete from 'rete' -import { ThothNode } from '../../types' +import { + NodeData, + ThothNode, + ThothWorkerInputs, + ThothWorkerOutputs, +} from '../../types' import { SocketGeneratorControl } from '../dataControls/SocketGenerator' +import { EngineContext } from '../engine' import { triggerSocket } from '../sockets' import { ThothComponent } from '../thoth-component' @@ -38,7 +44,12 @@ export class StateWrite extends ThothComponent { return node } - async worker(node, inputs, outputs, { thoth }) { + async worker( + node: NodeData, + inputs: ThothWorkerInputs, + outputs: ThothWorkerOutputs, + { thoth }: { thoth: EngineContext } + ) { const { getCurrentGameState, updateCurrentGameState } = thoth try { From 5993adfe56a14e996a028e634911d25fa49991d3 Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 16:59:29 -0800 Subject: [PATCH 13/31] add generic type to gamestate in state write --- core/src/components/StateWrite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/components/StateWrite.ts b/core/src/components/StateWrite.ts index 6d504f0ee..8cfb7d6a5 100644 --- a/core/src/components/StateWrite.ts +++ b/core/src/components/StateWrite.ts @@ -53,7 +53,7 @@ export class StateWrite extends ThothComponent { const { getCurrentGameState, updateCurrentGameState } = thoth try { - const gameState = await getCurrentGameState() + const gameState = (await getCurrentGameState()) as Record let value const updates = Object.entries(inputs).reduce((acc, [key, val]) => { From 0def362ce39df1c08c2804da7a39db0644e30530 Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 17:00:00 -0800 Subject: [PATCH 14/31] add type to value in state write --- core/src/components/StateWrite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/components/StateWrite.ts b/core/src/components/StateWrite.ts index 8cfb7d6a5..a5777b2b5 100644 --- a/core/src/components/StateWrite.ts +++ b/core/src/components/StateWrite.ts @@ -67,7 +67,7 @@ export class StateWrite extends ThothComponent { } // if it is an object, we assume that the incoming data is an object update - value = { ...gameState[key], ...val[0] } + value = { ...gameState[key], ...(val[0] as unknown[]) } break default: From 48dc6edfd15451e5b5da898fdb7e24a05a0db8ac Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 17:00:58 -0800 Subject: [PATCH 15/31] add type to intial accumilator object --- core/src/components/StateWrite.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/components/StateWrite.ts b/core/src/components/StateWrite.ts index a5777b2b5..a9f615544 100644 --- a/core/src/components/StateWrite.ts +++ b/core/src/components/StateWrite.ts @@ -78,7 +78,7 @@ export class StateWrite extends ThothComponent { acc[key] = value return acc - }, {}) + }, {} as Record) await updateCurrentGameState(updates) } catch (err) { From cd73eb97833dfb46081f654ba0626dc754f93207 Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 17:01:27 -0800 Subject: [PATCH 16/31] delete js statewrite file --- core/src/components/StateWrite.js | 76 ------------------------------- 1 file changed, 76 deletions(-) delete mode 100644 core/src/components/StateWrite.js diff --git a/core/src/components/StateWrite.js b/core/src/components/StateWrite.js deleted file mode 100644 index ceb5b5fee..000000000 --- a/core/src/components/StateWrite.js +++ /dev/null @@ -1,76 +0,0 @@ -import Rete from 'rete' - -import { SocketGeneratorControl } from '../dataControls/SocketGenerator' -import { triggerSocket } from '../sockets' -import { ThothComponent } from '../thoth-component' - -const info = `The State Write component allows you to define any number of inputs, and to write values to the state manager which correspond to the names of those inputs. If the value does not exist in the state, it will be written. - -Note here that there are a few assumptions made, which will be changed once we have selectable socket types when generating inputs. If the key already exists in the state and it is an array, whatever value you insert will be added to the array. If the existing value is an object, the object will be updated by the incoming value.` - -export class StateWrite extends ThothComponent { - constructor() { - // Name of the component - super('State Write') - - this.task = { - outputs: {}, - } - - this.workspaceType = 'spell' - this.category = 'State' - this.info = info - } - - builder(node) { - const dataInput = new Rete.Input('trigger', 'Trigger', triggerSocket, true) - - const inputGenerator = new SocketGeneratorControl({ - connectionType: 'input', - ignored: ['trigger'], - name: 'Input Sockets', - }) - - node.inspector.add(inputGenerator) - node.addInput(dataInput) - - return node - } - - async worker(node, inputs, outputs, { thoth }) { - const { getCurrentGameState, updateCurrentGameState } = thoth - - try { - const gameState = await getCurrentGameState() - let value - - const updates = Object.entries(inputs).reduce((acc, [key, val]) => { - // Check here what type of data structure the gameState for the key is - switch (typeof gameState[key]) { - case 'object': - // if we have an array, add the value to the array and reassign to the state - if (Array.isArray(gameState[key])) { - value = [...gameState[key], val[0]] - break - } - - // if it is an object, we assume that the incoming data is an object update - value = { ...gameState[key], ...val[0] } - - break - default: - // default is to just overwrite whatever value is there with a new one. - value = val[0] - } - - acc[key] = value - - return acc - }, {}) - - await updateCurrentGameState(updates) - } catch (err) { - throw new Error('Error in State Write component') - } - } -} From 0856e0269901bbe265a7da2aea10a2722e108cd7 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 17:07:54 -0800 Subject: [PATCH 17/31] Add types to data control --- core/src/plugins/inspectorPlugin/DataControl.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/plugins/inspectorPlugin/DataControl.ts b/core/src/plugins/inspectorPlugin/DataControl.ts index 645ed4496..86383a900 100644 --- a/core/src/plugins/inspectorPlugin/DataControl.ts +++ b/core/src/plugins/inspectorPlugin/DataControl.ts @@ -1,4 +1,5 @@ -import { Node, NodeEditor, Component } from 'rete' +import { Node, NodeEditor } from 'rete' +import { ThothComponent } from '../../thoth-component' import { Inspector } from './Inspector' export type RestProps = {} @@ -6,9 +7,10 @@ export abstract class DataControl { inspector: Inspector | null = null editor: NodeEditor | null = null node: Node | null = null - component: Component | null = null + component: ThothComponent | null = null id: string | null = null dataKey: string + key: string name: string defaultValue: unknown componentData: object From 636954a683349272370b4e7ee4373c45483fa812 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 17:08:15 -0800 Subject: [PATCH 18/31] Converting inspector to typescript --- .../{Inspector.js => Inspector.ts} | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) rename core/src/plugins/inspectorPlugin/{Inspector.js => Inspector.ts} (85%) diff --git a/core/src/plugins/inspectorPlugin/Inspector.js b/core/src/plugins/inspectorPlugin/Inspector.ts similarity index 85% rename from core/src/plugins/inspectorPlugin/Inspector.js rename to core/src/plugins/inspectorPlugin/Inspector.ts index 4b75972de..d34e799f1 100644 --- a/core/src/plugins/inspectorPlugin/Inspector.js +++ b/core/src/plugins/inspectorPlugin/Inspector.ts @@ -1,14 +1,33 @@ import deepEqual from 'deep-equal' import Rete from 'rete' import { v4 as uuidv4 } from 'uuid' +import { DataSocketType, IRunContextEditor, ThothNode } from '../../../types' +import { ThothComponent } from '../../thoth-component' import * as socketMap from '../../sockets' +import { DataControl } from './DataControl' + +type InspectorConstructor = { + component: ThothComponent + editor: IRunContextEditor + node: ThothNode +} + +// todo improve this typing +type DataControlData = Record + export class Inspector { // Stub of function. Can be a nodes catch all onData - onData = () => {} - cache = {} - - constructor({ component, editor, node }) { + onData = Function + cache: Record = {} + node: ThothNode + component: ThothComponent + editor: IRunContextEditor + dataControls: Map + category: string + info: string + + constructor({ component, editor, node }: InspectorConstructor) { this.component = component this.editor = editor this.dataControls = new Map() @@ -17,7 +36,7 @@ export class Inspector { this.info = component.info } - _add(list, control, prop) { + _add(list, control: DataControl, prop: keyof DataControl) { if (list.has(control.key)) throw new Error( `Item with key '${control.key}' already been added to the inspector` @@ -39,13 +58,13 @@ export class Inspector { list.set(control.dataKey, control) } - add(dataControl) { + add(dataControl: DataControl) { this._add(this.dataControls, dataControl, 'inspector') dataControl.onAdd() return this } - handleSockets(sockets, control, type) { + handleSockets(sockets: DataSocketType[], control, type: keyof ThothNode) { // we assume all sockets are of the same type here // and that the data key is set to 'inputs' or 'outputs' const isOutput = type === 'outputs' @@ -53,7 +72,8 @@ export class Inspector { this.node.data[type] = sockets // get all sockets currently on the node - const existingSockets = [] + const existingSockets: DataSocketType[] = [] + this.node[type].forEach(out => { existingSockets.push(out.key) }) @@ -130,7 +150,7 @@ export class Inspector { }) } - cacheControls(dataControls) { + cacheControls(dataControls: DataControlData) { const cache = Object.entries(dataControls).reduce( (acc, [key, { expanded = true }]) => { acc[key] = { @@ -139,13 +159,13 @@ export class Inspector { return acc }, - {} + {} as Record ) this.node.data.dataControls = cache } - handleData(update) { + handleData(update: Record) { // store all data controls inside the nodes data // WATCH in case our graphs start getting quite large. if (update.dataControls) this.cacheControls(update.dataControls) @@ -210,13 +230,13 @@ export class Inspector { data() { const dataControls = Array.from(this.dataControls.entries()).reduce( (acc, [key, val]) => { - const cache = this.node?.data?.dataControls + const cache = this.node?.data?.dataControls as DataControlData const cachedControl = cache && cache[key] ? cache[key] : {} // use the data method on controls to get data shape acc[key] = { ...val.control, ...cachedControl } return acc }, - {} + {} as Record ) return { From 43782c3cc38162d86edf3aa80b895a1334ea6eee Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 18:56:24 -0800 Subject: [PATCH 19/31] add ThothComponent unknown type to inspector plugin --- core/src/plugins/inspectorPlugin/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/plugins/inspectorPlugin/index.ts b/core/src/plugins/inspectorPlugin/index.ts index 162706130..781f600ab 100644 --- a/core/src/plugins/inspectorPlugin/index.ts +++ b/core/src/plugins/inspectorPlugin/index.ts @@ -1,4 +1,5 @@ import { IRunContextEditor, ThothNode } from '../../../types' +import { ThothComponent } from '../../thoth-component' // @seang todo: convert data controls to typescript to remove this // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore @@ -7,7 +8,7 @@ import { Inspector } from './Inspector' function install(editor: IRunContextEditor) { const { onInspector, sendToInspector, clearTextEditor } = editor.thoth - editor.on('componentregister', component => { + editor.on('componentregister', (component: ThothComponent) => { const builder = component.builder if (!component.info) @@ -36,7 +37,7 @@ function install(editor: IRunContextEditor) { if (!onInspector) return - node.subscription = onInspector(node, (data: unknown) => { + node.subscription = onInspector(node, (data: Record) => { node.inspector.handleData(data) editor.trigger('nodecreated') // NOTE might still need this. Keep an eye out. From 0ee7dde7b6bb9b21aef37269cc6e033474bf808e Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 18:57:00 -0800 Subject: [PATCH 20/31] add void to potential builder output --- core/src/thoth-component.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/thoth-component.ts b/core/src/thoth-component.ts index 442563815..7f613ef65 100644 --- a/core/src/thoth-component.ts +++ b/core/src/thoth-component.ts @@ -53,8 +53,7 @@ export abstract class ThothComponent< constructor(name: string) { super(name) } - - abstract builder(node: ThothNode): Promise | ThothNode + abstract builder(node: ThothNode): Promise | ThothNode | void async build(node: ThothNode) { await this.builder(node) From caed9eaea27ad6315248de2fe4b4a3d7dff11549 Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 19:19:06 -0800 Subject: [PATCH 21/31] add type to list argument --- core/src/plugins/inspectorPlugin/Inspector.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/plugins/inspectorPlugin/Inspector.ts b/core/src/plugins/inspectorPlugin/Inspector.ts index d34e799f1..65dc8f612 100644 --- a/core/src/plugins/inspectorPlugin/Inspector.ts +++ b/core/src/plugins/inspectorPlugin/Inspector.ts @@ -35,8 +35,12 @@ export class Inspector { this.category = component.category this.info = component.info } - - _add(list, control: DataControl, prop: keyof DataControl) { + // addede DataControl[] + _add( + list: Map, + control: DataControl, + prop: keyof DataControl + ) { if (list.has(control.key)) throw new Error( `Item with key '${control.key}' already been added to the inspector` From b858564865a3fdaeb2f1d9f8e0b8d43ebb340ade Mon Sep 17 00:00:00 2001 From: Jakob Grant Date: Mon, 7 Mar 2022 19:34:43 -0800 Subject: [PATCH 22/31] add data to DataControl --- core/src/plugins/inspectorPlugin/DataControl.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/plugins/inspectorPlugin/DataControl.ts b/core/src/plugins/inspectorPlugin/DataControl.ts index 86383a900..b2a640e4f 100644 --- a/core/src/plugins/inspectorPlugin/DataControl.ts +++ b/core/src/plugins/inspectorPlugin/DataControl.ts @@ -18,6 +18,8 @@ export abstract class DataControl { options: object icon: string write: boolean + //Jake added below + data: Record constructor({ dataKey, From a6ed03a062c949d023570eb90206e658970078b0 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 19:59:34 -0800 Subject: [PATCH 23/31] Remove prop argument for hard coded value --- core/src/plugins/inspectorPlugin/Inspector.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/core/src/plugins/inspectorPlugin/Inspector.ts b/core/src/plugins/inspectorPlugin/Inspector.ts index 65dc8f612..a9c522326 100644 --- a/core/src/plugins/inspectorPlugin/Inspector.ts +++ b/core/src/plugins/inspectorPlugin/Inspector.ts @@ -36,21 +36,17 @@ export class Inspector { this.info = component.info } // addede DataControl[] - _add( - list: Map, - control: DataControl, - prop: keyof DataControl - ) { + _add(list: Map, control: DataControl) { if (list.has(control.key)) throw new Error( `Item with key '${control.key}' already been added to the inspector` ) - if (control[prop] !== null) + if (control['inspector'] !== null) throw new Error('Inspector has already been added to some control') // Attach the inspector to the incoming control instance - control[prop] = this + control['inspector'] = this control.editor = this.editor control.node = this.node control.component = this.component @@ -63,7 +59,7 @@ export class Inspector { } add(dataControl: DataControl) { - this._add(this.dataControls, dataControl, 'inspector') + this._add(this.dataControls, dataControl) dataControl.onAdd() return this } From 510a92905de06e467852007ec3b08fc4da7e85c2 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 20:05:59 -0800 Subject: [PATCH 24/31] Fix socket handler --- core/src/plugins/inspectorPlugin/Inspector.ts | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/core/src/plugins/inspectorPlugin/Inspector.ts b/core/src/plugins/inspectorPlugin/Inspector.ts index a9c522326..75a775d4f 100644 --- a/core/src/plugins/inspectorPlugin/Inspector.ts +++ b/core/src/plugins/inspectorPlugin/Inspector.ts @@ -1,5 +1,5 @@ import deepEqual from 'deep-equal' -import Rete from 'rete' +import Rete, { Input, Output } from 'rete' import { v4 as uuidv4 } from 'uuid' import { DataSocketType, IRunContextEditor, ThothNode } from '../../../types' import { ThothComponent } from '../../thoth-component' @@ -64,7 +64,11 @@ export class Inspector { return this } - handleSockets(sockets: DataSocketType[], control, type: keyof ThothNode) { + handleSockets( + sockets: DataSocketType[], + control: DataControlData, + type: 'inputs' | 'outputs' + ) { // we assume all sockets are of the same type here // and that the data key is set to 'inputs' or 'outputs' const isOutput = type === 'outputs' @@ -72,13 +76,13 @@ export class Inspector { this.node.data[type] = sockets // get all sockets currently on the node - const existingSockets: DataSocketType[] = [] + const existingSockets: string[] = [] - this.node[type].forEach(out => { + this.node[type]?.forEach(out => { existingSockets.push(out.key) }) - const ignored = (control && control?.data?.ignored) || [] + const ignored: string[] = (control && control?.data?.ignored) || [] // outputs that are on the node but not in the incoming sockets is removed existingSockets @@ -94,10 +98,14 @@ export class Inspector { .forEach(key => { const socket = this.node[type].get(key) + if (!socket) return + // we get the connections for the node and remove that connection const connections = this.node .getConnections() - .filter(con => con[type.slice(0, -1)].key === key) + .filter( + con => con[type.slice(0, -1) as 'input' | 'output'].key === key + ) if (connections) connections.forEach(con => { @@ -106,9 +114,9 @@ export class Inspector { // handle removing the socket, either output or input if (isOutput) { - this.node.removeOutput(socket) + this.node.removeOutput(socket as Output) } else { - this.node.removeInput(socket) + this.node.removeInput(socket as Input) } }) From f30d967b97f77eebb022c2d0dca1aab972a8a567 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 20:07:27 -0800 Subject: [PATCH 25/31] Fix typing of addition of task outputs --- core/src/plugins/inspectorPlugin/Inspector.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/plugins/inspectorPlugin/Inspector.ts b/core/src/plugins/inspectorPlugin/Inspector.ts index 75a775d4f..29750c07a 100644 --- a/core/src/plugins/inspectorPlugin/Inspector.ts +++ b/core/src/plugins/inspectorPlugin/Inspector.ts @@ -128,7 +128,8 @@ export class Inspector { // Here we are running over and ensuring that the outputs are in the tasks outputs // We only need to do this with outputs, as inputs don't need to be in the task if (isOutput) { - this.component.task.outputs = this.node.data.outputs.reduce( + const dataOutputs = this.node.data.outputs as DataSocketType[] + this.component.task.outputs = dataOutputs.reduce( (acc, out) => { acc[out.socketKey] = out.taskType || 'output' return acc From 9f110605b4ad5c6c8762a30d25db6e5ff62cd251 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 20:07:59 -0800 Subject: [PATCH 26/31] Coerce typings for adding new sockets --- core/src/plugins/inspectorPlugin/Inspector.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/plugins/inspectorPlugin/Inspector.ts b/core/src/plugins/inspectorPlugin/Inspector.ts index 29750c07a..96a66d94f 100644 --- a/core/src/plugins/inspectorPlugin/Inspector.ts +++ b/core/src/plugins/inspectorPlugin/Inspector.ts @@ -152,9 +152,9 @@ export class Inspector { ) if (isOutput) { - this.node.addOutput(newSocket) + this.node.addOutput(newSocket as Output) } else { - this.node.addInput(newSocket) + this.node.addInput(newSocket as Input) } }) } From befb5ed3d4cadc0ee0e7b7eead81f7844156513c Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 20:09:02 -0800 Subject: [PATCH 27/31] Rename socket generator to ts --- core/src/plugins/socketGenerator/{index.js => index.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/src/plugins/socketGenerator/{index.js => index.ts} (100%) diff --git a/core/src/plugins/socketGenerator/index.js b/core/src/plugins/socketGenerator/index.ts similarity index 100% rename from core/src/plugins/socketGenerator/index.js rename to core/src/plugins/socketGenerator/index.ts From 9d76475786328f9b3500cef2b22c837a1e0ce645 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 20:15:17 -0800 Subject: [PATCH 28/31] Convert socket generator to typescript --- core/src/plugins/socketGenerator/index.ts | 30 ++++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/core/src/plugins/socketGenerator/index.ts b/core/src/plugins/socketGenerator/index.ts index 54e3b419c..57853f83d 100644 --- a/core/src/plugins/socketGenerator/index.ts +++ b/core/src/plugins/socketGenerator/index.ts @@ -1,21 +1,25 @@ -import Rete from 'rete' +import Rete, { Input, Output } from 'rete' +import { DataSocketType, IRunContextEditor, ThothNode } from '../../../types' import * as sockets from '../../sockets' +import { ThothComponent } from '../../thoth-component' -function install(editor) { - editor.on('componentregister', component => { +function install(editor: IRunContextEditor) { + editor.on('componentregister', (component: ThothComponent) => { const builder = component.builder // we are going to override the default builder with our own, and will invoke the original builder inside it. - component.builder = node => { + component.builder = (node: ThothNode) => { + const nodeOutputs = node.data.outputs as DataSocketType[] + // Handle outputs in the nodes data to repopulate when loading from JSON - if (node.data.outputs && node.data.outputs.length !== 0) { - const outputMap = {} + if (nodeOutputs && nodeOutputs.length !== 0) { + const outputMap = {} as Record node.outputs.forEach((value, key) => { outputMap[key] = value }) - node.data.outputs.forEach(socket => { + nodeOutputs.forEach(socket => { if (!outputMap[socket.socketKey]) { const output = new Rete.Output( socket.socketKey ? socket.socketKey : socket.name, @@ -27,8 +31,8 @@ function install(editor) { }) } - if (node.data.outputs && node.data.outputs.length > 0) { - component.task.outputs = node.data.outputs.reduce( + if (nodeOutputs && nodeOutputs.length > 0) { + component.task.outputs = nodeOutputs.reduce( (acc, out) => { acc[out.socketKey] = out.taskType || 'output' return acc @@ -37,14 +41,16 @@ function install(editor) { ) } - if (node.data.inputs && node.data.inputs.length !== 0) { + const nodeInputs = node.data.inputs as DataSocketType[] + + if (nodeInputs && nodeInputs.length !== 0) { // get inputs from node.inputs - const inputMap = {} + const inputMap = {} as Record node.inputs.forEach((value, key) => { inputMap[key] = value }) - node.data.inputs.forEach(socket => { + nodeInputs.forEach(socket => { // If the input key is already on the node, return if (inputMap[socket.socketKey]) return const input = new Rete.Input( From 426d6fbeb62ab528bb2de19987e67b3795fbef88 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 20:17:03 -0800 Subject: [PATCH 29/31] Formatting comment --- core/src/plugins/taskPlugin/task.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/core/src/plugins/taskPlugin/task.ts b/core/src/plugins/taskPlugin/task.ts index e31124154..d9bd9fc3a 100644 --- a/core/src/plugins/taskPlugin/task.ts +++ b/core/src/plugins/taskPlugin/task.ts @@ -102,16 +102,13 @@ export class Task { const inputs = {} as Record /* - This is where we are populating all the input values to be passed into the worker. - We are getting all the input connections that are connected as outputs (ie have values) - We filter out all connections which did not come from the previou node. This is to hgelp support multiple - inputs properly, otherwise we actually back propagate along every input and run it, whichI think is unwanted behaviour. - After we have filtered these out, we need to run the task, which triggers that nodes worker. After the worker runs, - the task has populated output data, which we take and we associate with the tasks input values, which are subsequently + This is where we are populating all the input values to be passed into the worker. We are getting all the input connections that are connected as outputs (ie have values) + We filter out all connections which did not come from the previou node. This is to hgelp support multiple inputs properly, otherwise we actually back propagate along every input and run it, whichI think is unwanted behaviour. + + After we have filtered these out, we need to run the task, which triggers that nodes worker. After the worker runs, the task has populated output data, which we take and we associate with the tasks input values, which are subsequently passed to the nodes worker for processing. - We assume here that his nodes worker does not need to access ALL values simultaneously, but is only interested in one. - There is a task option which enables this functionality just in case we have use cases that don't want this behaviour. + We assume here that his nodes worker does not need to access ALL values simultaneously, but is only interested in one. There is a task option which enables this functionality just in case we have use cases that don't want this behaviour. */ await Promise.all( this.getInputs('output').map(async key => { From 9b48ba9deac515652fa60ed8ac8cbb3ce4f73e30 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 20:18:52 -0800 Subject: [PATCH 30/31] Bump core up to proper 0.0.62 --- core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/package.json b/core/package.json index b4a0a949b..4e7eda925 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@latitudegames/thoth-core", - "version": "0.0.61", + "version": "0.0.62", "license": "Apache-2.0", "author": "Michael Sharpe (https://www.project89.org)", "contributors": [ From fcbbce8dd932791a9f987e4b20999e332b308132 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Mon, 7 Mar 2022 20:28:48 -0800 Subject: [PATCH 31/31] Fix another nested iterator typescript issue --- core/src/plugins/inspectorPlugin/Inspector.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/plugins/inspectorPlugin/Inspector.ts b/core/src/plugins/inspectorPlugin/Inspector.ts index 96a66d94f..35dd6932b 100644 --- a/core/src/plugins/inspectorPlugin/Inspector.ts +++ b/core/src/plugins/inspectorPlugin/Inspector.ts @@ -185,7 +185,8 @@ export class Inspector { this.onData(data) // go over each data control - for (const [key, control] of this.dataControls) { + const dataControlArray = Array.from(this.dataControls) + for (const [key, control] of dataControlArray) { const isEqual = deepEqual(this.cache[key], data[key]) // compare agains the cache to see if it has changed