sandbox0 0.10.3 → 0.10.5

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 (188) hide show
  1. package/README.md +134 -0
  2. package/dist/apispec/src/apis/FilesApi.d.ts +14 -10
  3. package/dist/apispec/src/apis/FilesApi.d.ts.map +1 -1
  4. package/dist/apispec/src/apis/FilesApi.js +14 -10
  5. package/dist/apispec/src/apis/SandboxRootfsApi.d.ts +96 -5
  6. package/dist/apispec/src/apis/SandboxRootfsApi.d.ts.map +1 -1
  7. package/dist/apispec/src/apis/SandboxRootfsApi.js +291 -5
  8. package/dist/apispec/src/apis/SandboxesApi.d.ts +345 -6
  9. package/dist/apispec/src/apis/SandboxesApi.d.ts.map +1 -1
  10. package/dist/apispec/src/apis/SandboxesApi.js +1017 -7
  11. package/dist/apispec/src/apis/SessionsApi.d.ts +51 -1
  12. package/dist/apispec/src/apis/SessionsApi.d.ts.map +1 -1
  13. package/dist/apispec/src/apis/SessionsApi.js +159 -1
  14. package/dist/apispec/src/models/CaptureSandboxRootFSSnapshotRequest.d.ts +51 -0
  15. package/dist/apispec/src/models/CaptureSandboxRootFSSnapshotRequest.d.ts.map +1 -0
  16. package/dist/apispec/src/models/CaptureSandboxRootFSSnapshotRequest.js +49 -0
  17. package/dist/apispec/src/models/ConditionalExecutionSessionRequest.d.ts +46 -0
  18. package/dist/apispec/src/models/ConditionalExecutionSessionRequest.d.ts.map +1 -0
  19. package/dist/apispec/src/models/ConditionalExecutionSessionRequest.js +52 -0
  20. package/dist/apispec/src/models/ContainerSpec.d.ts +1 -2
  21. package/dist/apispec/src/models/ContainerSpec.d.ts.map +1 -1
  22. package/dist/apispec/src/models/ContainerSpec.js +0 -1
  23. package/dist/apispec/src/models/ForkSandboxConfig.d.ts +6 -0
  24. package/dist/apispec/src/models/ForkSandboxConfig.d.ts.map +1 -1
  25. package/dist/apispec/src/models/ForkSandboxConfig.js +2 -0
  26. package/dist/apispec/src/models/ForkSandboxRequest.d.ts +6 -0
  27. package/dist/apispec/src/models/ForkSandboxRequest.d.ts.map +1 -1
  28. package/dist/apispec/src/models/ForkSandboxRequest.js +2 -0
  29. package/dist/apispec/src/models/ManagedFileReadResponse.d.ts +64 -0
  30. package/dist/apispec/src/models/ManagedFileReadResponse.d.ts.map +1 -0
  31. package/dist/apispec/src/models/ManagedFileReadResponse.js +65 -0
  32. package/dist/apispec/src/models/ManagedFileWriteRequest.d.ts +39 -0
  33. package/dist/apispec/src/models/ManagedFileWriteRequest.d.ts.map +1 -0
  34. package/dist/apispec/src/models/ManagedFileWriteRequest.js +47 -0
  35. package/dist/apispec/src/models/ManagedFilesState.d.ts +58 -0
  36. package/dist/apispec/src/models/ManagedFilesState.d.ts.map +1 -0
  37. package/dist/apispec/src/models/ManagedFilesState.js +61 -0
  38. package/dist/apispec/src/models/PauseSandboxResponse.d.ts +12 -0
  39. package/dist/apispec/src/models/PauseSandboxResponse.d.ts.map +1 -1
  40. package/dist/apispec/src/models/PauseSandboxResponse.js +4 -0
  41. package/dist/apispec/src/models/QuotaDimension.d.ts +6 -1
  42. package/dist/apispec/src/models/QuotaDimension.d.ts.map +1 -1
  43. package/dist/apispec/src/models/QuotaDimension.js +6 -1
  44. package/dist/apispec/src/models/ResourceQuota.d.ts +1 -1
  45. package/dist/apispec/src/models/ResumeSandboxResponse.d.ts +25 -1
  46. package/dist/apispec/src/models/ResumeSandboxResponse.d.ts.map +1 -1
  47. package/dist/apispec/src/models/ResumeSandboxResponse.js +8 -0
  48. package/dist/apispec/src/models/SandboxExecutionStateRequest.d.ts +14 -2
  49. package/dist/apispec/src/models/SandboxExecutionStateRequest.d.ts.map +1 -1
  50. package/dist/apispec/src/models/SandboxExecutionStateRequest.js +4 -0
  51. package/dist/apispec/src/models/SandboxHealth.d.ts +99 -0
  52. package/dist/apispec/src/models/SandboxHealth.d.ts.map +1 -0
  53. package/dist/apispec/src/models/SandboxHealth.js +90 -0
  54. package/dist/apispec/src/models/SandboxHealthObservation.d.ts +109 -0
  55. package/dist/apispec/src/models/SandboxHealthObservation.d.ts.map +1 -0
  56. package/dist/apispec/src/models/SandboxHealthObservation.js +110 -0
  57. package/dist/apispec/src/models/SandboxMemoryOperation.d.ts +115 -0
  58. package/dist/apispec/src/models/SandboxMemoryOperation.d.ts.map +1 -0
  59. package/dist/apispec/src/models/SandboxMemoryOperation.js +100 -0
  60. package/dist/apispec/src/models/SandboxMemoryRestoration.d.ts +64 -0
  61. package/dist/apispec/src/models/SandboxMemoryRestoration.d.ts.map +1 -0
  62. package/dist/apispec/src/models/SandboxMemoryRestoration.js +64 -0
  63. package/dist/apispec/src/models/SandboxMemoryRestorationStep.d.ts +63 -0
  64. package/dist/apispec/src/models/SandboxMemoryRestorationStep.d.ts.map +1 -0
  65. package/dist/apispec/src/models/SandboxMemoryRestorationStep.js +63 -0
  66. package/dist/apispec/src/models/SandboxPauseRequest.d.ts +39 -0
  67. package/dist/apispec/src/models/SandboxPauseRequest.d.ts.map +1 -0
  68. package/dist/apispec/src/models/SandboxPauseRequest.js +43 -0
  69. package/dist/apispec/src/models/SandboxRestartFinalCapture.d.ts +79 -0
  70. package/dist/apispec/src/models/SandboxRestartFinalCapture.d.ts.map +1 -0
  71. package/dist/apispec/src/models/SandboxRestartFinalCapture.js +70 -0
  72. package/dist/apispec/src/models/SandboxRestartFinalCaptureAcknowledgement.d.ts +39 -0
  73. package/dist/apispec/src/models/SandboxRestartFinalCaptureAcknowledgement.d.ts.map +1 -0
  74. package/dist/apispec/src/models/SandboxRestartFinalCaptureAcknowledgement.js +47 -0
  75. package/dist/apispec/src/models/SandboxRestartFinalCaptureFile.d.ts +69 -0
  76. package/dist/apispec/src/models/SandboxRestartFinalCaptureFile.d.ts.map +1 -0
  77. package/dist/apispec/src/models/SandboxRestartFinalCaptureFile.js +67 -0
  78. package/dist/apispec/src/models/SandboxRestartOperation.d.ts +115 -0
  79. package/dist/apispec/src/models/SandboxRestartOperation.d.ts.map +1 -0
  80. package/dist/apispec/src/models/SandboxRestartOperation.js +95 -0
  81. package/dist/apispec/src/models/SandboxRestartRequest.d.ts +33 -0
  82. package/dist/apispec/src/models/SandboxRestartRequest.d.ts.map +1 -0
  83. package/dist/apispec/src/models/SandboxRestartRequest.js +43 -0
  84. package/dist/apispec/src/models/SandboxRestartRetryObservation.d.ts +83 -0
  85. package/dist/apispec/src/models/SandboxRestartRetryObservation.d.ts.map +1 -0
  86. package/dist/apispec/src/models/SandboxRestartRetryObservation.js +75 -0
  87. package/dist/apispec/src/models/SandboxRootFSForkLaunch.d.ts +123 -0
  88. package/dist/apispec/src/models/SandboxRootFSForkLaunch.d.ts.map +1 -0
  89. package/dist/apispec/src/models/SandboxRootFSForkLaunch.js +104 -0
  90. package/dist/apispec/src/models/SandboxRootFSForkLaunchRequest.d.ts +51 -0
  91. package/dist/apispec/src/models/SandboxRootFSForkLaunchRequest.d.ts.map +1 -0
  92. package/dist/apispec/src/models/SandboxRootFSForkLaunchRequest.js +55 -0
  93. package/dist/apispec/src/models/SandboxRootFSForkObservation.d.ts +129 -0
  94. package/dist/apispec/src/models/SandboxRootFSForkObservation.d.ts.map +1 -0
  95. package/dist/apispec/src/models/SandboxRootFSForkObservation.js +107 -0
  96. package/dist/apispec/src/models/SandboxRootFSIdentity.d.ts +138 -0
  97. package/dist/apispec/src/models/SandboxRootFSIdentity.d.ts.map +1 -0
  98. package/dist/apispec/src/models/SandboxRootFSIdentity.js +111 -0
  99. package/dist/apispec/src/models/SandboxRootFSSnapshot.d.ts +6 -0
  100. package/dist/apispec/src/models/SandboxRootFSSnapshot.d.ts.map +1 -1
  101. package/dist/apispec/src/models/SandboxRootFSSnapshot.js +2 -0
  102. package/dist/apispec/src/models/SandboxRuntimeHealth.d.ts +40 -0
  103. package/dist/apispec/src/models/SandboxRuntimeHealth.d.ts.map +1 -0
  104. package/dist/apispec/src/models/SandboxRuntimeHealth.js +48 -0
  105. package/dist/apispec/src/models/SandboxSnapshotRestoreOperation.d.ts +139 -0
  106. package/dist/apispec/src/models/SandboxSnapshotRestoreOperation.d.ts.map +1 -0
  107. package/dist/apispec/src/models/SandboxSnapshotRestoreOperation.js +109 -0
  108. package/dist/apispec/src/models/SandboxSnapshotRestoreRequest.d.ts +51 -0
  109. package/dist/apispec/src/models/SandboxSnapshotRestoreRequest.d.ts.map +1 -0
  110. package/dist/apispec/src/models/SandboxSnapshotRestoreRequest.js +55 -0
  111. package/dist/apispec/src/models/SandboxStorageHealth.d.ts +46 -0
  112. package/dist/apispec/src/models/SandboxStorageHealth.d.ts.map +1 -0
  113. package/dist/apispec/src/models/SandboxStorageHealth.js +52 -0
  114. package/dist/apispec/src/models/SandboxUpdateConfig.d.ts +15 -3
  115. package/dist/apispec/src/models/SandboxUpdateConfig.d.ts.map +1 -1
  116. package/dist/apispec/src/models/SandboxUpdateConfig.js +3 -0
  117. package/dist/apispec/src/models/SuccessManagedFileReadResponse.d.ts +40 -0
  118. package/dist/apispec/src/models/SuccessManagedFileReadResponse.d.ts.map +1 -0
  119. package/dist/apispec/src/models/SuccessManagedFileReadResponse.js +48 -0
  120. package/dist/apispec/src/models/SuccessManagedFilesStateResponse.d.ts +40 -0
  121. package/dist/apispec/src/models/SuccessManagedFilesStateResponse.d.ts.map +1 -0
  122. package/dist/apispec/src/models/SuccessManagedFilesStateResponse.js +48 -0
  123. package/dist/apispec/src/models/SuccessSandboxHealthResponse.d.ts +40 -0
  124. package/dist/apispec/src/models/SuccessSandboxHealthResponse.d.ts.map +1 -0
  125. package/dist/apispec/src/models/SuccessSandboxHealthResponse.js +48 -0
  126. package/dist/apispec/src/models/SuccessSandboxMemoryOperationResponse.d.ts +40 -0
  127. package/dist/apispec/src/models/SuccessSandboxMemoryOperationResponse.d.ts.map +1 -0
  128. package/dist/apispec/src/models/SuccessSandboxMemoryOperationResponse.js +48 -0
  129. package/dist/apispec/src/models/SuccessSandboxMemoryRestorationResponse.d.ts +40 -0
  130. package/dist/apispec/src/models/SuccessSandboxMemoryRestorationResponse.d.ts.map +1 -0
  131. package/dist/apispec/src/models/SuccessSandboxMemoryRestorationResponse.js +48 -0
  132. package/dist/apispec/src/models/SuccessSandboxRestartFinalCaptureFileResponse.d.ts +40 -0
  133. package/dist/apispec/src/models/SuccessSandboxRestartFinalCaptureFileResponse.d.ts.map +1 -0
  134. package/dist/apispec/src/models/SuccessSandboxRestartFinalCaptureFileResponse.js +48 -0
  135. package/dist/apispec/src/models/SuccessSandboxRestartFinalCaptureResponse.d.ts +40 -0
  136. package/dist/apispec/src/models/SuccessSandboxRestartFinalCaptureResponse.d.ts.map +1 -0
  137. package/dist/apispec/src/models/SuccessSandboxRestartFinalCaptureResponse.js +48 -0
  138. package/dist/apispec/src/models/SuccessSandboxRestartOperationResponse.d.ts +40 -0
  139. package/dist/apispec/src/models/SuccessSandboxRestartOperationResponse.d.ts.map +1 -0
  140. package/dist/apispec/src/models/SuccessSandboxRestartOperationResponse.js +48 -0
  141. package/dist/apispec/src/models/SuccessSandboxRootFSForkLaunchResponse.d.ts +40 -0
  142. package/dist/apispec/src/models/SuccessSandboxRootFSForkLaunchResponse.d.ts.map +1 -0
  143. package/dist/apispec/src/models/SuccessSandboxRootFSForkLaunchResponse.js +48 -0
  144. package/dist/apispec/src/models/SuccessSandboxRootFSForkObservationResponse.d.ts +40 -0
  145. package/dist/apispec/src/models/SuccessSandboxRootFSForkObservationResponse.d.ts.map +1 -0
  146. package/dist/apispec/src/models/SuccessSandboxRootFSForkObservationResponse.js +48 -0
  147. package/dist/apispec/src/models/SuccessSandboxRootFSIdentityResponse.d.ts +40 -0
  148. package/dist/apispec/src/models/SuccessSandboxRootFSIdentityResponse.d.ts.map +1 -0
  149. package/dist/apispec/src/models/SuccessSandboxRootFSIdentityResponse.js +48 -0
  150. package/dist/apispec/src/models/SuccessSandboxSnapshotRestoreOperationResponse.d.ts +40 -0
  151. package/dist/apispec/src/models/SuccessSandboxSnapshotRestoreOperationResponse.d.ts.map +1 -0
  152. package/dist/apispec/src/models/SuccessSandboxSnapshotRestoreOperationResponse.js +48 -0
  153. package/dist/apispec/src/models/index.d.ts +37 -0
  154. package/dist/apispec/src/models/index.d.ts.map +1 -1
  155. package/dist/apispec/src/models/index.js +37 -0
  156. package/dist/fork_launch.d.ts +15 -0
  157. package/dist/fork_launch.d.ts.map +1 -0
  158. package/dist/fork_launch.js +38 -0
  159. package/dist/health.d.ts +4 -0
  160. package/dist/health.d.ts.map +1 -0
  161. package/dist/health.js +46 -0
  162. package/dist/index.d.ts +9 -0
  163. package/dist/index.d.ts.map +1 -1
  164. package/dist/index.js +1 -0
  165. package/dist/memory_operation.d.ts +12 -0
  166. package/dist/memory_operation.d.ts.map +1 -0
  167. package/dist/memory_operation.js +44 -0
  168. package/dist/memory_restoration.d.ts +5 -0
  169. package/dist/memory_restoration.d.ts.map +1 -0
  170. package/dist/memory_restoration.js +29 -0
  171. package/dist/models.d.ts +2 -0
  172. package/dist/models.d.ts.map +1 -1
  173. package/dist/resources/sandboxes.d.ts +73 -1
  174. package/dist/resources/sandboxes.d.ts.map +1 -1
  175. package/dist/resources/sandboxes.js +336 -3
  176. package/dist/restart_final_capture.d.ts +10 -0
  177. package/dist/restart_final_capture.d.ts.map +1 -0
  178. package/dist/restart_final_capture.js +52 -0
  179. package/dist/sandbox_managed_files.d.ts +34 -0
  180. package/dist/sandbox_managed_files.d.ts.map +1 -0
  181. package/dist/sandbox_managed_files.js +96 -0
  182. package/dist/sandbox_sessions.d.ts +5 -0
  183. package/dist/sandbox_sessions.d.ts.map +1 -1
  184. package/dist/sandbox_sessions.js +103 -1
  185. package/dist/ws_client.d.ts +8 -0
  186. package/dist/ws_client.d.ts.map +1 -1
  187. package/dist/ws_client.js +20 -2
  188. package/package.json +2 -2
@@ -0,0 +1,96 @@
1
+ import { wrapApiCall } from "./errors.js";
2
+ import { ensureData } from "./response.js";
3
+ import { Sandbox } from "./sandbox.js";
4
+ function validateName(name) {
5
+ if (!/^[A-Za-z0-9._-]{1,128}$/.test(name) || name === "." || name === ".." || name.startsWith(".s0-write-")) {
6
+ throw new Error("invalid managed file name or namespace");
7
+ }
8
+ }
9
+ function validateSequence(value) {
10
+ if (typeof value !== "string" || !/^(0|[1-9][0-9]{0,19})$/.test(value) || BigInt(value) > 18446744073709551615n) {
11
+ throw new Error("invalid managed file mutation sequence");
12
+ }
13
+ }
14
+ function encode(content) {
15
+ if (!(content instanceof Uint8Array) || content.byteLength > 4 * 1024 * 1024)
16
+ throw new Error("invalid managed file content size or type");
17
+ let binary = "";
18
+ for (let i = 0; i < content.length; i += 8192)
19
+ binary += String.fromCharCode(...content.subarray(i, i + 8192));
20
+ return btoa(binary);
21
+ }
22
+ function decode(content) {
23
+ try {
24
+ if (typeof content !== "string" || content.length > 4 * Math.ceil((4 * 1024 * 1024) / 3))
25
+ throw new Error();
26
+ const binary = atob(content);
27
+ if (binary.length > 4 * 1024 * 1024 || btoa(binary) !== content)
28
+ throw new Error();
29
+ return Uint8Array.from(binary, c => c.charCodeAt(0));
30
+ }
31
+ catch {
32
+ throw new Error("invalid managed file response content");
33
+ }
34
+ }
35
+ /** Fixed-generation access to node-owned files, independent of guest execution.
36
+ * No automatic resume, generation discovery, fallback or write retry is performed.
37
+ * Sequences are shared across namespaces and do not track native guest refreshes.
38
+ */
39
+ export class ManagedFiles {
40
+ client;
41
+ id;
42
+ generation;
43
+ namespace;
44
+ constructor(client, id, options) {
45
+ this.client = client;
46
+ this.id = id;
47
+ if (!Number.isSafeInteger(options.runtimeGeneration) || options.runtimeGeneration <= 0)
48
+ throw new Error("invalid managed file runtime generation");
49
+ if (options.namespace !== undefined)
50
+ validateName(options.namespace);
51
+ this.generation = options.runtimeGeneration;
52
+ this.namespace = options.namespace;
53
+ }
54
+ state(value) {
55
+ if (value.runtimeGeneration !== this.generation)
56
+ throw new Error("managed file response generation changed");
57
+ validateSequence(value.mutationSequence);
58
+ return value;
59
+ }
60
+ /** Describes projection state; does not attest historical RootFS credential safety. */
61
+ async inspect() {
62
+ const response = await wrapApiCall(() => this.client.apispec.sandboxes.inspectSandboxManagedFiles({ id: this.id, runtimeGeneration: this.generation }));
63
+ return this.state(ensureData(response, "managed file response missing"));
64
+ }
65
+ async read(name) {
66
+ validateName(name);
67
+ const params = { id: this.id, runtimeGeneration: this.generation, name };
68
+ const response = await wrapApiCall(() => this.namespace === undefined
69
+ ? this.client.apispec.sandboxes.readSandboxManagedFile(params)
70
+ : this.client.apispec.sandboxes.readSandboxNamespacedManagedFile({ ...params, namespace: this.namespace }));
71
+ const value = this.state(ensureData(response, "managed file response missing"));
72
+ return { ...value, content: decode(value.content) };
73
+ }
74
+ /** On an ambiguous error, inspect/read to reconcile; never blindly fetch a new sequence and repeat. */
75
+ async write(name, content, expectedMutationSequence) {
76
+ validateName(name);
77
+ validateSequence(expectedMutationSequence);
78
+ const params = { id: this.id, runtimeGeneration: this.generation, name, managedFileWriteRequest: { content: encode(content), expectedMutationSequence } };
79
+ const response = await wrapApiCall(() => this.namespace === undefined
80
+ ? this.client.apispec.sandboxes.writeSandboxManagedFile(params)
81
+ : this.client.apispec.sandboxes.writeSandboxNamespacedManagedFile({ ...params, namespace: this.namespace }));
82
+ return this.state(ensureData(response, "managed file response missing"));
83
+ }
84
+ async delete(name, expectedMutationSequence) {
85
+ validateName(name);
86
+ validateSequence(expectedMutationSequence);
87
+ const params = { id: this.id, runtimeGeneration: this.generation, name, expectedMutationSequence };
88
+ const response = await wrapApiCall(() => this.namespace === undefined
89
+ ? this.client.apispec.sandboxes.deleteSandboxManagedFile(params)
90
+ : this.client.apispec.sandboxes.deleteSandboxNamespacedManagedFile({ ...params, namespace: this.namespace }));
91
+ return this.state(ensureData(response, "managed file response missing"));
92
+ }
93
+ }
94
+ Sandbox.prototype.managedFiles = function (options) {
95
+ return new ManagedFiles(this.client, this.id, options);
96
+ };
@@ -5,6 +5,10 @@ declare module "./sandbox.js" {
5
5
  interface Sandbox {
6
6
  listSessions(): Promise<ExecutionSession[]>;
7
7
  createSession(spec: ExecutionSessionSpec, options?: SessionCreateOptions): Promise<ExecutionSession>;
8
+ /** Read-only original creation receipt; never auto-resumes or creates. */
9
+ findConditionalSession(creationKey: string, runtimeGeneration: number): Promise<ExecutionSession>;
10
+ findRestoredConditionalSession(creationKey: string, runtimeGeneration: number, creationRuntimeGeneration: number): Promise<ExecutionSession>;
11
+ connectRestoredConditionalSession(sessionId: string, creationKey: string, runtimeGeneration: number, creationRuntimeGeneration: number, attemptId: string, options?: SessionWebSocketOptions): Promise<ExecutionSessionConnection>;
8
12
  getSession(sessionId: string): Promise<ExecutionSession>;
9
13
  updateSession(sessionId: string, spec: ExecutionSessionSpec): Promise<ExecutionSession>;
10
14
  deleteSession(sessionId: string): Promise<SuccessDeletedResponse>;
@@ -15,6 +19,7 @@ declare module "./sandbox.js" {
15
19
  resizeSessionTerminal(sessionId: string, request: ExecutionSessionTerminalResizeRequest): Promise<SuccessResizedResponse>;
16
20
  listSessionEvents(sessionId: string, options?: SessionEventOptions): Promise<ExecutionSessionEventPage>;
17
21
  watchSessionEvents(sessionId: string, options?: SessionEventStreamOptions): Promise<SessionEventStream>;
22
+ connectConditionalSession(sessionId: string, creationKey: string, runtimeGeneration: number, attemptId: string, options?: SessionWebSocketOptions): Promise<ExecutionSessionConnection>;
18
23
  connectSession(sessionId: string, options?: SessionWebSocketOptions): Promise<ExecutionSessionConnection>;
19
24
  }
20
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox_sessions.d.ts","sourceRoot":"","sources":["../src/sandbox_sessions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sandbox_sessions.d.ts","sourceRoot":"","sources":["../src/sandbox_sessions.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { models } from "./apispec_compat.js";
2
2
  import { APIError, wrapApiCall } from "./errors.js";
3
3
  import { ensureData, ensureModel } from "./response.js";
4
4
  import { Sandbox } from "./sandbox.js";
5
- import { WebSocketClient } from "./ws_client.js";
5
+ import { WebSocketClient, WebSocketUpgradeError } from "./ws_client.js";
6
6
  function getClient(sandbox) {
7
7
  return sandbox.client;
8
8
  }
@@ -11,6 +11,20 @@ Sandbox.prototype.listSessions = async function () {
11
11
  return ensureData(response, "list sessions returned empty response").sessions ?? [];
12
12
  };
13
13
  Sandbox.prototype.createSession = async function (spec, options) {
14
+ if (options?.runtimeGeneration !== undefined) {
15
+ if (!Number.isSafeInteger(options.runtimeGeneration) || options.runtimeGeneration <= 0 ||
16
+ !options.idempotencyKey?.trim() || options.idempotencyKey.length > 255) {
17
+ throw new Error("Conditional session creation requires a positive safe runtime generation and idempotency key");
18
+ }
19
+ const response = await wrapApiCall(() => getClient(this).apispec.sessions.apiV1SandboxesIdSessionsConditionalPost({
20
+ id: this.id, idempotencyKey: options.idempotencyKey,
21
+ conditionalExecutionSessionRequest: { sandboxId: this.id, runtimeGeneration: options.runtimeGeneration, spec },
22
+ }));
23
+ const session = ensureData(response, "conditional create session returned empty response");
24
+ if (session.runtimeGeneration !== options.runtimeGeneration)
25
+ throw new Error("Conditional session response has a different runtime generation; reconcile before retrying");
26
+ return session;
27
+ }
14
28
  const response = await wrapApiCall(() => getClient(this).apispec.sessions.apiV1SandboxesIdSessionsPost({
15
29
  id: this.id,
16
30
  executionSessionSpec: spec,
@@ -18,6 +32,37 @@ Sandbox.prototype.createSession = async function (spec, options) {
18
32
  }));
19
33
  return ensureData(response, "create session returned empty response");
20
34
  };
35
+ Sandbox.prototype.findConditionalSession = async function (creationKey, runtimeGeneration) {
36
+ if (!Number.isSafeInteger(runtimeGeneration) || runtimeGeneration <= 0 ||
37
+ !creationKey?.trim() || creationKey.length > 255) {
38
+ throw new Error("Conditional session lookup requires a positive safe runtime generation and original creation key");
39
+ }
40
+ const response = await wrapApiCall(() => getClient(this).apispec.sessions.apiV1SandboxesIdSessionsConditionalLookupGet({
41
+ id: this.id, runtimeGeneration, idempotencyKey: creationKey,
42
+ }));
43
+ const session = ensureData(response, "conditional session lookup returned empty response");
44
+ if (session.runtimeGeneration !== runtimeGeneration)
45
+ throw new Error("Conditional session response has a different runtime generation; reconcile before retrying");
46
+ return session;
47
+ };
48
+ /** Explicit restored original attempt; external lineage and credential admission are caller responsibilities. */
49
+ Sandbox.prototype.findRestoredConditionalSession = async function (creationKey, runtimeGeneration, creationRuntimeGeneration) {
50
+ if (!Number.isSafeInteger(creationRuntimeGeneration) || creationRuntimeGeneration <= 0 || creationRuntimeGeneration >= runtimeGeneration)
51
+ throw new Error("Restored lookup requires an earlier positive safe creation generation");
52
+ if (!Number.isSafeInteger(runtimeGeneration) || runtimeGeneration <= 0 ||
53
+ !creationKey?.trim() || creationKey.length > 255) {
54
+ throw new Error("Conditional session lookup requires a positive safe runtime generation and original creation key");
55
+ }
56
+ const response = await wrapApiCall(() => getClient(this).apispec.sessions.apiV1SandboxesIdSessionsConditionalLookupGet({
57
+ id: this.id, runtimeGeneration, creationRuntimeGeneration, idempotencyKey: creationKey,
58
+ }));
59
+ const session = ensureData(response, "conditional session lookup returned empty response");
60
+ if (session.runtimeGeneration !== runtimeGeneration)
61
+ throw new Error("Conditional session response has a different runtime generation; reconcile before retrying");
62
+ if (session.phase !== "running" || !session.attempt || session.attempt.runtimeGeneration !== creationRuntimeGeneration || session.attempt.finishedAt !== undefined)
63
+ throw new Error("Restored lookup requires the running original attempt");
64
+ return session;
65
+ };
21
66
  Sandbox.prototype.getSession = async function (sessionId) {
22
67
  const response = await wrapApiCall(() => getClient(this).apispec.sessions.apiV1SandboxesIdSessionsSessionIdGet({
23
68
  id: this.id,
@@ -113,6 +158,63 @@ Sandbox.prototype.connectSession = async function (sessionId, options) {
113
158
  await socket.waitForOpen();
114
159
  return new ExecutionSessionConnection(socket);
115
160
  };
161
+ /** Exact conditional attachment; no retry, auto-resume or ordinary fallback. */
162
+ Sandbox.prototype.connectConditionalSession = async function (sessionId, creationKey, runtimeGeneration, attemptId, options) {
163
+ if (!sessionId || !attemptId || !creationKey.trim() || creationKey.length > 255 ||
164
+ !Number.isSafeInteger(runtimeGeneration) || runtimeGeneration <= 0 ||
165
+ (options?.after !== undefined && (!Number.isSafeInteger(options.after) || options.after < 0))) {
166
+ throw new Error("Conditional attachment requires session, creation key, positive safe generation, attempt and nonnegative safe cursor");
167
+ }
168
+ const client = getClient(this);
169
+ const path = `/api/v1/sandboxes/${encodeURIComponent(this.id)}/sessions/${encodeURIComponent(sessionId)}/conditional/ws`;
170
+ const wsUrl = new URL(client.websocketUrl(path));
171
+ wsUrl.searchParams.set("runtime_generation", String(runtimeGeneration));
172
+ wsUrl.searchParams.set("attempt_id", attemptId);
173
+ if (options?.after !== undefined)
174
+ wsUrl.searchParams.set("after", String(options.after));
175
+ const headers = { ...await client.wsHeaders(), "Idempotency-Key": creationKey };
176
+ const socket = await WebSocketClient.connect(wsUrl.toString(), { headers, singleAttempt: true });
177
+ try {
178
+ await socket.waitForOpen();
179
+ }
180
+ catch (error) {
181
+ if (error instanceof WebSocketUpgradeError)
182
+ throw new APIError({ statusCode: error.statusCode,
183
+ code: error.statusCode === 410 ? "event_cursor_expired" : undefined, message: "Conditional session attachment rejected" });
184
+ throw error;
185
+ }
186
+ return new ExecutionSessionConnection(socket);
187
+ };
188
+ /** Explicit restored attachment; never retries or creates. */
189
+ Sandbox.prototype.connectRestoredConditionalSession = async function (sessionId, creationKey, runtimeGeneration, creationRuntimeGeneration, attemptId, options) {
190
+ if (!Number.isSafeInteger(creationRuntimeGeneration) || creationRuntimeGeneration <= 0 || creationRuntimeGeneration >= runtimeGeneration)
191
+ throw new Error("Restored attachment requires an earlier positive safe creation generation");
192
+ if (!sessionId || !attemptId || !creationKey.trim() || creationKey.length > 255 ||
193
+ !Number.isSafeInteger(runtimeGeneration) || runtimeGeneration <= 0 ||
194
+ (options?.after !== undefined && (!Number.isSafeInteger(options.after) || options.after < 0))) {
195
+ throw new Error("Conditional attachment requires session, creation key, positive safe generation, attempt and nonnegative safe cursor");
196
+ }
197
+ const client = getClient(this);
198
+ const path = `/api/v1/sandboxes/${encodeURIComponent(this.id)}/sessions/${encodeURIComponent(sessionId)}/conditional/ws`;
199
+ const wsUrl = new URL(client.websocketUrl(path));
200
+ wsUrl.searchParams.set("runtime_generation", String(runtimeGeneration));
201
+ wsUrl.searchParams.set("creation_runtime_generation", String(creationRuntimeGeneration));
202
+ wsUrl.searchParams.set("attempt_id", attemptId);
203
+ if (options?.after !== undefined)
204
+ wsUrl.searchParams.set("after", String(options.after));
205
+ const headers = { ...await client.wsHeaders(), "Idempotency-Key": creationKey };
206
+ const socket = await WebSocketClient.connect(wsUrl.toString(), { headers, singleAttempt: true });
207
+ try {
208
+ await socket.waitForOpen();
209
+ }
210
+ catch (error) {
211
+ if (error instanceof WebSocketUpgradeError)
212
+ throw new APIError({ statusCode: error.statusCode,
213
+ code: error.statusCode === 410 ? "event_cursor_expired" : undefined, message: "Conditional session attachment rejected" });
214
+ throw error;
215
+ }
216
+ return new ExecutionSessionConnection(socket);
217
+ };
116
218
  export class ExecutionSessionEventStream {
117
219
  response;
118
220
  body;
@@ -11,6 +11,8 @@ type WebSocketLike = EventTargetSocket | EventEmitterSocket;
11
11
  type WebSocketClientOptions = {
12
12
  headers?: Record<string, string>;
13
13
  connectTimeoutMs?: number;
14
+ /** Use the explicit ws transport: native runtimes may retry authentication. */
15
+ singleAttempt?: boolean;
14
16
  resolveWebSocketConstructor?: (options: WebSocketClientOptions) => Promise<WebSocketConstructor>;
15
17
  };
16
18
  export declare class WebSocketClient {
@@ -18,6 +20,7 @@ export declare class WebSocketClient {
18
20
  private readonly pendingSends;
19
21
  private closePending;
20
22
  private readonly connectTimeoutMs;
23
+ private upgradeStatus?;
21
24
  static connect(url: string, options?: WebSocketClientOptions): Promise<WebSocketClient>;
22
25
  private constructor();
23
26
  get readyState(): number;
@@ -30,5 +33,10 @@ export declare class WebSocketClient {
30
33
  waitForMessage(timeoutMs?: number): Promise<WebSocketRawData | null>;
31
34
  private flushPendingSends;
32
35
  }
36
+ /** Internal status-only failure for an explicit, single HTTP upgrade. */
37
+ export declare class WebSocketUpgradeError extends Error {
38
+ readonly statusCode: number;
39
+ constructor(statusCode: number);
40
+ }
33
41
  export {};
34
42
  //# sourceMappingURL=ws_client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ws_client.d.ts","sourceRoot":"","sources":["../src/ws_client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,gBAAgB,MAAM,IAAI,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,WAAW,GACX,UAAU,GACV,MAAM,GACN,MAAM,EAAE,CAAC;AAEb,KAAK,oBAAoB,GAAG,KAAK,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,OAAO,KAAK,aAAa,CAAC;AAQ7F,KAAK,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,kBAAkB,GAAG,qBAAqB,CAAC,GAAG;IACvH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,KAAK,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,GAAG;IAC1G,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,KAAK,aAAa,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;AAS5D,KAAK,sBAAsB,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2BAA2B,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAClG,CAAC;AAEF,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;WAE7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,eAAe,CAAC;IAKjG,OAAO;IAaP,IAAI,UAAU,IAAI,MAAM,CAEvB;IAEK,WAAW,CAAC,SAAS,SAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCnE,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,GAAG,MAAM,IAAI;IAIhE,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAIxC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,MAAM,IAAI;IAIlD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAY3B,KAAK,IAAI,IAAI;IAYP,cAAc,CAAC,SAAS,SAAQ,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAiCzE,OAAO,CAAC,iBAAiB;CAQ1B"}
1
+ {"version":3,"file":"ws_client.d.ts","sourceRoot":"","sources":["../src/ws_client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,gBAAgB,MAAM,IAAI,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,WAAW,GACX,UAAU,GACV,MAAM,GACN,MAAM,EAAE,CAAC;AAEb,KAAK,oBAAoB,GAAG,KAAK,GAAG,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,OAAO,KAAK,aAAa,CAAC;AAQ7F,KAAK,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,kBAAkB,GAAG,qBAAqB,CAAC,GAAG;IACvH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,KAAK,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC,GAAG;IAC1G,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,KAAK,aAAa,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;AAS5D,KAAK,sBAAsB,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2BAA2B,CAAC,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAClG,CAAC;AAEF,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,aAAa,CAAC,CAAS;WAElB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,eAAe,CAAC;IAKjG,OAAO;IAoBP,IAAI,UAAU,IAAI,MAAM,CAEvB;IAEK,WAAW,CAAC,SAAS,SAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCnE,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,GAAG,MAAM,IAAI;IAIhE,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAIxC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,MAAM,IAAI;IAIlD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAY3B,KAAK,IAAI,IAAI;IAYP,cAAc,CAAC,SAAS,SAAQ,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAiCzE,OAAO,CAAC,iBAAiB;CAQ1B;AAED,yEAAyE;AACzE,qBAAa,qBAAsB,SAAQ,KAAK;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM;CACxC"}
package/dist/ws_client.js CHANGED
@@ -9,6 +9,7 @@ export class WebSocketClient {
9
9
  pendingSends = [];
10
10
  closePending = false;
11
11
  connectTimeoutMs;
12
+ upgradeStatus;
12
13
  static async connect(url, options = {}) {
13
14
  const socket = await createWebSocket(url, options);
14
15
  return new WebSocketClient(socket, options);
@@ -16,6 +17,13 @@ export class WebSocketClient {
16
17
  constructor(socket, options = {}) {
17
18
  this.connectTimeoutMs = options.connectTimeoutMs ?? 10000;
18
19
  this.socket = socket;
20
+ if (options.singleAttempt && "on" in socket) {
21
+ // Keep only the status. Do not retain response headers, bodies or URLs.
22
+ socket.once("unexpected-response", (_request, response) => {
23
+ this.upgradeStatus = response.statusCode;
24
+ socket.close();
25
+ });
26
+ }
19
27
  addOpenListener(this.socket, () => {
20
28
  this.flushPendingSends();
21
29
  if (this.closePending) {
@@ -44,7 +52,9 @@ export class WebSocketClient {
44
52
  };
45
53
  const onError = (err) => {
46
54
  cleanup();
47
- reject(err instanceof Error ? err : new Error("websocket error"));
55
+ reject(this.upgradeStatus === undefined
56
+ ? (err instanceof Error ? err : new Error("websocket error"))
57
+ : new WebSocketUpgradeError(this.upgradeStatus));
48
58
  };
49
59
  const onClose = () => {
50
60
  cleanup();
@@ -131,6 +141,14 @@ export class WebSocketClient {
131
141
  }
132
142
  }
133
143
  }
144
+ /** Internal status-only failure for an explicit, single HTTP upgrade. */
145
+ export class WebSocketUpgradeError extends Error {
146
+ statusCode;
147
+ constructor(statusCode) {
148
+ super("WebSocket upgrade rejected");
149
+ this.statusCode = statusCode;
150
+ }
151
+ }
134
152
  async function createWebSocket(url, options) {
135
153
  const resolveConstructor = options.resolveWebSocketConstructor ?? defaultResolveWebSocketConstructor;
136
154
  const WebSocketCtor = await resolveConstructor(options);
@@ -143,7 +161,7 @@ async function createWebSocket(url, options) {
143
161
  return socket;
144
162
  }
145
163
  async function defaultResolveWebSocketConstructor(options) {
146
- if (typeof globalThis.WebSocket === "function" && (!options.headers || isNodeLikeRuntime())) {
164
+ if (!options.singleAttempt && typeof globalThis.WebSocket === "function" && (!options.headers || isNodeLikeRuntime())) {
147
165
  return globalThis.WebSocket;
148
166
  }
149
167
  const imported = await importWsModule();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sandbox0",
3
- "version": "0.10.3",
3
+ "version": "0.10.5",
4
4
  "description": "Sandbox0 JavaScript/TypeScript SDK",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Sandbox0 Team",
@@ -29,7 +29,7 @@
29
29
  "lint:eve": "npm run build && npm --prefix packages/eve run lint",
30
30
  "lint:e2e": "tsc -p tsconfig.e2e.json --noEmit",
31
31
  "lint:unit": "tsc -p tsconfig.unit.json --noEmit",
32
- "generate:apispec": "rm -rf src/apispec && openapi-generator-cli generate -i openapi.yaml -g typescript-fetch -o src/apispec -c openapi-generator-config.yaml",
32
+ "generate:apispec": "rm -rf src/apispec && openapi-generator-cli generate -i openapi.yaml -g typescript-fetch -o src/apispec -c openapi-generator-config.yaml && node scripts/normalize-apispec.mjs",
33
33
  "test": "npm run test:unit",
34
34
  "test:e2e": "npm run test:e2e:sdk && npm run test:e2e:frameworks",
35
35
  "test:e2e:frameworks": "npm run test:e2e:eve",