From 88bf4a2639db2a3fdeca4d22d121b09b71d75d43 Mon Sep 17 00:00:00 2001 From: everbrez Date: Wed, 31 Jan 2024 03:21:19 +0800 Subject: [PATCH] feat: use Action instead of extraData + value --- packages/core/demos/index.ts | 8 +- packages/core/demos/simple-demo.ts | 8 +- packages/core/demos/sub-demo.ts | 22 ++- packages/core/demos/todo-list-demo.ts | 176 ++++++++++++------ packages/core/src/ModelState/Action.ts | 14 +- packages/core/src/ModelState/ExtraInfo.ts | 20 -- packages/core/src/ModelState/ModelEvent.ts | 6 +- packages/core/src/ModelState/Observable.ts | 8 +- packages/core/src/ModelState/State.ts | 28 +-- packages/core/src/ModelState/index.ts | 1 + packages/core/src/Tracker/index.ts | 4 +- packages/core/src/index.ts | 3 +- packages/core/src/models/ListMState.ts | 13 +- .../core/src/operators/streams/combine.ts | 9 +- packages/core/src/operators/streams/merge.ts | 9 +- .../core/src/operators/streams/proxyData.ts | 38 ++-- packages/core/src/operators/streams/sum.ts | 19 +- .../core/src/operators/streams/transform.ts | 13 +- .../core/src/operators/utils/mountList.ts | 18 +- .../Operators/MergeOperator/index.tsx | 15 +- .../Operators/OutputOperator/index.tsx | 7 +- .../Operators/StateOperator/StateOperator.tsx | 7 +- .../src/Diagrams/Panels/ConsolePanel/Demo.tsx | 27 ++- 23 files changed, 280 insertions(+), 193 deletions(-) delete mode 100644 packages/core/src/ModelState/ExtraInfo.ts diff --git a/packages/core/demos/index.ts b/packages/core/demos/index.ts index 5498f83..7d2cc18 100644 --- a/packages/core/demos/index.ts +++ b/packages/core/demos/index.ts @@ -1,5 +1,5 @@ import { start, tracker, type TrackRecord } from '../src'; -import { ExtraInfo } from '../src/ModelState/ExtraInfo'; +import { Action } from '../src/ModelState'; import { SimpleDemoApp } from './simple-demo'; import { TodoListDemoApp } from './todo-list-demo'; @@ -12,14 +12,16 @@ function main() { const appInstance = start(SimpleDemoApp); console.log(appInstance.output?.result.current); - appInstance.output?.event.next(2, new ExtraInfo('manual add 2')); + appInstance.output?.event.next(new Action({ payload: 2, path: 'manual add 2' })); console.log('result', appInstance.output?.result.current); start(TodoListDemoApp); setTimeout(() => { console.log('====== RECORD ======'); - console.log(JSON.stringify(logs, undefined, 2)); + // TODO: MState record + // console.log(JSON.stringify(logs, undefined, 2)); + console.log(logs); console.log('====== RECORD END ======'); }, 10000); } diff --git a/packages/core/demos/simple-demo.ts b/packages/core/demos/simple-demo.ts index 6a2db97..b7ca048 100644 --- a/packages/core/demos/simple-demo.ts +++ b/packages/core/demos/simple-demo.ts @@ -13,15 +13,15 @@ export function SimpleDemoApp(input: any, context: ModelBlockContextType) { event.pipe((item) => { const value = new ModelState(0); - item.subscribe((val, extraInfo) => { - value.update(val, extraInfo); + item.subscribe((action) => { + value.next(action); }); return value; }), constValue(1) - ).subscribe((res, extraInfo) => { - state2.update(res, extraInfo); + ).subscribe((action) => { + state2.next(action); }); return { diff --git a/packages/core/demos/sub-demo.ts b/packages/core/demos/sub-demo.ts index f6abc29..201957e 100644 --- a/packages/core/demos/sub-demo.ts +++ b/packages/core/demos/sub-demo.ts @@ -1,14 +1,14 @@ import { ModelState, ModelEvent, type ModelBlockContextType } from '../src'; -import { ExtraInfo } from '../src/ModelState/ExtraInfo'; +import { Action } from '../src/ModelState'; function other1(input: any, context: ModelBlockContextType) { const { onLifecycle } = context; const count = new ModelState(0); - const event = new ModelEvent(); + const event = new ModelEvent(); onLifecycle('postInit', () => { - const subscription = count.subscribe((val, extraInfo) => { - event.next(val, extraInfo); + const subscription = count.subscribe((action) => { + event.next(action); }); return subscription; @@ -51,8 +51,18 @@ function Test(_input: any, context: ModelBlockContextType) { const state2 = new ModelState(1); onLifecycle('mount', () => { - state1.update((c) => c + 2, new ExtraInfo()); - state2.update((c) => c * 5, new ExtraInfo()); + state1.next( + new Action({ + payload: (c) => c + 2, + path: 'mount' + }) + ); + state2.next( + new Action({ + payload: (c) => c * 5, + path: 'mount' + }) + ); }); return { diff --git a/packages/core/demos/todo-list-demo.ts b/packages/core/demos/todo-list-demo.ts index 9cea5e9..07f7fd4 100644 --- a/packages/core/demos/todo-list-demo.ts +++ b/packages/core/demos/todo-list-demo.ts @@ -1,6 +1,6 @@ import { type ModelBlockContextType, ModelState, ModelEvent } from '../src'; import { proxyData, mountList } from '../src/operators'; -import { ExtraInfo } from '../src/ModelState/ExtraInfo'; +import { Action } from '../src/ModelState'; function TodoItem( input: { index: ModelState; data: ModelState; key: string }, @@ -12,34 +12,49 @@ function TodoItem( // delete // change title // check/uncheck - const deleteEvent = new ModelEvent(); - const titleChangeEvent = new ModelEvent(); + const deleteEvent = new ModelEvent(); + const titleChangeEvent = new ModelEvent(); const checkEvent = new ModelEvent(); - deleteEvent.subscribe((_val, extraInfo) => { - data.update((data) => { - const dataWillUpdate = [...data]; - dataWillUpdate.splice(index.current, 1); - return dataWillUpdate; - }, extraInfo); + deleteEvent.subscribe((action) => { + data.next( + action.concat({ + payload: (data: any[]) => { + const dataWillUpdate = [...data]; + dataWillUpdate.splice(index.current, 1); + return dataWillUpdate; + }, + path: 'deleteEvent' + }) + ); }); - titleChangeEvent.subscribe((val, extraInfo) => { - data.update((data) => { - const dataWillUpdate = [...data]; - const item = data[index.current]; - item.title = val; - return dataWillUpdate; - }, extraInfo); + titleChangeEvent.subscribe((action) => { + data.next( + action.concat({ + payload: (data: any[]) => { + const dataWillUpdate = [...data]; + const item = data[index.current]; + item.title = action.payload; + return dataWillUpdate; + }, + path: 'titleChangeEvent' + }) + ); }); - checkEvent.subscribe((val, extraInfo) => { - data.update((data) => { - const dataWillUpdate = [...data]; - const item = data[index.current]; - item.checked = Boolean(val); - return dataWillUpdate; - }, extraInfo); + checkEvent.subscribe((action) => { + data.next( + action.concat({ + payload: (data: any[]) => { + const dataWillUpdate = [...data]; + const item = data[index.current]; + item.checked = Boolean(action.payload); + return dataWillUpdate; + }, + path: 'checkEvent' + }) + ); }); onLifecycle('mount', () => { @@ -72,28 +87,38 @@ function TodoListContainer( // clear const addItemEvent = new ModelEvent<{ key: string; title: string }>(); const checkAllEvent = new ModelEvent(); - const clearAllEvent = new ModelEvent(); - - addItemEvent.subscribe((val, extraInfo) => { - listData.update((list) => { - return list.concat({ - ...val, - checked: false - }); - }, extraInfo); + const clearAllEvent = new ModelEvent(); + + addItemEvent.subscribe((action) => { + listData.next( + action.concat({ + payload: (list: any[]) => { + return list.concat({ + ...action.payload, + checked: false + }); + }, + path: 'addItemEvent' + }) + ); }); - checkAllEvent.subscribe((val, extraInfo) => { - listData.update((list) => { - return list.map((item) => ({ - ...item, - checked: Boolean(val) - })); - }, extraInfo); + checkAllEvent.subscribe((action) => { + listData.next( + action.concat({ + payload: (list: any[]) => { + return list.map((item) => ({ + ...item, + checked: Boolean(action.payload) + })); + }, + path: 'checkAllEvent' + }) + ); }); - clearAllEvent.subscribe((_val, extraInfo) => { - listData.update([], extraInfo); + clearAllEvent.subscribe((action) => { + listData.next(action.concat({ payload: [], path: 'clearAllEvent' })); }); return { @@ -109,10 +134,20 @@ export function TodoListDemoApp(_input: any, context: ModelBlockContextType) { const data = new ModelState({ list: [{ key: 1 }] }); const listData = proxyData(data, 'list'); - listData.update((list) => [...(list || []), { key: 777 }], new ExtraInfo('update list')); + listData.next( + new Action({ + payload: (list) => [...(list || []), { key: 777 }], + path: 'update list' + }) + ); setTimeout(() => { - listData.update((list) => [{ key: 777 }, { key: 99 }], new ExtraInfo('update list')); + listData.next( + new Action({ + payload: (list) => [{ key: 777 }, { key: 99 }], + path: 'update list' + }) + ); }, 1000); console.log('listData', listData.current); @@ -127,41 +162,58 @@ export function TodoListDemoApp(_input: any, context: ModelBlockContextType) { setTimeout(() => { // 增加一个 todoListContainerInstance.output?.addItemEvent.next( - { key: '23333', title: 'new item' }, - new ExtraInfo('add manually') + new Action({ + payload: { key: '23333', title: 'new item' }, + path: 'add manually' + }) ); console.log('listData addItemEvent', listData.current); todoListContainerInstance.output?.checkAllEvent.next( - true, - new ExtraInfo('listData checkAllEvent true') + new Action({ + payload: true, + path: 'listData checkAllEvent true' + }) ); console.log('listData checkAllEvent true', listData.current); todoListContainerInstance.output?.checkAllEvent.next( - false, - new ExtraInfo('listData checkAllEvent false') + new Action({ + payload: false, + path: 'listData checkAllEvent false' + }) ); console.log('listData checkAllEvent false', listData.current); // change title - todoListContainerInstance.output?.instanceList?.current - ?.at(-1) - ?.instance.output?.titleChangeEvent.next( - 'change - title', - new ExtraInfo('listData titleChangeEvent') - ); + todoListContainerInstance.output?.instanceList?.current?.at(-1)?.instance.output?.titleChangeEvent.next( + new Action({ + payload: 'change - title', + path: 'listData titleChangeEvent' + }) + ); console.log('listData titleChangeEvent', listData.current); - todoListContainerInstance.output?.instanceList?.current - ?.at(-1) - ?.instance.output?.checkEvent.next(true, new ExtraInfo('listData checkEvent true')); + todoListContainerInstance.output?.instanceList?.current?.at(-1)?.instance.output?.checkEvent.next( + new Action({ + payload: true, + path: 'listData checkEvent true' + }) + ); console.log('listData checkEvent true', listData.current); - todoListContainerInstance.output?.instanceList?.current - ?.at(-2) - ?.instance.output?.deleteEvent.next(undefined, new ExtraInfo('listData deleteEvent')); + todoListContainerInstance.output?.instanceList?.current?.at(-2)?.instance.output?.deleteEvent.next( + new Action({ + payload: undefined, + path: 'listData deleteEvent' + }) + ); console.log('listData deleteEvent', listData.current); - todoListContainerInstance.output?.clearAllEvent.next(false, new ExtraInfo('listData clearAllEvent')); + todoListContainerInstance.output?.clearAllEvent.next( + new Action({ + payload: false, + path: 'listData clearAllEvent' + }) + ); console.log('listData clearAllEvent', listData.current); }, 3000); }); diff --git a/packages/core/src/ModelState/Action.ts b/packages/core/src/ModelState/Action.ts index bcbbe56..b1b9199 100644 --- a/packages/core/src/ModelState/Action.ts +++ b/packages/core/src/ModelState/Action.ts @@ -2,20 +2,12 @@ import { Entity } from '../Entity'; export type IUpdateAction = (source: T) => T; -function isAction>(data: any): data is Action { - return typeof data === 'object'; -} - -function isUpdateAction(data: any): data is IUpdateAction { - return !isAction(data); -} - -type IActionObjectParam = Required> & +type IActionObjectParam = Required> & Partial>; export class Action = Record> extends Entity { - /** UpdateAction */ - action?: T | IUpdateAction; + /** UpdateAction, value or function */ + payload: T | IUpdateAction | undefined; /** value update hint */ path: string = ''; /** extra data */ diff --git a/packages/core/src/ModelState/ExtraInfo.ts b/packages/core/src/ModelState/ExtraInfo.ts deleted file mode 100644 index 1073bf6..0000000 --- a/packages/core/src/ModelState/ExtraInfo.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Entity } from '../Entity'; - -export class ExtraInfo extends Entity { - hint: string[] = []; - - constructor(defaultDataOrHint?: ExtraInfo['hint'][number] | Partial) { - super(typeof defaultDataOrHint === 'object' ? defaultDataOrHint?.uid : undefined); - if (typeof defaultDataOrHint === 'string') { - // hint - this.hint = [defaultDataOrHint]; - } else { - Object.assign(this, defaultDataOrHint ?? {}); - } - } - - concat(hint: string) { - this.hint.push(hint); - return this; - } -} diff --git a/packages/core/src/ModelState/ModelEvent.ts b/packages/core/src/ModelState/ModelEvent.ts index 52c69c1..68c3ce2 100644 --- a/packages/core/src/ModelState/ModelEvent.ts +++ b/packages/core/src/ModelState/ModelEvent.ts @@ -1,8 +1,8 @@ -import { ExtraInfo } from './ExtraInfo'; import { Observable } from './Observable'; +import { Action } from './Action'; export class ModelEvent extends Observable { - next(info: T, extraInfo: ExtraInfo) { - super.next(info, extraInfo || new ExtraInfo('[ModelEvent] fallback')); + next(action?: Action) { + super.trigger(action || new Action({ payload: undefined, path: 'event' })); } } diff --git a/packages/core/src/ModelState/Observable.ts b/packages/core/src/ModelState/Observable.ts index 82a4fb8..1969707 100644 --- a/packages/core/src/ModelState/Observable.ts +++ b/packages/core/src/ModelState/Observable.ts @@ -1,8 +1,8 @@ import { Entity } from '../Entity'; -import { type ExtraInfo } from './ExtraInfo'; +import { Action } from './Action'; type CleanupCallback = () => void; -type Callback = (value: T, extraInfo: ExtraInfo) => any; +export type Callback = (action: Action) => any; export interface Subscribable { subscribe: (callback: Callback) => Subscription; @@ -32,12 +32,12 @@ export class Observable extends Entity implements Subscribable>(); - protected next(...args: Parameters>) { + protected trigger(...args: Parameters>) { for (const callback of this.#subscribers.values()) { try { callback(...args); diff --git a/packages/core/src/ModelState/State.ts b/packages/core/src/ModelState/State.ts index 58c2fb8..1e93cd2 100644 --- a/packages/core/src/ModelState/State.ts +++ b/packages/core/src/ModelState/State.ts @@ -1,18 +1,8 @@ import { Observable } from './Observable'; -import { type ExtraInfo } from './ExtraInfo'; import { tracker } from '../Tracker'; +import { Action, IUpdateAction } from './Action'; -export interface ReportPayload { - traceId: string; // maybe multiple input source. - operatorId: string; - current: T; - next: T; - reason?: string; -} - -export type UpdateAction = (source: T) => T; - -export function updateValue(currentValue: T, updateAction: UpdateAction | T) { +export function updateValue(currentValue: T, updateAction: IUpdateAction | T | undefined) { const nextValue = typeof updateAction === 'function' ? (updateAction as (...args: any) => any)(currentValue) : updateAction; @@ -30,20 +20,20 @@ export class Atom extends Observable { super(); this._current = defaultValue; - this.update = this.update.bind(this); + this.next = this.next.bind(this); } - protected update(updateAction: UpdateAction | ValueType, extraInfo: ExtraInfo) { - const nextValue = updateValue(this._current, updateAction); + protected next(action: Action) { + const nextValue = updateValue(this._current, action.payload); this._current = nextValue; - tracker.track({ target: this.uid, extraInfo }); + tracker.track({ target: this.uid, action }); - this.next(nextValue, extraInfo); + super.trigger(action.concat({ payload: nextValue, path: this.uid })); } } export class State extends Atom { - update(updateAction: ValueType | UpdateAction, extraInfo: ExtraInfo): void { - super.update(updateAction, extraInfo); + next(action: Action): void { + super.next(action); } } diff --git a/packages/core/src/ModelState/index.ts b/packages/core/src/ModelState/index.ts index 265636b..405b8ac 100644 --- a/packages/core/src/ModelState/index.ts +++ b/packages/core/src/ModelState/index.ts @@ -1,2 +1,3 @@ export { State as ModelState } from './State'; export { ModelEvent } from './ModelEvent'; +export { Action } from './Action'; diff --git a/packages/core/src/Tracker/index.ts b/packages/core/src/Tracker/index.ts index c85f24c..3d296d1 100644 --- a/packages/core/src/Tracker/index.ts +++ b/packages/core/src/Tracker/index.ts @@ -1,10 +1,10 @@ import { EventEmitter } from '@eos/shared'; -import { type ExtraInfo } from '../ModelState/ExtraInfo'; +import { Action } from '../ModelState/Action'; export interface TrackRecord { /** 上报的主体 */ target: string; - extraInfo: ExtraInfo; + action: Action; } class Tracker extends EventEmitter { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 1fc2006..8878a6b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -5,9 +5,8 @@ export { start, type InputOutputInterface } from './ModelBlock'; -export { ModelState, ModelEvent } from './ModelState'; +export { ModelState, ModelEvent, Action } from './ModelState'; export { type Observable } from './ModelState/Observable'; export { tracker, type TrackRecord } from './Tracker'; -export { ExtraInfo } from './ModelState/ExtraInfo'; // not ready // export { ConditionMState, LazyMState, ListMState } from './models'; diff --git a/packages/core/src/models/ListMState.ts b/packages/core/src/models/ListMState.ts index 1ddd2fe..d049c03 100644 --- a/packages/core/src/models/ListMState.ts +++ b/packages/core/src/models/ListMState.ts @@ -26,8 +26,8 @@ export function ListMState, Output extends InputO }) || [] ); - data.subscribe((_val, extraInfo) => { - // console.log('change::', extraInfo, data.current, instanceList); + data.subscribe((action) => { + // console.log('change::', data.current, instanceList); const nextList = data.current.map((item, index) => ({ key: get(item, key), index })); const currentList = instanceList.current; // reconciliation @@ -42,7 +42,12 @@ export function ListMState, Output extends InputO // update nextInstanceList.push(currentItem); if (currentItem.index.current !== currentNextItem.index) { - currentItem.index.update(currentNextItem.index, extraInfo); + currentItem.index.next( + action.concat({ + payload: currentNextItem.index, + path: 'nextInstanceList' + }) + ); } } else { // mount @@ -65,7 +70,7 @@ export function ListMState, Output extends InputO unmount(node.instance); }); - instanceList.update(nextInstanceList, extraInfo); + instanceList.next(action.concat({ payload: nextInstanceList, path: 'ListMState' })); }); return { diff --git a/packages/core/src/operators/streams/combine.ts b/packages/core/src/operators/streams/combine.ts index d1bf363..2d30813 100644 --- a/packages/core/src/operators/streams/combine.ts +++ b/packages/core/src/operators/streams/combine.ts @@ -8,9 +8,14 @@ export function combine< const result = new ModelState([]); streamSource.forEach((input) => { - input.subscribe((_value, extraInfo) => { + input.subscribe((action) => { const allValue = [...streamSource, ...appendSource].map((item) => item.current); - result.update(allValue, extraInfo.concat('combine')); + result.next( + action.concat({ + payload: allValue, + path: 'combine' + }) + ); }); }); diff --git a/packages/core/src/operators/streams/merge.ts b/packages/core/src/operators/streams/merge.ts index 713eb64..3edfd05 100644 --- a/packages/core/src/operators/streams/merge.ts +++ b/packages/core/src/operators/streams/merge.ts @@ -5,8 +5,13 @@ export function merge>>(streamSour const result = new ModelState([]); streamSource.forEach((input) => { - input.subscribe((value, extraInfo) => { - result.update(value, extraInfo.concat('combine')); + input.subscribe((action) => { + result.next( + action.concat({ + payload: action.payload, + path: 'merge' + }) + ); }); }); diff --git a/packages/core/src/operators/streams/proxyData.ts b/packages/core/src/operators/streams/proxyData.ts index d2b03b8..79e708f 100644 --- a/packages/core/src/operators/streams/proxyData.ts +++ b/packages/core/src/operators/streams/proxyData.ts @@ -1,6 +1,8 @@ import { get, set, clone } from 'lodash'; -import { ModelState, type ExtraInfo } from '../..'; -import { updateValue, type UpdateAction } from '../../ModelState/State'; +import { ModelState } from '../..'; +import { updateValue } from '../../ModelState/State'; +import { Action } from '../../ModelState'; +import { Callback } from '../../ModelState/Observable'; // todo 重载 export function proxyData, Key extends string>( @@ -15,19 +17,29 @@ export function proxyData, Key extends string>( return get(originState.current, key); } - update(updateAction: SubDataType | UpdateAction, extraInfo: ExtraInfo): void { - originState.update((data) => { - const currentValue = get(data, key); - const newData = clone(data); - const nextValue = updateValue(currentValue, updateAction); - set(newData, key, nextValue); - return newData; - }, extraInfo); + next(action: Action): void { + originState.next( + action.concat({ + payload: (data: T) => { + const currentValue = get(data, key); + const newData = clone(data); + const nextValue = updateValue(currentValue, action.payload); + set(newData, key, nextValue); + return newData; + }, + path: 'ProxyState' + }) + ); } - subscribe(callback: (value: any, extraInfo: ExtraInfo) => any) { - return originState.subscribe((value, extraInfo) => { - return callback(get(value, key), extraInfo); + subscribe(callback: Callback) { + return originState.subscribe((action) => { + return callback( + action.concat({ + payload: get(action.payload, key), + path: 'ProxyState' + }) + ); }); } } diff --git a/packages/core/src/operators/streams/sum.ts b/packages/core/src/operators/streams/sum.ts index 248bfdc..94d04d6 100644 --- a/packages/core/src/operators/streams/sum.ts +++ b/packages/core/src/operators/streams/sum.ts @@ -1,21 +1,24 @@ import { type Atom } from '../../ModelState/State'; -import { ExtraInfo, ModelState } from '../..'; +import { ModelState } from '../..'; +import { Action } from '../../ModelState'; export function sum>>(...inputs: ObservableSubjectList) { const result = new ModelState(0); - function computed(extraInfo: ExtraInfo) { - result.update( - inputs.map((input) => input.current).reduce((acc, cur) => acc + cur, 0), - extraInfo + function computed(action: Action, path: string) { + result.next( + action.concat({ + payload: inputs.map((input) => input.current).reduce((acc, cur) => acc + cur, 0), + path + }) ); } - computed(new ExtraInfo('[sum]: init')); + computed(new Action({ payload: undefined, path: 'init' }), '[sum]: init'); inputs.forEach((input) => { - input.subscribe((_value, extraInfo) => { - computed(extraInfo.concat('sum')); + input.subscribe((action) => { + computed(action, 'sum'); }); }); diff --git a/packages/core/src/operators/streams/transform.ts b/packages/core/src/operators/streams/transform.ts index 208c486..d0990eb 100644 --- a/packages/core/src/operators/streams/transform.ts +++ b/packages/core/src/operators/streams/transform.ts @@ -3,18 +3,23 @@ import { ModelState } from '../..'; export function transform( steam: Atom, - action: (value: StreamValue) => ResultValue + actionFn: (value: StreamValue) => ResultValue ) { return steam.pipe((observer) => { const result = new ModelState(undefined); - observer.subscribe(async (value, extra) => { - const actionResult = action(value); + observer.subscribe(async (action) => { + const actionResult = actionFn(action.payload as StreamValue); let resultValue = actionResult; if (actionResult instanceof Promise) { resultValue = await actionResult; } - result.update(resultValue, extra.concat('transform')); + result.next( + action.concat({ + payload: resultValue, + path: 'transform' + }) + ); }); return result; diff --git a/packages/core/src/operators/utils/mountList.ts b/packages/core/src/operators/utils/mountList.ts index c762932..ff5d9e2 100644 --- a/packages/core/src/operators/utils/mountList.ts +++ b/packages/core/src/operators/utils/mountList.ts @@ -22,8 +22,8 @@ export function mountList, Output extends InputOu }) || [] ); - data.subscribe((_val, extraInfo) => { - // console.log('change::', extraInfo, data.current, instanceList); + data.subscribe((action) => { + // console.log('change::', data.current, instanceList); const nextList = data.current.map((item, index) => ({ key: get(item, key), index })); const currentList = instanceList.current; // reconciliation @@ -38,7 +38,12 @@ export function mountList, Output extends InputOu // update nextInstanceList.push(currentItem); if (currentItem.index.current !== currentNextItem.index) { - currentItem.index.update(currentNextItem.index, extraInfo); + currentItem.index.next( + action.concat({ + payload: currentNextItem.index, + path: 'nextInstanceList' + }) + ); } } else { // mount @@ -61,7 +66,12 @@ export function mountList, Output extends InputOu unmount(node.instance); }); - instanceList.update(nextInstanceList, extraInfo); + instanceList.next( + action.concat({ + payload: nextInstanceList, + path: 'instanceList' + }) + ); }); return { diff --git a/packages/flow/src/Diagrams/Operators/MergeOperator/index.tsx b/packages/flow/src/Diagrams/Operators/MergeOperator/index.tsx index 312439b..1a7ceec 100644 --- a/packages/flow/src/Diagrams/Operators/MergeOperator/index.tsx +++ b/packages/flow/src/Diagrams/Operators/MergeOperator/index.tsx @@ -104,12 +104,15 @@ export class MergeOperator return [ ...relationList.map( - ({ inputId, targetId }) => `${formatVariableName(targetId)}.subscribe((val, extraInfo) => { - ${formatVariableName(inputId)}.update(val, extraInfo.concat('${JSON.stringify({ - currentNodeId: node.id, - fromPortId: targetId, - toPortId: inputId - })}')); + ({ inputId, targetId }) => `${formatVariableName(targetId)}.subscribe((action) => { + ${formatVariableName(inputId)}.next(action.concat({ + payload: action.payload, + path: '${JSON.stringify({ + currentNodeId: node.id, + fromPortId: targetId, + toPortId: inputId + })}' + })); });` ) ]; diff --git a/packages/flow/src/Diagrams/Operators/OutputOperator/index.tsx b/packages/flow/src/Diagrams/Operators/OutputOperator/index.tsx index 6498983..aa61fec 100644 --- a/packages/flow/src/Diagrams/Operators/OutputOperator/index.tsx +++ b/packages/flow/src/Diagrams/Operators/OutputOperator/index.tsx @@ -100,8 +100,11 @@ export class OutputOperator return ''; } - return `${formatVariableName(sourceId)}.subscribe((value, extraInfo) => { - ${formatVariableName(targetId)}.next(value, extraInfo.concat('${node.id}')) + return `${formatVariableName(sourceId)}.subscribe((action) => { + ${formatVariableName(targetId)}.next(action.concat({ + payload: action.payload, + path: '${node.id}' + })) })`; }); diff --git a/packages/flow/src/Diagrams/Operators/StateOperator/StateOperator.tsx b/packages/flow/src/Diagrams/Operators/StateOperator/StateOperator.tsx index 79e4165..95639d2 100644 --- a/packages/flow/src/Diagrams/Operators/StateOperator/StateOperator.tsx +++ b/packages/flow/src/Diagrams/Operators/StateOperator/StateOperator.tsx @@ -92,8 +92,11 @@ export class StateOperator return [ ...sources?.map( (item) => ` - ${formatVariableName(item.relatedHandleId)}.subscribe((val, extraInfo) => { - ${this.getStateSymbol(options)}.update(val, extraInfo.concat('${item.nodeId}')); + ${formatVariableName(item.relatedHandleId)}.subscribe((action) => { + ${this.getStateSymbol(options)}.next(action.concat({ + payload: action.payload, + path: '${item.nodeId}' + })); });` ) ]; diff --git a/packages/flow/src/Diagrams/Panels/ConsolePanel/Demo.tsx b/packages/flow/src/Diagrams/Panels/ConsolePanel/Demo.tsx index 64ce833..6e8c1e9 100644 --- a/packages/flow/src/Diagrams/Panels/ConsolePanel/Demo.tsx +++ b/packages/flow/src/Diagrams/Panels/ConsolePanel/Demo.tsx @@ -7,7 +7,7 @@ import { useEffect, useRef, useState } from 'react'; import { type IInputOperatorData, type IOutputOperatorData } from '../../Operators/types'; import { type OutputOperator } from '../../Operators/OutputOperator'; import { type InputOperator } from '../../Operators/InputOperator'; -import { type ModelBlock, ModelState, ExtraInfo } from '@eos/core'; +import { type ModelBlock, ModelState, Action } from '@eos/core'; export const Demo: React.FC = () => { const { store, nodes, edges } = useLinkRuntimeContext(); @@ -49,9 +49,9 @@ export const Demo: React.FC = () => { const outputPorts = getOperatorFromNode(outputNode)?.getEventPorts(outputNode); outputPorts?.forEach((port) => { - instance?.output[port.variableName || '']?.subscribe((value: any, extraInfo: any) => { - message.info(`value: ${value}`); - console.log('events', port, value, extraInfo); + instance?.output[port.variableName || '']?.subscribe((action: any) => { + message.info(`value: ${action.payload}`); + console.log('events', port, action); }); }); }, [instance]); @@ -79,8 +79,8 @@ export const Demo: React.FC = () => { return instance?.output?.[port.variableName || '']; }) .forEach((value) => { - value?.subscribe((value: any, extraInfo: any) => { - console.log(value, extraInfo); + value?.subscribe((action: any) => { + console.log(action); forceUpdate([]); }); }); @@ -108,9 +108,11 @@ export const Demo: React.FC = () => { onChange={(e) => { const value: string = e.target.value; console.log('instance', instance); - inputStateMapRef.current?.[item.variableName || '']?.update( - Number(value), - new ExtraInfo() + inputStateMapRef.current?.[item.variableName || '']?.next( + new Action({ + payload: Number(value), + path: item.variableName || '' + }) ); }} /> @@ -131,7 +133,12 @@ export const Demo: React.FC = () => {