All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Async race condition in
ArrayMailbox.dispatch(): Added adispatchingguard so only one dispatch loop runs at a time — concurrent callers (e.g.send(),resume()) return immediately when a loop is already active, preventing duplicate message delivery - The active loop re-checks
isReceivable()after eachawait, so it naturally picks up messages queued during delivery and resumes after supervisor-triggered un-suspension
- Project logo: Added
docs/domo-actors-logo.png
- No public API changes; patch release per Semantic Versioning
- Mailbox dispatch refactored from recursive to iterative:
ArrayMailbox.dispatch()andBoundedMailbox.dispatch()now use awhileloop instead of recursive calls, preventing potential stack overflow when processing large message queues - Removed redundant
Promise.resolve()wrappers inLocalMessage.deliver(): Sincedeliver()isasync, returned values are already wrapped in a Promise
- ArrayMailbox test suite: New
ArrayMailbox.test.tswith 9 tests covering dispatch draining, FIFO ordering, suspension/close behavior, and a 10,000-message stress test validating the iterative dispatch
- No public API changes; all modifications are internal implementation improvements
- Patch release per Semantic Versioning (no new functionality, no breaking changes)
- ESM Module Resolution: Updated TypeScript configuration and imports for stricter ESM compliance
- Changed
moduleResolutionfrom"node"to"NodeNext"in tsconfig.json - Changed
modulefrom"ES2022"to"NodeNext"in tsconfig.json - Added explicit
.jsextensions to all internal imports (26 source files)
- Changed
- This is an internal code quality improvement with no API changes
- The compiled output remains standard ESM, compatible with all JavaScript runtimes
- No changes required for library consumers (JS or TS)
- Continues to work in pure V8 environments (Cloudflare Workers, Deno, Bun, browsers)
- Stage Value Registry: New value registration system for shared runtime objects
registerValue<V>(name: string, value: V): Register shared runtime objects (database instances, configuration, connection pools, etc.)registeredValue<V>(name: string): V: Retrieve registered values from any actorderegisterValue<V>(name: string): V | undefined: Remove and return registered values for cleanup- Supports namespaced keys for avoiding conflicts (e.g., 'myapp:database', 'myapp:config')
- Type-safe with generic type parameters
- Comprehensive test coverage with 39 tests (28 for registration, 11 for deregistration)
- Database connection management: Register database instances or connection pools for actor access
- Configuration management: Share application configuration across all actors
- Service registry pattern: Register and retrieve service instances throughout the application
- Dependency injection: Provide runtime dependencies to actors without constructor coupling
import { stage } from 'domo-actors'
// Register a database instance
const db = new DatabaseConnection()
stage().registerValue('myapp:database', db)
// Access from any actor
class MyActor extends Actor {
async query() {
const db = this.stage().registeredValue<DatabaseConnection>('myapp:database')
return await db.query('SELECT * FROM users')
}
}
// Clean up resources when shutting down
const db = stage().deregisterValue<DatabaseConnection>('myapp:database')
if (db) {
await db.close()
}- Core actor model implementation
- Supervision strategies
- Mailbox implementations (Array, Bounded)
- Lifecycle management
- Message delivery
- Scheduler
- Observable state
- State snapshots