@elaraai/e3-api-server 0.0.2-beta.3 → 0.0.2-beta.30

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 (107) hide show
  1. package/README.md +145 -30
  2. package/dist/src/async-operation-state.d.ts +37 -0
  3. package/dist/src/async-operation-state.d.ts.map +1 -0
  4. package/dist/src/async-operation-state.js +118 -0
  5. package/dist/src/async-operation-state.js.map +1 -0
  6. package/dist/src/auth/device.d.ts +26 -0
  7. package/dist/src/auth/device.d.ts.map +1 -0
  8. package/dist/src/auth/device.js +227 -0
  9. package/dist/src/auth/device.js.map +1 -0
  10. package/dist/src/auth/discovery.d.ts +23 -0
  11. package/dist/src/auth/discovery.d.ts.map +1 -0
  12. package/dist/src/auth/discovery.js +40 -0
  13. package/dist/src/auth/discovery.js.map +1 -0
  14. package/dist/src/auth/index.d.ts +56 -0
  15. package/dist/src/auth/index.d.ts.map +1 -0
  16. package/dist/src/auth/index.js +69 -0
  17. package/dist/src/auth/index.js.map +1 -0
  18. package/dist/src/auth/keys.d.ts +55 -0
  19. package/dist/src/auth/keys.d.ts.map +1 -0
  20. package/dist/src/auth/keys.js +78 -0
  21. package/dist/src/auth/keys.js.map +1 -0
  22. package/dist/src/beast2.d.ts +15 -3
  23. package/dist/src/beast2.d.ts.map +1 -1
  24. package/dist/src/beast2.js +30 -4
  25. package/dist/src/beast2.js.map +1 -1
  26. package/dist/src/cli.js +58 -6
  27. package/dist/src/cli.js.map +1 -1
  28. package/dist/src/errors.d.ts.map +1 -1
  29. package/dist/src/errors.js +8 -2
  30. package/dist/src/errors.js.map +1 -1
  31. package/dist/src/handlers/dataflow.d.ts +43 -0
  32. package/dist/src/handlers/dataflow.d.ts.map +1 -0
  33. package/dist/src/handlers/dataflow.js +363 -0
  34. package/dist/src/handlers/dataflow.js.map +1 -0
  35. package/dist/src/handlers/datasets.d.ts +23 -0
  36. package/dist/src/handlers/datasets.d.ts.map +1 -0
  37. package/dist/src/handlers/datasets.js +113 -0
  38. package/dist/src/handlers/datasets.js.map +1 -0
  39. package/dist/src/handlers/index.d.ts +11 -0
  40. package/dist/src/handlers/index.d.ts.map +1 -0
  41. package/dist/src/handlers/index.js +11 -0
  42. package/dist/src/handlers/index.js.map +1 -0
  43. package/dist/src/handlers/packages.d.ts +26 -0
  44. package/dist/src/handlers/packages.d.ts.map +1 -0
  45. package/dist/src/handlers/packages.js +101 -0
  46. package/dist/src/handlers/packages.js.map +1 -0
  47. package/dist/src/handlers/repository.d.ts +24 -0
  48. package/dist/src/handlers/repository.d.ts.map +1 -0
  49. package/dist/src/handlers/repository.js +79 -0
  50. package/dist/src/handlers/repository.js.map +1 -0
  51. package/dist/src/handlers/tasks.d.ts +18 -0
  52. package/dist/src/handlers/tasks.d.ts.map +1 -0
  53. package/dist/src/handlers/tasks.js +134 -0
  54. package/dist/src/handlers/tasks.js.map +1 -0
  55. package/dist/src/handlers/workspaces.d.ts +34 -0
  56. package/dist/src/handlers/workspaces.d.ts.map +1 -0
  57. package/dist/src/handlers/workspaces.js +225 -0
  58. package/dist/src/handlers/workspaces.js.map +1 -0
  59. package/dist/src/index.d.ts +3 -0
  60. package/dist/src/index.d.ts.map +1 -1
  61. package/dist/src/index.js +6 -0
  62. package/dist/src/index.js.map +1 -1
  63. package/dist/src/middleware/auth.d.ts +51 -0
  64. package/dist/src/middleware/auth.d.ts.map +1 -0
  65. package/dist/src/middleware/auth.js +158 -0
  66. package/dist/src/middleware/auth.js.map +1 -0
  67. package/dist/src/orchestrator-manager.d.ts +45 -0
  68. package/dist/src/orchestrator-manager.d.ts.map +1 -0
  69. package/dist/src/orchestrator-manager.js +150 -0
  70. package/dist/src/orchestrator-manager.js.map +1 -0
  71. package/dist/src/routes/datasets.d.ts +2 -1
  72. package/dist/src/routes/datasets.d.ts.map +1 -1
  73. package/dist/src/routes/datasets.js +50 -85
  74. package/dist/src/routes/datasets.js.map +1 -1
  75. package/dist/src/routes/executions.d.ts +2 -1
  76. package/dist/src/routes/executions.d.ts.map +1 -1
  77. package/dist/src/routes/executions.js +54 -287
  78. package/dist/src/routes/executions.js.map +1 -1
  79. package/dist/src/routes/index.d.ts +11 -0
  80. package/dist/src/routes/index.d.ts.map +1 -0
  81. package/dist/src/routes/index.js +11 -0
  82. package/dist/src/routes/index.js.map +1 -0
  83. package/dist/src/routes/packages.d.ts +2 -1
  84. package/dist/src/routes/packages.d.ts.map +1 -1
  85. package/dist/src/routes/packages.js +42 -105
  86. package/dist/src/routes/packages.js.map +1 -1
  87. package/dist/src/routes/repository.d.ts +2 -1
  88. package/dist/src/routes/repository.d.ts.map +1 -1
  89. package/dist/src/routes/repository.js +19 -54
  90. package/dist/src/routes/repository.js.map +1 -1
  91. package/dist/src/routes/tasks.d.ts +2 -1
  92. package/dist/src/routes/tasks.d.ts.map +1 -1
  93. package/dist/src/routes/tasks.js +22 -46
  94. package/dist/src/routes/tasks.js.map +1 -1
  95. package/dist/src/routes/workspaces.d.ts +2 -1
  96. package/dist/src/routes/workspaces.d.ts.map +1 -1
  97. package/dist/src/routes/workspaces.js +45 -116
  98. package/dist/src/routes/workspaces.js.map +1 -1
  99. package/dist/src/server.d.ts +24 -3
  100. package/dist/src/server.d.ts.map +1 -1
  101. package/dist/src/server.js +238 -19
  102. package/dist/src/server.js.map +1 -1
  103. package/dist/src/types.d.ts +1197 -721
  104. package/dist/src/types.d.ts.map +1 -1
  105. package/dist/src/types.js +192 -2
  106. package/dist/src/types.js.map +1 -1
  107. package/package.json +16 -4
@@ -0,0 +1,101 @@
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 'node:fs/promises';
6
+ import * as os from 'node:os';
7
+ import * as path from 'node:path';
8
+ import { ArrayType, BlobType, NullType } from '@elaraai/east';
9
+ import { packageList, packageImport, packageExport, packageRemove, packageRead, } from '@elaraai/e3-core';
10
+ import { PackageObjectType } from '@elaraai/e3-types';
11
+ import { sendSuccess, sendError } from '../beast2.js';
12
+ import { errorToVariant } from '../errors.js';
13
+ import { PackageListItemType, PackageImportResultType } from '../types.js';
14
+ /**
15
+ * List all packages in the repository.
16
+ */
17
+ export async function listPackages(storage, repoPath) {
18
+ try {
19
+ const packages = await packageList(storage, repoPath);
20
+ const result = packages.map((pkg) => ({
21
+ name: pkg.name,
22
+ version: pkg.version,
23
+ }));
24
+ return sendSuccess(ArrayType(PackageListItemType), result);
25
+ }
26
+ catch (err) {
27
+ return sendError(ArrayType(PackageListItemType), errorToVariant(err));
28
+ }
29
+ }
30
+ /**
31
+ * Get package details.
32
+ */
33
+ export async function getPackage(storage, repoPath, name, version) {
34
+ try {
35
+ const pkg = await packageRead(storage, repoPath, name, version);
36
+ return sendSuccess(PackageObjectType, pkg);
37
+ }
38
+ catch (err) {
39
+ return sendError(PackageObjectType, errorToVariant(err));
40
+ }
41
+ }
42
+ /**
43
+ * Import a package from a zip archive.
44
+ */
45
+ export async function importPackage(storage, repoPath, archive) {
46
+ try {
47
+ // Write to temp file
48
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'e3-import-'));
49
+ const tempPath = path.join(tempDir, 'package.zip');
50
+ try {
51
+ await fs.writeFile(tempPath, archive);
52
+ const result = await packageImport(storage, repoPath, tempPath);
53
+ return sendSuccess(PackageImportResultType, {
54
+ name: result.name,
55
+ version: result.version,
56
+ packageHash: result.packageHash,
57
+ objectCount: BigInt(result.objectCount),
58
+ });
59
+ }
60
+ finally {
61
+ await fs.rm(tempDir, { recursive: true, force: true });
62
+ }
63
+ }
64
+ catch (err) {
65
+ return sendError(PackageImportResultType, errorToVariant(err));
66
+ }
67
+ }
68
+ /**
69
+ * Export a package as a zip archive.
70
+ */
71
+ export async function exportPackage(storage, repoPath, name, version) {
72
+ try {
73
+ // Export to temp file
74
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'e3-export-'));
75
+ const tempPath = path.join(tempDir, 'package.zip');
76
+ try {
77
+ await packageExport(storage, repoPath, name, version, tempPath);
78
+ const archive = await fs.readFile(tempPath);
79
+ return sendSuccess(BlobType, new Uint8Array(archive));
80
+ }
81
+ finally {
82
+ await fs.rm(tempDir, { recursive: true, force: true });
83
+ }
84
+ }
85
+ catch (err) {
86
+ return sendError(BlobType, errorToVariant(err));
87
+ }
88
+ }
89
+ /**
90
+ * Delete a package.
91
+ */
92
+ export async function deletePackage(storage, repoPath, name, version) {
93
+ try {
94
+ await packageRemove(storage, repoPath, name, version);
95
+ return sendSuccess(NullType, null);
96
+ }
97
+ catch (err) {
98
+ return sendError(NullType, errorToVariant(err));
99
+ }
100
+ }
101
+ //# sourceMappingURL=packages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packages.js","sourceRoot":"","sources":["../../../src/handlers/packages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { StorageBackend } from '@elaraai/e3-core';
6
+ /**
7
+ * Get repository status.
8
+ */
9
+ export declare function getStatus(storage: StorageBackend, repoPath: string): Promise<Response>;
10
+ /**
11
+ * Start garbage collection (async).
12
+ *
13
+ * Returns immediately with an executionId. GC runs in background.
14
+ * Poll getGcStatus() for progress.
15
+ */
16
+ export declare function startGc(storage: StorageBackend, repoPath: string, options: {
17
+ dryRun: boolean;
18
+ minAge?: number;
19
+ }): Response;
20
+ /**
21
+ * Get garbage collection status.
22
+ */
23
+ export declare function getGcStatus(executionId: string): Response;
24
+ //# sourceMappingURL=repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../src/handlers/repository.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAgBvD;;GAEG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,QAAQ,CAAC,CAmBnB;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CACrB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5C,QAAQ,CAuBV;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAezD"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import { variant } from '@elaraai/east';
6
+ import { repoGc, packageList, workspaceList } from '@elaraai/e3-core';
7
+ import { sendSuccess, sendSuccessWithStatus, sendError } from '../beast2.js';
8
+ import { errorToVariant } from '../errors.js';
9
+ import { RepositoryStatusType, GcStartResultType, GcStatusResultType, } from '../types.js';
10
+ import { createGcOperation, completeGcOperation, failGcOperation, getGcOperationStatus, hasGcOperation, } from '../async-operation-state.js';
11
+ /**
12
+ * Get repository status.
13
+ */
14
+ export async function getStatus(storage, repoPath) {
15
+ try {
16
+ // Count objects
17
+ const objectCount = await storage.objects.count(repoPath);
18
+ // Count packages and workspaces
19
+ const packages = await packageList(storage, repoPath);
20
+ const workspaces = await workspaceList(storage, repoPath);
21
+ const status = {
22
+ path: repoPath,
23
+ objectCount: BigInt(objectCount),
24
+ packageCount: BigInt(packages.length),
25
+ workspaceCount: BigInt(workspaces.length),
26
+ };
27
+ return sendSuccess(RepositoryStatusType, status);
28
+ }
29
+ catch (err) {
30
+ return sendError(RepositoryStatusType, errorToVariant(err));
31
+ }
32
+ }
33
+ /**
34
+ * Start garbage collection (async).
35
+ *
36
+ * Returns immediately with an executionId. GC runs in background.
37
+ * Poll getGcStatus() for progress.
38
+ */
39
+ export function startGc(storage, repoPath, options) {
40
+ // Create operation and get executionId
41
+ const executionId = createGcOperation();
42
+ // Run GC in background (don't await)
43
+ void (async () => {
44
+ try {
45
+ const result = await repoGc(storage, repoPath, options);
46
+ completeGcOperation(executionId, {
47
+ deletedObjects: BigInt(result.deletedObjects),
48
+ deletedPartials: BigInt(result.deletedPartials),
49
+ retainedObjects: BigInt(result.retainedObjects),
50
+ skippedYoung: BigInt(result.skippedYoung),
51
+ bytesFreed: BigInt(result.bytesFreed),
52
+ });
53
+ }
54
+ catch (err) {
55
+ const message = err instanceof Error ? err.message : String(err);
56
+ failGcOperation(executionId, message);
57
+ }
58
+ })();
59
+ // Return 202 Accepted with executionId
60
+ return sendSuccessWithStatus(GcStartResultType, { executionId }, 202);
61
+ }
62
+ /**
63
+ * Get garbage collection status.
64
+ */
65
+ export function getGcStatus(executionId) {
66
+ if (!hasGcOperation(executionId)) {
67
+ return sendError(GcStatusResultType, variant('internal', {
68
+ message: `GC operation not found: ${executionId}`,
69
+ }));
70
+ }
71
+ const status = getGcOperationStatus(executionId);
72
+ if (!status) {
73
+ return sendError(GcStatusResultType, variant('internal', {
74
+ message: `GC operation not found: ${executionId}`,
75
+ }));
76
+ }
77
+ return sendSuccess(GcStatusResultType, status);
78
+ }
79
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/handlers/repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { StorageBackend } from '@elaraai/e3-core';
6
+ /**
7
+ * List all tasks in a workspace.
8
+ */
9
+ export declare function listTasks(storage: StorageBackend, repoPath: string, workspace: string): Promise<Response>;
10
+ /**
11
+ * Get task details.
12
+ */
13
+ export declare function getTask(storage: StorageBackend, repoPath: string, workspace: string, taskName: string): Promise<Response>;
14
+ /**
15
+ * List execution history for a task.
16
+ */
17
+ export declare function listExecutions(storage: StorageBackend, repoPath: string, workspace: string, taskName: string): Promise<Response>;
18
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/handlers/tasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD;;GAEG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,CAAC,CAgBnB;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,QAAQ,CAAC,CAenB;AAyBD;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,QAAQ,CAAC,CA+DnB"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import { ArrayType, none, some, variant } from '@elaraai/east';
6
+ import { workspaceListTasks, workspaceGetTask, workspaceGetTaskHash, executionListForTask, executionGetLatest, } from '@elaraai/e3-core';
7
+ import { sendSuccess, sendError } from '../beast2.js';
8
+ import { errorToVariant } from '../errors.js';
9
+ import { TaskInfoType, TaskDetailsType, ExecutionListItemType } from '../types.js';
10
+ /**
11
+ * List all tasks in a workspace.
12
+ */
13
+ export async function listTasks(storage, repoPath, workspace) {
14
+ try {
15
+ const taskNames = await workspaceListTasks(storage, repoPath, workspace);
16
+ // Get hash for each task
17
+ const result = await Promise.all(taskNames.map(async (name) => {
18
+ const hash = await workspaceGetTaskHash(storage, repoPath, workspace, name);
19
+ return { name, hash };
20
+ }));
21
+ return sendSuccess(ArrayType(TaskInfoType), result);
22
+ }
23
+ catch (err) {
24
+ return sendError(ArrayType(TaskInfoType), errorToVariant(err));
25
+ }
26
+ }
27
+ /**
28
+ * Get task details.
29
+ */
30
+ export async function getTask(storage, repoPath, workspace, taskName) {
31
+ try {
32
+ const hash = await workspaceGetTaskHash(storage, repoPath, workspace, taskName);
33
+ const task = await workspaceGetTask(storage, repoPath, workspace, taskName);
34
+ return sendSuccess(TaskDetailsType, {
35
+ name: taskName,
36
+ hash,
37
+ commandIr: task.commandIr,
38
+ inputs: task.inputs,
39
+ output: task.output,
40
+ });
41
+ }
42
+ catch (err) {
43
+ return sendError(TaskDetailsType, errorToVariant(err));
44
+ }
45
+ }
46
+ /**
47
+ * Convert ExecutionStatus to API ExecutionHistoryStatus variant.
48
+ */
49
+ function statusToApiStatus(status) {
50
+ switch (status.type) {
51
+ case 'running':
52
+ return variant('running', null);
53
+ case 'success':
54
+ return variant('success', null);
55
+ case 'failed':
56
+ return variant('failed', null);
57
+ case 'error':
58
+ return variant('error', null);
59
+ }
60
+ }
61
+ /**
62
+ * Calculate duration in milliseconds between two dates.
63
+ */
64
+ function calculateDuration(startedAt, completedAt) {
65
+ return BigInt(Math.round(completedAt.getTime() - startedAt.getTime()));
66
+ }
67
+ /**
68
+ * List execution history for a task.
69
+ */
70
+ export async function listExecutions(storage, repoPath, workspace, taskName) {
71
+ try {
72
+ const taskHash = await workspaceGetTaskHash(storage, repoPath, workspace, taskName);
73
+ const inputsHashes = await executionListForTask(storage, repoPath, taskHash);
74
+ const result = [];
75
+ for (const inputsHash of inputsHashes) {
76
+ const status = await executionGetLatest(storage, repoPath, taskHash, inputsHash);
77
+ if (!status)
78
+ continue;
79
+ // Build the complete item based on status type
80
+ let item;
81
+ if (status.type === 'success') {
82
+ item = {
83
+ inputsHash,
84
+ inputHashes: status.value.inputHashes,
85
+ status: statusToApiStatus(status),
86
+ startedAt: status.value.startedAt.toISOString(),
87
+ completedAt: some(status.value.completedAt.toISOString()),
88
+ duration: some(calculateDuration(status.value.startedAt, status.value.completedAt)),
89
+ exitCode: none,
90
+ };
91
+ }
92
+ else if (status.type === 'failed') {
93
+ item = {
94
+ inputsHash,
95
+ inputHashes: status.value.inputHashes,
96
+ status: statusToApiStatus(status),
97
+ startedAt: status.value.startedAt.toISOString(),
98
+ completedAt: some(status.value.completedAt.toISOString()),
99
+ duration: some(calculateDuration(status.value.startedAt, status.value.completedAt)),
100
+ exitCode: some(status.value.exitCode),
101
+ };
102
+ }
103
+ else if (status.type === 'error') {
104
+ item = {
105
+ inputsHash,
106
+ inputHashes: status.value.inputHashes,
107
+ status: statusToApiStatus(status),
108
+ startedAt: status.value.startedAt.toISOString(),
109
+ completedAt: some(status.value.completedAt.toISOString()),
110
+ duration: none,
111
+ exitCode: none,
112
+ };
113
+ }
114
+ else {
115
+ // running status
116
+ item = {
117
+ inputsHash,
118
+ inputHashes: status.value.inputHashes,
119
+ status: statusToApiStatus(status),
120
+ startedAt: status.value.startedAt.toISOString(),
121
+ completedAt: none,
122
+ duration: none,
123
+ exitCode: none,
124
+ };
125
+ }
126
+ result.push(item);
127
+ }
128
+ return sendSuccess(ArrayType(ExecutionListItemType), result);
129
+ }
130
+ catch (err) {
131
+ return sendError(ArrayType(ExecutionListItemType), errorToVariant(err));
132
+ }
133
+ }
134
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/handlers/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Copyright (c) 2025 Elara AI Pty Ltd
3
+ * Licensed under BSL 1.1. See LICENSE for details.
4
+ */
5
+ import type { StorageBackend } from '@elaraai/e3-core';
6
+ /**
7
+ * List all workspaces in the repository.
8
+ */
9
+ export declare function listWorkspaces(storage: StorageBackend, repoPath: string): Promise<Response>;
10
+ /**
11
+ * Create a new workspace.
12
+ */
13
+ export declare function createWorkspace(storage: StorageBackend, repoPath: string, name: string): Promise<Response>;
14
+ /**
15
+ * Get workspace state.
16
+ */
17
+ export declare function getWorkspace(storage: StorageBackend, repoPath: string, name: string): Promise<Response>;
18
+ /**
19
+ * Get comprehensive workspace status.
20
+ */
21
+ export declare function getWorkspaceStatus(storage: StorageBackend, repoPath: string, name: string): Promise<Response>;
22
+ /**
23
+ * Delete a workspace.
24
+ */
25
+ export declare function deleteWorkspace(storage: StorageBackend, repoPath: string, name: string): Promise<Response>;
26
+ /**
27
+ * Deploy a package to a workspace.
28
+ */
29
+ export declare function deployWorkspace(storage: StorageBackend, repoPath: string, workspace: string, packageRef: string): Promise<Response>;
30
+ /**
31
+ * Export a workspace as a zip archive.
32
+ */
33
+ export declare function exportWorkspace(storage: StorageBackend, repoPath: string, workspace: string): Promise<Response>;
34
+ //# sourceMappingURL=workspaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../../src/handlers/workspaces.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvD;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,QAAQ,CAAC,CA2BnB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,QAAQ,CAAC,CAYnB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,QAAQ,CAAC,CAUnB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,QAAQ,CAAC,CAkDnB;AA8CD;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,QAAQ,CAAC,CAOnB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,QAAQ,CAAC,CAanB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,QAAQ,CAAC,CAenB"}
@@ -0,0 +1,225 @@
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 'node:fs/promises';
6
+ import * as os from 'node:os';
7
+ import * as path from 'node:path';
8
+ import { BlobType, NullType, some, none, variant } from '@elaraai/east';
9
+ import { ArrayType } from '@elaraai/east';
10
+ import { WorkspaceStateType, parsePackageRef } from '@elaraai/e3-types';
11
+ import { workspaceList, workspaceCreate, workspaceRemove, workspaceGetState, workspaceDeploy, workspaceExport, workspaceStatus, packageGetLatestVersion, } from '@elaraai/e3-core';
12
+ import { sendSuccess, sendError } from '../beast2.js';
13
+ import { errorToVariant } from '../errors.js';
14
+ import { WorkspaceInfoType, WorkspaceStatusResultType } from '../types.js';
15
+ /**
16
+ * List all workspaces in the repository.
17
+ */
18
+ export async function listWorkspaces(storage, repoPath) {
19
+ try {
20
+ const workspaces = await workspaceList(storage, repoPath);
21
+ const result = await Promise.all(workspaces.map(async (name) => {
22
+ const state = await workspaceGetState(storage, repoPath, name);
23
+ if (state) {
24
+ return {
25
+ name,
26
+ deployed: true,
27
+ packageName: some(state.packageName),
28
+ packageVersion: some(state.packageVersion),
29
+ };
30
+ }
31
+ else {
32
+ return {
33
+ name,
34
+ deployed: false,
35
+ packageName: none,
36
+ packageVersion: none,
37
+ };
38
+ }
39
+ }));
40
+ return sendSuccess(ArrayType(WorkspaceInfoType), result);
41
+ }
42
+ catch (err) {
43
+ return sendError(ArrayType(WorkspaceInfoType), errorToVariant(err));
44
+ }
45
+ }
46
+ /**
47
+ * Create a new workspace.
48
+ */
49
+ export async function createWorkspace(storage, repoPath, name) {
50
+ try {
51
+ await workspaceCreate(storage, repoPath, name);
52
+ return sendSuccess(WorkspaceInfoType, {
53
+ name,
54
+ deployed: false,
55
+ packageName: none,
56
+ packageVersion: none,
57
+ });
58
+ }
59
+ catch (err) {
60
+ return sendError(WorkspaceInfoType, errorToVariant(err));
61
+ }
62
+ }
63
+ /**
64
+ * Get workspace state.
65
+ */
66
+ export async function getWorkspace(storage, repoPath, name) {
67
+ try {
68
+ const state = await workspaceGetState(storage, repoPath, name);
69
+ if (!state) {
70
+ return sendError(WorkspaceStateType, errorToVariant(new Error(`Workspace '${name}' is not deployed`)));
71
+ }
72
+ return sendSuccess(WorkspaceStateType, state);
73
+ }
74
+ catch (err) {
75
+ return sendError(WorkspaceStateType, errorToVariant(err));
76
+ }
77
+ }
78
+ /**
79
+ * Get comprehensive workspace status.
80
+ */
81
+ export async function getWorkspaceStatus(storage, repoPath, name) {
82
+ try {
83
+ const status = await workspaceStatus(storage, repoPath, name);
84
+ // Convert numbers to bigints for BEAST2 serialization
85
+ const result = {
86
+ workspace: status.workspace,
87
+ lock: status.lock ? some({
88
+ pid: BigInt(status.lock.pid ?? 0),
89
+ acquiredAt: status.lock.acquiredAt,
90
+ bootId: status.lock.bootId ? some(status.lock.bootId) : none,
91
+ command: status.lock.command ? some(status.lock.command) : none,
92
+ }) : none,
93
+ datasets: status.datasets.map(d => ({
94
+ path: d.path,
95
+ status: convertDatasetStatus(d.status),
96
+ hash: d.hash ? some(d.hash) : none,
97
+ isTaskOutput: d.isTaskOutput,
98
+ producedBy: d.producedBy ? some(d.producedBy) : none,
99
+ })),
100
+ tasks: status.tasks.map(t => ({
101
+ name: t.name,
102
+ hash: t.hash,
103
+ status: convertTaskStatus(t.status),
104
+ inputs: t.inputs,
105
+ output: t.output,
106
+ dependsOn: t.dependsOn,
107
+ })),
108
+ summary: {
109
+ datasets: {
110
+ total: BigInt(status.summary.datasets.total),
111
+ unset: BigInt(status.summary.datasets.unset),
112
+ stale: BigInt(status.summary.datasets.stale),
113
+ upToDate: BigInt(status.summary.datasets.upToDate),
114
+ },
115
+ tasks: {
116
+ total: BigInt(status.summary.tasks.total),
117
+ upToDate: BigInt(status.summary.tasks.upToDate),
118
+ ready: BigInt(status.summary.tasks.ready),
119
+ waiting: BigInt(status.summary.tasks.waiting),
120
+ inProgress: BigInt(status.summary.tasks.inProgress),
121
+ failed: BigInt(status.summary.tasks.failed),
122
+ error: BigInt(status.summary.tasks.error),
123
+ staleRunning: BigInt(status.summary.tasks.staleRunning),
124
+ },
125
+ },
126
+ };
127
+ return sendSuccess(WorkspaceStatusResultType, result);
128
+ }
129
+ catch (err) {
130
+ return sendError(WorkspaceStatusResultType, errorToVariant(err));
131
+ }
132
+ }
133
+ // Helper to convert dataset status to variant format
134
+ function convertDatasetStatus(status) {
135
+ switch (status.type) {
136
+ case 'unset': return variant('unset', null);
137
+ case 'stale': return variant('stale', null);
138
+ case 'up-to-date': return variant('up-to-date', null);
139
+ default: return variant('unset', null);
140
+ }
141
+ }
142
+ // Helper to convert task status to variant format
143
+ function convertTaskStatus(status) {
144
+ switch (status.type) {
145
+ case 'up-to-date':
146
+ return variant('up-to-date', { cached: status.cached });
147
+ case 'ready':
148
+ return variant('ready', null);
149
+ case 'waiting':
150
+ return variant('waiting', { reason: status.reason });
151
+ case 'in-progress':
152
+ return variant('in-progress', {
153
+ pid: status.pid != null ? some(BigInt(status.pid)) : none,
154
+ startedAt: status.startedAt ? some(status.startedAt) : none,
155
+ });
156
+ case 'failed':
157
+ return variant('failed', {
158
+ exitCode: BigInt(status.exitCode),
159
+ completedAt: status.completedAt ? some(status.completedAt) : none,
160
+ });
161
+ case 'error':
162
+ return variant('error', {
163
+ message: status.message,
164
+ completedAt: status.completedAt ? some(status.completedAt) : none,
165
+ });
166
+ case 'stale-running':
167
+ return variant('stale-running', {
168
+ pid: status.pid != null ? some(BigInt(status.pid)) : none,
169
+ startedAt: status.startedAt ? some(status.startedAt) : none,
170
+ });
171
+ default:
172
+ return variant('ready', null);
173
+ }
174
+ }
175
+ /**
176
+ * Delete a workspace.
177
+ */
178
+ export async function deleteWorkspace(storage, repoPath, name) {
179
+ try {
180
+ await workspaceRemove(storage, repoPath, name);
181
+ return sendSuccess(NullType, null);
182
+ }
183
+ catch (err) {
184
+ return sendError(NullType, errorToVariant(err));
185
+ }
186
+ }
187
+ /**
188
+ * Deploy a package to a workspace.
189
+ */
190
+ export async function deployWorkspace(storage, repoPath, workspace, packageRef) {
191
+ try {
192
+ const { name: pkgName, version: maybeVersion } = parsePackageRef(packageRef);
193
+ const pkgVersion = maybeVersion ?? await packageGetLatestVersion(storage, repoPath, pkgName);
194
+ if (!pkgVersion) {
195
+ return sendError(NullType, errorToVariant(new Error(`Package not found: ${pkgName}`)));
196
+ }
197
+ await workspaceDeploy(storage, repoPath, workspace, pkgName, pkgVersion);
198
+ return sendSuccess(NullType, null);
199
+ }
200
+ catch (err) {
201
+ return sendError(NullType, errorToVariant(err));
202
+ }
203
+ }
204
+ /**
205
+ * Export a workspace as a zip archive.
206
+ */
207
+ export async function exportWorkspace(storage, repoPath, workspace) {
208
+ try {
209
+ // Export to temp file
210
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'e3-ws-export-'));
211
+ const tempPath = path.join(tempDir, 'workspace.zip');
212
+ try {
213
+ await workspaceExport(storage, repoPath, workspace, tempPath);
214
+ const archive = await fs.readFile(tempPath);
215
+ return sendSuccess(BlobType, new Uint8Array(archive));
216
+ }
217
+ finally {
218
+ await fs.rm(tempDir, { recursive: true, force: true });
219
+ }
220
+ }
221
+ catch (err) {
222
+ return sendError(BlobType, errorToVariant(err));
223
+ }
224
+ }
225
+ //# sourceMappingURL=workspaces.js.map