diff --git a/Cargo.lock b/Cargo.lock index 049167470..38e8c3b07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1600,7 +1600,7 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "plane" -version = "0.2.0" +version = "0.4.0" dependencies = [ "acme2-eab", "anyhow", diff --git a/README.md b/README.md index 5e3a1c1fa..2a54e606e 100644 --- a/README.md +++ b/README.md @@ -36,52 +36,9 @@ Read more about [Plane’s architecture](https://plane.dev/concepts/architecture [![Architecture diagram of Plane](./docs/public/arch-diagram.svg)](https://plane.dev/concepts/architecture) -## Example +## Learn more -Imagine a multiplayer document editor. When Sam opens a document with ID `abc123`, the application requests a process from Plane with that key. In this case no process is running, so Plane starts a new one. - -When Jane opens the *same* document, the application requests a process from Plane with the same key (`abc123`). This time Plane already has a process running for that key, so it returns a URL which maps to that process. - -As long as either Jane or Sam has document `abc123` open, Plane will keep the process associated with that document running. After **both** Jane and Sam have closed the document, Plane will shut down the process. - -If Carl later opens the same document, Plane will start a _new_ process for him, possibly on a different machine. - -## Quick Start - -This repo includes a Docker Compose file that is suitable for running a local development instance of Plane. - -This works on Linux and Mac systems with Docker installed. - -In the root of this repo, run: - -```bash -docker compose -f docker/docker-compose.yml up -``` - -This tells Docker to run a Postgres database, as well as a minimal Plane stack: one controller, one drone, and one proxy (see below for an explanation). - -The Plane Controller will be available at http://localhost:8080, and the Plane Proxy will be available at http://localhost:9090. - -### Connecting to a process - -The `docker/cli.sh` script runs the Plane CLI, configured to connect to the local Plane Controller. - -```bash -docker/cli.sh connect \ - --wait \ - --cluster 'localhost:9090' \ - --image ghcr.io/drifting-in-space/demo-image-drop-four -``` - -## Running tests - -Tests can be run with `cargo test`, but it can be slow because it does not run tests in parallel and some of the tests are slow. - -You can use `nextest` to run tests in parallel: - -```bash -cargo install nextest -cargo nextest run -j 5 -``` - -The `-j 5` flag tells `nextest` to run 5 tests in parallel. If you set it too high, you may encounter Docker issues. +- Read the [quickstart guide](https://plane.dev/quickstart-guide) +- Learn about [Plane concepts](https://plane.dev/concepts/session-backends) +- See instructions for [building and developing Plane locally](https://plane.dev/developing) +- Read about [production deployment](https://plane.dev/deploy-to-prod) diff --git a/docs/components/logo.tsx b/docs/components/logo.tsx index 351e0bd31..cb3b83e71 100644 --- a/docs/components/logo.tsx +++ b/docs/components/logo.tsx @@ -1,5 +1,15 @@ -export default function PlaneLogo() { - return +export type PlaneLogoProps = { + height?: number +} + +export default function PlaneLogo(props: PlaneLogoProps) { + let height = props.height + let width + if (typeof height === 'number') { + width = height * 4.2125 + } + + return diff --git a/docs/pages/_app.tsx b/docs/pages/_app.tsx index 53c36ed78..67b029f07 100644 --- a/docs/pages/_app.tsx +++ b/docs/pages/_app.tsx @@ -10,7 +10,7 @@ export default function App({ Component, pageProps }: AppProps) { - + ) } diff --git a/docs/pages/api/OpenSans-SemiBold.ttf b/docs/pages/api/OpenSans-SemiBold.ttf new file mode 100644 index 000000000..e5ab46443 Binary files /dev/null and b/docs/pages/api/OpenSans-SemiBold.ttf differ diff --git a/docs/pages/api/og-image.tsx b/docs/pages/api/og-image.tsx new file mode 100644 index 000000000..e1d72337c --- /dev/null +++ b/docs/pages/api/og-image.tsx @@ -0,0 +1,51 @@ +import { ImageResponse } from 'next/og' +import PlaneLogo from '../../components/logo' +import { NextRequest } from 'next/server'; + +export const config = { + runtime: 'edge', +} + +export default async function handler(request: NextRequest) { + const { searchParams } = new URL(request.url); + + const fontData = await fetch( + new URL('OpenSans-SemiBold.ttf', import.meta.url), + ).then((res) => res.arrayBuffer()); + + const title = searchParams.get('title') + + return new ImageResponse( + ( +
+ + {title && ( +
+ docs/{title} +
+ )} +
+ ), + { + fonts: [ + { + name: 'Open Sans', + data: fontData, + style: 'normal', + } + ] + } + ) +} diff --git a/docs/pages/index.mdx b/docs/pages/index.mdx index 3f73aabaa..aef66aa21 100644 --- a/docs/pages/index.mdx +++ b/docs/pages/index.mdx @@ -22,7 +22,7 @@ Use cases include: This documentation refers to the 0.4.0 release of Plane, which is a complete rewrite. These docs are - brand new as of January 2024, and still a work in progres. Please mind the wet paint! + brand new as of January 2024, and still a work in progress. Please mind the wet paint! If anything is unclear in the meantime, please [open a discussion](https://github.com/drifting-in-space/plane/discussions) on Plane’s GitHub. diff --git a/docs/theme.config.jsx b/docs/theme.config.jsx index 81e52d5bf..386dba0ee 100644 --- a/docs/theme.config.jsx +++ b/docs/theme.config.jsx @@ -1,4 +1,5 @@ import { useRouter } from 'next/router' +import { useConfig } from 'nextra-theme-docs' import Logo from './components/logo' export default { @@ -9,6 +10,25 @@ export default { chat: { link: "https://discord.gg/N5sEpsuhh9" }, + head: () => { + const { frontMatter, title } = useConfig() + const { asPath } = useRouter() + + let ogImageUrl = asPath === '/' ? 'https://plane.dev/api/og-image' : `https://plane.dev/api/og-image?title=${encodeURIComponent(title)}` + + return <> + + + + + + + + + }, useNextSeoProps() { const { asPath } = useRouter() if (asPath !== '/') { diff --git a/docs/tsconfig.json b/docs/tsconfig.json index 65348e831..98f159b87 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -15,12 +15,19 @@ "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve" + "jsx": "preserve", + "plugins": [ + { + "name": "next" + } + ], + "strictNullChecks": true }, "include": [ "next-env.d.ts", "**/*.ts", - "**/*.tsx" + "**/*.tsx", + ".next/types/**/*.ts" ], "exclude": [ "node_modules" diff --git a/plane/Cargo.toml b/plane/Cargo.toml index c68553135..81b973561 100644 --- a/plane/Cargo.toml +++ b/plane/Cargo.toml @@ -1,12 +1,13 @@ [package] name = "plane" -version = "0.2.0" +version = "0.4.0" edition = "2021" default-run = "plane" description = "Session backend orchestrator for ambitious browser-based apps." repository = "https://github.com/drifting-in-space/plane" license = "MIT" -readme = "../README.md" +homepage = "https://plane.dev" +readme = "README.md" [dependencies] acme2-eab = "0.5.4" diff --git a/plane/README.md b/plane/README.md new file mode 100644 index 000000000..787ebd5a0 --- /dev/null +++ b/plane/README.md @@ -0,0 +1,27 @@ + + Plane logo + + +[![GitHub Repo stars](https://img.shields.io/github/stars/drifting-in-space/plane?style=social)](https://github.com/drifting-in-space/plane) +[![Docker image](https://img.shields.io/docker/v/plane/plane)](https://hub.docker.com/r/plane/plane/tags) +[![Build Docker Image](https://github.com/drifting-in-space/plane/actions/workflows/build-image.yml/badge.svg)](https://github.com/drifting-in-space/plane/actions/workflows/build-image.yml) +[![Tests](https://github.com/drifting-in-space/plane/actions/workflows/tests.yml/badge.svg)](https://github.com/drifting-in-space/plane/actions/workflows/tests.yml) +[![Chat on Discord](https://img.shields.io/static/v1?label=chat&message=discord&color=404eed)](https://discord.gg/N5sEpsuhh9) + +[Plane](https://plane.dev) is a distributed system for **running stateful WebSocket backends at scale**. Plane is heavily inspired by [Figma’s mulitplayer infrastructure](https://www.figma.com/blog/rust-in-production-at-figma/), which dynamically spawns a process for each active document. + +Use cases include: +- Scaling up [authoritative multiplayer backends](https://driftingin.space/posts/you-might-not-need-a-crdt). +- Running isolated code environments (like REPLs, code notebooks, and LLM agent sandboxes). +- Data-intensive applications that need a dedicated high-RAM process for each active user session. + +Read more about [Plane’s architecture](https://plane.dev/concepts/architecture). + +[![Architecture diagram of Plane](../docs/public/arch-diagram.svg)](https://plane.dev/concepts/architecture) + +## Learn more + +- Read the [quickstart guide](https://plane.dev/quickstart-guide) +- Learn about [Plane concepts](https://plane.dev/concepts/session-backends) +- See instructions for [building and developing Plane locally](https://plane.dev/developing) +- Read about [production deployment](https://plane.dev/deploy-to-prod) diff --git a/plane/src/lib.rs b/plane/src/lib.rs index ebf0e9f24..c900fd5ac 100644 --- a/plane/src/lib.rs +++ b/plane/src/lib.rs @@ -1,5 +1,6 @@ #![warn(clippy::unwrap_used)] #![cfg_attr(test, allow(clippy::unwrap_used))] +#![doc = include_str!("../README.md")] use serde::{Deserialize, Serialize};