@phpsandbox/sdk 0.0.29 → 0.0.30
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/README.md +18 -0
- package/dist/browser/phpsandbox-sdk.esm.js +187 -6
- package/dist/browser/phpsandbox-sdk.esm.js.map +3 -3
- package/dist/browser/phpsandbox-sdk.esm.min.js +2 -2
- package/dist/browser/phpsandbox-sdk.esm.min.js.map +4 -4
- package/dist/browser/phpsandbox-sdk.iife.js +187 -6
- package/dist/browser/phpsandbox-sdk.iife.js.map +3 -3
- package/dist/browser/phpsandbox-sdk.iife.min.js +2 -2
- package/dist/browser/phpsandbox-sdk.iife.min.js.map +4 -4
- package/dist/errors/index.d.ts +4 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +7 -0
- package/dist/errors/index.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -1
- package/dist/services.d.ts +78 -0
- package/dist/services.d.ts.map +1 -0
- package/dist/services.js +102 -0
- package/dist/services.js.map +1 -0
- package/dist/socket/index.d.ts +9 -0
- package/dist/socket/index.d.ts.map +1 -1
- package/dist/socket/index.js +46 -5
- package/dist/socket/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -336,6 +336,7 @@ var PHPSandbox = (() => {
|
|
|
336
336
|
NotebookSecretApi: () => NotebookSecretApi,
|
|
337
337
|
NotebookSecrets: () => NotebookSecrets,
|
|
338
338
|
NotebookState: () => NotebookState,
|
|
339
|
+
NotebookUnavailableError: () => NotebookUnavailableError,
|
|
339
340
|
PHPSandbox: () => PHPSandbox,
|
|
340
341
|
PHPSandboxError: () => PHPSandboxError,
|
|
341
342
|
PromiseTimeoutError: () => PromiseTimeoutError,
|
|
@@ -614,6 +615,13 @@ var PHPSandbox = (() => {
|
|
|
614
615
|
return new _SendTimeoutError(error.message, error.time);
|
|
615
616
|
}
|
|
616
617
|
};
|
|
618
|
+
var NotebookUnavailableError = class extends Error {
|
|
619
|
+
constructor(message = "Notebook is no longer available", raw = {}) {
|
|
620
|
+
super(message);
|
|
621
|
+
this.raw = raw;
|
|
622
|
+
this.name = "NotebookUnavailableError";
|
|
623
|
+
}
|
|
624
|
+
};
|
|
617
625
|
|
|
618
626
|
// src/utils/promise.ts
|
|
619
627
|
var timeout = (prom, time) => {
|
|
@@ -1061,6 +1069,103 @@ var PHPSandbox = (() => {
|
|
|
1061
1069
|
}
|
|
1062
1070
|
};
|
|
1063
1071
|
|
|
1072
|
+
// src/services.ts
|
|
1073
|
+
var Services = class {
|
|
1074
|
+
constructor(okra) {
|
|
1075
|
+
this.okra = okra;
|
|
1076
|
+
}
|
|
1077
|
+
list() {
|
|
1078
|
+
return this.okra.invoke("service.list");
|
|
1079
|
+
}
|
|
1080
|
+
run(name) {
|
|
1081
|
+
return this.okra.invoke("service.run", { name });
|
|
1082
|
+
}
|
|
1083
|
+
stop(name) {
|
|
1084
|
+
return this.okra.invoke("service.stop", { name });
|
|
1085
|
+
}
|
|
1086
|
+
onLog(id, handler) {
|
|
1087
|
+
return this.okra.listen(`service.log.${id}`, handler);
|
|
1088
|
+
}
|
|
1089
|
+
listen(event, handler) {
|
|
1090
|
+
return this.okra.listen(event, handler);
|
|
1091
|
+
}
|
|
1092
|
+
logs(name, options = {}) {
|
|
1093
|
+
if (options.follow) {
|
|
1094
|
+
return this.followLogs(name, options);
|
|
1095
|
+
}
|
|
1096
|
+
return this.okra.invoke("service.logs", {
|
|
1097
|
+
name,
|
|
1098
|
+
tail: options.tail
|
|
1099
|
+
}).then((response) => {
|
|
1100
|
+
if (!("output" in response)) {
|
|
1101
|
+
throw new Error(`Unexpected service.logs response for ${name}`);
|
|
1102
|
+
}
|
|
1103
|
+
return response.output;
|
|
1104
|
+
});
|
|
1105
|
+
}
|
|
1106
|
+
followLogs(name, options) {
|
|
1107
|
+
const id = options.id || nanoid();
|
|
1108
|
+
const disposables = /* @__PURE__ */ new Set();
|
|
1109
|
+
let controller = null;
|
|
1110
|
+
let closed = false;
|
|
1111
|
+
const dispose = () => {
|
|
1112
|
+
for (const disposable of disposables) {
|
|
1113
|
+
disposable.dispose();
|
|
1114
|
+
}
|
|
1115
|
+
disposables.clear();
|
|
1116
|
+
};
|
|
1117
|
+
const close = () => {
|
|
1118
|
+
if (closed) {
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
closed = true;
|
|
1122
|
+
dispose();
|
|
1123
|
+
if (controller) {
|
|
1124
|
+
try {
|
|
1125
|
+
controller.close();
|
|
1126
|
+
} catch {
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
const fail = (error) => {
|
|
1131
|
+
if (closed) {
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
closed = true;
|
|
1135
|
+
dispose();
|
|
1136
|
+
if (controller) {
|
|
1137
|
+
controller.error(error);
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
const stop = once(() => {
|
|
1141
|
+
close();
|
|
1142
|
+
return this.okra.invoke("service.stop-logs", { id });
|
|
1143
|
+
});
|
|
1144
|
+
const output = new ReadableStream({
|
|
1145
|
+
start: (_controller) => {
|
|
1146
|
+
controller = _controller;
|
|
1147
|
+
disposables.add(
|
|
1148
|
+
this.onLog(id, (data) => {
|
|
1149
|
+
controller?.enqueue(data.output);
|
|
1150
|
+
})
|
|
1151
|
+
);
|
|
1152
|
+
void this.okra.invoke("service.logs", {
|
|
1153
|
+
name,
|
|
1154
|
+
tail: options.tail,
|
|
1155
|
+
follow: true,
|
|
1156
|
+
id
|
|
1157
|
+
}).catch((error) => {
|
|
1158
|
+
fail(error);
|
|
1159
|
+
});
|
|
1160
|
+
},
|
|
1161
|
+
cancel: () => {
|
|
1162
|
+
void stop();
|
|
1163
|
+
}
|
|
1164
|
+
});
|
|
1165
|
+
return { id, output, stop };
|
|
1166
|
+
}
|
|
1167
|
+
};
|
|
1168
|
+
|
|
1064
1169
|
// node_modules/@msgpack/msgpack/dist.esm/utils/utf8.mjs
|
|
1065
1170
|
function utf8Count(str) {
|
|
1066
1171
|
const strLength = str.length;
|
|
@@ -3084,6 +3189,7 @@ var PHPSandbox = (() => {
|
|
|
3084
3189
|
this.closed = false;
|
|
3085
3190
|
this.disposables = new NamedDisposable();
|
|
3086
3191
|
this.connectPromise = null;
|
|
3192
|
+
this.terminalError = null;
|
|
3087
3193
|
this.pingIntervalStarted = false;
|
|
3088
3194
|
// Connection health monitoring
|
|
3089
3195
|
this.connectionStats = {
|
|
@@ -3115,7 +3221,7 @@ var PHPSandbox = (() => {
|
|
|
3115
3221
|
const startClosed = options.startClosed !== false;
|
|
3116
3222
|
this.rws = new reconnecting_websocket_mjs_default(this.url.toString(), [], {
|
|
3117
3223
|
WebSocket: globalThis.WebSocket ?? browser_default,
|
|
3118
|
-
connectionTimeout: options.connectionTimeout
|
|
3224
|
+
connectionTimeout: options.connectionTimeout,
|
|
3119
3225
|
maxReconnectionDelay: 2e3,
|
|
3120
3226
|
minReconnectionDelay: 200,
|
|
3121
3227
|
maxEnqueuedMessages: 0,
|
|
@@ -3158,6 +3264,9 @@ var PHPSandbox = (() => {
|
|
|
3158
3264
|
* Ensure the websocket is open without requiring an application-level roundtrip.
|
|
3159
3265
|
*/
|
|
3160
3266
|
connect() {
|
|
3267
|
+
if (this.terminalError) {
|
|
3268
|
+
return Promise.reject(this.terminalError);
|
|
3269
|
+
}
|
|
3161
3270
|
return __privateMethod(this, _Transport_instances, connect_fn).call(this);
|
|
3162
3271
|
}
|
|
3163
3272
|
id() {
|
|
@@ -3214,7 +3323,12 @@ var PHPSandbox = (() => {
|
|
|
3214
3323
|
return;
|
|
3215
3324
|
}
|
|
3216
3325
|
if (event === "Events.BootError" /* BootError */) {
|
|
3326
|
+
const error = new NotebookUnavailableError(
|
|
3327
|
+
data?.message || "Notebook is no longer available",
|
|
3328
|
+
data || {}
|
|
3329
|
+
);
|
|
3217
3330
|
this.log("error", "Boot error received", { data });
|
|
3331
|
+
this.terminate(error, 4e3, error.message);
|
|
3218
3332
|
return;
|
|
3219
3333
|
}
|
|
3220
3334
|
if (event === "response" /* Response */) {
|
|
@@ -3273,6 +3387,11 @@ var PHPSandbox = (() => {
|
|
|
3273
3387
|
listen(event, listener, _context) {
|
|
3274
3388
|
return this.eventEmitter.listen(event, listener);
|
|
3275
3389
|
}
|
|
3390
|
+
onDidBootError(listener) {
|
|
3391
|
+
this.eventEmitter.listen("transport.boot_error", (event) => {
|
|
3392
|
+
listener(event.error);
|
|
3393
|
+
});
|
|
3394
|
+
}
|
|
3276
3395
|
removeListener(event, listener) {
|
|
3277
3396
|
this.eventEmitter.removeListener(event, listener);
|
|
3278
3397
|
}
|
|
@@ -3299,6 +3418,9 @@ var PHPSandbox = (() => {
|
|
|
3299
3418
|
get isClosed() {
|
|
3300
3419
|
return this.closed;
|
|
3301
3420
|
}
|
|
3421
|
+
getTerminalError() {
|
|
3422
|
+
return this.terminalError;
|
|
3423
|
+
}
|
|
3302
3424
|
get status() {
|
|
3303
3425
|
return {
|
|
3304
3426
|
0: "CONNECTING",
|
|
@@ -3308,6 +3430,9 @@ var PHPSandbox = (() => {
|
|
|
3308
3430
|
}[this.rws.readyState];
|
|
3309
3431
|
}
|
|
3310
3432
|
async call(action, data = {}, options = {}) {
|
|
3433
|
+
if (this.terminalError) {
|
|
3434
|
+
throw this.terminalError;
|
|
3435
|
+
}
|
|
3311
3436
|
if (this.isRateLimited()) {
|
|
3312
3437
|
throw new RateLimitError("Rate limit exceeded - too many requests");
|
|
3313
3438
|
}
|
|
@@ -3324,6 +3449,10 @@ var PHPSandbox = (() => {
|
|
|
3324
3449
|
this.eventEmitter.removeListener(errorEvent);
|
|
3325
3450
|
};
|
|
3326
3451
|
const handler = async (resolve, reject) => {
|
|
3452
|
+
if (this.terminalError) {
|
|
3453
|
+
reject(this.terminalError);
|
|
3454
|
+
return;
|
|
3455
|
+
}
|
|
3327
3456
|
const abortError = new DOMException("Request aborted", "AbortError");
|
|
3328
3457
|
if (options.abortSignal?.aborted) {
|
|
3329
3458
|
reject(abortError);
|
|
@@ -3375,7 +3504,7 @@ var PHPSandbox = (() => {
|
|
|
3375
3504
|
reject(new RateLimitError(_ev.reason || "Rate limit exceeded", _ev));
|
|
3376
3505
|
return;
|
|
3377
3506
|
}
|
|
3378
|
-
reject(new Error(`Connection lost to the notebook during request: ${_ev.reason || "Unknown reason"}`));
|
|
3507
|
+
reject(this.terminalError || new Error(`Connection lost to the notebook during request: ${_ev.reason || "Unknown reason"}`));
|
|
3379
3508
|
};
|
|
3380
3509
|
this.rws.addEventListener("close", closeHandler);
|
|
3381
3510
|
this.rws.addEventListener("error", closeHandler);
|
|
@@ -3411,7 +3540,7 @@ var PHPSandbox = (() => {
|
|
|
3411
3540
|
try {
|
|
3412
3541
|
return await sender();
|
|
3413
3542
|
} catch (e) {
|
|
3414
|
-
if (e instanceof ErrorEvent || e instanceof RateLimitError || e instanceof InvalidConfigurationError || e instanceof InvalidMessageError || e instanceof DOMException) {
|
|
3543
|
+
if (e instanceof ErrorEvent || e instanceof RateLimitError || e instanceof InvalidConfigurationError || e instanceof InvalidMessageError || e instanceof NotebookUnavailableError || e instanceof DOMException) {
|
|
3415
3544
|
this.log("debug", "Non-retryable error, bailing", {
|
|
3416
3545
|
error: e.message,
|
|
3417
3546
|
attempt
|
|
@@ -3463,6 +3592,9 @@ var PHPSandbox = (() => {
|
|
|
3463
3592
|
* This preserves all event listeners and state.
|
|
3464
3593
|
*/
|
|
3465
3594
|
reconnect() {
|
|
3595
|
+
if (this.terminalError) {
|
|
3596
|
+
throw this.terminalError;
|
|
3597
|
+
}
|
|
3466
3598
|
if (this.closed) {
|
|
3467
3599
|
throw new Error("Cannot reconnect a closed transport. The transport has been permanently closed.");
|
|
3468
3600
|
}
|
|
@@ -3477,6 +3609,16 @@ var PHPSandbox = (() => {
|
|
|
3477
3609
|
}
|
|
3478
3610
|
this.close();
|
|
3479
3611
|
}
|
|
3612
|
+
terminate(error, code = 4e3, reason = error.message) {
|
|
3613
|
+
this.terminalError = error;
|
|
3614
|
+
if (error instanceof NotebookUnavailableError) {
|
|
3615
|
+
this.eventEmitter.emit("transport.boot_error", {
|
|
3616
|
+
error,
|
|
3617
|
+
timestamp: Date.now()
|
|
3618
|
+
});
|
|
3619
|
+
}
|
|
3620
|
+
this.close(code, reason);
|
|
3621
|
+
}
|
|
3480
3622
|
close(code, reason) {
|
|
3481
3623
|
if (this.closed) {
|
|
3482
3624
|
return;
|
|
@@ -3484,9 +3626,9 @@ var PHPSandbox = (() => {
|
|
|
3484
3626
|
this.log("info", "Closing transport connection", { code, reason });
|
|
3485
3627
|
this.connectPromise = null;
|
|
3486
3628
|
const queuedCount = this.messageQueue.length;
|
|
3629
|
+
const closeError = this.terminalError || new Error("Connection closed while message was queued");
|
|
3487
3630
|
this.messageQueue.forEach((msg) => {
|
|
3488
|
-
|
|
3489
|
-
msg.reject(new Error("Connection closed while message was queued"));
|
|
3631
|
+
msg.reject(closeError);
|
|
3490
3632
|
});
|
|
3491
3633
|
this.messageQueue = [];
|
|
3492
3634
|
if (queuedCount > 0) {
|
|
@@ -3574,6 +3716,9 @@ var PHPSandbox = (() => {
|
|
|
3574
3716
|
this.log("error", "Connection closed due to policy violation");
|
|
3575
3717
|
this.clearOldQueuedMessages();
|
|
3576
3718
|
return "stop";
|
|
3719
|
+
case 4e3:
|
|
3720
|
+
this.log("info", "Connection closed due to terminal notebook error");
|
|
3721
|
+
return "stop";
|
|
3577
3722
|
default:
|
|
3578
3723
|
this.log("warn", `Unknown close code: ${code}, will reconnect`);
|
|
3579
3724
|
return "reconnect";
|
|
@@ -3789,6 +3934,9 @@ var PHPSandbox = (() => {
|
|
|
3789
3934
|
* by caching the connection promise.
|
|
3790
3935
|
*/
|
|
3791
3936
|
connect_fn = function() {
|
|
3937
|
+
if (this.terminalError) {
|
|
3938
|
+
return Promise.reject(this.terminalError);
|
|
3939
|
+
}
|
|
3792
3940
|
if (this.isConnected) {
|
|
3793
3941
|
return Promise.resolve();
|
|
3794
3942
|
}
|
|
@@ -4835,9 +4983,14 @@ var PHPSandbox = (() => {
|
|
|
4835
4983
|
this.laravel = new Lravel(this);
|
|
4836
4984
|
this.shell = new Shell(this);
|
|
4837
4985
|
this.git = new Git(this);
|
|
4986
|
+
this.services = new Services(this);
|
|
4838
4987
|
this.secrets = new NotebookSecrets(client, this.data.id);
|
|
4839
4988
|
}
|
|
4840
4989
|
async ready() {
|
|
4990
|
+
const terminalError = this.socket.getTerminalError();
|
|
4991
|
+
if (terminalError) {
|
|
4992
|
+
throw terminalError;
|
|
4993
|
+
}
|
|
4841
4994
|
const ready = async () => {
|
|
4842
4995
|
if (this.client.options.startClosed && !this.socket.isConnected) {
|
|
4843
4996
|
await this.socket.connect();
|
|
@@ -4850,7 +5003,9 @@ var PHPSandbox = (() => {
|
|
|
4850
5003
|
return this.client.notebook.fork(this.data.id);
|
|
4851
5004
|
}
|
|
4852
5005
|
delete() {
|
|
4853
|
-
return this.client.notebook.delete(this.data.id)
|
|
5006
|
+
return this.client.notebook.delete(this.data.id).then(() => {
|
|
5007
|
+
this.socket.terminate(new NotebookUnavailableError("Notebook has been deleted.", { id: this.data.id }));
|
|
5008
|
+
});
|
|
4854
5009
|
}
|
|
4855
5010
|
stop() {
|
|
4856
5011
|
return this.container.stop();
|
|
@@ -4874,6 +5029,10 @@ var PHPSandbox = (() => {
|
|
|
4874
5029
|
!this.socket.isClosed && this.socket.disconnect();
|
|
4875
5030
|
}
|
|
4876
5031
|
connected() {
|
|
5032
|
+
const terminalError = this.socket.getTerminalError();
|
|
5033
|
+
if (terminalError) {
|
|
5034
|
+
return Promise.reject(terminalError);
|
|
5035
|
+
}
|
|
4877
5036
|
if (this.socket.isConnected) {
|
|
4878
5037
|
return Promise.resolve(this);
|
|
4879
5038
|
}
|
|
@@ -4881,18 +5040,24 @@ var PHPSandbox = (() => {
|
|
|
4881
5040
|
try {
|
|
4882
5041
|
this.socket.onDidConnect(() => resolve(this));
|
|
4883
5042
|
this.socket.onDidClose(() => reject(new Error("Connection closed")));
|
|
5043
|
+
this.socket.onDidBootError((error) => reject(error));
|
|
4884
5044
|
} catch (e) {
|
|
4885
5045
|
reject(e);
|
|
4886
5046
|
}
|
|
4887
5047
|
});
|
|
4888
5048
|
}
|
|
4889
5049
|
whenConnected() {
|
|
5050
|
+
const terminalError = this.socket.getTerminalError();
|
|
5051
|
+
if (terminalError) {
|
|
5052
|
+
return Promise.reject(terminalError);
|
|
5053
|
+
}
|
|
4890
5054
|
if (this.socket.isConnected) {
|
|
4891
5055
|
return Promise.resolve(this);
|
|
4892
5056
|
}
|
|
4893
5057
|
return new Promise((resolve, reject) => {
|
|
4894
5058
|
try {
|
|
4895
5059
|
this.socket.onDidConnect(() => resolve(this));
|
|
5060
|
+
this.socket.onDidBootError((error) => reject(error));
|
|
4896
5061
|
} catch (e) {
|
|
4897
5062
|
reject(e);
|
|
4898
5063
|
}
|
|
@@ -4909,6 +5074,11 @@ var PHPSandbox = (() => {
|
|
|
4909
5074
|
this.socket.emit("okra.disconnected");
|
|
4910
5075
|
this.initialized = false;
|
|
4911
5076
|
});
|
|
5077
|
+
this.socket.onDidBootError((error) => {
|
|
5078
|
+
this.socket.emit("okra.boot_error", error);
|
|
5079
|
+
this.socket.emit("okra.disconnected");
|
|
5080
|
+
this.initialized = false;
|
|
5081
|
+
});
|
|
4912
5082
|
}
|
|
4913
5083
|
onDidConnect(handler) {
|
|
4914
5084
|
this.socket.removeListener("okra.connected", handler);
|
|
@@ -4921,6 +5091,11 @@ var PHPSandbox = (() => {
|
|
|
4921
5091
|
this.disposables.push(disposable);
|
|
4922
5092
|
return disposable;
|
|
4923
5093
|
}
|
|
5094
|
+
onDidBootError(handler) {
|
|
5095
|
+
const disposable = this.socket.listen("okra.boot_error", handler);
|
|
5096
|
+
this.disposables.push(disposable);
|
|
5097
|
+
return disposable;
|
|
5098
|
+
}
|
|
4924
5099
|
update() {
|
|
4925
5100
|
return this.invoke("notebook.update");
|
|
4926
5101
|
}
|
|
@@ -4946,6 +5121,7 @@ var PHPSandbox = (() => {
|
|
|
4946
5121
|
init_fn = function() {
|
|
4947
5122
|
__privateSet(this, _initPromise, new Promise((resolve, reject) => {
|
|
4948
5123
|
const initializationListener = this.onDidInitialize((result) => {
|
|
5124
|
+
bootErrorListener.dispose();
|
|
4949
5125
|
initializationListener.dispose();
|
|
4950
5126
|
this.initialized = result;
|
|
4951
5127
|
if (result.type === "error") {
|
|
@@ -4954,6 +5130,11 @@ var PHPSandbox = (() => {
|
|
|
4954
5130
|
}
|
|
4955
5131
|
resolve(result);
|
|
4956
5132
|
});
|
|
5133
|
+
const bootErrorListener = this.onDidBootError((error) => {
|
|
5134
|
+
initializationListener.dispose();
|
|
5135
|
+
bootErrorListener.dispose();
|
|
5136
|
+
reject(error);
|
|
5137
|
+
});
|
|
4957
5138
|
}));
|
|
4958
5139
|
return __privateGet(this, _initPromise);
|
|
4959
5140
|
};
|