~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
145 lines · 4.6 KB Raw History
# Contributing

## Setup

```bash
git clone https://tangled.org/chadtmiller.com/pds.js
cd pds.js && pnpm install
npm run build:ui
```

Install with pnpm. The workspace dependencies use the `workspace:*` protocol, and
`npm install` fails on it with `EUNSUPPORTEDPROTOCOL`. The `npm run` scripts work
normally once pnpm has installed the tree.

Run `npm run build:ui` first on a fresh clone. `@pdsjs/account-ui` exports a
gitignored bundle, and without it the node and cloudflare entrypoints do not
resolve.

## Local development

With [`just`](https://github.com/casey/just) and Docker installed, one command
starts the whole stack:

```bash
just dev        # infra, PDS, and a seeded account
just dev-down   # stop the PDS and remove the docker infra
```

`just dev` starts the docker infra (local PLC, relay, Caddy) and runs the PDS on
port 2471. It then registers a mock account with a few records. Open
http://localhost:2471/account and sign in with the printed credentials.

`just dev` serves a prebuilt account interface. There is no hot reload. After you
change interface code, run `npm run build:ui` and refresh the page.

For live interface work, run `just dev-live`. It starts the same stack plus a
Vite dev server with hot module reload on port 5173. Sign in at
http://localhost:5173/account, and your edits reload in the browser. The PDS also
restarts on backend edits. Port 2471 and port 5173 are different origins, so you
sign in separately on each.

Run `just` to see all recipes. `just logs` tails the PDS log.

<details>
<summary>Setup without <code>just</code></summary>

```bash
# Start the local PLC and relay (needs Docker)
docker compose up -d

# Start the PDS
npm run dev:node

# Register with the local PLC, in another terminal
npm run setup -- --pds https://localhost:3443 --plc-url http://localhost:2582 --relay-url http://localhost:2470
```

</details>

## The commit gate

```bash
npm run ci
```

That runs `build:ui`, biome, `tsc --noEmit`, and `test:coverage`. CI runs the
same command. Run it before you commit.

The full gate is heavy: the git integration tests spawn the real `git` binary
against an in-process PDS, and the coverage floors across 195 test files take a
few minutes. You do not need it for every local edit. CI enforces it on every
push, so iterate with the targeted commands below and run the full gate only
before you commit.

The individual steps:

```bash
npm run check       # biome lint + format check
npm run format      # auto-format
npm run lint        # lint only
npm run typecheck   # tsc --noEmit
npm test            # unit tests
npm run test:watch  # unit tests, watching
```

Coverage floors are in `vitest.config.js`, per area rather than global. A glob
key aggregates every file it matches, so give each module its own entry.

## End-to-end tests

The e2e suite is not part of the gate. It needs docker compose.

```bash
docker compose up -d
npm run test:e2e:node
npm run test:e2e:deno
npm run test:e2e:cloudflare
```

The suite binds port 2471, so a `just dev` stack blocks it.

`npm run test:reference` tests permissioned data against the reference
implementation. See [docs/permissioned-data.md](docs/permissioned-data.md).

## Conventions

[CLAUDE.md](CLAUDE.md) holds the conventions this repository enforces by review
rather than by tooling: what earns a comment, how to phrase one, no `any` in
library type annotations, and no em dashes in user-facing copy.

[docs/architecture.md](docs/architecture.md) explains the ports and the packages.
[docs/pds-decomposition.md](docs/pds-decomposition.md) tracks the handler module
work in `core/src/pds.js`. Read it before you take the next cluster.

## Changesets

```bash
npm run changeset
```

Describe the change relative to the previous release. That is where "what
changed" belongs, rather than in a code comment.

## Project structure

```
packages/
  core/               # platform-agnostic core
  spaces/             # permissioned data (optional)
  lexicon-resolver/   # lexicon resolution and record validation
  account-ui/         # account interface
  node/               # Node.js adapter
  deno/               # Deno adapter
  cloudflare/         # Cloudflare adapter
  readonly/           # read-only server for CAR-backed repositories
  storage-sqlite/     # SQLite storage adapter
  blobs-*/            # blob storage adapters
examples/
  node/               # Node.js example
  deno/               # Deno example
  cloudflare/         # Cloudflare example
  runclub/            # permissioned data demo, two PDSes and a syncing app
docker/               # container entrypoint and the local dev stack
scripts/              # setup, seeding, and reference tests
```