@ai-ecoverse/slicc-kernel 1.44.0 → 1.46.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.
@@ -1594,6 +1594,9 @@ var KernelSocket = class _KernelSocket {
1594
1594
  get listening() {
1595
1595
  return this.state === "listening";
1596
1596
  }
1597
+ get unconnected() {
1598
+ return this.state === "open" || this.state === "listening";
1599
+ }
1597
1600
  connection() {
1598
1601
  if (!this.link || this.state !== "connected") throw new KernelError("ENOTCONN");
1599
1602
  return this.link;
@@ -1920,8 +1923,8 @@ function serveSocket(socket, port, onClose) {
1920
1923
  let writes = Promise.resolve();
1921
1924
  let credit = 0;
1922
1925
  let granted2;
1923
- const send = (message2, transfer) => {
1924
- if (!closed) port.postMessage(message2, transfer);
1926
+ const send = (message3, transfer) => {
1927
+ if (!closed) port.postMessage(message3, transfer);
1925
1928
  };
1926
1929
  const close = (reset = false) => {
1927
1930
  if (closed) return;
@@ -2036,8 +2039,8 @@ var BODY_IDLE_MS = 5 * 60 * 1e3;
2036
2039
  var INBOUND_LIMIT = 16 * 1024 * 1024;
2037
2040
  var MESSAGE_LIMIT = 64 * 1024 * 1024;
2038
2041
  var TOO_BIG = 1009;
2039
- function payloadSize(message2) {
2040
- return typeof message2 === "string" ? new TextEncoder().encode(message2).length : message2.length;
2042
+ function payloadSize(message3) {
2043
+ return typeof message3 === "string" ? new TextEncoder().encode(message3).length : message3.length;
2041
2044
  }
2042
2045
  var MessageQueue = class {
2043
2046
  items = [];
@@ -2057,9 +2060,9 @@ var MessageQueue = class {
2057
2060
  this.settle = resolve;
2058
2061
  });
2059
2062
  }
2060
- push(message2) {
2063
+ push(message3) {
2061
2064
  if (this.ended) return;
2062
- const size = payloadSize(message2);
2065
+ const size = payloadSize(message3);
2063
2066
  const huge = size > MESSAGE_LIMIT;
2064
2067
  if (huge || this.items.length > 0 && this.size + size > this.limit) {
2065
2068
  const reason = huge ? `a message is over ${MESSAGE_LIMIT} bytes` : `over ${this.limit} bytes of messages are waiting`;
@@ -2068,7 +2071,7 @@ var MessageQueue = class {
2068
2071
  return;
2069
2072
  }
2070
2073
  this.size += size;
2071
- this.items.push(message2);
2074
+ this.items.push(message3);
2072
2075
  this.wake();
2073
2076
  }
2074
2077
  end(close) {
@@ -2107,7 +2110,7 @@ var NO_WEBSOCKET = "WebSocket not supported by this transport (fetchTransport ne
2107
2110
  var MAX_REQUEST_BODY = 64 * 1024 * 1024;
2108
2111
  function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
2109
2112
  const open = /* @__PURE__ */ new Map();
2110
- const fail = (nid, e) => {
2113
+ const fail2 = (nid, e) => {
2111
2114
  open.delete(nid);
2112
2115
  const { status, code } = e;
2113
2116
  peer.postMessage({
@@ -2138,12 +2141,13 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
2138
2141
  peer.postMessage({
2139
2142
  net: "head",
2140
2143
  nid: call.nid,
2144
+ ...response.redirected ? { url: response.url, redirected: true } : {},
2141
2145
  status: response.status,
2142
2146
  statusText: response.statusText,
2143
2147
  headers: response.headers
2144
2148
  });
2145
2149
  } catch (e) {
2146
- fail(call.nid, e);
2150
+ fail2(call.nid, e);
2147
2151
  }
2148
2152
  };
2149
2153
  const sockets = /* @__PURE__ */ new Map();
@@ -2177,7 +2181,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
2177
2181
  peer.postMessage({ net: "ws-opened", nid: call.nid, protocol: socket.protocol });
2178
2182
  void relay(call.nid, socket);
2179
2183
  } catch (e) {
2180
- fail(call.nid, e);
2184
+ fail2(call.nid, e);
2181
2185
  }
2182
2186
  };
2183
2187
  const relay = async (nid, socket) => {
@@ -2249,7 +2253,7 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
2249
2253
  peer.postMessage({ net: "chunk", nid, bytes }, [bytes.buffer]);
2250
2254
  }
2251
2255
  } catch (e) {
2252
- fail(nid, e);
2256
+ fail2(nid, e);
2253
2257
  }
2254
2258
  };
2255
2259
  const drop = (nid) => {
@@ -2726,8 +2730,8 @@ function serveClient(port, host) {
2726
2730
  const watches = /* @__PURE__ */ new Map();
2727
2731
  let net;
2728
2732
  const ended = Promise.withResolvers();
2729
- const send = (message2, transfer = []) => {
2730
- if (state !== "closed") port.postMessage(message2, transfer);
2733
+ const send = (message3, transfer = []) => {
2734
+ if (state !== "closed") port.postMessage(message3, transfer);
2731
2735
  };
2732
2736
  const reply = (id2, body, transfer) => send({ id: id2, ...body }, transfer);
2733
2737
  const cdps = cdpRegistry(send, ended.promise);
@@ -2746,8 +2750,8 @@ function serveClient(port, host) {
2746
2750
  port.close?.();
2747
2751
  ended.resolve();
2748
2752
  }
2749
- async function hello(message2) {
2750
- const refused = versionError(message2.protocol);
2753
+ async function hello(message3) {
2754
+ const refused = versionError(message3.protocol);
2751
2755
  if (refused) {
2752
2756
  send({ hello: { protocol: PROTOCOL, error: refused } });
2753
2757
  detach();
@@ -2758,7 +2762,7 @@ function serveClient(port, host) {
2758
2762
  const transport = host.transport?.() ?? launcher.transport;
2759
2763
  net = serveTransport({ postMessage: (m, t) => send(m, t) }, transport);
2760
2764
  state = "open";
2761
- if (message2.lock && host.locks) void host.locks.request(message2.lock, () => detach());
2765
+ if (message3.lock && host.locks) void host.locks.request(message3.lock, () => detach());
2762
2766
  send({
2763
2767
  hello: {
2764
2768
  protocol: PROTOCOL,
@@ -2918,8 +2922,8 @@ function ownNames(hostname) {
2918
2922
  // src/kernel/net/http1.ts
2919
2923
  var HttpError = class extends Error {
2920
2924
  status;
2921
- constructor(status, message2) {
2922
- super(message2);
2925
+ constructor(status, message3) {
2926
+ super(message3);
2923
2927
  this.status = status;
2924
2928
  }
2925
2929
  };
@@ -3182,8 +3186,8 @@ var OP = {
3182
3186
  };
3183
3187
  var WsError = class extends Error {
3184
3188
  code;
3185
- constructor(code, message2) {
3186
- super(message2);
3189
+ constructor(code, message3) {
3190
+ super(message3);
3187
3191
  this.code = code;
3188
3192
  }
3189
3193
  };
@@ -3549,8 +3553,8 @@ function untilAborted(response, signal) {
3549
3553
  response.then(resolve, reject).finally(() => signal.removeEventListener("abort", onAbort));
3550
3554
  });
3551
3555
  }
3552
- function plainResponse(status, message2) {
3553
- const body = latin1Bytes(`slicc realm proxy: ${message2}
3556
+ function plainResponse(status, message3) {
3557
+ const body = latin1Bytes(`slicc realm proxy: ${message3}
3554
3558
  `);
3555
3559
  return {
3556
3560
  status,
@@ -3732,10 +3736,10 @@ var RealmProxy = class {
3732
3736
  return await untilAborted(fetching, signal);
3733
3737
  } catch (e) {
3734
3738
  if (signal.aborted) throw e;
3735
- const message2 = e instanceof Error ? e.message : String(e);
3739
+ const message3 = e instanceof Error ? e.message : String(e);
3736
3740
  const status = e?.status;
3737
3741
  const own = typeof status === "number" && status >= 400 && status <= 599 ? status : 502;
3738
- return plainResponse(own, message2 || "upstream request failed");
3742
+ return plainResponse(own, message3 || "upstream request failed");
3739
3743
  }
3740
3744
  }
3741
3745
  async relay(conn, method, minor, response, keepAlive) {
@@ -4240,8 +4244,8 @@ var SCRATCH = 64 * 1024;
4240
4244
  var EOF = -1;
4241
4245
  var TlsError = class extends Error {
4242
4246
  code;
4243
- constructor(code, message2) {
4244
- super(message2);
4247
+ constructor(code, message3) {
4248
+ super(message3);
4245
4249
  this.code = code;
4246
4250
  }
4247
4251
  };
@@ -4630,8 +4634,8 @@ function enableNetwork(net, options) {
4630
4634
  var TransportError = class extends Error {
4631
4635
  status;
4632
4636
  code;
4633
- constructor(message2, status, code) {
4634
- super(message2);
4637
+ constructor(message3, status, code) {
4638
+ super(message3);
4635
4639
  this.status = status;
4636
4640
  this.code = code;
4637
4641
  }
@@ -4716,7 +4720,7 @@ var RemoteTransport = class {
4716
4720
  finish();
4717
4721
  throw e;
4718
4722
  }
4719
- const { status, statusText, headers } = head;
4723
+ const { status, statusText, headers, url, redirected } = head;
4720
4724
  const read = async () => {
4721
4725
  if (finished) return void 0;
4722
4726
  const reply = await this.ask({ net: "read", nid }).catch((e) => {
@@ -4733,6 +4737,7 @@ var RemoteTransport = class {
4733
4737
  this.cancel(nid);
4734
4738
  };
4735
4739
  return {
4740
+ ...redirected ? { url, redirected } : {},
4736
4741
  status,
4737
4742
  statusText,
4738
4743
  headers,
@@ -5089,8 +5094,8 @@ var CdpFacade = class {
5089
5094
  clearTimeout(timer);
5090
5095
  reject(new HttpError(502, `the CDP host closed: ${reason ?? "no reason"}`));
5091
5096
  };
5092
- conn.onmessage = (message2) => {
5093
- const parsed2 = JSON.parse(message2);
5097
+ conn.onmessage = (message3) => {
5098
+ const parsed2 = JSON.parse(message3);
5094
5099
  if (parsed2.id !== 1) return;
5095
5100
  clearTimeout(timer);
5096
5101
  resolve(parsed2);
@@ -5158,9 +5163,9 @@ var Relay = class {
5158
5163
  void this.end(reason ? CLOSE.error : CLOSE.normal, reason ?? "").then(() => resolve());
5159
5164
  };
5160
5165
  });
5161
- this.host.onmessage = (message2) => {
5166
+ this.host.onmessage = (message3) => {
5162
5167
  if (this.ended) return;
5163
- const bytes = new TextEncoder().encode(message2);
5168
+ const bytes = new TextEncoder().encode(message3);
5164
5169
  if (bytes.length > this.max)
5165
5170
  void this.end(CLOSE.tooBig, `a message is over ${this.max} bytes`);
5166
5171
  else void this.send(frame(OP_TEXT, bytes));
@@ -5939,10 +5944,10 @@ var SpawnError = class extends Error {
5939
5944
  };
5940
5945
  function interrupted(signal) {
5941
5946
  const { promise, reject } = Promise.withResolvers();
5942
- const fail = () => reject(new KernelError("EINTR"));
5943
- if (signal?.aborted) fail();
5944
- else signal?.addEventListener("abort", fail, { once: true });
5945
- return { promise, done: () => signal?.removeEventListener("abort", fail) };
5947
+ const fail2 = () => reject(new KernelError("EINTR"));
5948
+ if (signal?.aborted) fail2();
5949
+ else signal?.addEventListener("abort", fail2, { once: true });
5950
+ return { promise, done: () => signal?.removeEventListener("abort", fail2) };
5946
5951
  }
5947
5952
  function stoppedStatus(sig) {
5948
5953
  return (sig & 255) << 8 | 127;
@@ -6133,8 +6138,8 @@ function unref(timer) {
6133
6138
  timer.unref?.();
6134
6139
  return timer;
6135
6140
  }
6136
- function errnoError(code, message2) {
6137
- return Object.assign(new Error(`${code}: ${message2}`), { code });
6141
+ function errnoError(code, message3) {
6142
+ return Object.assign(new Error(`${code}: ${message3}`), { code });
6138
6143
  }
6139
6144
  var DriverConnection = class _DriverConnection {
6140
6145
  capabilities;
@@ -7116,12 +7121,12 @@ function syncError(code, label) {
7116
7121
 
7117
7122
  // src/realm/sync-fs-dispatch.ts
7118
7123
  function toErrno(err) {
7119
- const message2 = err instanceof Error ? err.message : String(err);
7124
+ const message3 = err instanceof Error ? err.message : String(err);
7120
7125
  const code = err?.code;
7121
7126
  if (typeof code === "string" && /^E[A-Z]+$/.test(code)) {
7122
- return { ok: false, errno: code, message: message2 };
7127
+ return { ok: false, errno: code, message: message3 };
7123
7128
  }
7124
- return { ok: false, errno: "EIO", message: message2 };
7129
+ return { ok: false, errno: "EIO", message: message3 };
7125
7130
  }
7126
7131
  function statJson(s) {
7127
7132
  return {
@@ -7602,10 +7607,135 @@ async function hostSyscall(req, ctx) {
7602
7607
  }
7603
7608
  }
7604
7609
 
7610
+ // src/kernel/net/ws-syscalls.ts
7611
+ var WS_OPS = [
7612
+ "net-ws-open",
7613
+ "net-ws-ready",
7614
+ "net-ws-recv",
7615
+ "net-ws-wait",
7616
+ "net-ws-send",
7617
+ "net-ws-close"
7618
+ ];
7619
+ var TOKEN3 = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
7620
+ function message(e) {
7621
+ return e instanceof Error ? e.message : String(e);
7622
+ }
7623
+ function fail(errno, text) {
7624
+ return { ok: false, errno, message: text };
7625
+ }
7626
+ var WsHandles = class {
7627
+ transport;
7628
+ open = /* @__PURE__ */ new Map();
7629
+ next;
7630
+ constructor(transport, next2) {
7631
+ this.transport = transport;
7632
+ this.next = next2;
7633
+ }
7634
+ owns(handle) {
7635
+ return this.open.has(handle);
7636
+ }
7637
+ syscall(req) {
7638
+ if (req.op === "net-ws-open") return Promise.resolve(this.start(req));
7639
+ const entry = this.open.get(req.handle);
7640
+ if (!entry) return Promise.resolve(fail("EBADF", `no websocket ${req.handle}`));
7641
+ if (req.op === "net-ws-ready") return entry.ready;
7642
+ if (!entry.socket) return Promise.resolve(fail("ENOTCONN", "websocket not open"));
7643
+ if (req.op === "net-ws-recv") return this.recv(entry.socket, entry);
7644
+ if (req.op === "net-ws-wait") return this.closed(entry.socket);
7645
+ if (req.op === "net-ws-send") return Promise.resolve(this.send(entry.socket, req, entry));
7646
+ entry.ended = true;
7647
+ entry.socket.close(req.code ?? 1e3, req.reason ?? "");
7648
+ return Promise.resolve({ ok: true, kind: "void" });
7649
+ }
7650
+ start(req) {
7651
+ const handle = this.next();
7652
+ const entry = {
7653
+ abort: new AbortController(),
7654
+ ready: Promise.resolve({ ok: true, kind: "void" })
7655
+ };
7656
+ this.open.set(handle, entry);
7657
+ entry.ready = this.connect(handle, req, entry);
7658
+ return { ok: true, kind: "json", json: handle };
7659
+ }
7660
+ async connect(handle, req, entry) {
7661
+ const { transport } = this;
7662
+ if (!transport.traits.websocket || !transport.websocket) return fail("ENOTSUP", NO_WEBSOCKET2);
7663
+ let socket;
7664
+ try {
7665
+ socket = await transport.websocket({
7666
+ url: req.url,
7667
+ protocols: req.protocols,
7668
+ headers: req.headers,
7669
+ signal: entry.abort.signal
7670
+ });
7671
+ } catch (e) {
7672
+ return fail("ECONNREFUSED", message(e));
7673
+ }
7674
+ if (!this.open.has(handle)) {
7675
+ socket.close(1001, "the program went away");
7676
+ return fail("EBADF", `no websocket ${handle}`);
7677
+ }
7678
+ if (socket.protocol && !(req.protocols.includes(socket.protocol) && TOKEN3.test(socket.protocol))) {
7679
+ socket.close(1002, "subprotocol not offered");
7680
+ return fail("EPROTO", "the far end chose a subprotocol the program did not offer");
7681
+ }
7682
+ entry.socket = socket;
7683
+ void socket.closed.then(() => {
7684
+ entry.ended = true;
7685
+ });
7686
+ entry.messages = socket.messages[Symbol.asyncIterator]();
7687
+ return { ok: true, kind: "json", json: { protocol: socket.protocol } };
7688
+ }
7689
+ async recv(socket, entry) {
7690
+ try {
7691
+ const next2 = await entry.messages.next();
7692
+ if (!next2.done) {
7693
+ return typeof next2.value === "string" ? { ok: true, kind: "json", json: { text: next2.value } } : { ok: true, kind: "bytes", bytes: next2.value };
7694
+ }
7695
+ const closed = await socket.closed;
7696
+ return { ok: true, kind: "json", json: { code: closed.code, reason: closed.reason } };
7697
+ } catch (e) {
7698
+ return fail("ECONNRESET", message(e));
7699
+ }
7700
+ }
7701
+ async closed(socket) {
7702
+ const { code, reason } = await socket.closed;
7703
+ return { ok: true, kind: "json", json: { code, reason } };
7704
+ }
7705
+ send(socket, req, entry) {
7706
+ const data = req.text ?? req.body;
7707
+ if (entry.ended) return fail("EPIPE", "the websocket is closed");
7708
+ try {
7709
+ if (data !== void 0) socket.send(data);
7710
+ } catch (e) {
7711
+ return fail("EPIPE", message(e));
7712
+ }
7713
+ return { ok: true, kind: "json", json: socket.buffered };
7714
+ }
7715
+ close(handle) {
7716
+ const entry = this.open.get(handle);
7717
+ if (!entry) return;
7718
+ this.open.delete(handle);
7719
+ entry.abort.abort();
7720
+ entry.socket?.close(1001, "the program went away");
7721
+ }
7722
+ closeAll() {
7723
+ for (const handle of [...this.open.keys()]) this.close(handle);
7724
+ }
7725
+ };
7726
+
7605
7727
  // src/kernel/net/http-syscalls.ts
7606
- var HTTP_OPS = ["net-request", "net-read", "net-close", "net-traits"];
7728
+ var HTTP_OPS = [
7729
+ "net-request",
7730
+ "net-open",
7731
+ "net-head",
7732
+ "net-read",
7733
+ "net-close",
7734
+ "net-traits",
7735
+ ...WS_OPS
7736
+ ];
7607
7737
  var EMPTY = new Uint8Array(0);
7608
- function message(e) {
7738
+ function message2(e) {
7609
7739
  return e instanceof Error ? e.message : String(e);
7610
7740
  }
7611
7741
  async function* once(bytes) {
@@ -7615,11 +7745,16 @@ var HttpHandles = class {
7615
7745
  transport;
7616
7746
  open = /* @__PURE__ */ new Map();
7617
7747
  nextHandle = 0;
7748
+ ws;
7618
7749
  constructor(transport) {
7619
7750
  this.transport = transport;
7751
+ this.ws = new WsHandles(transport, () => ++this.nextHandle);
7620
7752
  }
7621
7753
  syscall(req) {
7754
+ if (req.op.startsWith("net-ws-")) return this.ws.syscall(req);
7622
7755
  if (req.op === "net-request") return this.request(req);
7756
+ if (req.op === "net-open") return Promise.resolve(this.opened(req));
7757
+ if (req.op === "net-head") return this.head(req.handle);
7623
7758
  if (req.op === "net-read") return this.read(req.handle, req.max);
7624
7759
  if (req.op === "net-traits") return Promise.resolve(this.traits());
7625
7760
  return this.close(req.handle);
@@ -7629,56 +7764,70 @@ var HttpHandles = class {
7629
7764
  if (unavailable) return { ok: false, errno: "ENETUNREACH", message: NO_TRANSPORT };
7630
7765
  return { ok: true, kind: "json", json: { ...rest2, crossOrigin } };
7631
7766
  }
7632
- add(abort, body, cancel) {
7767
+ async request(req) {
7768
+ const { handle, head } = this.start(req);
7769
+ const result = await head;
7770
+ if (!result.ok) this.open.delete(handle);
7771
+ return result;
7772
+ }
7773
+ opened(req) {
7774
+ return { ok: true, kind: "json", json: this.start(req).handle };
7775
+ }
7776
+ start(req) {
7633
7777
  const handle = ++this.nextHandle;
7634
- this.open.set(handle, {
7778
+ const abort = new AbortController();
7779
+ const entry = {
7635
7780
  abort,
7636
- body: body[Symbol.asyncIterator](),
7781
+ head: Promise.resolve({ ok: true, kind: "void" }),
7782
+ body: once(EMPTY),
7637
7783
  left: EMPTY,
7638
7784
  done: false,
7639
7785
  reading: Promise.resolve(),
7640
- cancel
7641
- });
7642
- return handle;
7786
+ cancel: async () => void 0
7787
+ };
7788
+ this.open.set(handle, entry);
7789
+ entry.head = this.respond(handle, req, entry);
7790
+ return { handle, head: entry.head };
7643
7791
  }
7644
- async request(req) {
7645
- const abort = new AbortController();
7792
+ async respond(handle, req, entry) {
7646
7793
  try {
7647
7794
  const response = await this.transport.fetch({
7648
7795
  url: req.url,
7649
7796
  method: req.method,
7650
7797
  headers: req.headers,
7651
7798
  ...req.body ? { body: req.body } : {},
7652
- signal: abort.signal
7799
+ signal: entry.abort.signal
7653
7800
  });
7654
- const handle = this.add(abort, response.body, () => response.cancel());
7655
- const head = {
7656
- handle,
7657
- status: response.status,
7658
- statusText: response.statusText,
7659
- url: req.url,
7660
- headers: response.headers
7661
- };
7662
- return { ok: true, kind: "json", json: head };
7801
+ entry.body = response.body[Symbol.asyncIterator]();
7802
+ entry.cancel = () => response.cancel();
7803
+ if (!this.open.has(handle)) await entry.cancel().catch(() => void 0);
7804
+ const head = this.headOf(handle, response.url ?? req.url, response);
7805
+ return response.redirected ? { ...head, json: { ...head.json, redirected: true } } : head;
7663
7806
  } catch (e) {
7664
- const text = message(e);
7665
- if (text === NO_TRANSPORT) return { ok: false, errno: "ENETUNREACH", message: text };
7807
+ const text = message2(e);
7666
7808
  const status = e.status;
7667
- if (typeof status !== "number" || status === 502) {
7668
- return { ok: false, errno: "ECONNREFUSED", message: text };
7809
+ if (text === NO_TRANSPORT || typeof status !== "number" || status === 502) {
7810
+ const errno = text === NO_TRANSPORT ? "ENETUNREACH" : "ECONNREFUSED";
7811
+ return { ok: false, errno, message: text };
7669
7812
  }
7670
- const body = new TextEncoder().encode(text);
7671
- const handle = this.add(abort, once(body), async () => void 0);
7672
- const head = {
7673
- handle,
7813
+ entry.body = once(new TextEncoder().encode(text))[Symbol.asyncIterator]();
7814
+ return this.headOf(handle, req.url, {
7674
7815
  status,
7675
7816
  statusText: "",
7676
- url: req.url,
7677
7817
  headers: [["content-type", "text/plain; charset=utf-8"]]
7678
- };
7679
- return { ok: true, kind: "json", json: head };
7818
+ });
7680
7819
  }
7681
7820
  }
7821
+ headOf(handle, url, response) {
7822
+ const { status, statusText, headers } = response;
7823
+ return { ok: true, kind: "json", json: { handle, status, statusText, url, headers } };
7824
+ }
7825
+ head(handle) {
7826
+ const entry = this.open.get(handle);
7827
+ if (!entry)
7828
+ return Promise.resolve({ ok: false, errno: "EBADF", message: `no request ${handle}` });
7829
+ return entry.head;
7830
+ }
7682
7831
  async read(handle, max) {
7683
7832
  const entry = this.open.get(handle);
7684
7833
  if (!entry) return { ok: false, errno: "EBADF", message: `no request ${handle}` };
@@ -7695,7 +7844,7 @@ var HttpHandles = class {
7695
7844
  } catch (e) {
7696
7845
  entry.done = true;
7697
7846
  const timedOut = e?.code === "ETIMEDOUT";
7698
- return { ok: false, errno: timedOut ? "ETIMEDOUT" : "EIO", message: message(e) };
7847
+ return { ok: false, errno: timedOut ? "ETIMEDOUT" : "EIO", message: message2(e) };
7699
7848
  }
7700
7849
  }
7701
7850
  const bytes = entry.left.subarray(0, Math.max(0, max));
@@ -7703,6 +7852,10 @@ var HttpHandles = class {
7703
7852
  return { ok: true, kind: "bytes", bytes };
7704
7853
  }
7705
7854
  async close(handle) {
7855
+ if (this.ws.owns(handle)) {
7856
+ this.ws.close(handle);
7857
+ return { ok: true, kind: "void" };
7858
+ }
7706
7859
  const entry = this.open.get(handle);
7707
7860
  if (!entry) return { ok: false, errno: "EBADF", message: `no request ${handle}` };
7708
7861
  this.open.delete(handle);
@@ -7711,6 +7864,7 @@ var HttpHandles = class {
7711
7864
  return { ok: true, kind: "void" };
7712
7865
  }
7713
7866
  async closeAll() {
7867
+ this.ws.closeAll();
7714
7868
  await Promise.all([...this.open.keys()].map((handle) => this.close(handle)));
7715
7869
  }
7716
7870
  };
@@ -7743,7 +7897,7 @@ var Resolver = class {
7743
7897
  this.routes = options.routes;
7744
7898
  this.now = options.now ?? Date.now;
7745
7899
  this.timeoutMs = options.timeoutMs ?? RESOLVE_TIMEOUT_MS;
7746
- this.log = options.log ?? ((message2) => console.warn(message2));
7900
+ this.log = options.log ?? ((message3) => console.warn(message3));
7747
7901
  this.own = ownNames(options.hostname ?? DEFAULT_HOSTNAME);
7748
7902
  }
7749
7903
  async resolve(name2, family, blocking) {
@@ -8303,10 +8457,10 @@ function ready(fds, read, write) {
8303
8457
  }
8304
8458
  function interruption(signal) {
8305
8459
  const { promise, reject } = Promise.withResolvers();
8306
- const fail = () => reject(new KernelError("EINTR"));
8307
- if (signal.aborted) fail();
8308
- else signal.addEventListener("abort", fail, { once: true });
8309
- return { promise, done: () => signal.removeEventListener("abort", fail) };
8460
+ const fail2 = () => reject(new KernelError("EINTR"));
8461
+ if (signal.aborted) fail2();
8462
+ else signal.addEventListener("abort", fail2, { once: true });
8463
+ return { promise, done: () => signal.removeEventListener("abort", fail2) };
8310
8464
  }
8311
8465
  async function selectFds(fds, read, write, timeoutMs, interrupt) {
8312
8466
  const deadline = timeoutMs < 0 ? Number.POSITIVE_INFINITY : Date.now() + timeoutMs;
@@ -9456,6 +9610,9 @@ var WasmProcess = class {
9456
9610
  throw e;
9457
9611
  }
9458
9612
  }
9613
+ refuseIfPending(restart) {
9614
+ if (restart && this.options.hasPending?.()) throw new KernelError("EINTR");
9615
+ }
9459
9616
  blockingSignal() {
9460
9617
  if (this.options.hasPending?.()) throw new KernelError("EINTR");
9461
9618
  return this.interrupt.signal;
@@ -9466,6 +9623,7 @@ var WasmProcess = class {
9466
9623
  if (!read) throw new KernelError(req.peek && file.read ? "EOPNOTSUPP" : "EBADF");
9467
9624
  if (file.tty) this.checkForeground(file.tty);
9468
9625
  if (req.max <= 0) return new Uint8Array(0);
9626
+ if (file instanceof KernelSocket && file.unconnected) throw new KernelError("ENOTCONN");
9469
9627
  const ready2 = pollFile(file).readable;
9470
9628
  if (!ready2 && req.nonblock) throw new KernelError("EAGAIN");
9471
9629
  const signal = ready2 ? this.interrupt.signal : this.blockingSignal();
@@ -9788,8 +9946,10 @@ var WasmProcess = class {
9788
9946
  async procSyscall(req) {
9789
9947
  switch (req.op) {
9790
9948
  case "proc-fork":
9949
+ this.refuseIfPending(req.restart);
9791
9950
  return { ok: true, kind: "json", json: await this.children.fork(req.state) };
9792
9951
  case "proc-spawn":
9952
+ this.refuseIfPending(req.restart);
9793
9953
  return { ok: true, kind: "json", json: await this.spawn(req) };
9794
9954
  case "proc-wait": {
9795
9955
  const signal = req.nohang ? this.interrupt.signal : this.blockingSignal();
@@ -10455,8 +10615,8 @@ var SettlingChildren = class {
10455
10615
  };
10456
10616
 
10457
10617
  // src/mount/driver.ts
10458
- function fsError2(code, message2 = code) {
10459
- return Object.assign(new Error(message2), { code });
10618
+ function fsError2(code, message3 = code) {
10619
+ return Object.assign(new Error(message3), { code });
10460
10620
  }
10461
10621
  async function dispatch(h, req) {
10462
10622
  switch (req.op) {
@@ -10506,15 +10666,15 @@ async function dispatch(h, req) {
10506
10666
  }
10507
10667
  function serveFilesystem(port, handlers, capabilities = {}, options = {}) {
10508
10668
  let open = false;
10509
- const reply = (message2, transfer = []) => port.postMessage(message2, transfer);
10510
- async function hello(message2) {
10511
- const refused = driverVersionError(message2.protocol);
10669
+ const reply = (message3, transfer = []) => port.postMessage(message3, transfer);
10670
+ async function hello(message3) {
10671
+ const refused = driverVersionError(message3.protocol);
10512
10672
  if (refused) {
10513
10673
  reply({ hello: { protocol: DRIVER_PROTOCOL, error: refused, errno: "EPROTO" } });
10514
10674
  return;
10515
10675
  }
10516
10676
  try {
10517
- const refined = await handlers.mount?.(message2.mount);
10677
+ const refined = await handlers.mount?.(message3.mount);
10518
10678
  open = true;
10519
10679
  reply({
10520
10680
  hello: { protocol: DRIVER_PROTOCOL, capabilities: { ...capabilities, ...refined } }
@@ -11837,10 +11997,10 @@ var Launcher = class {
11837
11997
  }
11838
11998
  interpreters() {
11839
11999
  this.binfmts ??= this.roots().then(
11840
- (roots) => scanBinfmts(this.base, roots, (message2) => {
11841
- if (this.warned.has(message2)) return;
11842
- this.warned.add(message2);
11843
- console.warn(message2);
12000
+ (roots) => scanBinfmts(this.base, roots, (message3) => {
12001
+ if (this.warned.has(message3)) return;
12002
+ this.warned.add(message3);
12003
+ console.warn(message3);
11844
12004
  })
11845
12005
  );
11846
12006
  return this.binfmts;
@@ -12467,7 +12627,7 @@ var Launcher = class {
12467
12627
  },
12468
12628
  account
12469
12629
  );
12470
- const report = (message2) => options.onData(encoder3.encode(`${message2}\r
12630
+ const report = (message3) => options.onData(encoder3.encode(`${message3}\r
12471
12631
  `));
12472
12632
  const handle = await this.launch(planned, { env, cwd, fds, report, ...this.identity(account) });
12473
12633
  leader = handle.pid;
@@ -12497,7 +12657,7 @@ var Launcher = class {
12497
12657
  };
12498
12658
  const stdout = collect(out, options.onStdout);
12499
12659
  const stderr = collect(err, options.onStderr);
12500
- const report = (message2) => stderr(encoder3.encode(`${message2}
12660
+ const report = (message3) => stderr(encoder3.encode(`${message3}
12501
12661
  `));
12502
12662
  if (!planned) {
12503
12663
  report(`${file}: command not found`);