Skip to content

Commit

Permalink
Merge pull request #213 from nksaraf/party
Browse files Browse the repository at this point in the history
feat: party API (inspired by partykit)
  • Loading branch information
nksaraf authored Feb 27, 2024
2 parents 5db67f3 + 8bb7761 commit df99efc
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 38 deletions.
6 changes: 6 additions & 0 deletions .changeset/wise-beds-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"vinxi": patch
"react-ssr-basic": patch
---

feat: party API (inspired by partykit)
8 changes: 7 additions & 1 deletion examples/react/ssr/basic/app.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ export default createApp({
handler: "./app/ws.ts",
target: "server",
base: "/_ws",
plugins: () => [reactRefresh()],
},
{
name: "party",
type: "http",
handler: "./app/party.ts",
target: "server",
base: "/party",
},
{
name: "ssr",
Expand Down
13 changes: 13 additions & 0 deletions examples/react/ssr/basic/app/party.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// import { defineWebSocket, eventHandler } from "vinxi/http";
import { partyHandler } from "vinxi/party";

export default partyHandler({
onConnect(party, conn) {
console.log(party);
conn.send("Hello from the server!");
party.broadcast(
"Hello from the server!" +
[...party.getConnections()].map((c) => c.id).join(","),
);
},
});
18 changes: 15 additions & 3 deletions packages/vinxi/lib/nitro-dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,22 @@ export async function createDevServer(nitro) {

const adapter = wsAdapter({
...wsApp.websocket,
adapterHooks: {
"node:message": (event) => {
hooks: {
open: (event) => {
event.ctx.node.req.url = event.ctx.node.req.originalUrl;
},
message: (event) => {
event.ctx.node.req.url = event.ctx.node.req.originalUrl;
},
close: (event) => {
event.ctx.node.req.url = event.ctx.node.req.originalUrl;
},
error: (event) => {
event.ctx.node.req.url = event.ctx.node.req.originalUrl;
},
upgrade: (event) => {
// event.ctx.node.req.url = event.ctx.node.req.originalUrl;
},
},
});
// Listen
Expand All @@ -288,7 +300,7 @@ export async function createDevServer(nitro) {
if (import.meta._websocket) {
console.log("enabling websockets");
listener.server.on("upgrade", (req, sock, head) => {
console.log("upgrading");
req.url = req.originalUrl;
adapter.handleUpgrade(req, sock, head);
});
}
Expand Down
2 changes: 1 addition & 1 deletion packages/vinxi/lib/router-modes.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ const routerModes = {
const { default: handler } = await viteServer.ssrLoadModule(
handlerModule(router),
);
return handler.__websocket__?.[hook]?.(...args);
return await handler.__websocket__?.[hook]?.(...args);
};
}

Expand Down
67 changes: 34 additions & 33 deletions packages/vinxi/runtime/party.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
import {
eventHandler,
isWebSocketEvent,
isWebSocketUpgradeRequest,
lazyEventHandler,
toWebRequest,
toWebSocketEvent,
upgradeWebSocket,
} from "./server";
import { eventHandler } from "./server";

class InternalParty {
connections = new Map();
Expand Down Expand Up @@ -94,33 +86,42 @@ function createConnection(webSocket) {
return webSocket;
}

globalThis.parties ??= {};

async function getParty(partyServer, id) {
if (!globalThis.parties[id]) {
globalThis.parties[id] = new InternalParty(id);
await partyServer.onStart?.(globalThis.parties[id]);
}

return globalThis.parties[id];
}

/**
* @param {import('../types/party.d.ts').PartyHandler} partyServer
*/
export function partyHandler(partyServer) {
return lazyEventHandler(async () => {
const party = new InternalParty("main");
await partyServer.onStart?.(party);
return eventHandler((e) => {
if (isWebSocketEvent(e)) {
const wsEvent = toWebSocketEvent(e);
const conn = createConnection(wsEvent.connection);
if (wsEvent.type === "connection") {
party.onConnect(conn);
partyServer.onConnect?.(party, conn);
} else if (wsEvent.type === "message") {
partyServer.onMessage?.(party, wsEvent.message, conn);
} else if (wsEvent.type === "error") {
partyServer.onError?.(party, conn, wsEvent.error);
} else if (wsEvent.type === "close") {
party.onClose(conn);
partyServer.onClose?.(party, conn);
}
} else if (isWebSocketUpgradeRequest(e)) {
return upgradeWebSocket(e);
} else {
return partyServer.onRequest?.(party, toWebRequest(e));
}
});
return eventHandler({
handler: (e) => {},
websocket: {
async open(peer) {
const party = await getParty(partyServer, peer.url);
await party.onConnect(peer);
return await partyServer.onConnect?.(party, peer);
},
async close(peer, details) {
const party = await getParty(partyServer, peer.url);
await party.onClose(peer);
return await partyServer.onClose?.(party, peer);
},
async message(peer, message) {
const party = await getParty(partyServer, peer.url);
return await partyServer.onMessage?.(party, message, peer);
},
async error(peer, error) {
const party = await getParty(partyServer, peer.url);
return await partyServer.onError?.(party, peer, error);
},
},
});
}

0 comments on commit df99efc

Please sign in to comment.