diff --git a/docs/.config/docs.yaml b/docs/.config/docs.yaml index eefd3d7..6e7b6e7 100644 --- a/docs/.config/docs.yaml +++ b/docs/.config/docs.yaml @@ -1,7 +1,7 @@ # yaml-language-server: $schema=https://unpkg.com/undocs/schema/config.json -name: CrossWS -shortDescription: runtime agnostic WebSockets +name: crossws +shortDescription: runtime agnostic websocket servers description: Unified WebSocket API for Node.js, Deno, Bun and Cloudflare Workers. github: unjs/crossws @@ -22,7 +22,7 @@ landing: per client but once. - title: Lightweight description: - Zero Dependency with bundled ws for Node.js support. Extremely lightweight + Zero Dependency with bundled support for Node.js support. Extremely lightweight and tree-shakable packaging with ESM and CJS support. - title: Developer Friendly description: Typed Hooks API and human friendly logging support. diff --git a/docs/1.guide/1.index.md b/docs/1.guide/1.index.md index c835338..9fa6cb5 100644 --- a/docs/1.guide/1.index.md +++ b/docs/1.guide/1.index.md @@ -4,27 +4,22 @@ icon: ph:book-open-duotone # Getting Started -> CrossWS provides a cross-platform API to define well-typed WebSocket apps that can then be integrated into various WebSocket servers using built-in adapters. +> crossws provides a cross-platform toolkit to define well-typed WebSocket apps that can then be integrated into various WebSocket servers using built-in adapters. -Writing a realtime WebSocket server that can work in different javascript and WebSocket runtimes is challenging because there is no single standard for WebSocket servers. You often need to go into many details of diffrent API implementations and it also makes switching from one runtime costly. CrossWS is a solution to this! - -> [!IMPORTANT] -> CrossWS API is still under development and can change. +Writing a realtime WebSocket server that can work in different runtimes is challenging because there is no single standard for WebSocket servers. You often need to go into many details of different API implementations and it also makes switching from one runtime costly. crossws is a solution to this! ## Quick Start > [!TIP] -> You can try CrossWS with [online playground](https://stackblitz.com/github/unjs/crossws/tree/main/examples/h3?file=app.ts) using [unjs/h3](https://h3.unjs.io) + [unjs/listhen](https://listhen.unjs.io) or alternatively integrate CrossWS with your own framework. +> You can try crossws with [online playground](https://stackblitz.com/github/unjs/crossws/tree/main/examples/h3?file=app.ts) using [unjs/h3](https://h3.unjs.io) + [unjs/listhen](https://listhen.unjs.io) or alternatively integrate crossws with your own framework. A simple WebSocket implementation looks like this: ```ts -// https://crossws.unjs.io/adapters -import wsAdapter from "crossws/adapters/"; - import { defineHooks } from "crossws"; +import crossws from "crossws/adapters/"; -const websocket = wsAdapter({ +const ws = crossws({ hooks: { open(peer) { console.log("[ws] open", peer); @@ -65,5 +60,6 @@ You can install `crossws` from [npm](https://npmjs.com/crossws) in your project: Alternatively you can import it from CDN: ```js -import { crossws } from "https://esm.sh/crossws"; +import { defineHooks } from "https://esm.sh/crossws"; +import crossws from "https://esm.sh/crossws/adapters/"; ``` diff --git a/docs/1.guide/2.hooks.md b/docs/1.guide/2.hooks.md index f5dfbb0..b8655ae 100644 --- a/docs/1.guide/2.hooks.md +++ b/docs/1.guide/2.hooks.md @@ -4,15 +4,12 @@ icon: material-symbols-light:data-object # Hooks -> Using WebSocket hooks API, you can define a WebSocket server that works across runtimes with same synax. +> Using hooks, you can define a WebSocket server that works across runtimes with the same syntax. -CrossWS provides a cross-platform API to define WebSocket servers. An implementation with these hooks works across runtimes without needing you to go into details of any of them (while you always have the power to control low-level hooks). You can only define the life-cycle hooks that you only need and only those will be called on runtime. - -> [!IMPORTANT] -> CrossWS API is still under development and can change. +Crossws provides a cross-platform API to define WebSocket servers. An implementation with these hooks works across runtimes without needing you to go into details of each of them. You only define the life-cycle hooks that you only need. > [!TIP] -> Using `defineHooks` to define hooks, we have type support and IDE auto-completion even if not using typescript. This utility does nothing more and you can use a plain object as well if you prefer to. +> Using `defineHooks()` wrapper is optional and for type support and code auto completion. ```ts import { defineHooks } from "crossws"; diff --git a/docs/1.guide/3.peer.md b/docs/1.guide/3.peer.md index 579a481..a52dc66 100644 --- a/docs/1.guide/3.peer.md +++ b/docs/1.guide/3.peer.md @@ -11,15 +11,19 @@ Websocket [hooks](/guide/hooks) accept a peer instance as their first argument. > [!TIP] > You can safely log a peer instance to the console using `console.log` it will be automatically stringified with useful information including the remote address and connection status! -## API +## Properties -### `peer.send(message, compress)` +### `peer.url` + +Request http url during upgrade. You can use it to do actions based on path and search params. + +### `peer.headers` -Send a message to the connected client +Request http headers during upgrade. Youb can use it to do authentication and access upgrade headers. ### `peer.addr` -The peer address (might be `undefined`) +The IP address of the client. ### `peer.id` @@ -31,12 +35,11 @@ Client connection status (might be `undefined`) :read-more{to="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState" title="readyState in MDN"} -### `peer.ctx` +## Methods -`peer.ctx` is an object that holds adapter specific context. It is scoped with `peer.ctx.[name]`. +### `peer.send(message, compress)` -> [!NOTE] -> `ctx`` is an advanced namespace and API changes might happen, so don't rely on it as much as possible! +Send a message to the connected client. ### `peer.subscribe(channel)` @@ -56,9 +59,6 @@ broadcast a message to the channel. :read-more{to="/guide/pubsub"} -> [!IMPORTANT] -> Native pub/sub is currently only available for [Bun](/adapters/bun) and [Node.js with uWebSockets](/adapters/node#uwebsockets). - ### `peer.close(code?, number?)` Gracefully closes the connection. diff --git a/docs/1.guide/5.pubsub.md b/docs/1.guide/5.pubsub.md index b59c1a5..72d9cf3 100644 --- a/docs/1.guide/5.pubsub.md +++ b/docs/1.guide/5.pubsub.md @@ -4,7 +4,7 @@ icon: simple-icons:googlepubsub # Pub / Sub -CrossWS supports native pub-sub API integration. A [peer](/guide/peer) can be subscribed to a set of named channels using `peer.subscribe()`. Messages can be published to a channel using `peer.publish(, )`. +crossws supports native pub-sub API integration. A [peer](/guide/peer) can be subscribed to a set of named channels using `peer.subscribe()`. Messages can be published to a channel using `peer.publish(, )`. ```js import { defineHooks } from "crossws"; diff --git a/docs/1.guide/6.resolver.md b/docs/1.guide/6.resolver.md index cff2504..ad2b440 100644 --- a/docs/1.guide/6.resolver.md +++ b/docs/1.guide/6.resolver.md @@ -4,18 +4,18 @@ icon: tabler:route # Resolver API -When integrating WebSockets with larger projects, it is often needed to dynamically route an incoming event to websocket hooks. CrossWS provides a very simple mechanism to do this using resolver API. +When integrating WebSockets with larger projects, it is often needed to dynamically route an incoming event to websocket hooks. crossws provides a very simple mechanism to do this using resolver API. > [!TIP] -> Resovler supports async results. This allows implementing lazy loading. +> Resolver supports async results. This allows implementing lazy loading. ```js // https://crossws.unjs.io/adapters -import wsAdapter from "crossws/adapters/"; +import crossws from "crossws/adapters/"; import { defineHooks } from "crossws"; -const websocket = wsAdapter({ +const websocket = crossws({ async resolve(req) { // TODO: Resolve hooks based on req.url, req.headers // You can return undefined in case there is no match diff --git a/docs/2.adapters/1.index.md b/docs/2.adapters/1.index.md index 32cac9a..10c362f 100644 --- a/docs/2.adapters/1.index.md +++ b/docs/2.adapters/1.index.md @@ -4,12 +4,6 @@ icon: emojione-monotone:electric-plug # Adapters -CrossWS allows integrating your WebSocket hooks with different runtimes and platforms using built-in adapters. Each runtime has a specific method of integrating WebSocket. Once integrated, will work consistently even if you change the runtime. +crossws allows integrating your WebSocket hooks with different runtimes and platforms using built-in adapters. Each runtime has a specific method of integrating WebSocket. Once integrated, will work consistently even if you change the runtime. See Adapters section to learn more about all available built-in adapters. - -## Integration with other runtimes - -You can define your custom adapters using `defineWebSocketAdapter` wrapper and using `createCrossWS` utility to handle events. - -See other adapter implementations in [`src/adapters`](https://github.com/unjs/crossws/tree/main/src/adapters/) to get an idea of how adapters can be implemented and feel free to directly make a Pull Request to support your environment in CrossWS! diff --git a/docs/2.adapters/bun.md b/docs/2.adapters/bun.md index 727ea93..9ed69d8 100644 --- a/docs/2.adapters/bun.md +++ b/docs/2.adapters/bun.md @@ -4,14 +4,14 @@ icon: simple-icons:bun # Bun -> Integrate CrossWS with Bun. +> Integrate crossws with Bun. -To integrate CrossWS with your Bun server, you need to handle upgrade with `handleUpgrade` util and also pass the `websocket` object returned from the adapter to server options. CrossWS leverages native Bun WebSocket API. +To integrate crossws with your Bun server, you need to handle upgrade with `handleUpgrade` util and also pass the `websocket` object returned from the adapter to server options. crossws leverages native bun [WebSocket API](https://bun.sh/docs/api/websockets). ```ts -import wsAdapter from "crossws/adapters/bun"; +import crossws from "crossws/adapters/bun"; -const ws = wsAdapter({ +const ws = crossws({ hooks: { message: console.log, }, @@ -21,8 +21,8 @@ Bun.serve({ port: 3000, websocket: ws.websocket, fetch(req, server) { - if (await ws.handleUpgrade(req, server)) { - return; + if (request.headers.get("upgrade") === "websocket") { + return ws.handleUpgrade(request, server); } return new Response( ``, diff --git a/docs/2.adapters/cloudflare.md b/docs/2.adapters/cloudflare.md index 49bb980..d1dd5b5 100644 --- a/docs/2.adapters/cloudflare.md +++ b/docs/2.adapters/cloudflare.md @@ -4,17 +4,17 @@ icon: devicon-plain:cloudflareworkers # Cloudflare -> Integrate CrossWS with Cloudflare Workers. +> Integrate crossws with Cloudflare Workers. -To integrate CrossWS with your Cloudflare Workers, you need to check for the `upgrade` header. +To integrate crossws with your Cloudflare Workers, you need to check for the `upgrade` header. > [!IMPORTANT] -> For [pub/sub](/guide/pubsub) support, you need to use [Durable objects](#durable-objects-support). +> For [pub/sub](/guide/pubsub) support, you need to use [Durable objects](#durable-objects). ```ts -import wsAdapter from "crossws/adapters/cloudflare"; +import crossws from "crossws/adapters/cloudflare"; -const ws = wsAdapter({ +const ws = crossws({ hooks: { message: console.log, }, @@ -44,15 +44,15 @@ export default { See [`test/fixture/cloudflare.ts`](https://github.com/unjs/crossws/blob/main/test/fixture/cloudflare.ts) for demo and [`src/adapters/cloudflare.ts`](https://github.com/unjs/crossws/blob/main/src/adapters/cloudflare.ts) for implementation. :: -## Durable objects support +## Durable objects -To integrate CrossWS with Cloudflare [Durable Objects](https://developers.cloudflare.com/durable-objects/api/websockets/) (available on paid plans) with pub/sub and hibernation support, you need to check for the `upgrade` header and additionally export a Durable object with crossws adapter hooks integrated. +To integrate crossws with Cloudflare [Durable Objects](https://developers.cloudflare.com/durable-objects/api/websockets/) (available on paid plans) with pub/sub and hibernation support, you need to check for the `upgrade` header and additionally export a Durable object with crossws adapter hooks integrated. ```js import { DurableObject } from "cloudflare:workers"; -import wsAdapter from "crossws/adapters/cloudflare-durable"; +import crossws from "crossws/adapters/cloudflare-durable"; -const ws = wsAdapter({ +const ws = crossws({ // bindingName: "$DurableObject", // instanceName: "crossws", hooks: { @@ -81,11 +81,11 @@ export class $DurableObject extends DurableObject { return ws.handleDurableUpgrade(this, request); } - async webSocketMessage(client, message) { + webSocketMessage(client, message) { return ws.handleDurableMessage(this, client, message); } - async webSocketClose(client, code, reason, wasClean) { + webSocketClose(client, code, reason, wasClean) { return ws.handleDurableClose(this, client, code, reason, wasClean); } } diff --git a/docs/2.adapters/deno.md b/docs/2.adapters/deno.md index 923e1e8..f656ac9 100644 --- a/docs/2.adapters/deno.md +++ b/docs/2.adapters/deno.md @@ -4,14 +4,14 @@ icon: teenyicons:deno-solid # Deno -> Integrate CrossWS with Deno. +> Integrate crossws with Deno. -To integrate CrossWS with your Deno server, you need to check for the `upgrade` header and then call `handleUpgrade` method from the adapter passing the incoming request object. The returned value is the server upgrade response. +To integrate crossws with your Deno server, you need to check for the `upgrade` header and then call `handleUpgrade` method from the adapter passing the incoming request object. The returned value is the server upgrade response. ```ts -import wsAdapter from "crossws/adapters/deno"; +import crossws from "crossws/adapters/deno"; -const ws = wsAdapter({ +const ws = crossws({ hooks: { message: console.log, }, diff --git a/docs/2.adapters/node.md b/docs/2.adapters/node.md index 083de9a..5bc3924 100644 --- a/docs/2.adapters/node.md +++ b/docs/2.adapters/node.md @@ -4,15 +4,15 @@ icon: akar-icons:node-fill # Node.js -> Integrate CrossWS with Node.js using ws or uWebSockets.js +> Integrate crossws with Node.js using ws or uWebSockets.js -To integrate CrossWS with your Node.js HTTP server, you need to connect the `upgrade` event to the `handleUpgrade` method returned from the adapter. CrossWS uses a prebundled version of [ws](https://github.com/websockets/ws). +To integrate crossws with your Node.js HTTP server, you need to connect the `upgrade` event to the `handleUpgrade` method returned from the adapter. crossws uses a prebundled version of [ws](https://github.com/websockets/ws). ```ts import { createServer } from "node:http"; -import wsAdapter from "crossws/adapters/node"; +import crossws from "crossws/adapters/node"; -const ws = wsAdapter({ +const ws = crossws({ hooks: { message: console.log, }, @@ -44,15 +44,15 @@ See [`test/fixture/node.ts`](https://github.com/unjs/crossws/blob/main/test/fixt ## uWebSockets -Integrate CrossWS with Node.js using uWebSockets.js. +You can alternatively use [uWebSockets.js](https://github.com/uNetworking/uWebSockets.js) for Node.js servers. -Instead of [using `ws`](/adapters/node-ws) you can use [uWebSockets.js](https://github.com/uNetworking/uWebSockets.js) for Node.js servers. +First add `uNetworking/uWebSockets.js` as a dependency. ```ts import { App } from "uWebSockets.js"; -import wsAdapter from "crossws/adapters/uws"; +import crossws from "crossws/adapters/uws"; -const ws = wsAdapter({ +const ws = crossws({ hooks: { message: console.log, }, diff --git a/docs/2.adapters/sse.md b/docs/2.adapters/sse.md index 963caf2..09aff81 100644 --- a/docs/2.adapters/sse.md +++ b/docs/2.adapters/sse.md @@ -4,12 +4,12 @@ icon: oui:token-event # SSE -> Integrate CrossWS with [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). +> Integrate crossws with [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). If your deployment server is incapable of of handling WebSocket upgrades but support standard web API ([`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)) you can integrate crossws to act as a one way (server to client) handler using [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). > [!IMPORTANT] -> This is an experimental adapter and works only with a limited subset of CrossWS functionalities. +> This is an experimental adapter and works only with a limited subset of crossws functionalities. > [!IMPORTANT] > Instead of [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) client you need to use [`EventSource`](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) as client to connect such server.