From e2964b56c4bec07a95b77ea2003fd2652e435ed6 Mon Sep 17 00:00:00 2001 From: Alexis Falaise Date: Wed, 9 Apr 2025 12:03:26 +0200 Subject: [PATCH] migrate from queuedEdgeIds to queuedEdges --- packages/bot-engine/src/addPortalEdge.ts | 14 ++----- .../logic/typebotLink/executeTypebotLink.ts | 4 +- .../bot-engine/src/computeCurrentProgress.ts | 4 +- packages/bot-engine/src/continueBotFlow.ts | 2 +- .../src/events/connectEdgeToNextBlock.ts | 16 ++++---- packages/bot-engine/src/executeGroup.ts | 2 +- packages/bot-engine/src/getNextGroup.ts | 36 ++++++++-------- packages/chat-session/src/schemas.ts | 41 +++++++++++++++++-- packages/typebot/src/schemas/edge.ts | 2 - 9 files changed, 70 insertions(+), 51 deletions(-) diff --git a/packages/bot-engine/src/addPortalEdge.ts b/packages/bot-engine/src/addPortalEdge.ts index b1ef6bdcb..3c194b905 100644 --- a/packages/bot-engine/src/addPortalEdge.ts +++ b/packages/bot-engine/src/addPortalEdge.ts @@ -4,7 +4,7 @@ import type { Edge } from "@typebot.io/typebot/schemas/edge"; export const addPortalEdge = ( id: string, state: SessionState, - { to, condition }: Pick, + { to }: Pick, ): SessionState => { const existingEdge = state.typebotsQueue[0].typebot.edges.find( (e) => e.id === id, @@ -26,10 +26,7 @@ export const addPortalEdge = ( ? queue.typebot.edges.map((e) => e.id === id ? { ...e, to } : e, ) - : [ - ...queue.typebot.edges, - createPortalEdge({ id, to, condition }), - ], + : [...queue.typebot.edges, createPortalEdge({ id, to })], }, } : queue, @@ -38,13 +35,8 @@ export const addPortalEdge = ( return newSessionState; }; -const createPortalEdge = ({ - id, - to, - condition, -}: Pick) => ({ +const createPortalEdge = ({ id, to }: Pick) => ({ id, from: { blockId: "", groupId: "" }, to, - condition, }); diff --git a/packages/bot-engine/src/blocks/logic/typebotLink/executeTypebotLink.ts b/packages/bot-engine/src/blocks/logic/typebotLink/executeTypebotLink.ts index 62fce688b..ab2520e56 100644 --- a/packages/bot-engine/src/blocks/logic/typebotLink/executeTypebotLink.ts +++ b/packages/bot-engine/src/blocks/logic/typebotLink/executeTypebotLink.ts @@ -101,7 +101,7 @@ const addSameTypebotToState = async ({ ...newSessionState.typebotsQueue[0].typebot, }, resultId: newSessionState.typebotsQueue[0].resultId, - queuedEdgeIds: edgeIdToQueue ? [edgeIdToQueue] : undefined, + queuedEdges: edgeIdToQueue ? [{ id: edgeIdToQueue }] : undefined, answers: newSessionState.typebotsQueue[0].answers, isMergingWithParent: true, }, @@ -161,7 +161,7 @@ const addLinkedTypebotToState = async ( : shouldMergeResults ? newSessionState.typebotsQueue[0].resultId : createId(), - queuedEdgeIds: edgeIdToQueue ? [edgeIdToQueue] : undefined, + queuedEdges: edgeIdToQueue ? [{ id: edgeIdToQueue }] : undefined, answers: shouldMergeResults ? newSessionState.typebotsQueue[0].answers : [], diff --git a/packages/bot-engine/src/computeCurrentProgress.ts b/packages/bot-engine/src/computeCurrentProgress.ts index 89a0a754e..5dcee6873 100644 --- a/packages/bot-engine/src/computeCurrentProgress.ts +++ b/packages/bot-engine/src/computeCurrentProgress.ts @@ -93,8 +93,8 @@ const computePossibleNextInputBlocks = ({ if (outgoingEdgeIds.length > 0 || group.blocks.length !== blockIndex + 1) return possibleNextInputBlocks; - if (typebotsQueue.length > 1 || typebotsQueue[0].queuedEdgeIds?.length) { - const nextEdgeId = typebotsQueue[0].queuedEdgeIds?.[0]; + if (typebotsQueue.length > 1 || typebotsQueue[0].queuedEdges?.length) { + const nextEdgeId = typebotsQueue[0].queuedEdges?.[0]?.id; const to = typebotsQueue[1].typebot.edges.find(byId(nextEdgeId))?.to; if (!to) return possibleNextInputBlocks; const blockId = diff --git a/packages/bot-engine/src/continueBotFlow.ts b/packages/bot-engine/src/continueBotFlow.ts index 3cd9ae95e..1cb333640 100644 --- a/packages/bot-engine/src/continueBotFlow.ts +++ b/packages/bot-engine/src/continueBotFlow.ts @@ -217,7 +217,7 @@ export const continueBotFlow = async ( if ( !nextEdgeId && newSessionState.typebotsQueue.length === 1 && - (newSessionState.typebotsQueue[0].queuedEdgeIds ?? []).length === 0 + (newSessionState.typebotsQueue[0].queuedEdges ?? []).length === 0 ) return { messages: [], diff --git a/packages/bot-engine/src/events/connectEdgeToNextBlock.ts b/packages/bot-engine/src/events/connectEdgeToNextBlock.ts index 7bf99202b..1f5b80ab2 100644 --- a/packages/bot-engine/src/events/connectEdgeToNextBlock.ts +++ b/packages/bot-engine/src/events/connectEdgeToNextBlock.ts @@ -83,30 +83,28 @@ export const connectEdgeToNextBlock = async ({ if (!resumeMetadata) return state; let newSessionState = state; - let condition: Condition | undefined; if (event.type === EventType.REPLY) { condition = event.options?.exitCondition?.condition; } + const virtualEdgeId = `virtual-${event.id}`; const { group, block } = resumeMetadata; - newSessionState = addPortalEdge(`virtual-${event.id}`, newSessionState, { + newSessionState = addPortalEdge(virtualEdgeId, newSessionState, { to: { groupId: group.id, blockId: block.id }, - condition, }); + const virtualEdge = { id: virtualEdgeId, condition }; + newSessionState = { ...newSessionState, typebotsQueue: [ { ...newSessionState.typebotsQueue[0], - queuedEdgeIds: newSessionState.typebotsQueue[0].queuedEdgeIds - ? [ - `virtual-${event.id}`, - ...newSessionState.typebotsQueue[0].queuedEdgeIds, - ] - : [`virtual-${event.id}`], + queuedEdges: newSessionState.typebotsQueue[0].queuedEdges + ? [virtualEdge, ...newSessionState.typebotsQueue[0].queuedEdges] + : [virtualEdge], }, ...newSessionState.typebotsQueue.slice(1), ], diff --git a/packages/bot-engine/src/executeGroup.ts b/packages/bot-engine/src/executeGroup.ts index bb78c33bc..8a90f0da8 100644 --- a/packages/bot-engine/src/executeGroup.ts +++ b/packages/bot-engine/src/executeGroup.ts @@ -243,7 +243,7 @@ export const executeGroup = async ( if ( !nextEdgeId && newSessionState.typebotsQueue.length === 1 && - (newSessionState.typebotsQueue[0].queuedEdgeIds ?? []).length === 0 + (newSessionState.typebotsQueue[0].queuedEdges ?? []).length === 0 ) return { messages, diff --git a/packages/bot-engine/src/getNextGroup.ts b/packages/bot-engine/src/getNextGroup.ts index a69ee3c37..0527d4bc3 100644 --- a/packages/bot-engine/src/getNextGroup.ts +++ b/packages/bot-engine/src/getNextGroup.ts @@ -1,7 +1,8 @@ -import type { Block } from "@typebot.io/blocks-core/schemas/schema"; -import type { SessionState } from "@typebot.io/chat-session/schemas"; +import type { + QueuedEdge, + SessionState, +} from "@typebot.io/chat-session/schemas"; import { executeCondition } from "@typebot.io/conditions/executeCondition"; -import { getBlockById } from "@typebot.io/groups/helpers/getBlockById"; import type { Group } from "@typebot.io/groups/schemas"; import { byId, isDefined, isNotDefined } from "@typebot.io/lib/utils"; import type { Prisma } from "@typebot.io/prisma/types"; @@ -27,17 +28,12 @@ export const getNextGroup = async ({ }): Promise => { const nextEdge = state.typebotsQueue[0].typebot.edges.find(byId(edgeId)); if (!nextEdge) { - const nextEdgeResponse = popQueuedEdge(state); - const poppedEdgeId = nextEdgeResponse.edgeId; - const poppedEdge = - nextEdgeResponse.state.typebotsQueue[0].typebot.edges.find( - byId(poppedEdgeId), - ); + const queuedEdgeResponse = popQueuedEdge(state); const exitConditionMet = - poppedEdge?.condition && - executeCondition(poppedEdge.condition, { - variables: nextEdgeResponse.state.typebotsQueue[0].typebot.variables, + queuedEdgeResponse.queuedEdge?.condition && + executeCondition(queuedEdgeResponse.queuedEdge.condition, { + variables: state.typebotsQueue[0].typebot.variables, sessionStore, }); @@ -47,7 +43,7 @@ export const getNextGroup = async ({ }; } - let newSessionState = nextEdgeResponse.state; + let newSessionState = queuedEdgeResponse.state; if (newSessionState.typebotsQueue.length > 1) { const isMergingWithParent = newSessionState.typebotsQueue[0].isMergingWithParent; @@ -112,10 +108,10 @@ export const getNextGroup = async ({ newSessionState.typebotsQueue[0].answers.length, }; } - if (nextEdgeResponse.edgeId) + if (queuedEdgeResponse.queuedEdge?.id) return getNextGroup({ state: newSessionState, - edgeId: nextEdgeResponse.edgeId, + edgeId: queuedEdgeResponse.queuedEdge.id, isOffDefaultPath, sessionStore, }); @@ -168,17 +164,17 @@ export const getNextGroup = async ({ const popQueuedEdge = ( state: SessionState, -): { edgeId?: string; state: SessionState } => { - const edgeId = state.typebotsQueue[0].queuedEdgeIds?.[0]; - if (!edgeId) return { state }; +): { queuedEdge?: QueuedEdge; state: SessionState } => { + const queuedEdge = state.typebotsQueue[0].queuedEdges?.[0]; + if (!queuedEdge) return { state }; return { - edgeId, + queuedEdge, state: { ...state, typebotsQueue: [ { ...state.typebotsQueue[0], - queuedEdgeIds: state.typebotsQueue[0].queuedEdgeIds?.slice(1), + queuedEdges: state.typebotsQueue[0].queuedEdges?.slice(1), }, ...state.typebotsQueue.slice(1), ], diff --git a/packages/chat-session/src/schemas.ts b/packages/chat-session/src/schemas.ts index ea426fbab..1403f2232 100644 --- a/packages/chat-session/src/schemas.ts +++ b/packages/chat-session/src/schemas.ts @@ -1,4 +1,5 @@ import { isInputBlock } from "@typebot.io/blocks-core/helpers"; +import { conditionSchema } from "@typebot.io/conditions/schemas"; import type { Prisma } from "@typebot.io/prisma/types"; import { answerInSessionStateSchemaV2, @@ -124,6 +125,12 @@ const sessionStateSchemaV2 = z.object({ .optional(), }); +const queuedEdgeSchema = z.object({ + id: z.string(), + condition: conditionSchema.optional(), +}); +export type QueuedEdge = z.infer; + const sessionStateSchemaV3 = sessionStateSchemaV2 .omit({ currentBlock: true }) .extend({ @@ -150,19 +157,33 @@ const sessionStateSchemaV3 = sessionStateSchemaV2 .optional(), }); -export type SessionState = z.infer; +const sessionStateSchemaV4 = sessionStateSchemaV3.extend({ + version: z.literal("4"), + typebotsQueue: z.array( + sessionStateSchemaV2.shape.typebotsQueue.element.extend({ + queuedEdges: z.array(queuedEdgeSchema).optional(), + }), + ), +}); + +export type SessionState = z.infer; export const sessionStateSchema = z .discriminatedUnion("version", [ sessionStateSchemaV1, sessionStateSchemaV2, sessionStateSchemaV3, + sessionStateSchemaV4, ]) .transform((state): SessionState => { - if (state.version === "3") return state; + if (state.version === "4") return state; let migratedState: any = state; if (!state.version) migratedState = migrateFromV1ToV2(state); - return migrateFromV2ToV3(migratedState); + if (migratedState.version === "2") + migratedState = migrateFromV2ToV3(migratedState); + if (migratedState.version === "3") + migratedState = migrateFromV3ToV4(migratedState); + return migratedState; }) as z.ZodType; const migrateFromV1ToV2 = ( @@ -246,6 +267,20 @@ const migrateFromV2ToV3 = ( workspaceId: "", }); +const migrateFromV3ToV4 = ( + state: z.infer, +): z.infer => ({ + ...state, + version: "4", + typebotsQueue: state.typebotsQueue.map((typebot) => ({ + ...typebot, + queuedEdges: typebot.queuedEdgeIds?.map((id) => ({ + id, + })), + queuedEdgeIds: undefined, + })), +}); + const chatSessionSchema = z.object({ id: z.string(), createdAt: z.date(), diff --git a/packages/typebot/src/schemas/edge.ts b/packages/typebot/src/schemas/edge.ts index e1aba3fd4..19ccc8231 100644 --- a/packages/typebot/src/schemas/edge.ts +++ b/packages/typebot/src/schemas/edge.ts @@ -1,4 +1,3 @@ -import { conditionSchema } from "@typebot.io/conditions/schemas"; import { z } from "@typebot.io/zod"; const blockSourceSchema = z.object({ @@ -24,6 +23,5 @@ export const edgeSchema = z.object({ id: z.string(), from: sourceSchema, to: targetSchema, - condition: conditionSchema.optional(), }); export type Edge = z.infer;