computesdk 1.8.6 → 1.8.8
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/index.js +63 -112
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -112
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -42,11 +42,10 @@ function isCommandExitError(error) {
|
|
|
42
42
|
return typeof error === "object" && error !== null && "name" in error && error.name === "CommandExitError" && "result" in error;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
// src/
|
|
46
|
-
var import_client = require("@computesdk/client");
|
|
45
|
+
// src/auth/license.ts
|
|
47
46
|
async function authorizeApiKey(apiKey) {
|
|
48
47
|
try {
|
|
49
|
-
const response = await fetch("https://
|
|
48
|
+
const response = await fetch("https://sandbox.computesdk.com/__api/license/authorize", {
|
|
50
49
|
method: "POST",
|
|
51
50
|
headers: {
|
|
52
51
|
"Content-Type": "application/json"
|
|
@@ -82,6 +81,8 @@ async function authorizeApiKey(apiKey) {
|
|
|
82
81
|
throw new Error(`Failed to authorize API key (network error): ${error instanceof Error ? error.message : String(error)}`);
|
|
83
82
|
}
|
|
84
83
|
}
|
|
84
|
+
|
|
85
|
+
// src/compute-daemon/dependencies.ts
|
|
85
86
|
async function isCommandAvailable(sandbox, command) {
|
|
86
87
|
const result = await sandbox.runCommand("sh", ["-c", `command -v ${command}`]);
|
|
87
88
|
return result.exitCode === 0;
|
|
@@ -123,6 +124,8 @@ Please install curl and bash manually or use a different sandbox image.`
|
|
|
123
124
|
);
|
|
124
125
|
}
|
|
125
126
|
}
|
|
127
|
+
|
|
128
|
+
// src/compute-daemon/installer.ts
|
|
126
129
|
async function isComputeInstalled(sandbox) {
|
|
127
130
|
const result = await sandbox.runCommand("sh", ["-c", 'test -f /usr/local/bin/compute && echo "exists" || echo "missing"']);
|
|
128
131
|
return result.stdout?.trim() === "exists";
|
|
@@ -141,18 +144,12 @@ async function runInstallScript(sandbox, accessToken) {
|
|
|
141
144
|
const installResult = await sandbox.runCommand("bash", ["-c", installCommand]);
|
|
142
145
|
if (installResult.exitCode !== 0) {
|
|
143
146
|
const errorOutput = installResult.stderr || installResult.stdout || "unknown error";
|
|
144
|
-
throw new Error(`Failed to install compute
|
|
147
|
+
throw new Error(`Failed to install compute daemon: ${errorOutput}`);
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
|
-
async function
|
|
148
|
-
let authResponse = null;
|
|
149
|
-
let accessToken = config?.accessToken;
|
|
150
|
-
if (config?.apiKey && !accessToken) {
|
|
151
|
-
authResponse = await authorizeApiKey(config.apiKey);
|
|
152
|
-
accessToken = authResponse.access_token;
|
|
153
|
-
}
|
|
150
|
+
async function installComputeDaemon(sandbox, accessToken) {
|
|
154
151
|
if (await isComputeInstalled(sandbox)) {
|
|
155
|
-
return
|
|
152
|
+
return;
|
|
156
153
|
}
|
|
157
154
|
await ensureDependencies(sandbox);
|
|
158
155
|
await downloadInstallScript(sandbox);
|
|
@@ -160,8 +157,12 @@ async function installComputeInSandbox(sandbox, config) {
|
|
|
160
157
|
if (!await isComputeInstalled(sandbox)) {
|
|
161
158
|
throw new Error("Compute binary not found at /usr/local/bin/compute after installation");
|
|
162
159
|
}
|
|
163
|
-
return authResponse;
|
|
164
160
|
}
|
|
161
|
+
|
|
162
|
+
// src/sandbox/wrapper.ts
|
|
163
|
+
var import_client = require("@computesdk/client");
|
|
164
|
+
|
|
165
|
+
// src/compute-daemon/lifecycle.ts
|
|
165
166
|
async function waitForComputeReady(client, maxRetries = 30, delayMs = 2e3) {
|
|
166
167
|
let lastError = null;
|
|
167
168
|
for (let i = 0; i < maxRetries; i++) {
|
|
@@ -172,7 +173,7 @@ async function waitForComputeReady(client, maxRetries = 30, delayMs = 2e3) {
|
|
|
172
173
|
lastError = error instanceof Error ? error : new Error(String(error));
|
|
173
174
|
if (i === maxRetries - 1) {
|
|
174
175
|
throw new Error(
|
|
175
|
-
`Compute
|
|
176
|
+
`Compute daemon failed to start after ${maxRetries} attempts (${maxRetries * delayMs / 1e3}s).
|
|
176
177
|
Last error: ${lastError.message}
|
|
177
178
|
This could indicate:
|
|
178
179
|
1. The compute daemon failed to start in the sandbox
|
|
@@ -184,6 +185,28 @@ This could indicate:
|
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
}
|
|
188
|
+
|
|
189
|
+
// src/sandbox/wrapper.ts
|
|
190
|
+
async function wrapWithComputeClient(originalSandbox, authResponse) {
|
|
191
|
+
const client = new import_client.ComputeClient({
|
|
192
|
+
sandboxUrl: authResponse.sandbox_url,
|
|
193
|
+
sandboxId: originalSandbox.sandboxId,
|
|
194
|
+
provider: originalSandbox.provider,
|
|
195
|
+
token: authResponse.access_token,
|
|
196
|
+
WebSocket: globalThis.WebSocket
|
|
197
|
+
});
|
|
198
|
+
await waitForComputeReady(client);
|
|
199
|
+
const wrappedSandbox = Object.assign(client, {
|
|
200
|
+
__originalSandbox: originalSandbox,
|
|
201
|
+
// Override getInstance to return the original provider's instance
|
|
202
|
+
getInstance: () => originalSandbox.getInstance(),
|
|
203
|
+
// Override getProvider to return the original provider
|
|
204
|
+
getProvider: () => originalSandbox.getProvider()
|
|
205
|
+
});
|
|
206
|
+
return wrappedSandbox;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/compute.ts
|
|
187
210
|
var ComputeManager = class {
|
|
188
211
|
constructor() {
|
|
189
212
|
this.config = null;
|
|
@@ -213,9 +236,22 @@ var ComputeManager = class {
|
|
|
213
236
|
const options = params?.options;
|
|
214
237
|
const sandbox = await provider.sandbox.create(options);
|
|
215
238
|
if (this.computeAuth.apiKey || this.computeAuth.accessToken) {
|
|
216
|
-
|
|
239
|
+
let authResponse = null;
|
|
240
|
+
let accessToken = this.computeAuth.accessToken;
|
|
241
|
+
if (this.computeAuth.apiKey && !accessToken) {
|
|
242
|
+
authResponse = await authorizeApiKey(this.computeAuth.apiKey);
|
|
243
|
+
accessToken = authResponse.access_token;
|
|
244
|
+
}
|
|
245
|
+
await installComputeDaemon(sandbox, accessToken);
|
|
217
246
|
if (authResponse) {
|
|
218
|
-
return await
|
|
247
|
+
return await wrapWithComputeClient(sandbox, authResponse);
|
|
248
|
+
} else if (accessToken) {
|
|
249
|
+
const defaultAuthResponse = {
|
|
250
|
+
access_token: accessToken,
|
|
251
|
+
sandbox_url: "https://sandbox.computesdk.com",
|
|
252
|
+
preview_url: "https://preview.computesdk.com"
|
|
253
|
+
};
|
|
254
|
+
return await wrapWithComputeClient(sandbox, defaultAuthResponse);
|
|
219
255
|
}
|
|
220
256
|
}
|
|
221
257
|
return sandbox;
|
|
@@ -304,28 +340,6 @@ var ComputeManager = class {
|
|
|
304
340
|
}
|
|
305
341
|
return provider;
|
|
306
342
|
}
|
|
307
|
-
/**
|
|
308
|
-
* Wrap a provider sandbox with ComputeClient while preserving the original sandbox
|
|
309
|
-
* This adds powerful features like WebSocket terminals, file watchers, and signals
|
|
310
|
-
*/
|
|
311
|
-
async wrapWithComputeClient(originalSandbox, authResponse) {
|
|
312
|
-
const client = new import_client.ComputeClient({
|
|
313
|
-
sandboxUrl: authResponse.sandbox_url,
|
|
314
|
-
sandboxId: originalSandbox.sandboxId,
|
|
315
|
-
provider: originalSandbox.provider,
|
|
316
|
-
token: authResponse.access_token,
|
|
317
|
-
WebSocket: globalThis.WebSocket
|
|
318
|
-
});
|
|
319
|
-
await waitForComputeReady(client);
|
|
320
|
-
const wrappedSandbox = Object.assign(client, {
|
|
321
|
-
__originalSandbox: originalSandbox,
|
|
322
|
-
// Override getInstance to return the original provider's instance
|
|
323
|
-
getInstance: () => originalSandbox.getInstance(),
|
|
324
|
-
// Override getProvider to return the original provider
|
|
325
|
-
getProvider: () => originalSandbox.getProvider()
|
|
326
|
-
});
|
|
327
|
-
return wrappedSandbox;
|
|
328
|
-
}
|
|
329
343
|
// Future: compute.blob.*, compute.database.*, compute.git.* will be added here
|
|
330
344
|
// blob = new BlobManager();
|
|
331
345
|
// database = new DatabaseManager();
|
|
@@ -592,80 +606,10 @@ function createBackgroundCommand(command, args = [], options) {
|
|
|
592
606
|
const fullCommand = args.length > 0 ? `${command} ${args.join(" ")}` : command;
|
|
593
607
|
return {
|
|
594
608
|
command: "sh",
|
|
595
|
-
args: ["-c",
|
|
609
|
+
args: ["-c", `nohup ${fullCommand} > /dev/null 2>&1 &`],
|
|
596
610
|
isBackground: true
|
|
597
611
|
};
|
|
598
612
|
}
|
|
599
|
-
var defaultFilesystemMethods = {
|
|
600
|
-
readFile: async (sandbox, path, runCommand) => {
|
|
601
|
-
const result = await runCommand(sandbox, "cat", [path]);
|
|
602
|
-
if (result.exitCode !== 0) {
|
|
603
|
-
throw new Error(`Failed to read file ${path}: ${result.stderr}`);
|
|
604
|
-
}
|
|
605
|
-
return result.stdout.replace(/\n$/, "");
|
|
606
|
-
},
|
|
607
|
-
writeFile: async (sandbox, path, content, runCommand) => {
|
|
608
|
-
const result = await runCommand(sandbox, "sh", ["-c", `echo ${JSON.stringify(content)} > ${JSON.stringify(path)}`]);
|
|
609
|
-
if (result.exitCode !== 0) {
|
|
610
|
-
throw new Error(`Failed to write file ${path}: ${result.stderr}`);
|
|
611
|
-
}
|
|
612
|
-
},
|
|
613
|
-
mkdir: async (sandbox, path, runCommand) => {
|
|
614
|
-
const result = await runCommand(sandbox, "mkdir", ["-p", path]);
|
|
615
|
-
if (result.exitCode !== 0) {
|
|
616
|
-
throw new Error(`Failed to create directory ${path}: ${result.stderr}`);
|
|
617
|
-
}
|
|
618
|
-
},
|
|
619
|
-
readdir: async (sandbox, path, runCommand) => {
|
|
620
|
-
let result = await runCommand(sandbox, "ls", ["-la", path]);
|
|
621
|
-
let hasDetailedOutput = true;
|
|
622
|
-
if (result.exitCode !== 0) {
|
|
623
|
-
result = await runCommand(sandbox, "ls", ["-l", path]);
|
|
624
|
-
}
|
|
625
|
-
if (result.exitCode !== 0) {
|
|
626
|
-
result = await runCommand(sandbox, "ls", [path]);
|
|
627
|
-
hasDetailedOutput = false;
|
|
628
|
-
}
|
|
629
|
-
if (result.exitCode !== 0) {
|
|
630
|
-
throw new Error(`Failed to list directory ${path}: ${result.stderr}`);
|
|
631
|
-
}
|
|
632
|
-
const lines = (result.stdout || "").split("\n").filter((line) => line.trim() && !line.startsWith("total"));
|
|
633
|
-
return lines.map((line) => {
|
|
634
|
-
if (hasDetailedOutput && line.includes(" ")) {
|
|
635
|
-
const parts = line.trim().split(/\s+/);
|
|
636
|
-
const name = parts[parts.length - 1];
|
|
637
|
-
const isDirectory = line.startsWith("d");
|
|
638
|
-
return {
|
|
639
|
-
name,
|
|
640
|
-
path: `${path}/${name}`,
|
|
641
|
-
isDirectory,
|
|
642
|
-
size: parseInt(parts[4]) || 0,
|
|
643
|
-
lastModified: /* @__PURE__ */ new Date()
|
|
644
|
-
};
|
|
645
|
-
} else {
|
|
646
|
-
const name = line.trim();
|
|
647
|
-
return {
|
|
648
|
-
name,
|
|
649
|
-
path: `${path}/${name}`,
|
|
650
|
-
isDirectory: false,
|
|
651
|
-
// Can't determine from simple ls
|
|
652
|
-
size: 0,
|
|
653
|
-
lastModified: /* @__PURE__ */ new Date()
|
|
654
|
-
};
|
|
655
|
-
}
|
|
656
|
-
});
|
|
657
|
-
},
|
|
658
|
-
exists: async (sandbox, path, runCommand) => {
|
|
659
|
-
const result = await runCommand(sandbox, "test", ["-e", path]);
|
|
660
|
-
return result.exitCode === 0;
|
|
661
|
-
},
|
|
662
|
-
remove: async (sandbox, path, runCommand) => {
|
|
663
|
-
const result = await runCommand(sandbox, "rm", ["-rf", path]);
|
|
664
|
-
if (result.exitCode !== 0) {
|
|
665
|
-
throw new Error(`Failed to remove ${path}: ${result.stderr}`);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
};
|
|
669
613
|
var UnsupportedFileSystem = class {
|
|
670
614
|
constructor(providerName) {
|
|
671
615
|
this.providerName = providerName;
|
|
@@ -739,6 +683,16 @@ var GeneratedSandbox = class {
|
|
|
739
683
|
return await this.methods.runCode(this.sandbox, code, runtime, this.config);
|
|
740
684
|
}
|
|
741
685
|
async runCommand(command, args, options) {
|
|
686
|
+
if (options?.background) {
|
|
687
|
+
const fullCommand = args?.length ? `${command} ${args.join(" ")}` : command;
|
|
688
|
+
const bgCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
689
|
+
const result = await this.methods.runCommand(this.sandbox, "sh", ["-c", bgCommand], void 0);
|
|
690
|
+
return {
|
|
691
|
+
...result,
|
|
692
|
+
isBackground: true,
|
|
693
|
+
pid: -1
|
|
694
|
+
};
|
|
695
|
+
}
|
|
742
696
|
return await this.methods.runCommand(this.sandbox, command, args, options);
|
|
743
697
|
}
|
|
744
698
|
async getInfo() {
|
|
@@ -879,9 +833,6 @@ var GeneratedProvider = class {
|
|
|
879
833
|
}
|
|
880
834
|
};
|
|
881
835
|
function createProvider(providerConfig) {
|
|
882
|
-
if (!providerConfig.methods.sandbox.filesystem) {
|
|
883
|
-
providerConfig.methods.sandbox.filesystem = defaultFilesystemMethods;
|
|
884
|
-
}
|
|
885
836
|
return (config) => {
|
|
886
837
|
return new GeneratedProvider(config, providerConfig);
|
|
887
838
|
};
|