@elaraai/e3-core 0.0.1-beta.0
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/LICENSE.md +50 -0
- package/README.md +76 -0
- package/dist/src/dataflow.d.ts +96 -0
- package/dist/src/dataflow.d.ts.map +1 -0
- package/dist/src/dataflow.js +433 -0
- package/dist/src/dataflow.js.map +1 -0
- package/dist/src/errors.d.ts +87 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +178 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/executions.d.ts +163 -0
- package/dist/src/executions.d.ts.map +1 -0
- package/dist/src/executions.js +535 -0
- package/dist/src/executions.js.map +1 -0
- package/dist/src/formats.d.ts +38 -0
- package/dist/src/formats.d.ts.map +1 -0
- package/dist/src/formats.js +115 -0
- package/dist/src/formats.js.map +1 -0
- package/dist/src/gc.d.ts +54 -0
- package/dist/src/gc.d.ts.map +1 -0
- package/dist/src/gc.js +232 -0
- package/dist/src/gc.js.map +1 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +68 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/objects.d.ts +62 -0
- package/dist/src/objects.d.ts.map +1 -0
- package/dist/src/objects.js +245 -0
- package/dist/src/objects.js.map +1 -0
- package/dist/src/packages.d.ts +85 -0
- package/dist/src/packages.d.ts.map +1 -0
- package/dist/src/packages.js +355 -0
- package/dist/src/packages.js.map +1 -0
- package/dist/src/repository.d.ts +38 -0
- package/dist/src/repository.d.ts.map +1 -0
- package/dist/src/repository.js +103 -0
- package/dist/src/repository.js.map +1 -0
- package/dist/src/tasks.d.ts +63 -0
- package/dist/src/tasks.d.ts.map +1 -0
- package/dist/src/tasks.js +145 -0
- package/dist/src/tasks.js.map +1 -0
- package/dist/src/test-helpers.d.ts +44 -0
- package/dist/src/test-helpers.d.ts.map +1 -0
- package/dist/src/test-helpers.js +141 -0
- package/dist/src/test-helpers.js.map +1 -0
- package/dist/src/trees.d.ts +156 -0
- package/dist/src/trees.d.ts.map +1 -0
- package/dist/src/trees.js +607 -0
- package/dist/src/trees.js.map +1 -0
- package/dist/src/workspaces.d.ts +116 -0
- package/dist/src/workspaces.d.ts.map +1 -0
- package/dist/src/workspaces.js +356 -0
- package/dist/src/workspaces.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs/promises';
|
|
6
|
+
import { createWriteStream } from 'fs';
|
|
7
|
+
import { Readable } from 'stream';
|
|
8
|
+
import { pipeline } from 'stream/promises';
|
|
9
|
+
import { encodeBeast2For, decodeBeast2For, parseFor, printFor, fromJSONFor, IRType, } from '@elaraai/east';
|
|
10
|
+
/**
|
|
11
|
+
* Load IR from a file (.json, .east, or .beast2)
|
|
12
|
+
*/
|
|
13
|
+
export async function loadIR(filePath) {
|
|
14
|
+
const ext = filePath.slice(filePath.lastIndexOf('.'));
|
|
15
|
+
if (ext === '.json') {
|
|
16
|
+
// JSON format
|
|
17
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
18
|
+
const jsonValue = JSON.parse(content);
|
|
19
|
+
const fromJSON = fromJSONFor(IRType);
|
|
20
|
+
return fromJSON(jsonValue);
|
|
21
|
+
}
|
|
22
|
+
else if (ext === '.east') {
|
|
23
|
+
// .east format
|
|
24
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
25
|
+
const parser = parseFor(IRType);
|
|
26
|
+
const result = parser(content);
|
|
27
|
+
if (!result.success) {
|
|
28
|
+
throw new Error(`Failed to parse .east file: ${result.error}`);
|
|
29
|
+
}
|
|
30
|
+
return result.value;
|
|
31
|
+
}
|
|
32
|
+
else if (ext === '.beast2') {
|
|
33
|
+
// .beast2 format
|
|
34
|
+
const data = await fs.readFile(filePath);
|
|
35
|
+
const decoder = decodeBeast2For(IRType);
|
|
36
|
+
return decoder(data);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw new Error(`Unsupported file format: ${ext} (expected .json, .east, or .beast2)`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Encode IR to Beast2 format
|
|
44
|
+
*/
|
|
45
|
+
export function irToBeast2(ir) {
|
|
46
|
+
const encoder = encodeBeast2For(IRType);
|
|
47
|
+
return encoder(ir);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Write a ReadableStream to a file
|
|
51
|
+
*/
|
|
52
|
+
export async function writeStreamToFile(stream, filePath) {
|
|
53
|
+
// Convert Web ReadableStream to Node.js Readable
|
|
54
|
+
const nodeStream = Readable.fromWeb(stream);
|
|
55
|
+
const writeStream = createWriteStream(filePath);
|
|
56
|
+
await pipeline(nodeStream, writeStream);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Load a value from Beast2 file
|
|
60
|
+
*/
|
|
61
|
+
export async function loadBeast2(filePath, type) {
|
|
62
|
+
const data = await fs.readFile(filePath);
|
|
63
|
+
const decoder = decodeBeast2For(type);
|
|
64
|
+
return decoder(data);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Format a value as .east format
|
|
68
|
+
*/
|
|
69
|
+
export function formatEast(value, type) {
|
|
70
|
+
const printer = printFor(type);
|
|
71
|
+
return printer(value);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parse a value from .east format
|
|
75
|
+
*/
|
|
76
|
+
export function parseEast(text, type) {
|
|
77
|
+
const parser = parseFor(type);
|
|
78
|
+
const result = parser(text);
|
|
79
|
+
if (!result.success) {
|
|
80
|
+
throw new Error(`Failed to parse .east: ${result.error}`);
|
|
81
|
+
}
|
|
82
|
+
return result.value;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Load a value from any format (.json, .east, or .beast2)
|
|
86
|
+
*/
|
|
87
|
+
export async function loadValue(filePath, type) {
|
|
88
|
+
const ext = filePath.slice(filePath.lastIndexOf('.'));
|
|
89
|
+
if (ext === '.json') {
|
|
90
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
91
|
+
const jsonValue = JSON.parse(content);
|
|
92
|
+
const fromJSON = fromJSONFor(type);
|
|
93
|
+
return fromJSON(jsonValue);
|
|
94
|
+
}
|
|
95
|
+
else if (ext === '.east') {
|
|
96
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
97
|
+
return parseEast(content, type);
|
|
98
|
+
}
|
|
99
|
+
else if (ext === '.beast2') {
|
|
100
|
+
const data = await fs.readFile(filePath);
|
|
101
|
+
const decoder = decodeBeast2For(type);
|
|
102
|
+
return decoder(data);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
throw new Error(`Unsupported file format: ${ext} (expected .json, .east, or .beast2)`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Encode a value to Beast2 format
|
|
110
|
+
*/
|
|
111
|
+
export function valueToBeast2(value, type) {
|
|
112
|
+
const encoder = encodeBeast2For(type);
|
|
113
|
+
return encoder(value);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=formats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/formats.ts"],"names":[],"mappings":"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"}
|
package/dist/src/gc.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Options for garbage collection
|
|
7
|
+
*/
|
|
8
|
+
export interface GcOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Minimum age in milliseconds for files to be considered for deletion.
|
|
11
|
+
* Files younger than this are skipped to avoid race conditions with concurrent writes.
|
|
12
|
+
* Default: 60000 (1 minute)
|
|
13
|
+
*/
|
|
14
|
+
minAge?: number;
|
|
15
|
+
/**
|
|
16
|
+
* If true, only report what would be deleted without actually deleting.
|
|
17
|
+
* Default: false
|
|
18
|
+
*/
|
|
19
|
+
dryRun?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Result of garbage collection
|
|
23
|
+
*/
|
|
24
|
+
export interface GcResult {
|
|
25
|
+
/**
|
|
26
|
+
* Number of objects deleted
|
|
27
|
+
*/
|
|
28
|
+
deletedObjects: number;
|
|
29
|
+
/**
|
|
30
|
+
* Number of orphaned staging files deleted
|
|
31
|
+
*/
|
|
32
|
+
deletedPartials: number;
|
|
33
|
+
/**
|
|
34
|
+
* Number of objects retained
|
|
35
|
+
*/
|
|
36
|
+
retainedObjects: number;
|
|
37
|
+
/**
|
|
38
|
+
* Number of files skipped due to being too young
|
|
39
|
+
*/
|
|
40
|
+
skippedYoung: number;
|
|
41
|
+
/**
|
|
42
|
+
* Total bytes freed
|
|
43
|
+
*/
|
|
44
|
+
bytesFreed: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Run garbage collection on an e3 repository.
|
|
48
|
+
*
|
|
49
|
+
* @param repoPath - Path to .e3 repository
|
|
50
|
+
* @param options - GC options
|
|
51
|
+
* @returns GC result with statistics
|
|
52
|
+
*/
|
|
53
|
+
export declare function repoGc(repoPath: string, options?: GcOptions): Promise<GcResult>;
|
|
54
|
+
//# sourceMappingURL=gc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gc.d.ts","sourceRoot":"","sources":["../../src/gc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH;;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;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,MAAM,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,SAAc,GACtB,OAAO,CAAC,QAAQ,CAAC,CAkBnB"}
|
package/dist/src/gc.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Garbage collection for e3 repositories.
|
|
7
|
+
*
|
|
8
|
+
* Uses mark-and-sweep algorithm:
|
|
9
|
+
* 1. Mark: Find all root refs (packages, executions, workspaces) and trace reachable objects
|
|
10
|
+
* 2. Sweep: Delete unreachable objects and orphaned staging files
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'fs/promises';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
import { decodeBeast2For } from '@elaraai/east';
|
|
15
|
+
import { WorkspaceStateType } from '@elaraai/e3-types';
|
|
16
|
+
import { objectRead } from './objects.js';
|
|
17
|
+
/**
|
|
18
|
+
* Run garbage collection on an e3 repository.
|
|
19
|
+
*
|
|
20
|
+
* @param repoPath - Path to .e3 repository
|
|
21
|
+
* @param options - GC options
|
|
22
|
+
* @returns GC result with statistics
|
|
23
|
+
*/
|
|
24
|
+
export async function repoGc(repoPath, options = {}) {
|
|
25
|
+
const minAge = options.minAge ?? 60000; // Default 1 minute
|
|
26
|
+
const dryRun = options.dryRun ?? false;
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
// Step 1: Collect all root hashes
|
|
29
|
+
const roots = await collectRoots(repoPath);
|
|
30
|
+
// Step 2: Mark all reachable objects starting from roots
|
|
31
|
+
const reachable = new Set();
|
|
32
|
+
for (const root of roots) {
|
|
33
|
+
await markReachable(repoPath, root, reachable);
|
|
34
|
+
}
|
|
35
|
+
// Step 3: Sweep - enumerate all objects and delete unreachable ones
|
|
36
|
+
const result = await sweep(repoPath, reachable, minAge, now, dryRun);
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Collect all root hashes from refs in packages, executions, and workspaces.
|
|
41
|
+
*/
|
|
42
|
+
async function collectRoots(repoPath) {
|
|
43
|
+
const roots = new Set();
|
|
44
|
+
// Collect from packages/<name>/<version> files
|
|
45
|
+
const packagesDir = path.join(repoPath, 'packages');
|
|
46
|
+
await collectRefsFromDir(packagesDir, roots, 2); // depth 2: packages/<name>/<version>
|
|
47
|
+
// Collect from executions/<taskHash>/<inputsHash>/output files
|
|
48
|
+
const executionsDir = path.join(repoPath, 'executions');
|
|
49
|
+
await collectRefsFromDir(executionsDir, roots, 3); // depth 3: executions/<taskHash>/<inputsHash>/output
|
|
50
|
+
// Collect from workspaces/<name>/state.beast2 files
|
|
51
|
+
const workspacesDir = path.join(repoPath, 'workspaces');
|
|
52
|
+
await collectWorkspaceRoots(workspacesDir, roots);
|
|
53
|
+
return roots;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Collect root hashes from workspace state files.
|
|
57
|
+
*/
|
|
58
|
+
async function collectWorkspaceRoots(workspacesDir, roots) {
|
|
59
|
+
try {
|
|
60
|
+
const entries = await fs.readdir(workspacesDir);
|
|
61
|
+
for (const entry of entries) {
|
|
62
|
+
if (!entry.endsWith('.beast2'))
|
|
63
|
+
continue;
|
|
64
|
+
const stateFile = path.join(workspacesDir, entry);
|
|
65
|
+
try {
|
|
66
|
+
const data = await fs.readFile(stateFile);
|
|
67
|
+
// Skip empty files (undeployed workspaces)
|
|
68
|
+
if (data.length === 0)
|
|
69
|
+
continue;
|
|
70
|
+
const decoder = decodeBeast2For(WorkspaceStateType);
|
|
71
|
+
const state = decoder(data);
|
|
72
|
+
// Add both the package hash and root hash as roots
|
|
73
|
+
roots.add(state.packageHash);
|
|
74
|
+
roots.add(state.rootHash);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// State file can't be parsed - skip
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Workspaces directory doesn't exist
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Recursively collect hashes from ref files in a directory.
|
|
87
|
+
*
|
|
88
|
+
* @param dir - Directory to scan
|
|
89
|
+
* @param roots - Set to add found hashes to
|
|
90
|
+
* @param maxDepth - Maximum depth to traverse
|
|
91
|
+
*/
|
|
92
|
+
async function collectRefsFromDir(dir, roots, maxDepth, currentDepth = 0) {
|
|
93
|
+
try {
|
|
94
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
95
|
+
for (const entry of entries) {
|
|
96
|
+
const entryPath = path.join(dir, entry.name);
|
|
97
|
+
if (entry.isDirectory() && currentDepth < maxDepth) {
|
|
98
|
+
await collectRefsFromDir(entryPath, roots, maxDepth, currentDepth + 1);
|
|
99
|
+
}
|
|
100
|
+
else if (entry.isFile()) {
|
|
101
|
+
// Read the ref file - it contains a hash
|
|
102
|
+
try {
|
|
103
|
+
const content = await fs.readFile(entryPath, 'utf-8');
|
|
104
|
+
const hash = content.trim();
|
|
105
|
+
// Validate it looks like a SHA256 hash
|
|
106
|
+
if (/^[a-f0-9]{64}$/.test(hash)) {
|
|
107
|
+
roots.add(hash);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Skip files we can't read
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Directory doesn't exist or can't be read - that's fine
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Mark all objects reachable from a root hash.
|
|
122
|
+
*
|
|
123
|
+
* Traverses the object graph by scanning for hash patterns in the data.
|
|
124
|
+
*/
|
|
125
|
+
async function markReachable(repoPath, hash, reachable) {
|
|
126
|
+
// Already visited?
|
|
127
|
+
if (reachable.has(hash)) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
// Try to load the object
|
|
131
|
+
try {
|
|
132
|
+
const data = await objectRead(repoPath, hash);
|
|
133
|
+
reachable.add(hash);
|
|
134
|
+
// Scan for hash patterns in the data
|
|
135
|
+
const dataStr = Buffer.from(data).toString('latin1');
|
|
136
|
+
const hashPattern = /[a-f0-9]{64}/g;
|
|
137
|
+
const matches = dataStr.matchAll(hashPattern);
|
|
138
|
+
for (const match of matches) {
|
|
139
|
+
const potentialHash = match[0];
|
|
140
|
+
if (!reachable.has(potentialHash)) {
|
|
141
|
+
// Recursively mark if it exists
|
|
142
|
+
await markReachable(repoPath, potentialHash, reachable);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Object doesn't exist - not an error, just means this hash
|
|
148
|
+
// wasn't actually a reference to an object
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Sweep unreachable objects and orphaned staging files.
|
|
153
|
+
*/
|
|
154
|
+
async function sweep(repoPath, reachable, minAge, now, dryRun) {
|
|
155
|
+
const objectsDir = path.join(repoPath, 'objects');
|
|
156
|
+
const result = {
|
|
157
|
+
deletedObjects: 0,
|
|
158
|
+
deletedPartials: 0,
|
|
159
|
+
retainedObjects: 0,
|
|
160
|
+
skippedYoung: 0,
|
|
161
|
+
bytesFreed: 0,
|
|
162
|
+
};
|
|
163
|
+
try {
|
|
164
|
+
// Iterate through objects/xx/ directories
|
|
165
|
+
const subdirs = await fs.readdir(objectsDir);
|
|
166
|
+
for (const subdir of subdirs) {
|
|
167
|
+
// Skip if not a 2-char hex directory
|
|
168
|
+
if (!/^[a-f0-9]{2}$/.test(subdir)) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const subdirPath = path.join(objectsDir, subdir);
|
|
172
|
+
const stat = await fs.stat(subdirPath);
|
|
173
|
+
if (!stat.isDirectory()) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const files = await fs.readdir(subdirPath);
|
|
177
|
+
for (const file of files) {
|
|
178
|
+
const filePath = path.join(subdirPath, file);
|
|
179
|
+
try {
|
|
180
|
+
const fileStat = await fs.stat(filePath);
|
|
181
|
+
// Check age - skip young files to avoid race with concurrent writes
|
|
182
|
+
const age = now - fileStat.mtimeMs;
|
|
183
|
+
if (age < minAge) {
|
|
184
|
+
result.skippedYoung++;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
// Handle .partial staging files
|
|
188
|
+
if (file.endsWith('.partial')) {
|
|
189
|
+
if (!dryRun) {
|
|
190
|
+
await fs.unlink(filePath);
|
|
191
|
+
}
|
|
192
|
+
result.deletedPartials++;
|
|
193
|
+
result.bytesFreed += fileStat.size;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
// Handle .beast2 object files
|
|
197
|
+
if (file.endsWith('.beast2')) {
|
|
198
|
+
// Reconstruct the hash: subdir (2 chars) + filename without extension
|
|
199
|
+
const hash = subdir + file.slice(0, -7); // -7 removes '.beast2'
|
|
200
|
+
if (reachable.has(hash)) {
|
|
201
|
+
result.retainedObjects++;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
if (!dryRun) {
|
|
205
|
+
await fs.unlink(filePath);
|
|
206
|
+
}
|
|
207
|
+
result.deletedObjects++;
|
|
208
|
+
result.bytesFreed += fileStat.size;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
// Skip files we can't stat or delete
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Try to remove empty subdirectory
|
|
217
|
+
if (!dryRun) {
|
|
218
|
+
try {
|
|
219
|
+
await fs.rmdir(subdirPath);
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// Directory not empty, that's fine
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Objects directory doesn't exist or can't be read
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=gc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gc.js","sourceRoot":"","sources":["../../src/gc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* e3 Core - Programmatic API for e3 repository operations
|
|
7
|
+
*
|
|
8
|
+
* This package provides the filesystem-based business logic for e3,
|
|
9
|
+
* similar to libgit2 for git. It has no UI dependencies and can be
|
|
10
|
+
* used programmatically.
|
|
11
|
+
*/
|
|
12
|
+
export { repoInit, repoFind, repoGet, type InitRepositoryResult, } from './repository.js';
|
|
13
|
+
export { repoGc, type GcOptions, type GcResult } from './gc.js';
|
|
14
|
+
export { computeHash, objectWrite, objectWriteStream, objectRead, objectExists, objectPath, objectAbbrev, } from './objects.js';
|
|
15
|
+
export { packageImport, packageExport, packageRemove, packageList, packageResolve, packageRead, type PackageImportResult, type PackageExportResult, } from './packages.js';
|
|
16
|
+
export { workspaceCreate, workspaceRemove, workspaceList, workspaceGetState, workspaceGetPackage, workspaceGetRoot, workspaceSetRoot, workspaceDeploy, workspaceExport, type WorkspaceExportResult, } from './workspaces.js';
|
|
17
|
+
export { treeRead, treeWrite, datasetRead, datasetWrite, type TreeObject, } from './trees.js';
|
|
18
|
+
export { packageListTree, packageGetDataset, workspaceListTree, workspaceGetDataset, workspaceGetDatasetHash, workspaceSetDataset, workspaceSetDatasetByHash, } from './trees.js';
|
|
19
|
+
export { packageListTasks, packageGetTask, workspaceListTasks, workspaceGetTask, workspaceGetTaskHash, } from './tasks.js';
|
|
20
|
+
export { inputsHash, executionPath, executionGet, executionGetOutput, executionListForTask, executionList, executionReadLog, type LogReadOptions, type LogChunk, evaluateCommandIr, isProcessAlive, taskExecute, type ExecuteOptions, type ExecutionResult, } from './executions.js';
|
|
21
|
+
export { dataflowExecute, dataflowGetGraph, type DataflowOptions, type DataflowResult, type TaskExecutionResult, } from './dataflow.js';
|
|
22
|
+
export { E3Error, RepositoryNotFoundError, WorkspaceNotFoundError, WorkspaceNotDeployedError, WorkspaceExistsError, PackageNotFoundError, PackageInvalidError, PackageExistsError, DatasetNotFoundError, TaskNotFoundError, ObjectNotFoundError, ObjectCorruptError, ExecutionCorruptError, DataflowError, PermissionDeniedError, isNotFoundError, isPermissionError, isExistsError, wrapError, } from './errors.js';
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAGH,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,KAAK,oBAAoB,GAC1B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGhE,OAAO,EACL,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,GACb,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,WAAW,EACX,cAAc,EACd,WAAW,EACX,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,eAAe,EACf,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,KAAK,qBAAqB,GAC3B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,YAAY,EACZ,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAEL,UAAU,EACV,aAAa,EAEb,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EAEb,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,QAAQ,EAEb,iBAAiB,EAEjB,cAAc,EAEd,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,mBAAmB,GACzB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAEL,OAAO,EAEP,uBAAuB,EAEvB,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,EAEpB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAElB,oBAAoB,EAEpB,iBAAiB,EAEjB,mBAAmB,EACnB,kBAAkB,EAElB,qBAAqB,EAErB,aAAa,EAEb,qBAAqB,EAErB,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,SAAS,GACV,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* e3 Core - Programmatic API for e3 repository operations
|
|
7
|
+
*
|
|
8
|
+
* This package provides the filesystem-based business logic for e3,
|
|
9
|
+
* similar to libgit2 for git. It has no UI dependencies and can be
|
|
10
|
+
* used programmatically.
|
|
11
|
+
*/
|
|
12
|
+
// Repository management
|
|
13
|
+
export { repoInit, repoFind, repoGet, } from './repository.js';
|
|
14
|
+
// Garbage collection
|
|
15
|
+
export { repoGc } from './gc.js';
|
|
16
|
+
// Object storage
|
|
17
|
+
export { computeHash, objectWrite, objectWriteStream, objectRead, objectExists, objectPath, objectAbbrev, } from './objects.js';
|
|
18
|
+
// Package operations
|
|
19
|
+
export { packageImport, packageExport, packageRemove, packageList, packageResolve, packageRead, } from './packages.js';
|
|
20
|
+
// Workspace operations
|
|
21
|
+
export { workspaceCreate, workspaceRemove, workspaceList, workspaceGetState, workspaceGetPackage, workspaceGetRoot, workspaceSetRoot, workspaceDeploy, workspaceExport, } from './workspaces.js';
|
|
22
|
+
// Tree and dataset operations (low-level, by hash)
|
|
23
|
+
export { treeRead, treeWrite, datasetRead, datasetWrite, } from './trees.js';
|
|
24
|
+
// Tree and dataset operations (high-level, by path)
|
|
25
|
+
export { packageListTree, packageGetDataset, workspaceListTree, workspaceGetDataset, workspaceGetDatasetHash, workspaceSetDataset, workspaceSetDatasetByHash, } from './trees.js';
|
|
26
|
+
// Task operations
|
|
27
|
+
export { packageListTasks, packageGetTask, workspaceListTasks, workspaceGetTask, workspaceGetTaskHash, } from './tasks.js';
|
|
28
|
+
// Execution operations
|
|
29
|
+
export {
|
|
30
|
+
// Identity
|
|
31
|
+
inputsHash, executionPath,
|
|
32
|
+
// Status
|
|
33
|
+
executionGet, executionGetOutput, executionListForTask, executionList,
|
|
34
|
+
// Logs
|
|
35
|
+
executionReadLog,
|
|
36
|
+
// Command IR evaluation
|
|
37
|
+
evaluateCommandIr,
|
|
38
|
+
// Process detection
|
|
39
|
+
isProcessAlive,
|
|
40
|
+
// Execution
|
|
41
|
+
taskExecute, } from './executions.js';
|
|
42
|
+
// Dataflow execution
|
|
43
|
+
export { dataflowExecute, dataflowGetGraph, } from './dataflow.js';
|
|
44
|
+
// Errors
|
|
45
|
+
export {
|
|
46
|
+
// Base
|
|
47
|
+
E3Error,
|
|
48
|
+
// Repository
|
|
49
|
+
RepositoryNotFoundError,
|
|
50
|
+
// Workspace
|
|
51
|
+
WorkspaceNotFoundError, WorkspaceNotDeployedError, WorkspaceExistsError,
|
|
52
|
+
// Package
|
|
53
|
+
PackageNotFoundError, PackageInvalidError, PackageExistsError,
|
|
54
|
+
// Dataset
|
|
55
|
+
DatasetNotFoundError,
|
|
56
|
+
// Task
|
|
57
|
+
TaskNotFoundError,
|
|
58
|
+
// Object
|
|
59
|
+
ObjectNotFoundError, ObjectCorruptError,
|
|
60
|
+
// Execution
|
|
61
|
+
ExecutionCorruptError,
|
|
62
|
+
// Dataflow
|
|
63
|
+
DataflowError,
|
|
64
|
+
// Generic
|
|
65
|
+
PermissionDeniedError,
|
|
66
|
+
// Helpers
|
|
67
|
+
isNotFoundError, isPermissionError, isExistsError, wrapError, } from './errors.js';
|
|
68
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH,wBAAwB;AACxB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,OAAO,GAER,MAAM,iBAAiB,CAAC;AAEzB,qBAAqB;AACrB,OAAO,EAAE,MAAM,EAAiC,MAAM,SAAS,CAAC;AAEhE,iBAAiB;AACjB,OAAO,EACL,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,qBAAqB;AACrB,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,WAAW,EACX,cAAc,EACd,WAAW,GAGZ,MAAM,eAAe,CAAC;AAEvB,uBAAuB;AACvB,OAAO,EACL,eAAe,EACf,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAEhB,MAAM,iBAAiB,CAAC;AAEzB,mDAAmD;AACnD,OAAO,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,YAAY,GAEb,MAAM,YAAY,CAAC;AAEpB,oDAAoD;AACpD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AAEpB,kBAAkB;AAClB,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,uBAAuB;AACvB,OAAO;AACL,WAAW;AACX,UAAU,EACV,aAAa;AACb,SAAS;AACT,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EACpB,aAAa;AACb,OAAO;AACP,gBAAgB;AAGhB,wBAAwB;AACxB,iBAAiB;AACjB,oBAAoB;AACpB,cAAc;AACd,YAAY;AACZ,WAAW,GAGZ,MAAM,iBAAiB,CAAC;AAEzB,qBAAqB;AACrB,OAAO,EACL,eAAe,EACf,gBAAgB,GAIjB,MAAM,eAAe,CAAC;AAEvB,SAAS;AACT,OAAO;AACL,OAAO;AACP,OAAO;AACP,aAAa;AACb,uBAAuB;AACvB,YAAY;AACZ,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB;AACpB,UAAU;AACV,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB;AAClB,UAAU;AACV,oBAAoB;AACpB,OAAO;AACP,iBAAiB;AACjB,SAAS;AACT,mBAAmB,EACnB,kBAAkB;AAClB,YAAY;AACZ,qBAAqB;AACrB,WAAW;AACX,aAAa;AACb,UAAU;AACV,qBAAqB;AACrB,UAAU;AACV,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,SAAS,GACV,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Calculate SHA256 hash of data
|
|
7
|
+
*/
|
|
8
|
+
export declare function computeHash(data: Uint8Array): string;
|
|
9
|
+
/**
|
|
10
|
+
* Atomically write an object to the repository
|
|
11
|
+
*
|
|
12
|
+
* @param repoPath - Path to .e3 repository
|
|
13
|
+
* @param data - Data to store
|
|
14
|
+
* @returns SHA256 hash of the data
|
|
15
|
+
*/
|
|
16
|
+
export declare function objectWrite(repoPath: string, data: Uint8Array): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Atomically write a stream to the repository
|
|
19
|
+
*
|
|
20
|
+
* @param repoPath - Path to .e3 repository
|
|
21
|
+
* @param stream - Stream to store
|
|
22
|
+
* @returns SHA256 hash of the data
|
|
23
|
+
*/
|
|
24
|
+
export declare function objectWriteStream(repoPath: string, stream: ReadableStream<Uint8Array>): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Read an object from the repository
|
|
27
|
+
*
|
|
28
|
+
* @param repoPath - Path to .e3 repository
|
|
29
|
+
* @param hash - SHA256 hash of the object
|
|
30
|
+
* @returns Object data
|
|
31
|
+
* @throws {ObjectNotFoundError} If object not found
|
|
32
|
+
*/
|
|
33
|
+
export declare function objectRead(repoPath: string, hash: string): Promise<Uint8Array>;
|
|
34
|
+
/**
|
|
35
|
+
* Check if an object exists in the repository
|
|
36
|
+
*
|
|
37
|
+
* @param repoPath - Path to .e3 repository
|
|
38
|
+
* @param hash - SHA256 hash of the object
|
|
39
|
+
* @returns true if object exists
|
|
40
|
+
*/
|
|
41
|
+
export declare function objectExists(repoPath: string, hash: string): Promise<boolean>;
|
|
42
|
+
/**
|
|
43
|
+
* Get the filesystem path for an object
|
|
44
|
+
*
|
|
45
|
+
* @param repoPath - Path to .e3 repository
|
|
46
|
+
* @param hash - SHA256 hash of the object
|
|
47
|
+
* @returns Filesystem path: objects/<hash[0..2]>/<hash[2..]>.beast2
|
|
48
|
+
*/
|
|
49
|
+
export declare function objectPath(repoPath: string, hash: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Get the minimum unambiguous prefix length for an object hash.
|
|
52
|
+
*
|
|
53
|
+
* Scans the object store to find the shortest prefix of the given hash
|
|
54
|
+
* that uniquely identifies it among all stored objects.
|
|
55
|
+
*
|
|
56
|
+
* @param repoPath - Path to .e3 repository
|
|
57
|
+
* @param hash - Full SHA256 hash of the object
|
|
58
|
+
* @param minLength - Minimum prefix length to return (default: 4)
|
|
59
|
+
* @returns Minimum unambiguous prefix length
|
|
60
|
+
*/
|
|
61
|
+
export declare function objectAbbrev(repoPath: string, hash: string, minLength?: number): Promise<number>;
|
|
62
|
+
//# sourceMappingURL=objects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objects.d.ts","sourceRoot":"","sources":["../../src/objects.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEpD;AA4BD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,CAiDjB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC,CAuDjB;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,CAerB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CASlB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIjE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAU,GACpB,OAAO,CAAC,MAAM,CAAC,CAwCjB"}
|