@othree.io/chisel-sdk
v7.1.1
Published
Utility functions for Chisel
Maintainers
Readme
@othree.io/chisel-sdk
SDK for building event-sourced microservices with Chisel on AWS. Provides pre-wired write-side actors, read-side projections, and CDK infrastructure stacks out of the box.
Installation
npm install @othree.io/chisel-sdkExports
import { aws, iac } from '@othree.io/chisel-sdk'| Namespace | Purpose |
|-----------|---------|
| aws | Runtime Lambda handlers for write-side (actor) and read-side (projections) |
| iac | CDK stack factories for the full CQRS infrastructure |
Write Side (aws.createActor)
Creates a fully wired Chisel actor with DynamoDB event persistence, sharded SNS publishing, and X-Ray tracing.
import { aws } from '@othree.io/chisel-sdk'
const actor = aws.createActor<MyAggregate, MyEvent>({
boundedContext: 'Orders',
now: () => Date.now(),
getInitialState: async (contextId) => Optional(emptyOrder),
handleCommand: myCommandHandler,
reduceEvent: myReducer,
})
// Lambda exports
export const handleCommand = actor.handleCommand
export const getState = actor.getStateEnvironment variables (read automatically):
| Variable | Description |
|----------|-------------|
| EVENTS_TABLE | DynamoDB events table name |
| EVENTS_TOPICS | Comma-separated SNS topic ARNs |
| LOG_LEVEL | Logging level (default: info) |
Returns a LambdaActor<AggregateRoot> with:
handleCommand- processes aLambdaCommandand returns anInvocationResult<CommandResult<AggregateRoot>>getState- loads and returns the current aggregate state asInvocationResult<AggregateRoot>bycontextId
Read Side (aws.getProjectionServices)
Creates a fully wired projection processor with DynamoDB upsert/delete, SQS batch processing, and DLQ routing.
import { aws } from '@othree.io/chisel-sdk'
const projection = aws.getProjectionServices<MyAggregate, MyEvent>({
boundedContext: 'Orders',
now: () => Date.now(),
})
// Lambda exports
export const updateProjection = projection.sqs.updateProjection
export const getById = projection.services.getByIdEnvironment variables (read automatically):
| Variable | Description |
|----------|-------------|
| PROJECTION_TABLE | DynamoDB projection table name |
| PROJECTION_DLQ | Application DLQ URL |
| PROJECTION_PK | Projection table partition key name |
| DELETE_ON_EVENTS | Comma-separated event types that trigger deletion |
| LOG_LEVEL | Logging level (default: info) |
Returns:
sqs.updateProjection- SQS batch handler that upserts or deletes projections based on event typeservices.getById- queries the projection table by ID
Standalone Functions
These are also exported for direct use or custom wiring:
| Function | Description |
|----------|-------------|
| aws.getProcessInput | Parses an SQS record containing an SNS-wrapped Chisel event |
| aws.processEvent | Routes to delete or upsert based on deleteOnEvents configuration |
| aws.getProjectionById | Queries the projection table and throws NotFoundError if empty |
| aws.getProjectionServiceHandler | Wraps a projection query function as a Lambda service handler |
| aws.getConfiguration | Reads projection configuration from environment variables |
Infrastructure (iac.createChiselStacks)
Creates all CDK stacks for a Chisel microservice in a single call.
import { App } from 'aws-cdk-lib'
import { iac } from '@othree.io/chisel-sdk'
const app = new App()
const stacks = iac.createChiselStacks(app, {
boundedContext: 'Orders',
version: 'v1',
projectMetadata: {
project: 'my-project',
environment: 'prod',
owner: 'team-a',
},
context: {
project: { env: 'prod', naming: { prefix: 'myapp' } },
lambda: { functions: [] },
chisel: { numberOfShards: 3 },
},
writeSide: {
codePath: 'dist/write',
},
readSide: {
codePath: 'dist/read',
deleteOnEvents: ['OrderDeleted'],
},
})The context is validated against ChiselServiceContextConstraints at runtime using Zod.
Generated Stacks
| Stack | Description | Output |
|-------|-------------|--------|
| EventBus | FIFO SNS topics (one per shard) | stacks.topics.stack, stacks.topics.topics |
| WritePersistence | DynamoDB events table | stacks.writeSide.persistence.eventsTable |
| WriteServices | Command handler and get-state Lambda functions | stacks.writeSide.services.handleCommandArn, stacks.writeSide.services.getStateArn |
| TopicSubscribers | SQS queues subscribed to SNS topics with DLQ and redrive | stacks.readSide.subscribers.eventQueues, stacks.readSide.subscribers.dlq |
| ProjectionPersistence | DynamoDB projection table with optional GSIs | stacks.readSide.persistence.projectionTable |
| ReadServices | Update-projection and get-by-id Lambda functions | stacks.readSide.servicesStack.stack |
The read side is optional. Omit readSide from the input to create a write-only service.
Context Configuration
The ChiselServiceContext controls stack behavior:
type ChiselServiceContext = Readonly<{
project: {
env: string // Environment name (used as resource suffix)
naming?: { prefix?: string } // Optional resource name prefix
}
lambda: {
functions: Array<{
name: string
reservedConcurrentExecutions?: number
}>
}
chisel: {
numberOfShards: number // Number of FIFO SNS topics
}
}>Read Side Options
type ReadSideInput = Readonly<{
codePath: string // Lambda code path
tablePk?: string // Projection table PK name (default: 'id')
globalSecondaryIndexes?: Array<GSIInput> // Optional GSIs
deleteOnEvents: Array<string> // Event types that trigger row deletion
}>Peer Dependencies
{
"@othree.io/auditor": "^5.0.0",
"@othree.io/awsome": "^5.0.0",
"@othree.io/cdk": "^6.0.0",
"@othree.io/chisel": "^7.0.0",
"@othree.io/chisel-aws": "^7.0.0",
"@othree.io/excuses": "^2.0.0",
"@othree.io/journal": "^3.0.0",
"@othree.io/stethoscope": "^5.0.0",
"aws-cdk-lib": "^2.239.0",
"aws-lambda": "^1.0.7",
"aws-xray-sdk-core": "^3.12.0",
"uuid": "^13.0.0"
}Development
npm install
npm run build # Dual CJS/ESM output
npm test # Vitest with coverageLicense
ISC
