@cnstra/core
v2.3.0
Published
Embeddable workflow/orchestration engine for TypeScript: deterministic runs over a typed neuron graph (in-memory, zero dependencies).
Maintainers
Readme
@cnstra/core
Workflow / orchestration engine for TypeScript — deterministic, embeddable, in-memory.
📚 Full Documentation → | Quick Start | API Reference | Recipes
What is CNStra?
CNStra (Central Nervous System Orchestrator) models your app as a typed neuron graph. You explicitly start a run with cns.stimulate(...); CNStra then performs a deterministic, hop-bounded traversal from collateral → dendrite → returned signal, step by step.
Zero dependencies • No pub/sub • CNS approach (Central Neural Network of your app)
Common backend use-cases:
- Jobs (queues/workers), sync/integrations (webhooks), ETL/pipelines
- Retries/timeouts/cancellation and saga-style compensations
👉 Read the full documentation →
Quick Start
npm install @cnstra/coreimport { CNS, collateral, neuron } from '@cnstra/core';
// Define collaterals (communication channels)
const userCreated = collateral<{ id: string; name: string }>();
const userRegistered = collateral<{ userId: string; status: string }>();
// Create a neuron
const userService = neuron({
userRegistered
})
.dendrite({
collateral: userCreated,
response: (payload, axon) => {
return axon.userRegistered.createSignal({
userId: payload.id,
status: 'completed'
});
}
});
// Create the CNS system
const cns = new CNS([userService]);
// Stimulate the system
const stimulation = cns.stimulate(userCreated.createSignal({
id: '123',
name: 'John Doe'
}));
await stimulation.waitUntilComplete();Registry & Naming
CNSPersistOptionsRegistry maps object references to stable string names — used by devtools, MCP server, and persistence/resume patterns.
Per-file registration (recommended):
// src/neurons/registry.ts
import { CNSPersistOptionsRegistry } from '@cnstra/core';
export const registry = new CNSPersistOptionsRegistry();
// src/neurons/deck.ts — each neuron registers itself
import { collateral, withCtx } from '@cnstra/core';
import { registry } from './registry';
const deckCreated = collateral<{ deckId: string }>();
const importStarted = collateral<{ importId: string }>(); // external entry point
const deckNeuron = withCtx()
.neuron({ deckCreated })
.bind({ importStarted }, {
importStarted: ({ importId }, axon) => axon.deckCreated.createSignal({ deckId: importId }),
});
registry
.register('deckNeuron', deckNeuron) // registers neuron + axon collaterals
.register('deckNeuron', deckNeuron, { deckCreated: 'deck-created' }) // explicit collateral names
.registerCollateral('importStarted', importStarted); // standalone collateral (no neuron)All at once (simple projects):
import { createPersistRegistry } from '@cnstra/core';
export const registry = createPersistRegistry({ deckNeuron, cardNeuron });
// explicit neuron name: { 'deck-neuron': deckNeuron }
// explicit collateral names: { 'deck-neuron': { neuron: deckNeuron, collaterals: { deckCreated: 'deck-created' } } }Documentation
- Quick Start Guide — Get up and running in minutes
- API Reference — Complete API documentation
- Concepts — Neurons, collaterals, signals, and the CNS model (Central Neural Network of your app)
- Recipes — Common patterns and use cases
- Advanced Topics — Performance, context stores, integrations
CNStra provides deterministic, type-safe orchestration without the complexity of traditional event systems.
