@phpsandbox/sdk 0.0.28 → 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 +188 -8
- 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 +188 -8
- 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/filesystem.d.ts +1 -1
- package/dist/filesystem.d.ts.map +1 -1
- package/dist/filesystem.js +1 -2
- package/dist/filesystem.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,
|
|
@@ -574,8 +575,7 @@ var PHPSandbox = (() => {
|
|
|
574
575
|
};
|
|
575
576
|
const subscription = new FilesystemSubscription(path, this.okra, wrappedDisposable);
|
|
576
577
|
this.watches.set(path, { options, path, onDidChange });
|
|
577
|
-
this.okra.invoke("fs.watch", { path, options });
|
|
578
|
-
return subscription;
|
|
578
|
+
return this.okra.invoke("fs.watch", { path, options }).then(() => subscription);
|
|
579
579
|
}
|
|
580
580
|
exists(path) {
|
|
581
581
|
return this.stat(path).then(() => true).catch(() => false);
|
|
@@ -615,6 +615,13 @@ var PHPSandbox = (() => {
|
|
|
615
615
|
return new _SendTimeoutError(error.message, error.time);
|
|
616
616
|
}
|
|
617
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
|
+
};
|
|
618
625
|
|
|
619
626
|
// src/utils/promise.ts
|
|
620
627
|
var timeout = (prom, time) => {
|
|
@@ -1062,6 +1069,103 @@ var PHPSandbox = (() => {
|
|
|
1062
1069
|
}
|
|
1063
1070
|
};
|
|
1064
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
|
+
|
|
1065
1169
|
// node_modules/@msgpack/msgpack/dist.esm/utils/utf8.mjs
|
|
1066
1170
|
function utf8Count(str) {
|
|
1067
1171
|
const strLength = str.length;
|
|
@@ -3085,6 +3189,7 @@ var PHPSandbox = (() => {
|
|
|
3085
3189
|
this.closed = false;
|
|
3086
3190
|
this.disposables = new NamedDisposable();
|
|
3087
3191
|
this.connectPromise = null;
|
|
3192
|
+
this.terminalError = null;
|
|
3088
3193
|
this.pingIntervalStarted = false;
|
|
3089
3194
|
// Connection health monitoring
|
|
3090
3195
|
this.connectionStats = {
|
|
@@ -3116,7 +3221,7 @@ var PHPSandbox = (() => {
|
|
|
3116
3221
|
const startClosed = options.startClosed !== false;
|
|
3117
3222
|
this.rws = new reconnecting_websocket_mjs_default(this.url.toString(), [], {
|
|
3118
3223
|
WebSocket: globalThis.WebSocket ?? browser_default,
|
|
3119
|
-
connectionTimeout: options.connectionTimeout
|
|
3224
|
+
connectionTimeout: options.connectionTimeout,
|
|
3120
3225
|
maxReconnectionDelay: 2e3,
|
|
3121
3226
|
minReconnectionDelay: 200,
|
|
3122
3227
|
maxEnqueuedMessages: 0,
|
|
@@ -3159,6 +3264,9 @@ var PHPSandbox = (() => {
|
|
|
3159
3264
|
* Ensure the websocket is open without requiring an application-level roundtrip.
|
|
3160
3265
|
*/
|
|
3161
3266
|
connect() {
|
|
3267
|
+
if (this.terminalError) {
|
|
3268
|
+
return Promise.reject(this.terminalError);
|
|
3269
|
+
}
|
|
3162
3270
|
return __privateMethod(this, _Transport_instances, connect_fn).call(this);
|
|
3163
3271
|
}
|
|
3164
3272
|
id() {
|
|
@@ -3215,7 +3323,12 @@ var PHPSandbox = (() => {
|
|
|
3215
3323
|
return;
|
|
3216
3324
|
}
|
|
3217
3325
|
if (event === "Events.BootError" /* BootError */) {
|
|
3326
|
+
const error = new NotebookUnavailableError(
|
|
3327
|
+
data?.message || "Notebook is no longer available",
|
|
3328
|
+
data || {}
|
|
3329
|
+
);
|
|
3218
3330
|
this.log("error", "Boot error received", { data });
|
|
3331
|
+
this.terminate(error, 4e3, error.message);
|
|
3219
3332
|
return;
|
|
3220
3333
|
}
|
|
3221
3334
|
if (event === "response" /* Response */) {
|
|
@@ -3274,6 +3387,11 @@ var PHPSandbox = (() => {
|
|
|
3274
3387
|
listen(event, listener, _context) {
|
|
3275
3388
|
return this.eventEmitter.listen(event, listener);
|
|
3276
3389
|
}
|
|
3390
|
+
onDidBootError(listener) {
|
|
3391
|
+
this.eventEmitter.listen("transport.boot_error", (event) => {
|
|
3392
|
+
listener(event.error);
|
|
3393
|
+
});
|
|
3394
|
+
}
|
|
3277
3395
|
removeListener(event, listener) {
|
|
3278
3396
|
this.eventEmitter.removeListener(event, listener);
|
|
3279
3397
|
}
|
|
@@ -3300,6 +3418,9 @@ var PHPSandbox = (() => {
|
|
|
3300
3418
|
get isClosed() {
|
|
3301
3419
|
return this.closed;
|
|
3302
3420
|
}
|
|
3421
|
+
getTerminalError() {
|
|
3422
|
+
return this.terminalError;
|
|
3423
|
+
}
|
|
3303
3424
|
get status() {
|
|
3304
3425
|
return {
|
|
3305
3426
|
0: "CONNECTING",
|
|
@@ -3309,6 +3430,9 @@ var PHPSandbox = (() => {
|
|
|
3309
3430
|
}[this.rws.readyState];
|
|
3310
3431
|
}
|
|
3311
3432
|
async call(action, data = {}, options = {}) {
|
|
3433
|
+
if (this.terminalError) {
|
|
3434
|
+
throw this.terminalError;
|
|
3435
|
+
}
|
|
3312
3436
|
if (this.isRateLimited()) {
|
|
3313
3437
|
throw new RateLimitError("Rate limit exceeded - too many requests");
|
|
3314
3438
|
}
|
|
@@ -3325,6 +3449,10 @@ var PHPSandbox = (() => {
|
|
|
3325
3449
|
this.eventEmitter.removeListener(errorEvent);
|
|
3326
3450
|
};
|
|
3327
3451
|
const handler = async (resolve, reject) => {
|
|
3452
|
+
if (this.terminalError) {
|
|
3453
|
+
reject(this.terminalError);
|
|
3454
|
+
return;
|
|
3455
|
+
}
|
|
3328
3456
|
const abortError = new DOMException("Request aborted", "AbortError");
|
|
3329
3457
|
if (options.abortSignal?.aborted) {
|
|
3330
3458
|
reject(abortError);
|
|
@@ -3376,7 +3504,7 @@ var PHPSandbox = (() => {
|
|
|
3376
3504
|
reject(new RateLimitError(_ev.reason || "Rate limit exceeded", _ev));
|
|
3377
3505
|
return;
|
|
3378
3506
|
}
|
|
3379
|
-
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"}`));
|
|
3380
3508
|
};
|
|
3381
3509
|
this.rws.addEventListener("close", closeHandler);
|
|
3382
3510
|
this.rws.addEventListener("error", closeHandler);
|
|
@@ -3412,7 +3540,7 @@ var PHPSandbox = (() => {
|
|
|
3412
3540
|
try {
|
|
3413
3541
|
return await sender();
|
|
3414
3542
|
} catch (e) {
|
|
3415
|
-
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) {
|
|
3416
3544
|
this.log("debug", "Non-retryable error, bailing", {
|
|
3417
3545
|
error: e.message,
|
|
3418
3546
|
attempt
|
|
@@ -3464,6 +3592,9 @@ var PHPSandbox = (() => {
|
|
|
3464
3592
|
* This preserves all event listeners and state.
|
|
3465
3593
|
*/
|
|
3466
3594
|
reconnect() {
|
|
3595
|
+
if (this.terminalError) {
|
|
3596
|
+
throw this.terminalError;
|
|
3597
|
+
}
|
|
3467
3598
|
if (this.closed) {
|
|
3468
3599
|
throw new Error("Cannot reconnect a closed transport. The transport has been permanently closed.");
|
|
3469
3600
|
}
|
|
@@ -3478,6 +3609,16 @@ var PHPSandbox = (() => {
|
|
|
3478
3609
|
}
|
|
3479
3610
|
this.close();
|
|
3480
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
|
+
}
|
|
3481
3622
|
close(code, reason) {
|
|
3482
3623
|
if (this.closed) {
|
|
3483
3624
|
return;
|
|
@@ -3485,9 +3626,9 @@ var PHPSandbox = (() => {
|
|
|
3485
3626
|
this.log("info", "Closing transport connection", { code, reason });
|
|
3486
3627
|
this.connectPromise = null;
|
|
3487
3628
|
const queuedCount = this.messageQueue.length;
|
|
3629
|
+
const closeError = this.terminalError || new Error("Connection closed while message was queued");
|
|
3488
3630
|
this.messageQueue.forEach((msg) => {
|
|
3489
|
-
|
|
3490
|
-
msg.reject(new Error("Connection closed while message was queued"));
|
|
3631
|
+
msg.reject(closeError);
|
|
3491
3632
|
});
|
|
3492
3633
|
this.messageQueue = [];
|
|
3493
3634
|
if (queuedCount > 0) {
|
|
@@ -3575,6 +3716,9 @@ var PHPSandbox = (() => {
|
|
|
3575
3716
|
this.log("error", "Connection closed due to policy violation");
|
|
3576
3717
|
this.clearOldQueuedMessages();
|
|
3577
3718
|
return "stop";
|
|
3719
|
+
case 4e3:
|
|
3720
|
+
this.log("info", "Connection closed due to terminal notebook error");
|
|
3721
|
+
return "stop";
|
|
3578
3722
|
default:
|
|
3579
3723
|
this.log("warn", `Unknown close code: ${code}, will reconnect`);
|
|
3580
3724
|
return "reconnect";
|
|
@@ -3790,6 +3934,9 @@ var PHPSandbox = (() => {
|
|
|
3790
3934
|
* by caching the connection promise.
|
|
3791
3935
|
*/
|
|
3792
3936
|
connect_fn = function() {
|
|
3937
|
+
if (this.terminalError) {
|
|
3938
|
+
return Promise.reject(this.terminalError);
|
|
3939
|
+
}
|
|
3793
3940
|
if (this.isConnected) {
|
|
3794
3941
|
return Promise.resolve();
|
|
3795
3942
|
}
|
|
@@ -4836,9 +4983,14 @@ var PHPSandbox = (() => {
|
|
|
4836
4983
|
this.laravel = new Lravel(this);
|
|
4837
4984
|
this.shell = new Shell(this);
|
|
4838
4985
|
this.git = new Git(this);
|
|
4986
|
+
this.services = new Services(this);
|
|
4839
4987
|
this.secrets = new NotebookSecrets(client, this.data.id);
|
|
4840
4988
|
}
|
|
4841
4989
|
async ready() {
|
|
4990
|
+
const terminalError = this.socket.getTerminalError();
|
|
4991
|
+
if (terminalError) {
|
|
4992
|
+
throw terminalError;
|
|
4993
|
+
}
|
|
4842
4994
|
const ready = async () => {
|
|
4843
4995
|
if (this.client.options.startClosed && !this.socket.isConnected) {
|
|
4844
4996
|
await this.socket.connect();
|
|
@@ -4851,7 +5003,9 @@ var PHPSandbox = (() => {
|
|
|
4851
5003
|
return this.client.notebook.fork(this.data.id);
|
|
4852
5004
|
}
|
|
4853
5005
|
delete() {
|
|
4854
|
-
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
|
+
});
|
|
4855
5009
|
}
|
|
4856
5010
|
stop() {
|
|
4857
5011
|
return this.container.stop();
|
|
@@ -4875,6 +5029,10 @@ var PHPSandbox = (() => {
|
|
|
4875
5029
|
!this.socket.isClosed && this.socket.disconnect();
|
|
4876
5030
|
}
|
|
4877
5031
|
connected() {
|
|
5032
|
+
const terminalError = this.socket.getTerminalError();
|
|
5033
|
+
if (terminalError) {
|
|
5034
|
+
return Promise.reject(terminalError);
|
|
5035
|
+
}
|
|
4878
5036
|
if (this.socket.isConnected) {
|
|
4879
5037
|
return Promise.resolve(this);
|
|
4880
5038
|
}
|
|
@@ -4882,18 +5040,24 @@ var PHPSandbox = (() => {
|
|
|
4882
5040
|
try {
|
|
4883
5041
|
this.socket.onDidConnect(() => resolve(this));
|
|
4884
5042
|
this.socket.onDidClose(() => reject(new Error("Connection closed")));
|
|
5043
|
+
this.socket.onDidBootError((error) => reject(error));
|
|
4885
5044
|
} catch (e) {
|
|
4886
5045
|
reject(e);
|
|
4887
5046
|
}
|
|
4888
5047
|
});
|
|
4889
5048
|
}
|
|
4890
5049
|
whenConnected() {
|
|
5050
|
+
const terminalError = this.socket.getTerminalError();
|
|
5051
|
+
if (terminalError) {
|
|
5052
|
+
return Promise.reject(terminalError);
|
|
5053
|
+
}
|
|
4891
5054
|
if (this.socket.isConnected) {
|
|
4892
5055
|
return Promise.resolve(this);
|
|
4893
5056
|
}
|
|
4894
5057
|
return new Promise((resolve, reject) => {
|
|
4895
5058
|
try {
|
|
4896
5059
|
this.socket.onDidConnect(() => resolve(this));
|
|
5060
|
+
this.socket.onDidBootError((error) => reject(error));
|
|
4897
5061
|
} catch (e) {
|
|
4898
5062
|
reject(e);
|
|
4899
5063
|
}
|
|
@@ -4910,6 +5074,11 @@ var PHPSandbox = (() => {
|
|
|
4910
5074
|
this.socket.emit("okra.disconnected");
|
|
4911
5075
|
this.initialized = false;
|
|
4912
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
|
+
});
|
|
4913
5082
|
}
|
|
4914
5083
|
onDidConnect(handler) {
|
|
4915
5084
|
this.socket.removeListener("okra.connected", handler);
|
|
@@ -4922,6 +5091,11 @@ var PHPSandbox = (() => {
|
|
|
4922
5091
|
this.disposables.push(disposable);
|
|
4923
5092
|
return disposable;
|
|
4924
5093
|
}
|
|
5094
|
+
onDidBootError(handler) {
|
|
5095
|
+
const disposable = this.socket.listen("okra.boot_error", handler);
|
|
5096
|
+
this.disposables.push(disposable);
|
|
5097
|
+
return disposable;
|
|
5098
|
+
}
|
|
4925
5099
|
update() {
|
|
4926
5100
|
return this.invoke("notebook.update");
|
|
4927
5101
|
}
|
|
@@ -4947,6 +5121,7 @@ var PHPSandbox = (() => {
|
|
|
4947
5121
|
init_fn = function() {
|
|
4948
5122
|
__privateSet(this, _initPromise, new Promise((resolve, reject) => {
|
|
4949
5123
|
const initializationListener = this.onDidInitialize((result) => {
|
|
5124
|
+
bootErrorListener.dispose();
|
|
4950
5125
|
initializationListener.dispose();
|
|
4951
5126
|
this.initialized = result;
|
|
4952
5127
|
if (result.type === "error") {
|
|
@@ -4955,6 +5130,11 @@ var PHPSandbox = (() => {
|
|
|
4955
5130
|
}
|
|
4956
5131
|
resolve(result);
|
|
4957
5132
|
});
|
|
5133
|
+
const bootErrorListener = this.onDidBootError((error) => {
|
|
5134
|
+
initializationListener.dispose();
|
|
5135
|
+
bootErrorListener.dispose();
|
|
5136
|
+
reject(error);
|
|
5137
|
+
});
|
|
4958
5138
|
}));
|
|
4959
5139
|
return __privateGet(this, _initPromise);
|
|
4960
5140
|
};
|