Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 0 additions & 31 deletions .changeset/authorization-core.md

This file was deleted.

32 changes: 0 additions & 32 deletions .changeset/database-transactions.md

This file was deleted.

13 changes: 13 additions & 0 deletions .changeset/drop-server-tier.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
---

Scope the module to the browser and Node scripts: removed the 13 server-tier packages
(`authentication`, `authorization`, `database`, `distributedlock`, `email`, `healthcheck`,
`idempotency`, `llm`, `messagequeue`, `notifications`, `search`, `secrets`, `uploads`).

Release-neutral for everything that remains — no kept package imported a dropped one, so no
surviving package's code or public surface changed. The dropped packages simply stop being
published; consumers of a previously published version keep it.

Pending changesets for `@primandproper/authorization`, `@primandproper/database` and
`@primandproper/idempotency` were removed along with their packages.
33 changes: 0 additions & 33 deletions .changeset/idempotency-port.md

This file was deleted.

19 changes: 12 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ Guidance for Claude Code when working in this repository.

## Project Overview

`@primandproper/platform-ts` is a TypeScript monorepo of isomorphic infrastructure
abstractions — the TypeScript sibling of `platform-go`. Each package exposes a stable
interface with swappable provider implementations selected by config. pnpm workspace,
Turborepo, ESM-only, Node 20+.
`primitives-ts` is a TypeScript monorepo of isomorphic infrastructure abstractions — the
TypeScript sibling of `primitives-go`. Each package exposes a stable interface with
swappable provider implementations selected by config. pnpm workspace, Turborepo,
ESM-only, Node 20+.

**Scope is the browser and Node scripts.** No service is written in TypeScript —
`platform-go` is the only server tier — so a package whose reason to exist is sitting
beside a database, a broker, an object store or a secret manager does not belong here.
Talking to a service built on `platform-go` is `platform-client-ts`'s job, not this
module's. When in doubt: would a browser tab or a one-off script ever construct this? If
no, it is out of scope.

## Common Commands

Expand All @@ -26,7 +33,7 @@ Run one package's tests: `pnpm --filter @primandproper/cache test`.

## Package modality (the core architectural rule)

Every package is exactly one of three modalities. This drives its `package.json`
Every package is exactly one of two modalities. This drives its `package.json`
`exports`, its tsup entries, and its lint rules.

- **Universal** — pure logic, one build, no env-specific code. **No Node built-ins, no DOM
Expand All @@ -35,8 +42,6 @@ Every package is exactly one of three modalities. This drives its `package.json`
Two build entries (`src/index.node.ts`, `src/index.browser.ts`) wiring different default
providers behind an **identical** interface + factory signature, so call-site code is
copy-paste portable between contexts. e.g. `observability`, `cache`.
- **Server-only** — Node bundle, `node`/`default` exports only (no `browser`). May use Node
built-ins. e.g. `secrets`, `database`.

Conditional `exports` shape for isomorphic packages:

Expand Down
71 changes: 30 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# platform-ts
# primitives-ts

Isomorphic infrastructure abstractions for TypeScript — the sibling of `platform-go`.
Isomorphic infrastructure abstractions for TypeScript — the sibling of `primitives-go`.

Each package exposes a stable interface with swappable providers selected by config. Most
packages are **isomorphic**: the same import resolves to the right implementation whether
it runs on Node or in the browser, so call-site code (e.g. logging) is copy-paste portable
between backend and frontend.
between a script and a page.

**Scope: the browser and Node scripts.** No service is built in TypeScript — `platform-go`
is the only server tier there is — so this module carries nothing that exists to run beside
a database, a broker or a secret manager. Code that needs to _talk_ to a service built on
`platform-go` wants `platform-client-ts`, not this.

## Packages

Every package is exactly one of three modalities (see `CLAUDE.md`): **universal** (pure
logic, one build), **isomorphic** (same import resolves per-environment), **server-only**
(Node bundle, may use Node built-ins).
Every package is exactly one of two modalities (see `CLAUDE.md`): **universal** (pure
logic, one build) or **isomorphic** (same import resolves per-environment).

### Universal

Expand All @@ -26,46 +30,31 @@ logic, one build), **isomorphic** (same import resolves per-environment), **serv
| `@primandproper/encoding` | `Encoder`/`ServerEncoderDecoder` over JSON, YAML, XML, TOML |
| `@primandproper/circuitbreaking` | Circuit breakers (noop + partitioned) |
| `@primandproper/version` | Build-time version and VCS metadata |
| `@primandproper/qrcodes` | QR code generation, for TOTP setup flows |

### Isomorphic

| Package | Purpose |
| ------------------------------ | ------------------------------------------------------------------------- |
| `@primandproper/observability` | `Logger` (pino on Node, console in browser) + OTel tracer/meter aliases |
| `@primandproper/cache` | `Cache<T>` (memory/redis on Node, memory/web-storage in browser) |
| `@primandproper/cryptography` | `Encryptor` + `Hasher` over WebCrypto |
| `@primandproper/random` | Cryptographically secure random (hex, base32, base64url) over WebCrypto |
| `@primandproper/compression` | `Compressor` interface with swappable providers |
| `@primandproper/cookies` | `CookieStore` interface with swappable providers |
| `@primandproper/httpclient` | Thin `fetch` wrapper with OpenTelemetry spans |
| `@primandproper/ratelimiting` | `RateLimiter` interface with swappable providers |
| `@primandproper/eventstream` | `EventStream` over SSE and WebSocket |
| `@primandproper/analytics` | `EventReporter` interface with swappable providers |
| `@primandproper/eventcapture` | Non-blocking high-volume event capture draining to a swappable sink |
| `@primandproper/idempotency` | At-most-once execution per client key (manager on Node, keys in either) |
| `@primandproper/authorization` | Synchronous permission checks everywhere, policy resolution on the server |

### Server-only

| Package | Purpose |
| -------------------------------- | ---------------------------------------------------------------- |
| `@primandproper/secrets` | `SecretSource` interface with swappable providers |
| `@primandproper/authentication` | Password hashing, TOTP, and tokens |
| `@primandproper/email` | `Email` sending interface with swappable providers |
| `@primandproper/uploads` | `UploadManager` object storage with swappable providers |
| `@primandproper/messagequeue` | `Publisher`/`Consumer` interfaces with swappable providers |
| `@primandproper/notifications` | `AsyncNotifier` publisher + mobile `PushNotificationSender` |
| `@primandproper/distributedlock` | Acquire/release/refresh distributed locks |
| `@primandproper/featureflags` | `FeatureFlagManager` with typed evaluation, OpenFeature-backed |
| `@primandproper/search` | Text + document index/search interfaces with swappable providers |
| `@primandproper/llm` | LLM completions over Anthropic and OpenAI |
| `@primandproper/healthcheck` | `Checker` + `Registry` aggregating component health |
| `@primandproper/qrcodes` | QR code generation, for TOTP setup flows |
| Package | Purpose |
| ------------------------------ | ----------------------------------------------------------------------- |
| `@primandproper/observability` | `Logger` (pino on Node, console in browser) + OTel tracer/meter aliases |
| `@primandproper/cache` | `Cache<T>` (memory/redis on Node, memory/web-storage in browser) |
| `@primandproper/cryptography` | `Encryptor` + `Hasher` over WebCrypto |
| `@primandproper/random` | Cryptographically secure random (hex, base32, base64url) over WebCrypto |
| `@primandproper/compression` | `Compressor` interface with swappable providers |
| `@primandproper/cookies` | `CookieStore` interface with swappable providers |
| `@primandproper/httpclient` | Thin `fetch` wrapper with OpenTelemetry spans |
| `@primandproper/ratelimiting` | `RateLimiter` interface with swappable providers |
| `@primandproper/eventstream` | `EventStream` over SSE and WebSocket |
| `@primandproper/analytics` | `EventReporter` interface with swappable providers |
| `@primandproper/eventcapture` | Non-blocking high-volume event capture draining to a swappable sink |
| `@primandproper/featureflags` | `FeatureFlagManager` with typed evaluation, OpenFeature-backed |

## Parity with platform-go
## Parity with primitives-go

`platform-go` is the source of truth. See [`PORT_PROGRESS.md`](./PORT_PROGRESS.md) for the
full package- and provider-level parity breakdown, scope decisions, and remaining work.
`primitives-go` is the source of truth for behaviour, but **not for scope**: parity is
deliberately partial. A package lands here when something in the browser or a Node script
needs it, and packages that only make sense beside server infrastructure are absent on
purpose rather than pending.

## Development

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@primandproper/platform-ts",
"name": "@primandproper/primitives-ts",
"version": "0.0.0",
"private": true,
"type": "module",
Expand Down
11 changes: 0 additions & 11 deletions packages/authentication/CHANGELOG.md

This file was deleted.

39 changes: 0 additions & 39 deletions packages/authentication/package.json

This file was deleted.

Loading
Loading