@miosa/sdk 3.2.3 → 3.2.4
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.d.ts +32 -14
- package/dist/index.js +68 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -7468,30 +7468,39 @@ declare class Sandbox {
|
|
|
7468
7468
|
/** Check readiness of the sandbox (GET /sandboxes/:id/readiness). */
|
|
7469
7469
|
readiness(): Promise<Record<string, unknown>>;
|
|
7470
7470
|
/**
|
|
7471
|
-
* Block until the sandbox reports ready, or *timeout* seconds
|
|
7471
|
+
* Block until the sandbox reports ready, or the caller's *timeout* seconds
|
|
7472
|
+
* (the full deadline budget) elapse.
|
|
7472
7473
|
*
|
|
7473
|
-
* When `stream` is `true` (the default) this opens an SSE connection
|
|
7474
|
-
*
|
|
7475
|
-
* `event: ready` frame.
|
|
7476
|
-
*
|
|
7477
|
-
*
|
|
7474
|
+
* When `stream` is `true` (the default) this opens an SSE connection to
|
|
7475
|
+
* `GET /sandboxes/:id/readiness/stream?timeout=<window>` and waits for an
|
|
7476
|
+
* `event: ready` frame. `<window>` is the caller's remaining budget clamped
|
|
7477
|
+
* to {@link READINESS_STREAM_MAX_TIMEOUT_SEC}, the server's own maximum
|
|
7478
|
+
* lease for a single stream connection — a long-restoring persistent
|
|
7479
|
+
* sandbox (e.g. Docker restore, 60-90 s) legitimately outlives one lease.
|
|
7480
|
+
* The server emits `ready` immediately if the sandbox is already ready,
|
|
7481
|
+
* `event: timeout` when *that connection's* window elapses without a
|
|
7482
|
+
* verdict, and `event: error` on a terminal boot failure.
|
|
7478
7483
|
*
|
|
7479
|
-
*
|
|
7480
|
-
*
|
|
7484
|
+
* An `event: timeout` (or the stream closing without a verdict) is NOT
|
|
7485
|
+
* treated as the final answer while the caller's overall deadline still has
|
|
7486
|
+
* budget left — that would silently truncate a 180 s wait down to the
|
|
7487
|
+
* server's lease window and return `false` while the sandbox was still
|
|
7488
|
+
* mid-restore. Instead this reconnects the stream (or falls back to
|
|
7489
|
+
* polling) for the remaining budget. `false` is only returned once the
|
|
7490
|
+
* caller's full deadline has elapsed.
|
|
7481
7491
|
*
|
|
7482
7492
|
* Throws {@link MiosaError} with code `SANDBOX_BOOT_FAILED` as soon as the
|
|
7483
7493
|
* sandbox is observed in a terminal failure state (`error` or `destroyed`)
|
|
7484
7494
|
* while waiting, instead of silently exhausting the timeout and returning
|
|
7485
7495
|
* `false` — a permanent boot failure and "still booting, keep waiting" must
|
|
7486
|
-
* never look the same to the caller.
|
|
7487
|
-
*
|
|
7488
|
-
*
|
|
7489
|
-
* authoritative {@link readiness} check before giving up, to catch a
|
|
7490
|
-
* failure that landed right at the boundary.
|
|
7496
|
+
* never look the same to the caller. On each `event: timeout` boundary this
|
|
7497
|
+
* also makes one authoritative {@link readiness} check before deciding to
|
|
7498
|
+
* reconnect or stop, to catch a failure that landed right at the boundary.
|
|
7491
7499
|
*
|
|
7492
7500
|
* If the SSE endpoint returns 404 (server pre-dates the streaming
|
|
7493
7501
|
* endpoint) this transparently falls back to polling {@link readiness}
|
|
7494
|
-
* every 10 ms until ready,
|
|
7502
|
+
* every 10 ms until ready, the caller's deadline elapses, or terminal
|
|
7503
|
+
* failure.
|
|
7495
7504
|
*/
|
|
7496
7505
|
waitUntilReady(options?: {
|
|
7497
7506
|
timeout?: number;
|
|
@@ -7522,6 +7531,15 @@ declare class Sandbox {
|
|
|
7522
7531
|
* stream endpoint is unavailable (404 or transport error) so callers
|
|
7523
7532
|
* can fall back to polling.
|
|
7524
7533
|
*/
|
|
7534
|
+
/**
|
|
7535
|
+
* Opens one readiness SSE connection for at most *windowSec* seconds (this
|
|
7536
|
+
* is a single lease, not the caller's overall {@link waitUntilReady}
|
|
7537
|
+
* budget — see there for how leases are chained). *windowSec* is sent to
|
|
7538
|
+
* the server as `?timeout=<seconds>` so the server's own stream deadline
|
|
7539
|
+
* matches what was actually requested instead of always falling back to
|
|
7540
|
+
* its 30 s default, which is what let a 180 s `waitUntilReady` call get
|
|
7541
|
+
* cut short at 30 s.
|
|
7542
|
+
*/
|
|
7525
7543
|
private tryReadinessStream;
|
|
7526
7544
|
destroy(): Promise<void>;
|
|
7527
7545
|
delete(): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -174,7 +174,7 @@ var TokenRefreshFailedError = class extends MiosaError {
|
|
|
174
174
|
};
|
|
175
175
|
|
|
176
176
|
// src/version.ts
|
|
177
|
-
var SDK_VERSION = "3.2.
|
|
177
|
+
var SDK_VERSION = "3.2.4";
|
|
178
178
|
var SDK_USER_AGENT = `@miosa/sdk/${SDK_VERSION}`;
|
|
179
179
|
|
|
180
180
|
// src/http.ts
|
|
@@ -8517,6 +8517,7 @@ function isCommandReady(payload) {
|
|
|
8517
8517
|
return status === "ready";
|
|
8518
8518
|
});
|
|
8519
8519
|
}
|
|
8520
|
+
var READINESS_STREAM_MAX_TIMEOUT_SEC = 120;
|
|
8520
8521
|
var SANDBOX_TEMPLATE = "miosa-sandbox";
|
|
8521
8522
|
var SANDBOX_TIER_BY_CPU = {
|
|
8522
8523
|
1: { size: "xs", memoryMb: 2048 },
|
|
@@ -9565,47 +9566,66 @@ var Sandbox = class _Sandbox {
|
|
|
9565
9566
|
);
|
|
9566
9567
|
}
|
|
9567
9568
|
/**
|
|
9568
|
-
* Block until the sandbox reports ready, or *timeout* seconds
|
|
9569
|
+
* Block until the sandbox reports ready, or the caller's *timeout* seconds
|
|
9570
|
+
* (the full deadline budget) elapse.
|
|
9569
9571
|
*
|
|
9570
|
-
* When `stream` is `true` (the default) this opens an SSE connection
|
|
9571
|
-
*
|
|
9572
|
-
* `event: ready` frame.
|
|
9573
|
-
*
|
|
9574
|
-
*
|
|
9572
|
+
* When `stream` is `true` (the default) this opens an SSE connection to
|
|
9573
|
+
* `GET /sandboxes/:id/readiness/stream?timeout=<window>` and waits for an
|
|
9574
|
+
* `event: ready` frame. `<window>` is the caller's remaining budget clamped
|
|
9575
|
+
* to {@link READINESS_STREAM_MAX_TIMEOUT_SEC}, the server's own maximum
|
|
9576
|
+
* lease for a single stream connection — a long-restoring persistent
|
|
9577
|
+
* sandbox (e.g. Docker restore, 60-90 s) legitimately outlives one lease.
|
|
9578
|
+
* The server emits `ready` immediately if the sandbox is already ready,
|
|
9579
|
+
* `event: timeout` when *that connection's* window elapses without a
|
|
9580
|
+
* verdict, and `event: error` on a terminal boot failure.
|
|
9575
9581
|
*
|
|
9576
|
-
*
|
|
9577
|
-
*
|
|
9582
|
+
* An `event: timeout` (or the stream closing without a verdict) is NOT
|
|
9583
|
+
* treated as the final answer while the caller's overall deadline still has
|
|
9584
|
+
* budget left — that would silently truncate a 180 s wait down to the
|
|
9585
|
+
* server's lease window and return `false` while the sandbox was still
|
|
9586
|
+
* mid-restore. Instead this reconnects the stream (or falls back to
|
|
9587
|
+
* polling) for the remaining budget. `false` is only returned once the
|
|
9588
|
+
* caller's full deadline has elapsed.
|
|
9578
9589
|
*
|
|
9579
9590
|
* Throws {@link MiosaError} with code `SANDBOX_BOOT_FAILED` as soon as the
|
|
9580
9591
|
* sandbox is observed in a terminal failure state (`error` or `destroyed`)
|
|
9581
9592
|
* while waiting, instead of silently exhausting the timeout and returning
|
|
9582
9593
|
* `false` — a permanent boot failure and "still booting, keep waiting" must
|
|
9583
|
-
* never look the same to the caller.
|
|
9584
|
-
*
|
|
9585
|
-
*
|
|
9586
|
-
* authoritative {@link readiness} check before giving up, to catch a
|
|
9587
|
-
* failure that landed right at the boundary.
|
|
9594
|
+
* never look the same to the caller. On each `event: timeout` boundary this
|
|
9595
|
+
* also makes one authoritative {@link readiness} check before deciding to
|
|
9596
|
+
* reconnect or stop, to catch a failure that landed right at the boundary.
|
|
9588
9597
|
*
|
|
9589
9598
|
* If the SSE endpoint returns 404 (server pre-dates the streaming
|
|
9590
9599
|
* endpoint) this transparently falls back to polling {@link readiness}
|
|
9591
|
-
* every 10 ms until ready,
|
|
9600
|
+
* every 10 ms until ready, the caller's deadline elapses, or terminal
|
|
9601
|
+
* failure.
|
|
9592
9602
|
*/
|
|
9593
9603
|
async waitUntilReady(options = {}) {
|
|
9594
9604
|
const timeout = options.timeout ?? 30;
|
|
9595
9605
|
const stream = options.stream ?? true;
|
|
9596
9606
|
const requireCommandReady = options.requireCommandReady ?? true;
|
|
9607
|
+
const deadlineMs = Date.now() + timeout * 1e3;
|
|
9597
9608
|
if (stream) {
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
await this.
|
|
9605
|
-
|
|
9609
|
+
while (true) {
|
|
9610
|
+
const remainingMs = deadlineMs - Date.now();
|
|
9611
|
+
if (remainingMs <= 0) return false;
|
|
9612
|
+
const remainingSec = remainingMs / 1e3;
|
|
9613
|
+
const clamped = remainingSec > READINESS_STREAM_MAX_TIMEOUT_SEC;
|
|
9614
|
+
const windowSec = clamped ? READINESS_STREAM_MAX_TIMEOUT_SEC : remainingSec;
|
|
9615
|
+
const sseResult = await this.tryReadinessStream(windowSec);
|
|
9616
|
+
if (sseResult === true) {
|
|
9617
|
+
await this.adoptReadyState();
|
|
9618
|
+
return true;
|
|
9619
|
+
}
|
|
9620
|
+
if (sseResult === false) {
|
|
9621
|
+
await this.throwIfTerminallyFailed();
|
|
9622
|
+
if (!clamped || Date.now() >= deadlineMs) return false;
|
|
9623
|
+
continue;
|
|
9624
|
+
}
|
|
9625
|
+
break;
|
|
9606
9626
|
}
|
|
9627
|
+
if (Date.now() >= deadlineMs) return false;
|
|
9607
9628
|
}
|
|
9608
|
-
const deadlineMs = Date.now() + timeout * 1e3;
|
|
9609
9629
|
while (Date.now() < deadlineMs) {
|
|
9610
9630
|
try {
|
|
9611
9631
|
const data = await this.readiness();
|
|
@@ -9669,9 +9689,25 @@ var Sandbox = class _Sandbox {
|
|
|
9669
9689
|
* stream endpoint is unavailable (404 or transport error) so callers
|
|
9670
9690
|
* can fall back to polling.
|
|
9671
9691
|
*/
|
|
9672
|
-
|
|
9692
|
+
/**
|
|
9693
|
+
* Opens one readiness SSE connection for at most *windowSec* seconds (this
|
|
9694
|
+
* is a single lease, not the caller's overall {@link waitUntilReady}
|
|
9695
|
+
* budget — see there for how leases are chained). *windowSec* is sent to
|
|
9696
|
+
* the server as `?timeout=<seconds>` so the server's own stream deadline
|
|
9697
|
+
* matches what was actually requested instead of always falling back to
|
|
9698
|
+
* its 30 s default, which is what let a 180 s `waitUntilReady` call get
|
|
9699
|
+
* cut short at 30 s.
|
|
9700
|
+
*/
|
|
9701
|
+
async tryReadinessStream(windowSec) {
|
|
9702
|
+
const clampedWindowSec = Math.max(
|
|
9703
|
+
1,
|
|
9704
|
+
Math.min(windowSec, READINESS_STREAM_MAX_TIMEOUT_SEC)
|
|
9705
|
+
);
|
|
9673
9706
|
const abort = new AbortController();
|
|
9674
|
-
const timer = setTimeout(
|
|
9707
|
+
const timer = setTimeout(
|
|
9708
|
+
() => abort.abort(),
|
|
9709
|
+
(clampedWindowSec + 5) * 1e3
|
|
9710
|
+
);
|
|
9675
9711
|
try {
|
|
9676
9712
|
const headers = {
|
|
9677
9713
|
Authorization: `Bearer ${this.http.apiKey}`,
|
|
@@ -9683,7 +9719,7 @@ var Sandbox = class _Sandbox {
|
|
|
9683
9719
|
"User-Agent": SDK_USER_AGENT
|
|
9684
9720
|
};
|
|
9685
9721
|
const response = await fetch(
|
|
9686
|
-
`${this.http.baseUrl}/sandboxes/${this.id}/readiness/stream`,
|
|
9722
|
+
`${this.http.baseUrl}/sandboxes/${this.id}/readiness/stream?timeout=${clampedWindowSec}`,
|
|
9687
9723
|
{ method: "GET", headers, signal: abort.signal }
|
|
9688
9724
|
);
|
|
9689
9725
|
if (response.status === 404) return null;
|
|
@@ -9704,6 +9740,7 @@ var Sandbox = class _Sandbox {
|
|
|
9704
9740
|
const evt = line.slice(6).trim();
|
|
9705
9741
|
if (evt === "ready") return true;
|
|
9706
9742
|
if (evt === "timeout") return false;
|
|
9743
|
+
if (evt === "error") throw this.bootFailedError("error");
|
|
9707
9744
|
}
|
|
9708
9745
|
}
|
|
9709
9746
|
}
|
|
@@ -9714,7 +9751,10 @@ var Sandbox = class _Sandbox {
|
|
|
9714
9751
|
}
|
|
9715
9752
|
}
|
|
9716
9753
|
return null;
|
|
9717
|
-
} catch {
|
|
9754
|
+
} catch (err) {
|
|
9755
|
+
if (err instanceof MiosaError && err.code === "SANDBOX_BOOT_FAILED") {
|
|
9756
|
+
throw err;
|
|
9757
|
+
}
|
|
9718
9758
|
return null;
|
|
9719
9759
|
} finally {
|
|
9720
9760
|
clearTimeout(timer);
|