@bytecodealliance/preview2-shim 0.17.3 → 0.17.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,53 @@ Node.js support is fully tested and conformant against the Wasmtime test suite.
6
6
 
7
7
  Browser support is considered experimental, and not currently suitable for production applications.
8
8
 
9
+ # Features
10
+
11
+ ## WASI Shim object for easy instantiation
12
+
13
+ An default instantiation object can be used via the `WASIShim` class in `@bytecodealliance/preview2-shim/instantiation`:
14
+
15
+ ```typescript
16
+ import { WASIShim } from '@bytecodealliance/preview2-shim/instantiation';
17
+ import type {
18
+ VersionedWASIImportObject,
19
+ WASIImportObject,
20
+ } from '@bytecodealliance/preview2-shim/instantiation';
21
+
22
+ const shim = new WASIShim();
23
+
24
+ const unversioned: WASIImportObject = shim.getImportObject();
25
+ // console.log('unversioned', unversioned);
26
+ unversioned satisfies WASIImportObject;
27
+ unversioned satisfies VersionedWASIImportObject<''>;
28
+
29
+ const versioned: VersionedWASIImportObject<'0.2.3'> = shim.getImportObject({
30
+ asVersion: '0.2.3',
31
+ });
32
+ //console.log('versioned', versioned);
33
+ versioned satisfies VersionedWASIImportObject<'0.2.3'>;
34
+ ```
35
+
36
+ The import object generated by `getImportObject` can be easily used in `instantiate()` calls
37
+ produced by [`jco transpile`][jco] (with `--instantiation=async`):
38
+
39
+ ```js
40
+ import { WASIShim } from '@bytecodealliance/preview2-shim/instantiation';
41
+
42
+ // The code below assumes that you have output your transpiled WebAssembly component to `dist/transpiled`
43
+ import { instantiate } from './dist/transpiled/component.js';
44
+
45
+ const loader = async (path: string) => {
46
+ const buf = await readFile(`./dist/transpiled/${path}`);
47
+ return await WebAssembly.compile(buf.buffer as ArrayBuffer);
48
+ };
49
+ const component = await instantiate(loader, new WASIShim().getImportObject());
50
+
51
+ // TODO: Code that uses your component's exports goes here.
52
+ ```
53
+
54
+ [jco]: https://www.npmjs.com/package/@bytecodealliance/jco
55
+
9
56
  # License
10
57
 
11
58
  This project is licensed under the Apache 2.0 license with the LLVM exception.
@@ -1,34 +1,10 @@
1
- import { _setCwd as fsSetCwd } from './filesystem.js';
2
1
  import { streams } from './io.js';
3
2
  const { InputStream, OutputStream } = streams;
4
3
 
5
- const symbolDispose = Symbol.dispose ?? Symbol.for('dispose');
6
-
7
- let _env = [],
8
- _args = [],
9
- _cwd = '/';
10
- export function _setEnv(envObj) {
11
- _env = Object.entries(envObj);
12
- }
13
- export function _setArgs(args) {
14
- _args = args;
15
- }
16
-
17
- export function _setCwd(cwd) {
18
- fsSetCwd((_cwd = cwd));
19
- }
4
+ export { _setEnv, _setArgs, environment } from './environment.js';
5
+ export { _setCwd } from './config.js';
20
6
 
21
- export const environment = {
22
- getEnvironment() {
23
- return _env;
24
- },
25
- getArguments() {
26
- return _args;
27
- },
28
- initialCwd() {
29
- return _cwd;
30
- },
31
- };
7
+ const symbolDispose = Symbol.dispose ?? Symbol.for('dispose');
32
8
 
33
9
  class ComponentExit extends Error {
34
10
  constructor(code) {
@@ -0,0 +1,10 @@
1
+ // eslint-disable-next-line no-unused-vars
2
+ let _cwd = '/';
3
+
4
+ export function _setCwd(cwd) {
5
+ _cwd = cwd;
6
+ }
7
+
8
+ export function _getCwd() {
9
+ return _cwd;
10
+ }
@@ -0,0 +1,29 @@
1
+ import { _setCwd as fsSetCwd } from './config.js';
2
+
3
+ let _env = [],
4
+ _args = [],
5
+ _cwd = '/';
6
+
7
+ export function _setEnv(envObj) {
8
+ _env = Object.entries(envObj);
9
+ }
10
+
11
+ export function _setArgs(args) {
12
+ _args = args;
13
+ }
14
+
15
+ export function _setCwd(cwd) {
16
+ fsSetCwd((_cwd = cwd));
17
+ }
18
+
19
+ export const environment = {
20
+ getEnvironment() {
21
+ return _env;
22
+ },
23
+ getArguments() {
24
+ return _args;
25
+ },
26
+ initialCwd() {
27
+ return _cwd;
28
+ },
29
+ };
@@ -1,13 +1,10 @@
1
1
  import { streams } from './io.js';
2
- import { environment } from './cli.js';
2
+ import { environment } from './environment.js';
3
3
 
4
- const { InputStream, OutputStream } = streams;
5
-
6
- let _cwd = '/';
4
+ import { _setCwd, _getCwd } from './config.js';
5
+ export { _setCwd } from './config.js';
7
6
 
8
- export function _setCwd(cwd) {
9
- _cwd = cwd;
10
- }
7
+ const { InputStream, OutputStream } = streams;
11
8
 
12
9
  export function _setFileData(fileData) {
13
10
  _fileData = fileData;
@@ -33,7 +30,7 @@ function getChildEntry(parentEntry, subpath, openFlags) {
33
30
  _rootPreopen &&
34
31
  descriptorGetEntry(_rootPreopen[0]) === parentEntry
35
32
  ) {
36
- subpath = _cwd;
33
+ subpath = _getCwd();
37
34
  if (subpath.startsWith('/') && subpath !== '/') {
38
35
  subpath = subpath.slice(1);
39
36
  }
@@ -82,46 +82,53 @@ export class WASIShim {
82
82
  * functions like `instantiate` that are exposed from a transpiled
83
83
  * WebAssembly component.
84
84
  *
85
- * @returns {object}
85
+ * @param {GetImportObjectArgs} [opts] - options for import object generation
86
+ * @returns {WASIImportObject}
87
+ *
88
+ * @typedef {{
89
+ * asVersion?: number,
90
+ * }} GetImportObjectArgs
86
91
  */
87
- getImportObject() {
88
- return {
89
- 'wasi:cli/environment': this.#cli.environment,
90
- 'wasi:cli/exit': this.#cli.exit,
91
- 'wasi:cli/stderr': this.#cli.stderr,
92
- 'wasi:cli/stdin': this.#cli.stdin,
93
- 'wasi:cli/stdout': this.#cli.stdout,
94
- 'wasi:cli/terminal-input': this.#cli.terminalInput,
95
- 'wasi:cli/terminal-output': this.#cli.terminalOutput,
96
- 'wasi:cli/terminal-stderr': this.#cli.terminalStderr,
97
- 'wasi:cli/terminal-stdin': this.#cli.terminalStdin,
98
- 'wasi:cli/terminal-stdout': this.#cli.terminalStdout,
92
+ getImportObject(opts) {
93
+ const versionSuffix = opts?.asVersion ? `@${opts.asVersion}` : '';
94
+
95
+ const obj = {};
96
+ obj[`wasi:cli/environment${versionSuffix}`] = this.#cli.environment;
97
+ obj[`wasi:cli/exit${versionSuffix}`] = this.#cli.exit;
98
+ obj[`wasi:cli/stderr${versionSuffix}`] = this.#cli.stderr;
99
+ obj[`wasi:cli/stdin${versionSuffix}`] = this.#cli.stdin;
100
+ obj[`wasi:cli/stdout${versionSuffix}`] = this.#cli.stdout;
101
+ obj[`wasi:cli/terminal-input${versionSuffix}`] = this.#cli.terminalInput;
102
+ obj[`wasi:cli/terminal-output${versionSuffix}`] = this.#cli.terminalOutput;
103
+ obj[`wasi:cli/terminal-stderr${versionSuffix}`] = this.#cli.terminalStderr;
104
+ obj[`wasi:cli/terminal-stdin${versionSuffix}`] = this.#cli.terminalStdin;
105
+ obj[`wasi:cli/terminal-stdout${versionSuffix}`] = this.#cli.terminalStdout;
106
+
107
+ obj[`wasi:sockets/instance-network${versionSuffix}`] = this.#sockets.instanceNetwork;
108
+ obj[`wasi:sockets/ip-name-lookup${versionSuffix}`] = this.#sockets.ipNameLookup;
109
+ obj[`wasi:sockets/network${versionSuffix}`] = this.#sockets.network;
110
+ obj[`wasi:sockets/tcp${versionSuffix}`] = this.#sockets.tcp;
111
+ obj[`wasi:sockets/tcp-create-socket${versionSuffix}`] = this.#sockets.tcpCreateSocket;
112
+ obj[`wasi:sockets/udp${versionSuffix}`] = this.#sockets.udp;
113
+ obj[`wasi:sockets/udp-create-socket${versionSuffix}`] = this.#sockets.udpCreateSocket;
99
114
 
100
- 'wasi:sockets/instance-network': this.#sockets.instanceNetwork,
101
- 'wasi:sockets/ip-name-lookup': this.#sockets.ipNameLookup,
102
- 'wasi:sockets/network': this.#sockets.network,
103
- 'wasi:sockets/tcp': this.#sockets.tcp,
104
- 'wasi:sockets/tcp-create-socket': this.#sockets.tcpCreateSocket,
105
- 'wasi:sockets/udp': this.#sockets.udp,
106
- 'wasi:sockets/udp-create-socket': this.#sockets.udpCreateSocket,
115
+ obj[`wasi:filesystem/preopens${versionSuffix}`] = this.#filesystem.preopens;
116
+ obj[`wasi:filesystem/types${versionSuffix}`] = this.#filesystem.types;
107
117
 
108
- 'wasi:filesystem/preopens': this.#filesystem.preopens,
109
- 'wasi:filesystem/types': this.#filesystem.types,
118
+ obj[`wasi:io/error${versionSuffix}`] = this.#io.error;
119
+ obj[`wasi:io/poll${versionSuffix}`] = this.#io.poll;
120
+ obj[`wasi:io/streams${versionSuffix}`] = this.#io.streams;
110
121
 
111
- 'wasi:io/error': this.#io.error,
112
- 'wasi:io/poll': this.#io.poll,
113
- 'wasi:io/streams': this.#io.streams,
122
+ obj[`wasi:random/random${versionSuffix}`] = this.#random.random;
123
+ obj[`wasi:random/insecure${versionSuffix}`] = this.#random.insecure;
124
+ obj[`wasi:random/insecure-seed${versionSuffix}`] = this.#random.insecureSeed;
114
125
 
115
- 'wasi:random/random': this.#random.random,
116
- 'wasi:random/insecure': this.#random.insecure,
117
- 'wasi:random/insecure-seed': this.#random.insecureSeed,
126
+ obj[`wasi:clocks/monotonic-clock${versionSuffix}`] = this.#clocks.monotonicClock;
127
+ obj[`wasi:clocks/wall-clock${versionSuffix}`] = this.#clocks.wallClock;
118
128
 
119
- 'wasi:clocks/monotonic-clock': this.#clocks.monotonicClock,
120
- 'wasi:clocks/timezone': this.#clocks.timezone,
121
- 'wasi:clocks/wall-clock': this.#clocks.wallClock,
129
+ obj[`wasi:http/types${versionSuffix}`] = this.#http.types;
130
+ obj[`wasi:http/outgoing-handler${versionSuffix}`] = this.#http.outgoingHandler;
122
131
 
123
- 'wasi:http/types': this.#http.types,
124
- 'wasi:http/outgoing-handler': this.#http.outgoingHandler,
125
- };
132
+ return obj;
126
133
  }
127
134
  }
package/lib/io/calls.js CHANGED
@@ -62,6 +62,7 @@ export const HTTP_SERVER_STOP = ++call_id << CALL_SHIFT;
62
62
  export const HTTP_SERVER_INCOMING_HANDLER = ++call_id << CALL_SHIFT;
63
63
  export const HTTP_SERVER_SET_OUTGOING_RESPONSE = ++call_id << CALL_SHIFT;
64
64
  export const HTTP_SERVER_CLEAR_OUTGOING_RESPONSE = ++call_id << CALL_SHIFT;
65
+ export const HTTP_SERVER_GET_ADDRESS = ++call_id << CALL_SHIFT;
65
66
  export const HTTP_OUTGOING_BODY_DISPOSE = ++call_id << CALL_SHIFT;
66
67
 
67
68
  // Clocks
@@ -27,6 +27,10 @@ export function clearOutgoingResponse(id) {
27
27
  responses.delete(id);
28
28
  }
29
29
 
30
+ export async function getHttpServerAddress(id) {
31
+ return servers.get(id).address();
32
+ }
33
+
30
34
  export async function setOutgoingResponse(
31
35
  id,
32
36
  { statusCode, headers, streamId }
@@ -112,30 +116,30 @@ export async function createHttpRequest(
112
116
  // Make a request
113
117
  let req;
114
118
  switch (scheme) {
115
- case 'http:':
116
- req = httpRequest({
117
- agent: httpAgent,
118
- method,
119
- host: authority.split(':')[0],
120
- port: authority.split(':')[1],
121
- path: pathWithQuery,
122
- timeout:
119
+ case 'http:':
120
+ req = httpRequest({
121
+ agent: httpAgent,
122
+ method,
123
+ host: authority.split(':')[0],
124
+ port: authority.split(':')[1],
125
+ path: pathWithQuery,
126
+ timeout:
123
127
  connectTimeout && Number(connectTimeout / 1_000_000n),
124
- });
125
- break;
126
- case 'https:':
127
- req = httpsRequest({
128
- agent: httpsAgent,
129
- method,
130
- host: authority.split(':')[0],
131
- port: authority.split(':')[1],
132
- path: pathWithQuery,
133
- timeout:
128
+ });
129
+ break;
130
+ case 'https:':
131
+ req = httpsRequest({
132
+ agent: httpsAgent,
133
+ method,
134
+ host: authority.split(':')[0],
135
+ port: authority.split(':')[1],
136
+ path: pathWithQuery,
137
+ timeout:
134
138
  connectTimeout && Number(connectTimeout / 1_000_000n),
135
- });
136
- break;
137
- default:
138
- throw { tag: 'HTTP-protocol-error' };
139
+ });
140
+ break;
141
+ default:
142
+ throw { tag: 'HTTP-protocol-error' };
139
143
  }
140
144
  for (const [key, value] of headers) {
141
145
  req.appendHeader(key, value);
@@ -177,20 +181,20 @@ export async function createHttpRequest(
177
181
  }
178
182
  const err = getFirstError(e);
179
183
  switch (err.code) {
180
- case 'ECONNRESET':
181
- throw { tag: 'HTTP-protocol-error' };
182
- case 'ENOTFOUND':
183
- throw {
184
- tag: 'DNS-error',
185
- val: {
186
- rcode: err.code,
187
- infoCode: err.errno < 0 ? -err.errno : err.errno,
188
- },
189
- };
190
- case 'ECONNREFUSED':
191
- throw {
192
- tag: 'connection-refused',
193
- };
184
+ case 'ECONNRESET':
185
+ throw { tag: 'HTTP-protocol-error' };
186
+ case 'ENOTFOUND':
187
+ throw {
188
+ tag: 'DNS-error',
189
+ val: {
190
+ rcode: err.code,
191
+ infoCode: err.errno < 0 ? -err.errno : err.errno,
192
+ },
193
+ };
194
+ case 'ECONNREFUSED':
195
+ throw {
196
+ tag: 'connection-refused',
197
+ };
194
198
  }
195
199
  throw {
196
200
  tag: 'internal-error',
@@ -52,8 +52,8 @@ const DEBUG =
52
52
  env.PREVIEW2_SHIM_DEBUG === '0'
53
53
  ? false
54
54
  : env.PREVIEW2_SHIM_DEBUG === '1'
55
- ? true
56
- : DEBUG_DEFAULT;
55
+ ? true
56
+ : DEBUG_DEFAULT;
57
57
 
58
58
  /**
59
59
  * @type {(call: number, id: number | null, payload: any) -> any}
@@ -219,23 +219,23 @@ class InputStream {
219
219
  stream.#streamType = streamType;
220
220
  let disposeFn;
221
221
  switch (streamType) {
222
- case FILE:
223
- disposeFn = fileInputStreamDispose;
224
- break;
225
- case SOCKET_TCP:
226
- disposeFn = socketTcpInputStreamDispose;
227
- break;
228
- case STDIN:
229
- disposeFn = stdinInputStreamDispose;
230
- break;
231
- case HTTP:
232
- disposeFn = httpInputStreamDispose;
233
- break;
234
- default:
235
- throw new Error(
236
- 'wasi-io trap: Dispose function not created for stream type ' +
222
+ case FILE:
223
+ disposeFn = fileInputStreamDispose;
224
+ break;
225
+ case SOCKET_TCP:
226
+ disposeFn = socketTcpInputStreamDispose;
227
+ break;
228
+ case STDIN:
229
+ disposeFn = stdinInputStreamDispose;
230
+ break;
231
+ case HTTP:
232
+ disposeFn = httpInputStreamDispose;
233
+ break;
234
+ default:
235
+ throw new Error(
236
+ 'wasi-io trap: Dispose function not created for stream type ' +
237
237
  reverseMap[streamType]
238
- );
238
+ );
239
239
  }
240
240
  stream.#finalizer = registerDispose(stream, null, id, disposeFn);
241
241
  return stream;
@@ -361,25 +361,25 @@ class OutputStream {
361
361
  stream.#streamType = streamType;
362
362
  let disposeFn;
363
363
  switch (streamType) {
364
- case STDOUT:
365
- disposeFn = stdoutOutputStreamDispose;
366
- break;
367
- case STDERR:
368
- disposeFn = stderrOutputStreamDispose;
369
- break;
370
- case SOCKET_TCP:
371
- disposeFn = socketTcpOutputStreamDispose;
372
- break;
373
- case FILE:
374
- disposeFn = fileOutputStreamDispose;
375
- break;
376
- case HTTP:
377
- return stream;
378
- default:
379
- throw new Error(
380
- 'wasi-io trap: Dispose function not created for stream type ' +
364
+ case STDOUT:
365
+ disposeFn = stdoutOutputStreamDispose;
366
+ break;
367
+ case STDERR:
368
+ disposeFn = stderrOutputStreamDispose;
369
+ break;
370
+ case SOCKET_TCP:
371
+ disposeFn = socketTcpOutputStreamDispose;
372
+ break;
373
+ case FILE:
374
+ disposeFn = fileOutputStreamDispose;
375
+ break;
376
+ case HTTP:
377
+ return stream;
378
+ default:
379
+ throw new Error(
380
+ 'wasi-io trap: Dispose function not created for stream type ' +
381
381
  reverseMap[streamType]
382
- );
382
+ );
383
383
  }
384
384
  stream.#finalizer = registerDispose(stream, null, id, disposeFn);
385
385
  return stream;
@@ -103,21 +103,21 @@ export function socketResolveAddress(name) {
103
103
  },
104
104
  (err) => {
105
105
  switch (err.code) {
106
- // TODO: verify these more carefully
107
- case NODATA:
108
- case BADFAMILY:
109
- case NONAME:
110
- case NOTFOUND:
111
- throw 'name-unresolvable';
112
- case TIMEOUT:
113
- case REFUSED:
114
- case CONNREFUSED:
115
- case SERVFAIL:
116
- case NOMEM:
117
- case CANCELLED:
118
- throw 'temporary-resolver-failure';
119
- default:
120
- throw 'permanent-resolver-failure';
106
+ // TODO: verify these more carefully
107
+ case NODATA:
108
+ case BADFAMILY:
109
+ case NONAME:
110
+ case NOTFOUND:
111
+ throw 'name-unresolvable';
112
+ case TIMEOUT:
113
+ case REFUSED:
114
+ case CONNREFUSED:
115
+ case SERVFAIL:
116
+ case NOMEM:
117
+ case CANCELLED:
118
+ throw 'temporary-resolver-failure';
119
+ default:
120
+ throw 'permanent-resolver-failure';
121
121
  }
122
122
  }
123
123
  );
@@ -125,82 +125,82 @@ export function socketResolveAddress(name) {
125
125
 
126
126
  export function convertSocketError(err) {
127
127
  switch (err?.code) {
128
- case 'EBADF':
129
- case 'ENOTCONN':
130
- case 'ERR_SOCKET_DGRAM_NOT_CONNECTED':
131
- return 'invalid-state';
132
- case 'EACCES':
133
- case 'EPERM':
134
- return 'access-denied';
135
- case 'ENOTSUP':
136
- return 'not-supported';
137
- case 'EINVAL':
138
- return 'invalid-argument';
139
- case 'ENOMEM':
140
- case 'ENOBUFS':
141
- return 'out-of-memory';
142
- case 'EALREADY':
143
- return 'concurrency-conflict';
144
- case 'EWOULDBLOCK':
145
- return 'would-block';
128
+ case 'EBADF':
129
+ case 'ENOTCONN':
130
+ case 'ERR_SOCKET_DGRAM_NOT_CONNECTED':
131
+ return 'invalid-state';
132
+ case 'EACCES':
133
+ case 'EPERM':
134
+ return 'access-denied';
135
+ case 'ENOTSUP':
136
+ return 'not-supported';
137
+ case 'EINVAL':
138
+ return 'invalid-argument';
139
+ case 'ENOMEM':
140
+ case 'ENOBUFS':
141
+ return 'out-of-memory';
142
+ case 'EALREADY':
143
+ return 'concurrency-conflict';
144
+ case 'EWOULDBLOCK':
145
+ return 'would-block';
146
146
  // TODO: return "new-socket-limit";
147
- case 'EADDRNOTAVAIL':
148
- return 'address-not-bindable';
149
- case 'EADDRINUSE':
150
- return 'address-in-use';
147
+ case 'EADDRNOTAVAIL':
148
+ return 'address-not-bindable';
149
+ case 'EADDRINUSE':
150
+ return 'address-in-use';
151
151
  // TODO: return "remote-unreachable";
152
- case 'ECONNREFUSED':
153
- return 'connection-refused';
154
- case 'ECONNRESET':
155
- return 'connection-reset';
156
- case 'ECONNABORTED':
157
- return 'connection-aborted';
158
- default:
159
- return 'unknown';
152
+ case 'ECONNREFUSED':
153
+ return 'connection-refused';
154
+ case 'ECONNRESET':
155
+ return 'connection-reset';
156
+ case 'ECONNABORTED':
157
+ return 'connection-aborted';
158
+ default:
159
+ return 'unknown';
160
160
  }
161
161
  }
162
162
 
163
163
  export function convertSocketErrorCode(code) {
164
164
  switch (code) {
165
- case 4053: // windows
166
- case 4083:
167
- case ENOTCONN:
168
- case EBADF:
169
- return 'invalid-state';
170
- case EACCES:
171
- case EPERM:
172
- return 'access-denied';
173
- case ENOTSUP:
174
- return 'not-supported';
175
- case EINVAL:
176
- return 'invalid-argument';
177
- case ENOMEM:
178
- case ENOBUFS:
179
- return 'out-of-memory';
180
- case EALREADY:
181
- return 'concurrency-conflict';
182
- case EWOULDBLOCK:
183
- return 'would-block';
165
+ case 4053: // windows
166
+ case 4083:
167
+ case ENOTCONN:
168
+ case EBADF:
169
+ return 'invalid-state';
170
+ case EACCES:
171
+ case EPERM:
172
+ return 'access-denied';
173
+ case ENOTSUP:
174
+ return 'not-supported';
175
+ case EINVAL:
176
+ return 'invalid-argument';
177
+ case ENOMEM:
178
+ case ENOBUFS:
179
+ return 'out-of-memory';
180
+ case EALREADY:
181
+ return 'concurrency-conflict';
182
+ case EWOULDBLOCK:
183
+ return 'would-block';
184
184
  // TODO: return "new-socket-limit";
185
- case 4090: // windows
186
- case EADDRNOTAVAIL:
187
- return 'address-not-bindable';
188
- case 4091: // windows
189
- case EADDRINUSE:
190
- return 'address-in-use';
185
+ case 4090: // windows
186
+ case EADDRNOTAVAIL:
187
+ return 'address-not-bindable';
188
+ case 4091: // windows
189
+ case EADDRINUSE:
190
+ return 'address-in-use';
191
191
  // TODO: return "remote-unreachable";
192
- case ECONNREFUSED:
193
- return 'connection-refused';
194
- case ECONNRESET:
195
- return 'connection-reset';
196
- case ECONNABORTED:
197
- return 'connection-aborted';
192
+ case ECONNREFUSED:
193
+ return 'connection-refused';
194
+ case ECONNRESET:
195
+ return 'connection-reset';
196
+ case ECONNABORTED:
197
+ return 'connection-aborted';
198
198
  // TODO: return "datagram-too-large";
199
199
  // TODO: return "name-unresolvable";
200
200
  // TODO: return "temporary-resolver-failure";
201
- default:
202
- // process._rawDebug('unknown error code', code);
203
- return 'unknown';
201
+ default:
202
+ // process._rawDebug('unknown error code', code);
203
+ return 'unknown';
204
204
  }
205
205
  }
206
206