@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.
- package/README.md +38 -0
- package/dist/beacon/index.js +4 -2
- package/dist/beacon/navigator.js +0 -1
- package/dist/beacon/types.d.ts +1 -1
- package/dist/browser/phpsandbox-sdk.esm.js +405 -308
- package/dist/browser/phpsandbox-sdk.esm.min.js +23 -25
- package/dist/browser/phpsandbox-sdk.iife.js +405 -308
- package/dist/browser/phpsandbox-sdk.iife.min.js +8 -10
- package/dist/composer.js +8 -4
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -3
- package/dist/feedback.js +2 -1
- package/dist/filesystem.js +32 -15
- package/dist/identity.d.ts +13 -0
- package/dist/identity.js +6 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +14 -5
- package/dist/integrations/sandbox.js +1 -1
- package/dist/lsp.d.ts +2 -2
- package/dist/lsp.js +2 -2
- package/dist/publication/index.d.ts +1 -0
- package/dist/publication/index.js +1 -0
- package/dist/publication/instance.d.ts +2 -0
- package/dist/publication/instance.js +8 -0
- package/dist/publication/notebook.js +7 -5
- package/dist/publication/resources.js +2 -1
- package/dist/publication/run.js +2 -76
- package/dist/publication/stream.d.ts +18 -0
- package/dist/publication/stream.js +185 -0
- package/dist/runtime/rest.js +2 -1
- package/dist/runtime.js +1 -1
- package/dist/schemas/publications.js +53 -59
- package/dist/servers.d.ts +2 -0
- package/dist/servers.js +5 -1
- package/dist/shell.js +5 -2
- package/dist/socket/index.js +25 -13
- package/dist/telemetry.js +8 -3
- package/dist/terminal.js +3 -4
- package/dist/utils/promise.js +1 -1
- package/dist/utils/websocket.js +2 -2
- package/package.json +49 -33
- package/dist/auth.d.ts +0 -11
- 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
|
+
}
|
package/dist/runtime/rest.js
CHANGED
|
@@ -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))
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
})
|
|
61
|
-
|
|
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
|
-
})
|
|
67
|
-
|
|
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
|
-
})
|
|
72
|
-
|
|
46
|
+
})
|
|
47
|
+
.strict();
|
|
48
|
+
export const PublishStreamLogSchema = z
|
|
49
|
+
.object({
|
|
73
50
|
stream: PublishStreamLogStreamSchema,
|
|
74
51
|
content: z.string(),
|
|
75
|
-
})
|
|
76
|
-
|
|
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
|
-
})
|
|
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
|
|
78
|
+
export const PublishStreamErrorSchema = z
|
|
79
|
+
.object({
|
|
99
80
|
message: z.string().optional(),
|
|
100
|
-
})
|
|
81
|
+
})
|
|
82
|
+
.passthrough();
|
|
101
83
|
export const PublishStreamSseEventNameSchema = z.enum(['phase', 'log', 'done', 'result', 'error']);
|
|
102
|
-
export const PublishStreamSsePhaseEventSchema = z
|
|
84
|
+
export const PublishStreamSsePhaseEventSchema = z
|
|
85
|
+
.object({
|
|
103
86
|
event: z.literal('phase'),
|
|
104
87
|
data: PublishStreamPhaseSchema,
|
|
105
|
-
})
|
|
106
|
-
|
|
88
|
+
})
|
|
89
|
+
.strict();
|
|
90
|
+
export const PublishStreamSseLogEventSchema = z
|
|
91
|
+
.object({
|
|
107
92
|
event: z.literal('log'),
|
|
108
93
|
data: PublishStreamLogSchema,
|
|
109
|
-
})
|
|
110
|
-
|
|
94
|
+
})
|
|
95
|
+
.strict();
|
|
96
|
+
export const PublishStreamSseDoneEventSchema = z
|
|
97
|
+
.object({
|
|
111
98
|
event: z.literal('done'),
|
|
112
99
|
data: PublishStreamResultSchema,
|
|
113
|
-
})
|
|
114
|
-
|
|
100
|
+
})
|
|
101
|
+
.strict();
|
|
102
|
+
export const PublishStreamSseResultEventSchema = z
|
|
103
|
+
.object({
|
|
115
104
|
event: z.literal('result'),
|
|
116
105
|
data: PublishStreamResultSchema,
|
|
117
|
-
})
|
|
118
|
-
|
|
106
|
+
})
|
|
107
|
+
.strict();
|
|
108
|
+
export const PublishStreamSseErrorEventSchema = z
|
|
109
|
+
.object({
|
|
119
110
|
event: z.literal('error'),
|
|
120
111
|
data: PublishStreamErrorSchema,
|
|
121
|
-
})
|
|
122
|
-
|
|
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
|
-
])
|
|
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
|
|
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
|
-
})
|
|
97
|
+
})
|
|
98
|
+
.catch((error) => {
|
|
96
99
|
fail(error);
|
|
97
100
|
throw error;
|
|
98
101
|
});
|
package/dist/socket/index.js
CHANGED
|
@@ -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
|
|
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',
|
|
18
|
-
'
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
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
|
-
})
|
|
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
|
|
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
|
|
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
|
-
})
|
|
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 = () => {
|
package/dist/utils/promise.js
CHANGED
package/dist/utils/websocket.js
CHANGED
|
@@ -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 {
|