@stainless-code/persist is a small, freshly extracted library. Before large PRs, please open an issue so we can align on:
- Public surface — anything exported from an entry point (
src/core/index.tsand the opt-in adapter subpaths) is the public API and must carry JSDoc that reads well in hovers and published typings. Seedocs/architecture.mdfor the seam model. - Runtimes — Node
^20.19.0 || >=22.12.0and Bun>=1.0.0(package.jsonengines). The core is zero-dep by design (enforced by a gate test on bothpersist-core.tsandhydration.ts); each subpath owns its optional peer.
bun install # runs `prepare` → Husky git hooks
bun test ./src # bun:test unit tests
bun run test:dom # vitest + jsdom — React useHydrated reactivity (DOM) tests
bun run typecheck # tsgo --noEmit
bun run lint # oxlint
bun run format # oxfmt
bun run build # tsdown → dist/ (one file per entry, mirroring src)
bun run docs:api # TypeDoc → apps/docs/content/reference/api (MDX)
bun run check # build, then format:check + lint:ci + test + test:dom + typecheck (in parallel)
bun run check-updates # interactive dependency updates (`bun update -i --latest`)
bun run clean # remove untracked/ignored build artifacts (keeps .env)The test suite is split by what it needs: bun:test for src/**/*.test.ts (no DOM), and vitest + jsdom + @testing-library/react for tests-dom/**/*.test.{ts,tsx} (the React useHydrated rerender path). See docs/architecture.md § Test matrix.
Branch main is the line of development for this personal repo. Open a pull request for anything non-trivial and merge after CI passes — the single CI complete job is the unambiguous green/red signal.
git fetch origin && git checkout main && git pull
git checkout -b your-branch-name
# … commit …
git push -u origin your-branch-nameThen open a PR on GitHub into main. PRs that change the public docs site (apps/docs/**) should carry the docs label — merge deploys https://stainless-code.com/persist (see .github/workflows/deploy-docs.yml).
Husky + lint-staged — see .husky/pre-commit. Every commit runs lint-staged on staged files: bun run format:check (oxfmt --check), oxlint, staged-only tsgo, and bun test on *.test.ts / paired co-located tests.
Match Oxfmt/Oxlint; prefer straight-line code and extracted helpers over long nested blocks. Existing source comments are preserved — never delete a TODO / FIXME / commented-out block without asking (see .agents/rules/authoring-discipline.md).
@changesets/cli — run bunx changeset when your PR should bump the version, and commit the .changeset/*.md file. The Release workflow opens a "Version packages" PR and publishes to npm on merge via trusted publishing (GitHub OIDC; no NPM_TOKEN); Sigstore provenance is auto-generated.
Release git uses a GitHub App install token (Contents + Pull requests + Workflows) so tag push works after workflow edits — GITHUB_TOKEN cannot.
One-time App setup (org owner):
- Create an App under the org (New GitHub App) — name e.g.
stainless-code-release; homepage any; no webhook. - Repository permissions: Contents, Pull requests, Workflows — read/write.
- Install on
stainless-code/persist. - Repo
releaseenvironment: variableRELEASE_APP_CLIENT_ID; secretRELEASE_APP_PRIVATE_KEY(PEM).
Use the GitHub issue templates — Bug vs Feature / adapter proposal (see .github/ISSUE_TEMPLATE/).
Rules live under .agents/rules/ as .md files; skills under .agents/skills/<name>/SKILL.md. Symlink into .cursor/ with .mdc extension (Cursor requires .mdc for frontmatter parsing; see .agents/rules/agents-first-convention.md). Inventory and tier system: .agents/README.md and .agents/rules/agents-tier-system.md.
Thank you for making hydration-aware persistence reusable across stores and frameworks.