Skip to content
CAI
Software that uses CAICheck a score

castore-dev/castore

55.0

Adequate · 21 September 2026

9.5k

lines of production code

TypeScript

with JavaScript

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is an event-sourcing framework that provides core abstractions for managing state through immutable events. It offers a modular architecture with typed command and event definitions, supporting validation via Zod and JSON Schema. The system includes pluggable adapters for message buses (SQS, EventBridge) and event storage (DynamoDB, Redux, HTTP), enabling flexible integration with various backends. Additionally, it provides utilities for data migration, visualization, and in-memory testing.

How it got here

2022 — Initial project scaffolding and core architecture

16 changes.

This period established the foundational structure of the codebase, introducing a monorepo configuration, core event-sourcing abstractions, and a Pokemon-themed demo application. It also modernized the build system by migrating to ESM and Vitest, while implementing key features like automatic retry logic and typed event handling.

2023–2025 — Messaging and adapter expansion

25 changes.

This period focused on expanding the core messaging infrastructure with structured message types, buses, and queues, while introducing a ConnectedEventStore to automate event publishing. The scope broadened to include diverse storage and integration adapters for HTTP, Redux, DynamoDB, AWS EventBridge, and SQS, alongside new command and event type validation using Zod and JSON Schema.

Features

Add EventBridge S3 message bus adapter for oversized payloads

A new \EventBridgeS3MessageBusAdapter\ is introduced to handle messages that exceed the 256KB limit for AWS EventBridge. When a message is too large, the adapter automatically stores the payload in an S3 bucket and sends a pre-signed URL via EventBridge instead. Listeners can use the provided \parseMessage\ utility to automatically fetch and parse these oversized events. This adapter wraps the existing \EventBridgeMessageBusAdapter\ and requires \@aws-sdk/client-eventbridge\, \@aws-sdk/client-s3\, and \@aws-sdk/s3-request-presigner\ as peer dependencies.

packages/message-bus-adapter-event-bridge-s3 · high confidence

Add EventBridge message bus adapter

Users can now integrate their application's message bus with AWS EventBridge. The new \EventBridgeMessageBusAdapter\ handles publishing messages by mapping event store IDs to the EventBridge \source\ field and event types to the \detail-type\ field. The adapter supports batching multiple messages, handles replayed events, and provides TypeScript types for typed message handling.

packages/message-bus-adapter-event-bridge · high confidence

Add HTTP-based event storage adapter

Introduced a new \HttpEventStorageAdapter\ that retrieves and pushes events via an HTTP API defined by a Swagger/OpenAPI document. The adapter uses \swagger-client\ to interact with the remote service, mapping operations like \getEvents\ and \listAggregateIds\ to specific API endpoints. This change adds the core implementation files (\adapter.ts\, \index.ts\), utility functions for API method resolution (\getApiMethod\, \getSwaggerClient\), and associated type definitions, enabling event storage through an HTTP interface.

packages/event-storage-adapter-http/src · high confidence

Add JSON Schema-based event type support

Introduces the \@castore/event-type-json-schema\ package, which provides a \JSONSchemaEventType\ class that extends the standard \EventType\ to validate event payloads and metadata against JSON Schemas using \json-schema-to-ts\. The package includes the core implementation, unit tests, and build configuration files.

packages/event-type-json-schema · high confidence

Add SQS and In-Memory Message Queue Adapters

Users can now connect their message queues to AWS SQS or use an in-memory adapter for local development. The SQS adapter publishes messages to an AWS SQS queue, supporting FIFO queues with message grouping and deduplication, and allows marking messages for replay. The in-memory adapter provides a simple, synchronous queue for testing or local runs. Both adapters implement the standard message queue interface, allowing seamless switching between backends.

packages/message-queue-adapter-sqs · high confidence

Add ZodEventType class for validating event payloads and metadata

A new \ZodEventType\ class has been introduced in the \event-type-zod\ package, allowing users to define event types with optional Zod schemas for both payload and metadata. The implementation supports both Zod v3 and v4, ensuring compatibility across versions. A corresponding unit test suite verifies that the class correctly exposes the \type\, \payloadSchema\, and \metadataSchema\ properties, and that the \EventTypeDetail\ type inference correctly reflects the presence or absence of payload and metadata schemas.

packages/event-type-zod/src · high confidence

Add demo implementation for Pokemon game functions

The demo/implementation/functions directory now contains the concrete serverless function implementations for the Pokemon game. This includes handlers for catching, leveling up, and spawning wild Pokemon, as well as endpoints to list aggregate IDs and retrieve event details. Each function is wired to the appropriate event stores (pokemons, trainers) and exposes AWS Lambda/HTTP API configurations, providing the operational logic for the demo blueprint.

demo/implementation/functions · high confidence

Add demo implementation package with DynamoDB resources and serverless configuration

A new 'demo-implementation' application is introduced, providing a concrete example of the event-sourcing prototype. It includes AWS CloudFormation templates for DynamoDB tables (TrainerEventsTable and PokemonEventsTable) and a Serverless Framework configuration that deploys the necessary AWS resources and IAM permissions. The setup also adds TypeScript and Vite configuration files to support the demo's build and test processes.

demo/implementation · high confidence

Add demo visualization app

A new demo/visualization application has been added, providing an interactive React-based interface to visualize event stores and commands. The demo renders a Visualizer component that displays state for 'pokemons' and 'trainers' event stores, allowing users to observe command execution and context arguments in a browser environment.

demo/visualization · high confidence

Add demo/blueprint project configuration

A new 'demo/blueprint' project has been added to the workspace, including its own \project.json\, \tsconfig.json\, \tsconfig.build.json\, \babel.config.js\, and \.dependency-cruiser.js\ configuration files. This establishes the structural foundation for the demo blueprint implementation, linking it to the core package and inheriting shared tooling configurations.

demo/blueprint · high confidence

Add in-memory message queue adapter

The \packages/message-queue-adapter-in-memory\ package now provides an in-memory implementation of the message queue adapter. This includes the core \InMemoryMessageQueueAdapter\ class, which manages message processing with configurable retry attempts, delay, and backoff rate, along with utility functions for parsing these configuration values. The package also exports the associated types (\InMemoryQueueMessage\, \TaskContext\) and a static \attachTo\ method for easy integration with existing message queues. A comprehensive set of unit tests has been added to verify the adapter's behavior, including worker assignment, message publishing, and retry logic.

(repo-wide) · high confidence

Add lib-dam library scaffolding and documentation

The \packages/lib-dam\ directory now contains the full scaffolding for the \lib-dam\ library, including build configuration files (\babel.config.js\, \tsconfig.json\, \tsconfig.build.json\, \vite.config.js\), a \project.json\ for the build system, and a \README.md\ that documents the library's data maintenance and migration utilities (such as \pourEventStoreAggregateIds\ and \pourAggregateEvents\). This establishes the library's structure and usage guide for developers.

packages/lib-dam · high confidence

Added Pokemon and Trainer domain models to the blueprint demo

The demo/blueprint/src/trainers area now includes new files defining the Pokemon and Trainer aggregates, event stores, and event types. Specifically, it introduces the \PokemonAggregate\ and \TrainerAggregate\ types, along with their respective event stores (\pokemonsEventStore\ and \trainersEventStore\) and event definitions (\APPEARED\, \CAUGHT\_BY\_TRAINER\, \LEVELLED\_UP\, \GAME\_STARTED\, \POKEMON\_CAUGHT\). Mock data for testing these aggregates is also provided.

demo/blueprint/src/trainers · medium confidence

Added console middleware for Lambda handlers

A new file, console.ts, was added to the middlewares library, introducing an applyConsoleMiddleware function that wraps AWS Lambda handlers using the Middy framework. This middleware optionally applies JSON validation to the input event based on a provided schema, allowing developers to easily add validation logic to their Lambda functions.

demo/implementation/libs/middlewares · high confidence

Added demo blueprint commands for the Pokemon game

The demo/blueprint/src/commands directory now includes four new command implementations: catchPokemon, levelUpPokemon, startPokemonGame, and wildPokemonAppear. Each command defines a specific game action with input/output schemas and handlers that interact with event stores (pokemonsEventStore, trainersEventStore) to manage game state transitions such as catching a Pokemon, leveling up, starting a game, or encountering a wild Pokemon.

demo/blueprint/src/commands · high confidence

Added logo assets

The repository now includes the project's logo assets in both PDF and SVG formats within the assets directory, providing scalable and high-resolution versions of the brand mark for use in documentation and web interfaces.

assets · high confidence

Initial project scaffolding and configuration

The repository is initialized with essential configuration files, including \.gitignore\, \.prettierrc\, \eslint.config.js\, \tsconfig.json\, and \nx.json\. This establishes the foundational build, linting, and formatting rules for the project.

(repo-wide) · high confidence

Introduce ConnectedEventStore to publish events to message channels

Added a new ConnectedEventStore class that wraps an existing EventStore and automatically publishes pushed events to a configured message channel (e.g., NotificationMessageQueue or StateCarryingMessageBus). This allows event stores to seamlessly broadcast events to external systems or other parts of the application without manual publishing logic. The implementation includes a helper function \publishPushedEvent\ that handles the actual message publishing, supporting both notification-style and state-carrying message channels. Unit tests verify that events are correctly published and that aggregate state is properly handled for state-carrying channels.

packages/core/src/connectedEventStore · high confidence

Introduce Pokemon-themed demo blueprint with new commands

The demo/blueprint/src directory now includes a new index.ts file that exports several command modules: catchPokemon, levelUpPokemon, startPokemonGame, and wildPokemonAppear. This adds a set of interactive commands to the demo, enabling users to engage with Pokemon-themed gameplay elements such as catching, leveling up, and encountering wild Pokemon.

demo/blueprint/src · medium confidence

Introduce ZodCommand for schema-validated commands

A new \ZodCommand\ class is introduced in the \@castore/command-zod\ package, allowing developers to define commands with automatic input and output validation using \zod\ schemas. This feature extends the existing \Command\ class to support type-safe command definitions, with full support for both \zod\ v3 and v4, and includes comprehensive unit and type tests to ensure correct behavior and type inference.

packages/command-zod · high confidence

Introduce core event store abstractions and messaging infrastructure

The @castore/core package now exposes a comprehensive set of types and interfaces for event-driven architecture, including the EventStorageAdapter interface for querying and pushing events, the ConnectedEventStore class for stateful operations, and a full messaging system with MessageChannel, MessageQueue, and MessageBus classes. Users gain access to structured options for pagination and filtering in listAggregateIds, context-aware event pushing, and typed message channels for notifications and state carrying, all exported from the core index.

packages/core/src · high confidence

Introduce in-memory event storage adapter

Added a new \InMemoryEventStorageAdapter\ implementation for the \event-storage-adapter-in-memory\ package. This adapter provides an in-memory store for events, supporting operations such as pushing single or grouped events, retrieving events with filtering (by version, limit, reverse order), and listing aggregate IDs with pagination. The adapter also includes a custom \InMemoryEventAlreadyExistsError\ for handling duplicate event scenarios and utility functions to parse pagination tokens.

(repo-wide) · high confidence

Introduce new Redux and DynamoDB event storage adapters

Added new event storage adapters for Redux and DynamoDB, enabling event persistence in a Redux store or AWS DynamoDB. The Redux adapter provides a \configureCastore\ helper to set up the store and exposes React hooks like \useAggregate\ and \useAggregateIds\ to access event data. The DynamoDB adapter introduces a \DynamoDBSingleTableEventStorageAdapter\ for modern single-table storage patterns, alongside a \LegacyDynamoDBEventStorageAdapter\ for backward compatibility. Both adapters support pushing events, querying by aggregate ID, and handling initial events.

packages/event-storage-adapter-dynamodb/src, packages/event-storage-adapter-redux/src · high confidence

Introduce structured message channels and type discrimination utilities

The core messaging system now includes three distinct message channel classes—AggregateExistsMessageChannel, NotificationMessageChannel, and StateCarryingMessageChannel—each handling specific message types and publishing through a shared MessageChannelAdapter interface. To support this, the codebase adds type discrimination utilities (isAggregateExistsMessage, isEventCarryingMessage, isNotificationMessage, isStateCarryingMessage) and associated error classes (MessageChannelEventStoreNotFoundError, UndefinedMessageChannelAdapterError) to ensure type safety and clear failure modes when resolving event stores or adapters.

packages/core/src/messaging/channel · high confidence

Introduce structured message types and channels for event store interactions

The core package now defines three distinct message types—AggregateExistsMessage, NotificationMessage, and StateCarryingMessage—each carrying specific data about event stores and aggregates. These messages are exposed via a new messaging module that also provides corresponding message channels and utility functions for type checking. This change establishes a clear, typed contract for how the system communicates about aggregate existence, notifications, and state-carrying events, replacing previous, less structured approaches.

packages/core/src/messaging · medium confidence

Introduces typed event definitions and grouped event handling

The core package now provides a typed \EventType\ class that enforces reserved event names and allows optional payload and metadata types. This enables stricter type inference for \EventDetail\ and \EventTypeDetails\, ensuring that event structures match their definitions. Additionally, a \GroupedEvent\ class is introduced to bundle an event with its context, previous aggregate state, and storage adapter, facilitating grouped event processing.

packages/core/src/event · high confidence

New JSON Schema and Zod-based command and event type abstractions

Users can now define commands and event types using JSON Schema and Zod respectively, which provides automatic TypeScript type inference for inputs, outputs, and event payloads. The \@castore/command-json-schema\ package introduces \JSONSchemaCommand\, allowing developers to specify \inputSchema\ and \outputSchema\ for commands, while \@castore/event-type-zod\ introduces \ZodEventType\ for defining event types with Zod schemas. Both packages include comprehensive unit and type tests to ensure correct behavior and type safety.

packages/command-json-schema · high confidence

New React visualizer and test utilities for event sourcing

A new React-based visualizer component has been added to help users visualize, design, and manually test event stores and commands. This includes a \Visualizer\ component that renders a UI for interacting with event stores, complete with a default MUI theme and an \UnthemedVisualizer\ for custom styling. Additionally, new test utilities (\mockEventStore\ and \muteEventStore\) have been introduced to simplify testing by providing in-memory event store implementations that can be reset or mutated during tests.

packages/lib-react-visualizer · high confidence

New architecture diagrams for documentation

Added new Excalidraw diagram files to the documentation assets, including visualizations for the message bus, message queues, event store, connected event store, event groups, events, aggregates, commands, and message types. These diagrams illustrate the system's internal structure and data flow, such as the 'Aggregate Exists' and 'State Carrying' message types, to help users understand the architecture.

assets/docsImg · high confidence

New event pouring utilities in lib-dam

The lib-dam package now exports a suite of functions for processing and emitting events: pourEventStoreAggregateIds, pourAggregateEvents, pourEventStoreEvents, and pourEventStoreCollectionEvents. These utilities handle scanning event stores, batching messages, and applying time-based filters. The implementation includes a new EventBook class for caching aggregate events, a MessagePourer for rate-limited publishing, and supporting utilities for throttling and timestamp filtering.

packages/lib-dam/src · high confidence

New event storage adapters for in-memory and Redux state management

Added two new event storage adapters: an in-memory adapter for testing and a Redux adapter for React applications. The in-memory adapter persists events in a local JavaScript object, making it suitable for unit tests. The Redux adapter integrates with the Redux store, providing React hooks (useAggregateEvents, useAggregate, etc.) for synchronous state access and automatic re-rendering. Both adapters are configured with standard build and test configurations.

packages/event-storage-adapter-in-memory, packages/event-storage-adapter-redux · high confidence

New message bus implementations for event-driven communication

The core messaging module now includes three new message bus classes—AggregateExistsMessageBus, NotificationMessageBus, and StateCarryingMessageBus—each extending a corresponding message channel. These buses provide a structured way to handle specific types of events and notifications within the system, allowing for more granular control over message routing and processing.

packages/core/src/messaging/bus · high confidence

New message queue implementations for notifications, state-carrying, and aggregate existence

The core messaging system now includes three new queue classes: NotificationMessageQueue, StateCarryingMessageQueue, and AggregateExistsMessageQueue. Each class is designed to handle specific message types and inherits from its corresponding message channel (NotificationMessageChannel, StateCarryingMessageChannel, and AggregateExistsMessageChannel respectively). These queues are exported from the core package's messaging/queue module, enabling developers to easily integrate these specialized message handling capabilities into their applications.

packages/core/src/messaging/queue · high confidence

Behavioural changes

Commands now retry on EventAlreadyExistsError

The Command class now automatically retries execution when an EventAlreadyExistsError is thrown, up to a configurable number of times (defaulting to 2 retries). This ensures that transient concurrency issues during event publishing are handled gracefully, with a callback provided to track retry attempts.

packages/core/src/command · high confidence

Configure Pokemon and Trainer event stores with DynamoDB adapters

The demo implementation now explicitly wires the \pokemonsEventStore\ and \trainersEventStore\ to use \DynamoDBSingleTableEventStorageAdapter\ instances. Each store is configured with its respective environment variable for the table name (\POKEMON\_EVENTS\_TABLE\_NAME\, \TRAINER\_EVENTS\_TABLE\_NAME\) and shares a common \DynamoDBClient\ instance, ensuring that event data for these entities is persisted in DynamoDB rather than relying on previous storage mechanisms.

demo/implementation/libs/eventStores · high confidence

Core package refactored to ESM and Vitest

The core package has been converted from CommonJS to ES modules, with build configuration updated to use tsc-alias and a new Vite-based test runner (Vitess) replacing the previous Jest setup. Configuration files including tsconfig, babel, and dependency-cruiser settings have been added or updated to support this modernization, while the project is now recognized by the Nx workspace.

packages/core · medium confidence

Enforce commit message validation on commit

A new hook has been added to the .husky directory to automatically validate commit messages using commitlint. This ensures that all new commits adhere to the project's specified message format, preventing non-conforming messages from being accepted.

.husky · high confidence

Event store refactoring and new group event capabilities

The event store implementation has been restructured, introducing a new \EventStore\ class with a static \pushEventGroup\ method that accepts a \force\ option and publishes messages from event groups. The \pushEvent\ method no longer requires a timestamp, and the \getAggregate\ method now accepts a \GetAggregateOptions\ parameter. Additionally, specific error classes such as \AggregateNotFoundError\ and \EventAlreadyExistsError\ have been moved into a dedicated \errors\ folder, and the \eventStorageAdapter\ is now explicitly included in the \GroupedEvent\ interface.

packages/core/src/eventStore · high confidence

New versioning script replaces lerna for package versioning

A new TypeScript script, setPackagesVersions.ts, has been introduced to handle versioning for all packages in the 'packages' directory. This script validates a semantic version tag (e.g., v1.2.3) and updates the version in each package's package.json, including dependencies and peer dependencies starting with '@castore/'. This change replaces the previous lerna-based approach, providing a more direct and controlled mechanism for synchronizing package versions across the monorepo.

scripts · medium confidence

Updated Yarn to version 4.10.2

The project's bundled Yarn executable has been upgraded to version 4.10.2. This update replaces the previous version with the new release, ensuring the project uses the latest features and fixes provided by the Yarn package manager.

.yarn · high confidence

Dependencies

Add package.json manifests for Castore demo and library packages

The repository now includes \package.json\ files for the \demo/blueprint\, \demo/implementation\, \demo/visualization\, \docs\, and all core packages (\core\, \command-json-schema\, \command-zod\, \event-storage-adapter-\\, \event-type-\\, \lib-\\, \message-bus-adapter-\\). These manifests define the dependencies, peer dependencies, and build scripts for each module, establishing the monorepo structure with workspace references (e.g., \@castore/core\, \@castore/demo-blueprint\) and external libraries such as \react\, \@mui/material\, \@aws-sdk/\*\, and \zod\.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 45 → 55 (+10.1)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 94 → 91 (-3.1)
  • Architecture 55 → 59 (+3.8)
  • Maturity 67 → 68 (+1.7)
  • Readiness 33 → 51 (+18.1)
  • Security 40 → 50 (+10.0)

Resolved (94)

  • Boundary-crossing change coupling: adapter.ts ↔ adapter.ts (packages/event-storage-adapter-in-memory/src/adapter.ts)
  • Boundary-crossing change coupling: legacyAdapter.ts ↔ adapter.ts (packages/event-storage-adapter-dynamodb/src/legacyAdapter.ts)
  • Boundary-crossing change coupling: legacyAdapter.ts ↔ adapter.ts (packages/event-storage-adapter-dynamodb/src/legacyAdapter.ts)
  • Change coupling: adapter.ts ↔ message.ts (packages/message-queue-adapter-sqs/src/adapter.ts)
  • Change coupling: legacyAdapter.ts ↔ singleTableAdapter.ts (packages/event-storage-adapter-dynamodb/src/legacyAdapter.ts)
  • Change coupling: message.ts ↔ types.ts (packages/message-bus-adapter-in-memory/src/message.ts)
  • Coverage not included — suite not readable by the collector
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • …and 74 more

New (198)

  • Change coupling clique: legacyAdapter.ts, adapter.ts, adapter.ts (packages/event-storage-adapter-dynamodb/src/legacyAdapter.ts)
  • Coverage not measured — JavaScript/TypeScript suite
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Critical CVE: [GHSA redacted] (yarn.lock)
  • Documentation: no architecture or design documentation (docs/docs/1-installation.md)
  • Documentation: no architecture or design documentation (packages/event-type-json-schema/README.md)
  • Documentation: no architecture or design documentation (packages/event-type-zod/README.md)
  • Documentation: no architecture or design documentation (packages/lib-dam/README.md)
  • FileTooLong: pages/index.tsx (docs/src/pages/index.tsx)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • High CVE: [GHSA redacted] (yarn.lock)
  • …and 178 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

castore-dev/castore was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit c07cfed7ef56499f92297fb2699b049440307e30 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-b84573e22831.