diff --git a/frontend/src/socket.ts b/frontend/src/socket.ts index 2e3fafb..d6007d5 100644 --- a/frontend/src/socket.ts +++ b/frontend/src/socket.ts @@ -1,5 +1,6 @@ import { io } from 'socket.io-client'; import { SerializedValue } from './components/GenericComponent'; +import { serializeDict, serializeList } from './utils/serializationUtils'; export const hostname = process.env.NODE_ENV === 'development' ? `localhost` : window.location.hostname; @@ -27,10 +28,20 @@ export const runMethod = ( kwargs: Record = {}, callback?: (ack: unknown) => void ) => { - // TODO: serialize args and kwargs before passing to trigger_method + const serializedArgs = serializeList(args); + const serializedKwargs = serializeDict(kwargs); + if (callback) { - socket.emit('trigger_method', { access_path: accessPath, args, kwargs }, callback); + socket.emit( + 'trigger_method', + { access_path: accessPath, args: serializedArgs, kwargs: serializedKwargs }, + callback + ); } else { - socket.emit('trigger_method', { access_path: accessPath, args, kwargs }); + socket.emit('trigger_method', { + access_path: accessPath, + args: serializedArgs, + kwargs: serializedKwargs + }); } }; diff --git a/frontend/src/utils/serializationUtils.ts b/frontend/src/utils/serializationUtils.ts new file mode 100644 index 0000000..ec7a79b --- /dev/null +++ b/frontend/src/utils/serializationUtils.ts @@ -0,0 +1,101 @@ +const serializePrimitive = ( + obj: number | boolean | string | null, + accessPath: string +) => { + let type: string; + + if (typeof obj === 'number') { + type = Number.isInteger(obj) ? 'int' : 'float'; + return { + full_access_path: accessPath, + doc: null, + readonly: false, + type, + value: obj + }; + } else if (typeof obj === 'boolean') { + type = 'bool'; + return { + full_access_path: accessPath, + doc: null, + readonly: false, + type, + value: obj + }; + } else if (typeof obj === 'string') { + type = 'str'; + return { + full_access_path: accessPath, + doc: null, + readonly: false, + type, + value: obj + }; + } else if (obj === null) { + type = 'NoneType'; + return { + full_access_path: accessPath, + doc: null, + readonly: false, + type, + value: null + }; + } else { + throw new Error('Unsupported type for serialization'); + } +}; + +export const serializeList = (obj: unknown[], accessPath: string = '') => { + const doc = null; + const value = obj.map((item, index) => { + if ( + typeof item === 'number' || + typeof item === 'boolean' || + typeof item === 'string' || + item === null + ) { + serializePrimitive( + item as number | boolean | string | null, + `${accessPath}[${index}]` + ); + } + }); + + return { + full_access_path: accessPath, + type: 'list', + value, + readonly: false, + doc + }; +}; +export const serializeDict = ( + obj: Record, + accessPath: string = '' +) => { + const doc = null; + const value = Object.entries(obj).reduce((acc, [key, val]) => { + // Construct the new access path for nested properties + const newPath = `${accessPath}["${key}"]`; + + // Serialize each value in the dictionary and assign to the accumulator + if ( + typeof val === 'number' || + typeof val === 'boolean' || + typeof val === 'string' || + val === null + ) { + acc[key] = serializePrimitive(val as number | boolean | string | null, newPath); + } + + return acc; + }, {}); + + return { + full_access_path: accessPath, + type: 'dict', + value, + readonly: false, + doc + }; +};