mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 15:07:55 -05:00
140 lines
4.2 KiB
TypeScript
140 lines
4.2 KiB
TypeScript
import { BlockState, SubBlockState } from '@/stores/workflow/types'
|
|
import { Edge } from 'reactflow'
|
|
import { SerializedBlock, SerializedConnection, SerializedWorkflow } from './types'
|
|
import { getBlock, getBlockTypeForTool } from '@/blocks'
|
|
|
|
export class Serializer {
|
|
serializeWorkflow(blocks: Record<string, BlockState>, edges: Edge[]): SerializedWorkflow {
|
|
return {
|
|
version: '1.0',
|
|
blocks: Object.values(blocks).map(block => this.serializeBlock(block)),
|
|
connections: edges.map(edge => ({
|
|
source: edge.source,
|
|
target: edge.target,
|
|
sourceHandle: edge.sourceHandle || undefined,
|
|
targetHandle: edge.targetHandle || undefined
|
|
}))
|
|
}
|
|
}
|
|
|
|
private serializeBlock(block: BlockState): SerializedBlock {
|
|
const blockConfig = getBlock(block.type)
|
|
if (!blockConfig) {
|
|
throw new Error(`Invalid block type: ${block.type}`)
|
|
}
|
|
|
|
// Get tool ID from block config
|
|
const toolId = blockConfig.tools.config?.tool
|
|
? blockConfig.tools.config.tool(this.extractParams(block))
|
|
: blockConfig.tools.access[0]
|
|
|
|
// Extract params from subBlocks
|
|
const params = this.extractParams(block)
|
|
|
|
// Get inputs from block config
|
|
const inputs: Record<string, any> = {}
|
|
if (blockConfig.workflow.inputs) {
|
|
Object.entries(blockConfig.workflow.inputs).forEach(([key, config]) => {
|
|
inputs[key] = config.type
|
|
})
|
|
}
|
|
|
|
return {
|
|
id: block.id,
|
|
position: block.position,
|
|
config: {
|
|
tool: toolId,
|
|
params
|
|
},
|
|
inputs,
|
|
outputs: block.outputs,
|
|
metadata: {
|
|
title: block.name,
|
|
description: blockConfig.toolbar.description,
|
|
category: blockConfig.toolbar.category,
|
|
color: blockConfig.toolbar.bgColor
|
|
},
|
|
enabled: block.enabled
|
|
}
|
|
}
|
|
|
|
private extractParams(block: BlockState): Record<string, any> {
|
|
const blockConfig = getBlock(block.type)
|
|
if (!blockConfig) {
|
|
throw new Error(`Invalid block type: ${block.type}`)
|
|
}
|
|
|
|
const params: Record<string, any> = {}
|
|
|
|
// First collect all current values from subBlocks
|
|
Object.entries(block.subBlocks).forEach(([id, subBlock]) => {
|
|
params[id] = subBlock.value
|
|
})
|
|
|
|
// Then check for any subBlocks with default values
|
|
blockConfig.workflow.subBlocks.forEach(subBlockConfig => {
|
|
const id = subBlockConfig.id
|
|
if (params[id] === null && subBlockConfig.value) {
|
|
// If the value is null and there's a default value function, use it
|
|
params[id] = subBlockConfig.value(params)
|
|
}
|
|
})
|
|
|
|
return params
|
|
}
|
|
|
|
deserializeWorkflow(workflow: SerializedWorkflow): { blocks: Record<string, BlockState>, edges: Edge[] } {
|
|
const blocks: Record<string, BlockState> = {}
|
|
const edges: Edge[] = []
|
|
|
|
// Deserialize blocks
|
|
workflow.blocks.forEach(serializedBlock => {
|
|
const block = this.deserializeBlock(serializedBlock)
|
|
blocks[block.id] = block
|
|
})
|
|
|
|
// Deserialize connections
|
|
workflow.connections.forEach(connection => {
|
|
edges.push({
|
|
id: crypto.randomUUID(),
|
|
source: connection.source,
|
|
target: connection.target,
|
|
sourceHandle: connection.sourceHandle,
|
|
targetHandle: connection.targetHandle
|
|
})
|
|
})
|
|
|
|
return { blocks, edges }
|
|
}
|
|
|
|
private deserializeBlock(serializedBlock: SerializedBlock): BlockState {
|
|
const blockType = getBlockTypeForTool(serializedBlock.config.tool)
|
|
if (!blockType) {
|
|
throw new Error(`Invalid tool ID: ${serializedBlock.config.tool}`)
|
|
}
|
|
|
|
const blockConfig = getBlock(blockType)
|
|
if (!blockConfig) {
|
|
throw new Error(`Invalid block type: ${blockType}`)
|
|
}
|
|
|
|
const subBlocks: Record<string, any> = {}
|
|
blockConfig.workflow.subBlocks.forEach(subBlock => {
|
|
subBlocks[subBlock.id] = {
|
|
id: subBlock.id,
|
|
type: subBlock.type,
|
|
value: serializedBlock.config.params[subBlock.id] ?? null
|
|
}
|
|
})
|
|
|
|
return {
|
|
id: serializedBlock.id,
|
|
type: blockType,
|
|
name: serializedBlock.metadata?.title || blockConfig.toolbar.title,
|
|
position: serializedBlock.position,
|
|
subBlocks,
|
|
outputs: serializedBlock.outputs,
|
|
enabled: true
|
|
}
|
|
}
|
|
} |