chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
# Changesets
Releases run through [changesets](https://github.com/changesets/changesets). Add
one in the same commit as the change it describes:
```bash
npm run changeset # describe the change, pick a bump
npm run version-packages # apply pending changesets, write CHANGELOGs
npm run release # build, then publish
```
`release` builds first because the `.d.ts` files are generated output — they
have to exist before packing, or the published packages ship without types.
## Two release groups
The ten runtime and adapter packages are a **fixed** group: one version across
all of them, always released together. A consumer cannot end up with
`@pdsjs/node` built against a different `@pdsjs/core` than it expects, which is
the failure mode a repo full of independently-versioned packages invites.
Internal `workspace:*` ranges resolve to that exact version at pack time.
`@pdsjs/spaces` versions on its own, and must stay out of the fixed group.
Inside it, **every** release escalated to a major regardless of what the
changesets asked for — a minor and a patch shipped as 2.0.0 with no
`### Major Changes` in any changelog. Measured from a 2.0.0 baseline with a
single `core: minor` changeset:
| fixed group | result |
|---|---|
| all eleven packages | 3.0.0 |
| spaces excluded | 2.1.0 |
| no fixed group | 2.1.0 |
`@pdsjs/cloudflare` depends on spaces and cannot defer the import — the Durable
Object constructor is synchronous — so a spaces bump still propagates to the
whole group. That is one major per upstream change to
[proposal 0016](https://github.com/bluesky-social/proposals/tree/main/0016-permissioned-data),
which is the price of the coupling; it is not a reason to put spaces back in the
group and pay a major on every release instead. The lever on the remaining
propagation is that cloudflare import, not the release config.
`npm run version-packages` refuses to continue if the version moves further
than any changeset asked for, because this failure was otherwise invisible
until after publishing.
## `@pdsjs/account-ui` is a private devDependency
`@pdsjs/account-ui` (the built account-page bundle) is imported by both
`@pdsjs/node` (dynamically) and `@pdsjs/cloudflare` (statically, for the
synchronous Durable Object constructor), and both are in the fixed group. It is
**private** (never published) and declared a **devDependency** of both, on
purpose — do not change either.
- **Private**, because it is an internal build input: the fixed-group packages
inline it at build time and nobody installs it standalone. Being private keeps
it out of changeset versioning entirely (`privatePackages.version: false`), so
it needs no changeset and has no npm version to reconcile.
- **devDependency, not `dependencies`/`peerDependencies`**, for two reasons.
First, a published package must not carry a private (unpublished) package in
its runtime deps, or consumers cannot install it — a devDependency is not
installed by consumers, so this is fine. Second, declaring it a runtime or
even an optional peer dependency escalated *every* account-ui change into a
whole-group **major**: `workspace:*` pins the exact version, so any bump read
as out-of-range and the fixed group carried the escalation with a version
number ahead of its changelog.
Because it is decoupled, an account-ui change does **not** auto-bump the fixed
group. To ship a UI change, add a changeset for the fixed group (e.g.
`@pdsjs/core` patch) so those packages republish with the rebuilt bundle.
Private packages (the examples) are neither versioned nor published.