Alpha Version: You are viewing the ALPHA documentation. This is an experimental version and may contain breaking changes.
Skip to main content

Getting Started with reventless-local

This guide covers setting up and using the Local provider for local development and testing.

Prerequisites

Install Dependencies

npm install @reventless/reventless @reventless/reventless-local @reventless/reventless-spec

Creating a Platform

The Local provider exposes a Platform.Make() functor that creates an isolated local platform:

module Platform = ReventlessLocal.Platform.Make()

This creates a fresh LocalBus, wires all adapter builders, and starts the GraphQL and MCP servers after plugin construction.

Silent Mode

For tests where you don't want diagnostic warnings (e.g., missing command handlers), use MakeWithConfig:

module Platform = ReventlessLocal.Platform.MakeWithConfig({
let silent = true
let splitApi = false
})

Split API Mode

To serve core administrative schema (plugin management) and plugin business domain schema on separate ports:

module Platform = ReventlessLocal.Platform.MakeWithConfig({
let silent = false
let splitApi = true
})

When splitApi = true:

  • Plugin GraphQL on port 4000 — business domain queries and mutations
  • Core GraphQL on port 4001 — plugin management queries and mutations
  • Plugin MCP on port 3001 — business domain tools and resources
  • Core MCP on port 3002 — administrative tools and resources

When splitApi = false (default), all schema is served from the unified endpoints (port 4000 for GraphQL, port 3001 for MCP).

Using in Tests

Test Setup

Use TestRunner.setup() to activate Pulumi mock mode before creating components:

// At the top of your test file
ReventlessLocal.TestRunner.setup()

module Platform = ReventlessLocal.Platform.MakeWithConfig({let silent = true; let splitApi = false})
module App = MyPlugin.Make(Platform)

Resolving Outputs

Since components wrap operations in Pulumi.Output.t, use TestRunner.resolve to unwrap them in tests:

let ops = await myComponent
->ReventlessCore.Component.operations
->ReventlessLocal.TestRunner.resolve

Async Test Registration

The bus registers handlers asynchronously via Output.apply. Use beforeAllAsync to ensure handlers are registered before tests run:

open ReventlessCore.AsyncTest

beforeAllAsync(async () => {
let _ = await myComponent
->ReventlessCore.Component.operations
->ReventlessLocal.TestRunner.resolve
})

Cleanup

Stop the GraphQL server in afterAll:

afterAll(() => {
ReventlessLocal.TestRunner.stopGraphQLServer()
})

GraphQL Server

The Local platform starts a GraphQL server on port 4000 automatically after all plugins are constructed. All mutation and query resolvers registered during plugin construction are available immediately.

Access it at http://localhost:4000/graphql.

MCP Server

The MCP server starts alongside the GraphQL server, providing AI-native access to:

  • Tools — mapped from GraphQL mutations (commands)
  • Resources — mapped from GraphQL queries (read models) and event log history

Next Steps