tailscale-web 0.1.10 → 0.1.11

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
@@ -5,7 +5,7 @@
5
5
  [![license](https://img.shields.io/github/license/adrianosela/tailscale-web.svg)](https://github.com/adrianosela/tailscale-web/blob/master/LICENSE)
6
6
  [![Go Report Card](https://goreportcard.com/badge/github.com/adrianosela/tailscale-web)](https://goreportcard.com/report/github.com/adrianosela/tailscale-web)
7
7
 
8
- Run a [Tailscale](https://tailscale.com) device directly in the browser. Make HTTP requests, open TCP connections, ping hosts, and use exit nodes for networking beyond Tailscale devices — all from a web page, with no server-side proxy required.
8
+ Run a [Tailscale](https://tailscale.com) device directly in the browser. Make HTTP requests, dial or listen for TCP connections, ping hosts, and use exit nodes for networking beyond Tailscale devices — all from a web page, with no server-side proxy required.
9
9
 
10
10
  <details>
11
11
  <summary>**Click here for motivation**</summary>
@@ -172,6 +172,24 @@ conn.write("hello\n")
172
172
  conn.close()
173
173
  ```
174
174
 
175
+ ### `network.listenTCP(port?, onConnection)`
176
+
177
+ Accept inbound TCP connections on a Tailscale port. Pass `0` (or omit) for an ephemeral port. Returns a `Listener` with the assigned `port` and a `close()` method.
178
+
179
+ ```ts
180
+ const listener = await network.listenTCP(8080, conn => {
181
+ conn.onData(data => {
182
+ console.log(new TextDecoder().decode(data))
183
+ conn.write("pong\n")
184
+ })
185
+ })
186
+
187
+ console.log("listening on port", listener.port)
188
+
189
+ // stop accepting connections
190
+ listener.close()
191
+ ```
192
+
175
193
  ### Exit nodes
176
194
 
177
195
  ```ts
package/dist/index.d.ts CHANGED
@@ -56,6 +56,13 @@ export declare interface InitOptions {
56
56
  onAuthComplete?: () => void;
57
57
  }
58
58
 
59
+ export declare interface Listener {
60
+ /** The port number the listener is bound to. */
61
+ port: number;
62
+ /** Stop the listener and release all resources. */
63
+ close(): void;
64
+ }
65
+
59
66
  export declare const network: {
60
67
  /**
61
68
  * Initialize and connect the Tailscale node. Must be called before any
@@ -117,6 +124,26 @@ export declare const network: {
117
124
  * conn.close()
118
125
  */
119
126
  dialTCP(addr: string): Promise<Connection>;
127
+ /**
128
+ * Listen for inbound TCP connections on the given Tailscale port.
129
+ * Pass port 0 (default) to get an ephemeral port assigned automatically.
130
+ * onConnection is called for each accepted connection.
131
+ * Returns a Listener with the assigned port number and a close() method.
132
+ *
133
+ * @example
134
+ * const listener = await network.listenTCP(8080, conn => {
135
+ * conn.onData(data => console.log(new TextDecoder().decode(data)))
136
+ * conn.write("hello\n")
137
+ * })
138
+ * console.log("listening on port", listener.port)
139
+ *
140
+ * @example
141
+ * // Ephemeral port
142
+ * const listener = await network.listenTCP(0, conn => { conn.close() })
143
+ * console.log("assigned port:", listener.port)
144
+ * listener.close()
145
+ */
146
+ listenTCP(port: number | undefined, onConnection: (conn: Connection) => void): Promise<Listener>;
120
147
  /**
121
148
  * Make an HTTP request through the Tailscale network. Supports method,
122
149
  * headers, and body. Does not yet support AbortSignal, streaming bodies
package/dist/main.wasm CHANGED
Binary file
@@ -1,21 +1,21 @@
1
1
  (() => {
2
2
  const n = () => {
3
- const c = new Error("not implemented");
4
- return c.code = "ENOSYS", c;
3
+ const l = new Error("not implemented");
4
+ return l.code = "ENOSYS", l;
5
5
  };
6
6
  if (!globalThis.fs) {
7
- let c = "";
7
+ let l = "";
8
8
  globalThis.fs = {
9
9
  constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1, O_DIRECTORY: -1 },
10
10
  // unused
11
11
  writeSync(i, s) {
12
- c += g.decode(s);
13
- const r = c.lastIndexOf(`
12
+ l += d.decode(s);
13
+ const r = l.lastIndexOf(`
14
14
  `);
15
- return r != -1 && (console.log(c.substring(0, r)), c = c.substring(r + 1)), s.length;
15
+ return r != -1 && (console.log(l.substring(0, r)), l = l.substring(r + 1)), s.length;
16
16
  },
17
- write(i, s, r, a, y, u) {
18
- if (r !== 0 || a !== s.length || y !== null) {
17
+ write(i, s, r, c, y, u) {
18
+ if (r !== 0 || c !== s.length || y !== null) {
19
19
  u(n());
20
20
  return;
21
21
  }
@@ -25,8 +25,8 @@
25
25
  chmod(i, s, r) {
26
26
  r(n());
27
27
  },
28
- chown(i, s, r, a) {
29
- a(n());
28
+ chown(i, s, r, c) {
29
+ c(n());
30
30
  },
31
31
  close(i, s) {
32
32
  s(n());
@@ -34,8 +34,8 @@
34
34
  fchmod(i, s, r) {
35
35
  r(n());
36
36
  },
37
- fchown(i, s, r, a) {
38
- a(n());
37
+ fchown(i, s, r, c) {
38
+ c(n());
39
39
  },
40
40
  fstat(i, s) {
41
41
  s(n());
@@ -46,8 +46,8 @@
46
46
  ftruncate(i, s, r) {
47
47
  r(n());
48
48
  },
49
- lchown(i, s, r, a) {
50
- a(n());
49
+ lchown(i, s, r, c) {
50
+ c(n());
51
51
  },
52
52
  link(i, s, r) {
53
53
  r(n());
@@ -58,10 +58,10 @@
58
58
  mkdir(i, s, r) {
59
59
  r(n());
60
60
  },
61
- open(i, s, r, a) {
62
- a(n());
61
+ open(i, s, r, c) {
62
+ c(n());
63
63
  },
64
- read(i, s, r, a, y, u) {
64
+ read(i, s, r, c, y, u) {
65
65
  u(n());
66
66
  },
67
67
  readdir(i, s) {
@@ -88,8 +88,8 @@
88
88
  unlink(i, s) {
89
89
  s(n());
90
90
  },
91
- utimes(i, s, r, a) {
92
- a(n());
91
+ utimes(i, s, r, c) {
92
+ c(n());
93
93
  }
94
94
  };
95
95
  }
@@ -121,8 +121,8 @@
121
121
  throw n();
122
122
  }
123
123
  }), globalThis.path || (globalThis.path = {
124
- resolve(...c) {
125
- return c.join("/");
124
+ resolve(...l) {
125
+ return l.join("/");
126
126
  }
127
127
  }), !globalThis.crypto)
128
128
  throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");
@@ -132,7 +132,7 @@
132
132
  throw new Error("globalThis.TextEncoder is not available, polyfill required");
133
133
  if (!globalThis.TextDecoder)
134
134
  throw new Error("globalThis.TextDecoder is not available, polyfill required");
135
- const h = new TextEncoder("utf-8"), g = new TextDecoder("utf-8");
135
+ const h = new TextEncoder("utf-8"), d = new TextDecoder("utf-8");
136
136
  globalThis.Go = class {
137
137
  constructor() {
138
138
  this.argv = ["js"], this.env = {}, this.exit = (t) => {
@@ -140,7 +140,7 @@
140
140
  }, this._exitPromise = new Promise((t) => {
141
141
  this._resolveExitPromise = t;
142
142
  }), this._pendingEvent = null, this._scheduledTimeouts = /* @__PURE__ */ new Map(), this._nextCallbackTimeoutID = 1;
143
- const c = (t, e) => {
143
+ const l = (t, e) => {
144
144
  this.mem.setUint32(t + 0, e, !0), this.mem.setUint32(t + 4, Math.floor(e / 4294967296), !0);
145
145
  }, i = (t) => {
146
146
  const e = this.mem.getUint32(t + 0, !0), o = this.mem.getInt32(t + 4, !0);
@@ -166,8 +166,8 @@
166
166
  this.mem.setFloat64(t, 0, !0);
167
167
  return;
168
168
  }
169
- let l = this._ids.get(e);
170
- l === void 0 && (l = this._idPool.pop(), l === void 0 && (l = this._values.length), this._values[l] = e, this._goRefCounts[l] = 0, this._ids.set(e, l)), this._goRefCounts[l]++;
169
+ let a = this._ids.get(e);
170
+ a === void 0 && (a = this._idPool.pop(), a === void 0 && (a = this._values.length), this._values[a] = e, this._goRefCounts[a] = 0, this._ids.set(e, a)), this._goRefCounts[a]++;
171
171
  let m = 0;
172
172
  switch (typeof e) {
173
173
  case "object":
@@ -183,19 +183,19 @@
183
183
  m = 4;
184
184
  break;
185
185
  }
186
- this.mem.setUint32(t + 4, 2146959360 | m, !0), this.mem.setUint32(t, l, !0);
187
- }, a = (t) => {
186
+ this.mem.setUint32(t + 4, 2146959360 | m, !0), this.mem.setUint32(t, a, !0);
187
+ }, c = (t) => {
188
188
  const e = i(t + 0), o = i(t + 8);
189
189
  return new Uint8Array(this._inst.exports.mem.buffer, e, o);
190
190
  }, y = (t) => {
191
- const e = i(t + 0), o = i(t + 8), l = new Array(o);
191
+ const e = i(t + 0), o = i(t + 8), a = new Array(o);
192
192
  for (let m = 0; m < o; m++)
193
- l[m] = s(e + m * 8);
194
- return l;
193
+ a[m] = s(e + m * 8);
194
+ return a;
195
195
  }, u = (t) => {
196
196
  const e = i(t + 0), o = i(t + 8);
197
- return g.decode(new DataView(this._inst.exports.mem.buffer, e, o));
198
- }, w = (t, e) => (this._inst.exports.testExport0(), this._inst.exports.testExport(t, e)), d = Date.now() - performance.now();
197
+ return d.decode(new DataView(this._inst.exports.mem.buffer, e, o));
198
+ }, w = (t, e) => (this._inst.exports.testExport0(), this._inst.exports.testExport(t, e)), g = Date.now() - performance.now();
199
199
  this.importObject = {
200
200
  _gotest: {
201
201
  add: (t, e) => t + e,
@@ -215,8 +215,8 @@
215
215
  // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
216
216
  "runtime.wasmWrite": (t) => {
217
217
  t >>>= 0;
218
- const e = i(t + 8), o = i(t + 16), l = this.mem.getInt32(t + 24, !0);
219
- fs.writeSync(e, new Uint8Array(this._inst.exports.mem.buffer, o, l));
218
+ const e = i(t + 8), o = i(t + 16), a = this.mem.getInt32(t + 24, !0);
219
+ fs.writeSync(e, new Uint8Array(this._inst.exports.mem.buffer, o, a));
220
220
  },
221
221
  // func resetMemoryDataView()
222
222
  "runtime.resetMemoryDataView": (t) => {
@@ -224,13 +224,13 @@
224
224
  },
225
225
  // func nanotime1() int64
226
226
  "runtime.nanotime1": (t) => {
227
- t >>>= 0, c(t + 8, (d + performance.now()) * 1e6);
227
+ t >>>= 0, l(t + 8, (g + performance.now()) * 1e6);
228
228
  },
229
229
  // func walltime() (sec int64, nsec int32)
230
230
  "runtime.walltime": (t) => {
231
231
  t >>>= 0;
232
232
  const e = (/* @__PURE__ */ new Date()).getTime();
233
- c(t + 8, e / 1e3), this.mem.setInt32(t + 16, e % 1e3 * 1e6, !0);
233
+ l(t + 8, e / 1e3), this.mem.setInt32(t + 16, e % 1e3 * 1e6, !0);
234
234
  },
235
235
  // func scheduleTimeoutEvent(delay int64) int32
236
236
  "runtime.scheduleTimeoutEvent": (t) => {
@@ -252,7 +252,7 @@
252
252
  },
253
253
  // func getRandomData(r []byte)
254
254
  "runtime.getRandomData": (t) => {
255
- t >>>= 0, crypto.getRandomValues(a(t + 8));
255
+ t >>>= 0, crypto.getRandomValues(c(t + 8));
256
256
  },
257
257
  // func finalizeRef(v ref)
258
258
  "syscall/js.finalizeRef": (t) => {
@@ -293,7 +293,7 @@
293
293
  "syscall/js.valueCall": (t) => {
294
294
  t >>>= 0;
295
295
  try {
296
- const e = s(t + 8), o = Reflect.get(e, u(t + 16)), l = y(t + 32), m = Reflect.apply(o, e, l);
296
+ const e = s(t + 8), o = Reflect.get(e, u(t + 16)), a = y(t + 32), m = Reflect.apply(o, e, a);
297
297
  t = this._inst.exports.getsp() >>> 0, r(t + 56, m), this.mem.setUint8(t + 64, 1);
298
298
  } catch (e) {
299
299
  t = this._inst.exports.getsp() >>> 0, r(t + 56, e), this.mem.setUint8(t + 64, 0);
@@ -303,8 +303,8 @@
303
303
  "syscall/js.valueInvoke": (t) => {
304
304
  t >>>= 0;
305
305
  try {
306
- const e = s(t + 8), o = y(t + 16), l = Reflect.apply(e, void 0, o);
307
- t = this._inst.exports.getsp() >>> 0, r(t + 40, l), this.mem.setUint8(t + 48, 1);
306
+ const e = s(t + 8), o = y(t + 16), a = Reflect.apply(e, void 0, o);
307
+ t = this._inst.exports.getsp() >>> 0, r(t + 40, a), this.mem.setUint8(t + 48, 1);
308
308
  } catch (e) {
309
309
  t = this._inst.exports.getsp() >>> 0, r(t + 40, e), this.mem.setUint8(t + 48, 0);
310
310
  }
@@ -313,27 +313,27 @@
313
313
  "syscall/js.valueNew": (t) => {
314
314
  t >>>= 0;
315
315
  try {
316
- const e = s(t + 8), o = y(t + 16), l = Reflect.construct(e, o);
317
- t = this._inst.exports.getsp() >>> 0, r(t + 40, l), this.mem.setUint8(t + 48, 1);
316
+ const e = s(t + 8), o = y(t + 16), a = Reflect.construct(e, o);
317
+ t = this._inst.exports.getsp() >>> 0, r(t + 40, a), this.mem.setUint8(t + 48, 1);
318
318
  } catch (e) {
319
319
  t = this._inst.exports.getsp() >>> 0, r(t + 40, e), this.mem.setUint8(t + 48, 0);
320
320
  }
321
321
  },
322
322
  // func valueLength(v ref) int
323
323
  "syscall/js.valueLength": (t) => {
324
- t >>>= 0, c(t + 16, parseInt(s(t + 8).length));
324
+ t >>>= 0, l(t + 16, parseInt(s(t + 8).length));
325
325
  },
326
326
  // valuePrepareString(v ref) (ref, int)
327
327
  "syscall/js.valuePrepareString": (t) => {
328
328
  t >>>= 0;
329
329
  const e = h.encode(String(s(t + 8)));
330
- r(t + 16, e), c(t + 24, e.length);
330
+ r(t + 16, e), l(t + 24, e.length);
331
331
  },
332
332
  // valueLoadString(v ref, b []byte)
333
333
  "syscall/js.valueLoadString": (t) => {
334
334
  t >>>= 0;
335
335
  const e = s(t + 8);
336
- a(t + 16).set(e);
336
+ c(t + 16).set(e);
337
337
  },
338
338
  // func valueInstanceOf(v ref, t ref) bool
339
339
  "syscall/js.valueInstanceOf": (t) => {
@@ -342,24 +342,24 @@
342
342
  // func copyBytesToGo(dst []byte, src ref) (int, bool)
343
343
  "syscall/js.copyBytesToGo": (t) => {
344
344
  t >>>= 0;
345
- const e = a(t + 8), o = s(t + 32);
345
+ const e = c(t + 8), o = s(t + 32);
346
346
  if (!(o instanceof Uint8Array || o instanceof Uint8ClampedArray)) {
347
347
  this.mem.setUint8(t + 48, 0);
348
348
  return;
349
349
  }
350
- const l = o.subarray(0, e.length);
351
- e.set(l), c(t + 40, l.length), this.mem.setUint8(t + 48, 1);
350
+ const a = o.subarray(0, e.length);
351
+ e.set(a), l(t + 40, a.length), this.mem.setUint8(t + 48, 1);
352
352
  },
353
353
  // func copyBytesToJS(dst ref, src []byte) (int, bool)
354
354
  "syscall/js.copyBytesToJS": (t) => {
355
355
  t >>>= 0;
356
- const e = s(t + 8), o = a(t + 16);
356
+ const e = s(t + 8), o = c(t + 16);
357
357
  if (!(e instanceof Uint8Array || e instanceof Uint8ClampedArray)) {
358
358
  this.mem.setUint8(t + 48, 0);
359
359
  return;
360
360
  }
361
- const l = o.subarray(0, e.length);
362
- e.set(l), c(t + 40, l.length), this.mem.setUint8(t + 48, 1);
361
+ const a = o.subarray(0, e.length);
362
+ e.set(a), l(t + 40, a.length), this.mem.setUint8(t + 48, 1);
363
363
  },
364
364
  debug: (t) => {
365
365
  console.log(t);
@@ -367,10 +367,10 @@
367
367
  }
368
368
  };
369
369
  }
370
- async run(c) {
371
- if (!(c instanceof WebAssembly.Instance))
370
+ async run(l) {
371
+ if (!(l instanceof WebAssembly.Instance))
372
372
  throw new Error("Go.run: WebAssembly.Instance expected");
373
- this._inst = c, this.mem = new DataView(this._inst.exports.mem.buffer), this._values = [
373
+ this._inst = l, this.mem = new DataView(this._inst.exports.mem.buffer), this._values = [
374
374
  // JS values that Go currently has references to, indexed by reference id
375
375
  NaN,
376
376
  0,
@@ -389,18 +389,18 @@
389
389
  [this, 6]
390
390
  ]), this._idPool = [], this.exited = !1;
391
391
  let i = 4096;
392
- const s = (d) => {
393
- const t = i, e = h.encode(d + "\0");
392
+ const s = (g) => {
393
+ const t = i, e = h.encode(g + "\0");
394
394
  return new Uint8Array(this.mem.buffer, i, e.length).set(e), i += e.length, i % 8 !== 0 && (i += 8 - i % 8), t;
395
- }, r = this.argv.length, a = [];
396
- this.argv.forEach((d) => {
397
- a.push(s(d));
398
- }), a.push(0), Object.keys(this.env).sort().forEach((d) => {
399
- a.push(s(`${d}=${this.env[d]}`));
400
- }), a.push(0);
395
+ }, r = this.argv.length, c = [];
396
+ this.argv.forEach((g) => {
397
+ c.push(s(g));
398
+ }), c.push(0), Object.keys(this.env).sort().forEach((g) => {
399
+ c.push(s(`${g}=${this.env[g]}`));
400
+ }), c.push(0);
401
401
  const u = i;
402
- if (a.forEach((d) => {
403
- this.mem.setUint32(i, d, !0), this.mem.setUint32(i + 4, 0, !0), i += 8;
402
+ if (c.forEach((g) => {
403
+ this.mem.setUint32(i, g, !0), this.mem.setUint32(i + 4, 0, !0), i += 8;
404
404
  }), i >= 12288)
405
405
  throw new Error("total length of command line and environment variables exceeds limit");
406
406
  this._inst.exports.run(r, u), this.exited && this._resolveExitPromise(), await this._exitPromise;
@@ -410,25 +410,25 @@
410
410
  throw new Error("Go program has already exited");
411
411
  this._inst.exports.resume(), this.exited && this._resolveExitPromise();
412
412
  }
413
- _makeFuncWrapper(c) {
413
+ _makeFuncWrapper(l) {
414
414
  const i = this;
415
415
  return function() {
416
- const s = { id: c, this: this, args: arguments };
416
+ const s = { id: l, this: this, args: arguments };
417
417
  return i._pendingEvent = s, i._resume(), s.result;
418
418
  };
419
419
  }
420
420
  };
421
421
  })();
422
- const b = new URL("main.wasm", import.meta.url).href;
422
+ const x = new URL("main.wasm", import.meta.url).href;
423
423
  (() => {
424
424
  const n = globalThis, h = "process";
425
425
  n[h] ? n[h].pid == null && (n[h].pid = 1) : n[h] = { pid: 1 };
426
426
  })();
427
427
  let _ = !1;
428
- async function x() {
428
+ async function b() {
429
429
  if (_) return;
430
430
  const n = new globalThis.Go(), h = await WebAssembly.instantiateStreaming(
431
- fetch(b),
431
+ fetch(x),
432
432
  n.importObject
433
433
  );
434
434
  n.run(h.instance), _ = !0;
@@ -481,7 +481,7 @@ const p = {
481
481
  * })
482
482
  */
483
483
  async init(n = {}) {
484
- return await x(), f().init(n);
484
+ return await b(), f().init(n);
485
485
  },
486
486
  /**
487
487
  * Send an ICMP ping to addr and measure round-trip time.
@@ -515,12 +515,12 @@ const p = {
515
515
  async dialTCP(n) {
516
516
  const h = await f().dialTCP(n);
517
517
  return {
518
- onData(g) {
519
- h.onData(g);
518
+ onData(d) {
519
+ h.onData(d);
520
520
  },
521
- write(g) {
521
+ write(d) {
522
522
  h.write(
523
- typeof g == "string" ? new TextEncoder().encode(g) : g
523
+ typeof d == "string" ? new TextEncoder().encode(d) : d
524
524
  );
525
525
  },
526
526
  close() {
@@ -528,6 +528,48 @@ const p = {
528
528
  }
529
529
  };
530
530
  },
531
+ /**
532
+ * Listen for inbound TCP connections on the given Tailscale port.
533
+ * Pass port 0 (default) to get an ephemeral port assigned automatically.
534
+ * onConnection is called for each accepted connection.
535
+ * Returns a Listener with the assigned port number and a close() method.
536
+ *
537
+ * @example
538
+ * const listener = await network.listenTCP(8080, conn => {
539
+ * conn.onData(data => console.log(new TextDecoder().decode(data)))
540
+ * conn.write("hello\n")
541
+ * })
542
+ * console.log("listening on port", listener.port)
543
+ *
544
+ * @example
545
+ * // Ephemeral port
546
+ * const listener = await network.listenTCP(0, conn => { conn.close() })
547
+ * console.log("assigned port:", listener.port)
548
+ * listener.close()
549
+ */
550
+ async listenTCP(n = 0, h) {
551
+ const d = await f().listenTCP(n, (l) => {
552
+ h({
553
+ onData(i) {
554
+ l.onData(i);
555
+ },
556
+ write(i) {
557
+ l.write(
558
+ typeof i == "string" ? new TextEncoder().encode(i) : i
559
+ );
560
+ },
561
+ close() {
562
+ l.close();
563
+ }
564
+ });
565
+ });
566
+ return {
567
+ port: d.port,
568
+ close() {
569
+ d.close();
570
+ }
571
+ };
572
+ },
531
573
  /**
532
574
  * Make an HTTP request through the Tailscale network. Supports method,
533
575
  * headers, and body. Does not yet support AbortSignal, streaming bodies
@@ -1,2 +1,2 @@
1
- (function(w,_){typeof exports=="object"&&typeof module<"u"?_(exports):typeof define=="function"&&define.amd?define(["exports"],_):(w=typeof globalThis<"u"?globalThis:w||self,_(w["tailscale-web"]={}))})(this,(function(w){"use strict";(()=>{const n=()=>{const c=new Error("not implemented");return c.code="ENOSYS",c};if(!globalThis.fs){let c="";globalThis.fs={constants:{O_WRONLY:-1,O_RDWR:-1,O_CREAT:-1,O_TRUNC:-1,O_APPEND:-1,O_EXCL:-1,O_DIRECTORY:-1},writeSync(i,s){c+=g.decode(s);const r=c.lastIndexOf(`
2
- `);return r!=-1&&(console.log(c.substring(0,r)),c=c.substring(r+1)),s.length},write(i,s,r,a,y,h){if(r!==0||a!==s.length||y!==null){h(n());return}const b=this.writeSync(i,s);h(null,b)},chmod(i,s,r){r(n())},chown(i,s,r,a){a(n())},close(i,s){s(n())},fchmod(i,s,r){r(n())},fchown(i,s,r,a){a(n())},fstat(i,s){s(n())},fsync(i,s){s(null)},ftruncate(i,s,r){r(n())},lchown(i,s,r,a){a(n())},link(i,s,r){r(n())},lstat(i,s){s(n())},mkdir(i,s,r){r(n())},open(i,s,r,a){a(n())},read(i,s,r,a,y,h){h(n())},readdir(i,s){s(n())},readlink(i,s){s(n())},rename(i,s,r){r(n())},rmdir(i,s){s(n())},stat(i,s){s(n())},symlink(i,s,r){r(n())},truncate(i,s,r){r(n())},unlink(i,s){s(n())},utimes(i,s,r,a){a(n())}}}if(globalThis.process||(globalThis.process={getuid(){return-1},getgid(){return-1},geteuid(){return-1},getegid(){return-1},getgroups(){throw n()},pid:-1,ppid:-1,umask(){throw n()},cwd(){throw n()},chdir(){throw n()}}),globalThis.path||(globalThis.path={resolve(...c){return c.join("/")}}),!globalThis.crypto)throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");if(!globalThis.performance)throw new Error("globalThis.performance is not available, polyfill required (performance.now only)");if(!globalThis.TextEncoder)throw new Error("globalThis.TextEncoder is not available, polyfill required");if(!globalThis.TextDecoder)throw new Error("globalThis.TextDecoder is not available, polyfill required");const u=new TextEncoder("utf-8"),g=new TextDecoder("utf-8");globalThis.Go=class{constructor(){this.argv=["js"],this.env={},this.exit=t=>{t!==0&&console.warn("exit code:",t)},this._exitPromise=new Promise(t=>{this._resolveExitPromise=t}),this._pendingEvent=null,this._scheduledTimeouts=new Map,this._nextCallbackTimeoutID=1;const c=(t,e)=>{this.mem.setUint32(t+0,e,!0),this.mem.setUint32(t+4,Math.floor(e/4294967296),!0)},i=t=>{const e=this.mem.getUint32(t+0,!0),o=this.mem.getInt32(t+4,!0);return e+o*4294967296},s=t=>{const e=this.mem.getFloat64(t,!0);if(e===0)return;if(!isNaN(e))return e;const o=this.mem.getUint32(t,!0);return this._values[o]},r=(t,e)=>{if(typeof e=="number"&&e!==0){if(isNaN(e)){this.mem.setUint32(t+4,2146959360,!0),this.mem.setUint32(t,0,!0);return}this.mem.setFloat64(t,e,!0);return}if(e===void 0){this.mem.setFloat64(t,0,!0);return}let l=this._ids.get(e);l===void 0&&(l=this._idPool.pop(),l===void 0&&(l=this._values.length),this._values[l]=e,this._goRefCounts[l]=0,this._ids.set(e,l)),this._goRefCounts[l]++;let m=0;switch(typeof e){case"object":e!==null&&(m=1);break;case"string":m=2;break;case"symbol":m=3;break;case"function":m=4;break}this.mem.setUint32(t+4,2146959360|m,!0),this.mem.setUint32(t,l,!0)},a=t=>{const e=i(t+0),o=i(t+8);return new Uint8Array(this._inst.exports.mem.buffer,e,o)},y=t=>{const e=i(t+0),o=i(t+8),l=new Array(o);for(let m=0;m<o;m++)l[m]=s(e+m*8);return l},h=t=>{const e=i(t+0),o=i(t+8);return g.decode(new DataView(this._inst.exports.mem.buffer,e,o))},b=(t,e)=>(this._inst.exports.testExport0(),this._inst.exports.testExport(t,e)),f=Date.now()-performance.now();this.importObject={_gotest:{add:(t,e)=>t+e,callExport:b},gojs:{"runtime.wasmExit":t=>{t>>>=0;const e=this.mem.getInt32(t+8,!0);this.exited=!0,delete this._inst,delete this._values,delete this._goRefCounts,delete this._ids,delete this._idPool,this.exit(e)},"runtime.wasmWrite":t=>{t>>>=0;const e=i(t+8),o=i(t+16),l=this.mem.getInt32(t+24,!0);fs.writeSync(e,new Uint8Array(this._inst.exports.mem.buffer,o,l))},"runtime.resetMemoryDataView":t=>{this.mem=new DataView(this._inst.exports.mem.buffer)},"runtime.nanotime1":t=>{t>>>=0,c(t+8,(f+performance.now())*1e6)},"runtime.walltime":t=>{t>>>=0;const e=new Date().getTime();c(t+8,e/1e3),this.mem.setInt32(t+16,e%1e3*1e6,!0)},"runtime.scheduleTimeoutEvent":t=>{t>>>=0;const e=this._nextCallbackTimeoutID;this._nextCallbackTimeoutID++,this._scheduledTimeouts.set(e,setTimeout(()=>{for(this._resume();this._scheduledTimeouts.has(e);)console.warn("scheduleTimeoutEvent: missed timeout event"),this._resume()},i(t+8))),this.mem.setInt32(t+16,e,!0)},"runtime.clearTimeoutEvent":t=>{t>>>=0;const e=this.mem.getInt32(t+8,!0);clearTimeout(this._scheduledTimeouts.get(e)),this._scheduledTimeouts.delete(e)},"runtime.getRandomData":t=>{t>>>=0,crypto.getRandomValues(a(t+8))},"syscall/js.finalizeRef":t=>{t>>>=0;const e=this.mem.getUint32(t+8,!0);if(this._goRefCounts[e]--,this._goRefCounts[e]===0){const o=this._values[e];this._values[e]=null,this._ids.delete(o),this._idPool.push(e)}},"syscall/js.stringVal":t=>{t>>>=0,r(t+24,h(t+8))},"syscall/js.valueGet":t=>{t>>>=0;const e=Reflect.get(s(t+8),h(t+16));t=this._inst.exports.getsp()>>>0,r(t+32,e)},"syscall/js.valueSet":t=>{t>>>=0,Reflect.set(s(t+8),h(t+16),s(t+32))},"syscall/js.valueDelete":t=>{t>>>=0,Reflect.deleteProperty(s(t+8),h(t+16))},"syscall/js.valueIndex":t=>{t>>>=0,r(t+24,Reflect.get(s(t+8),i(t+16)))},"syscall/js.valueSetIndex":t=>{t>>>=0,Reflect.set(s(t+8),i(t+16),s(t+24))},"syscall/js.valueCall":t=>{t>>>=0;try{const e=s(t+8),o=Reflect.get(e,h(t+16)),l=y(t+32),m=Reflect.apply(o,e,l);t=this._inst.exports.getsp()>>>0,r(t+56,m),this.mem.setUint8(t+64,1)}catch(e){t=this._inst.exports.getsp()>>>0,r(t+56,e),this.mem.setUint8(t+64,0)}},"syscall/js.valueInvoke":t=>{t>>>=0;try{const e=s(t+8),o=y(t+16),l=Reflect.apply(e,void 0,o);t=this._inst.exports.getsp()>>>0,r(t+40,l),this.mem.setUint8(t+48,1)}catch(e){t=this._inst.exports.getsp()>>>0,r(t+40,e),this.mem.setUint8(t+48,0)}},"syscall/js.valueNew":t=>{t>>>=0;try{const e=s(t+8),o=y(t+16),l=Reflect.construct(e,o);t=this._inst.exports.getsp()>>>0,r(t+40,l),this.mem.setUint8(t+48,1)}catch(e){t=this._inst.exports.getsp()>>>0,r(t+40,e),this.mem.setUint8(t+48,0)}},"syscall/js.valueLength":t=>{t>>>=0,c(t+16,parseInt(s(t+8).length))},"syscall/js.valuePrepareString":t=>{t>>>=0;const e=u.encode(String(s(t+8)));r(t+16,e),c(t+24,e.length)},"syscall/js.valueLoadString":t=>{t>>>=0;const e=s(t+8);a(t+16).set(e)},"syscall/js.valueInstanceOf":t=>{t>>>=0,this.mem.setUint8(t+24,s(t+8)instanceof s(t+16)?1:0)},"syscall/js.copyBytesToGo":t=>{t>>>=0;const e=a(t+8),o=s(t+32);if(!(o instanceof Uint8Array||o instanceof Uint8ClampedArray)){this.mem.setUint8(t+48,0);return}const l=o.subarray(0,e.length);e.set(l),c(t+40,l.length),this.mem.setUint8(t+48,1)},"syscall/js.copyBytesToJS":t=>{t>>>=0;const e=s(t+8),o=a(t+16);if(!(e instanceof Uint8Array||e instanceof Uint8ClampedArray)){this.mem.setUint8(t+48,0);return}const l=o.subarray(0,e.length);e.set(l),c(t+40,l.length),this.mem.setUint8(t+48,1)},debug:t=>{console.log(t)}}}}async run(c){if(!(c instanceof WebAssembly.Instance))throw new Error("Go.run: WebAssembly.Instance expected");this._inst=c,this.mem=new DataView(this._inst.exports.mem.buffer),this._values=[NaN,0,null,!0,!1,globalThis,this],this._goRefCounts=new Array(this._values.length).fill(1/0),this._ids=new Map([[0,1],[null,2],[!0,3],[!1,4],[globalThis,5],[this,6]]),this._idPool=[],this.exited=!1;let i=4096;const s=f=>{const t=i,e=u.encode(f+"\0");return new Uint8Array(this.mem.buffer,i,e.length).set(e),i+=e.length,i%8!==0&&(i+=8-i%8),t},r=this.argv.length,a=[];this.argv.forEach(f=>{a.push(s(f))}),a.push(0),Object.keys(this.env).sort().forEach(f=>{a.push(s(`${f}=${this.env[f]}`))}),a.push(0);const h=i;if(a.forEach(f=>{this.mem.setUint32(i,f,!0),this.mem.setUint32(i+4,0,!0),i+=8}),i>=12288)throw new Error("total length of command line and environment variables exceeds limit");this._inst.exports.run(r,h),this.exited&&this._resolveExitPromise(),await this._exitPromise}_resume(){if(this.exited)throw new Error("Go program has already exited");this._inst.exports.resume(),this.exited&&this._resolveExitPromise()}_makeFuncWrapper(c){const i=this;return function(){const s={id:c,this:this,args:arguments};return i._pendingEvent=s,i._resume(),s.result}}}})();const _=typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__dirname+"/main.wasm").href:new URL("main.wasm",typeof document>"u"?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href;(()=>{const n=globalThis,u="process";n[u]?n[u].pid==null&&(n[u].pid=1):n[u]={pid:1}})();let x=!1;async function p(){if(x)return;const n=new globalThis.Go,u=await WebAssembly.instantiateStreaming(fetch(_),n.importObject);n.run(u.instance),x=!0}function d(){return globalThis.__tailscaleWeb}function T(n){return{status:n.status,statusText:n.statusText,ok:n.ok,headers:n.headers,text:async()=>new TextDecoder().decode(n.body),json:async()=>JSON.parse(new TextDecoder().decode(n.body)),arrayBuffer:async()=>n.body.buffer,bytes:async()=>n.body}}const v={async init(n={}){return await p(),d().init(n)},async ping(n){return d().ping(n)},async dialTCP(n){const u=await d().dialTCP(n);return{onData(g){u.onData(g)},write(g){u.write(typeof g=="string"?new TextEncoder().encode(g):g)},close(){u.close()}}},async fetch(n,u={}){return T(await d().fetch(n,u))},getPrefs(){return d().getPrefs()},async setAcceptRoutes(n){return d().setAcceptRoutes(n)},listExitNodes(){return Array.from(d().listExitNodes())},async setExitNode(n=""){return d().setExitNode(n)},getRoutes(){return Array.from(d().getRoutes())},getDNS(){return d().getDNS()}};w.network=v,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(w,_){typeof exports=="object"&&typeof module<"u"?_(exports):typeof define=="function"&&define.amd?define(["exports"],_):(w=typeof globalThis<"u"?globalThis:w||self,_(w["tailscale-web"]={}))})(this,(function(w){"use strict";(()=>{const n=()=>{const l=new Error("not implemented");return l.code="ENOSYS",l};if(!globalThis.fs){let l="";globalThis.fs={constants:{O_WRONLY:-1,O_RDWR:-1,O_CREAT:-1,O_TRUNC:-1,O_APPEND:-1,O_EXCL:-1,O_DIRECTORY:-1},writeSync(i,s){l+=f.decode(s);const r=l.lastIndexOf(`
2
+ `);return r!=-1&&(console.log(l.substring(0,r)),l=l.substring(r+1)),s.length},write(i,s,r,c,y,h){if(r!==0||c!==s.length||y!==null){h(n());return}const b=this.writeSync(i,s);h(null,b)},chmod(i,s,r){r(n())},chown(i,s,r,c){c(n())},close(i,s){s(n())},fchmod(i,s,r){r(n())},fchown(i,s,r,c){c(n())},fstat(i,s){s(n())},fsync(i,s){s(null)},ftruncate(i,s,r){r(n())},lchown(i,s,r,c){c(n())},link(i,s,r){r(n())},lstat(i,s){s(n())},mkdir(i,s,r){r(n())},open(i,s,r,c){c(n())},read(i,s,r,c,y,h){h(n())},readdir(i,s){s(n())},readlink(i,s){s(n())},rename(i,s,r){r(n())},rmdir(i,s){s(n())},stat(i,s){s(n())},symlink(i,s,r){r(n())},truncate(i,s,r){r(n())},unlink(i,s){s(n())},utimes(i,s,r,c){c(n())}}}if(globalThis.process||(globalThis.process={getuid(){return-1},getgid(){return-1},geteuid(){return-1},getegid(){return-1},getgroups(){throw n()},pid:-1,ppid:-1,umask(){throw n()},cwd(){throw n()},chdir(){throw n()}}),globalThis.path||(globalThis.path={resolve(...l){return l.join("/")}}),!globalThis.crypto)throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");if(!globalThis.performance)throw new Error("globalThis.performance is not available, polyfill required (performance.now only)");if(!globalThis.TextEncoder)throw new Error("globalThis.TextEncoder is not available, polyfill required");if(!globalThis.TextDecoder)throw new Error("globalThis.TextDecoder is not available, polyfill required");const u=new TextEncoder("utf-8"),f=new TextDecoder("utf-8");globalThis.Go=class{constructor(){this.argv=["js"],this.env={},this.exit=t=>{t!==0&&console.warn("exit code:",t)},this._exitPromise=new Promise(t=>{this._resolveExitPromise=t}),this._pendingEvent=null,this._scheduledTimeouts=new Map,this._nextCallbackTimeoutID=1;const l=(t,e)=>{this.mem.setUint32(t+0,e,!0),this.mem.setUint32(t+4,Math.floor(e/4294967296),!0)},i=t=>{const e=this.mem.getUint32(t+0,!0),o=this.mem.getInt32(t+4,!0);return e+o*4294967296},s=t=>{const e=this.mem.getFloat64(t,!0);if(e===0)return;if(!isNaN(e))return e;const o=this.mem.getUint32(t,!0);return this._values[o]},r=(t,e)=>{if(typeof e=="number"&&e!==0){if(isNaN(e)){this.mem.setUint32(t+4,2146959360,!0),this.mem.setUint32(t,0,!0);return}this.mem.setFloat64(t,e,!0);return}if(e===void 0){this.mem.setFloat64(t,0,!0);return}let a=this._ids.get(e);a===void 0&&(a=this._idPool.pop(),a===void 0&&(a=this._values.length),this._values[a]=e,this._goRefCounts[a]=0,this._ids.set(e,a)),this._goRefCounts[a]++;let m=0;switch(typeof e){case"object":e!==null&&(m=1);break;case"string":m=2;break;case"symbol":m=3;break;case"function":m=4;break}this.mem.setUint32(t+4,2146959360|m,!0),this.mem.setUint32(t,a,!0)},c=t=>{const e=i(t+0),o=i(t+8);return new Uint8Array(this._inst.exports.mem.buffer,e,o)},y=t=>{const e=i(t+0),o=i(t+8),a=new Array(o);for(let m=0;m<o;m++)a[m]=s(e+m*8);return a},h=t=>{const e=i(t+0),o=i(t+8);return f.decode(new DataView(this._inst.exports.mem.buffer,e,o))},b=(t,e)=>(this._inst.exports.testExport0(),this._inst.exports.testExport(t,e)),g=Date.now()-performance.now();this.importObject={_gotest:{add:(t,e)=>t+e,callExport:b},gojs:{"runtime.wasmExit":t=>{t>>>=0;const e=this.mem.getInt32(t+8,!0);this.exited=!0,delete this._inst,delete this._values,delete this._goRefCounts,delete this._ids,delete this._idPool,this.exit(e)},"runtime.wasmWrite":t=>{t>>>=0;const e=i(t+8),o=i(t+16),a=this.mem.getInt32(t+24,!0);fs.writeSync(e,new Uint8Array(this._inst.exports.mem.buffer,o,a))},"runtime.resetMemoryDataView":t=>{this.mem=new DataView(this._inst.exports.mem.buffer)},"runtime.nanotime1":t=>{t>>>=0,l(t+8,(g+performance.now())*1e6)},"runtime.walltime":t=>{t>>>=0;const e=new Date().getTime();l(t+8,e/1e3),this.mem.setInt32(t+16,e%1e3*1e6,!0)},"runtime.scheduleTimeoutEvent":t=>{t>>>=0;const e=this._nextCallbackTimeoutID;this._nextCallbackTimeoutID++,this._scheduledTimeouts.set(e,setTimeout(()=>{for(this._resume();this._scheduledTimeouts.has(e);)console.warn("scheduleTimeoutEvent: missed timeout event"),this._resume()},i(t+8))),this.mem.setInt32(t+16,e,!0)},"runtime.clearTimeoutEvent":t=>{t>>>=0;const e=this.mem.getInt32(t+8,!0);clearTimeout(this._scheduledTimeouts.get(e)),this._scheduledTimeouts.delete(e)},"runtime.getRandomData":t=>{t>>>=0,crypto.getRandomValues(c(t+8))},"syscall/js.finalizeRef":t=>{t>>>=0;const e=this.mem.getUint32(t+8,!0);if(this._goRefCounts[e]--,this._goRefCounts[e]===0){const o=this._values[e];this._values[e]=null,this._ids.delete(o),this._idPool.push(e)}},"syscall/js.stringVal":t=>{t>>>=0,r(t+24,h(t+8))},"syscall/js.valueGet":t=>{t>>>=0;const e=Reflect.get(s(t+8),h(t+16));t=this._inst.exports.getsp()>>>0,r(t+32,e)},"syscall/js.valueSet":t=>{t>>>=0,Reflect.set(s(t+8),h(t+16),s(t+32))},"syscall/js.valueDelete":t=>{t>>>=0,Reflect.deleteProperty(s(t+8),h(t+16))},"syscall/js.valueIndex":t=>{t>>>=0,r(t+24,Reflect.get(s(t+8),i(t+16)))},"syscall/js.valueSetIndex":t=>{t>>>=0,Reflect.set(s(t+8),i(t+16),s(t+24))},"syscall/js.valueCall":t=>{t>>>=0;try{const e=s(t+8),o=Reflect.get(e,h(t+16)),a=y(t+32),m=Reflect.apply(o,e,a);t=this._inst.exports.getsp()>>>0,r(t+56,m),this.mem.setUint8(t+64,1)}catch(e){t=this._inst.exports.getsp()>>>0,r(t+56,e),this.mem.setUint8(t+64,0)}},"syscall/js.valueInvoke":t=>{t>>>=0;try{const e=s(t+8),o=y(t+16),a=Reflect.apply(e,void 0,o);t=this._inst.exports.getsp()>>>0,r(t+40,a),this.mem.setUint8(t+48,1)}catch(e){t=this._inst.exports.getsp()>>>0,r(t+40,e),this.mem.setUint8(t+48,0)}},"syscall/js.valueNew":t=>{t>>>=0;try{const e=s(t+8),o=y(t+16),a=Reflect.construct(e,o);t=this._inst.exports.getsp()>>>0,r(t+40,a),this.mem.setUint8(t+48,1)}catch(e){t=this._inst.exports.getsp()>>>0,r(t+40,e),this.mem.setUint8(t+48,0)}},"syscall/js.valueLength":t=>{t>>>=0,l(t+16,parseInt(s(t+8).length))},"syscall/js.valuePrepareString":t=>{t>>>=0;const e=u.encode(String(s(t+8)));r(t+16,e),l(t+24,e.length)},"syscall/js.valueLoadString":t=>{t>>>=0;const e=s(t+8);c(t+16).set(e)},"syscall/js.valueInstanceOf":t=>{t>>>=0,this.mem.setUint8(t+24,s(t+8)instanceof s(t+16)?1:0)},"syscall/js.copyBytesToGo":t=>{t>>>=0;const e=c(t+8),o=s(t+32);if(!(o instanceof Uint8Array||o instanceof Uint8ClampedArray)){this.mem.setUint8(t+48,0);return}const a=o.subarray(0,e.length);e.set(a),l(t+40,a.length),this.mem.setUint8(t+48,1)},"syscall/js.copyBytesToJS":t=>{t>>>=0;const e=s(t+8),o=c(t+16);if(!(e instanceof Uint8Array||e instanceof Uint8ClampedArray)){this.mem.setUint8(t+48,0);return}const a=o.subarray(0,e.length);e.set(a),l(t+40,a.length),this.mem.setUint8(t+48,1)},debug:t=>{console.log(t)}}}}async run(l){if(!(l instanceof WebAssembly.Instance))throw new Error("Go.run: WebAssembly.Instance expected");this._inst=l,this.mem=new DataView(this._inst.exports.mem.buffer),this._values=[NaN,0,null,!0,!1,globalThis,this],this._goRefCounts=new Array(this._values.length).fill(1/0),this._ids=new Map([[0,1],[null,2],[!0,3],[!1,4],[globalThis,5],[this,6]]),this._idPool=[],this.exited=!1;let i=4096;const s=g=>{const t=i,e=u.encode(g+"\0");return new Uint8Array(this.mem.buffer,i,e.length).set(e),i+=e.length,i%8!==0&&(i+=8-i%8),t},r=this.argv.length,c=[];this.argv.forEach(g=>{c.push(s(g))}),c.push(0),Object.keys(this.env).sort().forEach(g=>{c.push(s(`${g}=${this.env[g]}`))}),c.push(0);const h=i;if(c.forEach(g=>{this.mem.setUint32(i,g,!0),this.mem.setUint32(i+4,0,!0),i+=8}),i>=12288)throw new Error("total length of command line and environment variables exceeds limit");this._inst.exports.run(r,h),this.exited&&this._resolveExitPromise(),await this._exitPromise}_resume(){if(this.exited)throw new Error("Go program has already exited");this._inst.exports.resume(),this.exited&&this._resolveExitPromise()}_makeFuncWrapper(l){const i=this;return function(){const s={id:l,this:this,args:arguments};return i._pendingEvent=s,i._resume(),s.result}}}})();const _=typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__dirname+"/main.wasm").href:new URL("main.wasm",typeof document>"u"?location.href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href;(()=>{const n=globalThis,u="process";n[u]?n[u].pid==null&&(n[u].pid=1):n[u]={pid:1}})();let x=!1;async function p(){if(x)return;const n=new globalThis.Go,u=await WebAssembly.instantiateStreaming(fetch(_),n.importObject);n.run(u.instance),x=!0}function d(){return globalThis.__tailscaleWeb}function T(n){return{status:n.status,statusText:n.statusText,ok:n.ok,headers:n.headers,text:async()=>new TextDecoder().decode(n.body),json:async()=>JSON.parse(new TextDecoder().decode(n.body)),arrayBuffer:async()=>n.body.buffer,bytes:async()=>n.body}}const v={async init(n={}){return await p(),d().init(n)},async ping(n){return d().ping(n)},async dialTCP(n){const u=await d().dialTCP(n);return{onData(f){u.onData(f)},write(f){u.write(typeof f=="string"?new TextEncoder().encode(f):f)},close(){u.close()}}},async listenTCP(n=0,u){const f=await d().listenTCP(n,l=>{u({onData(i){l.onData(i)},write(i){l.write(typeof i=="string"?new TextEncoder().encode(i):i)},close(){l.close()}})});return{port:f.port,close(){f.close()}}},async fetch(n,u={}){return T(await d().fetch(n,u))},getPrefs(){return d().getPrefs()},async setAcceptRoutes(n){return d().setAcceptRoutes(n)},listExitNodes(){return Array.from(d().listExitNodes())},async setExitNode(n=""){return d().setExitNode(n)},getRoutes(){return Array.from(d().getRoutes())},getDNS(){return d().getDNS()}};w.network=v,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailscale-web",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "Run a Tailscale node in JS environments via WebAssembly",
5
5
  "type": "module",
6
6
  "main": "./dist/tailscale-web.umd.js",