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 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/compute.ts
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://preview.computesdk.com/__api/license/authorize", {
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 CLI: ${errorOutput}`);
147
+ throw new Error(`Failed to install compute daemon: ${errorOutput}`);
145
148
  }
146
149
  }
147
- async function installComputeInSandbox(sandbox, config) {
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 authResponse;
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 CLI failed to start after ${maxRetries} attempts (${maxRetries * delayMs / 1e3}s).
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
- const authResponse = await installComputeInSandbox(sandbox, this.computeAuth);
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 this.wrapWithComputeClient(sandbox, authResponse);
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", `${fullCommand} &`],
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
  };