@phpsandbox/sdk 0.0.30 → 0.0.33
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 +19 -0
- package/dist/browser/phpsandbox-sdk.esm.js +58 -9
- package/dist/browser/phpsandbox-sdk.esm.js.map +2 -2
- package/dist/browser/phpsandbox-sdk.esm.min.js +2 -2
- package/dist/browser/phpsandbox-sdk.esm.min.js.map +3 -3
- package/dist/browser/phpsandbox-sdk.iife.js +58 -9
- package/dist/browser/phpsandbox-sdk.iife.js.map +2 -2
- package/dist/browser/phpsandbox-sdk.iife.min.js +2 -2
- package/dist/browser/phpsandbox-sdk.iife.min.js.map +3 -3
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/services.d.ts +14 -7
- package/dist/services.d.ts.map +1 -1
- package/dist/services.js +7 -2
- package/dist/services.js.map +1 -1
- package/dist/socket/index.d.ts +1 -0
- package/dist/socket/index.d.ts.map +1 -1
- package/dist/socket/index.js +31 -3
- package/dist/socket/index.js.map +1 -1
- package/dist/terminal.d.ts.map +1 -1
- package/dist/terminal.js +16 -3
- package/dist/terminal.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -79,12 +79,20 @@ await fetched.ready();
|
|
|
79
79
|
|
|
80
80
|
const forked = await created.fork();
|
|
81
81
|
await forked.delete();
|
|
82
|
+
|
|
83
|
+
const persistent = await client.notebook.create('laravel', {
|
|
84
|
+
title: 'Persistent Laravel',
|
|
85
|
+
persistent: true,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
console.log(persistent.data.policy);
|
|
82
89
|
```
|
|
83
90
|
|
|
84
91
|
Notes:
|
|
85
92
|
|
|
86
93
|
- `create()` and `fork()` initialize automatically.
|
|
87
94
|
- `open()` and `get()` return a notebook instance; call `await notebook.ready()` before using tools.
|
|
95
|
+
- API notebook creates are ephemeral by default. `persistent: true` requires an entitled account.
|
|
88
96
|
|
|
89
97
|
## Services At A Glance
|
|
90
98
|
|
|
@@ -103,6 +111,12 @@ Each `NotebookInstance` exposes service clients:
|
|
|
103
111
|
- `notebook.log` (`Log`)
|
|
104
112
|
- `notebook.services` (`Services`)
|
|
105
113
|
|
|
114
|
+
Notes:
|
|
115
|
+
|
|
116
|
+
- `terminal.spawn()` and `shell.exec()` are part of the current okra websocket action set. `terminal.start` currently is not.
|
|
117
|
+
- `notebook.repl.eval()` is part of the current okra websocket action set. `repl.start` is currently not.
|
|
118
|
+
- `notebook.laravel` is exposed by the SDK, but the current okra websocket action set does not expose Laravel maintenance actions.
|
|
119
|
+
|
|
106
120
|
## Common Operations
|
|
107
121
|
|
|
108
122
|
### Files
|
|
@@ -148,9 +162,14 @@ console.log(result.output);
|
|
|
148
162
|
### Services
|
|
149
163
|
|
|
150
164
|
```ts
|
|
165
|
+
import { notebookBuiltinServices } from '@phpsandbox/sdk';
|
|
166
|
+
|
|
151
167
|
const services = await notebook.services.list();
|
|
152
168
|
|
|
169
|
+
console.log(notebookBuiltinServices); // ['redis']
|
|
170
|
+
|
|
153
171
|
await notebook.services.run('redis');
|
|
172
|
+
await notebook.services.run('queue', 'php artisan queue:work');
|
|
154
173
|
|
|
155
174
|
const snapshot = await notebook.services.logs('redis', { tail: 50 });
|
|
156
175
|
console.log(snapshot);
|
|
@@ -639,19 +639,30 @@ var Terminal = class {
|
|
|
639
639
|
},
|
|
640
640
|
close: dispose
|
|
641
641
|
});
|
|
642
|
+
let controller = null;
|
|
642
643
|
const output = new ReadableStream({
|
|
643
|
-
start: (
|
|
644
|
+
start: (_controller) => {
|
|
645
|
+
controller = _controller;
|
|
644
646
|
disposables.add(
|
|
645
647
|
this.listen(`terminal.output.${id}`, (data) => {
|
|
646
|
-
controller
|
|
648
|
+
controller?.enqueue(data.output);
|
|
647
649
|
})
|
|
648
650
|
);
|
|
649
651
|
},
|
|
650
|
-
cancel:
|
|
652
|
+
cancel: () => {
|
|
653
|
+
controller = null;
|
|
654
|
+
dispose();
|
|
655
|
+
}
|
|
651
656
|
});
|
|
652
657
|
const exit = new Promise((resolve) => {
|
|
653
658
|
disposables.add(
|
|
654
659
|
this.listen(`terminal.close.${id}`, (data) => {
|
|
660
|
+
if (controller) {
|
|
661
|
+
try {
|
|
662
|
+
controller.close();
|
|
663
|
+
} catch {
|
|
664
|
+
}
|
|
665
|
+
}
|
|
655
666
|
dispose();
|
|
656
667
|
resolve(data.exitCode);
|
|
657
668
|
})
|
|
@@ -1027,6 +1038,8 @@ var Shell = class {
|
|
|
1027
1038
|
};
|
|
1028
1039
|
|
|
1029
1040
|
// src/services.ts
|
|
1041
|
+
var notebookBuiltinServices = ["redis"];
|
|
1042
|
+
var notebookKnownServices = ["start", "nginx", ...notebookBuiltinServices];
|
|
1030
1043
|
var Services = class {
|
|
1031
1044
|
constructor(okra) {
|
|
1032
1045
|
this.okra = okra;
|
|
@@ -1034,8 +1047,11 @@ var Services = class {
|
|
|
1034
1047
|
list() {
|
|
1035
1048
|
return this.okra.invoke("service.list");
|
|
1036
1049
|
}
|
|
1037
|
-
run(name) {
|
|
1038
|
-
return this.okra.invoke("service.run", {
|
|
1050
|
+
run(name, command) {
|
|
1051
|
+
return this.okra.invoke("service.run", {
|
|
1052
|
+
name,
|
|
1053
|
+
command
|
|
1054
|
+
});
|
|
1039
1055
|
}
|
|
1040
1056
|
stop(name) {
|
|
1041
1057
|
return this.okra.invoke("service.stop", { name });
|
|
@@ -3177,7 +3193,7 @@ var Transport = class {
|
|
|
3177
3193
|
this.connectionStats.connectionStartTime = Date.now();
|
|
3178
3194
|
const startClosed = options.startClosed !== false;
|
|
3179
3195
|
this.rws = new reconnecting_websocket_mjs_default(this.url.toString(), [], {
|
|
3180
|
-
WebSocket: globalThis.WebSocket ?? browser_default,
|
|
3196
|
+
WebSocket: options.webSocket ?? globalThis.WebSocket ?? browser_default,
|
|
3181
3197
|
connectionTimeout: options.connectionTimeout,
|
|
3182
3198
|
maxReconnectionDelay: 2e3,
|
|
3183
3199
|
minReconnectionDelay: 200,
|
|
@@ -3232,7 +3248,19 @@ var Transport = class {
|
|
|
3232
3248
|
async registerWatchers() {
|
|
3233
3249
|
const onMessage = (ev) => {
|
|
3234
3250
|
if (!(ev.data instanceof Blob)) {
|
|
3235
|
-
|
|
3251
|
+
const error = new Error("Unexpected message type: " + typeof ev.data);
|
|
3252
|
+
this.connectionStats.totalErrors++;
|
|
3253
|
+
this.log("error", "Unexpected WebSocket message type", {
|
|
3254
|
+
error: error.message,
|
|
3255
|
+
messageType: typeof ev.data
|
|
3256
|
+
});
|
|
3257
|
+
this.eventEmitter.emit("transport.error", {
|
|
3258
|
+
type: "message_type_error",
|
|
3259
|
+
error,
|
|
3260
|
+
rawMessage: ev.data,
|
|
3261
|
+
timestamp: Date.now()
|
|
3262
|
+
});
|
|
3263
|
+
return;
|
|
3236
3264
|
}
|
|
3237
3265
|
ev.data.arrayBuffer().then((buffer) => {
|
|
3238
3266
|
if (buffer.byteLength === 0) {
|
|
@@ -3240,7 +3268,19 @@ var Transport = class {
|
|
|
3240
3268
|
return;
|
|
3241
3269
|
}
|
|
3242
3270
|
try {
|
|
3243
|
-
this.handleRawMessage(decode(buffer))
|
|
3271
|
+
void this.handleRawMessage(decode(buffer)).catch((error) => {
|
|
3272
|
+
this.connectionStats.totalErrors++;
|
|
3273
|
+
this.log("error", "Failed to process WebSocket frame", {
|
|
3274
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3275
|
+
byteLength: buffer.byteLength
|
|
3276
|
+
});
|
|
3277
|
+
this.eventEmitter.emit("transport.error", {
|
|
3278
|
+
type: "message_handle_error",
|
|
3279
|
+
error,
|
|
3280
|
+
rawMessage: buffer,
|
|
3281
|
+
timestamp: Date.now()
|
|
3282
|
+
});
|
|
3283
|
+
});
|
|
3244
3284
|
} catch (error) {
|
|
3245
3285
|
this.connectionStats.totalErrors++;
|
|
3246
3286
|
this.log("error", "Failed to decode WebSocket frame", {
|
|
@@ -3264,6 +3304,10 @@ var Transport = class {
|
|
|
3264
3304
|
});
|
|
3265
3305
|
}
|
|
3266
3306
|
async handleRawMessage(ev) {
|
|
3307
|
+
if (this.closed) {
|
|
3308
|
+
this.log("debug", "Ignoring message received after transport was closed");
|
|
3309
|
+
return;
|
|
3310
|
+
}
|
|
3267
3311
|
if (typeof ev !== "object" || ev === null) {
|
|
3268
3312
|
this.log("debug", "Received invalid message format", { ev });
|
|
3269
3313
|
return;
|
|
@@ -4925,7 +4969,8 @@ var NotebookInstance = class {
|
|
|
4925
4969
|
this.emitter = EventManager.createInstance();
|
|
4926
4970
|
this.socket = new Transport(data.okraUrl, this.emitter, {
|
|
4927
4971
|
debug: client.options.debug,
|
|
4928
|
-
startClosed: client.options.startClosed
|
|
4972
|
+
startClosed: client.options.startClosed,
|
|
4973
|
+
webSocket: client.options.webSocket
|
|
4929
4974
|
});
|
|
4930
4975
|
this.watchConnection();
|
|
4931
4976
|
__privateSet(this, _initPromise, __privateMethod(this, _NotebookInstance_instances, init_fn).call(this));
|
|
@@ -5093,6 +5138,8 @@ init_fn = function() {
|
|
|
5093
5138
|
reject(error);
|
|
5094
5139
|
});
|
|
5095
5140
|
}));
|
|
5141
|
+
void __privateGet(this, _initPromise).catch(() => {
|
|
5142
|
+
});
|
|
5096
5143
|
return __privateGet(this, _initPromise);
|
|
5097
5144
|
};
|
|
5098
5145
|
var NotebookSecrets = class {
|
|
@@ -5144,6 +5191,8 @@ export {
|
|
|
5144
5191
|
Transport,
|
|
5145
5192
|
createBeacon,
|
|
5146
5193
|
isBeaconSupported,
|
|
5194
|
+
notebookBuiltinServices,
|
|
5195
|
+
notebookKnownServices,
|
|
5147
5196
|
once,
|
|
5148
5197
|
timeout
|
|
5149
5198
|
};
|