@bytecodealliance/preview2-shim 0.0.13 → 0.0.14

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 (76) hide show
  1. package/README.md +2 -2
  2. package/lib/browser/cli.js +21 -6
  3. package/lib/browser/filesystem.js +204 -20
  4. package/lib/browser/http.js +4 -7
  5. package/lib/browser/io.js +76 -17
  6. package/lib/browser/logging.js +2 -2
  7. package/lib/browser/poll.js +48 -4
  8. package/lib/http/error.js +1 -1
  9. package/lib/http/make-request.js +3 -2
  10. package/lib/http/wasi-http.js +52 -40
  11. package/lib/nodejs/cli.js +17 -7
  12. package/lib/nodejs/http.js +4 -7
  13. package/lib/nodejs/logging.js +2 -2
  14. package/package.json +1 -1
  15. package/types/exports/wasi-cli-environment.d.ts +22 -0
  16. package/types/exports/wasi-cli-exit.d.ts +7 -0
  17. package/types/exports/wasi-cli-run.d.ts +6 -0
  18. package/types/exports/wasi-cli-stderr.d.ts +5 -0
  19. package/types/exports/wasi-cli-stdin.d.ts +5 -0
  20. package/types/exports/wasi-cli-stdout.d.ts +5 -0
  21. package/types/exports/wasi-cli-terminal-input.d.ts +13 -0
  22. package/types/exports/wasi-cli-terminal-output.d.ts +13 -0
  23. package/types/exports/wasi-cli-terminal-stderr.d.ts +9 -0
  24. package/types/exports/wasi-cli-terminal-stdin.d.ts +9 -0
  25. package/types/exports/wasi-cli-terminal-stdout.d.ts +9 -0
  26. package/types/exports/wasi-clocks-monotonic-clock.d.ts +24 -0
  27. package/types/exports/wasi-clocks-timezone.d.ts +71 -0
  28. package/types/exports/wasi-clocks-wall-clock.d.ts +31 -0
  29. package/types/exports/wasi-filesystem-preopens.d.ts +8 -0
  30. package/types/exports/wasi-filesystem-types.d.ts +843 -0
  31. package/types/exports/wasi-http-incoming-handler.d.ts +7 -0
  32. package/types/exports/wasi-http-outgoing-handler.d.ts +9 -0
  33. package/types/exports/wasi-http-types.d.ts +118 -0
  34. package/types/exports/wasi-io-streams.d.ts +220 -0
  35. package/types/exports/wasi-poll-poll.d.ts +39 -0
  36. package/types/exports/wasi-random-insecure-seed.d.ts +22 -0
  37. package/types/exports/wasi-random-insecure.d.ts +20 -0
  38. package/types/exports/wasi-random-random.d.ts +22 -0
  39. package/types/exports/wasi-sockets-instance-network.d.ts +8 -0
  40. package/types/exports/wasi-sockets-ip-name-lookup.d.ts +76 -0
  41. package/types/exports/wasi-sockets-network.d.ts +180 -0
  42. package/types/exports/wasi-sockets-tcp-create-socket.d.ts +33 -0
  43. package/types/exports/wasi-sockets-tcp.d.ts +285 -0
  44. package/types/exports/wasi-sockets-udp-create-socket.d.ts +33 -0
  45. package/types/exports/wasi-sockets-udp.d.ts +228 -0
  46. package/types/imports/wasi-cli-environment.d.ts +22 -0
  47. package/types/imports/wasi-cli-exit.d.ts +7 -0
  48. package/types/imports/wasi-cli-stderr.d.ts +5 -0
  49. package/types/imports/wasi-cli-stdin.d.ts +5 -0
  50. package/types/imports/wasi-cli-stdout.d.ts +5 -0
  51. package/types/imports/wasi-cli-terminal-input.d.ts +13 -0
  52. package/types/imports/wasi-cli-terminal-output.d.ts +13 -0
  53. package/types/imports/wasi-cli-terminal-stderr.d.ts +9 -0
  54. package/types/imports/wasi-cli-terminal-stdin.d.ts +9 -0
  55. package/types/imports/wasi-cli-terminal-stdout.d.ts +9 -0
  56. package/types/imports/wasi-clocks-monotonic-clock.d.ts +24 -0
  57. package/types/imports/wasi-clocks-timezone.d.ts +71 -0
  58. package/types/imports/wasi-clocks-wall-clock.d.ts +31 -0
  59. package/types/imports/wasi-filesystem-preopens.d.ts +8 -0
  60. package/types/imports/wasi-filesystem-types.d.ts +843 -0
  61. package/types/imports/wasi-http-outgoing-handler.d.ts +9 -0
  62. package/types/imports/wasi-http-types.d.ts +118 -0
  63. package/types/imports/wasi-io-streams.d.ts +220 -0
  64. package/types/imports/wasi-poll-poll.d.ts +39 -0
  65. package/types/imports/wasi-random-insecure-seed.d.ts +22 -0
  66. package/types/imports/wasi-random-insecure.d.ts +20 -0
  67. package/types/imports/wasi-random-random.d.ts +22 -0
  68. package/types/imports/wasi-sockets-instance-network.d.ts +8 -0
  69. package/types/imports/wasi-sockets-ip-name-lookup.d.ts +76 -0
  70. package/types/imports/wasi-sockets-network.d.ts +180 -0
  71. package/types/imports/wasi-sockets-tcp-create-socket.d.ts +33 -0
  72. package/types/imports/wasi-sockets-tcp.d.ts +285 -0
  73. package/types/imports/wasi-sockets-udp-create-socket.d.ts +33 -0
  74. package/types/imports/wasi-sockets-udp.d.ts +228 -0
  75. package/types/wasi-cli-command.d.ts +29 -0
  76. package/types/wasi-http-proxy.d.ts +13 -0
package/README.md CHANGED
@@ -10,13 +10,13 @@ Currently supports Node.js and browser versions, but alternative implementations
10
10
  | --------------- | ----------------------------:|-----------------------------:|
11
11
  | Clocks | Pending timezone, poll | Pending timezone, poll |
12
12
  | Filesystem | Basic read support | :x: |
13
- | HTTP | :x: | :x: |
13
+ | HTTP | Experimental support | Experimental support |
14
14
  | IO | Basic FS Streams | :x: |
15
15
  | Logging | :heavy_check_mark: | :heavy_check_mark: |
16
16
  | Poll | :x: | :x: |
17
17
  | Random | :heavy_check_mark: | :heavy_check_mark: |
18
18
  | Sockets | :x: | :x: |
19
- | CLI Base | :heavy_check_mark: | :heavy_check_mark: |
19
+ | CLI | :heavy_check_mark: | :heavy_check_mark: |
20
20
 
21
21
  # License
22
22
 
@@ -1,25 +1,40 @@
1
- let _env;
1
+ import { _setCwd as fsSetCwd } from './filesystem.js';
2
+
3
+ let _env = [], _args = [], _cwd = null;
2
4
  export function _setEnv (envObj) {
3
5
  _env = Object.entries(envObj);
4
6
  }
7
+ export function _setArgs (args) {
8
+ _args = args;
9
+ }
10
+
11
+ export function _setCwd (cwd) {
12
+ fsSetCwd(_cwd = cwd);
13
+ }
5
14
 
6
15
  export const environment = {
7
16
  getEnvironment () {
8
- if (!_env) _env = [];
9
17
  return _env;
18
+ },
19
+ getArguments () {
20
+ return _args;
21
+ },
22
+ initialCwd () {
23
+ return _cwd;
10
24
  }
11
25
  };
12
26
 
13
27
  class ComponentExit extends Error {
14
- constructor(code) {
15
- super(`Component exited ${code === 0 ? 'successfully' : 'with error'}`);
16
- this.code = code;
28
+ constructor(ok) {
29
+ super(`Component exited ${ok ? 'successfully' : 'with error'}`);
30
+ this.exitError = true;
31
+ this.ok = ok;
17
32
  }
18
33
  }
19
34
 
20
35
  export const exit = {
21
36
  exit (status) {
22
- throw new ComponentExit(status.tag === 'err' ? 1 : 0);
37
+ throw new ComponentExit(status.tag === 'err' ? true : false);
23
38
  }
24
39
  };
25
40
 
@@ -1,16 +1,145 @@
1
+ import { createStream, getStream, dropStream } from './io.js';
2
+ import { environment } from './cli.js';
3
+
4
+ let _preopens = [[3, '/']], _rootPreopen = _preopens[0];
5
+
6
+ export function _setPreopens (preopens) {
7
+ _preopens = preopens;
8
+ descriptorCnt = 3 + _preopens.length;
9
+ _rootPreopen = _preopens.find(preopen => preopen[1] === '/');
10
+ }
11
+
12
+ let _cwd = null;
13
+
14
+ export function _setCwd (cwd) {
15
+ _cwd = cwd;
16
+ }
17
+
18
+ export function _setFileData (fileData) {
19
+ _fileData = fileData;
20
+ _setPreopens(Object.keys(fileData).map((key) => {
21
+ const fd = descriptorCnt++;
22
+ descriptorTable[fd] = { entry: fileData[key] };
23
+ return [fd, key];
24
+ }));
25
+ const cwd = environment.initialCwd();
26
+ _setCwd(cwd || '/');
27
+ }
28
+
29
+ export function _getFileData () {
30
+ return JSON.stringify(_fileData);
31
+ }
32
+
33
+ let _fileData = {};
34
+
35
+ let descriptorCnt = 4;
36
+ const descriptorTable = {
37
+ 0: { stream: 0 },
38
+ 1: { stream: 1 },
39
+ 2: { stream: 2 },
40
+ 3: { entry: { dir: {} } },
41
+ };
42
+
43
+ const timeZero = {
44
+ seconds: BigInt(0),
45
+ nanoseconds: 0
46
+ };
47
+
48
+ function getDescriptor (fd) {
49
+ const descriptor = descriptorTable[fd];
50
+ if (!descriptor) throw 'bad-descriptor';
51
+ return descriptor;
52
+ }
53
+
54
+ function getChildEntry (fd, subpath, openFlags) {
55
+ if (subpath === '.' && _rootPreopen && _rootPreopen[0] === fd) {
56
+ subpath = _cwd;
57
+ if (subpath.startsWith('/'))
58
+ subpath = subpath.slice(1);
59
+ }
60
+ let entry = getDescriptor(fd)?.entry;
61
+ let segmentIdx;
62
+ do {
63
+ if (!entry || !entry.dir) throw 'not-directory';
64
+ segmentIdx = subpath.indexOf('/');
65
+ const segment = segmentIdx === -1 ? subpath : subpath.slice(0, segmentIdx);
66
+ if (segment === '.' || segment === '') return entry;
67
+ if (segment === '..') throw 'no-entry';
68
+ if (!entry.dir[segment] && openFlags.create)
69
+ entry = entry.dir[segment] = openFlags.directory ? { dir: {} } : { source: new Uint8Array([]) };
70
+ else
71
+ entry = entry.dir[segment];
72
+ } while (segmentIdx !== -1)
73
+ if (!entry) throw 'no-entry';
74
+ return entry;
75
+ }
76
+
77
+ function createChildDescriptor (fd, subpath, openFlags) {
78
+ const entry = getChildEntry(fd, subpath, openFlags);
79
+ const childFd = descriptorCnt++;
80
+ descriptorTable[childFd] = { entry };
81
+ return childFd;
82
+ }
83
+
84
+ function getSource (fileEntry) {
85
+ if (typeof fileEntry.source === 'string') {
86
+ fileEntry.source = new TextEncoder().encode(fileEntry.source);
87
+ }
88
+ return fileEntry.source;
89
+ }
90
+
91
+ class DirStream {
92
+ constructor (entries) {
93
+ this.idx = 0;
94
+ this.entries = entries;
95
+ }
96
+ next () {
97
+ if (this.idx === this.entries.length)
98
+ return null;
99
+ const [name, entry] = this.entries[this.idx];
100
+ this.idx += 1;
101
+ return {
102
+ name,
103
+ type: entry.dir ? 'directory' : 'regular-file'
104
+ };
105
+ }
106
+ }
107
+
1
108
  export const preopens = {
2
109
  getDirectories () {
3
- return [];
110
+ return _preopens;
4
111
  }
5
112
  }
6
113
 
7
114
  export const types = {
8
115
  readViaStream(fd, offset) {
9
- console.log(`[filesystem] READ STREAM ${fd} ${offset}`);
116
+ const descriptor = getDescriptor(fd);
117
+ const source = getSource(descriptor.entry);
118
+ return createStream({
119
+ i: Number(offset),
120
+ source,
121
+ read (len) {
122
+ const bytes = this.source.slice(this.i, this.i + Number(len));
123
+ this.i += bytes.byteLength;
124
+ return [bytes, this.i === this.source.byteLength ? 'ended' : 'open'];
125
+ }
126
+ });
10
127
  },
11
128
 
12
129
  writeViaStream(fd, offset) {
13
- console.log(`[filesystem] WRITE STREAM ${fd} ${offset}`);
130
+ const descriptor = getDescriptor(fd);
131
+ return createStream({
132
+ i: Number(offset),
133
+ entry: descriptor.entry,
134
+ write (buf) {
135
+ const newSource = new Uint8Array(buf.byteLength + this.entry.source.byteLength);
136
+ newSource.set(this.entry.source, 0);
137
+ newSource.set(buf, this.i);
138
+ this.i += buf.byteLength;
139
+ this.entry.source = newSource;
140
+ return buf.byteLength;
141
+ }
142
+ });
14
143
  },
15
144
 
16
145
  appendViaStream(fd) {
@@ -30,7 +159,12 @@ export const types = {
30
159
  },
31
160
 
32
161
  getType(fd) {
33
- console.log(`[filesystem] GET TYPE ${fd}`);
162
+ if (fd < 3) return 'fifo';
163
+ const descriptor = getDescriptor(fd);
164
+ if (descriptor.stream) return 'fifo';
165
+ if (descriptor.entry.dir) return 'directory';
166
+ if (descriptor.entry.source) return 'regular-file';
167
+ return 'unknown';
34
168
  },
35
169
 
36
170
  setFlags(fd, flags) {
@@ -46,15 +180,22 @@ export const types = {
46
180
  },
47
181
 
48
182
  read(fd, length, offset) {
49
- console.log(`[filesystem] READ`, fd, length, offset);
183
+ const descriptor = getDescriptor(fd);
184
+ const source = getSource(descriptor.entry);
185
+ return [source.slice(offset, offset + length), offset + length >= source.byteLength];
50
186
  },
51
187
 
52
188
  write(fd, buffer, offset) {
53
- console.log(`[filesystem] WRITE`, fd, buffer, offset);
189
+ const descriptor = getDescriptor(fd);
190
+ if (offset !== 0) throw 'invalid-seek';
191
+ descriptor.entry.source = buffer;
192
+ return buffer.byteLength;
54
193
  },
55
194
 
56
195
  readDirectory(fd) {
57
- console.log(`[filesystem] READ DIR`, fd);
196
+ const descriptor = getDescriptor(fd);
197
+ if (!descriptor?.entry?.dir) throw 'bad-descriptor';
198
+ return createStream(new DirStream(Object.entries(descriptor.entry.dir).sort(([a], [b]) => a > b ? 1 : -1)));
58
199
  },
59
200
 
60
201
  sync(fd) {
@@ -62,15 +203,50 @@ export const types = {
62
203
  },
63
204
 
64
205
  createDirectoryAt(fd, path) {
65
- console.log(`[filesystem] CREATE DIRECTORY`, fd, path);
206
+ const entry = getChildEntry(fd, path, { create: true, directory: true });
207
+ if (entry.source) throw 'exist';
66
208
  },
67
209
 
68
210
  stat(fd) {
69
- console.log(`[filesystem] STAT`, fd);
211
+ const descriptor = getDescriptor(fd);
212
+ let type = 'unknown', size = BigInt(0);
213
+ if (descriptor.entry.source) {
214
+ type = 'directory';
215
+ }
216
+ else if (descriptor.entry.dir) {
217
+ type = 'regular-file';
218
+ const source = getSource(descriptor.entry);
219
+ size = BigInt(source.byteLength);
220
+ }
221
+ return {
222
+ type,
223
+ linkCount: BigInt(0),
224
+ size,
225
+ dataAccessTimestamp: timeZero,
226
+ dataModificationTimestamp: timeZero,
227
+ statusChangeTimestamp: timeZero,
228
+ }
70
229
  },
71
230
 
72
231
  statAt(fd, pathFlags, path) {
73
- console.log(`[filesystem] STAT`, fd, pathFlags, path);
232
+ const entry = getChildEntry(fd, path);
233
+ let type = 'unknown', size = BigInt(0);
234
+ if (entry.source) {
235
+ type = 'regular-file';
236
+ const source = getSource(entry);
237
+ size = BigInt(source.byteLength);
238
+ }
239
+ else if (entry.dir) {
240
+ type = 'directory';
241
+ }
242
+ return {
243
+ type,
244
+ linkCount: BigInt(0),
245
+ size,
246
+ dataAccessTimestamp: timeZero,
247
+ dataModificationTimestamp: timeZero,
248
+ statusChangeTimestamp: timeZero,
249
+ };
74
250
  },
75
251
 
76
252
  setTimesAt(fd) {
@@ -81,8 +257,8 @@ export const types = {
81
257
  console.log(`[filesystem] LINK AT`, fd);
82
258
  },
83
259
 
84
- openAt(fd) {
85
- console.log(`[filesystem] OPEN AT ${fd}`);
260
+ openAt(fd, _pathFlags, path, openFlags, _descriptorFlags, _modes) {
261
+ return createChildDescriptor(fd, path, openFlags);
86
262
  },
87
263
 
88
264
  readlinkAt(fd) {
@@ -134,23 +310,31 @@ export const types = {
134
310
  },
135
311
 
136
312
  dropDescriptor(fd) {
137
- console.log(`[filesystem] DROP DESCRIPTOR`, fd);
313
+ if (fd < _preopens.length + 3)
314
+ return;
315
+ delete descriptorTable[fd];
138
316
  },
139
317
 
140
- readDirectoryEntry(stream) {
141
- console.log(`[filesystem] READ DIRECTRY ENTRY`, stream);
318
+ readDirectoryEntry(sid) {
319
+ return getStream(sid).next();
142
320
  },
143
321
 
144
- dropDirectoryEntryStream(stream) {
145
- console.log(`[filesystem] DROP DIRECTORY ENTRY`, stream);
322
+ dropDirectoryEntryStream(sid) {
323
+ dropStream(sid);
146
324
  },
147
325
 
148
326
  metadataHash(fd) {
149
- console.log(`[filesystem] METADATA HASH`, fd);
327
+ const descriptor = getDescriptor(fd);
328
+ let upper = BigInt(0);
329
+ upper += BigInt(descriptor.mtime || 0);
330
+ return { upper, lower: BigInt(0) };
150
331
  },
151
332
 
152
- metadataHashAt(fd, pathFlags, path) {
153
- console.log(`[filesystem] METADATA HASH AT `, fd, pathFlags, path);
333
+ metadataHashAt(fd, _pathFlags, _path) {
334
+ const descriptor = getDescriptor(fd);
335
+ let upper = BigInt(0);
336
+ upper += BigInt(descriptor.mtime || 0);
337
+ return { upper, lower: BigInt(0) };
154
338
  }
155
339
  };
156
340
 
@@ -1,7 +1,7 @@
1
1
  import { UnexpectedError } from "../http/error.js";
2
2
 
3
3
  /**
4
- * @param {import("../types/imports/types").Request} req
4
+ * @param {import("../../types/imports/wasi-http-types").Request} req
5
5
  * @returns {string}
6
6
  */
7
7
  export function send(req) {
@@ -86,11 +86,8 @@ export const types = {
86
86
  incomingRequestMethod(_req) {
87
87
  console.log("[types] Incoming request method");
88
88
  },
89
- incomingRequestPath(_req) {
90
- console.log("[types] Incoming request path");
91
- },
92
- incomingRequestQuery(_req) {
93
- console.log("[types] Incoming request query");
89
+ incomingRequestPathWithQuery(_req) {
90
+ console.log("[types] Incoming request path with query");
94
91
  },
95
92
  incomingRequestScheme(_req) {
96
93
  console.log("[types] Incoming request scheme");
@@ -104,7 +101,7 @@ export const types = {
104
101
  incomingRequestConsume(_req) {
105
102
  console.log("[types] Incoming request consume");
106
103
  },
107
- newOutgoingRequest(_method, _path, _query, _scheme, _authority, _headers) {
104
+ newOutgoingRequest(_method, _pathWithQuery, _scheme, _authority, _headers) {
108
105
  console.log("[types] New outgoing request");
109
106
  },
110
107
  outgoingRequestWrite(_req) {
package/lib/browser/io.js CHANGED
@@ -1,9 +1,81 @@
1
+ // buffer until the next newline
2
+ class NewlineBufferStream {
3
+ constructor (handler) {
4
+ this.bufferLen = 0;
5
+ this.bufferCapacity = 1024;
6
+ this.buffer = new Uint8Array(1024);
7
+ this.handler = handler;
8
+ }
9
+ write (bytes) {
10
+ const newlineIdx = bytes.lastIndexOf(10);
11
+ if (newlineIdx === -1) {
12
+ this.#addToBuffer(bytes);
13
+ } else {
14
+ this.#addToBuffer(bytes.slice(0, newlineIdx + 1));
15
+ this.handler(new TextDecoder().decode(this.buffer.slice(0, this.bufferLen)));
16
+ this.bufferLen = 0;
17
+ this.#addToBuffer(bytes.slice(newlineIdx + 1));
18
+ }
19
+ }
20
+ #addToBuffer (bytes) {
21
+ if (bytes.byteLength + this.bufferLen > this.bufferCapacity) {
22
+ this.bufferCapacity *= 2;
23
+ const buffer = new Uint8Array(this.bufferCapacity);
24
+ buffer.set(this.buffer);
25
+ this.buffer = buffer;
26
+ }
27
+ this.buffer.set(bytes, this.bufferLen);
28
+ this.bufferLen += bytes.byteLength;
29
+ }
30
+ }
31
+
32
+ class IgnoreStream {
33
+ read () {
34
+ return [new Uint8Array([]), 'ended'];
35
+ }
36
+ write () {}
37
+ }
38
+
39
+ export function createStream (stream) {
40
+ streamEntries[streamCnt] = stream;
41
+ return streamCnt++;
42
+ }
43
+
44
+ export function getStream (sid) {
45
+ const stream = streamEntries[sid];
46
+ if (!stream) throw new Error();
47
+ return stream;
48
+ }
49
+
50
+ export function dropStream (sid) {
51
+ delete streamEntries[sid];
52
+ }
53
+
54
+ let streamCnt = 3;
55
+ const streamEntries = {
56
+ 0: new IgnoreStream(),
57
+ 1: new NewlineBufferStream(console.log.bind(console)),
58
+ 2: new NewlineBufferStream(console.error.bind(console)),
59
+ };
60
+
61
+ export function _setStdout (stdout) {
62
+ streamEntries[1] = stdout;
63
+ }
64
+
65
+ export function _setStderr (stderr) {
66
+ streamEntries[2] = stderr;
67
+ }
68
+
69
+ export function _setStdin (stdin) {
70
+ streamEntries[0] = stdin;
71
+ }
72
+
1
73
  export const streams = {
2
74
  read(s, len) {
3
- console.log(`[streams] Read ${s} ${len}`);
75
+ return getStream(s).read(len);
4
76
  },
5
77
  blockingRead(s, len) {
6
- console.log(`[streams] Blocking read ${s} ${len}`);
78
+ return getStream(s).read(len);
7
79
  },
8
80
  skip(s, _len) {
9
81
  console.log(`[streams] Skip ${s}`);
@@ -18,23 +90,10 @@ export const streams = {
18
90
  console.log(`[streams] Drop input stream ${s}`);
19
91
  },
20
92
  write(s, buf) {
21
- streams.blockingWrite(s, buf);
93
+ return [BigInt(getStream(s).write(buf)), 'ended'];
22
94
  },
23
95
  blockingWrite(s, buf) {
24
- switch (s) {
25
- case 0:
26
- throw new Error(`TODO: write stdin`);
27
- case 1: {
28
- process.stdout.write(buf);
29
- return [BigInt(buf.byteLength), 'ended'];
30
- }
31
- case 2: {
32
- process.stderr.write(buf);
33
- return [BigInt(buf.byteLength), 'ended'];
34
- }
35
- default:
36
- throw new Error(`TODO: write ${s}`);
37
- }
96
+ return [BigInt(getStream(s).write(buf)), 'ended'];
38
97
  },
39
98
  writeZeroes(s, _len) {
40
99
  console.log(`[streams] Write zeroes ${s}`);
@@ -1,8 +1,8 @@
1
- const levels = ["trace", "debug", "info", "warn", "error"];
1
+ const levels = ["trace", "debug", "info", "warn", "error", "critical"];
2
2
 
3
3
  let logLevel = levels.indexOf("warn");
4
4
 
5
- export const handler = {
5
+ export const logging = {
6
6
  log(level, context, msg) {
7
7
  if (logLevel > levels.indexOf(level)) return;
8
8
  console[level](`(${context}) ${msg}\n`);
@@ -1,9 +1,53 @@
1
+ let polls = {};
2
+ let pollCnt = 1;
3
+
4
+ let timer = null, timerInterval = 10, watching = new Set();
5
+ function intervalCheck () {
6
+ for (const entry of watching) {
7
+ if (entry.settled) {
8
+ entry.resolvePromise();
9
+ entry.promise = entry.resolvePromise = null;
10
+ watching.delete(entry);
11
+ }
12
+ }
13
+ if (watching.size === 0) {
14
+ clearInterval(timer);
15
+ timer = null;
16
+ }
17
+ }
18
+
19
+ export function _createPollable (promise) {
20
+ const entry = { settled: false, promise: null, resolvePromise: null };
21
+ promise.finally(() => entry.settled = true);
22
+ polls[pollCnt] = entry;
23
+ return pollCnt++;
24
+ }
25
+
26
+ export function _pollablePromise (pollable, maxInterval) {
27
+ const entry = polls[pollable];
28
+ if (entry.settled) return Promise.resolve();
29
+ if (!entry.promise)
30
+ entry.promise = new Promise(resolve => entry.resolvePromise = resolve);
31
+ watching.add(entry);
32
+ if (maxInterval) {
33
+ if (timerInterval > maxInterval) {
34
+ clearInterval(timer);
35
+ timer = null;
36
+ timerInterval = maxInterval;
37
+ }
38
+ }
39
+ if (!timer)
40
+ timer = setInterval(intervalCheck, timerInterval);
41
+ return entry.promise;
42
+ }
43
+
1
44
  export const poll = {
2
45
  dropPollable (pollable) {
3
- console.log(`[poll] Drop (${pollable})`);
46
+ const entry = polls[pollable];
47
+ watching.delete(entry);
48
+ delete polls[pollable];
4
49
  },
5
- pollOneoff (input) {
6
- console.log(`[poll] Oneoff (${input})`);
7
- return [];
50
+ pollOneoff (from) {
51
+ return from.map(pollable => polls[pollable].settled);
8
52
  }
9
53
  };
package/lib/http/error.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export class UnexpectedError extends Error {
2
- /** @type { import("../types/http").HttpErrorUnexpectedError } */
2
+ /** @type { import("../../types/imports/wasi-http-types").ErrorUnexpectedError } */
3
3
  payload;
4
4
  constructor(message = "unexpected-error") {
5
5
  super(message);
@@ -1,7 +1,7 @@
1
1
  import { runAsWorker } from "./synckit/index.js";
2
2
 
3
3
  /**
4
- * @param {import("../types/imports/types").Request} req
4
+ * @param {import("../../types/imports/wasi-http-types").Request} req
5
5
  * @returns {Promise<string>}
6
6
  */
7
7
  async function makeRequest(req) {
@@ -11,6 +11,7 @@ async function makeRequest(req) {
11
11
  method: req.method.toString(),
12
12
  headers,
13
13
  body: req.body && req.body.length > 0 ? req.body : undefined,
14
+ redirect: "manual",
14
15
  });
15
16
  let arrayBuffer = await resp.arrayBuffer();
16
17
  return JSON.stringify({
@@ -22,7 +23,7 @@ async function makeRequest(req) {
22
23
  : undefined,
23
24
  });
24
25
  } catch (err) {
25
- return err.message;
26
+ return JSON.stringify({ message: err.toString() });
26
27
  }
27
28
  }
28
29