Files
suaveplan/openspec/archive/2026-05-26-api-events-in-memory/specs/api-events-in-memory/spec.md
2026-05-27 23:29:53 +01:00

3.0 KiB

Capability Spec Delta: api-events-in-memory (api-events-in-memory)

Package: @suaveplan/api-events-in-memory Status: PROPOSED

ADDED Requirements

Requirement: Wraps the real @suaveplan/events bus

The factory SHALL construct an EventBusLike by delegating to @suaveplan/events's createEventBus. Subscribers receive events as the real bus delivers them; this package only adds a recording layer around publish.

Scenario: subscriber receives published payload

  • WHEN a subscriber is registered on "billing.invoice.created" AND a payload is published
  • THEN the subscriber is invoked with the exact payload

Verified by: src/factory/create-in-memory-events-bus.test.ts::"subscriber receives published payload"


Requirement: published(topic) returns history

host.events.published(topic) SHALL return an array of every payload published to topic since the last reset() (or since construction), in publish order.

Scenario: history captures every publish in order

  • WHEN three payloads [A, B, C] are published to "x"
  • THEN host.events.published("x") returns [A, B, C] in that order

Scenario: reset clears history

  • WHEN host.events.reset() is called after publishes
  • THEN host.events.published("x") returns [] AND already-registered subscribers stay registered

Scenario: history bounded by maxHistoryPerTopic

  • WHEN maxHistoryPerTopic: 10 is configured AND 11 payloads are published
  • THEN publish either throws EVENTS_IN_MEMORY_HISTORY_OVERFLOW OR drops the oldest payload (the chosen policy is documented and tested both ways)

Verified by: src/factory/create-in-memory-events-bus.test.ts::"history captures every publish in order" AND src/factory/create-in-memory-events-bus.test.ts::"reset clears history without unregistering subscribers" AND src/history/history.test.ts::"bounds history at maxHistoryPerTopic"


Requirement: Conforms to EventsBus contract

The factory SHALL pass runEventsBusConformance from @suaveplan/api-events/testing (which itself wraps the conformance defined for @suaveplan/events plus any API-foundation specifics — error semantics, payload-id idempotency).

Scenario: conformance suite passes

  • WHEN runEventsBusConformance("in-memory-direct", () => createInMemoryEventsBus(...)) runs
  • THEN every invariant passes

Verified by: src/factory/create-in-memory-events-bus.spec-conformance.test.ts::"in-memory-direct conforms to EventsBus contract"


Requirement: Registered in api-host/testing adapter table

Scenario: createTestHost resolves the sentinel

  • WHEN createTestHost({ adapters: { events: "in-memory" } })
  • THEN the resulting host.events is an instance produced by this factory AND has a published(topic) method

Verified by: tests/integration/integration.test.ts::"createTestHost resolves events:\"in-memory\" to this adapter and exposes published()"