var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // https://jsr.io/@char/aftercare/0.2.0/src/elem.ts function elem(tag, attrs = {}, children = [], extras = {}) { const element = typeof tag === "string" ? document.createElement(tag) : new tag(); Object.assign( element, Object.fromEntries(Object.entries(attrs).filter(([_k, v]) => v !== void 0)) ); if (extras.classList) extras.classList.forEach((c) => element.classList.add(c)); if (extras.dataset && (element instanceof HTMLElement || element instanceof SVGElement)) Object.entries(extras.dataset).filter(([_k, v]) => v !== void 0).forEach(([k, v]) => element.dataset[k] = v); const childNodes = children.map( (e) => typeof e === "string" ? document.createTextNode(e) : e ); element.append(...childNodes); if (extras._tap) extras._tap(element); return element; } __name(elem, "elem"); // https://jsr.io/@char/aftercare/0.2.0/src/jsx.ts function jsx(tag, props, _key) { if (tag === void 0) { throw new Error("fragments are not supported"); } const { children = [], classList, dataset, _tap, ...attrs } = props; const childrenArray = Array.isArray(children) ? children : [children]; const extras = { classList, dataset, _tap }; return elem(tag, attrs, childrenArray, extras); } __name(jsx, "jsx"); // client/main.tsx var main = document.querySelector("main"); async function nav() { const nav2 = /* @__PURE__ */ jsx("nav", {}); const conversations = await fetch("/api/conversation").then((r) => r.json()); for (const conversation of conversations) { const button = /* @__PURE__ */ jsx("button", { type: "button", children: conversation.name }); button.addEventListener("click", (e) => { e.preventDefault(); main.append(conversationUI(conversation.id)); nav2.remove(); }); nav2.append(button); } nav2.append( /* @__PURE__ */ jsx( "button", { type: "button", _tap: (b) => b.addEventListener("click", (e) => { e.preventDefault(); main.append(conversationUI("new")); nav2.remove(); }), children: "new" } ) ); return nav2; } __name(nav, "nav"); function conversationUI(id) { window.location.hash = `#${id}`; const socket = new WebSocket(`/api/conversation/${id}/connect`); const chatlog = /* @__PURE__ */ jsx("section", { className: "chatlog" }); const inFlightMessages = /* @__PURE__ */ new Map(); socket.addEventListener("message", (event) => { if (typeof event.data !== "string") return; const message = JSON.parse(event.data); const scrolledToBottom = chatlog.scrollTop + 16 >= chatlog.scrollHeight - chatlog.clientHeight; if ("u" in message) { chatlog.append(/* @__PURE__ */ jsx("article", { className: "user", children: message.u })); } else if ("f" in message) { chatlog.append(/* @__PURE__ */ jsx("article", { className: "assistant", children: message.f })); } else if ("s" in message) { const article = /* @__PURE__ */ jsx("article", { className: "assistant" }); inFlightMessages.set(message.s, article); chatlog.append(article); } else if ("r" in message && "c" in message) { const article = inFlightMessages.get(message.r); article.append(message.c); } else if ("d" in message) { inFlightMessages.delete(message.d); } if (scrolledToBottom) chatlog.scrollTop = chatlog.scrollHeight - chatlog.clientHeight; }); const form = /* @__PURE__ */ jsx("form", { children: /* @__PURE__ */ jsx("input", { type: "text", required: true }) }); const input = form.querySelector("input"); form.addEventListener("submit", (e) => { e.preventDefault(); socket.send(input.value); input.value = ""; }); return /* @__PURE__ */ jsx("section", { className: "conversation", children: [ chatlog, form ] }); } __name(conversationUI, "conversationUI"); var showUI = /* @__PURE__ */ __name(async () => { main.innerHTML = ""; if (window.location.hash) { main.append(conversationUI(window.location.hash.substring(1))); } else { main.append(await nav()); } }, "showUI"); await showUI(); window.addEventListener("hashchange", async () => { await showUI(); }); //# sourceMappingURL=main.js.map