@bytecodealliance/preview2-shim 0.18.1 → 0.20.0
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 +15 -15
- package/dist/browser/cli.d.ts +16 -0
- package/dist/browser/cli.js +109 -0
- package/dist/browser/clocks.d.ts +3 -0
- package/dist/browser/clocks.js +36 -0
- package/dist/browser/config.d.ts +2 -0
- package/{lib → dist}/browser/config.js +2 -4
- package/dist/browser/environment.d.ts +5 -0
- package/dist/browser/environment.js +24 -0
- package/dist/browser/filesystem.d.ts +132 -0
- package/dist/browser/filesystem.js +488 -0
- package/dist/browser/http.d.ts +4 -0
- package/dist/browser/http.js +643 -0
- package/dist/browser/index.d.ts +7 -0
- package/dist/browser/index.js +7 -0
- package/dist/browser/io.d.ts +58 -0
- package/dist/browser/io.js +205 -0
- package/dist/browser/random.d.ts +4 -0
- package/dist/browser/random.js +49 -0
- package/dist/browser/sockets.d.ts +8 -0
- package/dist/browser/sockets.js +66 -0
- package/dist/common/instantiation.d.ts +97 -0
- package/dist/common/instantiation.js +228 -0
- package/dist/io/calls.d.ts +91 -0
- package/{lib → dist}/io/calls.js +4 -19
- package/dist/io/worker-http.d.ts +17 -0
- package/dist/io/worker-http.js +192 -0
- package/dist/io/worker-io.d.ts +84 -0
- package/dist/io/worker-io.js +381 -0
- package/dist/io/worker-socket-tcp.d.ts +34 -0
- package/dist/io/worker-socket-tcp.js +251 -0
- package/dist/io/worker-socket-udp.d.ts +54 -0
- package/dist/io/worker-socket-udp.js +493 -0
- package/dist/io/worker-sockets.d.ts +32 -0
- package/dist/io/worker-sockets.js +265 -0
- package/dist/io/worker-thread.d.ts +73 -0
- package/dist/io/worker-thread.js +794 -0
- package/dist/nodejs/cli.d.ts +30 -0
- package/dist/nodejs/cli.js +86 -0
- package/dist/nodejs/clocks.d.ts +3 -0
- package/dist/nodejs/clocks.js +61 -0
- package/dist/nodejs/filesystem.d.ts +113 -0
- package/dist/nodejs/filesystem.js +761 -0
- package/dist/nodejs/http.d.ts +82 -0
- package/dist/nodejs/http.js +674 -0
- package/dist/nodejs/index.d.ts +7 -0
- package/dist/nodejs/index.js +7 -0
- package/dist/nodejs/io.d.ts +1 -0
- package/dist/nodejs/io.js +1 -0
- package/dist/nodejs/random.d.ts +4 -0
- package/dist/nodejs/random.js +42 -0
- package/dist/nodejs/sockets.d.ts +21 -0
- package/dist/nodejs/sockets.js +482 -0
- package/dist/synckit/index.d.ts +2 -0
- package/dist/synckit/index.js +117 -0
- package/package.json +28 -15
- package/types/instantiation.d.ts +7 -7
- package/lib/browser/cli.js +0 -135
- package/lib/browser/clocks.js +0 -39
- package/lib/browser/environment.js +0 -29
- package/lib/browser/filesystem.js +0 -503
- package/lib/browser/http.js +0 -707
- package/lib/browser/index.js +0 -9
- package/lib/browser/io.js +0 -262
- package/lib/browser/random.js +0 -56
- package/lib/browser/sockets.js +0 -88
- package/lib/common/instantiation.js +0 -253
- package/lib/io/worker-http.js +0 -206
- package/lib/io/worker-io.js +0 -468
- package/lib/io/worker-socket-tcp.js +0 -331
- package/lib/io/worker-socket-udp.js +0 -587
- package/lib/io/worker-sockets.js +0 -364
- package/lib/io/worker-thread.js +0 -1051
- package/lib/nodejs/cli.js +0 -109
- package/lib/nodejs/clocks.js +0 -67
- package/lib/nodejs/filesystem.js +0 -829
- package/lib/nodejs/http.js +0 -764
- package/lib/nodejs/index.js +0 -9
- package/lib/nodejs/io.js +0 -1
- package/lib/nodejs/random.js +0 -49
- package/lib/nodejs/sockets.js +0 -565
- package/lib/synckit/index.js +0 -127
package/lib/browser/http.js
DELETED
|
@@ -1,707 +0,0 @@
|
|
|
1
|
-
import { streams, poll } from "./io.js";
|
|
2
|
-
|
|
3
|
-
const { InputStream, OutputStream } = streams;
|
|
4
|
-
const { Pollable } = poll;
|
|
5
|
-
|
|
6
|
-
const symbolDispose = Symbol.dispose || Symbol.for("dispose");
|
|
7
|
-
const utf8Decoder = new TextDecoder();
|
|
8
|
-
const forbiddenHeaders = new Set(["connection", "keep-alive", "host"]);
|
|
9
|
-
const DEFAULT_HTTP_TIMEOUT_NS = 600_000_000_000n;
|
|
10
|
-
|
|
11
|
-
// RFC 9110 compliant header validation
|
|
12
|
-
const TOKEN_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
13
|
-
const FIELD_VALUE_RE = /^[\t\x20-\x7E\x80-\xFF]*$/;
|
|
14
|
-
|
|
15
|
-
function validateHeaderName(name) {
|
|
16
|
-
if (!TOKEN_RE.test(name)) {
|
|
17
|
-
throw { tag: "invalid-syntax" };
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function validateHeaderValue(value) {
|
|
22
|
-
const str = typeof value === "string" ? value : utf8Decoder.decode(value);
|
|
23
|
-
if (!FIELD_VALUE_RE.test(str)) {
|
|
24
|
-
throw { tag: "invalid-syntax" };
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
class Fields {
|
|
29
|
-
#immutable = false;
|
|
30
|
-
/** @type {[string, Uint8Array][]} */ #entries = [];
|
|
31
|
-
/** @type {Map<string, [string, Uint8Array][]>} */ #table = new Map();
|
|
32
|
-
|
|
33
|
-
static fromList(entries) {
|
|
34
|
-
const fields = new Fields();
|
|
35
|
-
for (const [key, value] of entries) {
|
|
36
|
-
fields.append(key, value);
|
|
37
|
-
}
|
|
38
|
-
return fields;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get(name) {
|
|
42
|
-
const tableEntries = this.#table.get(name.toLowerCase());
|
|
43
|
-
if (!tableEntries) {
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
46
|
-
return tableEntries.map(([, v]) => v);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* WIT spec (https://github.com/WebAssembly/WASI/blob/91bb44c3c3a9b1e09187db23c85fa844d1fd6b15/proposals/http/wit/types.wit#L215-L223):
|
|
51
|
-
*
|
|
52
|
-
* > Set all of the values for a name. Clears any existing values for that
|
|
53
|
-
* > name, if they have been set.
|
|
54
|
-
* >
|
|
55
|
-
* > Fails with `header-error.immutable` if the `fields` are immutable.
|
|
56
|
-
* >
|
|
57
|
-
* > Fails with `header-error.invalid-syntax` if the `field-name` or any of
|
|
58
|
-
* > the `field-value`s are syntactically invalid.
|
|
59
|
-
*
|
|
60
|
-
* The existing-branch splice/reuse is an allocation optimization — values are cleared, not retained.
|
|
61
|
-
*/
|
|
62
|
-
set(name, values) {
|
|
63
|
-
if (this.#immutable) {
|
|
64
|
-
throw { tag: "immutable" };
|
|
65
|
-
}
|
|
66
|
-
validateHeaderName(name);
|
|
67
|
-
for (const value of values) {
|
|
68
|
-
validateHeaderValue(value);
|
|
69
|
-
}
|
|
70
|
-
const lowercased = name.toLowerCase();
|
|
71
|
-
if (forbiddenHeaders.has(lowercased)) {
|
|
72
|
-
throw { tag: "forbidden" };
|
|
73
|
-
}
|
|
74
|
-
const tableEntries = this.#table.get(lowercased);
|
|
75
|
-
if (tableEntries) {
|
|
76
|
-
this.#entries = this.#entries.filter((entry) => !tableEntries.includes(entry));
|
|
77
|
-
tableEntries.splice(0, tableEntries.length);
|
|
78
|
-
} else {
|
|
79
|
-
this.#table.set(lowercased, []);
|
|
80
|
-
}
|
|
81
|
-
const newTableEntries = this.#table.get(lowercased);
|
|
82
|
-
for (const value of values) {
|
|
83
|
-
const entry = [name, value];
|
|
84
|
-
this.#entries.push(entry);
|
|
85
|
-
newTableEntries.push(entry);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
has(name) {
|
|
90
|
-
return this.#table.has(name.toLowerCase());
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
delete(name) {
|
|
94
|
-
if (this.#immutable) {
|
|
95
|
-
throw { tag: "immutable" };
|
|
96
|
-
}
|
|
97
|
-
const lowercased = name.toLowerCase();
|
|
98
|
-
const tableEntries = this.#table.get(lowercased);
|
|
99
|
-
if (tableEntries) {
|
|
100
|
-
this.#entries = this.#entries.filter((entry) => !tableEntries.includes(entry));
|
|
101
|
-
this.#table.delete(lowercased);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
append(name, value) {
|
|
106
|
-
if (this.#immutable) {
|
|
107
|
-
throw { tag: "immutable" };
|
|
108
|
-
}
|
|
109
|
-
validateHeaderName(name);
|
|
110
|
-
validateHeaderValue(value);
|
|
111
|
-
const lowercased = name.toLowerCase();
|
|
112
|
-
if (forbiddenHeaders.has(lowercased)) {
|
|
113
|
-
throw { tag: "forbidden" };
|
|
114
|
-
}
|
|
115
|
-
const entry = [name, value];
|
|
116
|
-
this.#entries.push(entry);
|
|
117
|
-
const tableEntries = this.#table.get(lowercased);
|
|
118
|
-
if (tableEntries) {
|
|
119
|
-
tableEntries.push(entry);
|
|
120
|
-
} else {
|
|
121
|
-
this.#table.set(lowercased, [entry]);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
entries() {
|
|
126
|
-
return this.#entries;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
clone() {
|
|
130
|
-
return fieldsFromEntriesChecked(this.#entries);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
static _lock(fields) {
|
|
134
|
-
fields.#immutable = true;
|
|
135
|
-
return fields;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
static _fromEntriesChecked(entries) {
|
|
139
|
-
const fields = new Fields();
|
|
140
|
-
fields.#entries = entries;
|
|
141
|
-
for (const entry of entries) {
|
|
142
|
-
const lowercase = entry[0].toLowerCase();
|
|
143
|
-
const existing = fields.#table.get(lowercase);
|
|
144
|
-
if (existing) {
|
|
145
|
-
existing.push(entry);
|
|
146
|
-
} else {
|
|
147
|
-
fields.#table.set(lowercase, [entry]);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return fields;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
const fieldsLock = Fields._lock;
|
|
154
|
-
delete Fields._lock;
|
|
155
|
-
const fieldsFromEntriesChecked = Fields._fromEntriesChecked;
|
|
156
|
-
delete Fields._fromEntriesChecked;
|
|
157
|
-
|
|
158
|
-
class RequestOptions {
|
|
159
|
-
#connectTimeout = DEFAULT_HTTP_TIMEOUT_NS;
|
|
160
|
-
#firstByteTimeout = DEFAULT_HTTP_TIMEOUT_NS;
|
|
161
|
-
#betweenBytesTimeout = DEFAULT_HTTP_TIMEOUT_NS;
|
|
162
|
-
connectTimeout() {
|
|
163
|
-
return this.#connectTimeout;
|
|
164
|
-
}
|
|
165
|
-
setConnectTimeout(duration) {
|
|
166
|
-
if (duration < 0n) {
|
|
167
|
-
throw new Error("duration must not be negative");
|
|
168
|
-
}
|
|
169
|
-
this.#connectTimeout = duration;
|
|
170
|
-
}
|
|
171
|
-
firstByteTimeout() {
|
|
172
|
-
return this.#firstByteTimeout;
|
|
173
|
-
}
|
|
174
|
-
setFirstByteTimeout(duration) {
|
|
175
|
-
if (duration < 0n) {
|
|
176
|
-
throw new Error("duration must not be negative");
|
|
177
|
-
}
|
|
178
|
-
this.#firstByteTimeout = duration;
|
|
179
|
-
}
|
|
180
|
-
betweenBytesTimeout() {
|
|
181
|
-
return this.#betweenBytesTimeout;
|
|
182
|
-
}
|
|
183
|
-
setBetweenBytesTimeout(duration) {
|
|
184
|
-
if (duration < 0n) {
|
|
185
|
-
throw new Error("duration must not be negative");
|
|
186
|
-
}
|
|
187
|
-
this.#betweenBytesTimeout = duration;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
class OutgoingBody {
|
|
192
|
-
#outputStream = null;
|
|
193
|
-
#chunks = [];
|
|
194
|
-
#finished = false;
|
|
195
|
-
|
|
196
|
-
write() {
|
|
197
|
-
const outputStream = this.#outputStream;
|
|
198
|
-
if (outputStream === null) {
|
|
199
|
-
throw undefined;
|
|
200
|
-
}
|
|
201
|
-
this.#outputStream = null;
|
|
202
|
-
return outputStream;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
static finish(body, trailers) {
|
|
206
|
-
if (trailers) {
|
|
207
|
-
throw { tag: "internal-error", val: "trailers unsupported" };
|
|
208
|
-
}
|
|
209
|
-
if (body.#finished) {
|
|
210
|
-
throw { tag: "internal-error", val: "body already finished" };
|
|
211
|
-
}
|
|
212
|
-
body.#finished = true;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
static _bodyData(outgoingBody) {
|
|
216
|
-
if (outgoingBody.#chunks.length === 0) {
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
let totalLen = 0;
|
|
220
|
-
for (const chunk of outgoingBody.#chunks) {
|
|
221
|
-
totalLen += chunk.byteLength;
|
|
222
|
-
}
|
|
223
|
-
const result = new Uint8Array(totalLen);
|
|
224
|
-
let offset = 0;
|
|
225
|
-
for (const chunk of outgoingBody.#chunks) {
|
|
226
|
-
result.set(chunk, offset);
|
|
227
|
-
offset += chunk.byteLength;
|
|
228
|
-
}
|
|
229
|
-
return result;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
static _create() {
|
|
233
|
-
const outgoingBody = new OutgoingBody();
|
|
234
|
-
const chunks = outgoingBody.#chunks;
|
|
235
|
-
outgoingBody.#outputStream = new OutputStream({
|
|
236
|
-
write(buf) {
|
|
237
|
-
chunks.push(new Uint8Array(buf));
|
|
238
|
-
},
|
|
239
|
-
flush() {},
|
|
240
|
-
blockingFlush() {},
|
|
241
|
-
subscribe() {
|
|
242
|
-
return new Pollable();
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
return outgoingBody;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
[symbolDispose]() {}
|
|
249
|
-
}
|
|
250
|
-
const outgoingBodyCreate = OutgoingBody._create;
|
|
251
|
-
delete OutgoingBody._create;
|
|
252
|
-
const outgoingBodyData = OutgoingBody._bodyData;
|
|
253
|
-
delete OutgoingBody._bodyData;
|
|
254
|
-
|
|
255
|
-
class OutgoingRequest {
|
|
256
|
-
/** @type {{ tag: string, val?: string }} */ #method = { tag: "get" };
|
|
257
|
-
/** @type {{ tag: string, val?: string } | undefined} */ #scheme = undefined;
|
|
258
|
-
/** @type {string | undefined} */ #pathWithQuery = undefined;
|
|
259
|
-
/** @type {string | undefined} */ #authority = undefined;
|
|
260
|
-
/** @type {Fields} */ #headers;
|
|
261
|
-
/** @type {OutgoingBody} */ #body;
|
|
262
|
-
#bodyRequested = false;
|
|
263
|
-
|
|
264
|
-
constructor(headers) {
|
|
265
|
-
fieldsLock(headers);
|
|
266
|
-
this.#headers = headers;
|
|
267
|
-
this.#body = outgoingBodyCreate();
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
body() {
|
|
271
|
-
if (this.#bodyRequested) {
|
|
272
|
-
throw new Error("Body already requested");
|
|
273
|
-
}
|
|
274
|
-
this.#bodyRequested = true;
|
|
275
|
-
return this.#body;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
method() {
|
|
279
|
-
return this.#method;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
setMethod(method) {
|
|
283
|
-
if (method.tag === "other" && !method.val.match(/^[a-zA-Z-]+$/)) {
|
|
284
|
-
throw undefined;
|
|
285
|
-
}
|
|
286
|
-
this.#method = method;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
pathWithQuery() {
|
|
290
|
-
return this.#pathWithQuery;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
setPathWithQuery(pathWithQuery) {
|
|
294
|
-
if (pathWithQuery && !pathWithQuery.match(/^[a-zA-Z0-9.\-_~!$&'()*+,;=:@%?/]+$/)) {
|
|
295
|
-
throw undefined;
|
|
296
|
-
}
|
|
297
|
-
this.#pathWithQuery = pathWithQuery;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
scheme() {
|
|
301
|
-
return this.#scheme;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
setScheme(scheme) {
|
|
305
|
-
if (scheme?.tag === "other" && !scheme.val.match(/^[a-zA-Z]+$/)) {
|
|
306
|
-
throw undefined;
|
|
307
|
-
}
|
|
308
|
-
this.#scheme = scheme;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
authority() {
|
|
312
|
-
return this.#authority;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
setAuthority(authority) {
|
|
316
|
-
if (authority) {
|
|
317
|
-
const [host, port, ...extra] = authority.split(":");
|
|
318
|
-
const portNum = Number(port);
|
|
319
|
-
if (
|
|
320
|
-
extra.length ||
|
|
321
|
-
(port !== undefined && (portNum.toString() !== port || portNum > 65535)) ||
|
|
322
|
-
!host.match(/^[a-zA-Z0-9-.]+$/)
|
|
323
|
-
) {
|
|
324
|
-
throw undefined;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
this.#authority = authority;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
headers() {
|
|
331
|
-
return this.#headers;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
[symbolDispose]() {}
|
|
335
|
-
|
|
336
|
-
static _handle(request, options) {
|
|
337
|
-
const scheme = schemeString(request.#scheme);
|
|
338
|
-
const method = request.#method.val || request.#method.tag;
|
|
339
|
-
|
|
340
|
-
if (!request.#pathWithQuery) {
|
|
341
|
-
throw { tag: "HTTP-request-URI-invalid" };
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
const url = `${scheme}//${request.#authority || ""}${request.#pathWithQuery}`;
|
|
345
|
-
|
|
346
|
-
const headers = new Headers();
|
|
347
|
-
for (const [key, value] of request.#headers.entries()) {
|
|
348
|
-
const lowerKey = key.toLowerCase();
|
|
349
|
-
if (!forbiddenHeaders.has(lowerKey)) {
|
|
350
|
-
headers.set(key, utf8Decoder.decode(value));
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
const bodyData = outgoingBodyData(request.#body);
|
|
355
|
-
|
|
356
|
-
let timeoutMs = Number(DEFAULT_HTTP_TIMEOUT_NS / 1_000_000n);
|
|
357
|
-
if (options) {
|
|
358
|
-
const ct = options.connectTimeout?.() ?? DEFAULT_HTTP_TIMEOUT_NS;
|
|
359
|
-
const fbt = options.firstByteTimeout?.() ?? DEFAULT_HTTP_TIMEOUT_NS;
|
|
360
|
-
const minTimeout = ct < fbt ? ct : fbt;
|
|
361
|
-
timeoutMs = Number(minTimeout / 1_000_000n);
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
return futureIncomingResponseCreate(url, method.toUpperCase(), headers, bodyData, timeoutMs);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
const outgoingRequestHandle = OutgoingRequest._handle;
|
|
368
|
-
delete OutgoingRequest._handle;
|
|
369
|
-
|
|
370
|
-
class IncomingBody {
|
|
371
|
-
#finished = false;
|
|
372
|
-
#stream = undefined;
|
|
373
|
-
|
|
374
|
-
stream() {
|
|
375
|
-
if (!this.#stream) {
|
|
376
|
-
throw undefined;
|
|
377
|
-
}
|
|
378
|
-
const stream = this.#stream;
|
|
379
|
-
this.#stream = null;
|
|
380
|
-
return stream;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
static finish(incomingBody) {
|
|
384
|
-
if (incomingBody.#finished) {
|
|
385
|
-
throw new Error("incoming body already finished");
|
|
386
|
-
}
|
|
387
|
-
incomingBody.#finished = true;
|
|
388
|
-
return futureTrailersCreate();
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
[symbolDispose]() {}
|
|
392
|
-
|
|
393
|
-
static _create(fetchResponse) {
|
|
394
|
-
const incomingBody = new IncomingBody();
|
|
395
|
-
let buffer = null;
|
|
396
|
-
let bufferOffset = 0;
|
|
397
|
-
let done = false;
|
|
398
|
-
let reader = null;
|
|
399
|
-
let readPromise = null;
|
|
400
|
-
|
|
401
|
-
function ensureReader() {
|
|
402
|
-
if (!reader && fetchResponse.body) {
|
|
403
|
-
reader = fetchResponse.body.getReader();
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
function startRead() {
|
|
408
|
-
if (readPromise || done) {
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
ensureReader();
|
|
412
|
-
if (!reader) {
|
|
413
|
-
done = true;
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
readPromise = reader.read().then(
|
|
417
|
-
(result) => {
|
|
418
|
-
readPromise = null;
|
|
419
|
-
if (result.done) {
|
|
420
|
-
done = true;
|
|
421
|
-
} else {
|
|
422
|
-
buffer = result.value;
|
|
423
|
-
bufferOffset = 0;
|
|
424
|
-
}
|
|
425
|
-
},
|
|
426
|
-
() => {
|
|
427
|
-
readPromise = null;
|
|
428
|
-
done = true;
|
|
429
|
-
},
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
incomingBody.#stream = new InputStream({
|
|
434
|
-
read(len) {
|
|
435
|
-
if (done && (buffer === null || bufferOffset >= buffer.byteLength)) {
|
|
436
|
-
throw { tag: "closed" };
|
|
437
|
-
}
|
|
438
|
-
if (buffer !== null && bufferOffset < buffer.byteLength) {
|
|
439
|
-
const available = buffer.byteLength - bufferOffset;
|
|
440
|
-
const toRead = Math.min(Number(len), available);
|
|
441
|
-
const slice = buffer.slice(bufferOffset, bufferOffset + toRead);
|
|
442
|
-
bufferOffset += toRead;
|
|
443
|
-
if (bufferOffset >= buffer.byteLength) {
|
|
444
|
-
buffer = null;
|
|
445
|
-
bufferOffset = 0;
|
|
446
|
-
if (!done) {
|
|
447
|
-
startRead();
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
return slice;
|
|
451
|
-
}
|
|
452
|
-
throw { tag: "would-block" };
|
|
453
|
-
},
|
|
454
|
-
blockingRead(len) {
|
|
455
|
-
if (done && (buffer === null || bufferOffset >= buffer.byteLength)) {
|
|
456
|
-
throw { tag: "closed" };
|
|
457
|
-
}
|
|
458
|
-
if (buffer !== null && bufferOffset < buffer.byteLength) {
|
|
459
|
-
const available = buffer.byteLength - bufferOffset;
|
|
460
|
-
const toRead = Math.min(Number(len), available);
|
|
461
|
-
const slice = buffer.slice(bufferOffset, bufferOffset + toRead);
|
|
462
|
-
bufferOffset += toRead;
|
|
463
|
-
if (bufferOffset >= buffer.byteLength) {
|
|
464
|
-
buffer = null;
|
|
465
|
-
bufferOffset = 0;
|
|
466
|
-
if (!done) {
|
|
467
|
-
startRead();
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
return slice;
|
|
471
|
-
}
|
|
472
|
-
startRead();
|
|
473
|
-
const waitFor = readPromise || Promise.resolve();
|
|
474
|
-
return waitFor.then(() => {
|
|
475
|
-
if (done && (buffer === null || bufferOffset >= buffer.byteLength)) {
|
|
476
|
-
throw { tag: "closed" };
|
|
477
|
-
}
|
|
478
|
-
if (buffer !== null && bufferOffset < buffer.byteLength) {
|
|
479
|
-
const available = buffer.byteLength - bufferOffset;
|
|
480
|
-
const toRead = Math.min(Number(len), available);
|
|
481
|
-
const slice = buffer.slice(bufferOffset, bufferOffset + toRead);
|
|
482
|
-
bufferOffset += toRead;
|
|
483
|
-
if (bufferOffset >= buffer.byteLength) {
|
|
484
|
-
buffer = null;
|
|
485
|
-
bufferOffset = 0;
|
|
486
|
-
if (!done) {
|
|
487
|
-
startRead();
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
return slice;
|
|
491
|
-
}
|
|
492
|
-
throw { tag: "closed" };
|
|
493
|
-
});
|
|
494
|
-
},
|
|
495
|
-
subscribe() {
|
|
496
|
-
if (done || (buffer !== null && bufferOffset < buffer.byteLength)) {
|
|
497
|
-
return new Pollable();
|
|
498
|
-
}
|
|
499
|
-
startRead();
|
|
500
|
-
if (readPromise) {
|
|
501
|
-
return new Pollable(readPromise);
|
|
502
|
-
}
|
|
503
|
-
return new Pollable();
|
|
504
|
-
},
|
|
505
|
-
});
|
|
506
|
-
|
|
507
|
-
startRead();
|
|
508
|
-
return incomingBody;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
const incomingBodyCreate = IncomingBody._create;
|
|
512
|
-
delete IncomingBody._create;
|
|
513
|
-
|
|
514
|
-
class IncomingResponse {
|
|
515
|
-
/** @type {Fields} */ #headers = undefined;
|
|
516
|
-
#status = 0;
|
|
517
|
-
/** @type {IncomingBody} */ #body;
|
|
518
|
-
|
|
519
|
-
status() {
|
|
520
|
-
return this.#status;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
headers() {
|
|
524
|
-
return this.#headers;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
consume() {
|
|
528
|
-
if (this.#body === undefined) {
|
|
529
|
-
throw undefined;
|
|
530
|
-
}
|
|
531
|
-
const body = this.#body;
|
|
532
|
-
this.#body = undefined;
|
|
533
|
-
return body;
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
[symbolDispose]() {}
|
|
537
|
-
|
|
538
|
-
static _create(fetchResponse) {
|
|
539
|
-
const res = new IncomingResponse();
|
|
540
|
-
res.#status = fetchResponse.status;
|
|
541
|
-
|
|
542
|
-
const headerEntries = [];
|
|
543
|
-
const encoder = new TextEncoder();
|
|
544
|
-
fetchResponse.headers.forEach((value, key) => {
|
|
545
|
-
headerEntries.push([key, encoder.encode(value)]);
|
|
546
|
-
});
|
|
547
|
-
res.#headers = fieldsLock(fieldsFromEntriesChecked(headerEntries));
|
|
548
|
-
res.#body = incomingBodyCreate(fetchResponse);
|
|
549
|
-
return res;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
const incomingResponseCreate = IncomingResponse._create;
|
|
553
|
-
delete IncomingResponse._create;
|
|
554
|
-
|
|
555
|
-
class FutureTrailers {
|
|
556
|
-
#requested = false;
|
|
557
|
-
subscribe() {
|
|
558
|
-
return new Pollable();
|
|
559
|
-
}
|
|
560
|
-
get() {
|
|
561
|
-
if (this.#requested) {
|
|
562
|
-
return { tag: "err" };
|
|
563
|
-
}
|
|
564
|
-
this.#requested = true;
|
|
565
|
-
return {
|
|
566
|
-
tag: "ok",
|
|
567
|
-
val: {
|
|
568
|
-
tag: "ok",
|
|
569
|
-
val: undefined,
|
|
570
|
-
},
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
static _create() {
|
|
574
|
-
return new FutureTrailers();
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
const futureTrailersCreate = FutureTrailers._create;
|
|
578
|
-
delete FutureTrailers._create;
|
|
579
|
-
|
|
580
|
-
function mapFetchError(err) {
|
|
581
|
-
if (err.name === "AbortError") {
|
|
582
|
-
return { tag: "connection-timeout" };
|
|
583
|
-
}
|
|
584
|
-
if (err.name === "TypeError") {
|
|
585
|
-
return { tag: "connection-refused" };
|
|
586
|
-
}
|
|
587
|
-
return { tag: "internal-error", val: err.message };
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
class FutureIncomingResponse {
|
|
591
|
-
#result = undefined;
|
|
592
|
-
#promise = null;
|
|
593
|
-
|
|
594
|
-
subscribe() {
|
|
595
|
-
return new Pollable(this.#promise);
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
get() {
|
|
599
|
-
if (this.#result === undefined) {
|
|
600
|
-
return undefined;
|
|
601
|
-
}
|
|
602
|
-
const result = this.#result;
|
|
603
|
-
this.#result = { tag: "err" };
|
|
604
|
-
return result;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
[symbolDispose]() {
|
|
608
|
-
this.#promise = null;
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
static _create(url, method, headers, bodyData, timeoutMs) {
|
|
612
|
-
const future = new FutureIncomingResponse();
|
|
613
|
-
|
|
614
|
-
const controller = new AbortController();
|
|
615
|
-
let timer;
|
|
616
|
-
if (timeoutMs < Infinity) {
|
|
617
|
-
timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
const init = {
|
|
621
|
-
method,
|
|
622
|
-
headers,
|
|
623
|
-
signal: controller.signal,
|
|
624
|
-
};
|
|
625
|
-
if (bodyData && method !== "GET" && method !== "HEAD") {
|
|
626
|
-
init.body = bodyData;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
future.#promise = fetch(url, init).then(
|
|
630
|
-
(response) => {
|
|
631
|
-
if (timer) {
|
|
632
|
-
clearTimeout(timer);
|
|
633
|
-
}
|
|
634
|
-
future.#result = {
|
|
635
|
-
tag: "ok",
|
|
636
|
-
val: {
|
|
637
|
-
tag: "ok",
|
|
638
|
-
val: incomingResponseCreate(response),
|
|
639
|
-
},
|
|
640
|
-
};
|
|
641
|
-
},
|
|
642
|
-
(err) => {
|
|
643
|
-
if (timer) {
|
|
644
|
-
clearTimeout(timer);
|
|
645
|
-
}
|
|
646
|
-
future.#result = {
|
|
647
|
-
tag: "ok",
|
|
648
|
-
val: {
|
|
649
|
-
tag: "err",
|
|
650
|
-
val: mapFetchError(err),
|
|
651
|
-
},
|
|
652
|
-
};
|
|
653
|
-
},
|
|
654
|
-
);
|
|
655
|
-
|
|
656
|
-
return future;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
const futureIncomingResponseCreate = FutureIncomingResponse._create;
|
|
660
|
-
delete FutureIncomingResponse._create;
|
|
661
|
-
|
|
662
|
-
function schemeString(scheme) {
|
|
663
|
-
if (!scheme) {
|
|
664
|
-
return "https:";
|
|
665
|
-
}
|
|
666
|
-
switch (scheme.tag) {
|
|
667
|
-
case "HTTP":
|
|
668
|
-
return "http:";
|
|
669
|
-
case "HTTPS":
|
|
670
|
-
return "https:";
|
|
671
|
-
case "other":
|
|
672
|
-
return scheme.val.toLowerCase() + ":";
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
function httpErrorCode(err) {
|
|
677
|
-
if (err.payload) {
|
|
678
|
-
return err.payload;
|
|
679
|
-
}
|
|
680
|
-
return {
|
|
681
|
-
tag: "internal-error",
|
|
682
|
-
val: err.message,
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
export const outgoingHandler = {
|
|
687
|
-
handle: outgoingRequestHandle,
|
|
688
|
-
};
|
|
689
|
-
|
|
690
|
-
export const incomingHandler = {
|
|
691
|
-
handle() {},
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
export const types = {
|
|
695
|
-
Fields,
|
|
696
|
-
FutureIncomingResponse,
|
|
697
|
-
FutureTrailers,
|
|
698
|
-
IncomingBody,
|
|
699
|
-
IncomingRequest: class IncomingRequest {},
|
|
700
|
-
IncomingResponse,
|
|
701
|
-
OutgoingBody,
|
|
702
|
-
OutgoingRequest,
|
|
703
|
-
OutgoingResponse: class OutgoingResponse {},
|
|
704
|
-
ResponseOutparam: class ResponseOutparam {},
|
|
705
|
-
RequestOptions,
|
|
706
|
-
httpErrorCode,
|
|
707
|
-
};
|
package/lib/browser/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import * as clocks from "./clocks.js";
|
|
2
|
-
import * as filesystem from "./filesystem.js";
|
|
3
|
-
import * as http from "./http.js";
|
|
4
|
-
import * as io from "./io.js";
|
|
5
|
-
import * as random from "./random.js";
|
|
6
|
-
import * as sockets from "./sockets.js";
|
|
7
|
-
import * as cli from "./cli.js";
|
|
8
|
-
|
|
9
|
-
export { clocks, filesystem, http, io, random, sockets, cli };
|