@elaraai/e3-core 0.0.2-beta.12 → 0.0.2-beta.14

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 (95) hide show
  1. package/dist/src/dataflow.d.ts +118 -9
  2. package/dist/src/dataflow.d.ts.map +1 -1
  3. package/dist/src/dataflow.js +283 -54
  4. package/dist/src/dataflow.js.map +1 -1
  5. package/dist/src/errors.d.ts +11 -6
  6. package/dist/src/errors.d.ts.map +1 -1
  7. package/dist/src/errors.js +10 -3
  8. package/dist/src/errors.js.map +1 -1
  9. package/dist/src/execution/index.d.ts +14 -0
  10. package/dist/src/execution/index.d.ts.map +1 -0
  11. package/dist/src/execution/index.js +6 -0
  12. package/dist/src/execution/index.js.map +1 -0
  13. package/dist/src/execution/interfaces.d.ts +244 -0
  14. package/dist/src/execution/interfaces.d.ts.map +1 -0
  15. package/dist/src/execution/interfaces.js +6 -0
  16. package/dist/src/execution/interfaces.js.map +1 -0
  17. package/dist/src/executions.d.ts +48 -38
  18. package/dist/src/executions.d.ts.map +1 -1
  19. package/dist/src/executions.js +117 -162
  20. package/dist/src/executions.js.map +1 -1
  21. package/dist/src/gc.d.ts +9 -2
  22. package/dist/src/gc.d.ts.map +1 -1
  23. package/dist/src/gc.js +19 -9
  24. package/dist/src/gc.js.map +1 -1
  25. package/dist/src/index.d.ts +8 -6
  26. package/dist/src/index.d.ts.map +1 -1
  27. package/dist/src/index.js +22 -5
  28. package/dist/src/index.js.map +1 -1
  29. package/dist/src/objects.d.ts +6 -6
  30. package/dist/src/objects.js +6 -6
  31. package/dist/src/packages.d.ts +22 -14
  32. package/dist/src/packages.d.ts.map +1 -1
  33. package/dist/src/packages.js +45 -79
  34. package/dist/src/packages.js.map +1 -1
  35. package/dist/src/repository.d.ts +8 -4
  36. package/dist/src/repository.d.ts.map +1 -1
  37. package/dist/src/repository.js +25 -29
  38. package/dist/src/repository.js.map +1 -1
  39. package/dist/src/storage/index.d.ts +17 -0
  40. package/dist/src/storage/index.d.ts.map +1 -0
  41. package/dist/src/storage/index.js +8 -0
  42. package/dist/src/storage/index.js.map +1 -0
  43. package/dist/src/storage/interfaces.d.ts +299 -0
  44. package/dist/src/storage/interfaces.d.ts.map +1 -0
  45. package/dist/src/storage/interfaces.js +6 -0
  46. package/dist/src/storage/interfaces.js.map +1 -0
  47. package/dist/src/storage/local/LocalBackend.d.ts +51 -0
  48. package/dist/src/storage/local/LocalBackend.d.ts.map +1 -0
  49. package/dist/src/storage/local/LocalBackend.js +73 -0
  50. package/dist/src/storage/local/LocalBackend.js.map +1 -0
  51. package/dist/src/storage/local/LocalLockService.d.ts +22 -0
  52. package/dist/src/storage/local/LocalLockService.d.ts.map +1 -0
  53. package/dist/src/storage/local/LocalLockService.js +38 -0
  54. package/dist/src/storage/local/LocalLockService.js.map +1 -0
  55. package/dist/src/storage/local/LocalLogStore.d.ts +23 -0
  56. package/dist/src/storage/local/LocalLogStore.d.ts.map +1 -0
  57. package/dist/src/storage/local/LocalLogStore.js +66 -0
  58. package/dist/src/storage/local/LocalLogStore.js.map +1 -0
  59. package/dist/src/storage/local/LocalObjectStore.d.ts +19 -0
  60. package/dist/src/storage/local/LocalObjectStore.d.ts.map +1 -0
  61. package/dist/src/storage/local/LocalObjectStore.js +68 -0
  62. package/dist/src/storage/local/LocalObjectStore.js.map +1 -0
  63. package/dist/src/storage/local/LocalRefStore.d.ts +35 -0
  64. package/dist/src/storage/local/LocalRefStore.d.ts.map +1 -0
  65. package/dist/src/storage/local/LocalRefStore.js +233 -0
  66. package/dist/src/storage/local/LocalRefStore.js.map +1 -0
  67. package/dist/src/storage/local/index.d.ts +16 -0
  68. package/dist/src/storage/local/index.d.ts.map +1 -0
  69. package/dist/src/storage/local/index.js +16 -0
  70. package/dist/src/storage/local/index.js.map +1 -0
  71. package/dist/src/tasks.d.ts +16 -10
  72. package/dist/src/tasks.d.ts.map +1 -1
  73. package/dist/src/tasks.js +35 -41
  74. package/dist/src/tasks.js.map +1 -1
  75. package/dist/src/test-helpers.d.ts +4 -4
  76. package/dist/src/test-helpers.d.ts.map +1 -1
  77. package/dist/src/test-helpers.js +6 -20
  78. package/dist/src/test-helpers.js.map +1 -1
  79. package/dist/src/trees.d.ts +41 -29
  80. package/dist/src/trees.d.ts.map +1 -1
  81. package/dist/src/trees.js +112 -109
  82. package/dist/src/trees.js.map +1 -1
  83. package/dist/src/workspaceLock.d.ts +29 -7
  84. package/dist/src/workspaceLock.d.ts.map +1 -1
  85. package/dist/src/workspaceLock.js +130 -40
  86. package/dist/src/workspaceLock.js.map +1 -1
  87. package/dist/src/workspaceStatus.d.ts +6 -4
  88. package/dist/src/workspaceStatus.d.ts.map +1 -1
  89. package/dist/src/workspaceStatus.js +42 -58
  90. package/dist/src/workspaceStatus.js.map +1 -1
  91. package/dist/src/workspaces.d.ts +35 -26
  92. package/dist/src/workspaces.d.ts.map +1 -1
  93. package/dist/src/workspaces.js +93 -116
  94. package/dist/src/workspaces.js.map +1 -1
  95. package/package.json +3 -3
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import * as fs from 'fs/promises';
6
+ import * as path from 'path';
7
+ import { LocalObjectStore } from './LocalObjectStore.js';
8
+ import { LocalRefStore } from './LocalRefStore.js';
9
+ import { LocalLockService } from './LocalLockService.js';
10
+ import { LocalLogStore } from './LocalLogStore.js';
11
+ import { RepositoryNotFoundError } from '../../errors.js';
12
+ /**
13
+ * Local filesystem implementation of StorageBackend.
14
+ *
15
+ * This combines the local implementations of all storage interfaces,
16
+ * providing a complete backend for local e3 repositories.
17
+ *
18
+ * The `repo` parameter passed to each method is the path to the e3 repository directory.
19
+ * This allows a single LocalStorage instance to be used for multiple repositories.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { LocalStorage } from '@elaraai/e3-core';
24
+ *
25
+ * const storage = new LocalStorage();
26
+ * const repo = '/path/to/repo';
27
+ *
28
+ * // Use the backend with storage-agnostic functions
29
+ * const hash = await storage.objects.write(repo, data);
30
+ * const packages = await storage.refs.packageList(repo);
31
+ * ```
32
+ */
33
+ export class LocalStorage {
34
+ /** Content-addressed object storage */
35
+ objects;
36
+ /** Mutable reference storage */
37
+ refs;
38
+ /** Distributed locking service */
39
+ locks;
40
+ /** Execution log storage */
41
+ logs;
42
+ /**
43
+ * Create a new LocalStorage instance.
44
+ *
45
+ * No configuration needed - the `repo` parameter (path to e3 repository directory)
46
+ * is passed to each method call instead.
47
+ */
48
+ constructor() {
49
+ this.objects = new LocalObjectStore();
50
+ this.refs = new LocalRefStore();
51
+ this.locks = new LocalLockService();
52
+ this.logs = new LocalLogStore();
53
+ }
54
+ /**
55
+ * Validate that a repository exists and is properly structured.
56
+ * @param repo - Path to the e3 repository directory
57
+ * @throws {RepositoryNotFoundError} If repository doesn't exist or is invalid
58
+ */
59
+ async validateRepository(repo) {
60
+ const requiredDirs = ['objects', 'packages', 'workspaces', 'executions'];
61
+ for (const dir of requiredDirs) {
62
+ try {
63
+ await fs.access(path.join(repo, dir));
64
+ }
65
+ catch {
66
+ throw new RepositoryNotFoundError(repo);
67
+ }
68
+ }
69
+ }
70
+ }
71
+ // Re-export as LocalBackend for backwards compatibility during migration
72
+ export { LocalStorage as LocalBackend };
73
+ //# sourceMappingURL=LocalBackend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalBackend.js","sourceRoot":"","sources":["../../../../src/storage/local/LocalBackend.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,YAAY;IACvB,uCAAuC;IACvB,OAAO,CAAc;IAErC,gCAAgC;IAChB,IAAI,CAAW;IAE/B,kCAAkC;IAClB,KAAK,CAAc;IAEnC,4BAA4B;IACZ,IAAI,CAAW;IAE/B;;;;;OAKG;IACH;QACE,IAAI,CAAC,OAAO,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,IAAI,aAAa,EAAE,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,kBAAkB,CAAC,IAAY;QACnC,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;QACzE,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED,yEAAyE;AACzE,OAAO,EAAE,YAAY,IAAI,YAAY,EAAE,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { LockState, LockOperation } from '@elaraai/e3-types';
6
+ import type { LockHandle, LockService } from '../interfaces.js';
7
+ /**
8
+ * Local filesystem implementation of LockService.
9
+ *
10
+ * Uses flock() for kernel-managed locking with lock state
11
+ * stored in beast2 format using LockStateType.
12
+ * The `repo` parameter is the path to the e3 repository directory.
13
+ */
14
+ export declare class LocalLockService implements LockService {
15
+ acquire(repo: string, resource: string, operation: LockOperation, options?: {
16
+ wait?: boolean;
17
+ timeout?: number;
18
+ }): Promise<LockHandle | null>;
19
+ getState(repo: string, resource: string): Promise<LockState | null>;
20
+ isHolderAlive(holder: string): Promise<boolean>;
21
+ }
22
+ //# sourceMappingURL=LocalLockService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalLockService.d.ts","sourceRoot":"","sources":["../../../../src/storage/local/LocalLockService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAQhE;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAC5C,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,aAAa,EACxB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC7C,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAkB7B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAInE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGhD"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import { acquireWorkspaceLock, getWorkspaceLockState, isLockHolderAlive, } from '../../workspaceLock.js';
6
+ /**
7
+ * Local filesystem implementation of LockService.
8
+ *
9
+ * Uses flock() for kernel-managed locking with lock state
10
+ * stored in beast2 format using LockStateType.
11
+ * The `repo` parameter is the path to the e3 repository directory.
12
+ */
13
+ export class LocalLockService {
14
+ async acquire(repo, resource, operation, options) {
15
+ const acquireOptions = {
16
+ wait: options?.wait ?? false,
17
+ timeout: options?.timeout,
18
+ };
19
+ try {
20
+ const handle = await acquireWorkspaceLock(repo, resource, operation, acquireOptions);
21
+ return {
22
+ resource,
23
+ release: () => handle.release(),
24
+ };
25
+ }
26
+ catch {
27
+ // Lock couldn't be acquired
28
+ return null;
29
+ }
30
+ }
31
+ getState(repo, resource) {
32
+ return getWorkspaceLockState(repo, resource);
33
+ }
34
+ isHolderAlive(holder) {
35
+ return isLockHolderAlive(holder);
36
+ }
37
+ }
38
+ //# sourceMappingURL=LocalLockService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalLockService.js","sourceRoot":"","sources":["../../../../src/storage/local/LocalLockService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,GAElB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IAC3B,KAAK,CAAC,OAAO,CACX,IAAY,EACZ,QAAgB,EAChB,SAAwB,EACxB,OAA8C;QAE9C,MAAM,cAAc,GAAuB;YACzC,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,KAAK;YAC5B,OAAO,EAAE,OAAO,EAAE,OAAO;SAC1B,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;YACrF,OAAO;gBACL,QAAQ;gBACR,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE;aAChC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,4BAA4B;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,IAAY,EAAE,QAAgB;QACrC,OAAO,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,aAAa,CAAC,MAAc;QAC1B,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { LogChunk, LogStore } from '../interfaces.js';
6
+ /**
7
+ * Local filesystem implementation of LogStore.
8
+ *
9
+ * Logs are stored as text files in the execution directory:
10
+ * executions/<taskHash>/<inputsHash>/stdout.txt
11
+ * executions/<taskHash>/<inputsHash>/stderr.txt
12
+ *
13
+ * The `repo` parameter is the path to the e3 repository directory.
14
+ */
15
+ export declare class LocalLogStore implements LogStore {
16
+ private logPath;
17
+ append(repo: string, taskHash: string, inputsHash: string, stream: 'stdout' | 'stderr', data: string): Promise<void>;
18
+ read(repo: string, taskHash: string, inputsHash: string, stream: 'stdout' | 'stderr', options?: {
19
+ offset?: number;
20
+ limit?: number;
21
+ }): Promise<LogChunk>;
22
+ }
23
+ //# sourceMappingURL=LocalLogStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalLogStore.d.ts","sourceRoot":"","sources":["../../../../src/storage/local/LocalLogStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG3D;;;;;;;;GAQG;AACH,qBAAa,aAAc,YAAW,QAAQ;IAC5C,OAAO,CAAC,OAAO;IAUT,MAAM,CACV,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAC3B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAQV,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,QAAQ,GAAG,QAAQ,EAC3B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC5C,OAAO,CAAC,QAAQ,CAAC;CAwCrB"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import * as fs from 'fs/promises';
6
+ import * as path from 'path';
7
+ import { isNotFoundError } from '../../errors.js';
8
+ /**
9
+ * Local filesystem implementation of LogStore.
10
+ *
11
+ * Logs are stored as text files in the execution directory:
12
+ * executions/<taskHash>/<inputsHash>/stdout.txt
13
+ * executions/<taskHash>/<inputsHash>/stderr.txt
14
+ *
15
+ * The `repo` parameter is the path to the e3 repository directory.
16
+ */
17
+ export class LocalLogStore {
18
+ logPath(repo, taskHash, inputsHash, stream) {
19
+ return path.join(repo, 'executions', taskHash, inputsHash, `${stream}.txt`);
20
+ }
21
+ async append(repo, taskHash, inputsHash, stream, data) {
22
+ const logFile = this.logPath(repo, taskHash, inputsHash, stream);
23
+ const dir = path.dirname(logFile);
24
+ await fs.mkdir(dir, { recursive: true });
25
+ await fs.appendFile(logFile, data);
26
+ }
27
+ async read(repo, taskHash, inputsHash, stream, options) {
28
+ const logFile = this.logPath(repo, taskHash, inputsHash, stream);
29
+ const offset = options?.offset ?? 0;
30
+ const limit = options?.limit ?? 65536; // 64KB default
31
+ try {
32
+ const stat = await fs.stat(logFile);
33
+ const totalSize = stat.size;
34
+ // Open file and read chunk
35
+ const fd = await fs.open(logFile, 'r');
36
+ try {
37
+ const buffer = Buffer.alloc(Math.min(limit, Math.max(0, totalSize - offset)));
38
+ const { bytesRead } = await fd.read(buffer, 0, buffer.length, offset);
39
+ return {
40
+ data: buffer.slice(0, bytesRead).toString('utf-8'),
41
+ offset,
42
+ size: bytesRead,
43
+ totalSize,
44
+ complete: offset + bytesRead >= totalSize,
45
+ };
46
+ }
47
+ finally {
48
+ await fd.close();
49
+ }
50
+ }
51
+ catch (err) {
52
+ if (isNotFoundError(err)) {
53
+ // Log file doesn't exist yet
54
+ return {
55
+ data: '',
56
+ offset: 0,
57
+ size: 0,
58
+ totalSize: 0,
59
+ complete: true,
60
+ };
61
+ }
62
+ throw err;
63
+ }
64
+ }
65
+ }
66
+ //# sourceMappingURL=LocalLogStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalLogStore.js","sourceRoot":"","sources":["../../../../src/storage/local/LocalLogStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;;;GAQG;AACH,MAAM,OAAO,aAAa;IAChB,OAAO,CAAC,IAAY,EAAE,QAAgB,EAAE,UAAkB,EAAE,MAA2B;QAC7F,OAAO,IAAI,CAAC,IAAI,CACd,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,GAAG,MAAM,MAAM,CAChB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CACV,IAAY,EACZ,QAAgB,EAChB,UAAkB,EAClB,MAA2B,EAC3B,IAAY;QAEZ,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAElC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,IAAI,CACR,IAAY,EACZ,QAAgB,EAChB,UAAkB,EAClB,MAA2B,EAC3B,OAA6C;QAE7C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QAEjE,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC,CAAC,eAAe;QAEtD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;YAE5B,2BAA2B;YAC3B,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACvC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC9E,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAEtE,OAAO;oBACL,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;oBAClD,MAAM;oBACN,IAAI,EAAE,SAAS;oBACf,SAAS;oBACT,QAAQ,EAAE,MAAM,GAAG,SAAS,IAAI,SAAS;iBAC1C,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;YACnB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,6BAA6B;gBAC7B,OAAO;oBACL,IAAI,EAAE,EAAE;oBACR,MAAM,EAAE,CAAC;oBACT,IAAI,EAAE,CAAC;oBACP,SAAS,EAAE,CAAC;oBACZ,QAAQ,EAAE,IAAI;iBACf,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { ObjectStore } from '../interfaces.js';
6
+ /**
7
+ * Local filesystem implementation of ObjectStore.
8
+ *
9
+ * Wraps the existing objects.ts functions.
10
+ * The `repo` parameter is the path to the e3 repository directory.
11
+ */
12
+ export declare class LocalObjectStore implements ObjectStore {
13
+ write(repo: string, data: Uint8Array): Promise<string>;
14
+ writeStream(repo: string, stream: AsyncIterable<Uint8Array>): Promise<string>;
15
+ read(repo: string, hash: string): Promise<Uint8Array>;
16
+ exists(repo: string, hash: string): Promise<boolean>;
17
+ list(repo: string): Promise<string[]>;
18
+ }
19
+ //# sourceMappingURL=LocalObjectStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalObjectStore.d.ts","sourceRoot":"","sources":["../../../../src/storage/local/LocalObjectStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AASpD;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAC5C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAItD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAa7E,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAIrD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAgC5C"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import * as fs from 'fs/promises';
6
+ import * as path from 'path';
7
+ import { objectWrite, objectWriteStream, objectRead, objectExists, } from '../../objects.js';
8
+ import { isNotFoundError } from '../../errors.js';
9
+ /**
10
+ * Local filesystem implementation of ObjectStore.
11
+ *
12
+ * Wraps the existing objects.ts functions.
13
+ * The `repo` parameter is the path to the e3 repository directory.
14
+ */
15
+ export class LocalObjectStore {
16
+ async write(repo, data) {
17
+ return objectWrite(repo, data);
18
+ }
19
+ async writeStream(repo, stream) {
20
+ // Convert AsyncIterable to ReadableStream for objectWriteStream
21
+ const readableStream = new ReadableStream({
22
+ async start(controller) {
23
+ for await (const chunk of stream) {
24
+ controller.enqueue(chunk);
25
+ }
26
+ controller.close();
27
+ },
28
+ });
29
+ return objectWriteStream(repo, readableStream);
30
+ }
31
+ async read(repo, hash) {
32
+ return objectRead(repo, hash);
33
+ }
34
+ async exists(repo, hash) {
35
+ return objectExists(repo, hash);
36
+ }
37
+ async list(repo) {
38
+ const objectsDir = path.join(repo, 'objects');
39
+ const hashes = [];
40
+ try {
41
+ const prefixDirs = await fs.readdir(objectsDir);
42
+ for (const prefix of prefixDirs) {
43
+ if (!/^[a-f0-9]{2}$/.test(prefix))
44
+ continue;
45
+ const prefixPath = path.join(objectsDir, prefix);
46
+ const stat = await fs.stat(prefixPath);
47
+ if (!stat.isDirectory())
48
+ continue;
49
+ const files = await fs.readdir(prefixPath);
50
+ for (const file of files) {
51
+ if (file.endsWith('.beast2') && !file.includes('.partial')) {
52
+ // Reconstruct full hash: prefix + filename without extension
53
+ const hash = prefix + file.slice(0, -7);
54
+ hashes.push(hash);
55
+ }
56
+ }
57
+ }
58
+ }
59
+ catch (err) {
60
+ // Only suppress ENOENT - directory may not exist yet
61
+ if (!isNotFoundError(err)) {
62
+ throw err;
63
+ }
64
+ }
65
+ return hashes;
66
+ }
67
+ }
68
+ //# sourceMappingURL=LocalObjectStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalObjectStore.js","sourceRoot":"","sources":["../../../../src/storage/local/LocalObjectStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;IAC3B,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,IAAgB;QACxC,OAAO,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAY,EAAE,MAAiC;QAC/D,gEAAgE;QAChE,MAAM,cAAc,GAAG,IAAI,cAAc,CAAa;YACpD,KAAK,CAAC,KAAK,CAAC,UAAU;gBACpB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBACjC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC5B,CAAC;gBACD,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;SACF,CAAC,CAAC;QACH,OAAO,iBAAiB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAAY;QACnC,OAAO,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,IAAY;QACrC,OAAO,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAEhD,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;gBAChC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC;oBAAE,SAAS;gBAE5C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;gBACjD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACvC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;oBAAE,SAAS;gBAElC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC3D,6DAA6D;wBAC7D,MAAM,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;wBACxC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACpB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,qDAAqD;YACrD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { ExecutionStatus } from '@elaraai/e3-types';
6
+ import type { RefStore } from '../interfaces.js';
7
+ /**
8
+ * Local filesystem implementation of RefStore.
9
+ *
10
+ * The `repo` parameter is the path to the e3 repository directory.
11
+ */
12
+ export declare class LocalRefStore implements RefStore {
13
+ packageList(repo: string): Promise<{
14
+ name: string;
15
+ version: string;
16
+ }[]>;
17
+ packageResolve(repo: string, name: string, version: string): Promise<string | null>;
18
+ packageWrite(repo: string, name: string, version: string, hash: string): Promise<void>;
19
+ packageRemove(repo: string, name: string, version: string): Promise<void>;
20
+ workspaceList(repo: string): Promise<string[]>;
21
+ workspaceRead(repo: string, name: string): Promise<Uint8Array | null>;
22
+ workspaceWrite(repo: string, name: string, state: Uint8Array): Promise<void>;
23
+ workspaceRemove(repo: string, name: string): Promise<void>;
24
+ private executionDir;
25
+ executionGet(repo: string, taskHash: string, inputsHash: string): Promise<ExecutionStatus | null>;
26
+ executionWrite(repo: string, taskHash: string, inputsHash: string, status: ExecutionStatus): Promise<void>;
27
+ executionGetOutput(repo: string, taskHash: string, inputsHash: string): Promise<string | null>;
28
+ executionWriteOutput(repo: string, taskHash: string, inputsHash: string, outputHash: string): Promise<void>;
29
+ executionList(repo: string): Promise<{
30
+ taskHash: string;
31
+ inputsHash: string;
32
+ }[]>;
33
+ executionListForTask(repo: string, taskHash: string): Promise<string[]>;
34
+ }
35
+ //# sourceMappingURL=LocalRefStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalRefStore.d.ts","sourceRoot":"","sources":["../../../../src/storage/local/LocalRefStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;GAIG;AACH,qBAAa,aAAc,YAAW,QAAQ;IAKtC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IA0BvE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAanF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOtF,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBzE,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAqB9C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAarE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5E,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBhE,OAAO,CAAC,YAAY;IAId,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA0BjG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1G,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAe9F,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3G,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IA+BhF,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAc9E"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import * as fs from 'fs/promises';
6
+ import * as path from 'path';
7
+ import { decodeBeast2For, encodeBeast2For } from '@elaraai/east';
8
+ import { ExecutionStatusType } from '@elaraai/e3-types';
9
+ import { isNotFoundError, ExecutionCorruptError } from '../../errors.js';
10
+ /**
11
+ * Local filesystem implementation of RefStore.
12
+ *
13
+ * The `repo` parameter is the path to the e3 repository directory.
14
+ */
15
+ export class LocalRefStore {
16
+ // -------------------------------------------------------------------------
17
+ // Package References
18
+ // -------------------------------------------------------------------------
19
+ async packageList(repo) {
20
+ const packagesDir = path.join(repo, 'packages');
21
+ const packages = [];
22
+ try {
23
+ const names = await fs.readdir(packagesDir);
24
+ for (const name of names) {
25
+ const nameDir = path.join(packagesDir, name);
26
+ const stat = await fs.stat(nameDir);
27
+ if (stat.isDirectory()) {
28
+ const versions = await fs.readdir(nameDir);
29
+ for (const version of versions) {
30
+ packages.push({ name, version });
31
+ }
32
+ }
33
+ }
34
+ }
35
+ catch (err) {
36
+ // Only suppress ENOENT - directory may not exist yet
37
+ if (!isNotFoundError(err)) {
38
+ throw err;
39
+ }
40
+ }
41
+ return packages;
42
+ }
43
+ async packageResolve(repo, name, version) {
44
+ const refPath = path.join(repo, 'packages', name, version);
45
+ try {
46
+ const content = await fs.readFile(refPath, 'utf-8');
47
+ return content.trim();
48
+ }
49
+ catch (err) {
50
+ if (isNotFoundError(err)) {
51
+ return null;
52
+ }
53
+ throw err;
54
+ }
55
+ }
56
+ async packageWrite(repo, name, version, hash) {
57
+ const refDir = path.join(repo, 'packages', name);
58
+ await fs.mkdir(refDir, { recursive: true });
59
+ const refPath = path.join(refDir, version);
60
+ await fs.writeFile(refPath, hash + '\n');
61
+ }
62
+ async packageRemove(repo, name, version) {
63
+ const refPath = path.join(repo, 'packages', name, version);
64
+ try {
65
+ await fs.unlink(refPath);
66
+ }
67
+ catch (err) {
68
+ if (isNotFoundError(err)) {
69
+ return; // Already removed, idempotent
70
+ }
71
+ throw err;
72
+ }
73
+ // Try to remove the package name directory if empty
74
+ const packageDir = path.join(repo, 'packages', name);
75
+ try {
76
+ await fs.rmdir(packageDir);
77
+ }
78
+ catch {
79
+ // Directory not empty, that's fine
80
+ }
81
+ }
82
+ // -------------------------------------------------------------------------
83
+ // Workspace State
84
+ // -------------------------------------------------------------------------
85
+ async workspaceList(repo) {
86
+ const workspacesDir = path.join(repo, 'workspaces');
87
+ const names = [];
88
+ try {
89
+ const entries = await fs.readdir(workspacesDir);
90
+ for (const entry of entries) {
91
+ if (entry.endsWith('.beast2')) {
92
+ names.push(entry.slice(0, -7)); // Remove .beast2 extension
93
+ }
94
+ }
95
+ }
96
+ catch (err) {
97
+ // Only suppress ENOENT - directory may not exist yet
98
+ if (!isNotFoundError(err)) {
99
+ throw err;
100
+ }
101
+ }
102
+ return names;
103
+ }
104
+ async workspaceRead(repo, name) {
105
+ const stateFile = path.join(repo, 'workspaces', `${name}.beast2`);
106
+ try {
107
+ return await fs.readFile(stateFile);
108
+ }
109
+ catch (err) {
110
+ if (isNotFoundError(err)) {
111
+ return null;
112
+ }
113
+ throw err;
114
+ }
115
+ }
116
+ async workspaceWrite(repo, name, state) {
117
+ const wsDir = path.join(repo, 'workspaces');
118
+ const stateFile = path.join(wsDir, `${name}.beast2`);
119
+ await fs.mkdir(wsDir, { recursive: true });
120
+ // Write atomically: write to temp file, then rename
121
+ const randomSuffix = Math.random().toString(36).slice(2, 10);
122
+ const tempPath = path.join(wsDir, `.${name}.${Date.now()}.${randomSuffix}.tmp`);
123
+ await fs.writeFile(tempPath, state);
124
+ await fs.rename(tempPath, stateFile);
125
+ }
126
+ async workspaceRemove(repo, name) {
127
+ const stateFile = path.join(repo, 'workspaces', `${name}.beast2`);
128
+ try {
129
+ await fs.unlink(stateFile);
130
+ }
131
+ catch (err) {
132
+ if (isNotFoundError(err)) {
133
+ return; // Already removed, idempotent
134
+ }
135
+ throw err;
136
+ }
137
+ }
138
+ // -------------------------------------------------------------------------
139
+ // Execution Cache
140
+ // -------------------------------------------------------------------------
141
+ executionDir(repo, taskHash, inputsHash) {
142
+ return path.join(repo, 'executions', taskHash, inputsHash);
143
+ }
144
+ async executionGet(repo, taskHash, inputsHash) {
145
+ const execDir = this.executionDir(repo, taskHash, inputsHash);
146
+ const statusPath = path.join(execDir, 'status.beast2');
147
+ let data;
148
+ try {
149
+ data = await fs.readFile(statusPath);
150
+ }
151
+ catch (err) {
152
+ if (isNotFoundError(err)) {
153
+ return null;
154
+ }
155
+ throw err;
156
+ }
157
+ try {
158
+ const decoder = decodeBeast2For(ExecutionStatusType);
159
+ return decoder(data);
160
+ }
161
+ catch (err) {
162
+ throw new ExecutionCorruptError(taskHash, inputsHash, err instanceof Error ? err : new Error(String(err)));
163
+ }
164
+ }
165
+ async executionWrite(repo, taskHash, inputsHash, status) {
166
+ const execDir = this.executionDir(repo, taskHash, inputsHash);
167
+ await fs.mkdir(execDir, { recursive: true });
168
+ const encoder = encodeBeast2For(ExecutionStatusType);
169
+ await fs.writeFile(path.join(execDir, 'status.beast2'), encoder(status));
170
+ }
171
+ async executionGetOutput(repo, taskHash, inputsHash) {
172
+ const execDir = this.executionDir(repo, taskHash, inputsHash);
173
+ const outputPath = path.join(execDir, 'output');
174
+ try {
175
+ const content = await fs.readFile(outputPath, 'utf-8');
176
+ return content.trim();
177
+ }
178
+ catch (err) {
179
+ if (isNotFoundError(err)) {
180
+ return null;
181
+ }
182
+ throw err;
183
+ }
184
+ }
185
+ async executionWriteOutput(repo, taskHash, inputsHash, outputHash) {
186
+ const execDir = this.executionDir(repo, taskHash, inputsHash);
187
+ await fs.mkdir(execDir, { recursive: true });
188
+ await fs.writeFile(path.join(execDir, 'output'), outputHash + '\n');
189
+ }
190
+ async executionList(repo) {
191
+ const executionsDir = path.join(repo, 'executions');
192
+ const result = [];
193
+ try {
194
+ const taskDirs = await fs.readdir(executionsDir);
195
+ for (const taskHash of taskDirs) {
196
+ if (!/^[a-f0-9]{64}$/.test(taskHash))
197
+ continue;
198
+ const taskDir = path.join(executionsDir, taskHash);
199
+ const stat = await fs.stat(taskDir);
200
+ if (!stat.isDirectory())
201
+ continue;
202
+ const inputsDirs = await fs.readdir(taskDir);
203
+ for (const inputsHash of inputsDirs) {
204
+ if (/^[a-f0-9]{64}$/.test(inputsHash)) {
205
+ result.push({ taskHash, inputsHash });
206
+ }
207
+ }
208
+ }
209
+ }
210
+ catch (err) {
211
+ // Only suppress ENOENT - directory may not exist yet
212
+ if (!isNotFoundError(err)) {
213
+ throw err;
214
+ }
215
+ }
216
+ return result;
217
+ }
218
+ async executionListForTask(repo, taskHash) {
219
+ const taskDir = path.join(repo, 'executions', taskHash);
220
+ try {
221
+ const entries = await fs.readdir(taskDir);
222
+ return entries.filter((e) => /^[a-f0-9]{64}$/.test(e));
223
+ }
224
+ catch (err) {
225
+ // Only suppress ENOENT - task may not have any executions yet
226
+ if (!isNotFoundError(err)) {
227
+ throw err;
228
+ }
229
+ return [];
230
+ }
231
+ }
232
+ }
233
+ //# sourceMappingURL=LocalRefStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalRefStore.js","sourceRoot":"","sources":["../../../../src/storage/local/LocalRefStore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAEzE;;;;GAIG;AACH,MAAM,OAAO,aAAa;IACxB,4EAA4E;IAC5E,qBAAqB;IACrB,4EAA4E;IAE5E,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAwC,EAAE,CAAC;QAEzD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;gBAC7C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACpC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;oBACvB,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBAC3C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;wBAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;oBACnC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,qDAAqD;YACrD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,IAAY,EAAE,OAAe;QAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACpD,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,IAAY,EAAE,OAAe,EAAE,IAAY;QAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,IAAY,EAAE,OAAe;QAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,8BAA8B;YACxC,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,oDAAoD;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,kBAAkB;IAClB,4EAA4E;IAE5E,KAAK,CAAC,aAAa,CAAC,IAAY;QAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YAChD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC9B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B;gBAC7D,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,qDAAqD;YACrD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY,EAAE,IAAY;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,SAAS,CAAC,CAAC;QAElE,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,IAAY,EAAE,KAAiB;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,SAAS,CAAC,CAAC;QAErD,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,oDAAoD;QACpD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,YAAY,MAAM,CAAC,CAAC;QAChF,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACpC,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,IAAY,EAAE,IAAY;QAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,IAAI,SAAS,CAAC,CAAC;QAClE,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,8BAA8B;YACxC,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,kBAAkB;IAClB,4EAA4E;IAEpE,YAAY,CAAC,IAAY,EAAE,QAAgB,EAAE,UAAkB;QACrE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,QAAgB,EAAE,UAAkB;QACnE,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAEvD,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,eAAe,CAAC,mBAAmB,CAAC,CAAC;YACrD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,qBAAqB,CAC7B,QAAQ,EACR,UAAU,EACV,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CACpD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,QAAgB,EAAE,UAAkB,EAAE,MAAuB;QAC9F,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7C,MAAM,OAAO,GAAG,eAAe,CAAC,mBAAmB,CAAC,CAAC;QACrD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,IAAY,EAAE,QAAgB,EAAE,UAAkB;QACzE,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEhD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACvD,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,IAAY,EAAE,QAAgB,EAAE,UAAkB,EAAE,UAAkB;QAC/F,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAY;QAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,MAAM,GAA+C,EAAE,CAAC;QAE9D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YAEjD,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBAE/C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;gBACnD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;oBAAE,SAAS;gBAElC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBAC7C,KAAK,MAAM,UAAU,IAAI,UAAU,EAAE,CAAC;oBACpC,IAAI,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;wBACtC,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;oBACxC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,qDAAqD;YACrD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,IAAY,EAAE,QAAgB;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC1C,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,8DAA8D;YAC9D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ /**
6
+ * Local filesystem implementation of StorageBackend.
7
+ *
8
+ * This wraps the existing e3-core filesystem functions to provide a
9
+ * StorageBackend that works with local repositories.
10
+ */
11
+ export { LocalStorage, LocalBackend } from './LocalBackend.js';
12
+ export { LocalObjectStore } from './LocalObjectStore.js';
13
+ export { LocalRefStore } from './LocalRefStore.js';
14
+ export { LocalLockService } from './LocalLockService.js';
15
+ export { LocalLogStore } from './LocalLogStore.js';
16
+ //# sourceMappingURL=index.d.ts.map