@elaraai/e3-core 0.0.2-beta.4 → 0.0.2-beta.40

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 (208) 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 +139 -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 +76 -0
  11. package/dist/src/dataflow/orchestrator/LocalOrchestrator.d.ts.map +1 -0
  12. package/dist/src/dataflow/orchestrator/LocalOrchestrator.js +695 -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 +163 -0
  19. package/dist/src/dataflow/orchestrator/interfaces.d.ts.map +1 -0
  20. package/dist/src/dataflow/orchestrator/interfaces.js +52 -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 +300 -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 +229 -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 +222 -0
  39. package/dist/src/dataflow/steps.d.ts.map +1 -0
  40. package/dist/src/dataflow/steps.js +707 -0
  41. package/dist/src/dataflow/steps.js.map +1 -0
  42. package/dist/src/dataflow/types.d.ts +127 -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 +113 -38
  47. package/dist/src/dataflow.d.ts.map +1 -1
  48. package/dist/src/dataflow.js +269 -416
  49. package/dist/src/dataflow.js.map +1 -1
  50. package/dist/src/dataset-refs.d.ts +124 -0
  51. package/dist/src/dataset-refs.d.ts.map +1 -0
  52. package/dist/src/dataset-refs.js +319 -0
  53. package/dist/src/dataset-refs.js.map +1 -0
  54. package/dist/src/errors.d.ts +39 -9
  55. package/dist/src/errors.d.ts.map +1 -1
  56. package/dist/src/errors.js +51 -8
  57. package/dist/src/errors.js.map +1 -1
  58. package/dist/src/execution/LocalTaskRunner.d.ts +73 -0
  59. package/dist/src/execution/LocalTaskRunner.d.ts.map +1 -0
  60. package/dist/src/execution/LocalTaskRunner.js +399 -0
  61. package/dist/src/execution/LocalTaskRunner.js.map +1 -0
  62. package/dist/src/execution/MockTaskRunner.d.ts +49 -0
  63. package/dist/src/execution/MockTaskRunner.d.ts.map +1 -0
  64. package/dist/src/execution/MockTaskRunner.js +54 -0
  65. package/dist/src/execution/MockTaskRunner.js.map +1 -0
  66. package/dist/src/execution/index.d.ts +16 -0
  67. package/dist/src/execution/index.d.ts.map +1 -0
  68. package/dist/src/execution/index.js +8 -0
  69. package/dist/src/execution/index.js.map +1 -0
  70. package/dist/src/execution/interfaces.d.ts +246 -0
  71. package/dist/src/execution/interfaces.d.ts.map +1 -0
  72. package/dist/src/execution/interfaces.js +6 -0
  73. package/dist/src/execution/interfaces.js.map +1 -0
  74. package/dist/src/execution/processHelpers.d.ts +20 -0
  75. package/dist/src/execution/processHelpers.d.ts.map +1 -0
  76. package/dist/src/execution/processHelpers.js +62 -0
  77. package/dist/src/execution/processHelpers.js.map +1 -0
  78. package/dist/src/executions.d.ts +71 -104
  79. package/dist/src/executions.d.ts.map +1 -1
  80. package/dist/src/executions.js +110 -476
  81. package/dist/src/executions.js.map +1 -1
  82. package/dist/src/index.d.ts +19 -9
  83. package/dist/src/index.d.ts.map +1 -1
  84. package/dist/src/index.js +48 -18
  85. package/dist/src/index.js.map +1 -1
  86. package/dist/src/objects.d.ts +8 -51
  87. package/dist/src/objects.d.ts.map +1 -1
  88. package/dist/src/objects.js +13 -230
  89. package/dist/src/objects.js.map +1 -1
  90. package/dist/src/packages.d.ts +22 -14
  91. package/dist/src/packages.d.ts.map +1 -1
  92. package/dist/src/packages.js +134 -88
  93. package/dist/src/packages.js.map +1 -1
  94. package/dist/src/storage/in-memory/InMemoryRepoStore.d.ts +35 -0
  95. package/dist/src/storage/in-memory/InMemoryRepoStore.d.ts.map +1 -0
  96. package/dist/src/storage/in-memory/InMemoryRepoStore.js +107 -0
  97. package/dist/src/storage/in-memory/InMemoryRepoStore.js.map +1 -0
  98. package/dist/src/storage/in-memory/InMemoryStorage.d.ts +139 -0
  99. package/dist/src/storage/in-memory/InMemoryStorage.d.ts.map +1 -0
  100. package/dist/src/storage/in-memory/InMemoryStorage.js +439 -0
  101. package/dist/src/storage/in-memory/InMemoryStorage.js.map +1 -0
  102. package/dist/src/storage/in-memory/index.d.ts +12 -0
  103. package/dist/src/storage/in-memory/index.d.ts.map +1 -0
  104. package/dist/src/storage/in-memory/index.js +12 -0
  105. package/dist/src/storage/in-memory/index.js.map +1 -0
  106. package/dist/src/storage/index.d.ts +18 -0
  107. package/dist/src/storage/index.d.ts.map +1 -0
  108. package/dist/src/storage/index.js +10 -0
  109. package/dist/src/storage/index.js.map +1 -0
  110. package/dist/src/storage/interfaces.d.ts +581 -0
  111. package/dist/src/storage/interfaces.d.ts.map +1 -0
  112. package/dist/src/storage/interfaces.js +6 -0
  113. package/dist/src/storage/interfaces.js.map +1 -0
  114. package/dist/src/storage/local/LocalBackend.d.ts +56 -0
  115. package/dist/src/storage/local/LocalBackend.d.ts.map +1 -0
  116. package/dist/src/storage/local/LocalBackend.js +145 -0
  117. package/dist/src/storage/local/LocalBackend.js.map +1 -0
  118. package/dist/src/storage/local/LocalDatasetRefStore.d.ts +22 -0
  119. package/dist/src/storage/local/LocalDatasetRefStore.d.ts.map +1 -0
  120. package/dist/src/storage/local/LocalDatasetRefStore.js +118 -0
  121. package/dist/src/storage/local/LocalDatasetRefStore.js.map +1 -0
  122. package/dist/src/storage/local/LocalLockService.d.ts +111 -0
  123. package/dist/src/storage/local/LocalLockService.d.ts.map +1 -0
  124. package/dist/src/storage/local/LocalLockService.js +355 -0
  125. package/dist/src/storage/local/LocalLockService.js.map +1 -0
  126. package/dist/src/storage/local/LocalLogStore.d.ts +23 -0
  127. package/dist/src/storage/local/LocalLogStore.d.ts.map +1 -0
  128. package/dist/src/storage/local/LocalLogStore.js +66 -0
  129. package/dist/src/storage/local/LocalLogStore.js.map +1 -0
  130. package/dist/src/storage/local/LocalObjectStore.d.ts +55 -0
  131. package/dist/src/storage/local/LocalObjectStore.d.ts.map +1 -0
  132. package/dist/src/storage/local/LocalObjectStore.js +300 -0
  133. package/dist/src/storage/local/LocalObjectStore.js.map +1 -0
  134. package/dist/src/storage/local/LocalRefStore.d.ts +50 -0
  135. package/dist/src/storage/local/LocalRefStore.d.ts.map +1 -0
  136. package/dist/src/storage/local/LocalRefStore.js +337 -0
  137. package/dist/src/storage/local/LocalRefStore.js.map +1 -0
  138. package/dist/src/storage/local/LocalRepoStore.d.ts +55 -0
  139. package/dist/src/storage/local/LocalRepoStore.d.ts.map +1 -0
  140. package/dist/src/storage/local/LocalRepoStore.js +365 -0
  141. package/dist/src/storage/local/LocalRepoStore.js.map +1 -0
  142. package/dist/src/storage/local/gc.d.ts +92 -0
  143. package/dist/src/storage/local/gc.d.ts.map +1 -0
  144. package/dist/src/storage/local/gc.js +377 -0
  145. package/dist/src/storage/local/gc.js.map +1 -0
  146. package/dist/src/storage/local/index.d.ts +18 -0
  147. package/dist/src/storage/local/index.d.ts.map +1 -0
  148. package/dist/src/storage/local/index.js +18 -0
  149. package/dist/src/storage/local/index.js.map +1 -0
  150. package/dist/src/storage/local/localHelpers.d.ts +25 -0
  151. package/dist/src/storage/local/localHelpers.d.ts.map +1 -0
  152. package/dist/src/storage/local/localHelpers.js +69 -0
  153. package/dist/src/storage/local/localHelpers.js.map +1 -0
  154. package/dist/src/{repository.d.ts → storage/local/repository.d.ts} +8 -4
  155. package/dist/src/storage/local/repository.d.ts.map +1 -0
  156. package/dist/src/{repository.js → storage/local/repository.js} +31 -29
  157. package/dist/src/storage/local/repository.js.map +1 -0
  158. package/dist/src/tasks.d.ts +16 -10
  159. package/dist/src/tasks.d.ts.map +1 -1
  160. package/dist/src/tasks.js +35 -41
  161. package/dist/src/tasks.js.map +1 -1
  162. package/dist/src/test-helpers.d.ts +5 -4
  163. package/dist/src/test-helpers.d.ts.map +1 -1
  164. package/dist/src/test-helpers.js +9 -21
  165. package/dist/src/test-helpers.js.map +1 -1
  166. package/dist/src/transfer/InMemoryTransferBackend.d.ts +66 -0
  167. package/dist/src/transfer/InMemoryTransferBackend.d.ts.map +1 -0
  168. package/dist/src/transfer/InMemoryTransferBackend.js +166 -0
  169. package/dist/src/transfer/InMemoryTransferBackend.js.map +1 -0
  170. package/dist/src/transfer/index.d.ts +8 -0
  171. package/dist/src/transfer/index.d.ts.map +1 -0
  172. package/dist/src/transfer/index.js +9 -0
  173. package/dist/src/transfer/index.js.map +1 -0
  174. package/dist/src/transfer/interfaces.d.ts +103 -0
  175. package/dist/src/transfer/interfaces.d.ts.map +1 -0
  176. package/dist/src/transfer/interfaces.js +6 -0
  177. package/dist/src/transfer/interfaces.js.map +1 -0
  178. package/dist/src/transfer/types.d.ts +79 -0
  179. package/dist/src/transfer/types.d.ts.map +1 -0
  180. package/dist/src/transfer/types.js +58 -0
  181. package/dist/src/transfer/types.js.map +1 -0
  182. package/dist/src/trees.d.ts +147 -59
  183. package/dist/src/trees.d.ts.map +1 -1
  184. package/dist/src/trees.js +372 -419
  185. package/dist/src/trees.js.map +1 -1
  186. package/dist/src/uuid.d.ts +26 -0
  187. package/dist/src/uuid.d.ts.map +1 -0
  188. package/dist/src/uuid.js +80 -0
  189. package/dist/src/uuid.js.map +1 -0
  190. package/dist/src/workspaceStatus.d.ts +6 -4
  191. package/dist/src/workspaceStatus.d.ts.map +1 -1
  192. package/dist/src/workspaceStatus.js +43 -49
  193. package/dist/src/workspaceStatus.js.map +1 -1
  194. package/dist/src/workspaces.d.ts +35 -47
  195. package/dist/src/workspaces.d.ts.map +1 -1
  196. package/dist/src/workspaces.js +194 -156
  197. package/dist/src/workspaces.js.map +1 -1
  198. package/package.json +4 -4
  199. package/dist/src/gc.d.ts +0 -54
  200. package/dist/src/gc.d.ts.map +0 -1
  201. package/dist/src/gc.js +0 -233
  202. package/dist/src/gc.js.map +0 -1
  203. package/dist/src/repository.d.ts.map +0 -1
  204. package/dist/src/repository.js.map +0 -1
  205. package/dist/src/workspaceLock.d.ts +0 -67
  206. package/dist/src/workspaceLock.d.ts.map +0 -1
  207. package/dist/src/workspaceLock.js +0 -217
  208. package/dist/src/workspaceLock.js.map +0 -1
@@ -0,0 +1,365 @@
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 { RepoNotFoundError, RepoAlreadyExistsError, RepoStatusConflictError, } from '../../errors.js';
8
+ import { decodeBeast2For } from '@elaraai/east';
9
+ import { WorkspaceStateType } from '@elaraai/e3-types';
10
+ const METADATA_FILENAME = '.e3-metadata.json';
11
+ /**
12
+ * Local filesystem implementation of RepoStore.
13
+ *
14
+ * Manages repository lifecycle for local e3 repositories stored
15
+ * as subdirectories within a parent directory.
16
+ */
17
+ export class LocalRepoStore {
18
+ reposDir;
19
+ refs;
20
+ datasets;
21
+ /**
22
+ * Create a new LocalRepoStore.
23
+ * @param reposDir - Parent directory containing repositories
24
+ * @param refs - RefStore for reading package/workspace/execution refs
25
+ * @param datasets - DatasetRefStore for reading per-dataset refs (for GC scanning)
26
+ */
27
+ constructor(reposDir, refs, datasets) {
28
+ this.reposDir = reposDir;
29
+ this.refs = refs;
30
+ this.datasets = datasets;
31
+ }
32
+ /**
33
+ * Get the path to a repository directory.
34
+ */
35
+ getRepoPath(repo) {
36
+ return path.join(this.reposDir, repo);
37
+ }
38
+ /**
39
+ * Get the path to a repository's metadata file.
40
+ */
41
+ getMetadataPath(repo) {
42
+ return path.join(this.getRepoPath(repo), METADATA_FILENAME);
43
+ }
44
+ /**
45
+ * Check if a directory is a valid e3 repository.
46
+ */
47
+ async isValidRepository(repoPath) {
48
+ const requiredDirs = ['objects', 'packages', 'executions', 'workspaces'];
49
+ for (const dir of requiredDirs) {
50
+ try {
51
+ const stat = await fs.stat(path.join(repoPath, dir));
52
+ if (!stat.isDirectory()) {
53
+ return false;
54
+ }
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ return true;
61
+ }
62
+ // ===========================================================================
63
+ // Queries
64
+ // ===========================================================================
65
+ async list() {
66
+ const repos = [];
67
+ try {
68
+ const entries = await fs.readdir(this.reposDir, { withFileTypes: true });
69
+ for (const entry of entries) {
70
+ if (entry.isDirectory()) {
71
+ const repoPath = path.join(this.reposDir, entry.name);
72
+ if (await this.isValidRepository(repoPath)) {
73
+ repos.push(entry.name);
74
+ }
75
+ }
76
+ }
77
+ }
78
+ catch {
79
+ // reposDir doesn't exist or can't be read
80
+ }
81
+ return repos;
82
+ }
83
+ async exists(repo) {
84
+ const repoPath = this.getRepoPath(repo);
85
+ return this.isValidRepository(repoPath);
86
+ }
87
+ async getMetadata(repo) {
88
+ const repoPath = this.getRepoPath(repo);
89
+ // Check if repo exists
90
+ if (!(await this.isValidRepository(repoPath))) {
91
+ return null;
92
+ }
93
+ const metadataPath = this.getMetadataPath(repo);
94
+ try {
95
+ const content = await fs.readFile(metadataPath, 'utf-8');
96
+ const metadata = JSON.parse(content);
97
+ return {
98
+ name: metadata.name,
99
+ status: metadata.status,
100
+ createdAt: metadata.createdAt,
101
+ statusChangedAt: metadata.statusChangedAt,
102
+ };
103
+ }
104
+ catch {
105
+ // No metadata file - synthesize for legacy repos
106
+ // Get mtime from repo directory for createdAt
107
+ try {
108
+ const stat = await fs.stat(repoPath);
109
+ const createdAt = stat.birthtime.toISOString();
110
+ return {
111
+ name: repo,
112
+ status: 'active',
113
+ createdAt,
114
+ statusChangedAt: createdAt,
115
+ };
116
+ }
117
+ catch {
118
+ return null;
119
+ }
120
+ }
121
+ }
122
+ // ===========================================================================
123
+ // Lifecycle
124
+ // ===========================================================================
125
+ async create(repo) {
126
+ const repoPath = this.getRepoPath(repo);
127
+ // Check if already exists
128
+ if (await this.isValidRepository(repoPath)) {
129
+ throw new RepoAlreadyExistsError(repo);
130
+ }
131
+ // Create directory structure
132
+ await fs.mkdir(repoPath, { recursive: true });
133
+ await fs.mkdir(path.join(repoPath, 'objects'), { recursive: true });
134
+ await fs.mkdir(path.join(repoPath, 'packages'), { recursive: true });
135
+ await fs.mkdir(path.join(repoPath, 'executions'), { recursive: true });
136
+ await fs.mkdir(path.join(repoPath, 'workspaces'), { recursive: true });
137
+ // Write metadata file
138
+ const now = new Date().toISOString();
139
+ const metadata = {
140
+ name: repo,
141
+ status: 'active',
142
+ createdAt: now,
143
+ statusChangedAt: now,
144
+ };
145
+ await fs.writeFile(this.getMetadataPath(repo), JSON.stringify(metadata, null, 2));
146
+ }
147
+ async setStatus(repo, status, expected) {
148
+ const current = await this.getMetadata(repo);
149
+ if (!current) {
150
+ throw new RepoNotFoundError(repo);
151
+ }
152
+ // Check expected status (CAS)
153
+ if (expected !== undefined) {
154
+ const expectedArray = Array.isArray(expected) ? expected : [expected];
155
+ if (!expectedArray.includes(current.status)) {
156
+ throw new RepoStatusConflictError(repo, expected, current.status);
157
+ }
158
+ }
159
+ // Update metadata
160
+ const now = new Date().toISOString();
161
+ const metadata = {
162
+ name: current.name,
163
+ status,
164
+ createdAt: current.createdAt,
165
+ statusChangedAt: now,
166
+ };
167
+ // Atomic write using rename
168
+ const metadataPath = this.getMetadataPath(repo);
169
+ const tempPath = `${metadataPath}.tmp`;
170
+ await fs.writeFile(tempPath, JSON.stringify(metadata, null, 2));
171
+ await fs.rename(tempPath, metadataPath);
172
+ }
173
+ async remove(repo) {
174
+ const repoPath = this.getRepoPath(repo);
175
+ try {
176
+ // Remove the entire repository directory
177
+ await fs.rm(repoPath, { recursive: true, force: true });
178
+ }
179
+ catch {
180
+ // Ignore errors if directory doesn't exist
181
+ }
182
+ }
183
+ // ===========================================================================
184
+ // Batched Deletion
185
+ // ===========================================================================
186
+ async deleteRefsBatch(repo, _cursor) {
187
+ const repoPath = this.getRepoPath(repo);
188
+ let deleted = 0;
189
+ // For local storage, we delete all refs in one pass
190
+ // (packages/, workspaces/, executions/, locks/)
191
+ const refDirs = ['packages', 'workspaces', 'executions', 'locks'];
192
+ for (const dir of refDirs) {
193
+ const dirPath = path.join(repoPath, dir);
194
+ try {
195
+ deleted += await this.deleteDirectoryContents(dirPath);
196
+ }
197
+ catch {
198
+ // Directory doesn't exist
199
+ }
200
+ }
201
+ return { status: 'done', deleted };
202
+ }
203
+ async deleteObjectsBatch(repo, _cursor) {
204
+ const repoPath = this.getRepoPath(repo);
205
+ const objectsDir = path.join(repoPath, 'objects');
206
+ let deleted = 0;
207
+ try {
208
+ deleted = await this.deleteDirectoryContents(objectsDir);
209
+ }
210
+ catch {
211
+ // objects dir doesn't exist
212
+ }
213
+ return { status: 'done', deleted };
214
+ }
215
+ /**
216
+ * Recursively delete all contents of a directory.
217
+ * Returns count of files deleted.
218
+ */
219
+ async deleteDirectoryContents(dir) {
220
+ let count = 0;
221
+ try {
222
+ const entries = await fs.readdir(dir, { withFileTypes: true });
223
+ for (const entry of entries) {
224
+ const entryPath = path.join(dir, entry.name);
225
+ if (entry.isDirectory()) {
226
+ count += await this.deleteDirectoryContents(entryPath);
227
+ await fs.rmdir(entryPath);
228
+ }
229
+ else {
230
+ await fs.unlink(entryPath);
231
+ count++;
232
+ }
233
+ }
234
+ }
235
+ catch {
236
+ // Directory doesn't exist or can't be read
237
+ }
238
+ return count;
239
+ }
240
+ // ===========================================================================
241
+ // GC Primitives
242
+ // ===========================================================================
243
+ // Note: GC primitives receive `repo` as a full path (same as ObjectStore/RefStore),
244
+ // NOT as a repo name relative to reposDir. This is consistent with how all
245
+ // storage interfaces work in the local implementation.
246
+ async gcScanPackageRoots(repo, _cursor) {
247
+ const roots = [];
248
+ const packages = await this.refs.packageList(repo);
249
+ for (const { name, version } of packages) {
250
+ const hash = await this.refs.packageResolve(repo, name, version);
251
+ if (hash) {
252
+ roots.push(hash);
253
+ }
254
+ }
255
+ return { roots };
256
+ }
257
+ async gcScanWorkspaceRoots(repo, _cursor) {
258
+ const roots = [];
259
+ const decoder = decodeBeast2For(WorkspaceStateType);
260
+ const names = await this.refs.workspaceList(repo);
261
+ for (const name of names) {
262
+ const data = await this.refs.workspaceRead(repo, name);
263
+ if (!data || data.length === 0)
264
+ continue;
265
+ try {
266
+ const state = decoder(data);
267
+ roots.push(state.packageHash);
268
+ // Scan per-dataset ref files for value hashes
269
+ if (this.datasets) {
270
+ const refPaths = await this.datasets.list(repo, name);
271
+ for (const refPath of refPaths) {
272
+ const ref = await this.datasets.read(repo, name, refPath);
273
+ if (ref && ref.type === 'value') {
274
+ roots.push(ref.value.hash);
275
+ }
276
+ }
277
+ }
278
+ }
279
+ catch {
280
+ // Corrupt workspace state - skip
281
+ }
282
+ }
283
+ return { roots };
284
+ }
285
+ async gcScanExecutionRoots(repo, _cursor) {
286
+ const roots = [];
287
+ const entries = await this.refs.executionList(repo);
288
+ for (const { taskHash, inputsHash } of entries) {
289
+ const ids = await this.refs.executionListIds(repo, taskHash, inputsHash);
290
+ for (const executionId of ids) {
291
+ const status = await this.refs.executionGet(repo, taskHash, inputsHash, executionId);
292
+ if (!status)
293
+ continue;
294
+ // ExecutionStatus is a variant; extract outputHash from success
295
+ const raw = status;
296
+ if (raw.type === 'success' && raw.value.outputHash && /^[a-f0-9]{64}$/.test(raw.value.outputHash)) {
297
+ roots.push(raw.value.outputHash);
298
+ }
299
+ }
300
+ }
301
+ return { roots };
302
+ }
303
+ async gcScanObjects(repo, _cursor) {
304
+ const objectsDir = path.join(repo, 'objects');
305
+ const objects = [];
306
+ try {
307
+ const subdirs = await fs.readdir(objectsDir);
308
+ for (const subdir of subdirs) {
309
+ if (!/^[a-f0-9]{2}$/.test(subdir))
310
+ continue;
311
+ const subdirPath = path.join(objectsDir, subdir);
312
+ try {
313
+ const stat = await fs.stat(subdirPath);
314
+ if (!stat.isDirectory())
315
+ continue;
316
+ }
317
+ catch {
318
+ continue;
319
+ }
320
+ const files = await fs.readdir(subdirPath);
321
+ for (const file of files) {
322
+ if (file.endsWith('.partial'))
323
+ continue;
324
+ if (!file.endsWith('.beast2'))
325
+ continue;
326
+ const hash = subdir + file.slice(0, -7); // remove .beast2
327
+ try {
328
+ const fileStat = await fs.stat(path.join(subdirPath, file));
329
+ objects.push({ hash, lastModified: fileStat.mtimeMs, size: fileStat.size });
330
+ }
331
+ catch {
332
+ // Skip files we can't stat
333
+ }
334
+ }
335
+ }
336
+ }
337
+ catch {
338
+ // Objects directory doesn't exist
339
+ }
340
+ // Local returns all in one batch (no cursor)
341
+ return { objects };
342
+ }
343
+ async gcDeleteObjects(repo, hashes) {
344
+ const objectsDir = path.join(repo, 'objects');
345
+ for (const hash of hashes) {
346
+ const subdir = hash.slice(0, 2);
347
+ const rest = hash.slice(2);
348
+ const filePath = path.join(objectsDir, subdir, `${rest}.beast2`);
349
+ try {
350
+ await fs.unlink(filePath);
351
+ }
352
+ catch {
353
+ // File doesn't exist
354
+ }
355
+ // Try to remove empty subdirectory
356
+ try {
357
+ await fs.rmdir(path.join(objectsDir, subdir));
358
+ }
359
+ catch {
360
+ // Directory not empty or doesn't exist
361
+ }
362
+ }
363
+ }
364
+ }
365
+ //# sourceMappingURL=LocalRepoStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalRepoStore.js","sourceRoot":"","sources":["../../../../src/storage/local/LocalRepoStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { RepoStore, GcObjectEntry, StorageBackend } from '../interfaces.js';
6
+ /**
7
+ * Options for garbage collection
8
+ */
9
+ export interface GcOptions {
10
+ /**
11
+ * Minimum age in milliseconds for files to be considered for deletion.
12
+ * Files younger than this are skipped to avoid race conditions with concurrent writes.
13
+ * Default: 60000 (1 minute)
14
+ */
15
+ minAge?: number;
16
+ /**
17
+ * If true, only report what would be deleted without actually deleting.
18
+ * Default: false
19
+ */
20
+ dryRun?: boolean;
21
+ }
22
+ /**
23
+ * Result of garbage collection
24
+ */
25
+ export interface GcResult {
26
+ /** Number of objects deleted */
27
+ deletedObjects: number;
28
+ /** Number of orphaned staging files deleted */
29
+ deletedPartials: number;
30
+ /** Number of objects retained */
31
+ retainedObjects: number;
32
+ /** Number of files skipped due to being too young */
33
+ skippedYoung: number;
34
+ /** Total bytes freed */
35
+ bytesFreed: number;
36
+ }
37
+ /**
38
+ * Result from sweepBatch — pure decision, no side effects.
39
+ */
40
+ export interface SweepBatchResult {
41
+ /** Hashes of objects to delete */
42
+ toDelete: string[];
43
+ /** Number of objects retained (reachable) */
44
+ retained: number;
45
+ /** Number of objects skipped due to being too young */
46
+ skippedYoung: number;
47
+ /** Total bytes that would be freed */
48
+ bytesFreed: number;
49
+ }
50
+ /**
51
+ * Collect all root hashes from packages, workspaces, and executions.
52
+ *
53
+ * Calls each gcScan*Roots method with pagination support.
54
+ * Adding a new root scan method to RepoStore requires updating this function.
55
+ */
56
+ export declare function collectAllRoots(store: RepoStore, repo: string): Promise<Set<string>>;
57
+ /**
58
+ * Trace the object graph from roots using iterative DFS with schema-aware traversal.
59
+ *
60
+ * Decodes each object using BEAST2 self-describing format and extracts child
61
+ * hashes based on the detected object type (Package, Task, or Tree). Objects
62
+ * known to be leaves (values, IR blobs) are marked reachable without reading.
63
+ *
64
+ * @param readObject - Function to read an object by hash (returns null if missing)
65
+ * @param roots - Set of root hashes to start from
66
+ * @returns Set of all reachable hashes
67
+ */
68
+ export declare function markReachable(readObject: (hash: string) => Promise<Uint8Array | null>, roots: Set<string>): Promise<Set<string>>;
69
+ /**
70
+ * Pure decision function: determine which objects to delete.
71
+ *
72
+ * No side effects — trivially testable. Caller decides whether to
73
+ * actually delete (supports dry-run by skipping gcDeleteObjects).
74
+ *
75
+ * @param objects - Object entries from gcScanObjects
76
+ * @param reachable - Set of reachable hashes from markReachable
77
+ * @param minAge - Minimum age in ms; objects younger than this are skipped
78
+ * @returns Decision result with toDelete list and stats
79
+ */
80
+ export declare function sweepBatch(objects: GcObjectEntry[], reachable: Set<string>, minAge: number): SweepBatchResult;
81
+ /**
82
+ * Run garbage collection on an e3 repository.
83
+ *
84
+ * Works with any StorageBackend — no instanceof checks.
85
+ *
86
+ * @param storage - Storage backend
87
+ * @param repo - Repository identifier
88
+ * @param options - GC options
89
+ * @returns GC result with statistics
90
+ */
91
+ export declare function repoGc(storage: StorageBackend, repo: string, options?: GcOptions): Promise<GcResult>;
92
+ //# sourceMappingURL=gc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gc.d.ts","sourceRoot":"","sources":["../../../../src/storage/local/gc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAoB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEnG;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,eAAe,EAAE,MAAM,CAAC;IACxB,iCAAiC;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAmB1F;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EACxD,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GACjB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAgCtB;AAqGD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,aAAa,EAAE,EACxB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,MAAM,EAAE,MAAM,GACb,gBAAgB,CAsBlB;AAMD;;;;;;;;;GASG;AACH,wBAAsB,MAAM,CAC1B,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,SAAc,GACtB,OAAO,CAAC,QAAQ,CAAC,CAmEnB"}