- Copy core source from alkhub_ts/packages/core/pubsub/ with import path fixups (typed_event_target.ts → types.ts, .ts → .js extensions) - Make PubSubPublishArgsByKey exported (was private type, needed by barrel) - Add package.json with sub-path exports and optional peer deps (ioredis) - Add tsup.config.ts with multi-entry + splitting for tree-shaking - Add tsconfig.json, vitest.config.ts, .gitignore - Add AGENTS.md with project conventions and adapter checklist - Add architecture docs following taskgraph/alkhub pattern: docs/architecture/README.md, api-surface.md, event-targets.md, iroh-transport.md, build-distribution.md - Add ADRs: 001-graphql-yoga-fork, 002-tree-shake-pattern - Copy migration research doc to docs/research/migration.md - Dual-license MIT OR Apache-2.0 (matching taskgraph)
36 lines
2.0 KiB
Markdown
36 lines
2.0 KiB
Markdown
# ADR-002: Sub-Path Exports + Peer Deps for Adapter Isolation
|
|
|
|
**Status**: Accepted
|
|
**Date**: 2026-04-30
|
|
|
|
## Context
|
|
|
|
Each event target adapter has different peer dependencies (ioredis for Redis, @rayhanadev/iroh for Iroh). Consumers that only use in-process or one adapter should not be forced to install peer deps for adapters they don't use. Two approaches:
|
|
|
|
1. **Barrel + tree-shaking** — single entry point, rely on bundler to drop unused adapters
|
|
2. **Sub-path exports** — explicit per-adapter entry points in `package.json` exports map
|
|
|
|
Typemap uses barrel-only. Taskgraph uses plain barrel with no sub-path exports.
|
|
|
|
## Decision
|
|
|
|
Use sub-path exports with optional peer dependencies.
|
|
|
|
## Rationale
|
|
|
|
1. **Explicit dependency declaration** — `import { createRedisEventTarget } from '@alkdev/pubsub/event-target-redis'` makes it clear at the import site that this module needs ioredis. A barrel import doesn't.
|
|
|
|
2. **No bundler reliance** — sub-path exports don't depend on the consumer's bundler correctly tree-shaking. Not all consumers use bundlers (Deno, Node with `--experimental-strip-types`).
|
|
|
|
3. **peerDependenciesMeta** — npm treats optional peer deps as install warnings, not errors. `npm install @alkdev/pubsub` installs only the core. `npm install @alkdev/pubsub ioredis` gets Redis support.
|
|
|
|
4. **Consistent with typemap's philosophy** — typemap's peer deps (zod, valibot, typebox) are each their own module island. Sub-path exports make this explicit at the package boundary. We're adding the package.json entry points that typemap doesn't have.
|
|
|
|
5. **Incremental** — adapters can be added one at a time. Each new adapter adds one entry to the exports map and one entry point to tsup.
|
|
|
|
## Consequences
|
|
|
|
- More entries in `package.json` exports — maintenance burden scales with adapter count
|
|
- Both barrel and sub-path work — barrel re-exports everything for convenience, sub-path for explicitness
|
|
- tsup must list each adapter as a separate entry point
|
|
- Consumer docs should recommend sub-path imports for adapter-specific code |