@capsule-run/sdk 0.4.1 → 0.5.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.
Files changed (70) hide show
  1. package/README.md +22 -2
  2. package/dist/app.d.ts +1 -0
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js.map +1 -1
  5. package/dist/index.d.ts +4 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +4 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/polyfills/buffer.d.ts +8 -0
  10. package/dist/polyfills/buffer.d.ts.map +1 -0
  11. package/dist/polyfills/buffer.js +9 -0
  12. package/dist/polyfills/buffer.js.map +1 -0
  13. package/dist/polyfills/events.d.ts +8 -0
  14. package/dist/polyfills/events.d.ts.map +1 -0
  15. package/dist/polyfills/events.js +9 -0
  16. package/dist/polyfills/events.js.map +1 -0
  17. package/dist/polyfills/fs-promises.d.ts +7 -0
  18. package/dist/polyfills/fs-promises.d.ts.map +1 -0
  19. package/dist/polyfills/fs-promises.js +7 -0
  20. package/dist/polyfills/fs-promises.js.map +1 -0
  21. package/dist/polyfills/fs.d.ts +82 -0
  22. package/dist/polyfills/fs.d.ts.map +1 -0
  23. package/dist/{files.js → polyfills/fs.js} +100 -20
  24. package/dist/polyfills/fs.js.map +1 -0
  25. package/dist/polyfills/os.d.ts +150 -0
  26. package/dist/polyfills/os.d.ts.map +1 -0
  27. package/dist/polyfills/os.js +151 -0
  28. package/dist/polyfills/os.js.map +1 -0
  29. package/dist/polyfills/path.d.ts +8 -0
  30. package/dist/polyfills/path.d.ts.map +1 -0
  31. package/dist/polyfills/path.js +8 -0
  32. package/dist/polyfills/path.js.map +1 -0
  33. package/dist/polyfills/process.d.ts +109 -0
  34. package/dist/polyfills/process.d.ts.map +1 -0
  35. package/dist/polyfills/process.js +224 -0
  36. package/dist/polyfills/process.js.map +1 -0
  37. package/dist/polyfills/stream-web.d.ts +74 -0
  38. package/dist/polyfills/stream-web.d.ts.map +1 -0
  39. package/dist/polyfills/stream-web.js +23 -0
  40. package/dist/polyfills/stream-web.js.map +1 -0
  41. package/dist/polyfills/stream.d.ts +16 -0
  42. package/dist/polyfills/stream.d.ts.map +1 -0
  43. package/dist/polyfills/stream.js +16 -0
  44. package/dist/polyfills/stream.js.map +1 -0
  45. package/dist/polyfills/url.d.ts +47 -0
  46. package/dist/polyfills/url.d.ts.map +1 -0
  47. package/dist/polyfills/url.js +68 -0
  48. package/dist/polyfills/url.js.map +1 -0
  49. package/dist/task.d.ts +17 -1
  50. package/dist/task.d.ts.map +1 -1
  51. package/dist/task.js +26 -1
  52. package/dist/task.js.map +1 -1
  53. package/package.json +18 -1
  54. package/src/app.ts +1 -0
  55. package/src/index.ts +4 -1
  56. package/src/polyfills/buffer.ts +11 -0
  57. package/src/polyfills/events.ts +11 -0
  58. package/src/polyfills/fs-promises.ts +7 -0
  59. package/src/polyfills/fs.ts +336 -0
  60. package/src/polyfills/os.ts +222 -0
  61. package/src/polyfills/path.ts +21 -0
  62. package/src/polyfills/process.ts +286 -0
  63. package/src/polyfills/stream-web.ts +24 -0
  64. package/src/polyfills/stream.ts +28 -0
  65. package/src/polyfills/url.ts +73 -0
  66. package/src/task.ts +53 -9
  67. package/dist/files.d.ts +0 -46
  68. package/dist/files.d.ts.map +0 -1
  69. package/dist/files.js.map +0 -1
  70. package/src/files.ts +0 -217
package/src/task.ts CHANGED
@@ -25,13 +25,30 @@ export interface TaskOptions {
25
25
  maxRetries?: number;
26
26
  /** Files/folders accessible in the sandbox, e.g., ["./data"] */
27
27
  allowedFiles?: string[];
28
+ /** Environment variables available from your .env file for the task */
29
+ envVariables?: string[];
28
30
  }
29
31
 
30
- interface TaskResult {
31
- result?: any;
32
- error?: string;
32
+ interface TaskResult<T> {
33
+ success: boolean;
34
+ result: T;
35
+ error: string | null;
36
+ execution: TaskExecution;
33
37
  }
34
38
 
39
+ interface TaskExecution {
40
+ task_name: string;
41
+ duration_ms: number;
42
+ retries: number;
43
+ fuel_consumed: number;
44
+ }
45
+
46
+ type Awaited<T> = T extends Promise<infer U> ? U : T;
47
+
48
+ type TaskReturnType<T> = T extends Promise<infer U>
49
+ ? Promise<TaskResult<U>>
50
+ : TaskResult<T>;
51
+
35
52
  /**
36
53
  * Define a Capsule task with configuration.
37
54
  *
@@ -80,7 +97,7 @@ function normalizeTimeout(timeout?: string | number): string | undefined {
80
97
  export function task<TArgs extends any[], TReturn>(
81
98
  options: TaskOptions,
82
99
  fn: (...args: TArgs) => TReturn
83
- ): (...args: TArgs) => TReturn {
100
+ ): (...args: TArgs) => TaskReturnType<TReturn> {
84
101
  const taskName = options.name;
85
102
  let compute = options.compute?.toString().toUpperCase() ?? "MEDIUM";
86
103
 
@@ -91,21 +108,48 @@ export function task<TArgs extends any[], TReturn>(
91
108
  timeout: normalizeTimeout(options.timeout),
92
109
  maxRetries: options.maxRetries,
93
110
  allowedFiles: options.allowedFiles,
111
+ envVariables: options.envVariables,
94
112
  };
95
113
 
96
- const wrapper = (...args: TArgs): TReturn => {
114
+ const wrapper = (...args: TArgs): TaskReturnType<TReturn> => {
97
115
  if (!isWasmMode()) {
98
- return fn(...args);
116
+ const result = fn(...args);
117
+
118
+ if (result instanceof Promise) {
119
+ return result.then((value) => ({
120
+ success: true,
121
+ result: value,
122
+ error: null,
123
+ execution: {
124
+ task_name: taskName,
125
+ duration_ms: 0,
126
+ retries: 0,
127
+ fuel_consumed: 0,
128
+ },
129
+ })) as TaskReturnType<TReturn>;
130
+ }
131
+
132
+ return {
133
+ success: true,
134
+ result,
135
+ error: null,
136
+ execution: {
137
+ task_name: taskName,
138
+ duration_ms: 0,
139
+ retries: 0,
140
+ fuel_consumed: 0,
141
+ },
142
+ } as TaskReturnType<TReturn>;
99
143
  }
100
144
 
101
145
  const resultJson = callHost(taskName, args, taskConfig);
102
146
 
103
147
  try {
104
- const result: TaskResult = JSON.parse(resultJson);
105
- return result as TReturn;
148
+ const result: TaskResult<Awaited<TReturn>> = JSON.parse(resultJson);
149
+ return result as TaskReturnType<TReturn>;
106
150
  } catch (e) {
107
151
  if (e instanceof SyntaxError) {
108
- return resultJson as unknown as TReturn;
152
+ return resultJson as unknown as TaskReturnType<TReturn>;
109
153
  }
110
154
  throw e;
111
155
  }
package/dist/files.d.ts DELETED
@@ -1,46 +0,0 @@
1
- /**
2
- * Capsule Files API for WASM filesystem access.
3
- */
4
- /**
5
- * Read a file as text.
6
- *
7
- * @param path - The path to read.
8
- * @returns A promise that resolves to a string containing the file contents.
9
- */
10
- export declare function readText(path: string): Promise<string>;
11
- /**
12
- * Read a file as bytes.
13
- *
14
- * @param path - The path to read.
15
- * @returns A promise that resolves to a Uint8Array containing the file contents.
16
- */
17
- export declare function readBytes(path: string): Promise<Uint8Array>;
18
- /**
19
- * Write text content to a file.
20
- *
21
- * @param path - The path to write.
22
- * @param content - The text content to write.
23
- */
24
- export declare function writeText(path: string, content: string): Promise<void>;
25
- /**
26
- * Write bytes to a file.
27
- *
28
- * @param path - The path to write.
29
- * @param data - The bytes to write.
30
- */
31
- export declare function writeBytes(path: string, data: Uint8Array): Promise<void>;
32
- /**
33
- * List files/directories at a path.
34
- *
35
- * @param path - The path to list.
36
- * @returns A promise that resolves to an array of strings representing the files and directories at the specified path.
37
- */
38
- export declare function list(path?: string): Promise<string[]>;
39
- /**
40
- * Check if a file or directory exists.
41
- *
42
- * @param path - The path to check.
43
- * @returns A promise that resolves to a boolean indicating whether the file or directory exists.
44
- */
45
- export declare function exists(path: string): Promise<boolean>;
46
- //# sourceMappingURL=files.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoFH;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG5D;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAkBjE;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5E;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB9E;AAED;;;;;GAKG;AACH,wBAAsB,IAAI,CAAC,IAAI,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA6BhE;AAED;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAe3D"}
package/dist/files.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"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"}
package/src/files.ts DELETED
@@ -1,217 +0,0 @@
1
- /**
2
- * Capsule Files API for WASM filesystem access.
3
- */
4
-
5
- declare const globalThis: {
6
- 'wasi:filesystem/types': any;
7
- 'wasi:filesystem/preopens': any;
8
- };
9
-
10
- interface Descriptor {
11
- read(length: bigint, offset: bigint): [Uint8Array, boolean];
12
- write(buffer: Uint8Array, offset: bigint): bigint;
13
- stat(): { size: bigint };
14
- readDirectory(): any;
15
- openAt(
16
- pathFlags: { symlinkFollow?: boolean },
17
- path: string,
18
- openFlags: { create?: boolean; directory?: boolean; exclusive?: boolean; truncate?: boolean },
19
- descriptorFlags: { read?: boolean; write?: boolean; mutateDirectory?: boolean }
20
- ): Descriptor;
21
- }
22
-
23
- interface PreopenedDir {
24
- descriptor: Descriptor;
25
- guestPath: string;
26
- }
27
-
28
- function getFsBindings(): { types: any; preopens: any } | null {
29
- try {
30
- const types = globalThis['wasi:filesystem/types'];
31
- const preopens = globalThis['wasi:filesystem/preopens'];
32
- if (types && preopens) {
33
- return { types, preopens };
34
- }
35
- } catch {}
36
- return null;
37
- }
38
-
39
- function getPreopenedDirs(): PreopenedDir[] {
40
- const fs = getFsBindings();
41
- if (!fs) return [];
42
-
43
- try {
44
- const dirs = fs.preopens.getDirectories();
45
- return (dirs || []).map((entry: [Descriptor, string]) => ({
46
- descriptor: entry[0],
47
- guestPath: entry[1]
48
- }));
49
- } catch {
50
- return [];
51
- }
52
- }
53
-
54
- function normalizePath(path: string): string {
55
- if (path.startsWith('./')) {
56
- return path.slice(2);
57
- }
58
- return path;
59
- }
60
-
61
- function resolvePath(path: string): { dir: Descriptor; relativePath: string } | null {
62
- const preopens = getPreopenedDirs();
63
- if (preopens.length === 0) return null;
64
-
65
- const normalizedPath = normalizePath(path);
66
-
67
- for (const { descriptor, guestPath } of preopens) {
68
- const normalizedGuest = normalizePath(guestPath);
69
-
70
- if (normalizedGuest === '.' || normalizedGuest === '') {
71
- return { dir: descriptor, relativePath: normalizedPath };
72
- }
73
-
74
- if (normalizedPath.startsWith(normalizedGuest + '/')) {
75
- const relativePath = normalizedPath.slice(normalizedGuest.length + 1);
76
- return { dir: descriptor, relativePath };
77
- }
78
-
79
- if (normalizedPath === normalizedGuest) {
80
- return { dir: descriptor, relativePath: '.' };
81
- }
82
- }
83
-
84
- return { dir: preopens[0].descriptor, relativePath: normalizedPath };
85
- }
86
-
87
- /**
88
- * Read a file as text.
89
- *
90
- * @param path - The path to read.
91
- * @returns A promise that resolves to a string containing the file contents.
92
- */
93
- export async function readText(path: string): Promise<string> {
94
- const bytes = await readBytes(path);
95
- return new TextDecoder().decode(bytes);
96
- }
97
-
98
- /**
99
- * Read a file as bytes.
100
- *
101
- * @param path - The path to read.
102
- * @returns A promise that resolves to a Uint8Array containing the file contents.
103
- */
104
- export async function readBytes(path: string): Promise<Uint8Array> {
105
- const resolved = resolvePath(path);
106
- if (!resolved) {
107
- throw new Error("Filesystem not available.");
108
- }
109
-
110
- try {
111
- const pathFlags = { symlinkFollow: false };
112
- const openFlags = {};
113
- const descriptorFlags = { read: true };
114
-
115
- const fd = resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
116
- const stat = fd.stat();
117
- const [data] = fd.read(stat.size, BigInt(0));
118
- return data;
119
- } catch (e) {
120
- throw new Error(`Failed to read file '${path}': ${e}`);
121
- }
122
- }
123
-
124
- /**
125
- * Write text content to a file.
126
- *
127
- * @param path - The path to write.
128
- * @param content - The text content to write.
129
- */
130
- export async function writeText(path: string, content: string): Promise<void> {
131
- const bytes = new TextEncoder().encode(content);
132
- await writeBytes(path, bytes);
133
- }
134
-
135
- /**
136
- * Write bytes to a file.
137
- *
138
- * @param path - The path to write.
139
- * @param data - The bytes to write.
140
- */
141
- export async function writeBytes(path: string, data: Uint8Array): Promise<void> {
142
- const resolved = resolvePath(path);
143
- if (!resolved) {
144
- throw new Error("Filesystem not available.");
145
- }
146
-
147
- try {
148
- const pathFlags = { symlinkFollow: false };
149
- const openFlags = { create: true, truncate: true };
150
- const descriptorFlags = { write: true };
151
-
152
- const fd = resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
153
- fd.write(data, BigInt(0));
154
- } catch (e) {
155
- throw new Error(`Failed to write file '${path}': ${e}`);
156
- }
157
- }
158
-
159
- /**
160
- * List files/directories at a path.
161
- *
162
- * @param path - The path to list.
163
- * @returns A promise that resolves to an array of strings representing the files and directories at the specified path.
164
- */
165
- export async function list(path: string = "."): Promise<string[]> {
166
- const resolved = resolvePath(path);
167
- if (!resolved) {
168
- throw new Error("Filesystem not available.");
169
- }
170
-
171
- try {
172
- let targetDir = resolved.dir;
173
- if (resolved.relativePath !== ".") {
174
- const pathFlags = { symlinkFollow: false };
175
- const openFlags = { directory: true };
176
- const descriptorFlags = { read: true };
177
- targetDir = resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
178
- }
179
-
180
- const stream = targetDir.readDirectory();
181
- const entries: string[] = [];
182
-
183
- let entry;
184
- while ((entry = stream.readDirectoryEntry()) && entry) {
185
- if (entry.name) {
186
- entries.push(entry.name);
187
- }
188
- }
189
-
190
- return entries;
191
- } catch (e) {
192
- throw new Error(`Failed to list directory '${path}': ${e}`);
193
- }
194
- }
195
-
196
- /**
197
- * Check if a file or directory exists.
198
- *
199
- * @param path - The path to check.
200
- * @returns A promise that resolves to a boolean indicating whether the file or directory exists.
201
- */
202
- export async function exists(path: string): Promise<boolean> {
203
- const resolved = resolvePath(path);
204
- if (!resolved) {
205
- return false;
206
- }
207
-
208
- try {
209
- const pathFlags = { symlinkFollow: false };
210
- const openFlags = {};
211
- const descriptorFlags = { read: true };
212
- resolved.dir.openAt(pathFlags, resolved.relativePath, openFlags, descriptorFlags);
213
- return true;
214
- } catch {
215
- return false;
216
- }
217
- }