char-slop/berry

multipurpose self-modifiable agentic harness

git clone https://git.t4t.associates/char-slop/berry

Charlotte Somadd terminal extension6334b24

main
1.8 KiB43 linesraw
1import type { Channel, ChannelMessage, JsonValue } from "@berry/api";
2import { token } from "./client.ts";
3
4/** Open a channel to `path`: its first message authorizes it and carries `args`; what `send` is given before then waits. */
5export function openChannel(path: string, args: JsonValue | undefined): Channel {
6  const scheme = location.protocol === "https:" ? "wss:" : "ws:";
7  const socket = new WebSocket(`${scheme}//${location.host}${path}`);
8  socket.binaryType = "arraybuffer";
9  const waiting: ChannelMessage[] = [];
10  const encode = (message: ChannelMessage) =>
11    message instanceof Uint8Array ? message : JSON.stringify(message);
12  let incoming!: ReadableStreamDefaultController<ChannelMessage>;
13  const messages = new ReadableStream<ChannelMessage>({
14    start: (controller) => void (incoming = controller),
15    cancel: () => socket.close(1000),
16  });
17  socket.addEventListener("open", () => {
18    socket.send(JSON.stringify({ token: token.get(), args: args ?? {} }));
19    for (const message of waiting.splice(0)) socket.send(encode(message));
20  });
21  socket.addEventListener("message", (event) => {
22    incoming.enqueue(
23      typeof event.data === "string" ? JSON.parse(event.data) : new Uint8Array(event.data),
24    );
25  });
26  socket.addEventListener("close", ({ code, reason }) => {
27    try {
28      // closed as asked, by either end; anything else is a failure, such as a restart or a refusal
29      if (code === 1000) incoming.close();
30      else incoming.error(new Error(reason || `the channel closed (${code})`));
31    } catch {
32      // already ended
33    }
34  });
35  return {
36    send(message) {
37      if (socket.readyState === WebSocket.CONNECTING) waiting.push(message);
38      else if (socket.readyState === WebSocket.OPEN) socket.send(encode(message));
39    },
40    messages,
41    close: () => socket.close(1000),
42  };
43}