@elaraai/e3-core 0.0.2-beta.3 → 0.0.2-beta.31

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 (184) hide show
  1. package/README.md +25 -22
  2. package/dist/src/dataflow/api-compat.d.ts +90 -0
  3. package/dist/src/dataflow/api-compat.d.ts.map +1 -0
  4. package/dist/src/dataflow/api-compat.js +134 -0
  5. package/dist/src/dataflow/api-compat.js.map +1 -0
  6. package/dist/src/dataflow/index.d.ts +18 -0
  7. package/dist/src/dataflow/index.d.ts.map +1 -0
  8. package/dist/src/dataflow/index.js +23 -0
  9. package/dist/src/dataflow/index.js.map +1 -0
  10. package/dist/src/dataflow/orchestrator/LocalOrchestrator.d.ts +53 -0
  11. package/dist/src/dataflow/orchestrator/LocalOrchestrator.d.ts.map +1 -0
  12. package/dist/src/dataflow/orchestrator/LocalOrchestrator.js +416 -0
  13. package/dist/src/dataflow/orchestrator/LocalOrchestrator.js.map +1 -0
  14. package/dist/src/dataflow/orchestrator/index.d.ts +12 -0
  15. package/dist/src/dataflow/orchestrator/index.d.ts.map +1 -0
  16. package/dist/src/dataflow/orchestrator/index.js +12 -0
  17. package/dist/src/dataflow/orchestrator/index.js.map +1 -0
  18. package/dist/src/dataflow/orchestrator/interfaces.d.ts +157 -0
  19. package/dist/src/dataflow/orchestrator/interfaces.d.ts.map +1 -0
  20. package/dist/src/dataflow/orchestrator/interfaces.js +51 -0
  21. package/dist/src/dataflow/orchestrator/interfaces.js.map +1 -0
  22. package/dist/src/dataflow/state-store/FileStateStore.d.ts +67 -0
  23. package/dist/src/dataflow/state-store/FileStateStore.d.ts.map +1 -0
  24. package/dist/src/dataflow/state-store/FileStateStore.js +286 -0
  25. package/dist/src/dataflow/state-store/FileStateStore.js.map +1 -0
  26. package/dist/src/dataflow/state-store/InMemoryStateStore.d.ts +42 -0
  27. package/dist/src/dataflow/state-store/InMemoryStateStore.d.ts.map +1 -0
  28. package/dist/src/dataflow/state-store/InMemoryStateStore.js +214 -0
  29. package/dist/src/dataflow/state-store/InMemoryStateStore.js.map +1 -0
  30. package/dist/src/dataflow/state-store/index.d.ts +13 -0
  31. package/dist/src/dataflow/state-store/index.d.ts.map +1 -0
  32. package/dist/src/dataflow/state-store/index.js +13 -0
  33. package/dist/src/dataflow/state-store/index.js.map +1 -0
  34. package/dist/src/dataflow/state-store/interfaces.d.ts +159 -0
  35. package/dist/src/dataflow/state-store/interfaces.d.ts.map +1 -0
  36. package/dist/src/dataflow/state-store/interfaces.js +6 -0
  37. package/dist/src/dataflow/state-store/interfaces.js.map +1 -0
  38. package/dist/src/dataflow/steps.d.ts +176 -0
  39. package/dist/src/dataflow/steps.d.ts.map +1 -0
  40. package/dist/src/dataflow/steps.js +528 -0
  41. package/dist/src/dataflow/steps.js.map +1 -0
  42. package/dist/src/dataflow/types.d.ts +116 -0
  43. package/dist/src/dataflow/types.d.ts.map +1 -0
  44. package/dist/src/dataflow/types.js +7 -0
  45. package/dist/src/dataflow/types.js.map +1 -0
  46. package/dist/src/dataflow.d.ts +142 -9
  47. package/dist/src/dataflow.d.ts.map +1 -1
  48. package/dist/src/dataflow.js +427 -64
  49. package/dist/src/dataflow.js.map +1 -1
  50. package/dist/src/errors.d.ts +39 -9
  51. package/dist/src/errors.d.ts.map +1 -1
  52. package/dist/src/errors.js +51 -8
  53. package/dist/src/errors.js.map +1 -1
  54. package/dist/src/execution/LocalTaskRunner.d.ts +73 -0
  55. package/dist/src/execution/LocalTaskRunner.d.ts.map +1 -0
  56. package/dist/src/execution/LocalTaskRunner.js +399 -0
  57. package/dist/src/execution/LocalTaskRunner.js.map +1 -0
  58. package/dist/src/execution/MockTaskRunner.d.ts +49 -0
  59. package/dist/src/execution/MockTaskRunner.d.ts.map +1 -0
  60. package/dist/src/execution/MockTaskRunner.js +55 -0
  61. package/dist/src/execution/MockTaskRunner.js.map +1 -0
  62. package/dist/src/execution/index.d.ts +16 -0
  63. package/dist/src/execution/index.d.ts.map +1 -0
  64. package/dist/src/execution/index.js +8 -0
  65. package/dist/src/execution/index.js.map +1 -0
  66. package/dist/src/execution/interfaces.d.ts +246 -0
  67. package/dist/src/execution/interfaces.d.ts.map +1 -0
  68. package/dist/src/execution/interfaces.js +6 -0
  69. package/dist/src/execution/interfaces.js.map +1 -0
  70. package/dist/src/execution/processHelpers.d.ts +20 -0
  71. package/dist/src/execution/processHelpers.d.ts.map +1 -0
  72. package/dist/src/execution/processHelpers.js +62 -0
  73. package/dist/src/execution/processHelpers.js.map +1 -0
  74. package/dist/src/executions.d.ts +71 -104
  75. package/dist/src/executions.d.ts.map +1 -1
  76. package/dist/src/executions.js +110 -476
  77. package/dist/src/executions.js.map +1 -1
  78. package/dist/src/index.d.ts +17 -9
  79. package/dist/src/index.d.ts.map +1 -1
  80. package/dist/src/index.js +44 -18
  81. package/dist/src/index.js.map +1 -1
  82. package/dist/src/objects.d.ts +6 -53
  83. package/dist/src/objects.d.ts.map +1 -1
  84. package/dist/src/objects.js +11 -232
  85. package/dist/src/objects.js.map +1 -1
  86. package/dist/src/packages.d.ts +22 -14
  87. package/dist/src/packages.d.ts.map +1 -1
  88. package/dist/src/packages.js +116 -83
  89. package/dist/src/packages.js.map +1 -1
  90. package/dist/src/storage/in-memory/InMemoryRepoStore.d.ts +35 -0
  91. package/dist/src/storage/in-memory/InMemoryRepoStore.d.ts.map +1 -0
  92. package/dist/src/storage/in-memory/InMemoryRepoStore.js +107 -0
  93. package/dist/src/storage/in-memory/InMemoryRepoStore.js.map +1 -0
  94. package/dist/src/storage/in-memory/InMemoryStorage.d.ts +114 -0
  95. package/dist/src/storage/in-memory/InMemoryStorage.d.ts.map +1 -0
  96. package/dist/src/storage/in-memory/InMemoryStorage.js +349 -0
  97. package/dist/src/storage/in-memory/InMemoryStorage.js.map +1 -0
  98. package/dist/src/storage/in-memory/index.d.ts +12 -0
  99. package/dist/src/storage/in-memory/index.d.ts.map +1 -0
  100. package/dist/src/storage/in-memory/index.js +12 -0
  101. package/dist/src/storage/in-memory/index.js.map +1 -0
  102. package/dist/src/storage/index.d.ts +18 -0
  103. package/dist/src/storage/index.d.ts.map +1 -0
  104. package/dist/src/storage/index.js +10 -0
  105. package/dist/src/storage/index.js.map +1 -0
  106. package/dist/src/storage/interfaces.d.ts +520 -0
  107. package/dist/src/storage/interfaces.d.ts.map +1 -0
  108. package/dist/src/storage/interfaces.js +6 -0
  109. package/dist/src/storage/interfaces.js.map +1 -0
  110. package/dist/src/storage/local/LocalBackend.d.ts +54 -0
  111. package/dist/src/storage/local/LocalBackend.d.ts.map +1 -0
  112. package/dist/src/storage/local/LocalBackend.js +141 -0
  113. package/dist/src/storage/local/LocalBackend.js.map +1 -0
  114. package/dist/src/storage/local/LocalLockService.d.ts +105 -0
  115. package/dist/src/storage/local/LocalLockService.d.ts.map +1 -0
  116. package/dist/src/storage/local/LocalLockService.js +342 -0
  117. package/dist/src/storage/local/LocalLockService.js.map +1 -0
  118. package/dist/src/storage/local/LocalLogStore.d.ts +23 -0
  119. package/dist/src/storage/local/LocalLogStore.d.ts.map +1 -0
  120. package/dist/src/storage/local/LocalLogStore.js +66 -0
  121. package/dist/src/storage/local/LocalLogStore.js.map +1 -0
  122. package/dist/src/storage/local/LocalObjectStore.d.ts +52 -0
  123. package/dist/src/storage/local/LocalObjectStore.d.ts.map +1 -0
  124. package/dist/src/storage/local/LocalObjectStore.js +287 -0
  125. package/dist/src/storage/local/LocalObjectStore.js.map +1 -0
  126. package/dist/src/storage/local/LocalRefStore.d.ts +50 -0
  127. package/dist/src/storage/local/LocalRefStore.d.ts.map +1 -0
  128. package/dist/src/storage/local/LocalRefStore.js +337 -0
  129. package/dist/src/storage/local/LocalRefStore.js.map +1 -0
  130. package/dist/src/storage/local/LocalRepoStore.d.ts +53 -0
  131. package/dist/src/storage/local/LocalRepoStore.d.ts.map +1 -0
  132. package/dist/src/storage/local/LocalRepoStore.js +353 -0
  133. package/dist/src/storage/local/LocalRepoStore.js.map +1 -0
  134. package/dist/src/storage/local/gc.d.ts +92 -0
  135. package/dist/src/storage/local/gc.d.ts.map +1 -0
  136. package/dist/src/storage/local/gc.js +322 -0
  137. package/dist/src/storage/local/gc.js.map +1 -0
  138. package/dist/src/storage/local/index.d.ts +17 -0
  139. package/dist/src/storage/local/index.d.ts.map +1 -0
  140. package/dist/src/storage/local/index.js +17 -0
  141. package/dist/src/storage/local/index.js.map +1 -0
  142. package/dist/src/storage/local/localHelpers.d.ts +25 -0
  143. package/dist/src/storage/local/localHelpers.d.ts.map +1 -0
  144. package/dist/src/storage/local/localHelpers.js +69 -0
  145. package/dist/src/storage/local/localHelpers.js.map +1 -0
  146. package/dist/src/{repository.d.ts → storage/local/repository.d.ts} +8 -4
  147. package/dist/src/storage/local/repository.d.ts.map +1 -0
  148. package/dist/src/{repository.js → storage/local/repository.js} +31 -29
  149. package/dist/src/storage/local/repository.js.map +1 -0
  150. package/dist/src/tasks.d.ts +16 -10
  151. package/dist/src/tasks.d.ts.map +1 -1
  152. package/dist/src/tasks.js +35 -41
  153. package/dist/src/tasks.js.map +1 -1
  154. package/dist/src/test-helpers.d.ts +4 -4
  155. package/dist/src/test-helpers.d.ts.map +1 -1
  156. package/dist/src/test-helpers.js +7 -21
  157. package/dist/src/test-helpers.js.map +1 -1
  158. package/dist/src/trees.d.ts +89 -27
  159. package/dist/src/trees.d.ts.map +1 -1
  160. package/dist/src/trees.js +218 -100
  161. package/dist/src/trees.js.map +1 -1
  162. package/dist/src/uuid.d.ts +26 -0
  163. package/dist/src/uuid.d.ts.map +1 -0
  164. package/dist/src/uuid.js +80 -0
  165. package/dist/src/uuid.js.map +1 -0
  166. package/dist/src/workspaceStatus.d.ts +6 -4
  167. package/dist/src/workspaceStatus.d.ts.map +1 -1
  168. package/dist/src/workspaceStatus.js +43 -49
  169. package/dist/src/workspaceStatus.js.map +1 -1
  170. package/dist/src/workspaces.d.ts +35 -26
  171. package/dist/src/workspaces.d.ts.map +1 -1
  172. package/dist/src/workspaces.js +169 -118
  173. package/dist/src/workspaces.js.map +1 -1
  174. package/package.json +4 -4
  175. package/dist/src/gc.d.ts +0 -54
  176. package/dist/src/gc.d.ts.map +0 -1
  177. package/dist/src/gc.js +0 -233
  178. package/dist/src/gc.js.map +0 -1
  179. package/dist/src/repository.d.ts.map +0 -1
  180. package/dist/src/repository.js.map +0 -1
  181. package/dist/src/workspaceLock.d.ts +0 -67
  182. package/dist/src/workspaceLock.d.ts.map +0 -1
  183. package/dist/src/workspaceLock.js +0 -217
  184. package/dist/src/workspaceLock.js.map +0 -1
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ /**
6
+ * Convert execution state to status summary.
7
+ */
8
+ export function stateToStatus(state) {
9
+ const completed = [];
10
+ const running = [];
11
+ const pending = [];
12
+ const failed = [];
13
+ const skipped = [];
14
+ for (const [name, taskState] of state.tasks) {
15
+ switch (taskState.status) {
16
+ case 'completed':
17
+ completed.push(name);
18
+ break;
19
+ case 'in_progress':
20
+ running.push(name);
21
+ break;
22
+ case 'pending':
23
+ case 'ready':
24
+ pending.push(name);
25
+ break;
26
+ case 'failed':
27
+ failed.push(name);
28
+ break;
29
+ case 'skipped':
30
+ skipped.push(name);
31
+ break;
32
+ }
33
+ }
34
+ // Get error value (handle Option type)
35
+ const errorValue = state.error.type === 'some' ? state.error.value : undefined;
36
+ // Get completedAt value (handle Option type)
37
+ const completedAtValue = state.completedAt.type === 'some' ? state.completedAt.value : undefined;
38
+ return {
39
+ id: state.id,
40
+ state: state.status,
41
+ completed,
42
+ running,
43
+ pending,
44
+ failed,
45
+ skipped,
46
+ error: errorValue,
47
+ startedAt: state.startedAt,
48
+ completedAt: completedAtValue,
49
+ };
50
+ }
51
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../../src/dataflow/orchestrator/interfaces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAsKH;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAA6B;IACzD,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC5C,QAAQ,SAAS,CAAC,MAAM,EAAE,CAAC;YACzB,KAAK,WAAW;gBACd,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrB,MAAM;YACR,KAAK,aAAa;gBAChB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnB,MAAM;YACR,KAAK,SAAS,CAAC;YACf,KAAK,OAAO;gBACV,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnB,MAAM;YACR,KAAK,QAAQ;gBACX,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClB,MAAM;YACR,KAAK,SAAS;gBACZ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACnB,MAAM;QACV,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE/E,6CAA6C;IAC7C,MAAM,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjG,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,KAAK,EAAE,KAAK,CAAC,MAA0D;QACvE,SAAS;QACT,OAAO;QACP,OAAO;QACP,MAAM;QACN,OAAO;QACP,KAAK,EAAE,UAAU;QACjB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,WAAW,EAAE,gBAAgB;KAC9B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { ExecutionStateStore, TaskStatusDetails, ExecutionStatusDetails } from './interfaces.js';
6
+ import { type DataflowExecutionState, type ExecutionEvent, type TaskStatus } from '../types.js';
7
+ /**
8
+ * File-based state store for local filesystem persistence.
9
+ *
10
+ * @remarks
11
+ * - Uses atomic writes (write to temp, then rename) for durability
12
+ * - State is stored in beast2 binary format for type safety
13
+ * - Events are stored inline in the execution state
14
+ * - Thread-safe for concurrent access within a single process (via file locking)
15
+ * - Suitable for local CLI and API server usage
16
+ */
17
+ export declare class FileStateStore implements ExecutionStateStore {
18
+ private readonly workspacesDir;
19
+ /**
20
+ * Create a new FileStateStore.
21
+ *
22
+ * @param workspacesDir - Path to the workspaces directory (e.g., repo/workspaces)
23
+ */
24
+ constructor(workspacesDir: string);
25
+ /**
26
+ * Get the path to a workspace's directory.
27
+ */
28
+ private workspacePath;
29
+ /**
30
+ * Get the path to a workspace's execution state file.
31
+ */
32
+ private statePath;
33
+ /**
34
+ * Get the path to a workspace's execution counter file.
35
+ */
36
+ private counterPath;
37
+ create(state: DataflowExecutionState): Promise<void>;
38
+ read(repo: string, workspace: string, id: string): Promise<DataflowExecutionState | null>;
39
+ readLatest(_repo: string, workspace: string): Promise<DataflowExecutionState | null>;
40
+ update(state: DataflowExecutionState): Promise<void>;
41
+ updateTaskStatus(repo: string, workspace: string, executionId: string, task: string, status: TaskStatus, details?: TaskStatusDetails): Promise<void>;
42
+ updateStatus(repo: string, workspace: string, executionId: string, status: 'running' | 'completed' | 'failed' | 'cancelled', details?: ExecutionStatusDetails): Promise<void>;
43
+ recordEvent(repo: string, workspace: string, executionId: string, event: ExecutionEvent): Promise<void>;
44
+ getEventsSince(repo: string, workspace: string, executionId: string, sinceSeq: number): Promise<ExecutionEvent[]>;
45
+ nextExecutionId(_repo: string, workspace: string): Promise<string>;
46
+ delete(_repo: string, workspace: string, executionId: string): Promise<void>;
47
+ /**
48
+ * Check if an incomplete execution exists for a workspace.
49
+ *
50
+ * An execution is incomplete if its status is 'running'.
51
+ * This is used to detect crash recovery scenarios.
52
+ *
53
+ * @param repo - Repository identifier
54
+ * @param workspace - Workspace name
55
+ * @returns The incomplete execution if one exists, null otherwise
56
+ */
57
+ getIncompleteExecution(repo: string, workspace: string): Promise<DataflowExecutionState | null>;
58
+ /**
59
+ * Write a binary file atomically using temp file + rename.
60
+ */
61
+ private atomicWrite;
62
+ /**
63
+ * Write a text file atomically using temp file + rename.
64
+ */
65
+ private atomicWriteText;
66
+ }
67
+ //# sourceMappingURL=FileStateStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileStateStore.d.ts","sourceRoot":"","sources":["../../../../src/dataflow/state-store/FileStateStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EAEnB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AASrB;;;;;;;;;GASG;AACH,qBAAa,cAAe,YAAW,mBAAmB;IAM5C,OAAO,CAAC,QAAQ,CAAC,aAAa;IAL1C;;;;OAIG;gBAC0B,aAAa,EAAE,MAAM;IAElD;;OAEG;IACH,OAAO,CAAC,aAAa;IAIrB;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,WAAW;IAIb,MAAM,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcpD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IA0BzF,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAcpF,MAAM,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMpD,gBAAgB,CACpB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC;IAqCV,YAAY,CAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,EACxD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,IAAI,CAAC;IAyBV,WAAW,CACf,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,IAAI,CAAC;IAYV,cAAc,CAClB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,EAAE,CAAC;IAetB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBlE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBlF;;;;;;;;;OASG;IACG,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAQrG;;OAEG;YACW,WAAW;IAmBzB;;OAEG;YACW,eAAe;CAkB9B"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ /**
6
+ * File-based implementation of ExecutionStateStore.
7
+ *
8
+ * Persists execution state to the workspace directory structure:
9
+ * - workspaces/{ws}/execution.beast2 - Current/last execution state (binary format)
10
+ * - workspaces/{ws}/execution-counter - Auto-increment counter
11
+ *
12
+ * Events are stored inline in the execution state (not as a separate file).
13
+ * This enables crash recovery and external monitoring of execution progress.
14
+ */
15
+ import { promises as fs } from 'node:fs';
16
+ import { join, dirname } from 'node:path';
17
+ import { encodeBeast2For, decodeBeast2For, some } from '@elaraai/east';
18
+ import { DataflowExecutionStateType, } from '../types.js';
19
+ // Create encoder/decoder for beast2 serialization
20
+ const encode = encodeBeast2For(DataflowExecutionStateType);
21
+ const decode = decodeBeast2For(DataflowExecutionStateType);
22
+ /**
23
+ * File-based state store for local filesystem persistence.
24
+ *
25
+ * @remarks
26
+ * - Uses atomic writes (write to temp, then rename) for durability
27
+ * - State is stored in beast2 binary format for type safety
28
+ * - Events are stored inline in the execution state
29
+ * - Thread-safe for concurrent access within a single process (via file locking)
30
+ * - Suitable for local CLI and API server usage
31
+ */
32
+ export class FileStateStore {
33
+ workspacesDir;
34
+ /**
35
+ * Create a new FileStateStore.
36
+ *
37
+ * @param workspacesDir - Path to the workspaces directory (e.g., repo/workspaces)
38
+ */
39
+ constructor(workspacesDir) {
40
+ this.workspacesDir = workspacesDir;
41
+ }
42
+ /**
43
+ * Get the path to a workspace's directory.
44
+ */
45
+ workspacePath(workspace) {
46
+ return join(this.workspacesDir, workspace);
47
+ }
48
+ /**
49
+ * Get the path to a workspace's execution state file.
50
+ */
51
+ statePath(workspace) {
52
+ return join(this.workspacePath(workspace), 'execution.beast2');
53
+ }
54
+ /**
55
+ * Get the path to a workspace's execution counter file.
56
+ */
57
+ counterPath(workspace) {
58
+ return join(this.workspacePath(workspace), 'execution-counter');
59
+ }
60
+ async create(state) {
61
+ const path = this.statePath(state.workspace);
62
+ // Check if execution already exists
63
+ const existing = await this.read(state.repo, state.workspace, state.id);
64
+ if (existing) {
65
+ throw new Error(`Execution ${state.id} already exists in workspace '${state.workspace}'`);
66
+ }
67
+ // Write state atomically using beast2 encoding
68
+ const data = encode(state);
69
+ await this.atomicWrite(path, data);
70
+ }
71
+ async read(repo, workspace, id) {
72
+ const path = this.statePath(workspace);
73
+ try {
74
+ const data = await fs.readFile(path);
75
+ const state = decode(data);
76
+ // Check if this is the requested execution
77
+ if (state.id !== id) {
78
+ return null;
79
+ }
80
+ // Verify repo matches (if stored)
81
+ if (state.repo && state.repo !== repo) {
82
+ return null;
83
+ }
84
+ return state;
85
+ }
86
+ catch (err) {
87
+ if (err.code === 'ENOENT') {
88
+ return null;
89
+ }
90
+ throw err;
91
+ }
92
+ }
93
+ async readLatest(_repo, workspace) {
94
+ const path = this.statePath(workspace);
95
+ try {
96
+ const data = await fs.readFile(path);
97
+ return decode(data);
98
+ }
99
+ catch (err) {
100
+ if (err.code === 'ENOENT') {
101
+ return null;
102
+ }
103
+ throw err;
104
+ }
105
+ }
106
+ async update(state) {
107
+ const path = this.statePath(state.workspace);
108
+ const data = encode(state);
109
+ await this.atomicWrite(path, data);
110
+ }
111
+ async updateTaskStatus(repo, workspace, executionId, task, status, details) {
112
+ const state = await this.read(repo, workspace, executionId);
113
+ if (!state) {
114
+ throw new Error(`Execution ${executionId} not found in workspace '${workspace}'`);
115
+ }
116
+ const taskState = state.tasks.get(task);
117
+ if (!taskState) {
118
+ throw new Error(`Task '${task}' not found in execution ${executionId}`);
119
+ }
120
+ const mutableState = state;
121
+ taskState.status = status;
122
+ if (details) {
123
+ if (details.cached !== undefined)
124
+ taskState.cached = some(details.cached);
125
+ if (details.outputHash !== undefined)
126
+ taskState.outputHash = some(details.outputHash);
127
+ if (details.error !== undefined)
128
+ taskState.error = some(details.error);
129
+ if (details.exitCode !== undefined)
130
+ taskState.exitCode = some(BigInt(details.exitCode));
131
+ if (details.duration !== undefined)
132
+ taskState.duration = some(BigInt(details.duration));
133
+ }
134
+ taskState.completedAt = some(new Date());
135
+ // Update counters based on status
136
+ if (status === 'completed' && details?.cached) {
137
+ mutableState.cached = state.cached + 1n;
138
+ }
139
+ else if (status === 'completed') {
140
+ mutableState.executed = state.executed + 1n;
141
+ }
142
+ else if (status === 'failed') {
143
+ mutableState.failed = state.failed + 1n;
144
+ }
145
+ else if (status === 'skipped') {
146
+ mutableState.skipped = state.skipped + 1n;
147
+ }
148
+ await this.update(state);
149
+ }
150
+ async updateStatus(repo, workspace, executionId, status, details) {
151
+ const state = await this.read(repo, workspace, executionId);
152
+ if (!state) {
153
+ throw new Error(`Execution ${executionId} not found in workspace '${workspace}'`);
154
+ }
155
+ const mutableState = state;
156
+ mutableState.status = status;
157
+ if (status !== 'running') {
158
+ mutableState.completedAt = some(new Date());
159
+ }
160
+ if (details?.error) {
161
+ mutableState.error = some(details.error);
162
+ }
163
+ if (details?.summary) {
164
+ mutableState.executed = BigInt(details.summary.executed);
165
+ mutableState.cached = BigInt(details.summary.cached);
166
+ mutableState.failed = BigInt(details.summary.failed);
167
+ mutableState.skipped = BigInt(details.summary.skipped);
168
+ }
169
+ await this.update(state);
170
+ }
171
+ async recordEvent(repo, workspace, executionId, event) {
172
+ const state = await this.read(repo, workspace, executionId);
173
+ if (!state) {
174
+ throw new Error(`Execution ${executionId} not found in workspace '${workspace}'`);
175
+ }
176
+ // Append event to inline events array (cast to mutable array)
177
+ state.events.push(event);
178
+ await this.update(state);
179
+ }
180
+ async getEventsSince(repo, workspace, executionId, sinceSeq) {
181
+ const state = await this.read(repo, workspace, executionId);
182
+ if (!state) {
183
+ return [];
184
+ }
185
+ // Filter events from inline array
186
+ const sinceSeqBigInt = BigInt(sinceSeq);
187
+ return state.events.filter(e => {
188
+ // Events are variants, so we access seq via e.value.seq
189
+ const seq = e.value.seq;
190
+ return seq > sinceSeqBigInt;
191
+ });
192
+ }
193
+ async nextExecutionId(_repo, workspace) {
194
+ const path = this.counterPath(workspace);
195
+ let current = 0;
196
+ try {
197
+ const data = await fs.readFile(path, 'utf-8');
198
+ current = parseInt(data.trim(), 10) || 0;
199
+ }
200
+ catch (err) {
201
+ if (err.code !== 'ENOENT') {
202
+ throw err;
203
+ }
204
+ }
205
+ const next = current + 1;
206
+ await this.atomicWriteText(path, String(next));
207
+ return String(next);
208
+ }
209
+ async delete(_repo, workspace, executionId) {
210
+ // Only delete if the stored execution matches the requested ID
211
+ const state = await this.readLatest(_repo, workspace);
212
+ if (state && state.id === executionId) {
213
+ const statePath = this.statePath(workspace);
214
+ try {
215
+ await fs.unlink(statePath);
216
+ }
217
+ catch (err) {
218
+ if (err.code !== 'ENOENT') {
219
+ throw err;
220
+ }
221
+ }
222
+ }
223
+ }
224
+ /**
225
+ * Check if an incomplete execution exists for a workspace.
226
+ *
227
+ * An execution is incomplete if its status is 'running'.
228
+ * This is used to detect crash recovery scenarios.
229
+ *
230
+ * @param repo - Repository identifier
231
+ * @param workspace - Workspace name
232
+ * @returns The incomplete execution if one exists, null otherwise
233
+ */
234
+ async getIncompleteExecution(repo, workspace) {
235
+ const state = await this.readLatest(repo, workspace);
236
+ if (state && state.status === 'running') {
237
+ return state;
238
+ }
239
+ return null;
240
+ }
241
+ /**
242
+ * Write a binary file atomically using temp file + rename.
243
+ */
244
+ async atomicWrite(path, content) {
245
+ const dir = dirname(path);
246
+ const tmpPath = join(dir, `.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`);
247
+ try {
248
+ await fs.mkdir(dir, { recursive: true });
249
+ await fs.writeFile(tmpPath, content);
250
+ await fs.rename(tmpPath, path);
251
+ }
252
+ catch (err) {
253
+ // Clean up temp file on failure
254
+ try {
255
+ await fs.unlink(tmpPath);
256
+ }
257
+ catch {
258
+ // Ignore cleanup errors
259
+ }
260
+ throw err;
261
+ }
262
+ }
263
+ /**
264
+ * Write a text file atomically using temp file + rename.
265
+ */
266
+ async atomicWriteText(path, content) {
267
+ const dir = dirname(path);
268
+ const tmpPath = join(dir, `.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`);
269
+ try {
270
+ await fs.mkdir(dir, { recursive: true });
271
+ await fs.writeFile(tmpPath, content, 'utf-8');
272
+ await fs.rename(tmpPath, path);
273
+ }
274
+ catch (err) {
275
+ // Clean up temp file on failure
276
+ try {
277
+ await fs.unlink(tmpPath);
278
+ }
279
+ catch {
280
+ // Ignore cleanup errors
281
+ }
282
+ throw err;
283
+ }
284
+ }
285
+ }
286
+ //# sourceMappingURL=FileStateStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileStateStore.js","sourceRoot":"","sources":["../../../../src/dataflow/state-store/FileStateStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { ExecutionStateStore, TaskStatusDetails, ExecutionStatusDetails } from './interfaces.js';
6
+ import type { DataflowExecutionState, ExecutionEvent, TaskStatus } from '../types.js';
7
+ /**
8
+ * In-memory state store for testing and simple use cases.
9
+ *
10
+ * @remarks
11
+ * - Thread-safe for concurrent access within a single process
12
+ * - State is lost on process exit
13
+ * - No durability guarantees
14
+ */
15
+ export declare class InMemoryStateStore implements ExecutionStateStore {
16
+ /** Map of "repo::workspace" -> execution ID -> state */
17
+ private states;
18
+ /** Map of "repo::workspace" -> next execution ID counter */
19
+ private counters;
20
+ private makeKey;
21
+ create(state: DataflowExecutionState): Promise<void>;
22
+ read(repo: string, workspace: string, id: string): Promise<DataflowExecutionState | null>;
23
+ readLatest(repo: string, workspace: string): Promise<DataflowExecutionState | null>;
24
+ update(state: DataflowExecutionState): Promise<void>;
25
+ updateTaskStatus(repo: string, workspace: string, executionId: string, task: string, status: TaskStatus, details?: TaskStatusDetails): Promise<void>;
26
+ updateStatus(repo: string, workspace: string, executionId: string, status: 'running' | 'completed' | 'failed' | 'cancelled', details?: ExecutionStatusDetails): Promise<void>;
27
+ recordEvent(repo: string, workspace: string, executionId: string, event: ExecutionEvent): Promise<void>;
28
+ getEventsSince(repo: string, workspace: string, executionId: string, sinceSeq: number): Promise<ExecutionEvent[]>;
29
+ nextExecutionId(repo: string, workspace: string): Promise<string>;
30
+ delete(repo: string, workspace: string, executionId: string): Promise<void>;
31
+ /**
32
+ * Clear all state (for testing).
33
+ */
34
+ clear(): void;
35
+ /**
36
+ * Deep clone execution state to prevent external mutation.
37
+ *
38
+ * Note: We use spread and some() to properly clone the branded option types.
39
+ */
40
+ private cloneState;
41
+ }
42
+ //# sourceMappingURL=InMemoryStateStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InMemoryStateStore.d.ts","sourceRoot":"","sources":["../../../../src/dataflow/state-store/InMemoryStateStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EACV,sBAAsB,EAEtB,cAAc,EACd,UAAU,EAEX,MAAM,aAAa,CAAC;AAKrB;;;;;;;GAOG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;IAC5D,wDAAwD;IACxD,OAAO,CAAC,MAAM,CAA0D;IAExE,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAA6B;IAE7C,OAAO,CAAC,OAAO;IAKT,MAAM,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBpD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAYzF,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAwBnF,MAAM,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUpD,gBAAgB,CACpB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC;IAwBV,YAAY,CAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,EACxD,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,IAAI,CAAC;IAyBV,WAAW,CACf,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,IAAI,CAAC;IAaV,cAAc,CAClB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,EAAE,CAAC;IActB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASjE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjF;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;;;OAIG;IACH,OAAO,CAAC,UAAU;CAmCnB"}