@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.
Files changed (173) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +2 -0
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/job.prisma +62 -0
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/system.prisma +0 -21
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +171 -0
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/AgendaJob.ts +60 -0
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Event.ts +1 -1
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowEventOutbox.ts +62 -0
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeInstance.ts +62 -0
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/WorkflowNodeType.ts +62 -0
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.env +5 -0
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +5 -4
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma.config.ts +14 -7
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +4 -0
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +49 -3
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +746 -0
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflows.ts +786 -0
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.controller.ts +6 -0
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agenda/agenda.service.ts +79 -0
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.spec.ts +20 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.ts +145 -0
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.module.ts +10 -0
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/{canvas/canvas.service.spec.ts → agendaJob/agendaJob.service.spec.ts} +71 -65
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.service.ts +83 -0
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +2 -1
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.module.ts +9 -0
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +100 -0
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-execution.dto.ts +19 -0
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.dto.ts +43 -0
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-export.service.ts +317 -0
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.controller.ts +16 -0
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow-node-type.service.ts +13 -0
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +220 -0
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.dto.ts +82 -0
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.module.ts +16 -0
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +505 -0
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +22 -0
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.ts +147 -0
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.module.ts +10 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +356 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.ts +110 -0
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.spec.ts +22 -0
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.ts +216 -0
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.module.ts +10 -0
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +356 -0
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.ts +168 -0
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.spec.ts +22 -0
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.ts +199 -0
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.module.ts +10 -0
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.spec.ts +348 -0
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.ts +106 -0
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/server/yarn.lock +579 -1082
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +278 -0
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/config/development-sql.yaml +5 -0
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/docker-compose.yml +25 -0
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/package.json +13 -0
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/sql/create-event-trigger.sql +87 -0
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.env +7 -0
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/SANDBOX.md +122 -0
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package-lock.json +4285 -0
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/package.json +28 -0
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/code-execute.test.ts +44 -0
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/activities/http-request.test.ts +87 -0
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/helpers.test.ts +225 -0
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/__tests__/node-type-consistency.test.ts +101 -0
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/code-execute.ts +51 -0
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-execute.ts +85 -0
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/db-query.ts +35 -0
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/http-request.ts +54 -0
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts +6 -0
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/reporting.ts +62 -0
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/send-notification.ts +47 -0
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/config.ts +13 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/condition.ts +101 -0
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/context.ts +58 -0
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/graph.ts +184 -0
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/helpers.ts +133 -0
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/node-types.ts +57 -0
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/dsl/types.ts +77 -0
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/index.ts +36 -0
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/outbox-poller.ts +226 -0
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/workflows/dsl-workflow.ts +411 -0
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/tsconfig.json +19 -0
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/vitest.config.ts +8 -0
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/yarn.lock +1905 -0
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package-lock.json +17555 -0
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +5 -2
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +1 -0
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/sider.tsx +5 -1
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/title.tsx +1 -1
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +63 -0
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +91 -2
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +48 -2
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/show.tsx +43 -2
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +14 -9
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +14 -9
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/index.tsx +309 -56
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agenda/show.tsx +1 -3
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/create.tsx +108 -0
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/edit.tsx +124 -0
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/index.tsx +4 -0
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/list.tsx +245 -0
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/agendaJob/show.tsx +70 -0
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +0 -1
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +160 -2
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +120 -148
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CodeFloatWindow.tsx +74 -181
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/LivePreview.tsx +15 -13
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasConfigRegistry.tsx +2 -2
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasContextMenuRegistry.tsx +338 -3
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasDefaults.ts +18 -17
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/BarChartDataSourceModal.tsx +10 -4
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/LineChartDataSourceModal.tsx +10 -4
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/{ChartViewerConfigModal.tsx → MultiChartConfigModal.tsx} +30 -18
  115. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/MultiChartDataSourceModal.tsx +427 -0
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/NumCardDataSourceModal.tsx +10 -4
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/PromptModal.tsx +6 -14
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/RadarChartDataSourceModal.tsx +10 -4
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/TableDataSourceModal.tsx +10 -4
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/canvasModalProps.ts +24 -0
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/demos.ts +45 -63
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/CustomNode.tsx +99 -0
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ExportModal.tsx +87 -0
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/FlowRenderer.tsx +322 -0
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/ImportModal.tsx +175 -0
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodeEditModal.tsx +60 -0
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/NodePropertyPanel.tsx +1150 -0
  128. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/RunWorkflowModal.tsx +101 -0
  129. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/StatusCards.tsx +198 -0
  130. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/VersionPanel.tsx +81 -0
  131. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +566 -0
  132. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/hooks/useWorkflowAgent.ts +224 -0
  133. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/index.tsx +524 -0
  134. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +343 -0
  135. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instances.tsx +243 -0
  136. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/CreateNodeInstanceModal.tsx +363 -0
  137. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/DynamicConfigForm.tsx +154 -0
  138. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/components/NodeInstanceForm.tsx +176 -0
  139. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/create.tsx +77 -0
  140. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/edit.tsx +112 -0
  141. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/index.tsx +305 -0
  142. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/node-instances/show.tsx +282 -0
  143. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +469 -0
  144. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +92 -0
  145. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/create.tsx +111 -0
  146. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/edit.tsx +127 -0
  147. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/index.tsx +4 -0
  148. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/list.tsx +254 -0
  149. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflowEventOutbox/show.tsx +74 -0
  150. package/dist/lib/application/files/gadmin2-game-angle-demo/web/yarn.lock +1501 -1199
  151. package/package.json +1 -1
  152. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/app.controller.spec.ts +0 -22
  153. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/BarChart/index.tsx +0 -896
  154. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartSwitcher/index.tsx +0 -219
  155. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartViewer/index.tsx +0 -159
  156. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Filter/index.tsx +0 -192
  157. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/LineChart/index.tsx +0 -1034
  158. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/NumCard.module.css +0 -8
  159. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/index.tsx +0 -509
  160. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumLineCard/index.tsx +0 -66
  161. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/PieChart/index.tsx +0 -552
  162. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/RadarChart/index.tsx +0 -263
  163. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Section/index.tsx +0 -35
  164. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Table/index.tsx +0 -207
  165. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/TreemapChart/index.tsx +0 -382
  166. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/WorldMap/index.tsx +0 -135
  167. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/chart-constants.ts +0 -53
  168. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/InfoIcon.tsx +0 -8
  169. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/index.ts +0 -1
  170. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/config.ts +0 -31
  171. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/nameMap.json +0 -9
  172. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/world.geo.json +0 -39349
  173. 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
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ root: './src',
6
+ include: ['**/__tests__/**/*.test.ts'],
7
+ },
8
+ });