diff --git a/cypress/package.json b/cypress/package.json
index 02e2a74c032de..832abd9ef58d8 100644
--- a/cypress/package.json
+++ b/cypress/package.json
@@ -26,6 +26,7 @@
"cypress": "^13.14.2",
"cypress-otp": "^1.0.3",
"cypress-real-events": "^1.13.0",
+ "flatted": "catalog:",
"lodash": "catalog:",
"nanoid": "catalog:",
"start-server-and-test": "^2.0.8"
diff --git a/cypress/support/index.ts b/cypress/support/index.ts
index 2fd1faeb22a77..6be463150304b 100644
--- a/cypress/support/index.ts
+++ b/cypress/support/index.ts
@@ -1,7 +1,7 @@
// Load type definitions that come with Cypress module
///
-import type { FrontendSettings } from '@n8n/api-types';
+import type { FrontendSettings, PushPayload, PushType } from '@n8n/api-types';
Cypress.Keyboard.defaults({
keystrokeDelay: 0,
@@ -66,7 +66,7 @@ declare global {
droppableSelector: string,
options?: Partial,
): void;
- push(type: string, data: unknown): void;
+ push(type: Type, data: PushPayload): void;
shouldNotHaveConsoleErrors(): void;
window(): Chainable<
AUTWindow & {
diff --git a/cypress/utils/executions.ts b/cypress/utils/executions.ts
index 0f429728560a0..12f4d2454a458 100644
--- a/cypress/utils/executions.ts
+++ b/cypress/utils/executions.ts
@@ -1,5 +1,5 @@
+import { stringify } from 'flatted';
import type { IDataObject, IPinData, ITaskData, ITaskDataConnections } from 'n8n-workflow';
-import { nanoid } from 'nanoid';
import { clickExecuteWorkflowButton } from '../composables/workflow';
@@ -39,41 +39,35 @@ export function createMockNodeExecutionData(
};
}
-export function createMockWorkflowExecutionData({
- executionId,
+function createMockWorkflowExecutionData({
runData,
- pinData = {},
lastNodeExecuted,
}: {
- executionId: string;
runData: Record;
pinData?: IPinData;
lastNodeExecuted: string;
}) {
return {
- executionId,
- data: {
- data: {
- startData: {},
- resultData: {
- runData,
- pinData,
- lastNodeExecuted,
- },
- executionData: {
- contextData: {},
- nodeExecutionStack: [],
- metadata: {},
- waitingExecution: {},
- waitingExecutionSource: {},
- },
+ data: stringify({
+ startData: {},
+ resultData: {
+ runData,
+ pinData: {},
+ lastNodeExecuted,
},
- mode: 'manual',
- startedAt: new Date().toISOString(),
- stoppedAt: new Date().toISOString(),
- status: 'success',
- finished: true,
- },
+ executionData: {
+ contextData: {},
+ nodeExecutionStack: [],
+ metadata: {},
+ waitingExecution: {},
+ waitingExecutionSource: {},
+ },
+ }),
+ mode: 'manual',
+ startedAt: new Date().toISOString(),
+ stoppedAt: new Date().toISOString(),
+ status: 'success',
+ finished: true,
};
}
@@ -81,14 +75,12 @@ export function runMockWorkflowExecution({
trigger,
lastNodeExecuted,
runData,
- workflowExecutionData,
}: {
trigger?: () => void;
lastNodeExecuted: string;
runData: Array>;
- workflowExecutionData?: ReturnType;
}) {
- const executionId = nanoid(8);
+ const executionId = Math.floor(Math.random() * 1_000_000).toString();
cy.intercept('POST', '/rest/workflows/**/run?**', {
statusCode: 201,
@@ -125,13 +117,17 @@ export function runMockWorkflowExecution({
resolvedRunData[nodeName] = nodeExecution[nodeName];
});
- cy.push(
- 'executionFinished',
- createMockWorkflowExecutionData({
- executionId,
- lastNodeExecuted,
- runData: resolvedRunData,
- ...workflowExecutionData,
- }),
- );
+ cy.intercept('GET', `/rest/executions/${executionId}`, {
+ statusCode: 200,
+ body: {
+ data: createMockWorkflowExecutionData({
+ lastNodeExecuted,
+ runData: resolvedRunData,
+ }),
+ },
+ }).as('getExecution');
+
+ cy.push('executionFinished', { executionId });
+
+ cy.wait('@getExecution');
}
diff --git a/packages/@n8n/api-types/src/push/execution.ts b/packages/@n8n/api-types/src/push/execution.ts
index 78c0b34a36324..3c7459dec5715 100644
--- a/packages/@n8n/api-types/src/push/execution.ts
+++ b/packages/@n8n/api-types/src/push/execution.ts
@@ -1,4 +1,4 @@
-import type { IRun, ITaskData, WorkflowExecuteMode } from 'n8n-workflow';
+import type { ITaskData, WorkflowExecuteMode } from 'n8n-workflow';
type ExecutionStarted = {
type: 'executionStarted';
@@ -16,8 +16,6 @@ type ExecutionFinished = {
type: 'executionFinished';
data: {
executionId: string;
- data: IRun;
- retryOf?: string;
};
};
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 88f843893194b..3f2b0397ab233 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -122,7 +122,7 @@
"express-rate-limit": "7.2.0",
"fast-glob": "catalog:",
"flat": "5.0.2",
- "flatted": "3.2.7",
+ "flatted": "catalog:",
"formidable": "3.5.1",
"handlebars": "4.7.8",
"helmet": "7.1.0",
diff --git a/packages/cli/src/workflow-execute-additional-data.ts b/packages/cli/src/workflow-execute-additional-data.ts
index 476ebf492dc7f..78c21b44c0795 100644
--- a/packages/cli/src/workflow-execute-additional-data.ts
+++ b/packages/cli/src/workflow-execute-additional-data.ts
@@ -309,54 +309,18 @@ function hookFunctionsPush(): IWorkflowExecuteHooks {
},
],
workflowExecuteAfter: [
- async function (this: WorkflowHooks, fullRunData: IRun): Promise {
- const { pushRef, executionId, retryOf } = this;
+ async function (this: WorkflowHooks): Promise {
+ const { pushRef, executionId } = this;
+ if (pushRef === undefined) return;
+
const { id: workflowId } = this.workflowData;
logger.debug('Executing hook (hookFunctionsPush)', {
executionId,
pushRef,
workflowId,
});
- // Push data to session which started the workflow
- if (pushRef === undefined) {
- return;
- }
-
- // Clone the object except the runData. That one is not supposed
- // to be send. Because that data got send piece by piece after
- // each node which finished executing
- // Edit: we now DO send the runData to the UI if mode=manual so that it shows the point of crashes
- let pushRunData;
- if (fullRunData.mode === 'manual') {
- pushRunData = fullRunData;
- } else {
- pushRunData = {
- ...fullRunData,
- data: {
- ...fullRunData.data,
- resultData: {
- ...fullRunData.data.resultData,
- runData: {},
- },
- },
- };
- }
- // Push data to editor-ui once workflow finished
- logger.debug(`Save execution progress to database for execution ID ${executionId} `, {
- executionId,
- workflowId,
- });
- // TODO: Look at this again
- pushInstance.send(
- 'executionFinished',
- {
- executionId,
- data: pushRunData,
- retryOf,
- },
- pushRef,
- );
+ pushInstance.send('executionFinished', { executionId }, pushRef);
},
],
};
diff --git a/packages/editor-ui/package.json b/packages/editor-ui/package.json
index c9b866bb37b1b..905d0819a1333 100644
--- a/packages/editor-ui/package.json
+++ b/packages/editor-ui/package.json
@@ -56,7 +56,7 @@
"esprima-next": "5.8.4",
"fast-json-stable-stringify": "^2.1.0",
"file-saver": "^2.0.2",
- "flatted": "^3.2.4",
+ "flatted": "catalog:",
"highlight.js": "catalog:frontend",
"humanize-duration": "^3.27.2",
"jsonpath": "^1.1.1",
diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts
index 9db1ac10407d5..4bf5f02e84a7c 100644
--- a/packages/editor-ui/src/Interface.ts
+++ b/packages/editor-ui/src/Interface.ts
@@ -392,15 +392,10 @@ export interface IExecutionsListResponse {
export interface IExecutionsCurrentSummaryExtended {
id: string;
- finished?: boolean;
status: ExecutionStatus;
mode: WorkflowExecuteMode;
- retryOf?: string | null;
- retrySuccessId?: string | null;
startedAt: Date;
- stoppedAt?: Date;
workflowId: string;
- workflowName?: string;
}
export interface IExecutionsStopData {
@@ -839,14 +834,12 @@ export interface IUsedCredential {
}
export interface WorkflowsState {
- activeExecutions: IExecutionsCurrentSummaryExtended[];
activeWorkflows: string[];
activeWorkflowExecution: ExecutionSummary | null;
currentWorkflowExecutions: ExecutionSummary[];
activeExecutionId: string | null;
executingNode: string[];
executionWaitingForWebhook: boolean;
- finishedExecutionsCount: number;
nodeMetadata: NodeMetadataMap;
subWorkflowExecutionError: Error | null;
usedCredentials: Record;
@@ -1083,11 +1076,6 @@ export interface IVersionsState {
currentVersion: IVersion | undefined;
}
-export interface IWorkflowsState {
- currentWorkflowExecutions: ExecutionSummary[];
- activeWorkflowExecution: ExecutionSummary | null;
- finishedExecutionsCount: number;
-}
export interface IWorkflowsMap {
[name: string]: IWorkflowDb;
}
diff --git a/packages/editor-ui/src/composables/usePushConnection.test.ts b/packages/editor-ui/src/composables/usePushConnection.test.ts
index 819b9e842e9a7..297235a42418d 100644
--- a/packages/editor-ui/src/composables/usePushConnection.test.ts
+++ b/packages/editor-ui/src/composables/usePushConnection.test.ts
@@ -1,6 +1,9 @@
+import { stringify } from 'flatted';
import { useRouter } from 'vue-router';
import { createPinia, setActivePinia } from 'pinia';
import type { PushMessage, PushPayload } from '@n8n/api-types';
+import { mock } from 'vitest-mock-extended';
+import type { WorkflowOperationError } from 'n8n-workflow';
import { usePushConnection } from '@/composables/usePushConnection';
import { usePushConnectionStore } from '@/stores/pushConnection.store';
@@ -8,7 +11,7 @@ import { useOrchestrationStore } from '@/stores/orchestration.store';
import { useUIStore } from '@/stores/ui.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useToast } from '@/composables/useToast';
-import type { WorkflowOperationError } from 'n8n-workflow';
+import type { IExecutionResponse } from '@/Interface';
vi.mock('vue-router', () => {
return {
@@ -135,34 +138,40 @@ describe('usePushConnection()', () => {
});
describe('executionFinished', () => {
- it('should handle executionFinished event correctly', async () => {
- const event: PushMessage = {
- type: 'executionFinished',
- data: {
- executionId: '1',
- data: {
- data: {
- resultData: {
- runData: {},
- },
- },
- finished: true,
- mode: 'manual',
- startedAt: new Date(),
- stoppedAt: new Date(),
- status: 'success',
- },
- },
- };
+ const executionId = '1';
+ const event: PushMessage = {
+ type: 'executionFinished',
+ data: { executionId: '1' },
+ };
- workflowsStore.activeExecutionId = '1';
+ beforeEach(() => {
+ workflowsStore.activeExecutionId = executionId;
uiStore.isActionActive.workflowRunning = true;
+ });
+
+ it('should handle executionFinished event correctly', async () => {
+ const spy = vi.spyOn(workflowsStore, 'fetchExecutionDataById').mockResolvedValue(
+ mock({
+ id: executionId,
+ data: stringify({
+ resultData: {
+ runData: {},
+ },
+ }) as unknown as IExecutionResponse['data'],
+ finished: true,
+ mode: 'manual',
+ startedAt: new Date(),
+ stoppedAt: new Date(),
+ status: 'success',
+ }),
+ );
const result = await pushConnection.pushMessageReceived(event);
expect(result).toBeTruthy();
expect(workflowsStore.workflowExecutionData).toBeDefined();
expect(uiStore.isActionActive['workflowRunning']).toBeTruthy();
+ expect(spy).toHaveBeenCalledWith(executionId);
expect(toast.showMessage).toHaveBeenCalledWith({
title: 'Workflow executed successfully',
@@ -171,35 +180,29 @@ describe('usePushConnection()', () => {
});
it('should handle isManualExecutionCancelled correctly', async () => {
- const event: PushMessage = {
- type: 'executionFinished',
- data: {
- executionId: '1',
- data: {
- data: {
- startData: {},
- resultData: {
- runData: {
- 'Last Node': [],
- },
- lastNodeExecuted: 'Last Node',
- error: {
- message:
- 'Your trial has ended. Upgrade now to keep automating',
- name: 'NodeApiError',
- node: 'Last Node',
- } as unknown as WorkflowOperationError,
+ const spy = vi.spyOn(workflowsStore, 'fetchExecutionDataById').mockResolvedValue(
+ mock({
+ id: executionId,
+ data: stringify({
+ startData: {},
+ resultData: {
+ runData: {
+ 'Last Node': [],
},
+ lastNodeExecuted: 'Last Node',
+ error: {
+ message:
+ 'Your trial has ended. Upgrade now to keep automating',
+ name: 'NodeApiError',
+ node: 'Last Node',
+ } as unknown as WorkflowOperationError,
},
- startedAt: new Date(),
- mode: 'manual',
- status: 'running',
- },
- },
- };
-
- workflowsStore.activeExecutionId = '1';
- uiStore.isActionActive['workflowRunning'] = true;
+ }) as unknown as IExecutionResponse['data'],
+ mode: 'manual',
+ startedAt: new Date(),
+ status: 'running',
+ }),
+ );
const result = await pushConnection.pushMessageReceived(event);
@@ -215,6 +218,7 @@ describe('usePushConnection()', () => {
expect(result).toBeTruthy();
expect(workflowsStore.workflowExecutionData).toBeDefined();
expect(uiStore.isActionActive.workflowRunning).toBeTruthy();
+ expect(spy).toHaveBeenCalledWith(executionId);
});
});
});
diff --git a/packages/editor-ui/src/composables/usePushConnection.ts b/packages/editor-ui/src/composables/usePushConnection.ts
index a5976d35d48bf..1d03ffe2d7b98 100644
--- a/packages/editor-ui/src/composables/usePushConnection.ts
+++ b/packages/editor-ui/src/composables/usePushConnection.ts
@@ -6,7 +6,6 @@ import type {
ExpressionError,
IDataObject,
INodeTypeNameVersion,
- IRun,
IRunExecutionData,
IWorkflowBase,
SubworkflowOperationError,
@@ -15,9 +14,8 @@ import type {
INodeTypeDescription,
NodeError,
} from 'n8n-workflow';
-import type { PushMessage, PushPayload } from '@n8n/api-types';
+import type { PushMessage } from '@n8n/api-types';
-import type { IExecutionResponse, IExecutionsCurrentSummaryExtended } from '@/Interface';
import { useNodeHelpers } from '@/composables/useNodeHelpers';
import { useToast } from '@/composables/useToast';
import { WORKFLOW_SETTINGS_MODAL_KEY } from '@/constants';
@@ -38,8 +36,6 @@ import type { PushMessageQueueItem } from '@/types';
import { useAssistantStore } from '@/stores/assistant.store';
import NodeExecutionErrorMessage from '@/components/NodeExecutionErrorMessage.vue';
-type IPushDataExecutionFinishedPayload = PushPayload<'executionFinished'>;
-
export function usePushConnection({ router }: { router: ReturnType }) {
const workflowHelpers = useWorkflowHelpers({ router });
const nodeHelpers = useNodeHelpers();
@@ -165,52 +161,6 @@ export function usePushConnection({ router }: { router: ReturnType 0
- )
- pushData.data.data.resultData.runData[key] = activeRunData[key];
- }
- }
- workflowsStore.finishActiveExecution(pushData);
- }
-
if (!uiStore.isActionActive['workflowRunning']) {
// No workflow is running so ignore the messages
return false;
}
- if (activeExecutionId !== pushData.executionId) {
+ const { executionId } = receivedData.data;
+ const { activeExecutionId } = workflowsStore;
+ if (executionId !== activeExecutionId) {
// The workflow which did finish execution did either not get started
// by this session or we do not have the execution id yet.
if (isRetry !== true) {
@@ -277,13 +205,32 @@ export function usePushConnection({ router }: { router: ReturnType {
const eventData: IDataObject = {
@@ -365,8 +312,8 @@ export function usePushConnection({ router }: { router: ReturnType = {
- data: executedData,
- executionId,
- retryOf: execution.retryOf,
- };
- workflowsStore.finishActiveExecution(pushData);
workflowHelpers.setDocumentTitle(execution.workflowData.name, 'IDLE');
workflowsStore.executingNode.length = 0;
workflowsStore.setWorkflowExecutionData(executedData as IExecutionResponse);
diff --git a/packages/editor-ui/src/stores/workflows.store.test.ts b/packages/editor-ui/src/stores/workflows.store.test.ts
index 66471fafbac72..8d56d8675abcd 100644
--- a/packages/editor-ui/src/stores/workflows.store.test.ts
+++ b/packages/editor-ui/src/stores/workflows.store.test.ts
@@ -8,13 +8,7 @@ import {
WAIT_NODE_TYPE,
} from '@/constants';
import { useWorkflowsStore } from '@/stores/workflows.store';
-import type {
- IExecutionResponse,
- IExecutionsCurrentSummaryExtended,
- INodeUi,
- IWorkflowDb,
- IWorkflowSettings,
-} from '@/Interface';
+import type { IExecutionResponse, INodeUi, IWorkflowDb, IWorkflowSettings } from '@/Interface';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { SEND_AND_WAIT_OPERATION } from 'n8n-workflow';
@@ -619,50 +613,6 @@ describe('useWorkflowsStore', () => {
});
});
});
-
- describe('finishActiveExecution', () => {
- it('should update execution', async () => {
- const cursor = 1;
- const ids = ['0', '1', '2'];
- workflowsStore.setActiveExecutions(
- ids.map((id) => ({ id })) as IExecutionsCurrentSummaryExtended[],
- );
-
- const stoppedAt = new Date();
-
- workflowsStore.finishActiveExecution({
- executionId: ids[cursor],
- data: {
- finished: true,
- stoppedAt,
- },
- } as PushPayload<'executionFinished'>);
-
- expect(workflowsStore.activeExecutions[cursor]).toStrictEqual({
- id: ids[cursor],
- finished: true,
- stoppedAt,
- });
- });
-
- it('should handle parameter casting', async () => {
- const cursor = 1;
- const ids = ['0', '1', '2'];
- workflowsStore.setActiveExecutions(
- ids.map((id) => ({ id })) as IExecutionsCurrentSummaryExtended[],
- );
-
- workflowsStore.finishActiveExecution({
- executionId: ids[cursor],
- } as PushPayload<'executionFinished'>);
-
- expect(workflowsStore.activeExecutions[cursor]).toStrictEqual({
- id: ids[cursor],
- finished: undefined,
- stoppedAt: undefined,
- });
- });
- });
});
function getMockEditFieldsNode() {
diff --git a/packages/editor-ui/src/stores/workflows.store.ts b/packages/editor-ui/src/stores/workflows.store.ts
index a9305f23f22a9..4bf38546b1e5f 100644
--- a/packages/editor-ui/src/stores/workflows.store.ts
+++ b/packages/editor-ui/src/stores/workflows.store.ts
@@ -11,10 +11,8 @@ import {
WAIT_NODE_TYPE,
} from '@/constants';
import type {
- ExecutionsQueryFilter,
IExecutionPushResponse,
IExecutionResponse,
- IExecutionsCurrentSummaryExtended,
IExecutionsListResponse,
INewWorkflowData,
INodeMetadata,
@@ -125,10 +123,8 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
const usedCredentials = ref>({});
const activeWorkflows = ref([]);
- const activeExecutions = ref([]);
const activeWorkflowExecution = ref(null);
const currentWorkflowExecutions = ref([]);
- const finishedExecutionsCount = ref(0);
const workflowExecutionData = ref(null);
const workflowExecutionPairedItemMappings = ref>>({});
const activeExecutionId = ref(null);
@@ -266,8 +262,6 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
const getWorkflowExecution = computed(() => workflowExecutionData.value);
- const getTotalFinishedExecutionsCount = computed(() => finishedExecutionsCount.value);
-
const getPastChatMessages = computed(() => Array.from(new Set(chatMessages.value)));
function getWorkflowResultDataByNodeName(nodeName: string): ITaskData[] | null {
@@ -1338,52 +1332,6 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
return ndvStore.activeNode;
}
- function addActiveExecution(newActiveExecution: IExecutionsCurrentSummaryExtended): void {
- // Check if the execution exists already
- const activeExecution = activeExecutions.value.find((execution) => {
- return execution.id === newActiveExecution.id;
- });
-
- if (activeExecution !== undefined) {
- // Exists already so no need to add it again
- if (activeExecution.workflowName === undefined) {
- activeExecution.workflowName = newActiveExecution.workflowName;
- }
- return;
- }
-
- activeExecutions.value.unshift(newActiveExecution);
- activeExecutionId.value = newActiveExecution.id;
- }
-
- function finishActiveExecution(finishedActiveExecution: PushPayload<'executionFinished'>): void {
- // Find the execution to set to finished
- const activeExecutionIndex = activeExecutions.value.findIndex((execution) => {
- return execution.id === finishedActiveExecution.executionId;
- });
-
- if (activeExecutionIndex === -1) {
- // The execution could not be found
- return;
- }
-
- Object.assign(activeExecutions.value[activeExecutionIndex], {
- ...(finishedActiveExecution.executionId !== undefined
- ? { id: finishedActiveExecution.executionId }
- : {}),
- finished: finishedActiveExecution.data?.finished,
- stoppedAt: finishedActiveExecution.data?.stoppedAt,
- });
-
- if (finishedActiveExecution.data?.data) {
- setWorkflowExecutionRunData(finishedActiveExecution.data.data);
- }
- }
-
- function setActiveExecutions(newActiveExecutions: IExecutionsCurrentSummaryExtended[]): void {
- activeExecutions.value = newActiveExecutions;
- }
-
// TODO: For sure needs some kind of default filter like last day, with max 10 results, ...
async function getPastExecutions(
filter: IDataObject,
@@ -1404,26 +1352,6 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
return await makeRestApiRequest(rootStore.restApiContext, 'GET', '/executions', sendData);
}
- async function getActiveExecutions(
- filter: IDataObject,
- ): Promise {
- let sendData = {};
- if (filter) {
- sendData = {
- filter,
- };
- }
- const rootStore = useRootStore();
- const output = await makeRestApiRequest<{ results: IExecutionsCurrentSummaryExtended[] }>(
- rootStore.restApiContext,
- 'GET',
- '/executions',
- sendData,
- );
-
- return output.results;
- }
-
async function getExecution(id: string): Promise {
const rootStore = useRootStore();
const response = await makeRestApiRequest(
@@ -1507,36 +1435,6 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
);
}
- async function loadCurrentWorkflowExecutions(
- requestFilter: ExecutionsQueryFilter,
- ): Promise {
- let retrievedActiveExecutions: IExecutionsCurrentSummaryExtended[] = [];
-
- if (!requestFilter.workflowId) {
- return [];
- }
-
- try {
- const rootStore = useRootStore();
- if ((!requestFilter.status || !requestFilter.finished) && isEmpty(requestFilter.metadata)) {
- retrievedActiveExecutions = await workflowsApi.getActiveExecutions(
- rootStore.restApiContext,
- {
- workflowId: requestFilter.workflowId,
- },
- );
- }
- const retrievedFinishedExecutions = await workflowsApi.getExecutions(
- rootStore.restApiContext,
- requestFilter,
- );
- finishedExecutionsCount.value = retrievedFinishedExecutions.count;
- return [...retrievedActiveExecutions, ...(retrievedFinishedExecutions.results || [])];
- } catch (error) {
- throw error;
- }
- }
-
async function fetchExecutionDataById(executionId: string): Promise {
const rootStore = useRootStore();
return await workflowsApi.getExecutionData(rootStore.restApiContext, executionId);
@@ -1644,10 +1542,8 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
workflow,
usedCredentials,
activeWorkflows,
- activeExecutions,
activeWorkflowExecution,
currentWorkflowExecutions,
- finishedExecutionsCount,
workflowExecutionData,
workflowExecutionPairedItemMappings,
activeExecutionId,
@@ -1682,7 +1578,6 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
executedNode,
getAllLoadedFinishedExecutions,
getWorkflowExecution,
- getTotalFinishedExecutionsCount,
getPastChatMessages,
isChatPanelOpen: computed(() => isChatPanelOpen.value),
isLogsPanelOpen: computed(() => isLogsPanelOpen.value),
@@ -1760,17 +1655,12 @@ export const useWorkflowsStore = defineStore(STORES.WORKFLOWS, () => {
clearNodeExecutionData,
pinDataByNodeName,
activeNode,
- addActiveExecution,
- finishActiveExecution,
- setActiveExecutions,
getPastExecutions,
- getActiveExecutions,
getExecution,
createNewWorkflow,
updateWorkflow,
runWorkflow,
removeTestWebhook,
- loadCurrentWorkflowExecutions,
fetchExecutionDataById,
deleteExecution,
addToCurrentExecutions,
diff --git a/packages/editor-ui/src/views/NodeView.vue b/packages/editor-ui/src/views/NodeView.vue
index 39d5a7c672c20..72947fe40058c 100644
--- a/packages/editor-ui/src/views/NodeView.vue
+++ b/packages/editor-ui/src/views/NodeView.vue
@@ -181,7 +181,6 @@ import { useNpsSurveyStore } from '@/stores/npsSurvey.store';
import { getResourcePermissions } from '@/permissions';
import { useBeforeUnload } from '@/composables/useBeforeUnload';
import NodeViewUnfinishedWorkflowMessage from '@/components/NodeViewUnfinishedWorkflowMessage.vue';
-import type { PushPayload } from '@n8n/api-types';
interface AddNodeOptions {
position?: XYPosition;
@@ -1728,10 +1727,6 @@ export default defineComponent({
if (execution === undefined) {
// execution finished but was not saved (e.g. due to low connectivity)
- this.workflowsStore.finishActiveExecution({
- executionId,
- data: { finished: true, stoppedAt: new Date() } as IRun,
- });
this.workflowsStore.executingNode.length = 0;
this.uiStore.removeActiveAction('workflowRunning');
@@ -1753,12 +1748,6 @@ export default defineComponent({
startedAt: execution.startedAt,
stoppedAt: execution.stoppedAt,
} as IRun;
- const pushData: PushPayload<'executionFinished'> = {
- data: executedData,
- executionId,
- retryOf: execution.retryOf,
- };
- this.workflowsStore.finishActiveExecution(pushData);
this.workflowHelpers.setDocumentTitle(execution.workflowData.name, 'IDLE');
this.workflowsStore.executingNode.length = 0;
this.workflowsStore.setWorkflowExecutionData(executedData as IExecutionResponse);
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index dd9248e41485e..1a43366f16a64 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -33,6 +33,9 @@ catalogs:
fast-glob:
specifier: 3.2.12
version: 3.2.12
+ flatted:
+ specifier: 3.2.7
+ version: 3.2.7
form-data:
specifier: 4.0.0
version: 4.0.0
@@ -216,6 +219,9 @@ importers:
cypress-real-events:
specifier: ^1.13.0
version: 1.13.0(cypress@13.14.2)
+ flatted:
+ specifier: 'catalog:'
+ version: 3.2.7
lodash:
specifier: 'catalog:'
version: 4.17.21
@@ -265,7 +271,7 @@ importers:
version: 4.0.7
axios:
specifier: 'catalog:'
- version: 1.7.4(debug@4.3.7)
+ version: 1.7.4
dotenv:
specifier: 8.6.0
version: 8.6.0
@@ -333,7 +339,7 @@ importers:
dependencies:
axios:
specifier: 'catalog:'
- version: 1.7.4(debug@4.3.7)
+ version: 1.7.4
packages/@n8n/codemirror-lang:
dependencies:
@@ -407,7 +413,7 @@ importers:
version: 3.666.0(@aws-sdk/client-sts@3.666.0)
'@getzep/zep-cloud':
specifier: 1.0.12
- version: 1.0.12(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)(langchain@0.3.5(4ubssgvn2k3t3hxnzmxuoc2aja))
+ version: 1.0.12(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)(langchain@0.3.5(7umjwzmwnymi4lyinuvazmp6ki))
'@getzep/zep-js':
specifier: 0.9.0
version: 0.9.0
@@ -434,7 +440,7 @@ importers:
version: 0.3.1(@aws-sdk/client-sso-oidc@3.666.0(@aws-sdk/client-sts@3.666.0))(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)
'@langchain/community':
specifier: 0.3.11
- version: 0.3.11(tzffvezibmkr4px5bpuitcp7xu)
+ version: 0.3.11(simkpjwqw7qnwbripe37u5qu7a)
'@langchain/core':
specifier: 'catalog:'
version: 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
@@ -521,7 +527,7 @@ importers:
version: 23.0.1
langchain:
specifier: 0.3.5
- version: 0.3.5(4ubssgvn2k3t3hxnzmxuoc2aja)
+ version: 0.3.5(7umjwzmwnymi4lyinuvazmp6ki)
lodash:
specifier: 'catalog:'
version: 4.17.21
@@ -774,7 +780,7 @@ importers:
version: 1.11.0
axios:
specifier: 'catalog:'
- version: 1.7.4(debug@4.3.7)
+ version: 1.7.4
bcryptjs:
specifier: 2.4.3
version: 2.4.3
@@ -839,7 +845,7 @@ importers:
specifier: 5.0.2
version: 5.0.2
flatted:
- specifier: 3.2.7
+ specifier: 'catalog:'
version: 3.2.7
formidable:
specifier: 3.5.1
@@ -1093,7 +1099,7 @@ importers:
dependencies:
'@langchain/core':
specifier: 'catalog:'
- version: 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
+ version: 0.3.15(openai@4.69.0(zod@3.23.8))
'@n8n/client-oauth2':
specifier: workspace:*
version: link:../@n8n/client-oauth2
@@ -1105,7 +1111,7 @@ importers:
version: 1.11.0
axios:
specifier: 'catalog:'
- version: 1.7.4(debug@4.3.7)
+ version: 1.7.4
concat-stream:
specifier: 2.0.0
version: 2.0.0
@@ -1395,7 +1401,7 @@ importers:
version: 10.11.0(vue@3.5.11(typescript@5.6.2))
axios:
specifier: 'catalog:'
- version: 1.7.4(debug@4.3.7)
+ version: 1.7.4
bowser:
specifier: 2.11.0
version: 2.11.0
@@ -1424,7 +1430,7 @@ importers:
specifier: ^2.0.2
version: 2.0.5
flatted:
- specifier: ^3.2.4
+ specifier: 'catalog:'
version: 3.2.7
highlight.js:
specifier: catalog:frontend
@@ -1875,7 +1881,7 @@ importers:
version: 0.15.2
axios:
specifier: 'catalog:'
- version: 1.7.4(debug@4.3.7)
+ version: 1.7.4
callsites:
specifier: 3.1.0
version: 3.1.0
@@ -1921,7 +1927,7 @@ importers:
devDependencies:
'@langchain/core':
specifier: 'catalog:'
- version: 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
+ version: 0.3.15(openai@4.69.0)
'@types/deep-equal':
specifier: ^1.0.1
version: 1.0.1
@@ -14076,7 +14082,7 @@ snapshots:
'@gar/promisify@1.1.3':
optional: true
- '@getzep/zep-cloud@1.0.12(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)(langchain@0.3.5(4ubssgvn2k3t3hxnzmxuoc2aja))':
+ '@getzep/zep-cloud@1.0.12(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)(langchain@0.3.5(7umjwzmwnymi4lyinuvazmp6ki))':
dependencies:
form-data: 4.0.0
node-fetch: 2.7.0(encoding@0.1.13)
@@ -14085,7 +14091,7 @@ snapshots:
zod: 3.23.8
optionalDependencies:
'@langchain/core': 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
- langchain: 0.3.5(4ubssgvn2k3t3hxnzmxuoc2aja)
+ langchain: 0.3.5(7umjwzmwnymi4lyinuvazmp6ki)
transitivePeerDependencies:
- encoding
@@ -14552,7 +14558,7 @@ snapshots:
- aws-crt
- encoding
- '@langchain/community@0.3.11(tzffvezibmkr4px5bpuitcp7xu)':
+ '@langchain/community@0.3.11(simkpjwqw7qnwbripe37u5qu7a)':
dependencies:
'@ibm-cloud/watsonx-ai': 1.1.2
'@langchain/core': 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
@@ -14562,7 +14568,7 @@ snapshots:
flat: 5.0.2
ibm-cloud-sdk-core: 5.1.0
js-yaml: 4.1.0
- langchain: 0.3.5(4ubssgvn2k3t3hxnzmxuoc2aja)
+ langchain: 0.3.5(7umjwzmwnymi4lyinuvazmp6ki)
langsmith: 0.2.3(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
uuid: 10.0.0
zod: 3.23.8
@@ -14575,7 +14581,7 @@ snapshots:
'@aws-sdk/client-s3': 3.666.0
'@aws-sdk/credential-provider-node': 3.666.0(@aws-sdk/client-sso-oidc@3.666.0(@aws-sdk/client-sts@3.666.0))(@aws-sdk/client-sts@3.666.0)
'@azure/storage-blob': 12.18.0(encoding@0.1.13)
- '@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)(langchain@0.3.5(4ubssgvn2k3t3hxnzmxuoc2aja))
+ '@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)(langchain@0.3.5(7umjwzmwnymi4lyinuvazmp6ki))
'@getzep/zep-js': 0.9.0
'@google-ai/generativelanguage': 2.6.0(encoding@0.1.13)
'@google-cloud/storage': 7.12.1(encoding@0.1.13)
@@ -14639,6 +14645,38 @@ snapshots:
transitivePeerDependencies:
- openai
+ '@langchain/core@0.3.15(openai@4.69.0(zod@3.23.8))':
+ dependencies:
+ ansi-styles: 5.2.0
+ camelcase: 6.3.0
+ decamelize: 1.2.0
+ js-tiktoken: 1.0.12
+ langsmith: 0.2.3(openai@4.69.0(zod@3.23.8))
+ mustache: 4.2.0
+ p-queue: 6.6.2
+ p-retry: 4.6.2
+ uuid: 10.0.0
+ zod: 3.23.8
+ zod-to-json-schema: 3.23.3(zod@3.23.8)
+ transitivePeerDependencies:
+ - openai
+
+ '@langchain/core@0.3.15(openai@4.69.0)':
+ dependencies:
+ ansi-styles: 5.2.0
+ camelcase: 6.3.0
+ decamelize: 1.2.0
+ js-tiktoken: 1.0.12
+ langsmith: 0.2.3(openai@4.69.0)
+ mustache: 4.2.0
+ p-queue: 6.6.2
+ p-retry: 4.6.2
+ uuid: 10.0.0
+ zod: 3.23.8
+ zod-to-json-schema: 3.23.3(zod@3.23.8)
+ transitivePeerDependencies:
+ - openai
+
'@langchain/google-common@0.1.1(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(zod@3.23.8)':
dependencies:
'@langchain/core': 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
@@ -15256,7 +15294,7 @@ snapshots:
'@rudderstack/rudder-sdk-node@2.0.9(tslib@2.6.2)':
dependencies:
- axios: 1.7.4(debug@4.3.7)
+ axios: 1.7.4
axios-retry: 3.7.0
component-type: 1.2.1
join-component: 1.1.0
@@ -17512,7 +17550,23 @@ snapshots:
'@babel/runtime': 7.24.7
is-retry-allowed: 2.2.0
+ axios@1.7.4:
+ dependencies:
+ follow-redirects: 1.15.6(debug@4.3.6)
+ form-data: 4.0.0
+ proxy-from-env: 1.1.0
+ transitivePeerDependencies:
+ - debug
+
axios@1.7.4(debug@4.3.7):
+ dependencies:
+ follow-redirects: 1.15.6(debug@4.3.7)
+ form-data: 4.0.0
+ proxy-from-env: 1.1.0
+ transitivePeerDependencies:
+ - debug
+
+ axios@1.7.7:
dependencies:
follow-redirects: 1.15.6(debug@4.3.6)
form-data: 4.0.0
@@ -19188,7 +19242,7 @@ snapshots:
eslint-import-resolver-node@0.3.9:
dependencies:
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
is-core-module: 2.13.1
resolve: 1.22.8
transitivePeerDependencies:
@@ -19213,7 +19267,7 @@ snapshots:
eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0):
dependencies:
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
optionalDependencies:
'@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2)
eslint: 8.57.0
@@ -19233,7 +19287,7 @@ snapshots:
array.prototype.findlastindex: 1.2.3
array.prototype.flat: 1.3.2
array.prototype.flatmap: 1.3.2
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
doctrine: 2.1.0
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
@@ -20026,7 +20080,7 @@ snapshots:
array-parallel: 0.1.3
array-series: 0.1.5
cross-spawn: 4.0.2
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@@ -20412,7 +20466,7 @@ snapshots:
infisical-node@1.3.0:
dependencies:
- axios: 1.7.7(debug@4.3.6)
+ axios: 1.7.7
dotenv: 16.3.1
tweetnacl: 1.0.3
tweetnacl-util: 0.15.1
@@ -21342,7 +21396,7 @@ snapshots:
kuler@2.0.0: {}
- langchain@0.3.5(4ubssgvn2k3t3hxnzmxuoc2aja):
+ langchain@0.3.5(7umjwzmwnymi4lyinuvazmp6ki):
dependencies:
'@langchain/core': 0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8))
'@langchain/openai': 0.3.11(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)
@@ -21366,7 +21420,7 @@ snapshots:
'@langchain/groq': 0.1.2(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)
'@langchain/mistralai': 0.1.1(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))(encoding@0.1.13)
'@langchain/ollama': 0.1.1(@langchain/core@0.3.15(openai@4.69.0(encoding@0.1.13)(zod@3.23.8)))
- axios: 1.7.4(debug@4.3.7)
+ axios: 1.7.4
cheerio: 1.0.0
handlebars: 4.7.8
transitivePeerDependencies:
@@ -21385,6 +21439,28 @@ snapshots:
optionalDependencies:
openai: 4.69.0(encoding@0.1.13)(zod@3.23.8)
+ langsmith@0.2.3(openai@4.69.0(zod@3.23.8)):
+ dependencies:
+ '@types/uuid': 10.0.0
+ commander: 10.0.1
+ p-queue: 6.6.2
+ p-retry: 4.6.2
+ semver: 7.6.0
+ uuid: 10.0.0
+ optionalDependencies:
+ openai: 4.69.0(zod@3.23.8)
+
+ langsmith@0.2.3(openai@4.69.0):
+ dependencies:
+ '@types/uuid': 10.0.0
+ commander: 10.0.1
+ p-queue: 6.6.2
+ p-retry: 4.6.2
+ semver: 7.6.0
+ uuid: 10.0.0
+ optionalDependencies:
+ openai: 4.69.0(zod@3.23.8)
+
lazy-ass@1.6.0: {}
ldapts@4.2.6:
@@ -22719,6 +22795,22 @@ snapshots:
- encoding
- supports-color
+ openai@4.69.0(zod@3.23.8):
+ dependencies:
+ '@types/node': 18.16.16
+ '@types/node-fetch': 2.6.4
+ abort-controller: 3.0.0
+ agentkeepalive: 4.2.1
+ form-data-encoder: 1.7.2
+ formdata-node: 4.4.1
+ node-fetch: 2.7.0(encoding@0.1.13)
+ optionalDependencies:
+ zod: 3.23.8
+ transitivePeerDependencies:
+ - encoding
+ - supports-color
+ optional: true
+
openapi-sampler@1.5.1:
dependencies:
'@types/json-schema': 7.0.15
@@ -22899,7 +22991,7 @@ snapshots:
pdf-parse@1.1.1:
dependencies:
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
node-ensure: 0.0.0
transitivePeerDependencies:
- supports-color
@@ -23101,7 +23193,7 @@ snapshots:
posthog-node@3.2.1:
dependencies:
- axios: 1.7.7(debug@4.3.6)
+ axios: 1.7.7
rusha: 0.8.14
transitivePeerDependencies:
- debug
@@ -23730,7 +23822,7 @@ snapshots:
rhea@1.0.24:
dependencies:
- debug: 3.2.7(supports-color@8.1.1)
+ debug: 3.2.7(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@@ -24106,7 +24198,7 @@ snapshots:
asn1.js: 5.4.1
asn1.js-rfc2560: 5.0.1(asn1.js@5.4.1)
asn1.js-rfc5280: 3.0.0
- axios: 1.7.7(debug@4.3.6)
+ axios: 1.7.7
big-integer: 1.6.51
bignumber.js: 9.1.2
binascii: 0.0.2
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 7dd0916282f9d..52e1230ca38f1 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -14,6 +14,7 @@ catalog:
basic-auth: 2.0.1
chokidar: 4.0.1
fast-glob: 3.2.12
+ flatted: 3.2.7
form-data: 4.0.0
lodash: 4.17.21
luxon: 3.4.4