- 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)
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:
- Barrel + tree-shaking — single entry point, rely on bundler to drop unused adapters
- Sub-path exports — explicit per-adapter entry points in
package.jsonexports map
Typemap uses barrel-only. Taskgraph uses plain barrel with no sub-path exports.
Decision
Use sub-path exports with optional peer dependencies.
Rationale
-
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. -
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). -
peerDependenciesMeta — npm treats optional peer deps as install warnings, not errors.
npm install @alkdev/pubsubinstalls only the core.npm install @alkdev/pubsub ioredisgets Redis support. -
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.
-
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.jsonexports — 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