@phpsandbox/sdk 0.3.2 → 0.3.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.
Files changed (43) hide show
  1. package/README.md +38 -0
  2. package/dist/beacon/index.js +4 -2
  3. package/dist/beacon/navigator.js +0 -1
  4. package/dist/beacon/types.d.ts +1 -1
  5. package/dist/browser/phpsandbox-sdk.esm.js +405 -308
  6. package/dist/browser/phpsandbox-sdk.esm.min.js +23 -25
  7. package/dist/browser/phpsandbox-sdk.iife.js +405 -308
  8. package/dist/browser/phpsandbox-sdk.iife.min.js +8 -10
  9. package/dist/composer.js +8 -4
  10. package/dist/errors/index.d.ts +1 -1
  11. package/dist/errors/index.js +1 -3
  12. package/dist/feedback.js +2 -1
  13. package/dist/filesystem.js +32 -15
  14. package/dist/identity.d.ts +13 -0
  15. package/dist/identity.js +6 -0
  16. package/dist/index.d.ts +5 -4
  17. package/dist/index.js +14 -5
  18. package/dist/integrations/sandbox.js +1 -1
  19. package/dist/lsp.d.ts +2 -2
  20. package/dist/lsp.js +2 -2
  21. package/dist/publication/index.d.ts +1 -0
  22. package/dist/publication/index.js +1 -0
  23. package/dist/publication/instance.d.ts +2 -0
  24. package/dist/publication/instance.js +8 -0
  25. package/dist/publication/notebook.js +7 -5
  26. package/dist/publication/resources.js +2 -1
  27. package/dist/publication/run.js +2 -76
  28. package/dist/publication/stream.d.ts +18 -0
  29. package/dist/publication/stream.js +185 -0
  30. package/dist/runtime/rest.js +2 -1
  31. package/dist/runtime.js +1 -1
  32. package/dist/schemas/publications.js +53 -59
  33. package/dist/servers.d.ts +2 -0
  34. package/dist/servers.js +5 -1
  35. package/dist/shell.js +5 -2
  36. package/dist/socket/index.js +25 -13
  37. package/dist/telemetry.js +8 -3
  38. package/dist/terminal.js +3 -4
  39. package/dist/utils/promise.js +1 -1
  40. package/dist/utils/websocket.js +2 -2
  41. package/package.json +49 -33
  42. package/dist/auth.d.ts +0 -11
  43. package/dist/auth.js +0 -12
@@ -0,0 +1,185 @@
1
+ import { PublishStreamSseEventNameSchema, PublishStreamSseEventSchema } from '../schemas/publications.js';
2
+ import { PHPSandboxError } from '../errors/index.js';
3
+ /** Consume publishing SSE in browsers or servers, including through an authenticated proxy.
4
+ * Cancels the source when iteration ends early or parsing fails. Fetch cancellation belongs
5
+ * to the caller's AbortSignal. Unknown event names and heartbeat comments are ignored.
6
+ * A complete stream must include a result; set requireResult to false only for fragments.
7
+ */
8
+ export async function* readPublicationStream(input, options = {}) {
9
+ if (input instanceof Response && (!input.ok || !input.body)) {
10
+ await input.body?.cancel().catch(() => undefined);
11
+ throw new PHPSandboxError(`Publishing stream is unavailable (HTTP ${input.status}).`);
12
+ }
13
+ const stream = input instanceof Response ? input.body : input;
14
+ const reader = stream.getReader();
15
+ const decoder = new TextDecoder();
16
+ let buffer = '';
17
+ let eventName = 'message';
18
+ let data = [];
19
+ let ended = false;
20
+ let receivedResult = false;
21
+ function dispatch() {
22
+ const name = eventName;
23
+ const lines = data;
24
+ eventName = 'message';
25
+ data = [];
26
+ if (!lines.length || !PublishStreamSseEventNameSchema.safeParse(name).success) {
27
+ return null;
28
+ }
29
+ const raw = lines.join('\n');
30
+ let payload;
31
+ try {
32
+ payload = JSON.parse(raw);
33
+ }
34
+ catch {
35
+ payload = raw;
36
+ }
37
+ const event = PublishStreamSseEventSchema.parse({ event: name, data: payload });
38
+ if (event.type === 'result') {
39
+ receivedResult = true;
40
+ }
41
+ return event;
42
+ }
43
+ function line(value) {
44
+ if (value === '') {
45
+ return dispatch();
46
+ }
47
+ if (value.startsWith(':')) {
48
+ return null;
49
+ }
50
+ const colon = value.indexOf(':');
51
+ const field = colon < 0 ? value : value.slice(0, colon);
52
+ let content = colon < 0 ? '' : value.slice(colon + 1);
53
+ if (content.startsWith(' ')) {
54
+ content = content.slice(1);
55
+ }
56
+ if (field === 'event') {
57
+ eventName = content;
58
+ }
59
+ if (field === 'data') {
60
+ data.push(content);
61
+ }
62
+ return null;
63
+ }
64
+ try {
65
+ while (true) {
66
+ const { done, value } = await reader.read();
67
+ buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });
68
+ // A CR at the end of a chunk may be the first half of CRLF.
69
+ let match;
70
+ while ((match = /\r\n|\r|\n/.exec(buffer))) {
71
+ if (!done && match[0] === '\r' && match.index === buffer.length - 1) {
72
+ break;
73
+ }
74
+ const event = line(buffer.slice(0, match.index));
75
+ buffer = buffer.slice(match.index + match[0].length);
76
+ if (event) {
77
+ yield event;
78
+ }
79
+ }
80
+ if (done) {
81
+ ended = true;
82
+ if (buffer) {
83
+ const event = line(buffer);
84
+ if (event) {
85
+ yield event;
86
+ }
87
+ }
88
+ // Preserve the SDK's support for a final event without a trailing blank line.
89
+ const event = dispatch();
90
+ if (event) {
91
+ yield event;
92
+ }
93
+ if (options.requireResult !== false && !receivedResult) {
94
+ throw new PHPSandboxError('Publish stream ended without result');
95
+ }
96
+ return;
97
+ }
98
+ }
99
+ }
100
+ finally {
101
+ if (!ended) {
102
+ await reader.cancel().catch(() => undefined);
103
+ }
104
+ reader.releaseLock();
105
+ }
106
+ }
107
+ /** Forward the original bytes with SSE headers and exactly-once resource cleanup.
108
+ * Works with Fetch-based servers and frameworks that accept a standard Response.
109
+ * Does not parse, buffer a replay, or re-encode events. Upstream errors fail the body.
110
+ */
111
+ export function createPublicationStreamResponse(stream, options = {}) {
112
+ const reader = stream.getReader();
113
+ let disposed = false;
114
+ let finished = false;
115
+ let cancellation;
116
+ let abort;
117
+ async function dispose() {
118
+ if (disposed) {
119
+ return;
120
+ }
121
+ disposed = true;
122
+ options.signal?.removeEventListener('abort', abort);
123
+ reader.releaseLock();
124
+ await options.onDispose?.();
125
+ }
126
+ function cancel(reason) {
127
+ return (cancellation ?? (cancellation = (async () => {
128
+ finished = true;
129
+ try {
130
+ await reader.cancel(reason);
131
+ }
132
+ finally {
133
+ await dispose();
134
+ }
135
+ })()));
136
+ }
137
+ return new Response(new ReadableStream({
138
+ start(controller) {
139
+ abort = () => {
140
+ controller.error(options.signal.reason);
141
+ void cancel(options.signal.reason).catch(() => undefined);
142
+ };
143
+ if (options.signal?.aborted) {
144
+ abort();
145
+ }
146
+ else {
147
+ options.signal?.addEventListener('abort', abort, { once: true });
148
+ }
149
+ },
150
+ async pull(controller) {
151
+ try {
152
+ const { done, value } = await reader.read();
153
+ if (finished) {
154
+ return;
155
+ }
156
+ if (done) {
157
+ finished = true;
158
+ await dispose();
159
+ controller.close();
160
+ }
161
+ else {
162
+ controller.enqueue(value);
163
+ }
164
+ }
165
+ catch (error) {
166
+ if (finished && cancellation) {
167
+ return;
168
+ }
169
+ try {
170
+ await cancel(error);
171
+ }
172
+ finally {
173
+ controller.error(error);
174
+ }
175
+ }
176
+ },
177
+ cancel,
178
+ }, { highWaterMark: 0 }), {
179
+ headers: {
180
+ 'Content-Type': 'text/event-stream',
181
+ 'Cache-Control': 'no-cache, no-transform',
182
+ 'X-Accel-Buffering': 'no',
183
+ },
184
+ });
185
+ }
@@ -194,7 +194,8 @@ function runtimeActionRequestBody(action, data, url, headers) {
194
194
  throw new TypeError('Runtime file contents must be binary data.');
195
195
  }
196
196
  headers['Content-Type'] = 'application/octet-stream';
197
- return Uint8Array.from(new Uint8Array(payload.contents.buffer, payload.contents.byteOffset, payload.contents.byteLength)).buffer;
197
+ return Uint8Array.from(new Uint8Array(payload.contents.buffer, payload.contents.byteOffset, payload.contents.byteLength))
198
+ .buffer;
198
199
  }
199
200
  headers['Content-Type'] = 'application/json';
200
201
  return JSON.stringify(data);
package/dist/runtime.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import Logs from './log.js';
2
2
  import Metrics from './metrics.js';
3
3
  import Ports from './ports.js';
4
- import { RuntimeTelemetry, } from './telemetry.js';
4
+ import { RuntimeTelemetry } from './telemetry.js';
5
5
  export class RuntimeMetrics {
6
6
  constructor(metrics) {
7
7
  this.metrics = metrics;
@@ -1,9 +1,5 @@
1
1
  import { z } from 'zod';
2
- export const PublicationProviderNameSchema = z.enum([
3
- 'cloudflare-containers',
4
- 'ssh-server',
5
- 'laravel-cloud',
6
- ]);
2
+ export const PublicationProviderNameSchema = z.enum(['cloudflare-containers', 'ssh-server', 'laravel-cloud']);
7
3
  export const PublicationStatusSchema = z.enum([
8
4
  'pending',
9
5
  'queued',
@@ -16,71 +12,55 @@ export const PublicationStatusSchema = z.enum([
16
12
  'deleted',
17
13
  'delete_failed',
18
14
  ]);
19
- export const PublicationBuildStatusSchema = z.enum([
20
- 'pending',
21
- 'queued',
22
- 'running',
23
- 'succeeded',
24
- 'failed',
25
- 'cancelled',
26
- ]);
15
+ export const PublicationBuildStatusSchema = z.enum(['pending', 'queued', 'running', 'succeeded', 'failed', 'cancelled']);
27
16
  export const PublicationReleaseStatusSchema = z.enum(['created', 'ready', 'deleted']);
28
- export const PublicationSizeSchema = z.enum([
29
- 'nano',
30
- 'small',
31
- 'medium',
32
- 'large',
33
- 'lite',
34
- 'basic',
35
- 'standard-1',
36
- 'standard-2',
37
- ]);
38
- export const PublicationRegionSchema = z.enum([
39
- 'ENAM',
40
- 'WNAM',
41
- 'EEUR',
42
- 'WEUR',
43
- 'APAC',
44
- 'SAM',
45
- 'ME',
46
- 'OC',
47
- 'AFR',
48
- ]);
17
+ export const PublicationSizeSchema = z.enum(['nano', 'small', 'medium', 'large', 'lite', 'basic', 'standard-1', 'standard-2']);
18
+ export const PublicationRegionSchema = z.enum(['ENAM', 'WNAM', 'EEUR', 'WEUR', 'APAC', 'SAM', 'ME', 'OC', 'AFR']);
49
19
  export const PublicationJurisdictionSchema = z.enum(['eu', 'fedramp']);
50
20
  export const PublicationProtectionModeSchema = z.enum(['none', 'password']);
51
21
  export const PublicationLogStreamSchema = z.enum(['build', 'runtime']);
52
22
  export const PublishStreamLogStreamSchema = z.enum(['build', 'publish', 'runtime']);
53
- const PublicationEventPayloadSchema = z.preprocess((payload) => Array.isArray(payload) && payload.length === 0 ? {} : payload, z.record(z.string(), z.unknown()));
54
- export const PublicationEventDataSchema = z.object({
23
+ const PublicationEventPayloadSchema = z.preprocess((payload) => (Array.isArray(payload) && payload.length === 0 ? {} : payload), z.record(z.string(), z.unknown()));
24
+ export const PublicationEventDataSchema = z
25
+ .object({
55
26
  id: z.union([z.number(), z.string()]).optional(),
56
27
  sequence: z.number(),
57
28
  type: z.string(),
58
29
  payload: PublicationEventPayloadSchema,
59
30
  createdAt: z.string().nullable(),
60
- }).passthrough();
61
- export const PublicationLogChunkDataSchema = z.object({
31
+ })
32
+ .passthrough();
33
+ export const PublicationLogChunkDataSchema = z
34
+ .object({
62
35
  sequence: z.number(),
63
36
  stream: PublicationLogStreamSchema,
64
37
  content: z.string(),
65
38
  createdAt: z.string().nullable(),
66
- }).passthrough();
67
- export const PublishStreamPhaseSchema = z.object({
39
+ })
40
+ .passthrough();
41
+ export const PublishStreamPhaseSchema = z
42
+ .object({
68
43
  name: z.string(),
69
44
  status: z.enum(['running', 'completed', 'failed']).optional(),
70
45
  data: z.record(z.string(), z.unknown()).optional(),
71
- }).strict();
72
- export const PublishStreamLogSchema = z.object({
46
+ })
47
+ .strict();
48
+ export const PublishStreamLogSchema = z
49
+ .object({
73
50
  stream: PublishStreamLogStreamSchema,
74
51
  content: z.string(),
75
- }).strict();
76
- export const PublishStreamResultSchema = z.object({
52
+ })
53
+ .strict();
54
+ export const PublishStreamResultSchema = z
55
+ .object({
77
56
  success: z.boolean(),
78
57
  publicationId: z.string(),
79
58
  url: z.string().url(),
80
59
  buildId: z.string(),
81
60
  releaseId: z.string(),
82
61
  status: PublicationStatusSchema,
83
- }).strict();
62
+ })
63
+ .strict();
84
64
  export const PublishStreamPhaseEventSchema = PublishStreamPhaseSchema.extend({
85
65
  type: z.literal('phase'),
86
66
  }).strict();
@@ -95,37 +75,51 @@ export const PublishStreamEventSchema = z.discriminatedUnion('type', [
95
75
  PublishStreamLogEventSchema,
96
76
  PublishStreamResultEventSchema,
97
77
  ]);
98
- export const PublishStreamErrorSchema = z.object({
78
+ export const PublishStreamErrorSchema = z
79
+ .object({
99
80
  message: z.string().optional(),
100
- }).passthrough();
81
+ })
82
+ .passthrough();
101
83
  export const PublishStreamSseEventNameSchema = z.enum(['phase', 'log', 'done', 'result', 'error']);
102
- export const PublishStreamSsePhaseEventSchema = z.object({
84
+ export const PublishStreamSsePhaseEventSchema = z
85
+ .object({
103
86
  event: z.literal('phase'),
104
87
  data: PublishStreamPhaseSchema,
105
- }).strict();
106
- export const PublishStreamSseLogEventSchema = z.object({
88
+ })
89
+ .strict();
90
+ export const PublishStreamSseLogEventSchema = z
91
+ .object({
107
92
  event: z.literal('log'),
108
93
  data: PublishStreamLogSchema,
109
- }).strict();
110
- export const PublishStreamSseDoneEventSchema = z.object({
94
+ })
95
+ .strict();
96
+ export const PublishStreamSseDoneEventSchema = z
97
+ .object({
111
98
  event: z.literal('done'),
112
99
  data: PublishStreamResultSchema,
113
- }).strict();
114
- export const PublishStreamSseResultEventSchema = z.object({
100
+ })
101
+ .strict();
102
+ export const PublishStreamSseResultEventSchema = z
103
+ .object({
115
104
  event: z.literal('result'),
116
105
  data: PublishStreamResultSchema,
117
- }).strict();
118
- export const PublishStreamSseErrorEventSchema = z.object({
106
+ })
107
+ .strict();
108
+ export const PublishStreamSseErrorEventSchema = z
109
+ .object({
119
110
  event: z.literal('error'),
120
111
  data: PublishStreamErrorSchema,
121
- }).strict();
122
- export const PublishStreamSseEventSchema = z.discriminatedUnion('event', [
112
+ })
113
+ .strict();
114
+ export const PublishStreamSseEventSchema = z
115
+ .discriminatedUnion('event', [
123
116
  PublishStreamSsePhaseEventSchema,
124
117
  PublishStreamSseLogEventSchema,
125
118
  PublishStreamSseDoneEventSchema,
126
119
  PublishStreamSseResultEventSchema,
127
120
  PublishStreamSseErrorEventSchema,
128
- ]).transform((event) => {
121
+ ])
122
+ .transform((event) => {
129
123
  if (event.event === 'error') {
130
124
  throw new Error(event.data.message ?? 'Publish failed');
131
125
  }
package/dist/servers.d.ts CHANGED
@@ -14,6 +14,7 @@ export interface ServerData {
14
14
  updatedAt: string | null;
15
15
  }
16
16
  export interface ServerMemberData {
17
+ organizationId?: string | null;
17
18
  id: number;
18
19
  name: string;
19
20
  email: string;
@@ -47,6 +48,7 @@ export declare class ServerInstance {
47
48
  }>;
48
49
  members(options?: ServerListOptions): Promise<PaginatedApiResponse<ServerMemberData>>;
49
50
  share(email: string): Promise<ServerMemberData>;
51
+ shareWithOrganization(organizationId: string): Promise<ServerMemberData>;
50
52
  revokeAccess(memberId: number): Promise<void>;
51
53
  refresh(): Promise<ServerInstance>;
52
54
  delete(): Promise<void>;
package/dist/servers.js CHANGED
@@ -30,6 +30,10 @@ export class ServerInstance {
30
30
  async share(email) {
31
31
  return (await this.client.post(`/servers/${encodeURIComponent(this.data.id)}/members`, { email })).data;
32
32
  }
33
+ async shareWithOrganization(organizationId) {
34
+ return (await this.client.post(`/servers/${encodeURIComponent(this.data.id)}/members`, { organizationId }))
35
+ .data;
36
+ }
33
37
  async revokeAccess(memberId) {
34
38
  await this.client.delete(`/servers/${encodeURIComponent(this.data.id)}/members/${encodeURIComponent(String(memberId))}`);
35
39
  }
@@ -51,7 +55,7 @@ export class ServerInstance {
51
55
  if (server.data.status === 'failed') {
52
56
  throw new Error(`Server provisioning failed: ${server.data.id}`);
53
57
  }
54
- await new Promise(resolve => setTimeout(resolve, interval));
58
+ await new Promise((resolve) => setTimeout(resolve, interval));
55
59
  }
56
60
  throw new Error(`Server did not become ready within ${timeout}ms`);
57
61
  }
package/dist/shell.js CHANGED
@@ -89,10 +89,13 @@ export class ShellProcess {
89
89
  stderr.fail(error);
90
90
  };
91
91
  const { abortSignal, ...payloadOpts } = opts;
92
- this.completion = this.okra.invoke('shell.exec', { command, opts: { ...payloadOpts, id: this.id } }, { abortSignal }).then((result) => {
92
+ this.completion = this.okra
93
+ .invoke('shell.exec', { command, opts: { ...payloadOpts, id: this.id } }, { abortSignal })
94
+ .then((result) => {
93
95
  finish();
94
96
  return result;
95
- }).catch((error) => {
97
+ })
98
+ .catch((error) => {
96
99
  fail(error);
97
100
  throw error;
98
101
  });
@@ -6,7 +6,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
6
6
  var _Transport_instances, _Transport_connect, _Transport_startPeriodicPing;
7
7
  import { nanoid } from 'nanoid';
8
8
  import { encode, decode } from '@msgpack/msgpack';
9
- import { PromiseTimeoutError, RemoteError, SendTimeoutError, TransportError, remoteError, } from '../errors/index.js';
9
+ import { PromiseTimeoutError, RemoteError, SendTimeoutError, TransportError, remoteError } from '../errors/index.js';
10
10
  import { retry } from '../utils/retry.js';
11
11
  import * as ReconnectingWebSocketModule from 'reconnecting-websocket';
12
12
  import { timeout } from '../utils/promise.js';
@@ -14,11 +14,21 @@ import { describeWebSocketEvent } from '../utils/websocket.js';
14
14
  import WebSocket from 'isomorphic-ws';
15
15
  import { NamedDisposable } from '../utils/disposable.js';
16
16
  const SAFE_DEBUG_METADATA_KEYS = new Set([
17
- 'url', 'action', 'event', 'responseEvent', 'errorEvent', 'hasData',
18
- 'code', 'attempt', 'maxRetries', 'timeout', 'errorCount', 'byteLength',
17
+ 'url',
18
+ 'action',
19
+ 'event',
20
+ 'responseEvent',
21
+ 'errorEvent',
22
+ 'hasData',
23
+ 'code',
24
+ 'attempt',
25
+ 'maxRetries',
26
+ 'timeout',
27
+ 'errorCount',
28
+ 'byteLength',
19
29
  ]);
20
- const ReconnectingWebSocket = (ReconnectingWebSocketModule.default
21
- ?? ReconnectingWebSocketModule);
30
+ const ReconnectingWebSocket = (ReconnectingWebSocketModule
31
+ .default ?? ReconnectingWebSocketModule);
22
32
  export var SocketEvent;
23
33
  (function (SocketEvent) {
24
34
  SocketEvent["BootError"] = "Events.BootError";
@@ -66,9 +76,7 @@ export class Transport {
66
76
  // Validate configuration
67
77
  this.validateConfiguration(options);
68
78
  this.url = typeof url === 'string' ? new URL(url) : null;
69
- const urlProvider = typeof url === 'string'
70
- ? new URL(url).toString()
71
- : async () => new URL(await url()).toString();
79
+ const urlProvider = typeof url === 'string' ? new URL(url).toString() : async () => new URL(await url()).toString();
72
80
  // Use configurable ping interval
73
81
  this.PING_INTERVAL = options.pingInterval ?? 30000;
74
82
  this.CONNECT_WAIT_TIMEOUT = options.connectWaitTimeout ?? 30000;
@@ -127,7 +135,7 @@ export class Transport {
127
135
  id() {
128
136
  return this.clientId;
129
137
  }
130
- async registerWatchers() {
138
+ registerWatchers() {
131
139
  const onMessage = (ev) => {
132
140
  this.incomingMessageChain = this.incomingMessageChain
133
141
  .catch(() => undefined)
@@ -306,7 +314,9 @@ export class Transport {
306
314
  this.eventEmitter.emit(event, this.clientId);
307
315
  return;
308
316
  }
309
- event && this.eventEmitter.emit(as || event, data);
317
+ if (event) {
318
+ this.eventEmitter.emit(as || event, data);
319
+ }
310
320
  }
311
321
  listen(event, listener, _context) {
312
322
  return this.eventEmitter.listen(event, listener);
@@ -437,14 +447,16 @@ export class Transport {
437
447
  if (!options.timeout) {
438
448
  return promise;
439
449
  }
440
- return timeout(promise, options.timeout).catch((error) => {
450
+ return timeout(promise, options.timeout)
451
+ .catch((error) => {
441
452
  if (error instanceof PromiseTimeoutError) {
442
453
  throw SendTimeoutError.fromPromiseTimeoutError(error);
443
454
  }
444
455
  throw error;
445
- }).finally(removeListeners);
456
+ })
457
+ .finally(removeListeners);
446
458
  };
447
- const retries = options.retries === false ? 0 : options.retries ?? 0;
459
+ const retries = options.retries === false ? 0 : (options.retries ?? 0);
448
460
  return this.sendWithRetry(async () => await send(), retries);
449
461
  }
450
462
  send(action, data = {}) {
package/dist/telemetry.js CHANGED
@@ -40,7 +40,9 @@ export class RuntimeTelemetry {
40
40
  }
41
41
  }
42
42
  synchronize() {
43
- this.synchronization = this.synchronization.catch(() => { }).then(async () => {
43
+ this.synchronization = this.synchronization
44
+ .catch(() => { })
45
+ .then(async () => {
44
46
  const features = Array.from(this.references.keys());
45
47
  if (features.length === 0) {
46
48
  await this.okra.invoke('container.stop-telemetry');
@@ -88,13 +90,16 @@ export function watchRuntimeTelemetry(okra, telemetry, feature, event, transform
88
90
  }
89
91
  options.signal.addEventListener('abort', abort, { once: true });
90
92
  }
91
- void telemetry.acquire(feature).then(async (releaseTelemetry) => {
93
+ void telemetry
94
+ .acquire(feature)
95
+ .then(async (releaseTelemetry) => {
92
96
  if (closed) {
93
97
  await releaseTelemetry();
94
98
  return;
95
99
  }
96
100
  release = releaseTelemetry;
97
- }).catch((error) => {
101
+ })
102
+ .catch((error) => {
98
103
  if (!closed) {
99
104
  closed = true;
100
105
  subscription?.dispose();
package/dist/terminal.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { nanoid } from 'nanoid';
2
2
  import { once } from './utils/promise.js';
3
3
  const TERMINAL_INPUT_FLUSH_DELAY_MS = 8;
4
+ // eslint-disable-next-line no-control-regex -- Terminal control bytes intentionally trigger an immediate flush.
4
5
  const terminalInputFlushPattern = /[\x00-\x1f\x7f]/;
5
6
  export default class Terminals {
6
7
  constructor(okra) {
@@ -12,9 +13,7 @@ export default class Terminals {
12
13
  async create(options = {}) {
13
14
  const id = options.id ?? nanoid();
14
15
  const handle = this.processHandle(id, options.abortSignal);
15
- const command = typeof options.command === 'string' && options.args?.length
16
- ? [options.command, ...options.args]
17
- : options.command;
16
+ const command = typeof options.command === 'string' && options.args?.length ? [options.command, ...options.args] : options.command;
18
17
  const { abortSignal, args: _args, ...input } = options;
19
18
  try {
20
19
  const task = await this.okra.invoke('terminal.create', {
@@ -135,7 +134,7 @@ export default class Terminals {
135
134
  return this.okra.invoke('terminal.close', { id });
136
135
  });
137
136
  const resize = (dimensions) => {
138
- this.okra.invoke('terminal.resize', { id, width: dimensions.cols, height: dimensions.rows });
137
+ return this.okra.invoke('terminal.resize', { id, width: dimensions.cols, height: dimensions.rows });
139
138
  };
140
139
  if (abortSignal && !abortSignal.aborted) {
141
140
  abortHandler = () => {
@@ -5,7 +5,7 @@
5
5
  * @param time
6
6
  * @param exception
7
7
  */
8
- import { PromiseTimeoutError } from "../errors/index.js";
8
+ import { PromiseTimeoutError } from '../errors/index.js';
9
9
  export const timeout = (prom, time) => {
10
10
  let timer;
11
11
  return Promise.race([
@@ -2,12 +2,12 @@ const getReadyStateLabel = (state) => {
2
2
  if (typeof state !== 'number') {
3
3
  return undefined;
4
4
  }
5
- return {
5
+ return ({
6
6
  0: 'CONNECTING',
7
7
  1: 'OPEN',
8
8
  2: 'CLOSING',
9
9
  3: 'CLOSED',
10
- }[state] ?? `STATE_${state}`;
10
+ }[state] ?? `STATE_${state}`);
11
11
  };
12
12
  const sanitizeWebSocketUrl = (value) => {
13
13
  try {