Files
pubsub/docs/architecture/decisions/002-tree-shake-pattern.md
glm-5.1 8c025c3433 Set up project structure, source files, and architecture docs
- 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)
2026-04-30 10:20:41 +00:00

2.0 KiB

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 declarationimport { 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