computesdk 1.11.0 → 1.12.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/dist/index.mjs CHANGED
@@ -1337,13 +1337,38 @@ var Server = class {
1337
1337
  this.updateStatusHandler = handlers.updateStatus;
1338
1338
  }
1339
1339
  /**
1340
- * Start a new managed server
1340
+ * Start a new managed server with optional supervisor settings
1341
+ *
1342
+ * **Restart Policies:**
1343
+ * - `never` (default): No automatic restart on exit
1344
+ * - `on-failure`: Restart only on non-zero exit code
1345
+ * - `always`: Always restart on exit (including exit code 0)
1346
+ *
1347
+ * **Graceful Shutdown:**
1348
+ * When stopping a server, it first sends SIGTERM and waits for `stop_timeout_ms`
1349
+ * before sending SIGKILL if the process hasn't exited.
1350
+ *
1341
1351
  * @param options - Server configuration
1342
- * @param options.slug - Unique server slug (URL-safe identifier)
1343
- * @param options.command - Command to start the server
1344
- * @param options.path - Working directory (optional)
1345
- * @param options.env_file - Path to env file (optional)
1346
1352
  * @returns Server info
1353
+ *
1354
+ * @example
1355
+ * ```typescript
1356
+ * // Basic server
1357
+ * const server = await sandbox.server.start({
1358
+ * slug: 'web',
1359
+ * command: 'npm run dev',
1360
+ * path: '/app',
1361
+ * });
1362
+ *
1363
+ * // With supervisor settings
1364
+ * const server = await sandbox.server.start({
1365
+ * slug: 'api',
1366
+ * command: 'node server.js',
1367
+ * environment: { NODE_ENV: 'production' },
1368
+ * restart_policy: 'always',
1369
+ * max_restarts: 0, // unlimited
1370
+ * });
1371
+ * ```
1347
1372
  */
1348
1373
  async start(options) {
1349
1374
  const response = await this.startHandler(options);
@@ -2743,8 +2768,40 @@ API request failed (${response.status}): ${error}`
2743
2768
  return this.request("/servers");
2744
2769
  }
2745
2770
  /**
2746
- * Start a new managed server
2771
+ * Start a new managed server with optional supervisor settings
2772
+ *
2747
2773
  * @param options - Server configuration
2774
+ * @param options.slug - Unique server identifier
2775
+ * @param options.command - Command to start the server
2776
+ * @param options.path - Working directory (optional)
2777
+ * @param options.env_file - Path to .env file relative to path (optional)
2778
+ * @param options.environment - Inline environment variables (merged with env_file if both provided)
2779
+ * @param options.restart_policy - When to automatically restart: 'never' (default), 'on-failure', 'always'
2780
+ * @param options.max_restarts - Maximum restart attempts, 0 = unlimited (default: 0)
2781
+ * @param options.restart_delay_ms - Delay between restart attempts in milliseconds (default: 1000)
2782
+ * @param options.stop_timeout_ms - Graceful shutdown timeout in milliseconds (default: 10000)
2783
+ *
2784
+ * @example
2785
+ * ```typescript
2786
+ * // Basic server
2787
+ * await sandbox.startServer({
2788
+ * slug: 'web',
2789
+ * command: 'npm run dev',
2790
+ * path: '/app',
2791
+ * });
2792
+ *
2793
+ * // With supervisor settings
2794
+ * await sandbox.startServer({
2795
+ * slug: 'api',
2796
+ * command: 'node server.js',
2797
+ * path: '/app',
2798
+ * environment: { NODE_ENV: 'production', PORT: '3000' },
2799
+ * restart_policy: 'on-failure',
2800
+ * max_restarts: 5,
2801
+ * restart_delay_ms: 2000,
2802
+ * stop_timeout_ms: 5000,
2803
+ * });
2804
+ * ```
2748
2805
  */
2749
2806
  async startServer(options) {
2750
2807
  return this.request("/servers", {
@@ -3567,6 +3624,34 @@ async function gatewayFetch(url, config, options = {}) {
3567
3624
  throw error;
3568
3625
  }
3569
3626
  }
3627
+ async function waitForSandboxStatus(config, endpoint, body, options = {}) {
3628
+ const maxWaitMs = options.maxWaitMs ?? 6e4;
3629
+ const initialDelayMs = 500;
3630
+ const maxDelayMs = 2e3;
3631
+ const backoffFactor = 1.5;
3632
+ const startTime = Date.now();
3633
+ let currentDelay = initialDelayMs;
3634
+ while (Date.now() - startTime < maxWaitMs) {
3635
+ const result = await gatewayFetch(endpoint, config, {
3636
+ method: "POST",
3637
+ body: JSON.stringify(body)
3638
+ });
3639
+ if (!result.success || !result.data) {
3640
+ return result;
3641
+ }
3642
+ if (result.data.status !== "creating") {
3643
+ return result;
3644
+ }
3645
+ if (process.env.COMPUTESDK_DEBUG) {
3646
+ console.log(`[Compute] Sandbox still creating, waiting ${currentDelay}ms...`);
3647
+ }
3648
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
3649
+ currentDelay = Math.min(currentDelay * backoffFactor, maxDelayMs);
3650
+ }
3651
+ throw new Error(
3652
+ `Sandbox is still being created after ${maxWaitMs}ms. This may indicate the sandbox failed to start. Check your provider dashboard.`
3653
+ );
3654
+ }
3570
3655
  var ComputeManager = class {
3571
3656
  constructor() {
3572
3657
  this.config = null;
@@ -3654,14 +3739,15 @@ var ComputeManager = class {
3654
3739
  findOrCreate: async (options) => {
3655
3740
  const config = this.getGatewayConfig();
3656
3741
  const { name, namespace, ...restOptions } = options;
3657
- const result = await gatewayFetch(`${config.gatewayUrl}/v1/sandboxes/find-or-create`, config, {
3658
- method: "POST",
3659
- body: JSON.stringify({
3742
+ const result = await waitForSandboxStatus(
3743
+ config,
3744
+ `${config.gatewayUrl}/v1/sandboxes/find-or-create`,
3745
+ {
3660
3746
  namespace: namespace || "default",
3661
3747
  name,
3662
3748
  ...restOptions
3663
- })
3664
- });
3749
+ }
3750
+ );
3665
3751
  if (!result.success || !result.data) {
3666
3752
  throw new Error(`Gateway returned invalid response`);
3667
3753
  }
@@ -3691,13 +3777,14 @@ var ComputeManager = class {
3691
3777
  */
3692
3778
  find: async (options) => {
3693
3779
  const config = this.getGatewayConfig();
3694
- const result = await gatewayFetch(`${config.gatewayUrl}/v1/sandboxes/find`, config, {
3695
- method: "POST",
3696
- body: JSON.stringify({
3780
+ const result = await waitForSandboxStatus(
3781
+ config,
3782
+ `${config.gatewayUrl}/v1/sandboxes/find`,
3783
+ {
3697
3784
  namespace: options.namespace || "default",
3698
3785
  name: options.name
3699
- })
3700
- });
3786
+ }
3787
+ );
3701
3788
  if (!result.success || !result.data) {
3702
3789
  return null;
3703
3790
  }