reSolve Framework

website·Indexed 29 days ago

https://reimagined.github.io/resolve/docs/

A TypeScript framework for building scalable applications using Event Sourcing (ES) and CQRS principles. It provides tools for managing Aggregates on the write side, Read Models and View Models on the read side, and Sagas for long-running processes. The ecosystem includes client libraries such as @resolve-js/react-hooks and @resolve-js/redux to connect React frontends to the backend.

Tokens
39.9K
Snippets
240
Records
303
Agent score
75%

What's inside reSolve

  1. Overview of reSolve architecture

    reSolve is a full-stack framework designed for scalability and maintainability. It leverages CQRS (Command Query Responsibility Segregation) and Event Sourcing, ensuring that all data is stored and nothing is removed, which eliminates the need to predict future data requirements. The framework emphasizes functional JavaScript to make code easier to test and adapt.
  2. Overview of the Monitoring API

    The Monitoring type from the @resolve-js/core package provides a standardized interface for tracking application metrics. It shares the same interface as a monitoring adapter, except that getMetrics and clearMetrics require a monitoring adapter ID as an argument.
    import { Monitoring } from '@resolve-js/core';
  3. Overview of @resolve-js/testing-tools

    The @resolve-js/testing-tools package provides utilities for writing BDD-style tests for reSolve aggregates, read models, and sagas. It allows developers to reproduce a read model's full lifecycle within a testing environment. Tests are initiated by calling the givenEvents function, which accepts an array of events and returns a chainable API for defining test cases and assertions.
  4. Overview of the ReSolve Framework

    ReSolve is a Node.js framework designed for building server-side infrastructure using Command Query Responsibility Segregation (CQRS), Domain Driven Design (DDD), and Event Sourcing. It provides built-in support for various data storages, event import/export, encryption, and debugging tools. It can be interfaced via a dedicated HTTP API or provided client libraries.
  5. Overview of Sagas in Resolve.js

    A saga in Resolve.js describes a long-running process as a sequence of events. It is implemented as a set of event handler functions that react to specific events. Sagas can send commands to aggregates, schedule future commands, store intermediate data in a persistent store, and trigger custom side effects.
  6. Understand the MonitoringMetric object structure

    A MonitoringMetric object contains data about a specific metric collected during application execution. These objects are processed by monitoring adapters and can be retrieved using the getMetrics method of a monitoring object.
    // Retrieve metrics for the 'default' scope
    const metrics = monitoring.getMetrics('default');
    
    // Structure of a MonitoringMetric object
    {
      metricName: string, // The name of a metric
      dimensions: any[],  // An array of monitoring dimensions
      timestamp: any,     // The time at which the metric was last updated
      values: any[],      // An array of the metric's values
      counts: any[],      // An array of the metric's counts
      unit: string,       // The name of the measurement unit
    }
  7. Understand the ReSolve adapter mechanism

    ReSolve utilizes an adapter mechanism to create an abstraction layer over the APIs used by its subsystems. This allows the application to interact with a unified data management API while abstracting away the direct interactions with the underlying storage. ReSolve provides two primary types of adapters: Event store adapters and Read model store adapters. While ReSolve includes built-in adapters for popular Database Management Systems (DBMS), developers can implement custom adapters or bypass the adapter mechanism entirely by interacting directly with a system (e.g., a full-text-search engine or OLAP database) within projection functions and query resolvers.
  8. Get Event Store metadata using describe

    The describe method returns information about the event store, such as event and secret counts, freeze status, and the timestamp of the last event.

    For the @resolve-js/eventstore-postgresql adapter, setting estimateCounts: true optimizes performance on large stores by using metadata from service tables instead of calculating exact counts.

    const info = await eventStoreAdapter.describe({
      estimateCounts: true, // Use estimated values for eventCount and secretCount
      calculateCursor: false // Whether to get the database cursor for traversing events
    });
    
    // Result structure:
    // {
    //   eventCount: number,
    //   secretCount: number,
    //   setSecretCount: number,
    //   deletedSecretCount: number,
    //   isFrozen: boolean,
    //   lastEventTimestamp: number,
    //   cursor: string | null,
    //   resourceNames: object
    // }
  9. Understand Aggregates in reSolve

    In reSolve, an aggregate is a static object that serves as a transaction boundary in a CQRS/ES application. It encapsulates domain logic and ensures that commands are executed without needing to communicate with other aggregates. An aggregate consists of two primary components: Projections (which build state from events) and Command Handlers (which execute commands). Aggregate state is explicitly passed as an argument to these functions.
  10. Implement the Write Side using Aggregates

    In reSolve, the Write Side is responsible for receiving commands and modifying application state. It is implemented as a set of aggregates consisting of:

    • Command Handlers: Functions that analyze command data and produce event objects to describe state changes.
    • Projections: Components that use produced events to build the aggregate state, which is then used by command handlers for tasks like input validation.
  11. Understand ReSolve code splitting and bundle distribution

    ReSolve uses webpack to transpile and bundle application code into specific chunks based on where the logic needs to execute. Chunks are categorized as server-only (business logic), browser-only (UI/client logic), or isomorphic (shared logic like view models and Redux reducers).

    Generated chunks include:

    • Command processor code: Aggregate command handlers and projections (Server only).
    • View model projection: Isomorphic (used by both server and client).
    • Read model projections and resolvers: (Server only).
    • API handlers: (Server only).
    • SSR renderer: (Server only, includes peer dependencies like styled-components).
    • Client application with UI: (Browser only).

    In cloud or serverless environments, server-only chunks (API handlers, read model projections, SSR renderer) are distributed to the appropriate cloud executors. For local development, the @resolve-js/scripts utility manages loading and combining these chunks with the runtime code.

  12. Understand reSolve CQRS architecture (Write and Read sides)

    reSolve implements the CQRS paradigm by splitting the application into two sides:

    1. Write Side: Composed of aggregates that receive commands and emit events, which are then persisted in the event store.
    2. Read Side: Used for querying data. It consists of:
      • Read Models: Accumulate event data in storage via a projection. A resolver pulls this data, processes it based on arguments, and returns it to the client.
      • View Models: A specialized Read Model assembled on the fly. They are Redux-compatible, allowing for reactive updates on the client side.