@gadmin2n/schematics 0.0.72 → 0.0.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/job.prisma +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/system.prisma +0 -21
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +171 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/AgendaJob.ts +60 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Event.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowEventOutbox.ts +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeInstance.ts +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeType.ts +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/.env +5 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +5 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma.config.ts +14 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +4 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +49 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +746 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +786 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.controller.ts +6 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.service.ts +79 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.spec.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.ts +145 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/{canvas/canvas.service.spec.ts → agendaJob/agendaJob.service.spec.ts} +71 -65
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.service.ts +83 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +2 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.module.ts +9 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +100 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +19 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.dto.ts +43 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.ts +317 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.controller.ts +16 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.service.ts +13 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +220 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +82 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.module.ts +16 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +505 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +22 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.ts +147 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +356 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.ts +110 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.spec.ts +22 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.ts +216 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +356 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.ts +168 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.spec.ts +22 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.ts +199 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.module.ts +10 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.spec.ts +348 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.ts +106 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/yarn.lock +579 -1082
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +278 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/config/development-sql.yaml +5 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/docker-compose.yml +25 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/package.json +13 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/sql/create-event-trigger.sql +87 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.env +7 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/SANDBOX.md +122 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package-lock.json +4285 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package.json +28 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/code-execute.test.ts +44 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/http-request.test.ts +87 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/helpers.test.ts +225 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/node-type-consistency.test.ts +101 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/code-execute.ts +51 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-execute.ts +85 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-query.ts +35 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/http-request.ts +54 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts +6 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/reporting.ts +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/send-notification.ts +47 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/config.ts +13 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/condition.ts +101 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/context.ts +58 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/graph.ts +184 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/helpers.ts +133 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/node-types.ts +57 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/types.ts +77 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/index.ts +36 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/outbox-poller.ts +226 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/workflows/dsl-workflow.ts +411 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/tsconfig.json +19 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/vitest.config.ts +8 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/yarn.lock +1905 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/package-lock.json +17555 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +5 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/sider.tsx +5 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/title.tsx +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +63 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +91 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +48 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/show.tsx +43 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +14 -9
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +14 -9
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +309 -56
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/show.tsx +1 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/create.tsx +108 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/edit.tsx +124 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/index.tsx +4 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +245 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/show.tsx +70 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +0 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +160 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +120 -148
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CodeFloatWindow.tsx +74 -181
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/LivePreview.tsx +15 -13
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasConfigRegistry.tsx +2 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasContextMenuRegistry.tsx +338 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasDefaults.ts +18 -17
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/BarChartDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/LineChartDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/{ChartViewerConfigModal.tsx → MultiChartConfigModal.tsx} +30 -18
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/MultiChartDataSourceModal.tsx +427 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/NumCardDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/PromptModal.tsx +6 -14
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/RadarChartDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/TableDataSourceModal.tsx +10 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/canvasModalProps.ts +24 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/demos.ts +45 -63
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +99 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExportModal.tsx +87 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +322 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ImportModal.tsx +175 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeEditModal.tsx +60 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +1150 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.tsx +101 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +198 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/VersionPanel.tsx +81 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +566 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.ts +224 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +524 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +343 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +243 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +363 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/DynamicConfigForm.tsx +154 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +176 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/create.tsx +77 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/edit.tsx +112 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/index.tsx +305 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +282 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +469 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +92 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/create.tsx +111 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/edit.tsx +127 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/index.tsx +4 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +254 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/show.tsx +74 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/yarn.lock +1501 -1199
- package/package.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.controller.spec.ts +0 -22
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/BarChart/index.tsx +0 -896
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartSwitcher/index.tsx +0 -219
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartViewer/index.tsx +0 -159
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Filter/index.tsx +0 -192
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/LineChart/index.tsx +0 -1034
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/NumCard.module.css +0 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/index.tsx +0 -509
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumLineCard/index.tsx +0 -66
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/PieChart/index.tsx +0 -552
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/RadarChart/index.tsx +0 -263
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Section/index.tsx +0 -35
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Table/index.tsx +0 -207
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/TreemapChart/index.tsx +0 -382
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/WorldMap/index.tsx +0 -135
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/chart-constants.ts +0 -53
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/InfoIcon.tsx +0 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/index.ts +0 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/config.ts +0 -31
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/nameMap.json +0 -9
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/world.geo.json +0 -39349
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/metric-info-tooltip/index.tsx +0 -19
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DSL Workflow — The dynamic interpreter that executes any workflow DSL.
|
|
3
|
+
*
|
|
4
|
+
* This is the ONLY Temporal workflow in the system. It receives a DSL definition
|
|
5
|
+
* and interprets it at runtime, calling the appropriate activities for each node.
|
|
6
|
+
*
|
|
7
|
+
* Temporal Workflow constraints apply:
|
|
8
|
+
* - Must be deterministic (no Math.random, Date.now, etc.)
|
|
9
|
+
* - Side effects only through activities
|
|
10
|
+
* - Use workflow.sleep() instead of setTimeout
|
|
11
|
+
*/
|
|
12
|
+
import {
|
|
13
|
+
proxyActivities,
|
|
14
|
+
defineSignal,
|
|
15
|
+
defineQuery,
|
|
16
|
+
setHandler,
|
|
17
|
+
condition,
|
|
18
|
+
sleep,
|
|
19
|
+
CancellationScope,
|
|
20
|
+
isCancellation,
|
|
21
|
+
executeChild,
|
|
22
|
+
} from '@temporalio/workflow';
|
|
23
|
+
import type {
|
|
24
|
+
WorkflowInput,
|
|
25
|
+
WorkflowResult,
|
|
26
|
+
DslNode,
|
|
27
|
+
WorkflowDSL,
|
|
28
|
+
NodeStatus,
|
|
29
|
+
ApprovalSignalPayload,
|
|
30
|
+
ReportNodeStatusInput,
|
|
31
|
+
ReportWorkflowStatusInput,
|
|
32
|
+
} from '../dsl/types';
|
|
33
|
+
import { assertNever } from '../dsl/node-types';
|
|
34
|
+
import {
|
|
35
|
+
resolveTemplates,
|
|
36
|
+
resolveExpression,
|
|
37
|
+
getNestedValue,
|
|
38
|
+
evaluateConditions,
|
|
39
|
+
getSuccessorsFromNodes,
|
|
40
|
+
getNextNodes,
|
|
41
|
+
} from '../dsl/helpers';
|
|
42
|
+
|
|
43
|
+
// ─── Activity Proxies ─────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
const acts = proxyActivities<typeof import('../activities')>({
|
|
46
|
+
startToCloseTimeout: '60s',
|
|
47
|
+
retry: { maximumAttempts: 3 },
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const reportActs = proxyActivities<typeof import('../activities')>({
|
|
51
|
+
startToCloseTimeout: '10s',
|
|
52
|
+
retry: { maximumAttempts: 5 },
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// ─── Signals & Queries ────────────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
export const approvalSignal = defineSignal<[ApprovalSignalPayload]>('approval');
|
|
58
|
+
export const cancelSignal = defineSignal('cancel');
|
|
59
|
+
|
|
60
|
+
export const getProgressQuery = defineQuery<Record<string, NodeStatus>>('getProgress');
|
|
61
|
+
|
|
62
|
+
// ─── Main Workflow ────────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
export async function dslWorkflow(input: WorkflowInput): Promise<WorkflowResult> {
|
|
65
|
+
const { instanceId, dsl, context: initialContext } = input;
|
|
66
|
+
|
|
67
|
+
// Node status tracking (for queries)
|
|
68
|
+
const nodeStatuses: Record<string, NodeStatus> = {};
|
|
69
|
+
// Execution context — flows between nodes
|
|
70
|
+
const ctx: Record<string, any> = { ...initialContext };
|
|
71
|
+
// Approval results collected from signals
|
|
72
|
+
const approvalResults: Record<string, ApprovalSignalPayload> = {};
|
|
73
|
+
// Cancellation flag
|
|
74
|
+
let cancelled = false;
|
|
75
|
+
|
|
76
|
+
// Set up signal handlers
|
|
77
|
+
setHandler(approvalSignal, (payload: ApprovalSignalPayload) => {
|
|
78
|
+
approvalResults[payload.nodeId] = payload;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
setHandler(cancelSignal, () => {
|
|
82
|
+
cancelled = true;
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
setHandler(getProgressQuery, () => nodeStatuses);
|
|
86
|
+
|
|
87
|
+
// Report workflow as RUNNING
|
|
88
|
+
await reportActs.reportWorkflowStatus({ instanceId, status: 'RUNNING' });
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
// Find trigger nodes and start from their successors
|
|
92
|
+
const triggerNodes = dsl.nodes.filter((n) => n.type.endsWith('_trigger'));
|
|
93
|
+
const startNodeIds = getSuccessorsFromNodes(dsl, triggerNodes.map((n) => n.id));
|
|
94
|
+
|
|
95
|
+
// Execute the graph starting from trigger successors
|
|
96
|
+
await executeGraph(dsl, startNodeIds, ctx, nodeStatuses, instanceId, approvalResults, () => cancelled);
|
|
97
|
+
|
|
98
|
+
// Report success
|
|
99
|
+
await reportActs.reportWorkflowStatus({ instanceId, status: 'COMPLETED', result: ctx });
|
|
100
|
+
return { status: 'COMPLETED', context: ctx };
|
|
101
|
+
} catch (err: any) {
|
|
102
|
+
if (isCancellation(err) || cancelled) {
|
|
103
|
+
await reportActs.reportWorkflowStatus({ instanceId, status: 'CANCELLED' });
|
|
104
|
+
return { status: 'CANCELLED', context: ctx };
|
|
105
|
+
}
|
|
106
|
+
await reportActs.reportWorkflowStatus({ instanceId, status: 'FAILED', result: { error: err.message } });
|
|
107
|
+
return { status: 'FAILED', context: ctx, error: err.message };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ─── Graph Execution Engine ───────────────────────────────────────────────────
|
|
112
|
+
|
|
113
|
+
async function executeGraph(
|
|
114
|
+
dsl: WorkflowDSL,
|
|
115
|
+
startNodeIds: string[],
|
|
116
|
+
ctx: Record<string, any>,
|
|
117
|
+
nodeStatuses: Record<string, NodeStatus>,
|
|
118
|
+
instanceId: number,
|
|
119
|
+
approvalResults: Record<string, ApprovalSignalPayload>,
|
|
120
|
+
isCancelled: () => boolean,
|
|
121
|
+
): Promise<void> {
|
|
122
|
+
// BFS-style execution following edges
|
|
123
|
+
const executed = new Set<string>();
|
|
124
|
+
const queue = [...startNodeIds];
|
|
125
|
+
|
|
126
|
+
while (queue.length > 0) {
|
|
127
|
+
if (isCancelled()) throw new CancellationScope().cancel;
|
|
128
|
+
|
|
129
|
+
const nodeId = queue.shift()!;
|
|
130
|
+
if (executed.has(nodeId)) continue;
|
|
131
|
+
|
|
132
|
+
// Check if all predecessors have been executed
|
|
133
|
+
const predecessors = dsl.edges.filter((e) => e.target === nodeId).map((e) => e.source);
|
|
134
|
+
const allPredsDone = predecessors.every((p) => executed.has(p) || dsl.nodes.find((n) => n.id === p)?.type.endsWith('_trigger'));
|
|
135
|
+
if (!allPredsDone) {
|
|
136
|
+
// Re-queue for later
|
|
137
|
+
queue.push(nodeId);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const node = dsl.nodes.find((n) => n.id === nodeId);
|
|
142
|
+
if (!node) continue;
|
|
143
|
+
|
|
144
|
+
executed.add(nodeId);
|
|
145
|
+
nodeStatuses[nodeId] = 'RUNNING';
|
|
146
|
+
|
|
147
|
+
// Report node as RUNNING
|
|
148
|
+
await reportActs.reportNodeStatus({
|
|
149
|
+
instanceId,
|
|
150
|
+
nodeId: node.id,
|
|
151
|
+
nodeType: node.type,
|
|
152
|
+
nodeLabel: node.label,
|
|
153
|
+
status: 'RUNNING',
|
|
154
|
+
input: ctx,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
// Execute the node and get result
|
|
159
|
+
const result = await executeNode(node, dsl, ctx, instanceId, approvalResults, nodeStatuses, isCancelled);
|
|
160
|
+
nodeStatuses[nodeId] = 'COMPLETED';
|
|
161
|
+
|
|
162
|
+
// Report node completion
|
|
163
|
+
await reportActs.reportNodeStatus({
|
|
164
|
+
instanceId,
|
|
165
|
+
nodeId: node.id,
|
|
166
|
+
nodeType: node.type,
|
|
167
|
+
nodeLabel: node.label,
|
|
168
|
+
status: 'COMPLETED',
|
|
169
|
+
output: result?.output,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Merge output into context
|
|
173
|
+
if (result?.output) {
|
|
174
|
+
ctx[nodeId] = result.output;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Determine next nodes based on node type
|
|
178
|
+
const nextNodeIds = getNextNodes(dsl, node, result?.branch);
|
|
179
|
+
for (const nextId of nextNodeIds) {
|
|
180
|
+
if (!executed.has(nextId)) queue.push(nextId);
|
|
181
|
+
}
|
|
182
|
+
} catch (err: any) {
|
|
183
|
+
nodeStatuses[nodeId] = 'FAILED';
|
|
184
|
+
await reportActs.reportNodeStatus({
|
|
185
|
+
instanceId,
|
|
186
|
+
nodeId: node.id,
|
|
187
|
+
nodeType: node.type,
|
|
188
|
+
nodeLabel: node.label,
|
|
189
|
+
status: 'FAILED',
|
|
190
|
+
error: { message: err.message, stack: err.stack },
|
|
191
|
+
});
|
|
192
|
+
throw err; // Propagate to workflow level
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ─── Node Execution Dispatcher ────────────────────────────────────────────────
|
|
198
|
+
|
|
199
|
+
async function executeNode(
|
|
200
|
+
node: DslNode,
|
|
201
|
+
dsl: WorkflowDSL,
|
|
202
|
+
ctx: Record<string, any>,
|
|
203
|
+
instanceId: number,
|
|
204
|
+
approvalResults: Record<string, ApprovalSignalPayload>,
|
|
205
|
+
nodeStatuses: Record<string, NodeStatus>,
|
|
206
|
+
isCancelled: () => boolean,
|
|
207
|
+
): Promise<{ output?: Record<string, any>; branch?: string } | undefined> {
|
|
208
|
+
const config = resolveTemplates(node.config, ctx);
|
|
209
|
+
|
|
210
|
+
switch (node.type) {
|
|
211
|
+
// ─── Triggers (never reach executeNode; handled at graph entry) ──
|
|
212
|
+
case 'cron_trigger':
|
|
213
|
+
case 'webhook_trigger':
|
|
214
|
+
case 'event_trigger':
|
|
215
|
+
case 'manual_trigger':
|
|
216
|
+
return { output: { triggeredAt: new Date().toISOString() } };
|
|
217
|
+
|
|
218
|
+
// ─── Actions ────────────────────────────────────────────────────
|
|
219
|
+
case 'http_request': {
|
|
220
|
+
const result = await acts.httpRequest(config as any);
|
|
221
|
+
return { output: result };
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
case 'db_query': {
|
|
225
|
+
const result = await acts.dbQuery(config as any);
|
|
226
|
+
return { output: result };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
case 'db_execute': {
|
|
230
|
+
const result = await acts.dbExecute(config as any);
|
|
231
|
+
return { output: result };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
case 'send_notification': {
|
|
235
|
+
const result = await acts.sendNotification(config as any);
|
|
236
|
+
return { output: result };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
case 'code': {
|
|
240
|
+
const result = await acts.codeExecute({
|
|
241
|
+
...config,
|
|
242
|
+
data: ctx,
|
|
243
|
+
} as any);
|
|
244
|
+
return { output: result };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ─── Data Processing ────────────────────────────────────────────
|
|
248
|
+
case 'set_variable': {
|
|
249
|
+
const assignments = config.assignments as Array<{ name: string; value: string }>;
|
|
250
|
+
const output: Record<string, any> = {};
|
|
251
|
+
for (const { name, value } of assignments || []) {
|
|
252
|
+
const resolved = resolveExpression(value, ctx);
|
|
253
|
+
ctx[name] = resolved;
|
|
254
|
+
output[name] = resolved;
|
|
255
|
+
}
|
|
256
|
+
return { output };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// ─── Conditions ─────────────────────────────────────────────────
|
|
260
|
+
case 'if_else': {
|
|
261
|
+
const conditions = config.conditions as Array<{ field: string; operator: string; value: string }> || [];
|
|
262
|
+
const combineOp = (config.combineOperation as 'AND' | 'OR') || 'AND';
|
|
263
|
+
const result = evaluateConditions(conditions, ctx, combineOp);
|
|
264
|
+
return { output: { branch: result ? 'true' : 'false' }, branch: result ? 'true' : 'false' };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
case 'switch': {
|
|
268
|
+
const field = config.field as string;
|
|
269
|
+
const cases = config.cases as Array<{ value: string; label: string }> || [];
|
|
270
|
+
const fieldValue = String(getNestedValue(ctx, field) ?? '');
|
|
271
|
+
const matched = cases.find((c) => c.value === fieldValue);
|
|
272
|
+
const branch = matched ? matched.value : (config.defaultCase as string || 'default');
|
|
273
|
+
return { output: { matchedCase: branch }, branch };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ─── Flow Control ───────────────────────────────────────────────
|
|
277
|
+
case 'delay': {
|
|
278
|
+
const delayType = config.delayType as string;
|
|
279
|
+
if (delayType === 'fixedDuration') {
|
|
280
|
+
const duration = (config.duration as number) || 1;
|
|
281
|
+
await sleep(duration * 1000);
|
|
282
|
+
} else if (delayType === 'untilTime') {
|
|
283
|
+
const targetTime = new Date(config.untilTime as string).getTime();
|
|
284
|
+
const now = Date.now();
|
|
285
|
+
if (targetTime > now) {
|
|
286
|
+
await sleep(targetTime - now);
|
|
287
|
+
}
|
|
288
|
+
} else if (delayType === 'untilSignal') {
|
|
289
|
+
// Wait for a specific signal (reuse approval mechanism)
|
|
290
|
+
await condition(() => approvalResults[node.id] !== undefined, '24h');
|
|
291
|
+
}
|
|
292
|
+
return { output: { resumedAt: new Date().toISOString(), resumeReason: delayType } };
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
case 'parallel': {
|
|
296
|
+
// Execute all outgoing branches in parallel
|
|
297
|
+
const branches = getSuccessorsFromNodes(dsl, [node.id]);
|
|
298
|
+
const branchPromises = branches.map(async (branchNodeId) => {
|
|
299
|
+
await executeGraph(
|
|
300
|
+
dsl,
|
|
301
|
+
[branchNodeId],
|
|
302
|
+
ctx,
|
|
303
|
+
nodeStatuses,
|
|
304
|
+
instanceId,
|
|
305
|
+
approvalResults,
|
|
306
|
+
isCancelled,
|
|
307
|
+
);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
const waitMode = config.waitMode as string || 'all';
|
|
311
|
+
if (waitMode === 'all') {
|
|
312
|
+
await Promise.all(branchPromises);
|
|
313
|
+
} else if (waitMode === 'any') {
|
|
314
|
+
await Promise.race(branchPromises);
|
|
315
|
+
}
|
|
316
|
+
return { output: { completedBranches: branches.length } };
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
case 'for_each': {
|
|
320
|
+
const iteratorField = config.iteratorField as string;
|
|
321
|
+
const items = getNestedValue(ctx, iteratorField) as any[];
|
|
322
|
+
if (!Array.isArray(items)) {
|
|
323
|
+
return { output: { results: [], error: 'iteratorField is not an array' } };
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const concurrency = (config.concurrency as number) || 1;
|
|
327
|
+
const errorPolicy = (config.errorPolicy as string) || 'stop';
|
|
328
|
+
const results: any[] = [];
|
|
329
|
+
const errors: any[] = [];
|
|
330
|
+
|
|
331
|
+
// Process items with concurrency control
|
|
332
|
+
for (let i = 0; i < items.length; i += concurrency) {
|
|
333
|
+
const batch = items.slice(i, i + concurrency);
|
|
334
|
+
const batchPromises = batch.map(async (item, batchIdx) => {
|
|
335
|
+
const idx = i + batchIdx;
|
|
336
|
+
// Set iteration context
|
|
337
|
+
ctx['$currentItem'] = item;
|
|
338
|
+
ctx['$index'] = idx;
|
|
339
|
+
try {
|
|
340
|
+
// Execute successor nodes for each item
|
|
341
|
+
const successors = getSuccessorsFromNodes(dsl, [node.id]);
|
|
342
|
+
if (successors.length > 0) {
|
|
343
|
+
await executeGraph(dsl, successors, { ...ctx }, nodeStatuses, instanceId, approvalResults, isCancelled);
|
|
344
|
+
}
|
|
345
|
+
results.push({ index: idx, success: true });
|
|
346
|
+
} catch (err: any) {
|
|
347
|
+
if (errorPolicy === 'stop') throw err;
|
|
348
|
+
errors.push({ index: idx, error: err.message });
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
await Promise.all(batchPromises);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return { output: { results, errors, totalProcessed: items.length } };
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
case 'error_handler': {
|
|
358
|
+
// Error handler is special — it wraps the execution of upstream nodes
|
|
359
|
+
// In practice, the error handling is done at the graph execution level
|
|
360
|
+
return { output: { handled: true } };
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// ─── Approval ───────────────────────────────────────────────────
|
|
364
|
+
case 'approval': {
|
|
365
|
+
const timeoutSec = (config.timeout as number) || 86400; // Default 24h
|
|
366
|
+
const timeoutAction = (config.timeoutAction as string) || 'auto_reject';
|
|
367
|
+
|
|
368
|
+
// Wait for approval signal
|
|
369
|
+
const gotApproval = await condition(
|
|
370
|
+
() => approvalResults[node.id] !== undefined,
|
|
371
|
+
`${timeoutSec}s`,
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
if (!gotApproval) {
|
|
375
|
+
// Timeout
|
|
376
|
+
if (timeoutAction === 'auto_approve') {
|
|
377
|
+
return { output: { approved: true, approvedBy: 'system', comment: 'Auto-approved (timeout)' } };
|
|
378
|
+
} else {
|
|
379
|
+
return { output: { approved: false, approvedBy: 'system', comment: 'Auto-rejected (timeout)' } };
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const approval = approvalResults[node.id];
|
|
384
|
+
return {
|
|
385
|
+
output: { approved: approval.approved, approvedBy: approval.approvedBy, comment: approval.comment },
|
|
386
|
+
branch: approval.approved ? 'true' : 'false',
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// ─── Sub Workflow ────────────────────────────────────────────────
|
|
391
|
+
case 'sub_workflow': {
|
|
392
|
+
const childWorkflowId = config.workflowId as string;
|
|
393
|
+
const inputMapping = config.inputMapping as Record<string, string> || {};
|
|
394
|
+
const childContext: Record<string, any> = {};
|
|
395
|
+
|
|
396
|
+
for (const [key, path] of Object.entries(inputMapping)) {
|
|
397
|
+
childContext[key] = getNestedValue(ctx, path);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// TODO: Load child workflow DSL from DB via activity, then execute as child workflow
|
|
401
|
+
// For now, placeholder
|
|
402
|
+
return { output: { status: 'not_implemented', childWorkflowId } };
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
default:
|
|
406
|
+
return assertNever(node.type);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// ─── Helper Functions ─────────────────────────────────────────────────────────
|
|
411
|
+
// Pure functions are defined in ../dsl/helpers.ts and imported above.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2021",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2021"],
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"declaration": true,
|
|
14
|
+
"declarationMap": true,
|
|
15
|
+
"sourceMap": true
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*"],
|
|
18
|
+
"exclude": ["node_modules", "dist"]
|
|
19
|
+
}
|