@elaraai/e3-core 0.0.2-beta.25 → 0.0.2-beta.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/storage/in-memory/InMemoryRepoStore.d.ts +6 -7
- package/dist/src/storage/in-memory/InMemoryRepoStore.d.ts.map +1 -1
- package/dist/src/storage/in-memory/InMemoryRepoStore.js +13 -9
- package/dist/src/storage/in-memory/InMemoryRepoStore.js.map +1 -1
- package/dist/src/storage/in-memory/InMemoryStorage.d.ts +1 -0
- package/dist/src/storage/in-memory/InMemoryStorage.d.ts.map +1 -1
- package/dist/src/storage/in-memory/InMemoryStorage.js +3 -0
- package/dist/src/storage/in-memory/InMemoryStorage.js.map +1 -1
- package/dist/src/storage/index.d.ts +2 -2
- package/dist/src/storage/index.d.ts.map +1 -1
- package/dist/src/storage/index.js +1 -1
- package/dist/src/storage/index.js.map +1 -1
- package/dist/src/storage/interfaces.d.ts +55 -34
- package/dist/src/storage/interfaces.d.ts.map +1 -1
- package/dist/src/storage/local/LocalBackend.js +10 -4
- package/dist/src/storage/local/LocalBackend.js.map +1 -1
- package/dist/src/storage/local/LocalObjectStore.d.ts +1 -0
- package/dist/src/storage/local/LocalObjectStore.d.ts.map +1 -1
- package/dist/src/storage/local/LocalObjectStore.js +24 -0
- package/dist/src/storage/local/LocalObjectStore.js.map +1 -1
- package/dist/src/storage/local/LocalRepoStore.d.ts +10 -38
- package/dist/src/storage/local/LocalRepoStore.d.ts.map +1 -1
- package/dist/src/storage/local/LocalRepoStore.js +90 -191
- package/dist/src/storage/local/LocalRepoStore.js.map +1 -1
- package/dist/src/storage/local/gc.d.ts +53 -22
- package/dist/src/storage/local/gc.d.ts.map +1 -1
- package/dist/src/storage/local/gc.js +264 -94
- package/dist/src/storage/local/gc.js.map +1 -1
- package/dist/src/storage/local/index.d.ts +1 -1
- package/dist/src/storage/local/index.d.ts.map +1 -1
- package/dist/src/storage/local/index.js +1 -1
- package/dist/src/storage/local/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -3,150 +3,320 @@
|
|
|
3
3
|
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Shared garbage collection algorithm for e3 repositories.
|
|
7
7
|
*
|
|
8
|
-
* Uses mark-and-sweep
|
|
9
|
-
* 1.
|
|
10
|
-
* 2.
|
|
8
|
+
* Uses mark-and-sweep:
|
|
9
|
+
* 1. collectAllRoots: Collect root hashes from all root scan methods
|
|
10
|
+
* 2. markReachable: DFS through object graph via BEAST2 schema-aware traversal
|
|
11
|
+
* 3. sweepBatch: Pure decision function — identify unreachable objects to delete
|
|
12
|
+
* 4. repoGc: Driver that calls all phases in sequence
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
+
* These functions work with any StorageBackend — no instanceof checks.
|
|
15
|
+
* Cloud-specific concerns (S3 reachable set persistence, orphaned version cleanup)
|
|
16
|
+
* are handled in the cloud Lambda handlers.
|
|
14
17
|
*/
|
|
15
18
|
import * as fs from 'fs/promises';
|
|
16
19
|
import * as path from 'path';
|
|
17
|
-
import {
|
|
20
|
+
import { decodeBeast2 } from '@elaraai/east';
|
|
21
|
+
// =============================================================================
|
|
22
|
+
// Shared Algorithm Functions
|
|
23
|
+
// =============================================================================
|
|
18
24
|
/**
|
|
19
|
-
*
|
|
25
|
+
* Collect all root hashes from packages, workspaces, and executions.
|
|
20
26
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
|
|
27
|
+
* Calls each gcScan*Roots method with pagination support.
|
|
28
|
+
* Adding a new root scan method to RepoStore requires updating this function.
|
|
29
|
+
*/
|
|
30
|
+
export async function collectAllRoots(store, repo) {
|
|
31
|
+
const roots = new Set();
|
|
32
|
+
const scanAll = async (scan) => {
|
|
33
|
+
let cursor;
|
|
34
|
+
do {
|
|
35
|
+
const result = await scan(repo, cursor);
|
|
36
|
+
for (const hash of result.roots) {
|
|
37
|
+
roots.add(hash);
|
|
38
|
+
}
|
|
39
|
+
cursor = result.cursor;
|
|
40
|
+
} while (cursor !== undefined);
|
|
41
|
+
};
|
|
42
|
+
await scanAll(store.gcScanPackageRoots.bind(store));
|
|
43
|
+
await scanAll(store.gcScanWorkspaceRoots.bind(store));
|
|
44
|
+
await scanAll(store.gcScanExecutionRoots.bind(store));
|
|
45
|
+
return roots;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Trace the object graph from roots using iterative DFS with schema-aware traversal.
|
|
24
49
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* @
|
|
50
|
+
* Decodes each object using BEAST2 self-describing format and extracts child
|
|
51
|
+
* hashes based on the detected object type (Package, Task, or Tree). Objects
|
|
52
|
+
* known to be leaves (values, IR blobs) are marked reachable without reading.
|
|
53
|
+
*
|
|
54
|
+
* @param readObject - Function to read an object by hash (returns null if missing)
|
|
55
|
+
* @param roots - Set of root hashes to start from
|
|
56
|
+
* @returns Set of all reachable hashes
|
|
30
57
|
*/
|
|
31
|
-
export async function
|
|
32
|
-
// GC requires direct filesystem access - verify we have LocalStorage
|
|
33
|
-
if (!(storage instanceof LocalStorage)) {
|
|
34
|
-
throw new Error('GC is only supported with LocalStorage storage');
|
|
35
|
-
}
|
|
36
|
-
const minAge = options.minAge ?? 60000; // Default 1 minute
|
|
37
|
-
const dryRun = options.dryRun ?? false;
|
|
38
|
-
// Step 1: Collect all root hashes
|
|
39
|
-
const roots = await collectRoots(repo);
|
|
40
|
-
// Step 2: Mark all reachable objects starting from roots
|
|
58
|
+
export async function markReachable(readObject, roots) {
|
|
41
59
|
const reachable = new Set();
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
const stack = [...roots];
|
|
61
|
+
while (stack.length > 0) {
|
|
62
|
+
const hash = stack.pop();
|
|
63
|
+
if (reachable.has(hash))
|
|
64
|
+
continue;
|
|
65
|
+
const data = await readObject(hash);
|
|
66
|
+
if (!data)
|
|
67
|
+
continue;
|
|
68
|
+
reachable.add(hash);
|
|
69
|
+
// Schema-aware child extraction
|
|
70
|
+
let children;
|
|
71
|
+
try {
|
|
72
|
+
const decoded = decodeBeast2(Buffer.from(data));
|
|
73
|
+
children = extractChildren(decoded.type, decoded.value);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
continue; // Not valid BEAST2 or unknown format — treat as leaf
|
|
77
|
+
}
|
|
78
|
+
for (const child of children) {
|
|
79
|
+
if (reachable.has(child.hash))
|
|
80
|
+
continue;
|
|
81
|
+
if (child.isLeaf) {
|
|
82
|
+
reachable.add(child.hash); // Mark without reading
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
stack.push(child.hash);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return reachable;
|
|
90
|
+
}
|
|
91
|
+
// =============================================================================
|
|
92
|
+
// Type Detection Helpers
|
|
93
|
+
// =============================================================================
|
|
94
|
+
// EastTypeValue is a variant object: { type: string, value: any }
|
|
95
|
+
// For Struct: type.type === "Struct", type.value is Array<{ name: string, type: EastTypeValue }>
|
|
96
|
+
// For Variant: type.type === "Variant", type.value is Array<{ name: string, type: EastTypeValue }>
|
|
97
|
+
/**
|
|
98
|
+
* Check if a decoded EastTypeValue represents a PackageObject.
|
|
99
|
+
* PackageObject is a Struct with fields: tasks (Dict<String,String>), data (Struct)
|
|
100
|
+
*/
|
|
101
|
+
function isPackageObjectShape(type) {
|
|
102
|
+
if (type.type !== 'Struct')
|
|
103
|
+
return false;
|
|
104
|
+
const fields = type.value;
|
|
105
|
+
const names = new Set(fields.map(f => f.name));
|
|
106
|
+
return names.has('tasks') && names.has('data');
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Check if a decoded EastTypeValue represents a TaskObject.
|
|
110
|
+
* TaskObject is a Struct with fields: commandIr, inputs, output
|
|
111
|
+
*/
|
|
112
|
+
function isTaskObjectShape(type) {
|
|
113
|
+
if (type.type !== 'Struct')
|
|
114
|
+
return false;
|
|
115
|
+
const fields = type.value;
|
|
116
|
+
const names = new Set(fields.map(f => f.name));
|
|
117
|
+
return names.has('commandIr') && names.has('inputs') && names.has('output');
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Check if a field type is a DataRef (Variant with cases: unassigned, null, value, tree).
|
|
121
|
+
*/
|
|
122
|
+
function isDataRefFieldType(fieldType) {
|
|
123
|
+
if (fieldType.type !== 'Variant')
|
|
124
|
+
return false;
|
|
125
|
+
const cases = fieldType.value;
|
|
126
|
+
const names = new Set(cases.map(c => c.name));
|
|
127
|
+
return names.has('tree') && names.has('value') && names.has('unassigned') && names.has('null');
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if a decoded EastTypeValue represents a TreeObject.
|
|
131
|
+
* A tree is a Struct where every field is a DataRef variant.
|
|
132
|
+
*/
|
|
133
|
+
function isTreeObjectShape(type) {
|
|
134
|
+
if (type.type !== 'Struct')
|
|
135
|
+
return false;
|
|
136
|
+
const fields = type.value;
|
|
137
|
+
return fields.length > 0 && fields.every(f => isDataRefFieldType(f.type));
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Extract child hashes from a decoded BEAST2 object based on its type.
|
|
141
|
+
* Returns children with isLeaf flag to avoid reading leaf objects.
|
|
142
|
+
*/
|
|
143
|
+
function extractChildren(type, value) {
|
|
144
|
+
const t = type;
|
|
145
|
+
const children = [];
|
|
146
|
+
if (isPackageObjectShape(t)) {
|
|
147
|
+
const pkg = value;
|
|
148
|
+
for (const taskHash of pkg.tasks.values()) {
|
|
149
|
+
children.push({ hash: taskHash, isLeaf: false });
|
|
150
|
+
}
|
|
151
|
+
children.push({ hash: pkg.data.value, isLeaf: false }); // root tree
|
|
152
|
+
return children;
|
|
44
153
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return result;
|
|
154
|
+
if (isTaskObjectShape(t)) {
|
|
155
|
+
const task = value;
|
|
156
|
+
children.push({ hash: task.commandIr, isLeaf: true }); // IR is a leaf
|
|
157
|
+
return children;
|
|
50
158
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
159
|
+
if (isTreeObjectShape(t)) {
|
|
160
|
+
const tree = value;
|
|
161
|
+
for (const ref of Object.values(tree)) {
|
|
162
|
+
if (ref.type === 'tree') {
|
|
163
|
+
children.push({ hash: ref.value, isLeaf: false }); // subtree needs traversal
|
|
164
|
+
}
|
|
165
|
+
else if (ref.type === 'value') {
|
|
166
|
+
children.push({ hash: ref.value, isLeaf: true }); // value is a leaf
|
|
167
|
+
}
|
|
168
|
+
// 'unassigned' and 'null': no hash to follow
|
|
169
|
+
}
|
|
170
|
+
return children;
|
|
171
|
+
}
|
|
172
|
+
return []; // Unknown type: leaf, no children
|
|
59
173
|
}
|
|
60
174
|
/**
|
|
61
|
-
*
|
|
175
|
+
* Pure decision function: determine which objects to delete.
|
|
62
176
|
*
|
|
63
|
-
*
|
|
177
|
+
* No side effects — trivially testable. Caller decides whether to
|
|
178
|
+
* actually delete (supports dry-run by skipping gcDeleteObjects).
|
|
179
|
+
*
|
|
180
|
+
* @param objects - Object entries from gcScanObjects
|
|
181
|
+
* @param reachable - Set of reachable hashes from markReachable
|
|
182
|
+
* @param minAge - Minimum age in ms; objects younger than this are skipped
|
|
183
|
+
* @returns Decision result with toDelete list and stats
|
|
64
184
|
*/
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
185
|
+
export function sweepBatch(objects, reachable, minAge) {
|
|
186
|
+
const now = Date.now();
|
|
187
|
+
const toDelete = [];
|
|
188
|
+
let retained = 0;
|
|
189
|
+
let skippedYoung = 0;
|
|
190
|
+
let bytesFreed = 0;
|
|
191
|
+
for (const obj of objects) {
|
|
192
|
+
if (reachable.has(obj.hash)) {
|
|
193
|
+
retained++;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const age = now - obj.lastModified;
|
|
197
|
+
if (minAge > 0 && age < minAge) {
|
|
198
|
+
skippedYoung++;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
toDelete.push(obj.hash);
|
|
202
|
+
bytesFreed += obj.size;
|
|
69
203
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
204
|
+
return { toDelete, retained, skippedYoung, bytesFreed };
|
|
205
|
+
}
|
|
206
|
+
// =============================================================================
|
|
207
|
+
// Local Driver
|
|
208
|
+
// =============================================================================
|
|
209
|
+
/**
|
|
210
|
+
* Run garbage collection on an e3 repository.
|
|
211
|
+
*
|
|
212
|
+
* Works with any StorageBackend — no instanceof checks.
|
|
213
|
+
*
|
|
214
|
+
* @param storage - Storage backend
|
|
215
|
+
* @param repo - Repository identifier
|
|
216
|
+
* @param options - GC options
|
|
217
|
+
* @returns GC result with statistics
|
|
218
|
+
*/
|
|
219
|
+
export async function repoGc(storage, repo, options = {}) {
|
|
220
|
+
const minAge = options.minAge ?? 60000;
|
|
221
|
+
const dryRun = options.dryRun ?? false;
|
|
222
|
+
// Step 1: Collect all root hashes
|
|
223
|
+
const roots = await collectAllRoots(storage.repos, repo);
|
|
224
|
+
// Step 2: Mark all reachable objects
|
|
225
|
+
const readObject = async (hash) => {
|
|
226
|
+
try {
|
|
227
|
+
return await storage.objects.read(repo, hash);
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
const reachable = await markReachable(readObject, roots);
|
|
234
|
+
// Step 3: Scan and sweep objects
|
|
235
|
+
let totalDeleted = 0;
|
|
236
|
+
let totalRetained = 0;
|
|
237
|
+
let totalSkippedYoung = 0;
|
|
238
|
+
let totalBytesFreed = 0;
|
|
239
|
+
let cursor;
|
|
240
|
+
do {
|
|
241
|
+
const scan = await storage.repos.gcScanObjects(repo, cursor);
|
|
242
|
+
const result = sweepBatch(scan.objects, reachable, minAge);
|
|
243
|
+
totalRetained += result.retained;
|
|
244
|
+
totalSkippedYoung += result.skippedYoung;
|
|
245
|
+
totalBytesFreed += result.bytesFreed;
|
|
246
|
+
if (!dryRun && result.toDelete.length > 0) {
|
|
247
|
+
await storage.repos.gcDeleteObjects(repo, result.toDelete);
|
|
84
248
|
}
|
|
249
|
+
totalDeleted += result.toDelete.length;
|
|
250
|
+
cursor = scan.cursor;
|
|
251
|
+
} while (cursor !== undefined);
|
|
252
|
+
// Step 4: Clean up orphaned .partial files (local-only concern)
|
|
253
|
+
let deletedPartials = 0;
|
|
254
|
+
let partialSkippedYoung = 0;
|
|
255
|
+
try {
|
|
256
|
+
const partialResult = await cleanupPartials(repo, minAge, dryRun);
|
|
257
|
+
deletedPartials = partialResult.deleted;
|
|
258
|
+
partialSkippedYoung = partialResult.skippedYoung;
|
|
85
259
|
}
|
|
86
260
|
catch {
|
|
87
|
-
//
|
|
88
|
-
// wasn't actually a reference to an object
|
|
261
|
+
// Not a fatal error
|
|
89
262
|
}
|
|
263
|
+
return {
|
|
264
|
+
deletedObjects: totalDeleted,
|
|
265
|
+
deletedPartials,
|
|
266
|
+
retainedObjects: totalRetained,
|
|
267
|
+
skippedYoung: totalSkippedYoung + partialSkippedYoung,
|
|
268
|
+
bytesFreed: totalBytesFreed,
|
|
269
|
+
};
|
|
90
270
|
}
|
|
91
271
|
/**
|
|
92
|
-
*
|
|
272
|
+
* Clean up orphaned .partial staging files in the objects directory.
|
|
273
|
+
* This is a local-only concern — cloud storage doesn't use .partial files.
|
|
93
274
|
*/
|
|
94
|
-
async function
|
|
275
|
+
async function cleanupPartials(repoPath, minAge, dryRun) {
|
|
95
276
|
const objectsDir = path.join(repoPath, 'objects');
|
|
96
277
|
const now = Date.now();
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
deletedPartials: 0,
|
|
100
|
-
retainedObjects: 0,
|
|
101
|
-
skippedYoung: 0,
|
|
102
|
-
bytesFreed: 0,
|
|
103
|
-
};
|
|
278
|
+
let deleted = 0;
|
|
279
|
+
let skippedYoung = 0;
|
|
104
280
|
try {
|
|
105
281
|
const subdirs = await fs.readdir(objectsDir);
|
|
106
282
|
for (const subdir of subdirs) {
|
|
107
|
-
if (!/^[a-f0-9]{2}$/.test(subdir))
|
|
283
|
+
if (!/^[a-f0-9]{2}$/.test(subdir))
|
|
108
284
|
continue;
|
|
109
|
-
}
|
|
110
285
|
const subdirPath = path.join(objectsDir, subdir);
|
|
111
|
-
|
|
112
|
-
|
|
286
|
+
try {
|
|
287
|
+
const stat = await fs.stat(subdirPath);
|
|
288
|
+
if (!stat.isDirectory())
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
113
292
|
continue;
|
|
114
293
|
}
|
|
115
294
|
const files = await fs.readdir(subdirPath);
|
|
116
295
|
for (const file of files) {
|
|
296
|
+
if (!file.endsWith('.partial'))
|
|
297
|
+
continue;
|
|
117
298
|
const filePath = path.join(subdirPath, file);
|
|
118
299
|
try {
|
|
119
300
|
const fileStat = await fs.stat(filePath);
|
|
120
301
|
const age = now - fileStat.mtimeMs;
|
|
121
302
|
if (minAge > 0 && age < minAge) {
|
|
122
|
-
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
if (file.endsWith('.partial')) {
|
|
126
|
-
result.deletedPartials++;
|
|
127
|
-
result.bytesFreed += fileStat.size;
|
|
303
|
+
skippedYoung++;
|
|
128
304
|
continue;
|
|
129
305
|
}
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
if (reachable.has(hash)) {
|
|
133
|
-
result.retainedObjects++;
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
result.deletedObjects++;
|
|
137
|
-
result.bytesFreed += fileStat.size;
|
|
138
|
-
}
|
|
306
|
+
if (!dryRun) {
|
|
307
|
+
await fs.unlink(filePath);
|
|
139
308
|
}
|
|
309
|
+
deleted++;
|
|
140
310
|
}
|
|
141
311
|
catch {
|
|
142
|
-
// Skip files we can't stat
|
|
312
|
+
// Skip files we can't stat or delete
|
|
143
313
|
}
|
|
144
314
|
}
|
|
145
315
|
}
|
|
146
316
|
}
|
|
147
317
|
catch {
|
|
148
|
-
// Objects directory doesn't exist
|
|
318
|
+
// Objects directory doesn't exist
|
|
149
319
|
}
|
|
150
|
-
return
|
|
320
|
+
return { deleted, skippedYoung };
|
|
151
321
|
}
|
|
152
322
|
//# sourceMappingURL=gc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gc.js","sourceRoot":"","sources":["../../../../src/storage/local/gc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH
|
|
1
|
+
{"version":3,"file":"gc.js","sourceRoot":"","sources":["../../../../src/storage/local/gc.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,5 +13,5 @@ export { LocalObjectStore } from './LocalObjectStore.js';
|
|
|
13
13
|
export { LocalRefStore } from './LocalRefStore.js';
|
|
14
14
|
export { LocalLockService } from './LocalLockService.js';
|
|
15
15
|
export { LocalLogStore } from './LocalLogStore.js';
|
|
16
|
-
export { LocalRepoStore
|
|
16
|
+
export { LocalRepoStore } from './LocalRepoStore.js';
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/storage/local/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,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,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/storage/local/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,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,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -13,5 +13,5 @@ export { LocalObjectStore } from './LocalObjectStore.js';
|
|
|
13
13
|
export { LocalRefStore } from './LocalRefStore.js';
|
|
14
14
|
export { LocalLockService } from './LocalLockService.js';
|
|
15
15
|
export { LocalLogStore } from './LocalLogStore.js';
|
|
16
|
-
export { LocalRepoStore
|
|
16
|
+
export { LocalRepoStore } from './LocalRepoStore.js';
|
|
17
17
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/storage/local/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,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,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/storage/local/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,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,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elaraai/e3-core",
|
|
3
|
-
"version": "0.0.2-beta.
|
|
3
|
+
"version": "0.0.2-beta.27",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "East Execution Engine Core - Programmatic API for e3 repository operations",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"directory": "packages/e3-core"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@elaraai/e3": "^0.0.2-beta.
|
|
44
|
-
"@elaraai/e3-types": "^0.0.2-beta.
|
|
43
|
+
"@elaraai/e3": "^0.0.2-beta.27",
|
|
44
|
+
"@elaraai/e3-types": "^0.0.2-beta.27",
|
|
45
45
|
"yauzl": "^3.2.0",
|
|
46
46
|
"yazl": "^2.5.1"
|
|
47
47
|
},
|