@phpsandbox/sdk 0.0.49 → 0.0.52
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/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/auth.d.ts +0 -1
- package/dist/auth.js +0 -1
- package/dist/beacon/index.d.ts +4 -5
- package/dist/beacon/index.js +11 -12
- package/dist/beacon/navigator.d.ts +1 -2
- package/dist/beacon/navigator.js +0 -1
- package/dist/beacon/types.d.ts +12 -13
- package/dist/beacon/types.js +0 -1
- package/dist/browser/phpsandbox-sdk.esm.js +282 -479
- package/dist/browser/phpsandbox-sdk.esm.min.js +2 -3
- package/dist/browser/phpsandbox-sdk.iife.js +277 -479
- package/dist/browser/phpsandbox-sdk.iife.min.js +2 -3
- package/dist/composer.d.ts +2 -3
- package/dist/composer.js +0 -1
- package/dist/config.d.ts +0 -1
- package/dist/config.js +0 -1
- package/dist/container.d.ts +0 -1
- package/dist/container.js +0 -1
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/events/index.d.ts +15 -15
- package/dist/events/index.js +16 -9
- package/dist/filesystem.d.ts +6 -7
- package/dist/filesystem.js +36 -14
- package/dist/git.d.ts +0 -1
- package/dist/git.js +0 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +38 -25
- package/dist/laravel.d.ts +1 -2
- package/dist/laravel.js +1 -2
- package/dist/log.d.ts +3 -4
- package/dist/log.js +1 -2
- package/dist/lsp.d.ts +10 -11
- package/dist/lsp.js +9 -10
- package/dist/repl.d.ts +3 -4
- package/dist/repl.js +2 -3
- package/dist/services.d.ts +0 -1
- package/dist/services.js +0 -1
- package/dist/shell.d.ts +1 -2
- package/dist/shell.js +1 -2
- package/dist/socket/index.d.ts +23 -129
- package/dist/socket/index.js +60 -350
- package/dist/terminal.d.ts +2 -3
- package/dist/terminal.js +45 -26
- package/dist/types.d.ts +0 -1
- package/dist/types.js +0 -1
- package/dist/utils/disposable.d.ts +0 -1
- package/dist/utils/disposable.js +0 -1
- package/dist/utils/promise.d.ts +0 -1
- package/dist/utils/promise.js +0 -1
- package/dist/utils/retry.d.ts +0 -1
- package/dist/utils/retry.js +0 -1
- package/dist/utils/websocket.d.ts +0 -1
- package/dist/utils/websocket.js +0 -1
- package/docs/api-summary.md +136 -0
- package/docs/cdn-usage.md +80 -0
- package/docs/getting-started.md +152 -0
- package/examples/README.md +206 -0
- package/examples/basic.ts +24 -0
- package/examples/get.ts +21 -0
- package/examples/git-merge-smoke.ts +415 -0
- package/examples/laravel-load-test.ts +2829 -0
- package/examples/notebook-readonly-smoke.ts +823 -0
- package/package.json +13 -7
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js.map +0 -1
- package/dist/beacon/index.d.ts.map +0 -1
- package/dist/beacon/index.js.map +0 -1
- package/dist/beacon/navigator.d.ts.map +0 -1
- package/dist/beacon/navigator.js.map +0 -1
- package/dist/beacon/types.d.ts.map +0 -1
- package/dist/beacon/types.js.map +0 -1
- package/dist/browser/phpsandbox-sdk.esm.js.map +0 -7
- package/dist/browser/phpsandbox-sdk.esm.min.js.map +0 -7
- package/dist/browser/phpsandbox-sdk.iife.js.map +0 -7
- package/dist/browser/phpsandbox-sdk.iife.min.js.map +0 -7
- package/dist/composer.d.ts.map +0 -1
- package/dist/composer.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/container.d.ts.map +0 -1
- package/dist/container.js.map +0 -1
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/events/index.d.ts.map +0 -1
- package/dist/events/index.js.map +0 -1
- package/dist/filesystem.d.ts.map +0 -1
- package/dist/filesystem.js.map +0 -1
- package/dist/git.d.ts.map +0 -1
- package/dist/git.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/laravel.d.ts.map +0 -1
- package/dist/laravel.js.map +0 -1
- package/dist/log.d.ts.map +0 -1
- package/dist/log.js.map +0 -1
- package/dist/lsp.d.ts.map +0 -1
- package/dist/lsp.js.map +0 -1
- package/dist/repl.d.ts.map +0 -1
- package/dist/repl.js.map +0 -1
- package/dist/services.d.ts.map +0 -1
- package/dist/services.js.map +0 -1
- package/dist/shell.d.ts.map +0 -1
- package/dist/shell.js.map +0 -1
- package/dist/socket/index.d.ts.map +0 -1
- package/dist/socket/index.js.map +0 -1
- package/dist/terminal.d.ts.map +0 -1
- package/dist/terminal.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/disposable.d.ts.map +0 -1
- package/dist/utils/disposable.js.map +0 -1
- package/dist/utils/promise.d.ts.map +0 -1
- package/dist/utils/promise.js.map +0 -1
- package/dist/utils/retry.d.ts.map +0 -1
- package/dist/utils/retry.js.map +0 -1
- package/dist/utils/websocket.d.ts.map +0 -1
- package/dist/utils/websocket.js.map +0 -1
|
@@ -36,6 +36,7 @@ var PHPSandbox = (() => {
|
|
|
36
36
|
Client: () => Client,
|
|
37
37
|
CommandError: () => CommandError,
|
|
38
38
|
ErrorEvent: () => ErrorEvent,
|
|
39
|
+
FileChangeFilter: () => FileChangeFilter,
|
|
39
40
|
FileChangeType: () => FileChangeType,
|
|
40
41
|
FileType: () => FileType,
|
|
41
42
|
Filesystem: () => Filesystem,
|
|
@@ -106,6 +107,12 @@ var PHPSandbox = (() => {
|
|
|
106
107
|
FileType2[FileType2["SymbolicLink"] = 64] = "SymbolicLink";
|
|
107
108
|
return FileType2;
|
|
108
109
|
})(FileType || {});
|
|
110
|
+
var FileChangeFilter = /* @__PURE__ */ ((FileChangeFilter2) => {
|
|
111
|
+
FileChangeFilter2[FileChangeFilter2["UPDATED"] = 2] = "UPDATED";
|
|
112
|
+
FileChangeFilter2[FileChangeFilter2["ADDED"] = 4] = "ADDED";
|
|
113
|
+
FileChangeFilter2[FileChangeFilter2["DELETED"] = 8] = "DELETED";
|
|
114
|
+
return FileChangeFilter2;
|
|
115
|
+
})(FileChangeFilter || {});
|
|
109
116
|
var FileChangeType = /* @__PURE__ */ ((FileChangeType2) => {
|
|
110
117
|
FileChangeType2[FileChangeType2["UPDATED"] = 1] = "UPDATED";
|
|
111
118
|
FileChangeType2[FileChangeType2["ADDED"] = 2] = "ADDED";
|
|
@@ -128,14 +135,18 @@ var PHPSandbox = (() => {
|
|
|
128
135
|
}
|
|
129
136
|
};
|
|
130
137
|
var FilesystemSubscription = class {
|
|
131
|
-
constructor(
|
|
132
|
-
this.path = path;
|
|
133
|
-
this.okra = okra;
|
|
138
|
+
constructor(disposable, onDispose) {
|
|
134
139
|
this.disposable = disposable;
|
|
140
|
+
this.onDispose = onDispose;
|
|
141
|
+
this.disposed = false;
|
|
135
142
|
}
|
|
136
143
|
dispose() {
|
|
137
|
-
this.
|
|
144
|
+
if (this.disposed) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
this.disposed = true;
|
|
138
148
|
this.disposable.dispose();
|
|
149
|
+
this.onDispose();
|
|
139
150
|
}
|
|
140
151
|
};
|
|
141
152
|
var Filesystem = class {
|
|
@@ -146,8 +157,9 @@ var PHPSandbox = (() => {
|
|
|
146
157
|
}
|
|
147
158
|
watchOkraConnection() {
|
|
148
159
|
this.okra.onDidConnect(() => {
|
|
149
|
-
for (const { path, options
|
|
150
|
-
this.watch
|
|
160
|
+
for (const { path, options } of this.watches.values()) {
|
|
161
|
+
void this.okra.invoke("fs.watch", { path, options }).catch(() => {
|
|
162
|
+
});
|
|
151
163
|
}
|
|
152
164
|
});
|
|
153
165
|
}
|
|
@@ -165,7 +177,7 @@ var PHPSandbox = (() => {
|
|
|
165
177
|
}) {
|
|
166
178
|
return this.okra.invoke("fs.find", {
|
|
167
179
|
query,
|
|
168
|
-
options:
|
|
180
|
+
options: {
|
|
169
181
|
includes: [],
|
|
170
182
|
excludes: [
|
|
171
183
|
"**/storage",
|
|
@@ -182,8 +194,9 @@ var PHPSandbox = (() => {
|
|
|
182
194
|
useIgnoreFiles: false,
|
|
183
195
|
followSymlinks: false,
|
|
184
196
|
useGlobalIgnoreFiles: false,
|
|
185
|
-
useParentIgnoreFiles: false
|
|
186
|
-
|
|
197
|
+
useParentIgnoreFiles: false,
|
|
198
|
+
...options
|
|
199
|
+
}
|
|
187
200
|
});
|
|
188
201
|
}
|
|
189
202
|
search(query, options, onMatch) {
|
|
@@ -289,12 +302,21 @@ var PHPSandbox = (() => {
|
|
|
289
302
|
const wrappedDisposable = {
|
|
290
303
|
dispose: () => {
|
|
291
304
|
disposable.dispose();
|
|
292
|
-
this.okra.invoke("fs.unwatch", { path })
|
|
305
|
+
void this.okra.invoke("fs.unwatch", { path }).catch(() => {
|
|
306
|
+
});
|
|
293
307
|
}
|
|
294
308
|
};
|
|
295
|
-
const subscription = new FilesystemSubscription(
|
|
309
|
+
const subscription = new FilesystemSubscription(wrappedDisposable, () => {
|
|
310
|
+
const watch = this.watches.get(path);
|
|
311
|
+
if (watch?.onDidChange === onDidChange) {
|
|
312
|
+
this.watches.delete(path);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
296
315
|
this.watches.set(path, { options, path, onDidChange });
|
|
297
|
-
return this.okra.invoke("fs.watch", { path, options }).then(() => subscription)
|
|
316
|
+
return this.okra.invoke("fs.watch", { path, options }).then(() => subscription).catch((error) => {
|
|
317
|
+
subscription.dispose();
|
|
318
|
+
throw error;
|
|
319
|
+
});
|
|
298
320
|
}
|
|
299
321
|
exists(path) {
|
|
300
322
|
return this.stat(path).then(() => true).catch(() => false);
|
|
@@ -303,13 +325,13 @@ var PHPSandbox = (() => {
|
|
|
303
325
|
const id = nanoid();
|
|
304
326
|
const stream = !!chunk;
|
|
305
327
|
const chunks = [];
|
|
306
|
-
this.okra.listen(
|
|
328
|
+
const disposable = this.okra.listen(
|
|
307
329
|
`fs.download.${id}`,
|
|
308
330
|
stream ? chunk : (data) => {
|
|
309
331
|
chunks.push(data);
|
|
310
332
|
}
|
|
311
333
|
);
|
|
312
|
-
return this.okra.invoke("fs.download", { id, exclude, include }).then(() => new Blob(chunks, { type: "application/octet-stream" }));
|
|
334
|
+
return this.okra.invoke("fs.download", { id, exclude, include }).then(() => new Blob(chunks, { type: "application/octet-stream" })).finally(() => disposable.dispose());
|
|
313
335
|
}
|
|
314
336
|
tree(path = "/") {
|
|
315
337
|
return this.okra.invoke("fs.tree", { path });
|
|
@@ -374,13 +396,13 @@ var PHPSandbox = (() => {
|
|
|
374
396
|
return this.okra.invoke("terminal.create", input);
|
|
375
397
|
}
|
|
376
398
|
onStarted(handler) {
|
|
377
|
-
this.okra.listen("terminal.started", handler);
|
|
399
|
+
return this.okra.listen("terminal.started", handler);
|
|
378
400
|
}
|
|
379
401
|
resize(id, size) {
|
|
380
402
|
return this.okra.invoke("terminal.resize", { id, width: size[0], height: size[1] });
|
|
381
403
|
}
|
|
382
404
|
onOutput(id, handler) {
|
|
383
|
-
this.okra.listen(`terminal.output.${id}`, handler);
|
|
405
|
+
return this.okra.listen(`terminal.output.${id}`, handler);
|
|
384
406
|
}
|
|
385
407
|
input(id, input) {
|
|
386
408
|
return Promise.resolve(this.okra.send("terminal.input", { id, input }));
|
|
@@ -390,46 +412,61 @@ var PHPSandbox = (() => {
|
|
|
390
412
|
}
|
|
391
413
|
async attach(id, opts) {
|
|
392
414
|
const handle = this.processHandle(id, opts?.abortSignal);
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
415
|
+
try {
|
|
416
|
+
const task = await this.okra.invoke(
|
|
417
|
+
"terminal.attach",
|
|
418
|
+
{
|
|
419
|
+
id,
|
|
420
|
+
replayHistory: opts?.replayHistory
|
|
421
|
+
},
|
|
422
|
+
{ abortSignal: opts?.abortSignal }
|
|
423
|
+
);
|
|
424
|
+
if (!task) {
|
|
425
|
+
handle.dispose();
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
...handle.process,
|
|
430
|
+
...task
|
|
431
|
+
};
|
|
432
|
+
} catch (error) {
|
|
402
433
|
handle.dispose();
|
|
403
|
-
|
|
434
|
+
throw error;
|
|
404
435
|
}
|
|
405
|
-
return {
|
|
406
|
-
...handle.process,
|
|
407
|
-
...task
|
|
408
|
-
};
|
|
409
436
|
}
|
|
410
437
|
async spawn(command, args, opts) {
|
|
411
438
|
const id = opts?.id || nanoid();
|
|
412
439
|
const handle = this.processHandle(id, opts?.abortSignal);
|
|
413
440
|
const { abortSignal, ...otherOpts } = opts ?? {};
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
441
|
+
try {
|
|
442
|
+
const result = await this.okra.invoke(
|
|
443
|
+
"terminal.spawn",
|
|
444
|
+
{
|
|
445
|
+
command: [command, ...args],
|
|
446
|
+
opts: {
|
|
447
|
+
id,
|
|
448
|
+
...otherOpts
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
{ abortSignal }
|
|
452
|
+
);
|
|
453
|
+
return {
|
|
454
|
+
...handle.process,
|
|
455
|
+
...result
|
|
456
|
+
};
|
|
457
|
+
} catch (error) {
|
|
458
|
+
handle.dispose();
|
|
459
|
+
throw error;
|
|
460
|
+
}
|
|
429
461
|
}
|
|
430
462
|
processHandle(id, abortSignal) {
|
|
431
463
|
const disposables = /* @__PURE__ */ new Set();
|
|
464
|
+
let abortHandler;
|
|
432
465
|
const dispose = () => {
|
|
466
|
+
if (abortHandler) {
|
|
467
|
+
abortSignal?.removeEventListener("abort", abortHandler);
|
|
468
|
+
abortHandler = void 0;
|
|
469
|
+
}
|
|
433
470
|
for (const disposable of disposables) {
|
|
434
471
|
disposable.dispose();
|
|
435
472
|
}
|
|
@@ -508,8 +545,11 @@ var PHPSandbox = (() => {
|
|
|
508
545
|
const resize = (dimensions) => {
|
|
509
546
|
this.okra.invoke("terminal.resize", { id, width: dimensions.cols, height: dimensions.rows });
|
|
510
547
|
};
|
|
511
|
-
if (abortSignal) {
|
|
512
|
-
|
|
548
|
+
if (abortSignal && !abortSignal.aborted) {
|
|
549
|
+
abortHandler = () => {
|
|
550
|
+
void kill();
|
|
551
|
+
};
|
|
552
|
+
abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
513
553
|
}
|
|
514
554
|
return {
|
|
515
555
|
process: {
|
|
@@ -603,19 +643,19 @@ var PHPSandbox = (() => {
|
|
|
603
643
|
return this.okra.invoke("lsp.message", { id, message });
|
|
604
644
|
}
|
|
605
645
|
listen(id, event, cb) {
|
|
606
|
-
this.okra.listen(`${event}.${id}`, (e) => cb(e));
|
|
646
|
+
return this.okra.listen(`${event}.${id}`, (e) => cb(e));
|
|
607
647
|
}
|
|
608
648
|
onClose(id, cb) {
|
|
609
|
-
this.listen(id, "lsp.closed", (e) => cb(e.code, e.reason));
|
|
649
|
+
return this.listen(id, "lsp.closed", (e) => cb(e.code, e.reason));
|
|
610
650
|
}
|
|
611
651
|
onError(id, cb) {
|
|
612
|
-
this.listen(id, "lsp.error", (e) => cb(e.message));
|
|
652
|
+
return this.listen(id, "lsp.error", (e) => cb(e.message));
|
|
613
653
|
}
|
|
614
654
|
onClientDisconnect(cb) {
|
|
615
|
-
this.okra.onDidDisconnect(() => cb(1e3, "OKRA DISCONNECTED"));
|
|
655
|
+
return this.okra.onDidDisconnect(() => cb(1e3, "OKRA DISCONNECTED"));
|
|
616
656
|
}
|
|
617
657
|
onResponse(id, cb) {
|
|
618
|
-
this.listen(id, "lsp.response", (e) => cb(JSON.stringify(e)));
|
|
658
|
+
return this.listen(id, "lsp.response", (e) => cb(JSON.stringify(e)));
|
|
619
659
|
}
|
|
620
660
|
close(id) {
|
|
621
661
|
return this.okra.invoke("lsp.close", { id });
|
|
@@ -639,13 +679,13 @@ var PHPSandbox = (() => {
|
|
|
639
679
|
return this.lsp.message(this.id, content);
|
|
640
680
|
}
|
|
641
681
|
onMessage(cb) {
|
|
642
|
-
this.lsp.onResponse(this.id, cb);
|
|
682
|
+
return this.lsp.onResponse(this.id, cb);
|
|
643
683
|
}
|
|
644
684
|
onError(cb) {
|
|
645
|
-
this.lsp.onError(this.id, cb);
|
|
685
|
+
return this.lsp.onError(this.id, cb);
|
|
646
686
|
}
|
|
647
687
|
onClose(cb) {
|
|
648
|
-
this.lsp.onClose(this.id, cb);
|
|
688
|
+
return this.lsp.onClose(this.id, cb);
|
|
649
689
|
}
|
|
650
690
|
dispose() {
|
|
651
691
|
this.lsp.close(this.id);
|
|
@@ -654,7 +694,7 @@ var PHPSandbox = (() => {
|
|
|
654
694
|
this.lsp.start(this.id);
|
|
655
695
|
}
|
|
656
696
|
onClientDisconnect(cb) {
|
|
657
|
-
this.lsp.onClientDisconnect(cb);
|
|
697
|
+
return this.lsp.onClientDisconnect(cb);
|
|
658
698
|
}
|
|
659
699
|
whenSocketConnected() {
|
|
660
700
|
return this.lsp.whenSocketConnected();
|
|
@@ -704,12 +744,12 @@ var PHPSandbox = (() => {
|
|
|
704
744
|
return this.okra.listen("notebook.log", fn);
|
|
705
745
|
}
|
|
706
746
|
listen(event, handler) {
|
|
707
|
-
this.okra.listen(event, handler);
|
|
747
|
+
return this.okra.listen(event, handler);
|
|
708
748
|
}
|
|
709
749
|
};
|
|
710
750
|
|
|
711
751
|
// src/laravel.ts
|
|
712
|
-
var
|
|
752
|
+
var Laravel = class {
|
|
713
753
|
constructor(okra) {
|
|
714
754
|
this.okra = okra;
|
|
715
755
|
}
|
|
@@ -742,10 +782,10 @@ var PHPSandbox = (() => {
|
|
|
742
782
|
return this.okra.invoke("repl.resize", { cols, rows });
|
|
743
783
|
}
|
|
744
784
|
listen(event, handler) {
|
|
745
|
-
this.okra.listen(event, handler);
|
|
785
|
+
return this.okra.listen(event, handler);
|
|
746
786
|
}
|
|
747
787
|
onOutput(handler) {
|
|
748
|
-
this.okra.listen("repl.output", handler);
|
|
788
|
+
return this.okra.listen("repl.output", handler);
|
|
749
789
|
}
|
|
750
790
|
};
|
|
751
791
|
|
|
@@ -782,7 +822,7 @@ var PHPSandbox = (() => {
|
|
|
782
822
|
this.okra = okra;
|
|
783
823
|
}
|
|
784
824
|
onOutput(id, handler) {
|
|
785
|
-
this.okra.listen(`shell.output.${id}`, handler);
|
|
825
|
+
return this.okra.listen(`shell.output.${id}`, handler);
|
|
786
826
|
}
|
|
787
827
|
listen(event, handler) {
|
|
788
828
|
return this.okra.listen(event, handler);
|
|
@@ -2435,6 +2475,10 @@ var PHPSandbox = (() => {
|
|
|
2435
2475
|
}
|
|
2436
2476
|
|
|
2437
2477
|
// node_modules/reconnecting-websocket/dist/reconnecting-websocket-mjs.js
|
|
2478
|
+
var reconnecting_websocket_mjs_exports = {};
|
|
2479
|
+
__export(reconnecting_websocket_mjs_exports, {
|
|
2480
|
+
default: () => reconnecting_websocket_mjs_default
|
|
2481
|
+
});
|
|
2438
2482
|
var extendStatics = function(d, b) {
|
|
2439
2483
|
extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
|
|
2440
2484
|
d2.__proto__ = b2;
|
|
@@ -2547,7 +2591,7 @@ var PHPSandbox = (() => {
|
|
|
2547
2591
|
var ReconnectingWebSocket = (
|
|
2548
2592
|
/** @class */
|
|
2549
2593
|
(function() {
|
|
2550
|
-
function
|
|
2594
|
+
function ReconnectingWebSocket3(url, protocols, options) {
|
|
2551
2595
|
var _this = this;
|
|
2552
2596
|
if (options === void 0) {
|
|
2553
2597
|
options = {};
|
|
@@ -2629,63 +2673,63 @@ var PHPSandbox = (() => {
|
|
|
2629
2673
|
}
|
|
2630
2674
|
this._connect();
|
|
2631
2675
|
}
|
|
2632
|
-
Object.defineProperty(
|
|
2676
|
+
Object.defineProperty(ReconnectingWebSocket3, "CONNECTING", {
|
|
2633
2677
|
get: function() {
|
|
2634
2678
|
return 0;
|
|
2635
2679
|
},
|
|
2636
2680
|
enumerable: true,
|
|
2637
2681
|
configurable: true
|
|
2638
2682
|
});
|
|
2639
|
-
Object.defineProperty(
|
|
2683
|
+
Object.defineProperty(ReconnectingWebSocket3, "OPEN", {
|
|
2640
2684
|
get: function() {
|
|
2641
2685
|
return 1;
|
|
2642
2686
|
},
|
|
2643
2687
|
enumerable: true,
|
|
2644
2688
|
configurable: true
|
|
2645
2689
|
});
|
|
2646
|
-
Object.defineProperty(
|
|
2690
|
+
Object.defineProperty(ReconnectingWebSocket3, "CLOSING", {
|
|
2647
2691
|
get: function() {
|
|
2648
2692
|
return 2;
|
|
2649
2693
|
},
|
|
2650
2694
|
enumerable: true,
|
|
2651
2695
|
configurable: true
|
|
2652
2696
|
});
|
|
2653
|
-
Object.defineProperty(
|
|
2697
|
+
Object.defineProperty(ReconnectingWebSocket3, "CLOSED", {
|
|
2654
2698
|
get: function() {
|
|
2655
2699
|
return 3;
|
|
2656
2700
|
},
|
|
2657
2701
|
enumerable: true,
|
|
2658
2702
|
configurable: true
|
|
2659
2703
|
});
|
|
2660
|
-
Object.defineProperty(
|
|
2704
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "CONNECTING", {
|
|
2661
2705
|
get: function() {
|
|
2662
|
-
return
|
|
2706
|
+
return ReconnectingWebSocket3.CONNECTING;
|
|
2663
2707
|
},
|
|
2664
2708
|
enumerable: true,
|
|
2665
2709
|
configurable: true
|
|
2666
2710
|
});
|
|
2667
|
-
Object.defineProperty(
|
|
2711
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "OPEN", {
|
|
2668
2712
|
get: function() {
|
|
2669
|
-
return
|
|
2713
|
+
return ReconnectingWebSocket3.OPEN;
|
|
2670
2714
|
},
|
|
2671
2715
|
enumerable: true,
|
|
2672
2716
|
configurable: true
|
|
2673
2717
|
});
|
|
2674
|
-
Object.defineProperty(
|
|
2718
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "CLOSING", {
|
|
2675
2719
|
get: function() {
|
|
2676
|
-
return
|
|
2720
|
+
return ReconnectingWebSocket3.CLOSING;
|
|
2677
2721
|
},
|
|
2678
2722
|
enumerable: true,
|
|
2679
2723
|
configurable: true
|
|
2680
2724
|
});
|
|
2681
|
-
Object.defineProperty(
|
|
2725
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "CLOSED", {
|
|
2682
2726
|
get: function() {
|
|
2683
|
-
return
|
|
2727
|
+
return ReconnectingWebSocket3.CLOSED;
|
|
2684
2728
|
},
|
|
2685
2729
|
enumerable: true,
|
|
2686
2730
|
configurable: true
|
|
2687
2731
|
});
|
|
2688
|
-
Object.defineProperty(
|
|
2732
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "binaryType", {
|
|
2689
2733
|
get: function() {
|
|
2690
2734
|
return this._ws ? this._ws.binaryType : this._binaryType;
|
|
2691
2735
|
},
|
|
@@ -2698,7 +2742,7 @@ var PHPSandbox = (() => {
|
|
|
2698
2742
|
enumerable: true,
|
|
2699
2743
|
configurable: true
|
|
2700
2744
|
});
|
|
2701
|
-
Object.defineProperty(
|
|
2745
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "retryCount", {
|
|
2702
2746
|
/**
|
|
2703
2747
|
* Returns the number or connection retries
|
|
2704
2748
|
*/
|
|
@@ -2708,7 +2752,7 @@ var PHPSandbox = (() => {
|
|
|
2708
2752
|
enumerable: true,
|
|
2709
2753
|
configurable: true
|
|
2710
2754
|
});
|
|
2711
|
-
Object.defineProperty(
|
|
2755
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "bufferedAmount", {
|
|
2712
2756
|
/**
|
|
2713
2757
|
* The number of bytes of data that have been queued using calls to send() but not yet
|
|
2714
2758
|
* transmitted to the network. This value resets to zero once all queued data has been sent.
|
|
@@ -2731,7 +2775,7 @@ var PHPSandbox = (() => {
|
|
|
2731
2775
|
enumerable: true,
|
|
2732
2776
|
configurable: true
|
|
2733
2777
|
});
|
|
2734
|
-
Object.defineProperty(
|
|
2778
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "extensions", {
|
|
2735
2779
|
/**
|
|
2736
2780
|
* The extensions selected by the server. This is currently only the empty string or a list of
|
|
2737
2781
|
* extensions as negotiated by the connection
|
|
@@ -2742,7 +2786,7 @@ var PHPSandbox = (() => {
|
|
|
2742
2786
|
enumerable: true,
|
|
2743
2787
|
configurable: true
|
|
2744
2788
|
});
|
|
2745
|
-
Object.defineProperty(
|
|
2789
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "protocol", {
|
|
2746
2790
|
/**
|
|
2747
2791
|
* A string indicating the name of the sub-protocol the server selected;
|
|
2748
2792
|
* this will be one of the strings specified in the protocols parameter when creating the
|
|
@@ -2754,7 +2798,7 @@ var PHPSandbox = (() => {
|
|
|
2754
2798
|
enumerable: true,
|
|
2755
2799
|
configurable: true
|
|
2756
2800
|
});
|
|
2757
|
-
Object.defineProperty(
|
|
2801
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "readyState", {
|
|
2758
2802
|
/**
|
|
2759
2803
|
* The current state of the connection; this is one of the Ready state constants
|
|
2760
2804
|
*/
|
|
@@ -2762,12 +2806,12 @@ var PHPSandbox = (() => {
|
|
|
2762
2806
|
if (this._ws) {
|
|
2763
2807
|
return this._ws.readyState;
|
|
2764
2808
|
}
|
|
2765
|
-
return this._options.startClosed ?
|
|
2809
|
+
return this._options.startClosed ? ReconnectingWebSocket3.CLOSED : ReconnectingWebSocket3.CONNECTING;
|
|
2766
2810
|
},
|
|
2767
2811
|
enumerable: true,
|
|
2768
2812
|
configurable: true
|
|
2769
2813
|
});
|
|
2770
|
-
Object.defineProperty(
|
|
2814
|
+
Object.defineProperty(ReconnectingWebSocket3.prototype, "url", {
|
|
2771
2815
|
/**
|
|
2772
2816
|
* The URL as resolved by the constructor
|
|
2773
2817
|
*/
|
|
@@ -2777,7 +2821,7 @@ var PHPSandbox = (() => {
|
|
|
2777
2821
|
enumerable: true,
|
|
2778
2822
|
configurable: true
|
|
2779
2823
|
});
|
|
2780
|
-
|
|
2824
|
+
ReconnectingWebSocket3.prototype.close = function(code, reason) {
|
|
2781
2825
|
if (code === void 0) {
|
|
2782
2826
|
code = 1e3;
|
|
2783
2827
|
}
|
|
@@ -2794,7 +2838,7 @@ var PHPSandbox = (() => {
|
|
|
2794
2838
|
}
|
|
2795
2839
|
this._ws.close(code, reason);
|
|
2796
2840
|
};
|
|
2797
|
-
|
|
2841
|
+
ReconnectingWebSocket3.prototype.reconnect = function(code, reason) {
|
|
2798
2842
|
this._shouldReconnect = true;
|
|
2799
2843
|
this._closeCalled = false;
|
|
2800
2844
|
this._retryCount = -1;
|
|
@@ -2805,7 +2849,7 @@ var PHPSandbox = (() => {
|
|
|
2805
2849
|
this._connect();
|
|
2806
2850
|
}
|
|
2807
2851
|
};
|
|
2808
|
-
|
|
2852
|
+
ReconnectingWebSocket3.prototype.send = function(data) {
|
|
2809
2853
|
if (this._ws && this._ws.readyState === this.OPEN) {
|
|
2810
2854
|
this._debug("send", data);
|
|
2811
2855
|
this._ws.send(data);
|
|
@@ -2817,12 +2861,12 @@ var PHPSandbox = (() => {
|
|
|
2817
2861
|
}
|
|
2818
2862
|
}
|
|
2819
2863
|
};
|
|
2820
|
-
|
|
2864
|
+
ReconnectingWebSocket3.prototype.addEventListener = function(type, listener) {
|
|
2821
2865
|
if (this._listeners[type]) {
|
|
2822
2866
|
this._listeners[type].push(listener);
|
|
2823
2867
|
}
|
|
2824
2868
|
};
|
|
2825
|
-
|
|
2869
|
+
ReconnectingWebSocket3.prototype.dispatchEvent = function(event) {
|
|
2826
2870
|
var e_1, _a;
|
|
2827
2871
|
var listeners = this._listeners[event.type];
|
|
2828
2872
|
if (listeners) {
|
|
@@ -2843,14 +2887,14 @@ var PHPSandbox = (() => {
|
|
|
2843
2887
|
}
|
|
2844
2888
|
return true;
|
|
2845
2889
|
};
|
|
2846
|
-
|
|
2890
|
+
ReconnectingWebSocket3.prototype.removeEventListener = function(type, listener) {
|
|
2847
2891
|
if (this._listeners[type]) {
|
|
2848
2892
|
this._listeners[type] = this._listeners[type].filter(function(l) {
|
|
2849
2893
|
return l !== listener;
|
|
2850
2894
|
});
|
|
2851
2895
|
}
|
|
2852
2896
|
};
|
|
2853
|
-
|
|
2897
|
+
ReconnectingWebSocket3.prototype._debug = function() {
|
|
2854
2898
|
var args = [];
|
|
2855
2899
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2856
2900
|
args[_i] = arguments[_i];
|
|
@@ -2859,7 +2903,7 @@ var PHPSandbox = (() => {
|
|
|
2859
2903
|
console.log.apply(console, __spread(["RWS>"], args));
|
|
2860
2904
|
}
|
|
2861
2905
|
};
|
|
2862
|
-
|
|
2906
|
+
ReconnectingWebSocket3.prototype._getNextDelay = function() {
|
|
2863
2907
|
var _a = this._options, _b = _a.reconnectionDelayGrowFactor, reconnectionDelayGrowFactor = _b === void 0 ? DEFAULT.reconnectionDelayGrowFactor : _b, _c = _a.minReconnectionDelay, minReconnectionDelay = _c === void 0 ? DEFAULT.minReconnectionDelay : _c, _d = _a.maxReconnectionDelay, maxReconnectionDelay = _d === void 0 ? DEFAULT.maxReconnectionDelay : _d;
|
|
2864
2908
|
var delay = 0;
|
|
2865
2909
|
if (this._retryCount > 0) {
|
|
@@ -2871,13 +2915,13 @@ var PHPSandbox = (() => {
|
|
|
2871
2915
|
this._debug("next delay", delay);
|
|
2872
2916
|
return delay;
|
|
2873
2917
|
};
|
|
2874
|
-
|
|
2918
|
+
ReconnectingWebSocket3.prototype._wait = function() {
|
|
2875
2919
|
var _this = this;
|
|
2876
2920
|
return new Promise(function(resolve) {
|
|
2877
2921
|
setTimeout(resolve, _this._getNextDelay());
|
|
2878
2922
|
});
|
|
2879
2923
|
};
|
|
2880
|
-
|
|
2924
|
+
ReconnectingWebSocket3.prototype._getNextUrl = function(urlProvider) {
|
|
2881
2925
|
if (typeof urlProvider === "string") {
|
|
2882
2926
|
return Promise.resolve(urlProvider);
|
|
2883
2927
|
}
|
|
@@ -2892,7 +2936,7 @@ var PHPSandbox = (() => {
|
|
|
2892
2936
|
}
|
|
2893
2937
|
throw Error("Invalid URL");
|
|
2894
2938
|
};
|
|
2895
|
-
|
|
2939
|
+
ReconnectingWebSocket3.prototype._connect = function() {
|
|
2896
2940
|
var _this = this;
|
|
2897
2941
|
if (this._connectLock || !this._shouldReconnect) {
|
|
2898
2942
|
return;
|
|
@@ -2925,11 +2969,11 @@ var PHPSandbox = (() => {
|
|
|
2925
2969
|
}, connectionTimeout);
|
|
2926
2970
|
});
|
|
2927
2971
|
};
|
|
2928
|
-
|
|
2972
|
+
ReconnectingWebSocket3.prototype._handleTimeout = function() {
|
|
2929
2973
|
this._debug("timeout event");
|
|
2930
2974
|
this._handleError(new ErrorEvent2(Error("TIMEOUT"), this));
|
|
2931
2975
|
};
|
|
2932
|
-
|
|
2976
|
+
ReconnectingWebSocket3.prototype._disconnect = function(code, reason) {
|
|
2933
2977
|
if (code === void 0) {
|
|
2934
2978
|
code = 1e3;
|
|
2935
2979
|
}
|
|
@@ -2944,18 +2988,18 @@ var PHPSandbox = (() => {
|
|
|
2944
2988
|
} catch (error) {
|
|
2945
2989
|
}
|
|
2946
2990
|
};
|
|
2947
|
-
|
|
2991
|
+
ReconnectingWebSocket3.prototype._acceptOpen = function() {
|
|
2948
2992
|
this._debug("accept open");
|
|
2949
2993
|
this._retryCount = 0;
|
|
2950
2994
|
};
|
|
2951
|
-
|
|
2995
|
+
ReconnectingWebSocket3.prototype._callEventListener = function(event, listener) {
|
|
2952
2996
|
if ("handleEvent" in listener) {
|
|
2953
2997
|
listener.handleEvent(event);
|
|
2954
2998
|
} else {
|
|
2955
2999
|
listener(event);
|
|
2956
3000
|
}
|
|
2957
3001
|
};
|
|
2958
|
-
|
|
3002
|
+
ReconnectingWebSocket3.prototype._removeListeners = function() {
|
|
2959
3003
|
if (!this._ws) {
|
|
2960
3004
|
return;
|
|
2961
3005
|
}
|
|
@@ -2965,7 +3009,7 @@ var PHPSandbox = (() => {
|
|
|
2965
3009
|
this._ws.removeEventListener("message", this._handleMessage);
|
|
2966
3010
|
this._ws.removeEventListener("error", this._handleError);
|
|
2967
3011
|
};
|
|
2968
|
-
|
|
3012
|
+
ReconnectingWebSocket3.prototype._addListeners = function() {
|
|
2969
3013
|
if (!this._ws) {
|
|
2970
3014
|
return;
|
|
2971
3015
|
}
|
|
@@ -2975,11 +3019,11 @@ var PHPSandbox = (() => {
|
|
|
2975
3019
|
this._ws.addEventListener("message", this._handleMessage);
|
|
2976
3020
|
this._ws.addEventListener("error", this._handleError);
|
|
2977
3021
|
};
|
|
2978
|
-
|
|
3022
|
+
ReconnectingWebSocket3.prototype._clearTimeouts = function() {
|
|
2979
3023
|
clearTimeout(this._connectTimeout);
|
|
2980
3024
|
clearTimeout(this._uptimeTimeout);
|
|
2981
3025
|
};
|
|
2982
|
-
return
|
|
3026
|
+
return ReconnectingWebSocket3;
|
|
2983
3027
|
})()
|
|
2984
3028
|
);
|
|
2985
3029
|
var reconnecting_websocket_mjs_default = ReconnectingWebSocket;
|
|
@@ -3104,6 +3148,7 @@ var PHPSandbox = (() => {
|
|
|
3104
3148
|
};
|
|
3105
3149
|
|
|
3106
3150
|
// src/socket/index.ts
|
|
3151
|
+
var ReconnectingWebSocket2 = reconnecting_websocket_mjs_default ?? reconnecting_websocket_mjs_exports;
|
|
3107
3152
|
var ConnectionTimeoutError = class extends Error {
|
|
3108
3153
|
constructor(message = "WebSocket connection timeout") {
|
|
3109
3154
|
super(message);
|
|
@@ -3142,30 +3187,13 @@ var PHPSandbox = (() => {
|
|
|
3142
3187
|
this.connectPromise = null;
|
|
3143
3188
|
this.terminalError = null;
|
|
3144
3189
|
this.pingIntervalStarted = false;
|
|
3145
|
-
// Connection health monitoring
|
|
3146
|
-
this.connectionStats = {
|
|
3147
|
-
connectTime: 0,
|
|
3148
|
-
reconnectCount: 0,
|
|
3149
|
-
lastPingTime: 0,
|
|
3150
|
-
lastPongTime: 0,
|
|
3151
|
-
avgResponseTime: 0,
|
|
3152
|
-
totalMessages: 0,
|
|
3153
|
-
totalErrors: 0,
|
|
3154
|
-
connectionStartTime: 0
|
|
3155
|
-
};
|
|
3156
|
-
// Message queue for disconnection handling
|
|
3157
|
-
this.messageQueue = [];
|
|
3158
|
-
this.MAX_QUEUE_SIZE = 100;
|
|
3159
|
-
this.QUEUE_TIMEOUT = 3e4;
|
|
3160
|
-
// 30 seconds
|
|
3161
3190
|
this.incomingMessageChain = Promise.resolve();
|
|
3162
3191
|
this.validateConfiguration(options);
|
|
3163
3192
|
this.url = new URL(url);
|
|
3164
3193
|
this.PING_INTERVAL = options.pingInterval ?? 3e4;
|
|
3165
3194
|
this.CONNECT_WAIT_TIMEOUT = options.connectWaitTimeout ?? 3e4;
|
|
3166
|
-
this.connectionStats.connectionStartTime = Date.now();
|
|
3167
3195
|
const startClosed = options.startClosed !== false;
|
|
3168
|
-
this.rws = new
|
|
3196
|
+
this.rws = new ReconnectingWebSocket2(this.url.toString(), [], {
|
|
3169
3197
|
WebSocket: options.webSocket ?? globalThis.WebSocket ?? browser_default,
|
|
3170
3198
|
connectionTimeout: options.connectionTimeout,
|
|
3171
3199
|
maxReconnectionDelay: 2e3,
|
|
@@ -3179,8 +3207,6 @@ var PHPSandbox = (() => {
|
|
|
3179
3207
|
options
|
|
3180
3208
|
});
|
|
3181
3209
|
this.registerWatchers();
|
|
3182
|
-
this.setupConnectionHealthMonitoring();
|
|
3183
|
-
this.startPeriodicMaintenance();
|
|
3184
3210
|
}
|
|
3185
3211
|
/**
|
|
3186
3212
|
* Validate configuration options
|
|
@@ -3224,7 +3250,6 @@ var PHPSandbox = (() => {
|
|
|
3224
3250
|
async registerWatchers() {
|
|
3225
3251
|
const onMessage = (ev) => {
|
|
3226
3252
|
this.incomingMessageChain = this.incomingMessageChain.catch(() => void 0).then(() => this.processIncomingMessage(ev)).catch((error) => {
|
|
3227
|
-
this.connectionStats.totalErrors++;
|
|
3228
3253
|
this.log("error", "Failed to process queued WebSocket frame", {
|
|
3229
3254
|
error: error instanceof Error ? error.message : String(error)
|
|
3230
3255
|
});
|
|
@@ -3244,11 +3269,12 @@ var PHPSandbox = (() => {
|
|
|
3244
3269
|
});
|
|
3245
3270
|
}
|
|
3246
3271
|
async processIncomingMessage(ev) {
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
this.
|
|
3272
|
+
let buffer;
|
|
3273
|
+
try {
|
|
3274
|
+
buffer = await this.toArrayBuffer(ev.data);
|
|
3275
|
+
} catch (error) {
|
|
3250
3276
|
this.log("error", "Unexpected WebSocket message type", {
|
|
3251
|
-
error: error.message,
|
|
3277
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3252
3278
|
messageType: typeof ev.data
|
|
3253
3279
|
});
|
|
3254
3280
|
this.eventEmitter.emit("transport.error", {
|
|
@@ -3259,7 +3285,6 @@ var PHPSandbox = (() => {
|
|
|
3259
3285
|
});
|
|
3260
3286
|
return;
|
|
3261
3287
|
}
|
|
3262
|
-
const buffer = await ev.data.arrayBuffer();
|
|
3263
3288
|
if (buffer.byteLength === 0) {
|
|
3264
3289
|
this.log("warn", "Ignoring empty WebSocket frame");
|
|
3265
3290
|
return;
|
|
@@ -3268,7 +3293,6 @@ var PHPSandbox = (() => {
|
|
|
3268
3293
|
try {
|
|
3269
3294
|
decoded = decode(buffer);
|
|
3270
3295
|
} catch (error) {
|
|
3271
|
-
this.connectionStats.totalErrors++;
|
|
3272
3296
|
this.log("error", "Failed to decode WebSocket frame", {
|
|
3273
3297
|
error: error instanceof Error ? error.message : String(error),
|
|
3274
3298
|
byteLength: buffer.byteLength
|
|
@@ -3284,7 +3308,6 @@ var PHPSandbox = (() => {
|
|
|
3284
3308
|
try {
|
|
3285
3309
|
await this.handleRawMessage(decoded);
|
|
3286
3310
|
} catch (error) {
|
|
3287
|
-
this.connectionStats.totalErrors++;
|
|
3288
3311
|
this.log("error", "Failed to process WebSocket frame", {
|
|
3289
3312
|
error: error instanceof Error ? error.message : String(error),
|
|
3290
3313
|
byteLength: buffer.byteLength
|
|
@@ -3297,6 +3320,19 @@ var PHPSandbox = (() => {
|
|
|
3297
3320
|
});
|
|
3298
3321
|
}
|
|
3299
3322
|
}
|
|
3323
|
+
async toArrayBuffer(data) {
|
|
3324
|
+
if (data instanceof Blob) {
|
|
3325
|
+
return data.arrayBuffer();
|
|
3326
|
+
}
|
|
3327
|
+
if (data instanceof ArrayBuffer) {
|
|
3328
|
+
return data;
|
|
3329
|
+
}
|
|
3330
|
+
if (ArrayBuffer.isView(data)) {
|
|
3331
|
+
const bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
3332
|
+
return bytes.slice().buffer;
|
|
3333
|
+
}
|
|
3334
|
+
throw new Error("Unexpected message type: " + typeof data);
|
|
3335
|
+
}
|
|
3300
3336
|
async handleRawMessage(ev) {
|
|
3301
3337
|
if (this.closed) {
|
|
3302
3338
|
this.log("debug", "Ignoring message received after transport was closed");
|
|
@@ -3318,9 +3354,10 @@ var PHPSandbox = (() => {
|
|
|
3318
3354
|
return;
|
|
3319
3355
|
}
|
|
3320
3356
|
if (event === "Events.BootError" /* BootError */) {
|
|
3357
|
+
const errorData = data;
|
|
3321
3358
|
const error = new NotebookUnavailableError(
|
|
3322
|
-
|
|
3323
|
-
|
|
3359
|
+
errorData?.message || "Notebook is no longer available",
|
|
3360
|
+
errorData || {}
|
|
3324
3361
|
);
|
|
3325
3362
|
this.log("error", "Boot error received", { data });
|
|
3326
3363
|
this.terminate(error, 4e3, error.message);
|
|
@@ -3349,18 +3386,15 @@ var PHPSandbox = (() => {
|
|
|
3349
3386
|
}
|
|
3350
3387
|
await this.handleMessage(event, data, as);
|
|
3351
3388
|
} catch (e) {
|
|
3352
|
-
this.connectionStats.totalErrors++;
|
|
3353
3389
|
if (e instanceof InvalidMessageError) {
|
|
3354
3390
|
this.log("error", "Invalid message format", {
|
|
3355
3391
|
error: e.message,
|
|
3356
|
-
data: e.data
|
|
3357
|
-
totalErrors: this.connectionStats.totalErrors
|
|
3392
|
+
data: e.data
|
|
3358
3393
|
});
|
|
3359
3394
|
} else {
|
|
3360
3395
|
this.log("error", "Failed to parse message", {
|
|
3361
3396
|
ev,
|
|
3362
|
-
error: e instanceof Error ? e.message : String(e)
|
|
3363
|
-
totalErrors: this.connectionStats.totalErrors
|
|
3397
|
+
error: e instanceof Error ? e.message : String(e)
|
|
3364
3398
|
});
|
|
3365
3399
|
}
|
|
3366
3400
|
this.eventEmitter.emit("transport.error", {
|
|
@@ -3374,7 +3408,7 @@ var PHPSandbox = (() => {
|
|
|
3374
3408
|
async handleMessage(event, data, as) {
|
|
3375
3409
|
if (event === "App.Actions.GetClientId" /* ClientId */) {
|
|
3376
3410
|
this.clientId = data.id;
|
|
3377
|
-
this.eventEmitter.emit(event,
|
|
3411
|
+
this.eventEmitter.emit(event, this.clientId);
|
|
3378
3412
|
return;
|
|
3379
3413
|
}
|
|
3380
3414
|
event && this.eventEmitter.emit(as || event, data);
|
|
@@ -3383,7 +3417,7 @@ var PHPSandbox = (() => {
|
|
|
3383
3417
|
return this.eventEmitter.listen(event, listener);
|
|
3384
3418
|
}
|
|
3385
3419
|
onDidBootError(listener) {
|
|
3386
|
-
this.eventEmitter.listen("transport.boot_error", (event) => {
|
|
3420
|
+
return this.eventEmitter.listen("transport.boot_error", (event) => {
|
|
3387
3421
|
listener(event.error);
|
|
3388
3422
|
});
|
|
3389
3423
|
}
|
|
@@ -3391,12 +3425,7 @@ var PHPSandbox = (() => {
|
|
|
3391
3425
|
this.eventEmitter.removeListener(event, listener);
|
|
3392
3426
|
}
|
|
3393
3427
|
listenOnce(event, listener, context) {
|
|
3394
|
-
this.eventEmitter.once(event, listener, context);
|
|
3395
|
-
this.disposables.add(`once_${event}_${nanoid()}`, {
|
|
3396
|
-
dispose: () => {
|
|
3397
|
-
this.eventEmitter.removeListener(event, listener);
|
|
3398
|
-
}
|
|
3399
|
-
});
|
|
3428
|
+
return this.eventEmitter.once(event, listener, context);
|
|
3400
3429
|
}
|
|
3401
3430
|
emit(event, ...data) {
|
|
3402
3431
|
this.eventEmitter.emit(event, ...data);
|
|
@@ -3428,19 +3457,23 @@ var PHPSandbox = (() => {
|
|
|
3428
3457
|
if (this.terminalError) {
|
|
3429
3458
|
throw this.terminalError;
|
|
3430
3459
|
}
|
|
3431
|
-
this.clearOldQueuedMessages();
|
|
3432
3460
|
const responseEvent = options.responseEvent || `${action}_${nanoid()}_response`;
|
|
3433
3461
|
const errorEvent = `${responseEvent}_error`;
|
|
3434
3462
|
let closeHandler;
|
|
3463
|
+
let abortHandler;
|
|
3435
3464
|
const removeListeners = () => {
|
|
3436
3465
|
if (closeHandler) {
|
|
3437
3466
|
this.rws.removeEventListener("close", closeHandler);
|
|
3438
3467
|
this.rws.removeEventListener("error", closeHandler);
|
|
3439
3468
|
}
|
|
3469
|
+
if (abortHandler) {
|
|
3470
|
+
options.abortSignal?.removeEventListener("abort", abortHandler);
|
|
3471
|
+
abortHandler = void 0;
|
|
3472
|
+
}
|
|
3440
3473
|
this.eventEmitter.removeListener(responseEvent);
|
|
3441
3474
|
this.eventEmitter.removeListener(errorEvent);
|
|
3442
3475
|
};
|
|
3443
|
-
const handler =
|
|
3476
|
+
const handler = (resolve, reject) => {
|
|
3444
3477
|
if (this.terminalError) {
|
|
3445
3478
|
reject(this.terminalError);
|
|
3446
3479
|
return;
|
|
@@ -3448,48 +3481,28 @@ var PHPSandbox = (() => {
|
|
|
3448
3481
|
const abortError = new DOMException("Request aborted", "AbortError");
|
|
3449
3482
|
if (options.abortSignal?.aborted) {
|
|
3450
3483
|
reject(abortError);
|
|
3484
|
+
return;
|
|
3451
3485
|
}
|
|
3452
3486
|
if (options.abortSignal) {
|
|
3453
|
-
|
|
3487
|
+
abortHandler = () => {
|
|
3454
3488
|
reject(abortError);
|
|
3455
|
-
}
|
|
3489
|
+
};
|
|
3490
|
+
options.abortSignal.addEventListener("abort", abortHandler, { once: true });
|
|
3456
3491
|
}
|
|
3457
|
-
if (!this.isConnected
|
|
3458
|
-
|
|
3459
|
-
action
|
|
3460
|
-
});
|
|
3461
|
-
if (this.messageQueue.length >= this.MAX_QUEUE_SIZE) {
|
|
3462
|
-
const oldestMessage = this.messageQueue.shift();
|
|
3463
|
-
if (oldestMessage) {
|
|
3464
|
-
oldestMessage.reject(new Error("Message queue full, oldest message dropped"));
|
|
3465
|
-
}
|
|
3466
|
-
}
|
|
3467
|
-
this.messageQueue.push({
|
|
3468
|
-
action,
|
|
3469
|
-
data,
|
|
3470
|
-
options,
|
|
3471
|
-
resolve,
|
|
3472
|
-
reject,
|
|
3473
|
-
timestamp: Date.now()
|
|
3474
|
-
});
|
|
3492
|
+
if (!this.isConnected || this.isClosed) {
|
|
3493
|
+
reject(new ConnectionFailedError(`Connection is not open while sending ${action}. Current status: ${this.status}`));
|
|
3475
3494
|
return;
|
|
3476
3495
|
}
|
|
3477
|
-
const startTime = Date.now();
|
|
3478
3496
|
this.listenOnce(responseEvent, (response) => {
|
|
3479
|
-
const responseTime = Date.now() - startTime;
|
|
3480
|
-
this.connectionStats.avgResponseTime = (this.connectionStats.avgResponseTime + responseTime) / 2;
|
|
3481
|
-
this.connectionStats.totalMessages++;
|
|
3482
3497
|
this.log("debug", "Message response received", {
|
|
3483
|
-
action
|
|
3484
|
-
responseTime,
|
|
3485
|
-
avgResponseTime: this.connectionStats.avgResponseTime
|
|
3498
|
+
action
|
|
3486
3499
|
});
|
|
3487
3500
|
resolve(response);
|
|
3488
3501
|
});
|
|
3489
3502
|
this.listenOnce(errorEvent, (e) => {
|
|
3490
|
-
this.connectionStats.totalErrors++;
|
|
3491
3503
|
this.log("error", "Message error received", { action, error: e });
|
|
3492
|
-
|
|
3504
|
+
const error = e;
|
|
3505
|
+
reject(new ErrorEvent(error.code, error.message, error));
|
|
3493
3506
|
});
|
|
3494
3507
|
closeHandler = (_ev) => {
|
|
3495
3508
|
if (_ev.code === 1008 && (_ev.reason || "").includes("rate limit")) {
|
|
@@ -3506,11 +3519,17 @@ var PHPSandbox = (() => {
|
|
|
3506
3519
|
this.log("debug", "Message sent", { action, data });
|
|
3507
3520
|
} catch (error) {
|
|
3508
3521
|
this.log("error", "Failed to send message", { action, error });
|
|
3509
|
-
|
|
3522
|
+
reject(error);
|
|
3510
3523
|
}
|
|
3511
3524
|
};
|
|
3512
3525
|
const send = async () => {
|
|
3526
|
+
if (options.abortSignal?.aborted) {
|
|
3527
|
+
throw new DOMException("Request aborted", "AbortError");
|
|
3528
|
+
}
|
|
3513
3529
|
await __privateMethod(this, _Transport_instances, connect_fn).call(this);
|
|
3530
|
+
if (options.abortSignal?.aborted) {
|
|
3531
|
+
throw new DOMException("Request aborted", "AbortError");
|
|
3532
|
+
}
|
|
3514
3533
|
const promise = new Promise(handler).finally(removeListeners);
|
|
3515
3534
|
if (!options.timeout) {
|
|
3516
3535
|
return promise;
|
|
@@ -3522,7 +3541,8 @@ var PHPSandbox = (() => {
|
|
|
3522
3541
|
throw error;
|
|
3523
3542
|
}).finally(removeListeners);
|
|
3524
3543
|
};
|
|
3525
|
-
|
|
3544
|
+
const retries = options.retries === false ? 0 : options.retries ?? 0;
|
|
3545
|
+
return this.sendWithRetry(async () => await send(), retries);
|
|
3526
3546
|
}
|
|
3527
3547
|
send(action, data = {}) {
|
|
3528
3548
|
if (this.terminalError) {
|
|
@@ -3536,11 +3556,9 @@ var PHPSandbox = (() => {
|
|
|
3536
3556
|
}
|
|
3537
3557
|
try {
|
|
3538
3558
|
this.rws.send(this.pack({ action, data }));
|
|
3539
|
-
this.connectionStats.totalMessages++;
|
|
3540
3559
|
this.log("debug", "One-way message sent", { action, data });
|
|
3541
3560
|
return true;
|
|
3542
3561
|
} catch (error) {
|
|
3543
|
-
this.connectionStats.totalErrors++;
|
|
3544
3562
|
this.log("error", "Failed to send one-way message", { action, error });
|
|
3545
3563
|
return false;
|
|
3546
3564
|
}
|
|
@@ -3548,7 +3566,7 @@ var PHPSandbox = (() => {
|
|
|
3548
3566
|
pack(data) {
|
|
3549
3567
|
return new Blob([encode(data)]);
|
|
3550
3568
|
}
|
|
3551
|
-
sendWithRetry(sender, retries
|
|
3569
|
+
sendWithRetry(sender, retries) {
|
|
3552
3570
|
return retry(
|
|
3553
3571
|
async (bail, attempt) => {
|
|
3554
3572
|
try {
|
|
@@ -3571,8 +3589,7 @@ var PHPSandbox = (() => {
|
|
|
3571
3589
|
}
|
|
3572
3590
|
this.log("debug", "Retrying send operation", {
|
|
3573
3591
|
attempt,
|
|
3574
|
-
error: e instanceof Error ? e.message : String(e)
|
|
3575
|
-
nextDelay: this.getBackoffDelay(attempt - 1)
|
|
3592
|
+
error: e instanceof Error ? e.message : String(e)
|
|
3576
3593
|
});
|
|
3577
3594
|
throw e;
|
|
3578
3595
|
}
|
|
@@ -3618,7 +3635,6 @@ var PHPSandbox = (() => {
|
|
|
3618
3635
|
}
|
|
3619
3636
|
disconnect() {
|
|
3620
3637
|
if (this.closed) {
|
|
3621
|
-
console.trace("Transport is already closed, cannot disconnect again");
|
|
3622
3638
|
return;
|
|
3623
3639
|
}
|
|
3624
3640
|
this.close();
|
|
@@ -3639,15 +3655,6 @@ var PHPSandbox = (() => {
|
|
|
3639
3655
|
}
|
|
3640
3656
|
this.log("info", "Closing transport connection", { code, reason });
|
|
3641
3657
|
this.connectPromise = null;
|
|
3642
|
-
const queuedCount = this.messageQueue.length;
|
|
3643
|
-
const closeError = this.terminalError || new Error("Connection closed while message was queued");
|
|
3644
|
-
this.messageQueue.forEach((msg) => {
|
|
3645
|
-
msg.reject(closeError);
|
|
3646
|
-
});
|
|
3647
|
-
this.messageQueue = [];
|
|
3648
|
-
if (queuedCount > 0) {
|
|
3649
|
-
this.log("debug", `Rejected ${queuedCount} queued messages due to connection close`);
|
|
3650
|
-
}
|
|
3651
3658
|
this.disposables.dispose();
|
|
3652
3659
|
try {
|
|
3653
3660
|
this.rws.close(code, reason);
|
|
@@ -3659,7 +3666,6 @@ var PHPSandbox = (() => {
|
|
|
3659
3666
|
this.eventEmitter.emit("transport.closed", {
|
|
3660
3667
|
code,
|
|
3661
3668
|
reason,
|
|
3662
|
-
metrics: this.getConnectionMetrics(),
|
|
3663
3669
|
timestamp: Date.now()
|
|
3664
3670
|
});
|
|
3665
3671
|
this.eventEmitter.removeListener("*");
|
|
@@ -3668,250 +3674,23 @@ var PHPSandbox = (() => {
|
|
|
3668
3674
|
}
|
|
3669
3675
|
onDidConnect(listener) {
|
|
3670
3676
|
this.rws.addEventListener("open", listener);
|
|
3671
|
-
|
|
3677
|
+
const disposable = {
|
|
3672
3678
|
dispose: () => {
|
|
3673
3679
|
this.rws.removeEventListener("open", listener);
|
|
3674
3680
|
}
|
|
3675
|
-
}
|
|
3681
|
+
};
|
|
3682
|
+
this.disposables.add(`connect_${nanoid()}`, disposable);
|
|
3683
|
+
return disposable;
|
|
3676
3684
|
}
|
|
3677
3685
|
onDidClose(listener) {
|
|
3678
3686
|
this.rws.addEventListener("close", listener);
|
|
3679
|
-
|
|
3687
|
+
const disposable = {
|
|
3680
3688
|
dispose: () => {
|
|
3681
3689
|
this.rws.removeEventListener("close", listener);
|
|
3682
3690
|
}
|
|
3683
|
-
});
|
|
3684
|
-
}
|
|
3685
|
-
/**
|
|
3686
|
-
* Setup connection health monitoring
|
|
3687
|
-
*/
|
|
3688
|
-
setupConnectionHealthMonitoring() {
|
|
3689
|
-
this.rws.addEventListener("open", () => {
|
|
3690
|
-
this.connectionStats.connectTime = Date.now();
|
|
3691
|
-
this.connectionStats.reconnectCount++;
|
|
3692
|
-
this.log("info", "Connection established", {
|
|
3693
|
-
reconnectCount: this.connectionStats.reconnectCount,
|
|
3694
|
-
timeSinceStart: Date.now() - this.connectionStats.connectionStartTime
|
|
3695
|
-
});
|
|
3696
|
-
this.processMessageQueue();
|
|
3697
|
-
});
|
|
3698
|
-
this.rws.addEventListener("close", (event) => {
|
|
3699
|
-
this.log("warn", "Connection closed", {
|
|
3700
|
-
code: event.code,
|
|
3701
|
-
reason: event.reason,
|
|
3702
|
-
wasClean: event.wasClean
|
|
3703
|
-
});
|
|
3704
|
-
this.handleConnectionClose(event.code);
|
|
3705
|
-
});
|
|
3706
|
-
this.rws.addEventListener("error", (event) => {
|
|
3707
|
-
this.connectionStats.totalErrors++;
|
|
3708
|
-
const detail = describeWebSocketEvent(event);
|
|
3709
|
-
this.log("error", "Connection error", {
|
|
3710
|
-
error: detail,
|
|
3711
|
-
rawError: event,
|
|
3712
|
-
totalErrors: this.connectionStats.totalErrors
|
|
3713
|
-
});
|
|
3714
|
-
});
|
|
3715
|
-
}
|
|
3716
|
-
/**
|
|
3717
|
-
* Handle different WebSocket close codes appropriately
|
|
3718
|
-
*/
|
|
3719
|
-
handleConnectionClose(code) {
|
|
3720
|
-
switch (code) {
|
|
3721
|
-
case 1e3:
|
|
3722
|
-
this.log("info", "Normal connection closure");
|
|
3723
|
-
return "stop";
|
|
3724
|
-
case 1001:
|
|
3725
|
-
this.log("info", "Connection going away, will reconnect");
|
|
3726
|
-
return "reconnect";
|
|
3727
|
-
case 1006:
|
|
3728
|
-
this.log("warn", "Abnormal connection closure, will retry");
|
|
3729
|
-
return "retry";
|
|
3730
|
-
case 1008:
|
|
3731
|
-
this.log("error", "Connection closed due to policy violation");
|
|
3732
|
-
this.clearOldQueuedMessages();
|
|
3733
|
-
return "stop";
|
|
3734
|
-
case 4e3:
|
|
3735
|
-
this.log("info", "Connection closed due to terminal notebook error");
|
|
3736
|
-
return "stop";
|
|
3737
|
-
default:
|
|
3738
|
-
this.log("warn", `Unknown close code: ${code}, will reconnect`);
|
|
3739
|
-
return "reconnect";
|
|
3740
|
-
}
|
|
3741
|
-
}
|
|
3742
|
-
/**
|
|
3743
|
-
* Process queued messages when connection is restored
|
|
3744
|
-
*/
|
|
3745
|
-
processMessageQueue() {
|
|
3746
|
-
if (this.messageQueue.length === 0) {
|
|
3747
|
-
return;
|
|
3748
|
-
}
|
|
3749
|
-
this.log("debug", `Processing ${this.messageQueue.length} queued messages`);
|
|
3750
|
-
const queue = [...this.messageQueue];
|
|
3751
|
-
this.messageQueue = [];
|
|
3752
|
-
for (const queuedMessage of queue) {
|
|
3753
|
-
if (Date.now() - queuedMessage.timestamp > this.QUEUE_TIMEOUT) {
|
|
3754
|
-
queuedMessage.reject(new Error("Queued message timed out"));
|
|
3755
|
-
continue;
|
|
3756
|
-
}
|
|
3757
|
-
this.call(queuedMessage.action, queuedMessage.data, queuedMessage.options).then(queuedMessage.resolve).catch(queuedMessage.reject);
|
|
3758
|
-
}
|
|
3759
|
-
}
|
|
3760
|
-
/**
|
|
3761
|
-
* Clear old queued messages to prevent memory leaks
|
|
3762
|
-
*/
|
|
3763
|
-
clearOldQueuedMessages() {
|
|
3764
|
-
const now = Date.now();
|
|
3765
|
-
const originalLength = this.messageQueue.length;
|
|
3766
|
-
this.messageQueue = this.messageQueue.filter((msg) => {
|
|
3767
|
-
const isExpired = now - msg.timestamp > this.QUEUE_TIMEOUT;
|
|
3768
|
-
if (isExpired) {
|
|
3769
|
-
msg.reject(new Error("Queued message expired"));
|
|
3770
|
-
}
|
|
3771
|
-
return !isExpired;
|
|
3772
|
-
});
|
|
3773
|
-
if (originalLength !== this.messageQueue.length) {
|
|
3774
|
-
this.log("debug", `Cleared ${originalLength - this.messageQueue.length} expired messages`);
|
|
3775
|
-
}
|
|
3776
|
-
}
|
|
3777
|
-
/**
|
|
3778
|
-
* Calculate exponential backoff delay
|
|
3779
|
-
*/
|
|
3780
|
-
getBackoffDelay(retryCount) {
|
|
3781
|
-
const baseDelay = 1e3;
|
|
3782
|
-
const maxDelay = 3e4;
|
|
3783
|
-
const delay = Math.min(baseDelay * Math.pow(2, retryCount), maxDelay);
|
|
3784
|
-
return delay + Math.random() * 1e3;
|
|
3785
|
-
}
|
|
3786
|
-
/**
|
|
3787
|
-
* Get comprehensive connection metrics
|
|
3788
|
-
*/
|
|
3789
|
-
getConnectionMetrics() {
|
|
3790
|
-
const now = Date.now();
|
|
3791
|
-
const connectionDuration = this.connectionStats.connectTime > 0 ? now - this.connectionStats.connectTime : 0;
|
|
3792
|
-
return {
|
|
3793
|
-
status: this.status,
|
|
3794
|
-
clientId: this.clientId,
|
|
3795
|
-
isConnected: this.isConnected,
|
|
3796
|
-
isConnecting: this.isConnecting,
|
|
3797
|
-
connectionStats: {
|
|
3798
|
-
...this.connectionStats,
|
|
3799
|
-
connectionDuration,
|
|
3800
|
-
uptime: now - this.connectionStats.connectionStartTime,
|
|
3801
|
-
messagesPerSecond: connectionDuration > 0 ? (this.connectionStats.totalMessages / (connectionDuration / 1e3)).toFixed(2) : "0",
|
|
3802
|
-
errorRate: this.connectionStats.totalMessages > 0 ? (this.connectionStats.totalErrors / this.connectionStats.totalMessages * 100).toFixed(2) + "%" : "0%",
|
|
3803
|
-
timeSinceLastPing: this.connectionStats.lastPingTime > 0 ? now - this.connectionStats.lastPingTime : 0,
|
|
3804
|
-
timeSinceLastPong: this.connectionStats.lastPongTime > 0 ? now - this.connectionStats.lastPongTime : 0
|
|
3805
|
-
},
|
|
3806
|
-
messageQueue: {
|
|
3807
|
-
length: this.messageQueue.length,
|
|
3808
|
-
maxSize: this.MAX_QUEUE_SIZE,
|
|
3809
|
-
oldestMessageAge: this.messageQueue.length > 0 ? now - Math.min(...this.messageQueue.map((m) => m.timestamp)) : 0
|
|
3810
|
-
},
|
|
3811
|
-
config: {
|
|
3812
|
-
pingInterval: this.PING_INTERVAL,
|
|
3813
|
-
queueTimeout: this.QUEUE_TIMEOUT,
|
|
3814
|
-
url: this.url.toString()
|
|
3815
|
-
}
|
|
3816
|
-
};
|
|
3817
|
-
}
|
|
3818
|
-
/**
|
|
3819
|
-
* Get connection health status
|
|
3820
|
-
*/
|
|
3821
|
-
getHealthStatus() {
|
|
3822
|
-
const metrics = this.getConnectionMetrics();
|
|
3823
|
-
const stats = metrics.connectionStats;
|
|
3824
|
-
if (!this.isConnected || stats.timeSinceLastPong > this.PING_INTERVAL * 2 || Number.parseFloat(stats.errorRate) > 50) {
|
|
3825
|
-
return "unhealthy";
|
|
3826
|
-
}
|
|
3827
|
-
if (stats.avgResponseTime > 5e3 || Number.parseFloat(stats.errorRate) > 10 || stats.timeSinceLastPong > this.PING_INTERVAL * 1.5) {
|
|
3828
|
-
return "degraded";
|
|
3829
|
-
}
|
|
3830
|
-
return "healthy";
|
|
3831
|
-
}
|
|
3832
|
-
/**
|
|
3833
|
-
* Reset connection statistics
|
|
3834
|
-
*/
|
|
3835
|
-
resetStats() {
|
|
3836
|
-
this.connectionStats = {
|
|
3837
|
-
connectTime: Date.now(),
|
|
3838
|
-
reconnectCount: 0,
|
|
3839
|
-
lastPingTime: 0,
|
|
3840
|
-
lastPongTime: 0,
|
|
3841
|
-
avgResponseTime: 0,
|
|
3842
|
-
totalMessages: 0,
|
|
3843
|
-
totalErrors: 0,
|
|
3844
|
-
connectionStartTime: Date.now()
|
|
3845
3691
|
};
|
|
3846
|
-
this.
|
|
3847
|
-
|
|
3848
|
-
/**
|
|
3849
|
-
* Run connection diagnostics
|
|
3850
|
-
*/
|
|
3851
|
-
async runDiagnostics() {
|
|
3852
|
-
const metrics = this.getConnectionMetrics();
|
|
3853
|
-
const status = this.getHealthStatus();
|
|
3854
|
-
const issues = [];
|
|
3855
|
-
const recommendations = [];
|
|
3856
|
-
if (!this.isConnected) {
|
|
3857
|
-
issues.push("Connection is not established");
|
|
3858
|
-
recommendations.push("Check network connectivity and server availability");
|
|
3859
|
-
}
|
|
3860
|
-
if (metrics.connectionStats.timeSinceLastPong > this.PING_INTERVAL * 2) {
|
|
3861
|
-
issues.push("No pong received recently - connection may be stale");
|
|
3862
|
-
recommendations.push("Consider forcing a reconnection");
|
|
3863
|
-
}
|
|
3864
|
-
if (Number.parseFloat(metrics.connectionStats.errorRate) > 10) {
|
|
3865
|
-
issues.push(`High error rate: ${metrics.connectionStats.errorRate}`);
|
|
3866
|
-
recommendations.push("Check server logs and network stability");
|
|
3867
|
-
}
|
|
3868
|
-
if (metrics.messageQueue.length > this.MAX_QUEUE_SIZE * 0.8) {
|
|
3869
|
-
issues.push("Message queue is nearly full");
|
|
3870
|
-
recommendations.push("Check connection stability and consider reducing message frequency");
|
|
3871
|
-
}
|
|
3872
|
-
if (metrics.connectionStats.avgResponseTime > 5e3) {
|
|
3873
|
-
issues.push("High average response time");
|
|
3874
|
-
recommendations.push("Check network latency and server performance");
|
|
3875
|
-
}
|
|
3876
|
-
this.log("info", "Connection diagnostics completed", {
|
|
3877
|
-
status,
|
|
3878
|
-
issueCount: issues.length,
|
|
3879
|
-
recommendationCount: recommendations.length
|
|
3880
|
-
});
|
|
3881
|
-
return {
|
|
3882
|
-
status,
|
|
3883
|
-
metrics,
|
|
3884
|
-
issues,
|
|
3885
|
-
recommendations
|
|
3886
|
-
};
|
|
3887
|
-
}
|
|
3888
|
-
/**
|
|
3889
|
-
* Periodic maintenance - clean up old data, run health checks
|
|
3890
|
-
*/
|
|
3891
|
-
startPeriodicMaintenance() {
|
|
3892
|
-
this.disposables.add("maintenance", () => {
|
|
3893
|
-
const maintenanceInterval = setInterval(
|
|
3894
|
-
() => {
|
|
3895
|
-
this.clearOldQueuedMessages();
|
|
3896
|
-
if (this.options.debug) {
|
|
3897
|
-
const health = this.getHealthStatus();
|
|
3898
|
-
const metrics = this.getConnectionMetrics();
|
|
3899
|
-
this.log("debug", "Periodic health check", {
|
|
3900
|
-
health,
|
|
3901
|
-
messageCount: metrics.connectionStats.totalMessages,
|
|
3902
|
-
errorCount: metrics.connectionStats.totalErrors,
|
|
3903
|
-
queueLength: metrics.messageQueue.length
|
|
3904
|
-
});
|
|
3905
|
-
}
|
|
3906
|
-
},
|
|
3907
|
-
5 * 60 * 1e3
|
|
3908
|
-
);
|
|
3909
|
-
return {
|
|
3910
|
-
dispose: () => {
|
|
3911
|
-
clearInterval(maintenanceInterval);
|
|
3912
|
-
}
|
|
3913
|
-
};
|
|
3914
|
-
});
|
|
3692
|
+
this.disposables.add(`close_${nanoid()}`, disposable);
|
|
3693
|
+
return disposable;
|
|
3915
3694
|
}
|
|
3916
3695
|
};
|
|
3917
3696
|
_Transport_instances = new WeakSet();
|
|
@@ -3961,7 +3740,7 @@ var PHPSandbox = (() => {
|
|
|
3961
3740
|
};
|
|
3962
3741
|
const closeHandler = (event) => {
|
|
3963
3742
|
const detail = describeWebSocketEvent(event);
|
|
3964
|
-
if (
|
|
3743
|
+
if (event.code === 1008 || event.code === 4e3) {
|
|
3965
3744
|
cleanup();
|
|
3966
3745
|
this.connectPromise = null;
|
|
3967
3746
|
reject(new ConnectionFailedError(`WebSocket connection failed: ${detail}`, event));
|
|
@@ -3993,21 +3772,13 @@ var PHPSandbox = (() => {
|
|
|
3993
3772
|
this.disposables.add("pingInterval", () => {
|
|
3994
3773
|
const interval = setInterval(async () => {
|
|
3995
3774
|
try {
|
|
3996
|
-
this.connectionStats.lastPingTime = Date.now();
|
|
3997
3775
|
this.log("debug", "Sending periodic ping");
|
|
3998
|
-
const startTime = Date.now();
|
|
3999
3776
|
await this.invoke("ping");
|
|
4000
|
-
this.
|
|
4001
|
-
const pingTime = this.connectionStats.lastPongTime - startTime;
|
|
4002
|
-
this.log("debug", `Ping successful`, { pingTime });
|
|
3777
|
+
this.log("debug", "Ping successful");
|
|
4003
3778
|
} catch (error) {
|
|
4004
3779
|
this.log("error", "Ping failed", {
|
|
4005
3780
|
error: error instanceof Error ? error.message : String(error)
|
|
4006
3781
|
});
|
|
4007
|
-
if (Date.now() - this.connectionStats.lastPongTime > this.PING_INTERVAL * 3) {
|
|
4008
|
-
this.log("warn", "Connection appears dead, forcing reconnection");
|
|
4009
|
-
this.rws.reconnect();
|
|
4010
|
-
}
|
|
4011
3782
|
}
|
|
4012
3783
|
}, this.PING_INTERVAL);
|
|
4013
3784
|
return {
|
|
@@ -4020,6 +3791,10 @@ var PHPSandbox = (() => {
|
|
|
4020
3791
|
};
|
|
4021
3792
|
|
|
4022
3793
|
// node_modules/mitt/dist/mitt.mjs
|
|
3794
|
+
var mitt_exports = {};
|
|
3795
|
+
__export(mitt_exports, {
|
|
3796
|
+
default: () => mitt_default
|
|
3797
|
+
});
|
|
4023
3798
|
function mitt_default(n) {
|
|
4024
3799
|
return { all: n = n || /* @__PURE__ */ new Map(), on: function(t, e) {
|
|
4025
3800
|
var i = n.get(t);
|
|
@@ -4038,11 +3813,20 @@ var PHPSandbox = (() => {
|
|
|
4038
3813
|
}
|
|
4039
3814
|
|
|
4040
3815
|
// src/events/index.ts
|
|
3816
|
+
var createMitt = mitt_default ?? mitt_exports;
|
|
4041
3817
|
function mittWithOnce(all) {
|
|
4042
|
-
const inst =
|
|
3818
|
+
const inst = createMitt(all);
|
|
4043
3819
|
inst.once = (type, fn) => {
|
|
4044
|
-
|
|
4045
|
-
|
|
3820
|
+
const onceHandler = (event) => {
|
|
3821
|
+
inst.off(type, onceHandler);
|
|
3822
|
+
fn(event);
|
|
3823
|
+
};
|
|
3824
|
+
inst.on(type, onceHandler);
|
|
3825
|
+
return {
|
|
3826
|
+
dispose: () => {
|
|
3827
|
+
inst.off(type, onceHandler);
|
|
3828
|
+
}
|
|
3829
|
+
};
|
|
4046
3830
|
};
|
|
4047
3831
|
return inst;
|
|
4048
3832
|
}
|
|
@@ -4057,11 +3841,11 @@ var PHPSandbox = (() => {
|
|
|
4057
3841
|
this.emitter.on(event, callback);
|
|
4058
3842
|
return { dispose };
|
|
4059
3843
|
}
|
|
4060
|
-
emit(event, data) {
|
|
4061
|
-
this.emitter.emit(event, data);
|
|
3844
|
+
emit(event, ...data) {
|
|
3845
|
+
this.emitter.emit(event, data.length > 1 ? data : data[0]);
|
|
4062
3846
|
}
|
|
4063
3847
|
once(event, callback) {
|
|
4064
|
-
this.emitter.once(event, callback);
|
|
3848
|
+
return this.emitter.once(event, callback);
|
|
4065
3849
|
}
|
|
4066
3850
|
static make() {
|
|
4067
3851
|
return new _EventManager();
|
|
@@ -4561,11 +4345,11 @@ var PHPSandbox = (() => {
|
|
|
4561
4345
|
});
|
|
4562
4346
|
},
|
|
4563
4347
|
{
|
|
4564
|
-
retries: this.options.retry?.retries
|
|
4565
|
-
minTimeout: this.options.retry?.minTimeout
|
|
4566
|
-
maxTimeout: this.options.retry?.maxTimeout
|
|
4567
|
-
factor: this.options.retry?.factor
|
|
4568
|
-
randomize: this.options.retry?.randomize
|
|
4348
|
+
retries: this.options.retry?.retries ?? 3,
|
|
4349
|
+
minTimeout: this.options.retry?.minTimeout ?? 1e3,
|
|
4350
|
+
maxTimeout: this.options.retry?.maxTimeout ?? 5e3,
|
|
4351
|
+
factor: this.options.retry?.factor ?? 2,
|
|
4352
|
+
randomize: this.options.retry?.randomize ?? true,
|
|
4569
4353
|
onRetry: (error, attempt) => {
|
|
4570
4354
|
if (this.options.debug) {
|
|
4571
4355
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -4635,11 +4419,11 @@ var PHPSandbox = (() => {
|
|
|
4635
4419
|
});
|
|
4636
4420
|
},
|
|
4637
4421
|
{
|
|
4638
|
-
retries: this.options.retry?.retries
|
|
4639
|
-
minTimeout: this.options.retry?.minTimeout
|
|
4640
|
-
maxTimeout: this.options.retry?.maxTimeout
|
|
4641
|
-
factor: this.options.retry?.factor
|
|
4642
|
-
randomize: this.options.retry?.randomize
|
|
4422
|
+
retries: this.options.retry?.retries ?? 3,
|
|
4423
|
+
minTimeout: this.options.retry?.minTimeout ?? 1e3,
|
|
4424
|
+
maxTimeout: this.options.retry?.maxTimeout ?? 5e3,
|
|
4425
|
+
factor: this.options.retry?.factor ?? 2,
|
|
4426
|
+
randomize: this.options.retry?.randomize ?? true,
|
|
4643
4427
|
onRetry: (error, attempt) => {
|
|
4644
4428
|
if (this.options.debug) {
|
|
4645
4429
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -4700,7 +4484,7 @@ var PHPSandbox = (() => {
|
|
|
4700
4484
|
* Listen for beacon events (one-time)
|
|
4701
4485
|
*/
|
|
4702
4486
|
once(event, handler) {
|
|
4703
|
-
this.eventEmitter.once(event, handler);
|
|
4487
|
+
return this.eventEmitter.once(event, handler);
|
|
4704
4488
|
}
|
|
4705
4489
|
/**
|
|
4706
4490
|
* Ping the beacon to check if it's responsive
|
|
@@ -4933,12 +4717,20 @@ var PHPSandbox = (() => {
|
|
|
4933
4717
|
return instance;
|
|
4934
4718
|
}
|
|
4935
4719
|
};
|
|
4720
|
+
function normalizeApiBaseUrl(url) {
|
|
4721
|
+
const baseUrl = new URL(url);
|
|
4722
|
+
const pathname = baseUrl.pathname.replace(/\/+$/, "");
|
|
4723
|
+
baseUrl.pathname = pathname === "" || pathname === "/" ? "/v1/" : `${pathname}/`;
|
|
4724
|
+
baseUrl.search = "";
|
|
4725
|
+
baseUrl.hash = "";
|
|
4726
|
+
return baseUrl.toString();
|
|
4727
|
+
}
|
|
4936
4728
|
var Client = class {
|
|
4937
4729
|
constructor(token, url = "https://api.phpsandbox.io/v1", options = {}) {
|
|
4938
4730
|
this.fetch = globalThis.fetch;
|
|
4939
4731
|
this.notebook = new NotebookApi(this);
|
|
4940
4732
|
this.options = Object.assign({ startClosed: true }, options);
|
|
4941
|
-
this.baseUrl = url;
|
|
4733
|
+
this.baseUrl = normalizeApiBaseUrl(url);
|
|
4942
4734
|
if (options.fetch) {
|
|
4943
4735
|
this.fetch = options.fetch;
|
|
4944
4736
|
}
|
|
@@ -4952,17 +4744,17 @@ var PHPSandbox = (() => {
|
|
|
4952
4744
|
return this.makeRequest("GET", path);
|
|
4953
4745
|
}
|
|
4954
4746
|
post(path, body) {
|
|
4955
|
-
return this.makeRequest("POST", path, { body: body ? JSON.stringify(body)
|
|
4747
|
+
return this.makeRequest("POST", path, { body: body === void 0 ? void 0 : JSON.stringify(body) });
|
|
4956
4748
|
}
|
|
4957
4749
|
delete(path) {
|
|
4958
4750
|
return this.makeRequest("DELETE", path);
|
|
4959
4751
|
}
|
|
4960
4752
|
put(path, body) {
|
|
4961
|
-
return this.makeRequest("PUT", path, { body: body ? JSON.stringify(body)
|
|
4753
|
+
return this.makeRequest("PUT", path, { body: body === void 0 ? void 0 : JSON.stringify(body) });
|
|
4962
4754
|
}
|
|
4963
4755
|
async makeRequest(method, path, init) {
|
|
4964
4756
|
const response = await this.fetch(
|
|
4965
|
-
new Request(new URL(
|
|
4757
|
+
new Request(new URL(path.replace(/^\//, ""), this.baseUrl), {
|
|
4966
4758
|
method,
|
|
4967
4759
|
...init,
|
|
4968
4760
|
headers: this.headers
|
|
@@ -5081,7 +4873,7 @@ var PHPSandbox = (() => {
|
|
|
5081
4873
|
this.log = new Log(this);
|
|
5082
4874
|
this.repl = new Repl(this);
|
|
5083
4875
|
this.container = new Container(this);
|
|
5084
|
-
this.laravel = new
|
|
4876
|
+
this.laravel = new Laravel(this);
|
|
5085
4877
|
this.shell = new Shell(this);
|
|
5086
4878
|
this.git = new Git(this);
|
|
5087
4879
|
this.services = new Services(this);
|
|
@@ -5139,24 +4931,12 @@ var PHPSandbox = (() => {
|
|
|
5139
4931
|
!this.socket.isClosed && this.socket.disconnect();
|
|
5140
4932
|
}
|
|
5141
4933
|
connected() {
|
|
5142
|
-
|
|
5143
|
-
if (terminalError) {
|
|
5144
|
-
return Promise.reject(terminalError);
|
|
5145
|
-
}
|
|
5146
|
-
if (this.socket.isConnected) {
|
|
5147
|
-
return Promise.resolve(this);
|
|
5148
|
-
}
|
|
5149
|
-
return new Promise((resolve, reject) => {
|
|
5150
|
-
try {
|
|
5151
|
-
this.socket.onDidConnect(() => resolve(this));
|
|
5152
|
-
this.socket.onDidClose(() => reject(new Error("Connection closed")));
|
|
5153
|
-
this.socket.onDidBootError((error) => reject(error));
|
|
5154
|
-
} catch (e) {
|
|
5155
|
-
reject(e);
|
|
5156
|
-
}
|
|
5157
|
-
});
|
|
4934
|
+
return this.waitForSocketConnection({ rejectOnClose: true });
|
|
5158
4935
|
}
|
|
5159
4936
|
whenConnected() {
|
|
4937
|
+
return this.waitForSocketConnection({ rejectOnClose: false });
|
|
4938
|
+
}
|
|
4939
|
+
waitForSocketConnection(options) {
|
|
5160
4940
|
const terminalError = this.socket.getTerminalError();
|
|
5161
4941
|
if (terminalError) {
|
|
5162
4942
|
return Promise.reject(terminalError);
|
|
@@ -5165,11 +4945,30 @@ var PHPSandbox = (() => {
|
|
|
5165
4945
|
return Promise.resolve(this);
|
|
5166
4946
|
}
|
|
5167
4947
|
return new Promise((resolve, reject) => {
|
|
4948
|
+
const disposables = [];
|
|
4949
|
+
let settled = false;
|
|
4950
|
+
const cleanup = () => {
|
|
4951
|
+
for (const disposable of disposables) {
|
|
4952
|
+
disposable.dispose();
|
|
4953
|
+
}
|
|
4954
|
+
disposables.length = 0;
|
|
4955
|
+
};
|
|
4956
|
+
const settle = (callback) => {
|
|
4957
|
+
if (settled) {
|
|
4958
|
+
return;
|
|
4959
|
+
}
|
|
4960
|
+
settled = true;
|
|
4961
|
+
cleanup();
|
|
4962
|
+
callback();
|
|
4963
|
+
};
|
|
5168
4964
|
try {
|
|
5169
|
-
this.socket.onDidConnect(() => resolve(this));
|
|
5170
|
-
|
|
4965
|
+
disposables.push(this.socket.onDidConnect(() => settle(() => resolve(this))));
|
|
4966
|
+
if (options.rejectOnClose) {
|
|
4967
|
+
disposables.push(this.socket.onDidClose(() => settle(() => reject(new Error("Connection closed")))));
|
|
4968
|
+
}
|
|
4969
|
+
disposables.push(this.socket.onDidBootError((error) => settle(() => reject(error))));
|
|
5171
4970
|
} catch (e) {
|
|
5172
|
-
reject(e);
|
|
4971
|
+
settle(() => reject(e));
|
|
5173
4972
|
}
|
|
5174
4973
|
});
|
|
5175
4974
|
}
|
|
@@ -5349,4 +5148,3 @@ reconnecting-websocket/dist/reconnecting-websocket-mjs.js:
|
|
|
5349
5148
|
* License MIT
|
|
5350
5149
|
*)
|
|
5351
5150
|
*/
|
|
5352
|
-
//# sourceMappingURL=phpsandbox-sdk.iife.js.map
|