feat: add iteration id

pull/12560/head
Joel 1 year ago
parent e0ed17a2e6
commit 228cd1cdbe

@ -20,8 +20,8 @@ describe('parseDSL', () => {
nodeId: 'a', nodeId: 'a',
params: [ params: [
[ [
{ nodeType: 'plain', nodeId: 'b' }, { nodeType: 'plain', nodeId: 'b', iterationId: 'a', iterationIndex: 0 },
{ nodeType: 'plain', nodeId: 'c' }, { nodeType: 'plain', nodeId: 'c', iterationId: 'a', iterationIndex: 0 },
], ],
], ],
}, },
@ -72,17 +72,19 @@ describe('parseDSL', () => {
nodeId: 'a', nodeId: 'a',
params: [ params: [
[ [
{ nodeType: 'plain', nodeId: 'b' }, { nodeType: 'plain', nodeId: 'b', iterationId: 'a', iterationIndex: 0 },
{ {
nodeType: 'parallel', nodeType: 'parallel',
nodeId: 'e', nodeId: 'e',
iterationId: 'a',
iterationIndex: 0,
params: [ params: [
[ [
{ nodeType: 'plain', nodeId: 'f' }, { nodeType: 'plain', nodeId: 'f', iterationId: 'a', iterationIndex: 0 },
{ nodeType: 'plain', nodeId: 'g' }, { nodeType: 'plain', nodeId: 'g', iterationId: 'a', iterationIndex: 0 },
], ],
// single node don't need to be wrapped in an array // single node don't need to be wrapped in an array
{ nodeType: 'plain', nodeId: 'h' }, { nodeType: 'plain', nodeId: 'h', iterationId: 'a', iterationIndex: 0 },
], ],
}, },
], ],

@ -1,5 +1,6 @@
type NodePlain = { nodeType: 'plain'; nodeId: string } type IterationInfo = { iterationId: string; iterationIndex: number }
type NodeComplex = { nodeType: string; nodeId: string; params: (NodePlain | NodeComplex | Node[])[] } type NodePlain = { nodeType: 'plain'; nodeId: string; } & Partial<IterationInfo>
type NodeComplex = { nodeType: string; nodeId: string; params: (NodePlain | (NodeComplex & Partial<IterationInfo>) | Node[] | number)[] } & Partial<IterationInfo>
type Node = NodePlain | NodeComplex type Node = NodePlain | NodeComplex
/** /**
@ -8,7 +9,7 @@ type Node = NodePlain | NodeComplex
* @returns An array of parsed nodes. * @returns An array of parsed nodes.
*/ */
function parseDSL(dsl: string): Node[] { function parseDSL(dsl: string): Node[] {
return parseTopLevelFlow(dsl).map(parseNode) return parseTopLevelFlow(dsl).map(nodeStr => parseNode(nodeStr))
} }
/** /**
@ -44,9 +45,10 @@ function parseTopLevelFlow(dsl: string): string[] {
* Parses a single node string. * Parses a single node string.
* If the node is complex (e.g., has parentheses), it extracts the node type, node ID, and parameters. * If the node is complex (e.g., has parentheses), it extracts the node type, node ID, and parameters.
* @param nodeStr - The node string to parse. * @param nodeStr - The node string to parse.
* @param parentIterationId - The ID of the parent iteration node (if applicable).
* @returns A parsed node object. * @returns A parsed node object.
*/ */
function parseNode(nodeStr: string): Node { function parseNode(nodeStr: string, parentIterationId?: string): Node {
// Check if the node is a complex node // Check if the node is a complex node
if (nodeStr.startsWith('(') && nodeStr.endsWith(')')) { if (nodeStr.startsWith('(') && nodeStr.endsWith(')')) {
const innerContent = nodeStr.slice(1, -1).trim() // Remove outer parentheses const innerContent = nodeStr.slice(1, -1).trim() // Remove outer parentheses
@ -72,42 +74,53 @@ function parseNode(nodeStr: string): Node {
// Extract nodeType, nodeId, and params // Extract nodeType, nodeId, and params
const [nodeType, nodeId, ...paramsRaw] = parts const [nodeType, nodeId, ...paramsRaw] = parts
const params = parseParams(paramsRaw) const params = parseParams(paramsRaw, nodeType === 'iteration' ? nodeId.trim() : parentIterationId)
const complexNode = {
return {
nodeType: nodeType.trim(), nodeType: nodeType.trim(),
nodeId: nodeId.trim(), nodeId: nodeId.trim(),
params, params,
} }
if (parentIterationId) {
complexNode.iterationId = parentIterationId
complexNode.iterationIndex = 0 // Fixed as 0
}
return complexNode
} }
// If it's not a complex node, treat it as a plain node // If it's not a complex node, treat it as a plain node
return { nodeType: 'plain', nodeId: nodeStr.trim() } const plainNode: NodePlain = { nodeType: 'plain', nodeId: nodeStr.trim() }
if (parentIterationId) {
plainNode.iterationId = parentIterationId
plainNode.iterationIndex = 0 // Fixed as 0
}
return plainNode
} }
/** /**
* Parses parameters of a complex node. * Parses parameters of a complex node.
* Supports nested flows and complex sub-nodes. * Supports nested flows and complex sub-nodes.
* Adds iteration-specific metadata recursively.
* @param paramParts - The parameters string split by commas. * @param paramParts - The parameters string split by commas.
* @param iterationId - The ID of the iteration node, if applicable.
* @returns An array of parsed parameters (plain nodes, nested nodes, or flows). * @returns An array of parsed parameters (plain nodes, nested nodes, or flows).
*/ */
function parseParams(paramParts: string[]): (Node | Node[])[] { function parseParams(paramParts: string[], iterationId?: string): (Node | Node[] | number)[] {
return paramParts.map((part) => { return paramParts.map((part) => {
if (part.includes('->')) { if (part.includes('->')) {
// Parse as a flow and return an array of nodes // Parse as a flow and return an array of nodes
return parseTopLevelFlow(part).map(parseNode) return parseTopLevelFlow(part).map(node => parseNode(node, iterationId))
} }
else if (part.startsWith('(')) { else if (part.startsWith('(')) {
// Parse as a nested complex node // Parse as a nested complex node
return parseNode(part) return parseNode(part, iterationId)
} }
else if (!isNaN(Number(part.trim()))) { else if (!Number.isNaN(Number(part.trim()))) {
// Parse as a numeric parameter // Parse as a numeric parameter
return Number(part.trim()) return Number(part.trim())
} }
else { else {
// Parse as a plain node // Parse as a plain node
return parseNode(part) return parseNode(part, iterationId)
} }
}) })
} }

Loading…
Cancel
Save