### Initialize PartyKit Project Source: https://docs.partykit.io/reference/partykit-cli Add PartyKit to an existing npm project. This installs PartyKit, creates a `partykit.json` configuration file, and generates example `client.ts` and `server.ts` files. ```bash npx partykit init ``` -------------------------------- ### Install Partysocket Source: https://docs.partykit.io/tutorials/2-adding-realtime-cursors Install the partysocket library, which simplifies WebSocket connection management for PartyKit. ```bash npm install partysocket@beta ``` -------------------------------- ### Load Data on Server Start with PartyKit Storage Source: https://docs.partykit.io/tutorials/add-partykit-to-a-nextjs-app/6-add-storage Implement the `onStart` method to load data from PartyKit storage when the server starts or the first connection is made. This ensures that existing data is available. ```typescript async onStart() { this.poll = await this.room.storage.get("poll"); } ``` -------------------------------- ### Install PartyKit CLI Source: https://docs.partykit.io/reference/partykit-cli Install the latest version of the PartyKit CLI using npm. ```bash npm install partykit@latest ``` -------------------------------- ### Start Local Development Server Source: https://docs.partykit.io/reference/partykit-cli Start a local development server that watches for code changes and restarts automatically. Uses the `main` field in `partykit.json` or a specified entry point. ```bash npx partykit dev ``` ```bash npx partykit dev src/server.ts ``` -------------------------------- ### Install PartySocket Source: https://docs.partykit.io/reference/partysocket-api Install the PartySocket package using npm. ```bash npm install partysocket@latest ``` -------------------------------- ### Install PartyKit CLI Source: https://docs.partykit.io/tutorials/add-partykit-to-a-nextjs-app/2-set-up-server Run this command in your app directory to add PartyKit to a new project. It installs necessary packages and creates a 'party' directory for server code. ```bash npx partykit@latest init ``` -------------------------------- ### Start PartyKit Dev Server Source: https://docs.partykit.io/add-to-existing-project Execute this command in your project's directory to launch the local development server for PartyKit. ```bash npx partykit dev ``` -------------------------------- ### Example PartyKit Token Output Source: https://docs.partykit.io/guides/setting-up-ci-cd-with-github-actions This is an example of the output you will receive after generating a PartyKit token. The PARTYKIT_TOKEN is sensitive and should be kept secure. ```bash PARTYKIT_LOGIN=your_username PARTYKIT_TOKEN=eyJhb...YR7Bw ``` -------------------------------- ### Install partykit-ai Package Source: https://docs.partykit.io/reference/partykit-ai Install the partykit-ai package to use AI models in your PartyKit project. ```bash npm install partykit-ai ``` -------------------------------- ### Basic PartyKit Server Setup Source: https://docs.partykit.io/guides Defines a basic PartyKit server that accepts WebSocket connections. No additional setup is required for WebSocket functionality. ```typescript import type * as Party from "partykit/server"; export default class WebSocketServer implements Party.Server {} ``` -------------------------------- ### Initialize PartyKit in Project Source: https://docs.partykit.io/add-to-existing-project Run this command in your project's root directory to install PartyKit packages and add the necessary 'party' directory with a server template. ```bash npx partykit@latest init ``` -------------------------------- ### Create a new PartyKit app Source: https://docs.partykit.io/quickstart Run this command in your terminal to initialize a new PartyKit project. Ensure you have Node.js v17 or higher installed. ```bash npm create partykit@latest ``` -------------------------------- ### Deploy PartyKit App Source: https://docs.partykit.io/add-to-existing-project Use this command to deploy your PartyKit server. Refer to the deployment guide for more details. ```bash npx partykit deploy ``` -------------------------------- ### Generate Text Description with Llama 2 Source: https://docs.partykit.io/reference/partykit-ai Example fetch handler using the text-generation model to get a description for a word. Ensure the model name and messages are correctly formatted. ```typescript import { Ai } from "partykit-ai"; import type * as Party from "partykit/server"; export default class { static async onFetch(request: Party.Request, lobby: Party.FetchLobby) { const ai = new Ai(lobby.ai); const result = await ai.run("@cf/meta/llama-2-7b-chat-int8", { messages: [ { role: "system", content: "You are a friendly assistant" }, { role: "user", content: "What is the origin of the phrase Hello, World" } ], stream: true }); return new Response(result, { headers: { "content-type": "text/event-stream" } }); } } ``` -------------------------------- ### Configure Custom Build Commands Source: https://docs.partykit.io/reference/partykit-configuration Define custom commands to run before starting the server, on code changes, or before deployment. Includes options for watching directories. ```json { "build": { "command": "npm run build", "watch": "src" } } ``` -------------------------------- ### Set up a Yjs Server with PartyKit Source: https://docs.partykit.io/reference/y-partykit-api Implement the PartyKit Server interface to host Yjs documents. This basic setup handles incoming connections and integrates with the onConnect function from y-partykit. ```typescript import type * as Party from "partykit/server"; import { onConnect } from "y-partykit"; export default class YjsServer implements Party.Server { constructor(public party: Party.Room) {} onConnect(conn: Party.Connection) { return onConnect(conn, this.party, { // ...options }); } } ``` -------------------------------- ### Party.Server onStart Lifecycle Method Source: https://docs.partykit.io/reference/partyserver-api The onStart method is called when the server starts or wakes from hibernation, prior to the first onConnect or onRequest. Use it for asynchronous initialization like loading data from storage. ```typescript import type * as Party from "partykit/server"; export default class Server implements Party.Server { async onStart() {} } ``` -------------------------------- ### Configure Vectorize Index in partykit.json Source: https://docs.partykit.io/reference/partykit-ai Example configuration for a Vectorize index named 'myIndex' within the partykit.json file. ```json { // ... "vectorize": { "myIndex": { "index_name": "my-index" } } } ``` -------------------------------- ### Run PartyKit Dev Server Source: https://docs.partykit.io/tutorials/add-partykit-to-a-nextjs-app/2-set-up-server Start the PartyKit development server in a separate terminal tab to handle server logic during development. ```bash npx partykit dev ``` -------------------------------- ### Handling String Messages Source: https://docs.partykit.io/guides/handling-binary-messages Examples of parsing incoming string messages and broadcasting stringified JSON. ```typescript onMessage(message: string) { const data = JSON.parse(message); } ``` ```typescript onConnect(connection: Party.Connection) { this.room.broadcast(JSON.stringify({ type: "join", id: connection.id })); } ``` -------------------------------- ### Stateful Party Server Implementation Source: https://docs.partykit.io/how-partykit-works Implement a stateful server for a PartyKit room. This example demonstrates managing in-memory messages and broadcasting them to connected clients, while also sending message history on new connections. ```typescript export default class Server implements PartyServer { this.messages = []; onMessage(message: string) { // keep track of messages in-memory this.messages.push(message); // send them to all connected clients this.room.broadcast(JSON.stringify({ messages: [message]} )); } onConnect(connection: PartyConnection) { // when a new client connects, send them the full message history connection.send(JSON.stringify({ messages: this.messages })); } } ``` -------------------------------- ### Handling String or Binary Messages Source: https://docs.partykit.io/guides/handling-binary-messages A basic example of checking the message type and broadcasting binary data directly. ```typescript onMessage(message: string | ArrayBufferLike) { if (typeof message !== string) { this.room.broadcast(message); } } ``` -------------------------------- ### Read data up front in onStart Source: https://docs.partykit.io/guides/persisting-state-into-storage Load data from storage into memory when the server starts. This is useful for frequent reads and infrequent writes, or when joining multiple data sets. Assumes data fits within storage limits. ```typescript export default class Main implements Party.Server { constructor(public room: Party.Room) {} messages: string[] = []; // You can use this to load data from storage and perform other // asynchronous initialization. The Room will wait until `onStart` completes before // processing any connections or requests. async onStart() { this.messages = (await this.room.storage.get( ``` ```typescript messages")) ?? []; } async onConnect(connection: Party.Connection) { connection.send(JSON.stringify(this.messages)); } async onMessage(message: string) { this.messages.push(message); this.room.storage.put("messages", this.messages); connection.send(message); } } ``` -------------------------------- ### Accessing Defined Constants in Code Source: https://docs.partykit.io/reference/partykit-configuration Example of how to access constants defined in the `define` section of `partykit.json` within your PartyKit server code. ```javascript export default { onConnect(connection, room) { console.log(MY_CONSTANT); // -> "my value" console.log(process.env.MY_MAGIC_NUMBER) -> // 1 }, }; ``` -------------------------------- ### PartyKit Vectorize CLI Commands Source: https://docs.partykit.io/reference/partykit-ai Command-line interface commands for managing Vectorize indexes, including create, delete, get, list, and insert. ```bash 🎈 PartyKit ------------ Usage: partykit vectorize [options] [command] Manage vectorize indexes Options: -h, --help display help for command Commands: create [options] Create a vectorize index delete [options] Delete a vectorize index get [options] Get a vectorize index by name list [options] List all vectorize indexes insert [options] [name] Insert vectors into a Vectorize index ``` -------------------------------- ### Accessing Environment Variables in Code Source: https://docs.partykit.io/reference/partykit-configuration Example of how to access environment variables defined in `partykit.json` within your PartyKit server code. ```javascript export default { onConnect(connection, room) { console.log(room.env.MY_VAR); // "my value" console.log(room.env["some-nested-object"].a); // 123 } }; ``` -------------------------------- ### Handle Custom HTTP Endpoints with static onFetch Source: https://docs.partykit.io/reference/partyserver-api Configure a custom HTTP endpoint using the static `onFetch` method. This example demonstrates returning a response with a specific status code. ```typescript import type * as Party from "partykit/server"; export default class Server implements Party.Server { static async onFetch( req: Party.Request, lobby: Party.FetchLobby, ctx: Party.ExecutionContext ) { return new Response(req.url, { status: 403 }); } } Server satisfies Party.Worker; ``` -------------------------------- ### GitHub Action Workflow for PartyKit Deployment Source: https://docs.partykit.io/guides/setting-up-ci-cd-with-github-actions This YAML file defines a GitHub Action that deploys your PartyKit project on every push to the 'main' branch. It checks out the code, sets up Node.js, installs dependencies, and then deploys using the PartyKit CLI. ```yaml name: Deploy on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: 18 cache: "npm" - run: npm ci - run: npx partykit deploy env: PARTYKIT_TOKEN: ${{ secrets.PARTYKIT_TOKEN }} PARTYKIT_LOGIN: ${{ secrets.PARTYKIT_LOGIN }} ``` -------------------------------- ### Implement Incremental Back-off Rate Limiter Source: https://docs.partykit.io/guides/rate-limiting-messages Apply a rate limiter to incoming messages with a specified interval and a callback for actions. This example uses a `rateLimit` function, likely from a utility or library. ```typescript onMessage(message: string, sender: Party.Connection) { // rate limit incoming messages to every 100ms with an incremental back-off rateLimit(sender, 100, () => { // do things }); } ``` -------------------------------- ### List all items in storage Source: https://docs.partykit.io/guides/persisting-state-into-storage Use `storage.list()` to retrieve all key-value pairs. This operation can be memory-intensive and should be used only when iteration is necessary. Consider using `get` for individual items. ```typescript const items = await this.room.storage.list(); for (const [key, value] of items) { console.log(key, value); } ``` -------------------------------- ### Party.Server.onStart Source: https://docs.partykit.io/reference/partyserver-api The `onStart` method is called when the server begins execution or resumes from hibernation, prior to any client connections or requests. ```APIDOC ## Party.Server.onStart Called when the server is started or after waking up from hibernation, before first `onConnect` or `onRequest`. You can use this to load data from storage and perform other asynchronous initialization, such as retrieving data or configuration from other services or databases. ```typescript import type * as Party from "partykit/server"; export default class Server implements Party.Server { async onStart() {} } ``` ``` -------------------------------- ### Deploy to a Preview Environment Source: https://docs.partykit.io/guides/preview-environments Use the `--preview` flag with `partykit deploy` to deploy your project to a custom URL. This is ideal for creating isolated environments for testing. ```bash partykit deploy --preview my-preview ``` -------------------------------- ### Get all connections or filter by tag Source: https://docs.partykit.io/reference/partyserver-api Use `room.getConnections()` to get an iterable of all connected clients, or `room.getConnections("tag")` to filter by a specific tag. This can be used to send messages or count players. ```typescript const playerCount = [...this.room.getConnections()].length; for (const everyone of this.room.getConnections()) { everyone.send(`Let's play!`); } for (const tagged of this.room.getConnections("some-tag")) { tagged.send(`You're it!`); } ``` -------------------------------- ### Get Vectorize Index Details Source: https://docs.partykit.io/reference/partykit-ai Command to retrieve details of a specific Vectorize index by its name. ```bash npx partykit vectorize get my-index ``` -------------------------------- ### Configure Main Entry Point Source: https://docs.partykit.io/reference/partykit-configuration Specify the main entry point file for your PartyKit project. ```json { "main": "src/server.ts" } ``` -------------------------------- ### Vector Object Example Source: https://docs.partykit.io/reference/partykit-ai Defines the structure of a vector object, including its ID, embedding values, and optional metadata. ```javascript let vectorExample = { id: "12345", values: [32.4, 6.55, 11.2, 10.3, 87.9], metadata: { key: "value", hello: "world", url: "r2://bucket/some/object.json" } }; ``` -------------------------------- ### Deploy PartyKit Project Source: https://docs.partykit.io/reference/partykit-cli Deploy your code to the PartyKit platform. Uses the `main` and `name` fields from `partykit.json` or specified arguments. ```bash npx partykit deploy ``` ```bash npx partykit deploy src/server.ts --name my-project ``` -------------------------------- ### Metadata Filter - Explicit Operator Source: https://docs.partykit.io/reference/partykit-ai Example of a metadata filter using an explicit operator, '$ne' (not equals), to exclude a boolean value. ```json { "someKey": { "$ne": true } } ``` -------------------------------- ### Party.Server Constructor with Room Access Source: https://docs.partykit.io/reference/partyserver-api Demonstrates the Party.Server constructor, which receives a Party.Room instance for accessing room state, storage, connections, and more. ```typescript import type * as Party from "partykit/server"; export default class Server implements Party.Server { constructor(readonly room: Party.Room) { // ... } } ``` -------------------------------- ### Metadata Filter - Implicit Equals Source: https://docs.partykit.io/reference/partykit-ai Example of a metadata filter using the implicit '$eq' operator for exact matching on a string value. ```json { "streaming_platform": "netflix" } ``` -------------------------------- ### Detailed Build Configuration for Asset Compilation Source: https://docs.partykit.io/guides/serving-static-assets Fine-tune the build process with options for entry points, bundling, splitting, output directory, minification, format, sourcemaps, and more. ```json { // ... "serve": { "path": "path/to/assets", // ... "build": { "entry": "path/to/entry.ts", // can also be an array of paths "bundle": true, // bundle all dependencies, defaults to true "splitting": true, // split bundles, defaults to true "outdir": "path/to/outdir", // defaults to serve.path + "dist" "minify": true, // minify bundles, defaults to false in dev and to true in deploy "format": "esm", // "esm" | "cjs" | "iife", default "esm" "sourcemap": true, // generate sourcemaps, defaults to true "define": { // define global constants, defaults to {} "process.env.xyz": "123" // you can pass values via the CLI with --define key=value }, "external": ["react", "react-dom"], // externalize modules, defaults to [] "loader": { // configure loaders, defaults to {} ".png": "file" // see https://esbuild.github.io/content-types/ for more info } } } } ``` -------------------------------- ### Party.Server Constructor Source: https://docs.partykit.io/reference/partyserver-api The constructor for Party.Server receives a Party.Room instance, providing access to room state, storage, connections, and other resources. ```APIDOC ## Party.Server (constructor) The `Party.Server` constructor receives an instance of `Party.Room`, which gives you access to the room state and resources such as storage, connections, id, and more. ```typescript import type * as Party from "partykit/server"; export default class Server implements Party.Server { constructor(readonly room: Party.Room) { // ... } } ``` ``` -------------------------------- ### Configure Static Asset Serving Source: https://docs.partykit.io/reference/partykit-configuration Configure PartyKit to serve static assets or a static website from your project's root. Includes options for build process customization. ```json { "serve": { "path": "path/to/assets", // ... "build": { "entry": "path/to/entry.ts", // can also be an array of paths "bundle": true, // bundle all dependencies, defaults to true "splitting": true, // split bundles, defaults to true "outdir": "path/to/outdir", // defaults to serve.path + "dist" "minify": true, // minify bundles, defaults to false in dev and to true in deploy "format": "esm", // "esm" | "cjs" | "iife", default "esm" "sourcemap": true, // generate sourcemaps, defaults to true "define": { // define global constants, defaults to {} "process.env.xyz": "123" // you can pass values via the CLI with --define key=value }, "external": ["react", "react-dom"], // externalize modules, defaults to [] "loader": { // configure loaders, defaults to {} ".png": "file" // see https://esbuild.github.io/content-types/ for more info } } } } ``` -------------------------------- ### Access and interact with other parties from within a party Source: https://docs.partykit.io/guides/using-multiple-parties-per-project Retrieve handles to other parties defined in the project and get specific room instances for communication. ```typescript const userParty = this.room.context.parties.user; const userRoom = userParty.get(userId); // make an HTTP request to the room const res = await userRoom.fetch({ method: "GET" }); // or open a WebSocket connection to the room to listen to messages const socket = await userRoom.socket(); ``` -------------------------------- ### Connecting to a PartyKit Server with PartySocket Source: https://docs.partykit.io/guides Demonstrates how to connect to a PartyKit WebSocket server using the PartySocket client library. It shows how to send messages and listen for incoming messages. ```typescript import PartySocket from "partysocket"; // connect to our server const partySocket = new PartySocket({ host: "localhost:1999", room: "my-room" }); // send a message to the server partySocket.send("Hello everyone"); // print each incoming message from the server to console partySocket.addEventListener("message", (e) => { console.log(e.data); }); ``` -------------------------------- ### Good: On-Demand Data Loading and Individual Updates Source: https://docs.partykit.io/guides/scaling-partykit-servers-with-hibernation This snippet demonstrates the recommended approach for handling data in a hibernating PartyKit server. It avoids loading all data on startup and instead fetches and updates individual items as needed, improving performance and reducing memory usage. ```typescript type AllItems = Record; export default class Server implements Party.Server { options: Party.ServerOptions = { hibernate: true }; constructor(readonly room: Party.Room) {} // GOOD: no data loading on startup // onStart() {} async onMessage(websocketMessage: string) { const event = JSON.parse(websocketMessage); if (event.type === "create") { this.room.broadcast(event.data); // store each item under a separate key this.room.storage.put(`item:${event.id}`, event.data); }; if (event.type === "update") { // GOOD: read stored state on-demand when needed const item = (await this.room.storage.get(`item:${event.id}`)) ?? {}; const updatedItem = { ...item, ...event.data, }; // GOOD: now we need to write only to a single key this.room.storage.put(`item:${event.id}`, updatedItem); }; }; }; ``` -------------------------------- ### Metadata Filter - Logical AND Source: https://docs.partykit.io/reference/partykit-ai Example of a metadata filter combining multiple conditions using an implicit logical AND. Both conditions must be met for a vector to be included. ```json { "pandas.nice": 42, "someKey": { "$ne": true } } ``` -------------------------------- ### Deploy PartyKit Project to Cloudflare Source: https://docs.partykit.io/guides/deploy-to-cloudflare Run this command to deploy your project to your own Cloudflare account. Ensure you have set the CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN environment variables or pass them directly. ```bash CLOUDFLARE_ACCOUNT_ID= CLOUDFLARE_API_TOKEN= npx partykit deploy --domain partykit.domain.com ``` -------------------------------- ### List Environment Variables Source: https://docs.partykit.io/reference/partykit-cli List all environment variable keys configured for your PartyKit project. ```bash npx partykit env list ``` -------------------------------- ### Get Vectors by IDs Source: https://docs.partykit.io/reference/partykit-ai Retrieves vectors from a Vectorize index based on their unique IDs. Returns an array of vector objects matching the provided IDs. ```javascript const result = await myIndex.getByIds(["1", "2"]); ``` -------------------------------- ### FetchLobby.env Source: https://docs.partykit.io/reference/partyserver-api Environment variables defined for this project. ```APIDOC ## FetchLobby.env ### Description Environment variables defined for this project. ### Related Reading Managing environment variables with PartyKit. ``` -------------------------------- ### Set and get connection state Source: https://docs.partykit.io/reference/partyserver-api Use `connection.setState()` to store small, non-persistent data (up to 2KB) on a connection for its lifetime. Access this data later using `connection.state`. ```typescript connection.setState({ username: "jani" }); ``` ```typescript const user = connection.state?.username; ``` -------------------------------- ### Access other parties via Room.context.parties Source: https://docs.partykit.io/reference/partyserver-api Use `this.room.context.parties` to access and interact with other parties within the same project. You can get a specific party instance and make fetch requests to it. ```typescript const otherParty = this.room.context.parties.other; const otherPartyInstance = otherParty.other.get("room-id"); const req = await otherRoom.fetch({ method: "GET" }); const res = await req.json(); ``` -------------------------------- ### Configure Project Name Source: https://docs.partykit.io/reference/partykit-configuration Set the name of your project, used for identification and URL generation. ```json { "name": "my-project" } ``` -------------------------------- ### Configure Build Process for Static Assets Source: https://docs.partykit.io/guides/serving-static-assets Integrate a build process for compiling assets like TypeScript or JSX by specifying the 'build' field in your partykit.json. ```json { // ... "serve": { "path": "path/to/assets", // ... "build": "path/to/entry.ts" } } ``` -------------------------------- ### Metadata Filter - Nested Keys Source: https://docs.partykit.io/reference/partykit-ai Example demonstrating how to filter on nested metadata keys using dot notation. This targets a specific key within a nested object. ```json { "pandas.nice": 42 } // looks for { "pandas": { "nice": 42 } } ``` -------------------------------- ### List Published Projects Source: https://docs.partykit.io/reference/partykit-cli List all projects you have published on the PartyKit platform. ```bash npx partykit list ``` -------------------------------- ### Store Room ID on Startup Source: https://docs.partykit.io/guides/scheduling-tasks-with-alarms Saves the room ID to storage when the room starts from a connection or request. This is a workaround for accessing the room ID within the onAlarm callback. ```typescript onStart() { if (this.room.id) { // save id when room starts from a connection or request await this.room.storage.put("id", this.id); } } ``` -------------------------------- ### List All Vectorize Indexes Source: https://docs.partykit.io/reference/partykit-ai Command to list all available Vectorize indexes. ```bash npx partykit vectorize list ``` -------------------------------- ### Basic PartySocket Usage Source: https://docs.partykit.io/reference/partysocket-api Demonstrates how to instantiate and use PartySocket to connect to a PartyKit room, including optional client identification and party specification. ```APIDOC ## Basic PartySocket Usage ### Description Instantiate `PartySocket` to connect to a PartyKit server. You can specify the host, room, a unique client ID, and the target party. Query parameters can also be dynamically provided. ### Constructor `new PartySocket(options: { host: string; room: string; id?: string; party?: string; query?: () => Record | Promise>; })` ### Parameters * **host** (string) - The hostname of the PartyKit server or `localhost` for development. * **room** (string) - The name of the room to connect to. * **id** (string, optional) - A unique identifier for this specific connection. If not provided, a random ID is generated. * **party** (string, optional) - The name of the party to connect to. Defaults to "main" if not specified. * **query** (function, optional) - A function that returns an object of query parameters to be appended to the connection URL. Can be synchronous or asynchronous. ### Request Example ```typescript import PartySocket from "partysocket"; const ws = new PartySocket({ host: "project-name.username.partykit.dev", // or localhost:1999 in dev room: "my-room", id: "some-connection-id", party: "main", query: async () => ({ token: await getAuthToken() }) }); ``` ``` -------------------------------- ### Fetch poll data from PartyKit server Source: https://docs.partykit.io/tutorials/add-partykit-to-a-nextjs-app/3-hook-up-data-to-the-server Fetches poll data from the PartyKit server using an HTTP GET request. Caching is disabled to ensure data is always current. ```typescript const req = await fetch(`${PARTYKIT_URL}/party/${pollId}`, { method: "GET", next: { revalidate: 0 } }); if (!req.ok) { if (req.status === 404) { notFound(); } else { throw new Error("Something went wrong."); } } ``` -------------------------------- ### Deploy PartyKit with Variables from .env File Source: https://docs.partykit.io/guides/managing-environment-variables This command deploys your PartyKit application and includes environment variables defined in a local `.env` file. This method takes precedence over globally deployed secrets for this specific deployment. ```bash npx partykit deploy --with-vars ``` -------------------------------- ### Bad: Loading All State on Startup and Persisting Entire State Source: https://docs.partykit.io/guides/scaling-partykit-servers-with-hibernation This snippet illustrates an inefficient pattern for hibernating PartyKit servers. It loads the entire state on startup and persists the whole state on every update, which can lead to significant performance issues and high costs with large datasets. ```typescript type AllItems = Record; export default class Server implements Party.Server { options: Party.ServerOptions = { hibernate: true }; constructor(readonly room: Party.Room) {} async onStart() { // BAD // we load full state from storage on start (may be big) this.items = await this.room.storage.get("state"); }; async onMessage(websocketMessage: string) { const event = JSON.parse(websocketMessage); if (event.type === "create") { this.items[event.id] = event.data; this.room.broadcast(event.data); }; if (event.type === "update") { const item = this.items[event.id]; this.items[event.id] = { ...item, ...event.data, }; }; // BAD // we need to persist the whole state again (expensive) await this.room.storage.put("items", this.items); }; }; ``` -------------------------------- ### Verify HTTP Request Token with Clerk Source: https://docs.partykit.io/guides/authentication Implement the `onBeforeRequest` handler to verify the `Authorization` header. This example uses Clerk for JWT verification. Returns an unauthorized response if verification fails. ```typescript import type * as Party from "partykit/server"; import { verifyToken } from "@clerk/backend"; const DEFAULT_CLERK_ENDPOINT = "https://clerk.yourdomain.com"; export default class Server implements Party.Server { static async onBeforeRequest(request: Party.Request) { try { // get authentication server url from environment variables (optional) const issuer = lobby.env.CLERK_ENDPOINT || DEFAULT_CLERK_ENDPOINT; // get token from request headers const token = request.headers.get("Authorization") ?? ""; // verify the JWT (in this case using clerk) await verifyToken(token, { issuer }); // forward the request onwards on onRequest return request; } catch (e) { // authentication failed! // short-circuit the request before it's forwarded to the party return new Response("Unauthorized", { status: 401 }); } } onRequest(req: Party.Request) { return new Response(`Hello from party!`); } } ``` -------------------------------- ### Custom WebSocket Options Source: https://docs.partykit.io/reference/partysocket-api Explains how to provide custom options, such as a different WebSocket constructor or connection timeouts, when creating a `WebSocket` instance. ```APIDOC ## Custom WebSocket Options ### Description Pass an `options` object to the `WebSocket` constructor to customize its behavior, such as specifying a custom WebSocket implementation or setting connection timeouts and retry limits. ### Parameters * **WebSocket** (constructor, optional) - A custom WebSocket constructor to use (e.g., `ws` from the `ws` package). * **connectionTimeout** (number, optional) - The timeout in milliseconds for establishing a connection. * **maxRetries** (number, optional) - The maximum number of times to retry the connection upon failure. ### Request Example ```typescript import { WebSocket } from "partysocket"; import WS from "ws"; const options = { WebSocket: WS, // custom WebSocket constructor connectionTimeout: 1000, maxRetries: 10 }; const ws = new WebSocket("wss://my.site.com", [], options); ``` ``` -------------------------------- ### Define the main party in partykit.json Source: https://docs.partykit.io/guides/using-multiple-parties-per-project This is the default configuration for a single party project. ```json { "name": "multiparty", "main": "src/server.ts" } ``` -------------------------------- ### Handle Incoming HTTP Requests in PartyKit Server Source: https://docs.partykit.io/guides/responding-to-http-requests Implement the `onRequest` handler in a PartyKit server to process incoming HTTP requests. Supports POST for adding messages and GET for retrieving them. ```typescript import type * as Party from "partykit/server"; export default class MessageServer implements Party.Server { messages: string[] = []; constructor(readonly room: Party.Room) {} async onRequest(request: Party.Request) { // push new message if (request.method === "POST") { const payload = await request.json<{ message: string }>(); this.messages.push(payload.message); this.room.broadcast(payload.message); return new Response("OK"); } // get all messages if (request.method === "GET") { return new Response(JSON.stringify(this.messages)); } return new Response("Method not allowed", { status: 405 }); } } ``` -------------------------------- ### Deploy to a Custom Domain with Preview Source: https://docs.partykit.io/guides/preview-environments When deploying to your own Cloudflare account, you can specify a custom domain and a preview environment name. This allows for more control over your deployment URLs. ```bash partykit deploy --domain mydomain.com --preview my-preview ``` -------------------------------- ### Update Alarm on Data Read Source: https://docs.partykit.io/guides/scheduling-tasks-with-alarms This example shows how to update the storage expiry alarm when data is read from the room. This ensures that storage persists for 30 days since the last read operation. ```typescript onConnect(connection: Party.Connection) { // do something, and save to storage connection.send(await this.room.storage.get(data.id)); await this.room.storage.setAlarm(Date.now() + EXPIRY_PERIOD_MILLISECONDS); } ``` -------------------------------- ### Tail Project Logs Source: https://docs.partykit.io/reference/partykit-cli View live logs for your PartyKit project, useful for debugging. You can specify the project name. ```bash npx partykit tail ``` ```bash npx partykit tail --name my-project ``` -------------------------------- ### Configure Yjs Server with Persistence and Read-Only Options Source: https://docs.partykit.io/reference/y-partykit-api Enhance the Yjs server setup with options for persistence and read-only mode. The `persist` option can be set to 'snapshot' or 'history', and `readOnly` can disable editing. ```typescript import type * as Party from "partykit/server"; import { onConnect } from "y-partykit"; export default class YjsServer implements Party.Server { constructor(public room: Party.Room) {} onConnect(conn: Party.Connection) { return onConnect(conn, this.room, { // experimental: persists the document to partykit's room storage persist: { mode: "snapshot" }, // enable read only access to true to disable editing, default: false readOnly: true, // Or, you can load/save to your own database or storage async load() { // load a document from a database, or some remote resource // and return a Y.Doc instance here (or null if no document exists) }, callback: { async handler(yDoc) { // called every few seconds after edits // you can use this to write to a database // or some external storage }, // control how often handler is called with these options debounceWait: 10000, // default: 2000 ms debounceMaxWait: 20000, // default: 10000 ms timeout: 5000 // default: 5000 ms } }); } } ``` -------------------------------- ### Authenticate with PartyKit Source: https://docs.partykit.io/reference/partykit-cli Authenticate with the PartyKit service by opening a browser window for GitHub authentication. Automatic login occurs on first `deploy` or `env` command usage if not manually logged in. ```bash npx partykit login ``` -------------------------------- ### Type Safety Example for Zod Schemas Source: https://docs.partykit.io/guides/validating-client-inputs Demonstrates how Zod's TypeScript inference provides type safety within switch statements, ensuring that message properties are correctly typed based on their schema. ```typescript case "remove": // @ts-expect-error RemoveMessage does not have `item` data.item; break; ``` -------------------------------- ### Create a Vectorize Index Source: https://docs.partykit.io/reference/partykit-ai Commands to create a new Vectorize index, specifying dimensions and metric, or using a preset model. ```bash npx partykit vectorize create my-index --dimensions --metric # or npx partykit vectorize create my-index --preset # where is one of: # - @cf/baai/bge-small-en-v1.5 # - @cf/baai/bge-base-en-v1.5 # - @cf/baai/bge-large-en-v1.5 # - openai/text-embedding-ada-002 ``` -------------------------------- ### Set and Clear Room Storage with Alarms Source: https://docs.partykit.io/guides/scheduling-tasks-with-alarms This example demonstrates how to set an alarm to expire room storage after a defined period of inactivity. The alarm is updated on every data save. If the alarm triggers, all storage in the room is cleared. ```typescript const EXPIRY_PERIOD_MILLISECONDS = 30 * 24 * 60 * 60 * 1000; // 30 days export default class UserSession implements Party.Server { onMessage(message: string) { const data = JSON.parse(message); // do something, and save to storage await this.room.storage.put(data.id, data); await this.room.storage.setAlarm(Date.now() + EXPIRY_PERIOD_MILLISECONDS); } onAlarm() { // clear all storage in this room await this.room.storage.deleteAll(); } } ``` -------------------------------- ### Basic Party.Server Implementation Source: https://docs.partykit.io/reference/partyserver-api The fundamental structure for a PartyKit server, implementing the Party.Server interface. Assumes TypeScript. ```typescript import type * as Party from "partykit/server"; export default class Server implements Party.Server {} ``` -------------------------------- ### PartyKit Server Implementation Source: https://docs.partykit.io/tutorials/add-partykit-to-a-nextjs-app/2-set-up-server This TypeScript code defines the PartyKit server for handling HTTP requests. It manages poll data in memory and responds to POST requests to create polls and GET requests to retrieve poll data. ```typescript import type * as Party from "partykit/server"; import type { Poll } from "@/app/types"; export default class Server implements Party.Server { constructor(readonly room: Party.Room) {} poll: Poll | undefined; async onRequest(req: Party.Request) { if (req.method === "POST") { const poll = (await req.json()) as Poll; this.poll = { ...poll, votes: poll.options.map(() => 0) }; } if (this.poll) { return new Response(JSON.stringify(this.poll), { status: 200, headers: { "Content-Type": "application/json" } }); } return new Response("Not found", { status: 404 }); } } Server satisfies Party.Worker; ``` -------------------------------- ### Create a vector index Source: https://docs.partykit.io/reference/partykit-ai Use this command to create a new vector index with specified dimensions and metric. ```bash $ npx partykit vectorize create tutorial-index --dimensions=3 --metric=cosine ``` -------------------------------- ### Party.Server.options Source: https://docs.partykit.io/reference/partyserver-api The `options` field allows customization of PartyServer behavior, such as enabling or disabling hibernation. ```APIDOC ## Party.Server.options You can define an `options` field to customise the PartyServer behaviour. ```typescript import type * as Party from "partykit/server"; export default class Server implements Party.Server { readonly options = { hibernate: false }; } ``` ##### Party.Server.options.hibernate Whether the PartyKit platform should remove the server from memory between HTTP requests and WebSocket messages. The default value is `false`. **Related guide:** Scaling PartyKit Servers with Hibernation ``` -------------------------------- ### Connecting to Other WebSocket Servers Source: https://docs.partykit.io/reference/partysocket-api Demonstrates using the `WebSocket` class from `partysocket` to connect to any standard WebSocket server. ```APIDOC ## Connecting to Other WebSocket Servers ### Description Utilize the `WebSocket` class exported from `partysocket` to establish connections with any WebSocket server, not limited to PartyKit. ### Constructor `new WebSocket(url: string | (() => string) | (() => Promise), protocols?: string | string[] | (() => string | string[] | null) | (() => Promise), options?: object)` ### Request Example (Basic) ```typescript import { WebSocket } from "partysocket"; const ws = new WebSocket("wss://my.site.com"); ws.addEventListener("open", () => { ws.send("hello!"); }); ``` ``` -------------------------------- ### Verify WebSocket Connection Token with Clerk Source: https://docs.partykit.io/guides/authentication Implement the `onBeforeConnect` handler to verify the JWT token received in the query string. This example uses Clerk for verification and sets a user ID header for subsequent handlers. Returns an unauthorized response if verification fails. ```typescript import * as Party from "partykit/server"; import { verifyToken } from "@clerk/backend"; const DEFAULT_CLERK_ENDPOINT = "https://clerk.yourdomain.com"; export default class Server implements Party.Server { static async onBeforeConnect(request: Party.Request, lobby: Party.Lobby) { try { // get authentication server url from environment variables (optional) const issuer = lobby.env.CLERK_ENDPOINT || DEFAULT_CLERK_ENDPOINT; // get token from request query string const token = new URL(request.url).searchParams.get("token") ?? ""; // verify the JWT (in this case using clerk) const session = await verifyToken(token, { issuer }); // pass any information to the onConnect handler in headers (optional) request.headers.set("X-User-ID", session.sub); // forward the request onwards on onConnect return request; } catch (e) { // authentication failed! // short-circuit the request before it's forwarded to the party return new Response("Unauthorized", { status: 401 }); } } onConnect( connection: Party.Connection, { request }: Party.ConnectionContext ) { const userId = request.headers.get("X-User-ID"); connection.send(`Hello ${userId} from party!`); } } ``` -------------------------------- ### Push Environment Variables to Platform Source: https://docs.partykit.io/reference/partykit-cli Deploy environment variables from `partykit.json` to the PartyKit platform. A subsequent `npx partykit deploy` is required for the variables to take effect. ```bash npx partykit env push ``` -------------------------------- ### Basic PartySocket Usage Source: https://docs.partykit.io/reference/partysocket-api Connect to a PartyKit server using PartySocket. Configure host, room, and optionally an ID, party, or query parameters. ```typescript import PartySocket from "partysocket"; const ws = new PartySocket({ host: "project-name.username.partykit.dev", // or localhost:1999 in dev room: "my-room", // add an optional id to identify the client, // if not provided, a random id will be generated // note that the id needs to be unique per connection, // not per user, so e.g. multiple devices or tabs need a different id id: "some-connection-id", // optionally, specify the party to connect to. // if not provided, will connect to the "main" party defined in partykit.json party: "main", // optionally, pass an object of query string parameters to add to the request query: async () => ({ token: await getAuthToken() }) }); // optionally, update the properties of the connection // (e.g. to change the host or room) ws.updateProperties({ host: "another-project.username.partykit.dev", room: "my-new-room" }); ws.reconnect(); // make sure to call reconnect() after updating the properties ``` -------------------------------- ### Party.Server.onBeforeRequest Source: https://docs.partykit.io/reference/partyserver-api Runs before any HTTP request is made to the party. It can modify the request or return a Response to short-circuit it. ```APIDOC ## `static` onBeforeRequest ### Description Runs before any HTTP request is made to the party. You can modify the `request` before it is forwarded to the party, or return a `Response` to short-circuit it. Receives an instance of `Party.Request`, and is expected to either return a request, or a standard Fetch API `Response`. ### Method Signature ```typescript static async onBeforeRequest(req: Party.Request, lobby: Party.Lobby, ctx: Party.ExecutionContext): Promise ``` ### Notes Because the static `onBeforeRequest` method runs in an edge worker near the user instead of in the room, it doesn’t have access to `Party` room resources such as storage. Instead, you can access a subset of its properties via a `Party.Lobby`. ### Example Usage ```typescript import type * as Party from "partykit/server"; export default class Server implements Party.Server { static async onBeforeRequest( req: Party.Request, lobby: Party.Lobby, ctx: Party.ExecutionContext ) { return new Response("Access denied", { status: 403 }); } // ... other methods } ``` ``` -------------------------------- ### Configure Global Constants Source: https://docs.partykit.io/reference/partykit-configuration Define global constants for your project, which will be substituted into your code. Values are provided as strings. ```json { "define": { "MY_CONSTANT": "'my value'", "process.env.MY_MAGIC_NUMBER": "1" } } ``` -------------------------------- ### Dynamic Protocols Provider Source: https://docs.partykit.io/reference/partysocket-api Illustrates how to use functions to dynamically provide WebSocket subprotocols during connection. ```APIDOC ## Dynamic Protocols Provider ### Description The `protocols` parameter can be a function that returns the desired subprotocols. This supports returning `null`, a single `string`, an array of `string`s, or a `Promise` resolving to any of these. ### Usage Provide `null`, a `string`, `string[]`, a function returning any of these, or a function returning a `Promise` resolving to any of these. ### Request Example (String Protocol) ```typescript import { WebSocket } from "partysocket"; const ws = new WebSocket("wss://your.site.com", "your protocol"); ``` ### Request Example (Round Robin Protocols) ```typescript import WebSocket from 'partysocket'; const protocols = ['p1', 'p2', ['p3.1', 'p3.2']]; let protocolsIndex = 0; const protocolsProvider = () => protocols[protocolsIndex++ % protocols.length]; const ws = new WebSocket('wss://your.site.com', protocolsProvider); ``` ``` -------------------------------- ### Connect a Yjs Client to the Server Source: https://docs.partykit.io/reference/y-partykit-api Use the YPartyKitProvider to connect a Yjs document to a running y-partykit server. Ensure the host and document name match the server configuration. ```typescript import YPartyKitProvider from "y-partykit/provider"; import * as Y from "yjs"; const yDoc = new Y.Doc(); const provider = new YPartyKitProvider( "localhost:1999", "my-document-name", yDoc ); ``` -------------------------------- ### Configure Static Assets Path in partykit.json Source: https://docs.partykit.io/guides/serving-static-assets Specify the directory containing static assets to be served by PartyKit using the 'serve' field in your partykit.json. ```json { //... "serve": "path/to/assets" } ``` -------------------------------- ### PartySocket Constructor Source: https://docs.partykit.io/reference/partysocket-api Initializes a new PartySocket client. Provide the WebSocket URL and optionally protocols and configuration options. ```typescript constructor(url: UrlProvider, protocols?: ProtocolsProvider, options?: Options) ``` -------------------------------- ### Deploy PartyKit with Inline Environment Variables Source: https://docs.partykit.io/guides/managing-environment-variables Specify environment variables directly on the command line during deployment. This is useful for CI environments or when not using a `.env` file. These variables will override any previously deployed secrets for this deployment. ```bash npx partykit deploy --var API_KEY=$API_KEY --var HOST=$HOST ``` -------------------------------- ### Accessing Other Parties in FetchLobby Source: https://docs.partykit.io/reference/partyserver-api Demonstrates how to access and interact with other parties within the same project using FetchLobby. Useful for inter-party communication. ```javascript const otherParty = lobby.parties.other; const otherPartyInstance = otherParty.other.get("room-id"); const req = await otherRoom.fetch({ method: "GET" }); const res = await req.json(); ``` -------------------------------- ### Implement PartyKit Server Logic Source: https://docs.partykit.io/how-partykit-works Define the behavior of your PartyKit server using the `Party.Server` interface. Implement methods like `onRequest`, `onConnect`, and `onMessage` to handle different types of interactions. ```typescript export default class Server implements Party.Server { constructor(readonly room: Party.Room) {} onRequest(req: PartyRequest) { return new Response("Hello via HTTP"); }, onConnect(connection: PartyConnection) { connection.send("Hello via WebSockets"); }, onMessage(message: string) { this.room.broadcast(`Received ${message} via WebSockets`); } } ``` -------------------------------- ### Send HTTP Request using PartySocket.fetch Utility Source: https://docs.partykit.io/guides/responding-to-http-requests Utilize the PartySocket.fetch utility to simplify constructing URLs and sending HTTP requests to a PartyKit room. It automatically handles protocol and host details. ```javascript PartySocket.fetch( { host: PARTYKIT_HOST, room: roomId }, { method: "POST", body: JSON.stringify({ message: "Hello!" }) } ); ```