@phpsandbox/sdk 0.1.1 → 0.1.4

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 CHANGED
@@ -23,9 +23,9 @@ const client = PHPSandbox.realtime(token);
23
23
  // create() initializes the notebook by default
24
24
  const notebook = await client.notebook.create('php');
25
25
 
26
- await notebook.file.write('index.php', '<?php echo "Hello from PHPSandbox";');
26
+ await notebook.files.write('index.php', '<?php echo "Hello from PHPSandbox";');
27
27
 
28
- const process = await notebook.terminal.spawn('php', ['index.php']);
28
+ const process = await notebook.terminals.create({ command: 'php', args: ['index.php'] });
29
29
 
30
30
  const reader = process.output.getReader();
31
31
  let output = '';
@@ -39,7 +39,7 @@ try {
39
39
  reader.releaseLock();
40
40
  }
41
41
 
42
- await process.exit;
42
+ await process.wait();
43
43
  console.log(output.trim());
44
44
 
45
45
  // close websocket resources when done
@@ -106,22 +106,23 @@ Notes:
106
106
 
107
107
  Each `NotebookInstance` exposes service clients:
108
108
 
109
- - `notebook.file` (`Filesystem`)
110
- - `notebook.terminal` (`Terminal`)
109
+ - `notebook.files` (`Filesystem`)
110
+ - `notebook.terminals` (`Terminals`)
111
111
  - `notebook.container` (`Container`)
112
- - `notebook.shell` (`Shell`)
113
112
  - `notebook.composer` (`Composer`)
114
113
  - `notebook.git` (`Git`)
115
114
  - `notebook.lsp` (`Lsp`)
116
115
  - `notebook.repl` (`Repl`)
117
116
  - `notebook.auth` (`Auth`)
118
- - `notebook.log` (`Log`)
117
+ - `notebook.logs` (`Logs`)
118
+ - `notebook.ports` (`Ports`)
119
+ - `notebook.metrics` (`Metrics`)
119
120
  - `notebook.services` (`Services`)
120
121
  - `notebook.mail` (`NotebookMail`)
121
122
 
122
123
  Notes:
123
124
 
124
- - `terminal.spawn()` is the TTY-oriented process API; `notebook.run()` is the native non-TTY process API.
125
+ - `terminals.create()` is the TTY-oriented process API; `notebook.exec()` and `notebook.run()` are the native non-TTY process APIs.
125
126
  - `notebook.repl.eval()` evaluates PHP without exposing the unsupported `repl.start` action.
126
127
 
127
128
  ## Common Operations
@@ -129,17 +130,26 @@ Notes:
129
130
  ### Files
130
131
 
131
132
  ```ts
132
- await notebook.file.write('README.md', '# App');
133
+ await notebook.files.write('README.md', '# App');
133
134
 
134
- const raw = await notebook.file.readFile('README.md');
135
- const text = new TextDecoder().decode(raw);
135
+ await notebook.files.write('archive.zip', byteStream);
136
+ for await (const chunk of notebook.files.readStream('archive.zip')) {
137
+ consume(chunk);
138
+ }
139
+
140
+ const raw = await notebook.files.read('README.md');
141
+ const text = await notebook.files.readText('README.md');
142
+ const excerpt = await notebook.files.readLines('storage/logs/laravel.log', {
143
+ start: 100,
144
+ end: 200,
145
+ });
136
146
 
137
- const files = await notebook.file.find('*.php', {
147
+ const files = await notebook.files.find('*.php', {
138
148
  includes: ['app/**'],
139
149
  excludes: ['vendor/**'],
140
150
  });
141
151
 
142
- const [hasMore, matches] = await notebook.file.search(
152
+ const [hasMore, matches] = await notebook.files.search(
143
153
  { pattern: 'class\\s+User', isRegExp: true },
144
154
  { maxResults: 20, includes: ['app/**'], excludes: ['vendor/**'] }
145
155
  );
@@ -148,24 +158,27 @@ const [hasMore, matches] = await notebook.file.search(
148
158
  ### Terminal
149
159
 
150
160
  ```ts
151
- const task = await notebook.terminal.spawn('composer', ['--version']);
161
+ const task = await notebook.terminals.create({ command: 'composer', args: ['--version'] });
152
162
 
153
163
  task.output.getReader().read().then(({ value }) => {
154
164
  console.log(value);
155
165
  });
156
166
 
157
- const exitCode = await task.exit;
167
+ const exitCode = await task.wait();
158
168
  console.log(exitCode);
159
169
  ```
160
170
 
161
171
  ### Shell
162
172
 
163
173
  ```ts
174
+ const result = await notebook.exec('php -v');
175
+ result.throw();
176
+
164
177
  const process = notebook.run('php -v', { tty: false });
165
178
  for await (const chunk of process.output) {
166
179
  console.log(chunk.source, new TextDecoder().decode(chunk.data));
167
180
  }
168
- (await process.exit).throw();
181
+ (await process.wait()).throw();
169
182
  ```
170
183
 
171
184
  ### Services
@@ -184,17 +197,41 @@ const snapshot = await notebook.services.logs('redis', { tail: 50 });
184
197
  console.log(snapshot);
185
198
 
186
199
  const stream = notebook.services.logs('redis', { follow: true, tail: 25 });
187
- const reader = stream.output.getReader();
200
+ const reader = stream.getReader();
188
201
  const chunk = await reader.read();
189
202
  console.log(chunk.value);
190
- await stream.stop();
203
+ await reader.cancel();
204
+ ```
205
+
206
+ ### Runtime observability
207
+
208
+ ```ts
209
+ const currentPorts = await notebook.ports.list();
210
+ const currentMetrics = await notebook.metrics.current();
211
+
212
+ for await (const sample of notebook.metrics.watch({ signal })) {
213
+ console.log(sample.cpu, sample.memory, sample.disk);
214
+ }
215
+
216
+ for await (const ports of notebook.ports.watch({ signal })) {
217
+ console.log(ports);
218
+ }
219
+
220
+ for await (const entry of notebook.logs.follow({ signal })) {
221
+ console.log(entry.timestamp, entry.source, entry.message);
222
+ }
191
223
  ```
192
224
 
193
225
  ### Composer
194
226
 
195
227
  ```ts
196
- await notebook.composer.install({ noInteraction: true });
197
- await notebook.composer.require({ packages: ['monolog/monolog'] });
228
+ const install = notebook.composer.install();
229
+ for await (const chunk of install.output) {
230
+ console.log(chunk.source, new TextDecoder().decode(chunk.data));
231
+ }
232
+ (await install.wait()).throw();
233
+
234
+ (await notebook.composer.require({ packages: ['monolog/monolog'] }).wait()).throw();
198
235
 
199
236
  const installed = await notebook.composer.packages();
200
237
  console.log(installed.map((pkg) => pkg.name));
@@ -276,7 +313,7 @@ const disposeConnect = notebook.onDidConnect(() => {
276
313
  console.log('connected');
277
314
  });
278
315
 
279
- const disposeFs = notebook.file.watch(
316
+ const disposeFs = notebook.files.watch(
280
317
  '/app',
281
318
  { recursive: true, excludes: ['vendor/**', 'node_modules/**'] },
282
319
  (change) => {
@@ -295,7 +332,7 @@ disposeFs.dispose();
295
332
  import { ApiError, FilesystemError, FilesystemErrorType } from '@phpsandbox/sdk';
296
333
 
297
334
  try {
298
- await notebook.file.readFile('/does-not-exist.php');
335
+ await notebook.files.read('/does-not-exist.php');
299
336
  } catch (error) {
300
337
  if (error instanceof FilesystemError && error.name === FilesystemErrorType.FileNotFound) {
301
338
  console.error('Missing file');