@rotorsoft/act 0.12.2 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ports.ts","../src/types/errors.ts","../src/utils.ts","../src/config.ts","../src/types/schemas.ts","../src/types/index.ts","../src/adapters/InMemoryStore.ts","../src/signals.ts","../src/act.ts","../src/event-sourcing.ts","../src/merge.ts","../src/projection-builder.ts","../src/slice-builder.ts","../src/act-builder.ts","../src/state-builder.ts"],"sourcesContent":["import { pino } from \"pino\";\nimport { InMemoryStore } from \"./adapters/InMemoryStore.js\";\nimport { config } from \"./config.js\";\nimport type {\n Disposable,\n Disposer,\n Fetch,\n Lease,\n LogLevel,\n Schemas,\n Store,\n} from \"./types/index.js\";\n\n/**\n * Port and adapter utilities for logging, store management, and resource disposal.\n *\n * Provides singleton store and logger instances, and helpers for resource lifecycle management.\n *\n * - Use `store()` to get or inject the event store (in-memory or persistent).\n * - Use `logger` for structured logging.\n * - Use `dispose()` to register resource disposers for graceful shutdown.\n *\n * @module ports\n */\n\n/**\n * List of exit codes for process termination.\n */\nexport const ExitCodes = [\"ERROR\", \"EXIT\"] as const;\n\n/**\n * Type for allowed exit codes.\n */\nexport type ExitCode = (typeof ExitCodes)[number];\n\n/**\n * Singleton logger instance (Pino).\n *\n * Use for structured logging throughout your application.\n *\n * @example\n * logger.info(\"Application started\");\n */\nexport const logger = pino({\n transport:\n config().env !== \"production\"\n ? {\n target: \"pino-pretty\",\n options: {\n ignore: \"pid,hostname\",\n singleLine: config().logSingleLine,\n colorize: true,\n },\n }\n : undefined,\n level: config().logLevel,\n});\n\n/**\n * Helper to create a singleton port (adapter) with optional injection.\n *\n * @param injector The function that creates the port/adapter\n * @returns A function to get or inject the singleton instance\n *\n * @example\n * const store = port((adapter) => adapter || new InMemoryStore());\n * const myStore = store();\n */\ntype Injector<Port extends Disposable> = (adapter?: Port) => Port;\nconst adapters = new Map<string, Disposable>();\nexport function port<Port extends Disposable>(injector: Injector<Port>) {\n return function (adapter?: Port): Port {\n if (!adapters.has(injector.name)) {\n const injected = injector(adapter);\n adapters.set(injector.name, injected);\n logger.info(`🔌 injected ${injector.name}:${injected.constructor.name}`);\n }\n return adapters.get(injector.name) as Port;\n };\n}\n\nconst disposers: Disposer[] = [];\nexport async function disposeAndExit(code: ExitCode = \"EXIT\"): Promise<void> {\n // ignore when errors are caught in production\n if (code === \"ERROR\" && config().env === \"production\") return;\n\n await Promise.all(disposers.map((disposer) => disposer()));\n await Promise.all(\n [...adapters.values()].reverse().map(async (adapter) => {\n await adapter.dispose();\n logger.info(`🔌 disposed ${adapter.constructor.name}`);\n })\n );\n adapters.clear();\n config().env !== \"test\" && process.exit(code === \"ERROR\" ? 1 : 0);\n}\n\n/**\n * Registers resource cleanup functions for graceful shutdown.\n *\n * Disposers are called automatically when the process exits (SIGINT, SIGTERM)\n * or when manually triggered. They execute in reverse registration order,\n * allowing proper cleanup of dependent resources.\n *\n * Act automatically disposes registered stores and adapters. Use this function\n * to register additional cleanup for your own resources (database connections,\n * file handles, timers, etc.).\n *\n * @param disposer - Async function to call during cleanup\n * @returns Function to manually trigger disposal and exit\n *\n * @example Register custom resource cleanup\n * ```typescript\n * import { dispose } from \"@rotorsoft/act\";\n *\n * const redis = createRedisClient();\n *\n * dispose(async () => {\n * console.log(\"Closing Redis connection...\");\n * await redis.quit();\n * });\n *\n * // On SIGINT/SIGTERM, Redis will be cleaned up automatically\n * ```\n *\n * @example Multiple disposers in order\n * ```typescript\n * import { dispose } from \"@rotorsoft/act\";\n *\n * const db = connectDatabase();\n * dispose(async () => {\n * console.log(\"Closing database...\");\n * await db.close();\n * });\n *\n * const cache = connectCache();\n * dispose(async () => {\n * console.log(\"Closing cache...\");\n * await cache.disconnect();\n * });\n *\n * // On exit: cache closes first, then database\n * ```\n *\n * @example Manual cleanup trigger\n * ```typescript\n * import { dispose } from \"@rotorsoft/act\";\n *\n * const shutdown = dispose(async () => {\n * await cleanup();\n * });\n *\n * // Manually trigger cleanup and exit\n * process.on(\"SIGUSR2\", async () => {\n * console.log(\"Manual shutdown requested\");\n * await shutdown(\"EXIT\");\n * });\n * ```\n *\n * @example With error handling\n * ```typescript\n * import { dispose } from \"@rotorsoft/act\";\n *\n * dispose(async () => {\n * try {\n * await expensiveCleanup();\n * } catch (error) {\n * console.error(\"Cleanup failed:\", error);\n * // Error doesn't prevent other disposers from running\n * }\n * });\n * ```\n *\n * @see {@link Disposer} for disposer function type\n * @see {@link Disposable} for disposable interface\n */\nexport function dispose(\n disposer?: Disposer\n): (code?: ExitCode) => Promise<void> {\n disposer && disposers.push(disposer);\n return disposeAndExit;\n}\n\n/**\n * Special event name for snapshot events in the event store.\n */\nexport const SNAP_EVENT = \"__snapshot__\";\n\n/**\n * Gets or injects the singleton event store.\n *\n * By default, Act uses an in-memory store suitable for development and testing.\n * For production, inject a persistent store like PostgresStore before building\n * your application.\n *\n * **Important:** Store injection must happen before creating any Act instances.\n * Once set, the store cannot be changed without restarting the application.\n *\n * @param adapter - Optional store implementation to inject\n * @returns The singleton store instance\n *\n * @example Using default in-memory store\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n *\n * const currentStore = store(); // Returns InMemoryStore\n * ```\n *\n * @example Injecting PostgreSQL store\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n * import { PostgresStore } from \"@rotorsoft/act-pg\";\n *\n * // Inject before building your app\n * store(new PostgresStore({\n * host: \"localhost\",\n * port: 5432,\n * database: \"myapp\",\n * user: \"postgres\",\n * password: \"secret\",\n * schema: \"public\",\n * table: \"events\"\n * }));\n *\n * // Now build your app - it will use PostgreSQL\n * const app = act()\n * .with(Counter)\n * .build();\n * ```\n *\n * @example With environment-based configuration\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n * import { PostgresStore } from \"@rotorsoft/act-pg\";\n *\n * if (process.env.NODE_ENV === \"production\") {\n * store(new PostgresStore({\n * host: process.env.DB_HOST,\n * port: parseInt(process.env.DB_PORT || \"5432\"),\n * database: process.env.DB_NAME,\n * user: process.env.DB_USER,\n * password: process.env.DB_PASSWORD\n * }));\n * }\n * // Development uses default in-memory store\n * ```\n *\n * @example Testing with fresh store\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n *\n * beforeEach(async () => {\n * // Reset store between tests\n * await store().seed();\n * });\n *\n * afterAll(async () => {\n * // Cleanup\n * await store().drop();\n * });\n * ```\n *\n * @see {@link Store} for the store interface\n * @see {@link InMemoryStore} for the default implementation\n * @see {@link PostgresStore} for production use\n */\nexport const store = port(function store(adapter?: Store) {\n return adapter || new InMemoryStore();\n});\n\n/**\n * Tracer builder for logging fetches, leases, etc.\n */\nexport function build_tracer(logLevel: LogLevel): {\n fetched: <E extends Schemas>(fetched: Fetch<E>) => void;\n correlated: (leases: Lease[]) => void;\n leased: (leases: Lease[]) => void;\n acked: (leases: Lease[]) => void;\n blocked: (leases: Array<Lease & { error: string }>) => void;\n} {\n if (logLevel === \"trace\") {\n return {\n fetched: <E extends Schemas>(fetched: Fetch<E>) => {\n const data = Object.fromEntries(\n fetched.map(({ stream, source, events }) => {\n const key = source ? `${stream}<-${source}` : stream;\n const value = Object.fromEntries(\n events.map(({ id, stream, name }) => [id, { [stream]: name }])\n );\n return [key, value];\n })\n );\n logger.trace(data, \"⚡️ fetch\");\n },\n correlated: (leases: Lease[]) => {\n const data = leases.map(({ stream }) => stream).join(\" \");\n logger.trace(`⚡️ correlate ${data}`);\n },\n leased: (leases: Lease[]) => {\n const data = Object.fromEntries(\n leases.map(({ stream, at, retry }) => [stream, { at, retry }])\n );\n logger.trace(data, \"⚡️ lease\");\n },\n acked: (leases: Lease[]) => {\n const data = Object.fromEntries(\n leases.map(({ stream, at, retry }) => [stream, { at, retry }])\n );\n logger.trace(data, \"⚡️ ack\");\n },\n blocked: (leases: Array<Lease & { error: string }>) => {\n const data = Object.fromEntries(\n leases.map(({ stream, at, retry, error }) => [\n stream,\n { at, retry, error },\n ])\n );\n logger.trace(data, \"⚡️ block\");\n },\n };\n } else {\n return {\n fetched: () => {},\n correlated: () => {},\n leased: () => {},\n acked: () => {},\n blocked: () => {},\n };\n }\n}\n","import type { Message, Schema, Schemas, Snapshot, Target } from \"./action.js\";\n\n/**\n * @packageDocumentation\n * @module act/types\n * @category Types\n * Application error type constants and error classes for the Act Framework.\n *\n * - `ERR_VALIDATION`: Schema validation error\n * - `ERR_INVARIANT`: Invariant validation error\n * - `ERR_CONCURRENCY`: Optimistic concurrency validation error on commits\n */\nexport const Errors = {\n ValidationError: \"ERR_VALIDATION\",\n InvariantError: \"ERR_INVARIANT\",\n ConcurrencyError: \"ERR_CONCURRENCY\",\n} as const;\n\n/**\n * Thrown when an action or event payload fails Zod schema validation.\n *\n * This error indicates that data doesn't match the expected schema defined\n * for an action or event. The `details` property contains the Zod validation\n * error with specific information about what failed.\n *\n * @example Catching validation errors\n * ```typescript\n * import { ValidationError } from \"@rotorsoft/act\";\n *\n * try {\n * await app.do(\"createUser\", target, {\n * email: \"invalid-email\", // Missing @ symbol\n * age: -5 // Negative age\n * });\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * console.error(\"Validation failed for:\", error.target);\n * console.error(\"Invalid payload:\", error.payload);\n * console.error(\"Validation details:\", error.details);\n * // details contains Zod error with field-level info\n * }\n * }\n * ```\n *\n * @example Logging validation details\n * ```typescript\n * try {\n * await app.do(\"updateProfile\", target, payload);\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * error.details.errors.forEach((err) => {\n * console.error(`Field ${err.path.join(\".\")}: ${err.message}`);\n * });\n * }\n * }\n * ```\n *\n * @see {@link https://zod.dev | Zod documentation} for validation details\n */\nexport class ValidationError extends Error {\n constructor(\n /** The type of target being validated (e.g., \"action\", \"event\") */\n public readonly target: string,\n /** The invalid payload that failed validation */\n public readonly payload: any,\n /** Zod validation error details */\n public readonly details: any\n ) {\n super(`Invalid ${target} payload`);\n this.name = Errors.ValidationError;\n }\n}\n\n/**\n * Thrown when a business rule (invariant) is violated during action execution.\n *\n * Invariants are conditions that must hold true for an action to succeed.\n * They're checked after loading the current state but before emitting events.\n * This error provides complete context about what action was attempted and\n * why it was rejected.\n *\n * @template S - State schema type\n * @template E - Event schemas type\n * @template A - Action schemas type\n * @template K - Action name\n *\n * @example Catching invariant violations\n * ```typescript\n * import { InvariantError } from \"@rotorsoft/act\";\n *\n * try {\n * await app.do(\"withdraw\",\n * { stream: \"account-123\", actor: { id: \"user1\", name: \"Alice\" } },\n * { amount: 1000 }\n * );\n * } catch (error) {\n * if (error instanceof InvariantError) {\n * console.error(\"Action:\", error.action);\n * console.error(\"Reason:\", error.description);\n * console.error(\"Current state:\", error.snapshot.state);\n * console.error(\"Attempted payload:\", error.payload);\n * }\n * }\n * ```\n *\n * @example User-friendly error messages\n * ```typescript\n * try {\n * await app.do(\"closeTicket\", target, payload);\n * } catch (error) {\n * if (error instanceof InvariantError) {\n * // Present friendly message to user\n * if (error.description === \"Ticket must be open\") {\n * return { error: \"This ticket is already closed\" };\n * } else if (error.description === \"Not authorized\") {\n * return { error: \"You don't have permission to close this ticket\" };\n * }\n * }\n * }\n * ```\n *\n * @example Logging with context\n * ```typescript\n * try {\n * await app.do(\"transfer\", target, { to: \"account2\", amount: 500 });\n * } catch (error) {\n * if (error instanceof InvariantError) {\n * logger.error({\n * action: error.action,\n * stream: error.target.stream,\n * actor: error.target.actor,\n * reason: error.description,\n * balance: error.snapshot.state.balance,\n * attempted: error.payload.amount\n * }, \"Invariant violation\");\n * }\n * }\n * ```\n *\n * @see {@link Invariant} for defining business rules\n */\nexport class InvariantError<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n K extends keyof A,\n> extends Error {\n constructor(\n /** The action that was attempted */\n readonly action: K,\n /** The action payload that was provided */\n readonly payload: Readonly<A[K]>,\n /** The target stream and actor context */\n readonly target: Target,\n /** The current state snapshot when invariant was checked */\n readonly snapshot: Snapshot<S, E>,\n /** Human-readable description of why the invariant failed */\n readonly description: string\n ) {\n super(`${action as string} failed invariant: ${description}`);\n this.name = Errors.InvariantError;\n }\n}\n\n/**\n * Thrown when optimistic concurrency control detects a conflict.\n *\n * This error occurs when trying to commit events to a stream that has been\n * modified by another process since it was last loaded. The version number\n * doesn't match expectations, indicating a concurrent modification.\n *\n * This is a normal occurrence in distributed systems and should be handled\n * by reloading the current state and retrying the action.\n *\n * @example Handling concurrency conflicts with retry\n * ```typescript\n * import { ConcurrencyError } from \"@rotorsoft/act\";\n *\n * async function transferWithRetry(from, to, amount, maxRetries = 3) {\n * for (let attempt = 0; attempt < maxRetries; attempt++) {\n * try {\n * await app.do(\"transfer\",\n * { stream: from, actor: currentUser },\n * { to, amount }\n * );\n * return { success: true };\n * } catch (error) {\n * if (error instanceof ConcurrencyError) {\n * if (attempt < maxRetries - 1) {\n * console.log(`Concurrent modification detected, retrying... (${attempt + 1}/${maxRetries})`);\n * await sleep(100 * Math.pow(2, attempt)); // Exponential backoff\n * continue;\n * }\n * }\n * throw error;\n * }\n * }\n * return { success: false, reason: \"Too many concurrent modifications\" };\n * }\n * ```\n *\n * @example Logging concurrency conflicts\n * ```typescript\n * try {\n * await app.do(\"updateInventory\", target, payload);\n * } catch (error) {\n * if (error instanceof ConcurrencyError) {\n * logger.warn({\n * stream: error.stream,\n * expectedVersion: error.expectedVersion,\n * actualVersion: error.lastVersion,\n * events: error.events.map(e => e.name)\n * }, \"Concurrent modification detected\");\n * }\n * }\n * ```\n *\n * @example User feedback for conflicts\n * ```typescript\n * try {\n * await app.do(\"editDocument\", target, { content: newContent });\n * } catch (error) {\n * if (error instanceof ConcurrencyError) {\n * return {\n * error: \"This document was modified by another user. Please refresh and try again.\",\n * code: \"CONCURRENT_MODIFICATION\"\n * };\n * }\n * }\n * ```\n *\n * @see {@link Store.commit} for version checking details\n */\nexport class ConcurrencyError extends Error {\n constructor(\n /** The stream that had the concurrent modification */\n public readonly stream: string,\n /** The actual current version in the store */\n public readonly lastVersion: number,\n /** The events that were being committed */\n public readonly events: Message<Schemas, keyof Schemas>[],\n /** The version number that was expected */\n public readonly expectedVersion: number\n ) {\n super(\n `Concurrency error committing \"${events\n .map((e) => `${stream}.${e.name}.${JSON.stringify(e.data)}`)\n .join(\n \", \"\n )}\". Expected version ${expectedVersion} but found version ${lastVersion}.`\n );\n this.name = Errors.ConcurrencyError;\n }\n}\n","import { type ZodError, type ZodType, prettifyError } from \"zod\";\nimport { config } from \"./config.js\";\nimport type { Patch, Schema } from \"./types/index.js\";\nimport { ValidationError } from \"./types/index.js\";\n\n/** These objects are copied instead of deep merged */\nconst UNMERGEABLES = [\n RegExp,\n Date,\n Array,\n Map,\n Set,\n WeakMap,\n WeakSet,\n ArrayBuffer,\n SharedArrayBuffer,\n DataView,\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n Float32Array,\n Float64Array,\n];\n\nconst is_mergeable = (value: any): boolean =>\n !!value &&\n typeof value === \"object\" &&\n !UNMERGEABLES.some((t) => value instanceof t);\n\n/**\n * @module utils\n * @category Utilities\n * Utility functions for patching state, validation, extending objects, and async helpers.\n *\n * - Use `patch()` to immutably update state with patches.\n * - Use `validate()` to validate payloads against Zod schemas.\n * - Use `extend()` to merge and validate configuration objects.\n * - Use `sleep()` for async delays.\n */\n\n/**\n * Immutably applies patches to a state object, creating a new copy.\n *\n * This function performs deep merging for plain objects while preserving\n * immutability. Special types (Arrays, Dates, Maps, etc.) are replaced\n * entirely rather than merged. Setting a property to `undefined` or `null`\n * removes it from the resulting object.\n *\n * Used internally by the framework to apply event patches to state, but\n * can also be used directly for state transformations.\n *\n * **Merging rules:**\n * - Plain objects: Deep merge recursively\n * - Arrays, Dates, RegExp, Maps, Sets, TypedArrays: Replace entirely\n * - `undefined` or `null` values: Delete the property\n * - Primitives: Replace with patch value\n *\n * @param original - The original state object to patch\n * @param patches - The patches to apply (partial state)\n * @returns A new state object with patches applied\n *\n * @example Simple property update\n * ```typescript\n * import { patch } from \"@rotorsoft/act\";\n *\n * const state = { count: 0, name: \"Alice\" };\n * const updated = patch(state, { count: 5 });\n * // Result: { count: 5, name: \"Alice\" }\n * // Original unchanged: { count: 0, name: \"Alice\" }\n * ```\n *\n * @example Nested object patching\n * ```typescript\n * const state = {\n * user: { id: 1, name: \"Alice\", email: \"alice@example.com\" },\n * settings: { theme: \"dark\" }\n * };\n *\n * const updated = patch(state, {\n * user: { email: \"newemail@example.com\" }\n * });\n * // Result: {\n * // user: { id: 1, name: \"Alice\", email: \"newemail@example.com\" },\n * // settings: { theme: \"dark\" }\n * // }\n * ```\n *\n * @example Property deletion\n * ```typescript\n * const state = { count: 5, temp: \"value\", flag: true };\n *\n * const updated = patch(state, {\n * temp: undefined, // Delete temp\n * flag: null // Delete flag\n * });\n * // Result: { count: 5 }\n * ```\n *\n * @example Array replacement (not merged)\n * ```typescript\n * const state = { items: [1, 2, 3], meta: { count: 3 } };\n *\n * const updated = patch(state, {\n * items: [4, 5] // Arrays are replaced, not merged\n * });\n * // Result: { items: [4, 5], meta: { count: 3 } }\n * ```\n *\n * @example In event handlers\n * ```typescript\n * import { state } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const Counter = state({ Counter: z.object({ count: z.number() }) })\n * .init(() => ({ count: 0 }))\n * .emits({ Incremented: z.object({ by: z.number() }) })\n * .patch({\n * Incremented: (event, state) => {\n * // patch() is called internally here\n * return { count: state.count + event.data.by };\n * }\n * });\n * ```\n *\n * @see {@link Patch} for the patch type definition\n */\nexport const patch = <S extends Schema>(\n original: Readonly<S>,\n patches: Readonly<Patch<S>>\n): Readonly<S> => {\n const copy = {} as Record<string, any>;\n Object.keys({ ...original, ...patches }).forEach((key) => {\n const patched_value = patches[key as keyof typeof patches];\n const original_value = original[key as keyof typeof original];\n const patched = patches && key in patches;\n const deleted =\n patched &&\n (typeof patched_value === \"undefined\" || patched_value === null);\n const value = patched && !deleted ? patched_value : original_value;\n !deleted &&\n (copy[key] = is_mergeable(value)\n ? patch(original_value || {}, patched_value || {})\n : value);\n });\n return copy as S;\n};\n\n/**\n * Validates a payload against a Zod schema.\n *\n * This is the primary validation function used throughout the Act framework.\n * It parses the payload using the provided Zod schema and throws a\n * {@link ValidationError} with detailed error information if validation fails.\n *\n * When no schema is provided, the payload is returned as-is without validation.\n * This allows for optional validation in the framework.\n *\n * The framework automatically calls this function when:\n * - Actions are invoked via `app.do()`\n * - Events are emitted from action handlers\n * - States are initialized\n *\n * @param target - Name of the target being validated (used in error messages)\n * @param payload - The data to validate\n * @param schema - Optional Zod schema to validate against\n * @returns The validated and type-safe payload\n * @throws {@link ValidationError} if validation fails with detailed error info\n *\n * @example Basic validation\n * ```typescript\n * import { validate } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const UserSchema = z.object({\n * email: z.string().email(),\n * age: z.number().min(0)\n * });\n *\n * const user = validate(\"User\", { email: \"alice@example.com\", age: 30 }, UserSchema);\n * // Returns: { email: \"alice@example.com\", age: 30 }\n * ```\n *\n * @example Handling validation errors\n * ```typescript\n * import { validate, ValidationError } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const schema = z.object({\n * email: z.string().email(),\n * age: z.number().min(18)\n * });\n *\n * try {\n * validate(\"User\", { email: \"invalid\", age: 15 }, schema);\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * console.error(\"Target:\", error.target); // \"User\"\n * console.error(\"Payload:\", error.payload); // { email: \"invalid\", age: 15 }\n * console.error(\"Details:\", error.details); // Prettified Zod errors\n * // Details shows: email must be valid, age must be >= 18\n * }\n * }\n * ```\n *\n * @example Optional validation\n * ```typescript\n * // When schema is undefined, payload is returned as-is\n * const data = validate(\"Data\", { any: \"value\" });\n * // Returns: { any: \"value\" } without validation\n * ```\n *\n * @example In action definitions\n * ```typescript\n * import { state } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const Counter = state({ Counter: z.object({ count: z.number() }) })\n * .init(() => ({ count: 0 }))\n * .emits({ Incremented: z.object({ by: z.number().positive() }) })\n * .on({ increment: z.object({ by: z.number() }) })\n * .emit((action) => {\n * // validate() is called automatically before this runs\n * // action.by is guaranteed to be a number\n * return [\"Incremented\", { by: action.by }];\n * })\n * .build();\n * ```\n *\n * @example Custom validation in application code\n * ```typescript\n * import { validate } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const ConfigSchema = z.object({\n * apiKey: z.string().min(32),\n * timeout: z.number().positive(),\n * retries: z.number().int().min(0).max(10)\n * });\n *\n * function loadConfig(raw: unknown) {\n * return validate(\"AppConfig\", raw, ConfigSchema);\n * }\n * ```\n *\n * @see {@link ValidationError} for error handling\n * @see {@link https://zod.dev | Zod documentation} for schema definition\n */\nexport const validate = <S>(\n target: string,\n payload: Readonly<S>,\n schema?: ZodType<S>\n): Readonly<S> => {\n try {\n return schema ? schema.parse(payload) : payload;\n } catch (error) {\n if (error instanceof Error && error.name === \"ZodError\") {\n throw new ValidationError(\n target,\n payload,\n prettifyError(error as ZodError)\n );\n }\n throw new ValidationError(target, payload, error);\n }\n};\n\n/**\n * Validates and merges configuration objects.\n *\n * This function first validates the source object against a Zod schema using\n * {@link validate}, then merges it with an optional target object. The source\n * properties override target properties in the result.\n *\n * Primarily used for configuration management where you want to:\n * 1. Define default configuration values\n * 2. Load environment-specific overrides\n * 3. Validate the final configuration\n *\n * The framework uses this internally for the {@link config} function.\n *\n * @template S - Source object type (must be a record)\n * @template T - Target object type (must be a record)\n * @param source - The source object to validate and use as overrides\n * @param schema - Zod schema to validate the source against\n * @param target - Optional target object with default values\n * @returns Merged object with validated source overriding target\n * @throws {@link ValidationError} if source fails schema validation\n *\n * @example Basic configuration merging\n * ```typescript\n * import { extend } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const ConfigSchema = z.object({\n * host: z.string(),\n * port: z.number(),\n * debug: z.boolean()\n * });\n *\n * const defaults = { host: \"localhost\", port: 3000, debug: false };\n * const overrides = { port: 8080, debug: true };\n *\n * const config = extend(overrides, ConfigSchema, defaults);\n * // Result: { host: \"localhost\", port: 8080, debug: true }\n * ```\n *\n * @example Environment-based configuration\n * ```typescript\n * import { extend } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const DbConfigSchema = z.object({\n * host: z.string(),\n * port: z.number(),\n * database: z.string(),\n * user: z.string(),\n * password: z.string()\n * });\n *\n * const defaults = {\n * host: \"localhost\",\n * port: 5432,\n * database: \"myapp_dev\",\n * user: \"postgres\",\n * password: \"dev\"\n * };\n *\n * const envConfig = {\n * host: process.env.DB_HOST || \"localhost\",\n * port: parseInt(process.env.DB_PORT || \"5432\"),\n * database: process.env.DB_NAME || \"myapp_dev\",\n * user: process.env.DB_USER || \"postgres\",\n * password: process.env.DB_PASSWORD || \"dev\"\n * };\n *\n * // Validates environment config and merges with defaults\n * const dbConfig = extend(envConfig, DbConfigSchema, defaults);\n * ```\n *\n * @example Framework usage\n * ```typescript\n * // This is how Act's config() function uses extend internally:\n * import { extend } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const BaseSchema = z.object({\n * env: z.enum([\"development\", \"test\", \"staging\", \"production\"]),\n * logLevel: z.enum([\"fatal\", \"error\", \"warn\", \"info\", \"debug\", \"trace\"]),\n * sleepMs: z.number().int().min(0).max(5000)\n * });\n *\n * const packageData = { name: \"my-app\", version: \"1.0.0\" };\n * const runtimeConfig = { env: \"production\", logLevel: \"info\", sleepMs: 100 };\n *\n * const config = extend(\n * { ...packageData, ...runtimeConfig },\n * BaseSchema,\n * packageData\n * );\n * ```\n *\n * @example With validation error handling\n * ```typescript\n * import { extend, ValidationError } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const schema = z.object({\n * apiKey: z.string().min(32),\n * timeout: z.number().positive()\n * });\n *\n * try {\n * const config = extend(\n * { apiKey: \"short\", timeout: -1 },\n * schema\n * );\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * console.error(\"Invalid configuration:\", error.details);\n * }\n * }\n * ```\n *\n * @see {@link validate} for validation details\n * @see {@link config} for framework configuration\n * @see {@link ValidationError} for error handling\n */\nexport const extend = <\n S extends Record<string, unknown>,\n T extends Record<string, unknown>,\n>(\n source: Readonly<S>,\n schema: ZodType<S>,\n target?: Readonly<T>\n): Readonly<S & T> => {\n const value = validate(\"config\", source, schema);\n return Object.assign(target || {}, value) as Readonly<S & T>;\n};\n\n/**\n * Pauses async execution for a specified duration.\n *\n * This is a simple async utility for adding delays in your code. When called\n * without arguments, it uses the configured sleep duration from `config().sleepMs`,\n * which defaults to 100ms in development and 0ms in test environments.\n *\n * The framework uses this internally in store adapters to simulate I/O delays\n * in the {@link InMemoryStore}.\n *\n * **Note:** In test environments (NODE_ENV=test), the default sleep duration is\n * 0ms to keep tests fast.\n *\n * @param ms - Optional duration in milliseconds (defaults to config().sleepMs)\n * @returns Promise that resolves after the specified delay\n *\n * @example Using default sleep duration\n * ```typescript\n * import { sleep } from \"@rotorsoft/act\";\n *\n * async function processWithDelay() {\n * console.log(\"Starting...\");\n * await sleep(); // Uses config().sleepMs (100ms in dev, 0ms in test)\n * console.log(\"Continued after delay\");\n * }\n * ```\n *\n * @example Custom sleep duration\n * ```typescript\n * import { sleep } from \"@rotorsoft/act\";\n *\n * async function retryWithBackoff(fn: () => Promise<void>, retries = 3) {\n * for (let i = 0; i < retries; i++) {\n * try {\n * await fn();\n * return;\n * } catch (error) {\n * if (i < retries - 1) {\n * const delay = Math.pow(2, i) * 1000; // Exponential backoff\n * console.log(`Retrying in ${delay}ms...`);\n * await sleep(delay);\n * } else {\n * throw error;\n * }\n * }\n * }\n * }\n * ```\n *\n * @example Rate limiting\n * ```typescript\n * import { sleep } from \"@rotorsoft/act\";\n *\n * async function processItems(items: string[]) {\n * for (const item of items) {\n * await processItem(item);\n * await sleep(500); // 500ms between items\n * }\n * }\n * ```\n *\n * @example Framework internal usage\n * ```typescript\n * // InMemoryStore uses sleep to simulate async I/O\n * class InMemoryStore implements Store {\n * async query(...) {\n * await sleep(); // Simulate database latency\n * // ... query logic\n * }\n *\n * async commit(...) {\n * await sleep(); // Simulate write latency\n * // ... commit logic\n * }\n * }\n * ```\n *\n * @example Configuring default sleep duration\n * ```bash\n * # Set custom default sleep duration via environment variable\n * SLEEP_MS=50 npm start\n *\n * # In tests, it's automatically 0\n * NODE_ENV=test npm test\n * ```\n *\n * @see {@link config} for sleep duration configuration\n */\nexport async function sleep(ms?: number) {\n return new Promise((resolve) => setTimeout(resolve, ms ?? config().sleepMs));\n}\n","/**\n * @packageDocumentation\n * Configuration utilities for Act Framework environment, logging, and package metadata.\n *\n * Provides type-safe configuration loading and validation using Zod schemas.\n *\n * @module config\n */\nimport * as fs from \"node:fs\";\nimport { z } from \"zod\";\nimport {\n Environment,\n Environments,\n LogLevel,\n LogLevels,\n} from \"./types/index.js\";\nimport { extend } from \"./utils.js\";\n\n/**\n * Zod schema for validating package.json metadata.\n * @internal\n */\nexport const PackageSchema = z.object({\n name: z.string().min(1),\n version: z.string().min(1),\n description: z.string().min(1).optional(),\n author: z\n .object({ name: z.string().min(1), email: z.string().optional() })\n .optional()\n .or(z.string().min(1))\n .optional(),\n license: z.string().min(1).optional(),\n dependencies: z.record(z.string(), z.string()).optional(),\n});\n\n/**\n * Type representing the validated package.json metadata.\n */\nexport type Package = z.infer<typeof PackageSchema>;\n\n/**\n * Loads and parses the local package.json file as a Package object.\n * @returns The parsed and validated package metadata.\n * @internal\n */\nconst getPackage = (): Package => {\n const pkg = fs.readFileSync(\"package.json\");\n return JSON.parse(pkg.toString()) as Package;\n};\n\n/**\n * Zod schema for the full Act Framework configuration object.\n * Includes package metadata, environment, logging, and timing options.\n * @internal\n */\nconst BaseSchema = PackageSchema.extend({\n env: z.enum(Environments),\n logLevel: z.enum(LogLevels),\n logSingleLine: z.boolean(),\n sleepMs: z.number().int().min(0).max(5000),\n});\n\n/**\n * Type representing the validated Act Framework configuration object.\n */\nexport type Config = z.infer<typeof BaseSchema>;\n\nconst { NODE_ENV, LOG_LEVEL, LOG_SINGLE_LINE, SLEEP_MS } = process.env;\n\nconst env = (NODE_ENV || \"development\") as Environment;\nconst logLevel = (LOG_LEVEL ||\n (NODE_ENV === \"test\"\n ? \"error\"\n : NODE_ENV === \"production\"\n ? \"info\"\n : \"trace\")) as LogLevel;\nconst logSingleLine = (LOG_SINGLE_LINE || \"true\") === \"true\";\nconst sleepMs = parseInt(NODE_ENV === \"test\" ? \"0\" : (SLEEP_MS ?? \"100\"));\n\nconst pkg = getPackage();\n\n/**\n * Gets the current Act Framework configuration.\n *\n * Configuration is loaded from package.json and environment variables, providing\n * type-safe access to application metadata and runtime settings.\n *\n * **Environment Variables:**\n * - `NODE_ENV`: \"development\" | \"test\" | \"staging\" | \"production\" (default: \"development\")\n * - `LOG_LEVEL`: \"fatal\" | \"error\" | \"warn\" | \"info\" | \"debug\" | \"trace\"\n * - `LOG_SINGLE_LINE`: \"true\" | \"false\" (default: \"true\")\n * - `SLEEP_MS`: Milliseconds for sleep utility (default: 100, 0 for tests)\n *\n * **Defaults by environment:**\n * - test: logLevel=\"error\", sleepMs=0\n * - production: logLevel=\"info\"\n * - development: logLevel=\"trace\"\n *\n * @returns The validated configuration object\n *\n * @example Basic usage\n * ```typescript\n * import { config } from \"@rotorsoft/act\";\n *\n * const cfg = config();\n * console.log(`App: ${cfg.name} v${cfg.version}`);\n * console.log(`Environment: ${cfg.env}`);\n * console.log(`Log level: ${cfg.logLevel}`);\n * ```\n *\n * @example Environment-specific behavior\n * ```typescript\n * import { config } from \"@rotorsoft/act\";\n *\n * const cfg = config();\n *\n * if (cfg.env === \"production\") {\n * // Use PostgreSQL in production\n * store(new PostgresStore(prodConfig));\n * } else {\n * // Use in-memory store for dev/test\n * store(new InMemoryStore());\n * }\n * ```\n *\n * @example Adjusting log levels\n * ```typescript\n * // Set via environment variable:\n * // LOG_LEVEL=debug npm start\n *\n * // Or check in code:\n * const cfg = config();\n * if (cfg.logLevel === \"trace\") {\n * logger.trace(\"Detailed debugging enabled\");\n * }\n * ```\n *\n * @see {@link Config} for configuration type\n * @see {@link Package} for package.json metadata\n */\nexport const config = (): Config => {\n return extend({ ...pkg, env, logLevel, logSingleLine, sleepMs }, BaseSchema);\n};\n","import { z, ZodObject, ZodRawShape } from \"zod\";\n\n/**\n * @packageDocumentation\n * @module act/types\n * @category Types\n * Zod schemas and helpers for the Act Framework.\n */\n\n/**\n * An empty Zod schema (no properties).\n */\nexport const ZodEmpty = z.record(z.string(), z.never());\n\n/**\n * Zod schema for an actor (user, system, etc.).\n */\nexport const ActorSchema = z\n .object({\n id: z.string(),\n name: z.string(),\n })\n .readonly();\n\n/**\n * Zod schema for a target (stream and actor info).\n */\nexport const TargetSchema = z\n .object({\n stream: z.string(),\n actor: ActorSchema,\n expectedVersion: z.number().optional(),\n })\n .readonly();\n\n/**\n * Zod schema for causation event metadata.\n */\nexport const CausationEventSchema = z.object({\n id: z.number(),\n name: z.string(),\n stream: z.string(),\n});\n\n/**\n * Zod schema for event metadata (correlation and causation).\n */\nexport const EventMetaSchema = z\n .object({\n correlation: z.string(),\n causation: z.object({\n action: TargetSchema.and(z.object({ name: z.string() })).optional(),\n event: CausationEventSchema.optional(),\n }),\n })\n .readonly();\n\n/**\n * Zod schema for committed event metadata (id, stream, version, created, meta).\n */\nexport const CommittedMetaSchema = z\n .object({\n id: z.number(),\n stream: z.string(),\n version: z.number(),\n created: z.date(),\n meta: EventMetaSchema,\n })\n .readonly();\n\n/**\n * Type representing the full state schema for a domain.\n * @property events - Map of event names to Zod schemas.\n * @property actions - Map of action names to Zod schemas.\n * @property state - Zod schema for the state object.\n */\nexport type StateSchema = Readonly<{\n events: Record<string, ZodObject<ZodRawShape> | typeof ZodEmpty>;\n actions: Record<string, ZodObject<ZodRawShape> | typeof ZodEmpty>;\n state: ZodObject<ZodRawShape>;\n}>;\n\n/**\n * Query options for event store queries.\n */\nexport const QuerySchema = z\n .object({\n stream: z.string().optional(),\n names: z.string().array().optional(),\n before: z.number().optional(),\n after: z.number().optional(),\n limit: z.number().optional(),\n created_before: z.date().optional(),\n created_after: z.date().optional(),\n backward: z.boolean().optional(),\n correlation: z.string().optional(),\n with_snaps: z.boolean().optional(),\n })\n .readonly();\n","/**\n * @packageDocumentation\n * @module act/types\n * Barrel file for Act Framework core types.\n *\n * Re-exports all major type definitions for actions, errors, ports, reactions, registries, and schemas.\n * Also defines common environment and log level types/constants for configuration and logging.\n *\n * @remarks\n * Import from this module to access all core framework types in one place.\n */\nexport type * from \"./action.js\";\nexport * from \"./errors.js\";\nexport type * from \"./ports.js\";\nexport type * from \"./reaction.js\";\nexport type * from \"./registry.js\";\nexport * from \"./schemas.js\";\n\n/**\n * Supported runtime environments for the framework.\n * - `development`: Local development\n * - `test`: Automated testing\n * - `staging`: Pre-production\n * - `production`: Live/production\n */\nexport const Environments = [\n \"development\",\n \"test\",\n \"staging\",\n \"production\",\n] as const;\n\n/**\n * Type representing a valid environment string.\n */\nexport type Environment = (typeof Environments)[number];\n\n/**\n * Supported log levels for framework logging.\n * - `fatal`, `error`, `warn`, `info`, `debug`, `trace`\n */\nexport const LogLevels = [\n \"fatal\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n \"trace\",\n] as const;\n\n/**\n * Type representing a valid log level string.\n */\nexport type LogLevel = (typeof LogLevels)[number];\n","/**\n * @packageDocumentation\n * @module act/adapters\n * In-memory event store adapter for the Act Framework.\n *\n * This adapter implements the Store interface and is suitable for development, testing, and demonstration purposes.\n * All data is stored in memory and lost on process exit.\n *\n * @category Adapters\n */\nimport { SNAP_EVENT } from \"../ports.js\";\nimport { ConcurrencyError } from \"../types/errors.js\";\nimport type {\n Committed,\n EventMeta,\n Lease,\n Message,\n Query,\n Schemas,\n Store,\n} from \"../types/index.js\";\nimport { sleep } from \"../utils.js\";\n\n/**\n * @internal\n * Represents an in-memory stream for event processing and leasing.\n */\nclass InMemoryStream {\n private _at = -1;\n private _retry = -1;\n private _blocked = false;\n private _error = \"\";\n private _leased_by: string | undefined = undefined;\n private _leased_until: Date | undefined = undefined;\n\n constructor(\n readonly stream: string,\n readonly source: string | undefined\n ) {}\n\n get is_avaliable() {\n return (\n !this._blocked &&\n (!this._leased_until || this._leased_until <= new Date())\n );\n }\n\n get at() {\n return this._at;\n }\n\n /**\n * Attempt to lease this stream for processing.\n * @param lease - The lease request.\n * @param millis - Lease duration in milliseconds.\n * @returns The granted lease or undefined if blocked.\n */\n lease(lease: Lease, millis: number): Lease | undefined {\n if (this.is_avaliable) {\n if (millis > 0) {\n this._leased_by = lease.by;\n this._leased_until = new Date(Date.now() + millis);\n this._retry = this._retry + 1;\n }\n return {\n stream: this.stream,\n source: this.source,\n at: lease.at,\n by: lease.by,\n retry: this._retry,\n lagging: lease.lagging,\n };\n }\n }\n\n /**\n * Acknowledge completion of processing for this stream.\n * @param lease - The lease request.\n */\n ack(lease: Lease) {\n if (this._leased_by === lease.by) {\n this._leased_by = undefined;\n this._leased_until = undefined;\n this._at = lease.at;\n this._retry = -1;\n return {\n stream: this.stream,\n source: this.source,\n at: this._at,\n by: lease.by,\n retry: this._retry,\n lagging: lease.lagging,\n };\n }\n }\n\n /**\n * Block a stream for processing after failing to process and reaching max retries with blocking enabled.\n * @param lease - The lease request.\n * @param error Blocked error message.\n */\n block(lease: Lease, error: string) {\n if (this._leased_by === lease.by) {\n this._blocked = true;\n this._error = error;\n return {\n stream: this.stream,\n source: this.source,\n at: this._at,\n by: this._leased_by,\n retry: this._retry,\n error: this._error,\n lagging: lease.lagging,\n };\n }\n }\n}\n\n/**\n * In-memory event store implementation.\n *\n * This is the default store used by Act when no other store is injected.\n * It stores all events in memory and is suitable for:\n * - Development and prototyping\n * - Unit and integration testing\n * - Demonstrations and examples\n *\n * **Not suitable for production** - all data is lost when the process exits.\n * Use {@link PostgresStore} for production deployments.\n *\n * The in-memory store provides:\n * - Full {@link Store} interface implementation\n * - Optimistic concurrency control\n * - Stream leasing for distributed processing simulation\n * - Snapshot support\n * - Fast performance (no I/O overhead)\n *\n * @example Using in tests\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n *\n * describe(\"Counter\", () => {\n * beforeEach(async () => {\n * // Reset store between tests\n * await store().seed();\n * });\n *\n * it(\"increments\", async () => {\n * await app.do(\"increment\", target, { by: 5 });\n * const snapshot = await app.load(Counter, \"counter-1\");\n * expect(snapshot.state.count).toBe(5);\n * });\n * });\n * ```\n *\n * @example Explicit instantiation\n * ```typescript\n * import { InMemoryStore } from \"@rotorsoft/act\";\n *\n * const testStore = new InMemoryStore();\n * await testStore.seed();\n *\n * // Use for specific test scenarios\n * await testStore.commit(\"test-stream\", events, meta);\n * ```\n *\n * @example Querying events\n * ```typescript\n * const events: any[] = [];\n * await store().query(\n * (event) => events.push(event),\n * { stream: \"test-stream\" }\n * );\n * console.log(`Found ${events.length} events`);\n * ```\n *\n * @see {@link Store} for the interface definition\n * @see {@link PostgresStore} for production use\n * @see {@link store} for injecting stores\n *\n * @category Adapters\n */\nexport class InMemoryStore implements Store {\n // stored events\n private _events: Committed<Schemas, keyof Schemas>[] = [];\n // stored stream positions and other metadata\n private _streams: Map<string, InMemoryStream> = new Map();\n\n /**\n * Dispose of the store and clear all events.\n * @returns Promise that resolves when disposal is complete.\n */\n async dispose() {\n await sleep();\n this._events.length = 0;\n }\n\n /**\n * Seed the store with initial data (no-op for in-memory).\n * @returns Promise that resolves when seeding is complete.\n */\n async seed() {\n await sleep();\n }\n\n /**\n * Drop all data from the store.\n * @returns Promise that resolves when the store is cleared.\n */\n async drop() {\n await sleep();\n this._events.length = 0;\n this._streams = new Map();\n }\n\n private in_query<E extends Schemas>(query: Query, e: Committed<E, keyof E>) {\n if (query.stream && !RegExp(`^${query.stream}$`).test(e.stream))\n return false;\n if (query.names && !query.names.includes(e.name as string)) return false;\n if (query.correlation && e.meta?.correlation !== query.correlation)\n return false;\n if (e.name === SNAP_EVENT && !query.with_snaps) return false;\n return true;\n }\n\n /**\n * Query events in the store, optionally filtered by query options.\n * @param callback - Function to call for each event.\n * @param query - Optional query options.\n * @returns The number of events processed.\n */\n async query<E extends Schemas>(\n callback: (event: Committed<E, keyof E>) => void,\n query?: Query\n ) {\n await sleep();\n let count = 0;\n if (query?.backward) {\n let i = (query?.before || this._events.length) - 1;\n while (i >= 0) {\n const e = this._events[i--];\n if (query && !this.in_query(query, e)) continue;\n if (query?.created_before && e.created >= query.created_before)\n continue;\n if (query.after && e.id <= query.after) break;\n if (query.created_after && e.created <= query.created_after) break;\n callback(e as Committed<E, keyof E>);\n count++;\n if (query?.limit && count >= query.limit) break;\n }\n } else {\n let i = (query?.after ?? -1) + 1;\n while (i < this._events.length) {\n const e = this._events[i++];\n if (query && !this.in_query(query, e)) continue;\n if (query?.created_after && e.created <= query.created_after) continue;\n if (query?.before && e.id >= query.before) break;\n if (query?.created_before && e.created >= query.created_before) break;\n callback(e as Committed<E, keyof E>);\n count++;\n if (query?.limit && count >= query.limit) break;\n }\n }\n return count;\n }\n\n /**\n * Commit one or more events to a stream.\n * @param stream - The stream name.\n * @param msgs - The events/messages to commit.\n * @param meta - Event metadata.\n * @param expectedVersion - Optional optimistic concurrency check.\n * @returns The committed events with metadata.\n * @throws ConcurrencyError if expectedVersion does not match.\n */\n async commit<E extends Schemas>(\n stream: string,\n msgs: Message<E, keyof E>[],\n meta: EventMeta,\n expectedVersion?: number\n ) {\n await sleep();\n const instance = this._events.filter((e) => e.stream === stream); // ignore state events, this is a production optimization\n if (\n typeof expectedVersion === \"number\" &&\n instance.length - 1 !== expectedVersion\n ) {\n throw new ConcurrencyError(\n stream,\n instance.length - 1,\n msgs as Message<Schemas, keyof Schemas>[],\n expectedVersion\n );\n }\n\n let version = instance.length;\n return msgs.map(({ name, data }) => {\n const committed: Committed<E, keyof E> = {\n id: this._events.length,\n stream,\n version,\n created: new Date(),\n name,\n data,\n meta,\n };\n this._events.push(committed as Committed<Schemas, keyof Schemas>);\n version++;\n return committed;\n });\n }\n\n /**\n * Polls the store for unblocked streams needing processing, ordered by lease watermark ascending.\n * @param lagging - Max number of streams to poll in ascending order.\n * @param leading - Max number of streams to poll in descending order.\n * @returns The polled streams.\n */\n async poll(lagging: number, leading: number) {\n await sleep();\n const a = [...this._streams.values()]\n .filter((s) => s.is_avaliable)\n .sort((a, b) => a.at - b.at)\n .slice(0, lagging)\n .map(({ stream, source, at }) => ({\n stream,\n source,\n at,\n lagging: true,\n }));\n const b = [...this._streams.values()]\n .filter((s) => s.is_avaliable)\n .sort((a, b) => b.at - a.at)\n .slice(0, leading)\n .map(({ stream, source, at }) => ({\n stream,\n source,\n at,\n lagging: false,\n }));\n return [...a, ...b];\n }\n\n /**\n * Lease streams for processing (e.g., for distributed consumers).\n * @param leases - Lease requests for streams, including end-of-lease watermark, lease holder, and source stream.\n * @param leaseMilis - Lease duration in milliseconds.\n * @returns Granted leases.\n */\n async lease(leases: Lease[], millis: number) {\n await sleep();\n return leases\n .map((l) => {\n if (!this._streams.has(l.stream)) {\n // store new correlations\n this._streams.set(l.stream, new InMemoryStream(l.stream, l.source));\n }\n return this._streams.get(l.stream)?.lease(l, millis);\n })\n .filter((l) => !!l);\n }\n\n /**\n * Acknowledge completion of processing for leased streams.\n * @param leases - Leases to acknowledge, including last processed watermark and lease holder.\n */\n async ack(leases: Lease[]) {\n await sleep();\n return leases\n .map((l) => this._streams.get(l.stream)?.ack(l))\n .filter((l) => !!l);\n }\n\n /**\n * Block a stream for processing after failing to process and reaching max retries with blocking enabled.\n * @param leases - Leases to block, including lease holder and last error message.\n * @returns Blocked leases.\n */\n async block(leases: Array<Lease & { error: string }>) {\n await sleep();\n return leases\n .map((l) => this._streams.get(l.stream)?.block(l, l.error))\n .filter((l) => !!l);\n }\n}\n","import { disposeAndExit, logger } from \"./ports.js\";\n\n// exit on signals\nprocess.once(\"SIGINT\", async (arg?: any) => {\n logger.info(arg, \"SIGINT\");\n await disposeAndExit(\"EXIT\");\n});\nprocess.once(\"SIGTERM\", async (arg?: any) => {\n logger.info(arg, \"SIGTERM\");\n await disposeAndExit(\"EXIT\");\n});\nprocess.once(\"uncaughtException\", async (arg?: any) => {\n logger.error(arg, \"Uncaught Exception\");\n await disposeAndExit(\"ERROR\");\n});\nprocess.once(\"unhandledRejection\", async (arg?: any) => {\n logger.error(arg, \"Unhandled Rejection\");\n await disposeAndExit(\"ERROR\");\n});\n","import { randomUUID } from \"crypto\";\nimport EventEmitter from \"events\";\nimport { config } from \"./config.js\";\nimport * as es from \"./event-sourcing.js\";\nimport { build_tracer, dispose, logger, store } from \"./ports.js\";\nimport type {\n Committed,\n Drain,\n DrainOptions,\n Lease,\n Query,\n ReactionPayload,\n Registry,\n Schema,\n SchemaRegister,\n Schemas,\n Snapshot,\n State,\n Target,\n} from \"./types/index.js\";\n\nconst tracer = build_tracer(config().logLevel);\n\n/**\n * @category Orchestrator\n * @see Store\n *\n * Main orchestrator for event-sourced state machines and workflows.\n *\n * It manages the lifecycle of actions, reactions, and event streams, providing APIs for loading state, executing actions, querying events, and draining reactions.\n *\n * ## Usage\n *\n * ```typescript\n * const app = new Act(registry, 100);\n * await app.do(\"increment\", { stream: \"counter1\", actor }, { by: 1 });\n * const snapshot = await app.load(Counter, \"counter1\");\n * await app.drain();\n * ```\n *\n * - Register event listeners with `.on(\"committed\", ...)` and `.on(\"acked\", ...)` to react to lifecycle events.\n * - Use `.query()` to analyze event streams for analytics or debugging.\n *\n * @template S SchemaRegister for state\n * @template E Schemas for events\n * @template A Schemas for actions\n */\nexport class Act<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n M extends Record<string, Schema> = Record<string, never>,\n> {\n private _emitter = new EventEmitter();\n private _drain_locked = false;\n private _drain_lag2lead_ratio = 0.5;\n private _correlation_interval: NodeJS.Timeout | undefined = undefined;\n\n /**\n * Emit a lifecycle event (internal use, but can be used for custom listeners).\n *\n * @param event The event name (\"committed\", \"acked\", or \"blocked\")\n * @param args The event payload\n * @returns true if the event had listeners, false otherwise\n */\n emit(event: \"committed\", args: Snapshot<S, E>[]): boolean;\n emit(event: \"acked\", args: Lease[]): boolean;\n emit(event: \"blocked\", args: Array<Lease & { error: string }>): boolean;\n emit(event: string, args: any): boolean {\n return this._emitter.emit(event, args);\n }\n\n /**\n * Register a listener for a lifecycle event (\"committed\", \"acked\", or \"blocked\").\n *\n * @param event The event name\n * @param listener The callback function\n * @returns this (for chaining)\n */\n on(event: \"committed\", listener: (args: Snapshot<S, E>[]) => void): this;\n on(event: \"acked\", listener: (args: Lease[]) => void): this;\n on(\n event: \"blocked\",\n listener: (args: Array<Lease & { error: string }>) => void\n ): this;\n on(event: string, listener: (args: any) => void): this {\n this._emitter.on(event, listener);\n return this;\n }\n\n /**\n * Remove a listener for a lifecycle event.\n *\n * @param event The event name\n * @param listener The callback function\n * @returns this (for chaining)\n */\n off(event: \"committed\", listener: (args: Snapshot<S, E>[]) => void): this;\n off(event: \"acked\", listener: (args: Lease[]) => void): this;\n off(\n event: \"blocked\",\n listener: (args: Array<Lease & { error: string }>) => void\n ): this;\n off(event: string, listener: (args: any) => void): this {\n this._emitter.off(event, listener);\n return this;\n }\n\n /**\n * Create a new Act orchestrator.\n *\n * @param registry The registry of state, event, and action schemas\n * @param states Map of state names to their (potentially merged) state definitions\n */\n constructor(\n public readonly registry: Registry<S, E, A>,\n private readonly _states: Map<string, State<any, any, any>> = new Map()\n ) {\n dispose(() => {\n this._emitter.removeAllListeners();\n this.stop_correlations();\n return Promise.resolve();\n });\n }\n\n /**\n * Executes an action on a state instance, committing resulting events.\n *\n * This is the primary method for modifying state. It:\n * 1. Validates the action payload against the schema\n * 2. Loads the current state snapshot\n * 3. Checks invariants (business rules)\n * 4. Executes the action handler to generate events\n * 5. Applies events to create new state\n * 6. Commits events to the store with optimistic concurrency control\n *\n * @template K - Action name from registered actions\n * @param action - The name of the action to execute\n * @param target - Target specification with stream ID and actor context\n * @param payload - Action payload matching the action's schema\n * @param reactingTo - Optional event that triggered this action (for correlation)\n * @param skipValidation - Skip schema validation (use carefully, for performance)\n * @returns Array of snapshots for all affected states (usually one)\n *\n * @throws {ValidationError} If payload doesn't match action schema\n * @throws {InvariantError} If business rules are violated\n * @throws {ConcurrencyError} If another process modified the stream\n *\n * @example Basic action execution\n * ```typescript\n * const snapshots = await app.do(\n * \"increment\",\n * {\n * stream: \"counter-1\",\n * actor: { id: \"user1\", name: \"Alice\" }\n * },\n * { by: 5 }\n * );\n *\n * console.log(snapshots[0].state.count); // Current count after increment\n * ```\n *\n * @example With error handling\n * ```typescript\n * try {\n * await app.do(\n * \"withdraw\",\n * { stream: \"account-123\", actor: { id: \"user1\", name: \"Alice\" } },\n * { amount: 1000 }\n * );\n * } catch (error) {\n * if (error instanceof InvariantError) {\n * console.error(\"Business rule violated:\", error.description);\n * } else if (error instanceof ConcurrencyError) {\n * console.error(\"Concurrent modification detected, retry...\");\n * } else if (error instanceof ValidationError) {\n * console.error(\"Invalid payload:\", error.details);\n * }\n * }\n * ```\n *\n * @example Reaction triggering another action\n * ```typescript\n * const app = act()\n * .with(Order)\n * .with(Inventory)\n * .on(\"OrderPlaced\")\n * .do(async (event, context) => {\n * // This action is triggered by an event\n * const result = await context.app.do(\n * \"reduceStock\",\n * {\n * stream: \"inventory-1\",\n * actor: event.meta.causation.action.actor\n * },\n * { amount: event.data.items.length },\n * event // Pass event for correlation tracking\n * );\n * return result;\n * })\n * .to(\"inventory-1\")\n * .build();\n * ```\n *\n * @see {@link Target} for target structure\n * @see {@link Snapshot} for return value structure\n * @see {@link ValidationError}, {@link InvariantError}, {@link ConcurrencyError}\n */\n async do<K extends keyof A>(\n action: K,\n target: Target,\n payload: Readonly<A[K]>,\n reactingTo?: Committed<E, string & keyof E>,\n skipValidation = false\n ) {\n const snapshots = await es.action(\n this.registry.actions[action],\n action,\n target,\n payload,\n reactingTo,\n skipValidation\n );\n this.emit(\"committed\", snapshots as Snapshot<S, E>[]);\n return snapshots;\n }\n\n /**\n * Loads the current state snapshot for a specific stream.\n *\n * Reconstructs the current state by replaying events from the event store.\n * Uses snapshots when available to optimize loading performance.\n *\n * Accepts either a State definition object or a state name string. When\n * using a string, the merged state (from partial states registered via\n * `.with()`) is resolved by name.\n *\n * @template SX - State schema type\n * @template EX - Event schemas type\n * @template AX - Action schemas type\n * @param state - The state definition or state name to load\n * @param stream - The stream ID (state instance identifier)\n * @param callback - Optional callback invoked with the loaded snapshot\n * @returns The current state snapshot for the stream\n *\n * @example Load by state definition\n * ```typescript\n * const snapshot = await app.load(Counter, \"counter-1\");\n * console.log(snapshot.state.count); // Current count\n * console.log(snapshot.patches); // Events since last snapshot\n * ```\n *\n * @example Load by state name (useful with partial states)\n * ```typescript\n * const snapshot = await app.load(\"Ticket\", \"ticket-123\");\n * console.log(snapshot.state.title); // Merged state from all partials\n * ```\n *\n * @example Load multiple states\n * ```typescript\n * const [user, account] = await Promise.all([\n * app.load(User, \"user-123\"),\n * app.load(BankAccount, \"account-456\")\n * ]);\n * ```\n *\n * @see {@link Snapshot} for snapshot structure\n */\n async load<SX extends Schema, EX extends Schemas, AX extends Schemas>(\n state: State<SX, EX, AX>,\n stream: string,\n callback?: (snapshot: Snapshot<SX, EX>) => void\n ): Promise<Snapshot<SX, EX>>;\n async load<K extends keyof M & string>(\n name: K,\n stream: string,\n callback?: (snapshot: Snapshot<M[K], E>) => void\n ): Promise<Snapshot<M[K], E>>;\n async load<SX extends Schema>(\n stateOrName: State<SX, any, any> | string,\n stream: string,\n callback?: (snapshot: Snapshot<any, any>) => void\n ): Promise<Snapshot<any, any>> {\n let merged: State<any, any, any>;\n if (typeof stateOrName === \"string\") {\n const found = this._states.get(stateOrName);\n if (!found) throw new Error(`State \"${stateOrName}\" not found`);\n merged = found;\n } else {\n merged = this._states.get(stateOrName.name) || stateOrName;\n }\n return await es.load(merged, stream, callback);\n }\n\n /**\n * Queries the event store for events matching a filter.\n *\n * Use this for analyzing event streams, generating reports, or debugging.\n * The callback is invoked for each matching event, and the method returns\n * summary information (first event, last event, total count).\n *\n * For small result sets, consider using {@link query_array} instead.\n *\n * @param query - The query filter\n * @param query.stream - Filter by stream ID\n * @param query.name - Filter by event name\n * @param query.after - Filter events after this event ID\n * @param query.before - Filter events before this event ID\n * @param query.created_after - Filter events after this timestamp\n * @param query.created_before - Filter events before this timestamp\n * @param query.limit - Maximum number of events to return\n * @param callback - Optional callback invoked for each matching event\n * @returns Object with first event, last event, and total count\n *\n * @example Query all events for a stream\n * ```typescript\n * const { first, last, count } = await app.query(\n * { stream: \"counter-1\" },\n * (event) => console.log(event.name, event.data)\n * );\n * console.log(`Found ${count} events from ${first?.id} to ${last?.id}`);\n * ```\n *\n * @example Query specific event types\n * ```typescript\n * const { count } = await app.query(\n * { name: \"UserCreated\", limit: 100 },\n * (event) => {\n * console.log(\"User created:\", event.data.email);\n * }\n * );\n * ```\n *\n * @example Query events in time range\n * ```typescript\n * const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000);\n * const { count } = await app.query({\n * created_after: yesterday,\n * stream: \"user-123\"\n * });\n * console.log(`User had ${count} events in last 24 hours`);\n * ```\n *\n * @see {@link query_array} for loading events into memory\n */\n async query(\n query: Query,\n callback?: (event: Committed<E, keyof E>) => void\n ): Promise<{\n first?: Committed<E, keyof E>;\n last?: Committed<E, keyof E>;\n count: number;\n }> {\n let first: Committed<E, keyof E> | undefined = undefined,\n last: Committed<E, keyof E> | undefined = undefined;\n const count = await store().query<E>((e) => {\n !first && (first = e);\n last = e;\n callback && callback(e);\n }, query);\n return { first, last, count };\n }\n\n /**\n * Queries the event store and returns all matching events in memory.\n *\n * **Use with caution** - this loads all results into memory. For large result sets,\n * use {@link query} with a callback instead to process events incrementally.\n *\n * @param query - The query filter (same as {@link query})\n * @returns Array of all matching events\n *\n * @example Load all events for a stream\n * ```typescript\n * const events = await app.query_array({ stream: \"counter-1\" });\n * console.log(`Loaded ${events.length} events`);\n * events.forEach(event => console.log(event.name, event.data));\n * ```\n *\n * @example Get recent events\n * ```typescript\n * const recent = await app.query_array({\n * stream: \"user-123\",\n * limit: 10\n * });\n * ```\n *\n * @see {@link query} for large result sets\n */\n async query_array(query: Query): Promise<Committed<E, keyof E>[]> {\n const events: Committed<E, keyof E>[] = [];\n await store().query<E>((e) => events.push(e), query);\n return events;\n }\n\n /**\n * Handles leased reactions.\n *\n * This is called by the main `drain` loop after fetching new events.\n * It handles reactions, supporting retries, blocking, and error handling.\n *\n * @internal\n * @param lease The lease to handle\n * @param payloads The reactions to handle\n * @returns The lease with results\n */\n private async handle(\n lease: Lease,\n payloads: ReactionPayload<E>[]\n ): Promise<{\n readonly lease: Lease;\n readonly handled: number;\n readonly at: number;\n readonly error?: string;\n readonly block?: boolean;\n }> {\n // no payloads, just advance the lease\n if (payloads.length === 0) return { lease, handled: 0, at: lease.at };\n\n const stream = lease.stream;\n let at = payloads.at(0)!.event.id,\n handled = 0;\n\n lease.retry > 0 &&\n logger.warn(`Retrying ${stream}@${at} (${lease.retry}).`);\n\n for (const payload of payloads) {\n const { event, handler, options } = payload;\n try {\n await handler(event, stream, this); // the actual reaction\n at = event.id;\n handled++;\n } catch (error) {\n logger.error(error);\n const block = lease.retry >= options.maxRetries && options.blockOnError;\n block &&\n logger.error(`Blocking ${stream} after ${lease.retry} retries.`);\n return {\n lease,\n handled,\n at,\n // only report error when nothing was handled\n error: handled === 0 ? (error as Error).message : undefined,\n block,\n };\n }\n }\n return { lease, handled, at };\n }\n\n /**\n * Processes pending reactions by draining uncommitted events from the event store.\n *\n * The drain process:\n * 1. Polls the store for streams with uncommitted events\n * 2. Leases streams to prevent concurrent processing\n * 3. Fetches events for each leased stream\n * 4. Executes matching reaction handlers\n * 5. Acknowledges successful reactions or blocks failing ones\n *\n * Drain uses a dual-frontier strategy to balance processing of new streams (lagging)\n * vs active streams (leading). The ratio adapts based on event pressure.\n *\n * Call this method periodically in a background loop, or after committing events.\n *\n * @param options - Drain configuration options\n * @param options.streamLimit - Maximum number of streams to process per cycle (default: 10)\n * @param options.eventLimit - Maximum events to fetch per stream (default: 10)\n * @param options.leaseMillis - Lease duration in milliseconds (default: 10000)\n * @returns Drain statistics with fetched, leased, acked, and blocked counts\n *\n * @example Basic drain loop\n * ```typescript\n * // Process reactions after each action\n * await app.do(\"createUser\", target, payload);\n * await app.drain();\n * ```\n *\n * @example Background drain worker\n * ```typescript\n * setInterval(async () => {\n * try {\n * const result = await app.drain({\n * streamLimit: 20,\n * eventLimit: 50\n * });\n * if (result.acked.length) {\n * console.log(`Processed ${result.acked.length} streams`);\n * }\n * } catch (error) {\n * console.error(\"Drain error:\", error);\n * }\n * }, 5000); // Every 5 seconds\n * ```\n *\n * @example With lifecycle listeners\n * ```typescript\n * app.on(\"acked\", (leases) => {\n * console.log(`Acknowledged ${leases.length} streams`);\n * });\n *\n * app.on(\"blocked\", (blocked) => {\n * console.error(`Blocked ${blocked.length} streams due to errors`);\n * blocked.forEach(({ stream, error }) => {\n * console.error(`Stream ${stream}: ${error}`);\n * });\n * });\n *\n * await app.drain();\n * ```\n *\n * @see {@link correlate} for dynamic stream discovery\n * @see {@link start_correlations} for automatic correlation\n */\n async drain({\n streamLimit = 10,\n eventLimit = 10,\n leaseMillis = 10_000,\n }: DrainOptions = {}): Promise<Drain<E>> {\n if (!this._drain_locked) {\n try {\n this._drain_locked = true;\n const lagging = Math.ceil(streamLimit * this._drain_lag2lead_ratio);\n const leading = streamLimit - lagging;\n const polled = await store().poll(lagging, leading);\n const fetched = await Promise.all(\n polled.map(async ({ stream, source, at, lagging }) => {\n const events = await this.query_array({\n stream: source,\n after: at,\n limit: eventLimit,\n });\n return { stream, source, at, lagging, events } as const;\n })\n );\n if (fetched.length) {\n tracer.fetched(fetched);\n\n const leases = new Map<\n string,\n { lease: Lease; payloads: ReactionPayload<E>[] }\n >();\n\n // compute fetch window max event id\n const fetch_window_at = fetched.reduce(\n (max, { at, events }) => Math.max(max, events.at(-1)?.id || at),\n 0\n );\n\n fetched.forEach(({ stream, lagging, events }) => {\n const payloads = events.flatMap((event) => {\n const register = this.registry.events[event.name];\n if (!register) return [];\n return [...register.reactions.values()]\n .filter((reaction) => {\n const resolved =\n typeof reaction.resolver === \"function\"\n ? reaction.resolver(event)\n : reaction.resolver;\n return resolved && resolved.target === stream;\n })\n .map((reaction) => ({ ...reaction, event }));\n });\n leases.set(stream, {\n lease: {\n stream,\n by: randomUUID(),\n at: events.at(-1)?.id || fetch_window_at, // ff when no matching events\n retry: 0,\n lagging,\n },\n payloads: payloads as ReactionPayload<E>[],\n });\n });\n\n const leased = await store().lease(\n [...leases.values()].map(({ lease }) => lease),\n leaseMillis\n );\n tracer.leased(leased);\n\n const handled = await Promise.all(\n leased.map((lease) =>\n this.handle(lease, leases.get(lease.stream)!.payloads)\n )\n );\n\n // adaptive drain ratio based on handled events, favors frontier with highest pressure (clamped between 20% and 80%)\n const [lagging_handled, leading_handled] = handled.reduce(\n ([lagging_handled, leading_handled], { lease, handled }) => [\n lagging_handled + (lease.lagging ? handled : 0),\n leading_handled + (lease.lagging ? 0 : handled),\n ],\n [0, 0]\n );\n const lagging_avg = lagging > 0 ? lagging_handled / lagging : 0;\n const leading_avg = leading > 0 ? leading_handled / leading : 0;\n const total = lagging_avg + leading_avg;\n this._drain_lag2lead_ratio =\n total > 0 ? Math.max(0.2, Math.min(0.8, lagging_avg / total)) : 0.5;\n\n const acked = await store().ack(\n handled\n .filter(({ error }) => !error)\n .map(({ at, lease }) => ({ ...lease, at }))\n );\n if (acked.length) {\n tracer.acked(acked);\n this.emit(\"acked\", acked);\n }\n\n const blocked = await store().block(\n handled\n .filter(({ block }) => block)\n .map(({ lease, error }) => ({ ...lease, error: error! }))\n );\n if (blocked.length) {\n tracer.blocked(blocked);\n this.emit(\"blocked\", blocked);\n }\n\n return { fetched, leased, acked, blocked };\n }\n } catch (error) {\n logger.error(error);\n } finally {\n this._drain_locked = false;\n }\n }\n\n return { fetched: [], leased: [], acked: [], blocked: [] };\n }\n\n /**\n * Discovers and registers new streams dynamically based on reaction resolvers.\n *\n * Correlation enables \"dynamic reactions\" where target streams are determined at runtime\n * based on event content. For example, you might create a stats stream for each user\n * when they perform certain actions.\n *\n * This method scans events matching the query and identifies new target streams based\n * on reaction resolvers. It then registers these streams so they'll be picked up by\n * the next drain cycle.\n *\n * @param query - Query filter to scan for new correlations\n * @param query.after - Start scanning after this event ID (default: -1)\n * @param query.limit - Maximum events to scan (default: 10)\n * @returns Object with newly leased streams and last scanned event ID\n *\n * @example Manual correlation\n * ```typescript\n * // Scan for new streams\n * const { leased, last_id } = await app.correlate({ after: 0, limit: 100 });\n * console.log(`Found ${leased.length} new streams`);\n *\n * // Save last_id for next scan\n * await saveCheckpoint(last_id);\n * ```\n *\n * @example Dynamic stream creation\n * ```typescript\n * const app = act()\n * .with(User)\n * .with(UserStats)\n * .on(\"UserLoggedIn\")\n * .do(async (event) => [\"incrementLoginCount\", {}])\n * .to((event) => ({\n * target: `stats-${event.stream}` // Dynamic target per user\n * }))\n * .build();\n *\n * // Discover stats streams as users log in\n * await app.correlate();\n * ```\n *\n * @see {@link start_correlations} for automatic periodic correlation\n * @see {@link stop_correlations} to stop automatic correlation\n */\n async correlate(\n query: Query = { after: -1, limit: 10 }\n ): Promise<{ leased: Lease[]; last_id: number }> {\n const correlated = new Map<string, ReactionPayload<E>[]>();\n let last_id = query.after || -1;\n await store().query<E>((event) => {\n last_id = event.id;\n const register = this.registry.events[event.name];\n // skip events with no registered reactions\n if (register) {\n for (const reaction of register.reactions.values()) {\n const resolved =\n typeof reaction.resolver === \"function\"\n ? reaction.resolver(event)\n : reaction.resolver;\n resolved &&\n (\n correlated.get(resolved.target) ||\n correlated.set(resolved.target, []).get(resolved.target)!\n ).push({ ...reaction, source: resolved.source, event });\n }\n }\n }, query);\n if (correlated.size) {\n const leases = [...correlated.entries()].map(([stream, payloads]) => ({\n stream,\n // TODO: by convention, the first defined source wins (this can be tricky)\n source: payloads.find((p) => p.source)?.source || undefined,\n by: randomUUID(),\n at: 0,\n retry: 0,\n lagging: true,\n payloads,\n }));\n // register leases with 0ms lease timeout (just to tag the new streams)\n const leased = await store().lease(leases, 0);\n leased.length && tracer.correlated(leased);\n return { leased, last_id };\n }\n return { leased: [], last_id };\n }\n\n /**\n * Starts automatic periodic correlation worker for discovering new streams.\n *\n * The correlation worker runs in the background, scanning for new events and identifying\n * new target streams based on reaction resolvers. It maintains a sliding window that\n * advances with each scan, ensuring all events are eventually correlated.\n *\n * This is useful for dynamic stream creation patterns where you don't know all streams\n * upfront - they're discovered as events arrive.\n *\n * **Note:** Only one correlation worker can run at a time per Act instance.\n *\n * @param query - Query filter for correlation scans\n * @param query.after - Initial starting point (default: -1, start from beginning)\n * @param query.limit - Events to scan per cycle (default: 100)\n * @param frequency - Correlation frequency in milliseconds (default: 10000)\n * @param callback - Optional callback invoked with newly discovered streams\n * @returns `true` if worker started, `false` if already running\n *\n * @example Start automatic correlation\n * ```typescript\n * // Start correlation worker scanning every 5 seconds\n * app.start_correlations(\n * { after: 0, limit: 100 },\n * 5000,\n * (leased) => {\n * console.log(`Discovered ${leased.length} new streams`);\n * }\n * );\n *\n * // Later, stop it\n * app.stop_correlations();\n * ```\n *\n * @example With checkpoint persistence\n * ```typescript\n * // Load last checkpoint\n * const lastId = await loadCheckpoint();\n *\n * app.start_correlations(\n * { after: lastId, limit: 100 },\n * 10000,\n * async (leased) => {\n * // Save checkpoint for next restart\n * if (leased.length) {\n * const maxId = Math.max(...leased.map(l => l.at));\n * await saveCheckpoint(maxId);\n * }\n * }\n * );\n * ```\n *\n * @see {@link correlate} for manual one-time correlation\n * @see {@link stop_correlations} to stop the worker\n */\n start_correlations(\n query: Query = {},\n frequency = 10_000,\n callback?: (leased: Lease[]) => void\n ): boolean {\n if (this._correlation_interval) return false;\n\n const limit = query.limit || 100;\n let after = query.after || -1;\n this._correlation_interval = setInterval(\n () =>\n this.correlate({ ...query, after, limit })\n .then((result) => {\n after = result.last_id;\n if (callback && result.leased.length) callback(result.leased);\n })\n .catch(console.error),\n frequency\n );\n return true;\n }\n\n /**\n * Stops the automatic correlation worker.\n *\n * Call this to stop the background correlation worker started by {@link start_correlations}.\n * This is automatically called when the Act instance is disposed.\n *\n * @example\n * ```typescript\n * // Start correlation\n * app.start_correlations();\n *\n * // Later, stop it\n * app.stop_correlations();\n * ```\n *\n * @see {@link start_correlations}\n */\n stop_correlations() {\n if (this._correlation_interval) {\n clearInterval(this._correlation_interval);\n this._correlation_interval = undefined;\n }\n }\n}\n","/**\n * @module event-sourcing\n * @category Event Sourcing\n *\n * Utilities for event sourcing, snapshotting, and event store interaction.\n */\n\nimport { randomUUID } from \"crypto\";\nimport { logger, SNAP_EVENT, store } from \"./ports.js\";\nimport { InvariantError } from \"./types/errors.js\";\nimport type {\n Committed,\n Emitted,\n EventMeta,\n Schema,\n Schemas,\n Snapshot,\n State,\n Target,\n} from \"./types/index.js\";\nimport { patch, validate } from \"./utils.js\";\n\n/**\n * Event sourcing utilities for snapshotting, loading, and committing actions/events.\n * Used internally by Act and state machines.\n */\n\n/**\n * Saves a snapshot of the state to the store.\n *\n * Snapshots are used to optimize state reconstruction for aggregates with long event streams.\n *\n * @template S The type of state\n * @template E The type of events\n * @param snapshot The snapshot to save\n * @returns Promise that resolves when the snapshot is saved\n *\n * @example\n * await snap(snapshot);\n */\nexport async function snap<S extends Schema, E extends Schemas>(\n snapshot: Snapshot<S, E>\n): Promise<void> {\n try {\n const { id, stream, name, meta, version } = snapshot.event!;\n const snapped = await store().commit(\n stream,\n [{ name: SNAP_EVENT, data: snapshot.state }],\n {\n correlation: meta.correlation,\n causation: { event: { id, name: name as string, stream } },\n },\n version // IMPORTANT! - state events are committed right after the snapshot event\n );\n logger.trace(snapped, \"🟠 snap\");\n } catch (error) {\n logger.error(error);\n }\n}\n\n/**\n * Loads a snapshot of the state from the store by replaying events and applying patches.\n *\n * @template S The type of state\n * @template E The type of events\n * @template A The type of actions\n * @param me The state machine definition\n * @param stream The stream (instance) to load\n * @param callback (Optional) Callback to receive the loaded snapshot as it is built\n * @returns The snapshot of the loaded state\n *\n * @example\n * const snapshot = await load(Counter, \"counter1\");\n */\nexport async function load<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n>(\n me: State<S, E, A>,\n stream: string,\n callback?: (snapshot: Snapshot<S, E>) => void\n): Promise<Snapshot<S, E>> {\n let state = me.init ? me.init() : ({} as S);\n let patches = 0;\n let snaps = 0;\n let event: Committed<E, string> | undefined;\n await store().query(\n (e) => {\n event = e as Committed<E, string>;\n if (e.name === SNAP_EVENT) {\n state = e.data as S;\n snaps++;\n patches = 0;\n } else if (me.patch[e.name]) {\n state = patch(state, me.patch[e.name](event, state));\n patches++;\n }\n callback && callback({ event, state, patches, snaps });\n },\n { stream, with_snaps: true }\n );\n logger.trace(state as object, `🟢 load ${stream}`);\n return { event, state, patches, snaps };\n}\n\n/**\n * Executes an action and emits an event to be committed by the store.\n *\n * This function validates the action, applies business invariants, emits events, and commits them to the event store.\n *\n * @template S The type of state\n * @template E The type of events\n * @template A The type of actionSchemas\n * @template K The type of action to execute\n * @param me The state machine definition\n * @param action The action to execute\n * @param target The target (stream, actor, etc.)\n * @param payload The payload of the action\n * @param reactingTo (Optional) The event that the action is reacting to\n * @param skipValidation (Optional) Whether to skip validation (not recommended)\n * @returns The snapshot of the committed event\n *\n * @example\n * const snapshot = await action(Counter, \"increment\", { stream: \"counter1\", actor }, { by: 1 });\n */\nexport async function action<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n K extends keyof A,\n>(\n me: State<S, E, A>,\n action: K,\n target: Target,\n payload: Readonly<A[K]>,\n reactingTo?: Committed<Schemas, keyof Schemas>,\n skipValidation = false\n): Promise<Snapshot<S, E>[]> {\n const { stream, expectedVersion, actor } = target;\n if (!stream) throw new Error(\"Missing target stream\");\n\n payload = skipValidation\n ? payload\n : validate(action as string, payload, me.actions[action]);\n\n const snapshot = await load(me, stream);\n const expected = expectedVersion || snapshot.event?.version;\n\n logger.trace(\n payload as object,\n `🔵 ${stream}.${action as string}${typeof expected === \"number\" ? `.${expected}` : \"\"}`\n );\n\n if (me.given) {\n const invariants = me.given[action] || [];\n invariants.forEach(({ valid, description }) => {\n if (!valid(snapshot.state, actor))\n throw new InvariantError(\n action,\n payload,\n target,\n snapshot,\n description\n );\n });\n }\n\n const result = me.on[action](payload, snapshot, target);\n if (!result) return [snapshot];\n\n // An empty array means no events were emitted\n if (Array.isArray(result) && result.length === 0) {\n return [snapshot];\n }\n\n const tuples = Array.isArray(result[0])\n ? (result as Emitted<E>[]) // array of tuples\n : ([result] as Emitted<E>[]); // single tuple\n\n const emitted = tuples.map(([name, data]) => ({\n name,\n data: skipValidation\n ? data\n : validate(name as string, data, me.events[name]),\n }));\n\n const meta: EventMeta = {\n correlation: reactingTo?.meta.correlation || randomUUID(),\n causation: {\n action: {\n name: action as string,\n ...target,\n // payload: TODO: flag to include action payload in metadata\n // not included by default to avoid large payloads\n },\n event: reactingTo\n ? {\n id: reactingTo.id,\n name: reactingTo.name,\n stream: reactingTo.stream,\n }\n : undefined,\n },\n };\n\n logger.trace(\n emitted.map((e) => e.data),\n `🔴 commit ${stream}.${emitted.map((e) => e.name).join(\", \")}`\n );\n\n const committed = await store().commit(\n stream,\n emitted,\n meta,\n // TODO: review reactions not enforcing expected version\n reactingTo ? undefined : expected\n );\n\n let { state, patches } = snapshot;\n const snapshots = committed.map((event) => {\n state = patch(state, me.patch[event.name](event, state));\n patches++;\n return { event, state, patches, snaps: snapshot.snaps };\n });\n\n // fire and forget snaps\n const last = snapshots.at(-1)!;\n me.snap && me.snap(last) && void snap(last);\n\n return snapshots;\n}\n","/**\n * @module merge\n * @category Builders\n *\n * Shared utilities for merging partial states and projections across builders.\n */\nimport { ZodObject, type ZodType } from \"zod\";\nimport type { Projection } from \"./projection-builder.js\";\nimport type { Schema, State } from \"./types/index.js\";\n\n/**\n * Unwraps wrapper types (ZodOptional, ZodNullable, ZodDefault, ZodReadonly)\n * to find the base type name, e.g. `z.string().optional()` -> `\"ZodString\"`.\n */\nexport function baseTypeName(zodType: ZodType): string {\n let t: any = zodType;\n while (typeof t.unwrap === \"function\") {\n t = t.unwrap();\n }\n return t.constructor.name;\n}\n\n/**\n * Merges two Zod schemas. If both are ZodObject instances, checks for\n * overlapping shape keys with incompatible base types (throws descriptive\n * error), then merges via `.extend()`. Falls back to keeping existing\n * schema if either is not a ZodObject.\n */\nexport function mergeSchemas(\n existing: ZodType,\n incoming: ZodType,\n stateName: string\n): ZodType {\n if (existing instanceof ZodObject && incoming instanceof ZodObject) {\n const existingShape = existing.shape as Record<string, ZodType>;\n const incomingShape = incoming.shape as Record<string, ZodType>;\n for (const key of Object.keys(incomingShape)) {\n if (key in existingShape) {\n const existingBase = baseTypeName(existingShape[key]);\n const incomingBase = baseTypeName(incomingShape[key]);\n if (existingBase !== incomingBase) {\n throw new Error(\n `Schema conflict in \"${stateName}\": key \"${key}\" has type \"${existingBase}\" but incoming partial declares \"${incomingBase}\"`\n );\n }\n }\n }\n return existing.extend(incomingShape);\n }\n return existing;\n}\n\n/**\n * Merges two init functions by spreading both results together.\n * Each partial only provides its own defaults.\n */\nexport function mergeInits<S extends Schema>(\n existing: () => Readonly<S>,\n incoming: () => Readonly<S>\n): () => Readonly<S> {\n return () => ({ ...existing(), ...incoming() });\n}\n\n/**\n * Registers a state into a states map and action/event registries,\n * merging with existing same-name states (partial state support).\n */\nexport function registerState(\n state: State<any, any, any>,\n states: Map<string, State<any, any, any>>,\n actions: Record<string, any>,\n events: Record<string, any>\n): void {\n if (states.has(state.name)) {\n // MERGE: same state name - combine events, actions, patches, handlers\n const existing = states.get(state.name)!;\n for (const name of Object.keys(state.actions)) {\n // Same schema reference means the same partial re-registered via another slice\n if (existing.actions[name] === state.actions[name]) continue;\n if (actions[name]) throw new Error(`Duplicate action \"${name}\"`);\n }\n for (const name of Object.keys(state.events)) {\n // Same schema reference means the same partial re-registered via another slice\n if (existing.events[name] === state.events[name]) continue;\n if (events[name]) throw new Error(`Duplicate event \"${name}\"`);\n }\n const merged = {\n ...existing,\n state: mergeSchemas(existing.state, state.state, state.name),\n init: mergeInits(existing.init, state.init),\n events: { ...existing.events, ...state.events },\n actions: { ...existing.actions, ...state.actions },\n patch: { ...existing.patch, ...state.patch },\n on: { ...existing.on, ...state.on },\n given: { ...existing.given, ...state.given },\n snap: state.snap || existing.snap,\n };\n states.set(state.name, merged);\n // Update ALL action->state pointers to the merged object\n for (const name of Object.keys(merged.actions)) {\n actions[name] = merged;\n }\n for (const name of Object.keys(state.events)) {\n if (events[name]) continue; // already registered, preserve reactions\n events[name] = {\n schema: state.events[name],\n reactions: new Map(),\n };\n }\n } else {\n // NEW: register state for the first time\n states.set(state.name, state);\n for (const name of Object.keys(state.actions)) {\n if (actions[name]) throw new Error(`Duplicate action \"${name}\"`);\n actions[name] = state;\n }\n for (const name of Object.keys(state.events)) {\n if (events[name]) throw new Error(`Duplicate event \"${name}\"`);\n events[name] = {\n schema: state.events[name],\n reactions: new Map(),\n };\n }\n }\n}\n\n/**\n * Merges a projection's event schemas and reactions into an event registry,\n * deduplicating reaction names by appending \"_p\" on collision.\n */\nexport function mergeProjection(\n proj: Projection<any>,\n events: Record<string, any>\n): void {\n for (const eventName of Object.keys(proj.events)) {\n const projRegister = proj.events[eventName];\n const existing = events[eventName];\n if (!existing) {\n events[eventName] = {\n schema: projRegister.schema,\n reactions: new Map(projRegister.reactions),\n };\n } else {\n for (const [name, reaction] of projRegister.reactions) {\n let key = name;\n while (existing.reactions.has(key)) key = `${key}_p`;\n existing.reactions.set(key, reaction);\n }\n }\n }\n}\n\n// Resolves the event stream as source and target (default)\nexport const _this_ = ({ stream }: { stream: string }) => ({\n source: stream,\n target: stream,\n});\n\n// Resolves to nothing\nexport const _void_ = () => undefined;\n","/**\n * @module projection-builder\n * @category Builders\n *\n * Fluent builder for composing projection handlers — read-model updaters\n * that react to events and update external state (databases, caches, etc.).\n *\n * Projections differ from slices: they don't contain states, don't dispatch\n * actions, and are pure side-effect handlers routed to a named stream.\n */\nimport type { ZodType } from \"zod\";\nimport { _this_, _void_ } from \"./merge.js\";\nimport type {\n Committed,\n EventRegister,\n Reaction,\n ReactionHandler,\n ReactionResolver,\n Schema,\n Schemas,\n} from \"./types/index.js\";\n\n/**\n * A self-contained projection grouping read-model update handlers.\n * Projections are composed into an Act orchestrator via `act().with(projection)`.\n *\n * @template E - Event schemas handled by this projection\n */\nexport type Projection<E extends Schemas> = {\n readonly _tag: \"Projection\";\n readonly events: EventRegister<E>;\n};\n\n/**\n * Type guard for distinguishing Projection from State and Slice objects.\n */\nexport function isProjection(x: any): x is Projection<any> {\n return x != null && x._tag === \"Projection\";\n}\n\n/** Helper: a single-key record mapping an event name to its Zod schema. */\ntype EventEntry<K extends string = string, D extends Schema = Schema> = {\n [P in K]: ZodType<D>;\n};\n\n/** Infer the handler-result type after registering one event. */\ntype DoResult<\n E extends Schemas,\n K extends string,\n D extends Schema,\n> = ProjectionBuilder<E & { [P in K]: D }> & {\n to: (\n resolver: ReactionResolver<E & { [P in K]: D }, K> | string\n ) => ProjectionBuilder<E & { [P in K]: D }>;\n void: () => ProjectionBuilder<E & { [P in K]: D }>;\n};\n\n/**\n * Fluent builder interface for composing projections.\n *\n * Provides a chainable API for registering event handlers that update\n * read models. Unlike slices, projections have no `.with()` for states\n * and handlers do not receive a `Dispatcher`.\n *\n * When a default target is provided via `projection(\"target\")`, all\n * handlers inherit that resolver. Per-handler `.to()` or `.void()` can\n * still override it.\n *\n * @template E - Event schemas\n */\nexport type ProjectionBuilder<E extends Schemas> = {\n /**\n * Begins defining a projection handler for a specific event.\n *\n * Pass a `{ EventName: schema }` record — use shorthand `{ EventName }`\n * when the variable name matches the event name. The key becomes the\n * event name, the value the Zod schema.\n */\n on: <K extends string, D extends Schema>(\n entry: EventEntry<K, D>\n ) => {\n do: (\n handler: (\n event: Committed<E & { [P in K]: D }, K>,\n stream: string\n ) => Promise<void>\n ) => DoResult<E, K, D>;\n };\n /**\n * Builds and returns the Projection data structure.\n */\n build: () => Projection<E>;\n /**\n * The registered event schemas and their reaction maps.\n */\n readonly events: EventRegister<E>;\n};\n\n/* eslint-disable @typescript-eslint/no-empty-object-type -- {} used as generic defaults */\n\n/**\n * Creates a new projection builder for composing read-model update handlers.\n *\n * Projections enable separation of read-model concerns from command handling.\n * Each `.on({ Event }).do(handler)` call registers a handler that updates\n * a projection (database table, cache, etc.) in response to events.\n *\n * Pass a target stream name to `projection(\"target\")` so every handler\n * inherits that resolver automatically. Omit it and use per-handler\n * `.to()` / `.void()` when handlers route to different streams.\n *\n * @param target - Optional default target stream for all handlers\n *\n * @example Default target (all handlers routed to \"tickets\")\n * ```typescript\n * const TicketProjection = projection(\"tickets\")\n * .on({ TicketOpened })\n * .do(async ({ stream, data }) => {\n * await db.insert(tickets).values({ id: stream, ...data });\n * })\n * .on({ TicketClosed })\n * .do(async ({ stream, data }) => {\n * await db.update(tickets).set(data).where(eq(tickets.id, stream));\n * })\n * .build();\n * ```\n *\n * @example Per-handler routing\n * ```typescript\n * const MultiProjection = projection()\n * .on({ OrderPlaced })\n * .do(async (event) => { ... })\n * .to(\"orders\")\n * .on({ PaymentReceived })\n * .do(async (event) => { ... })\n * .to(\"payments\")\n * .build();\n * ```\n *\n * @see {@link ProjectionBuilder} for builder methods\n * @see {@link Projection} for the output type\n */\nexport function projection<E extends Schemas = {}>(\n target?: string,\n events: EventRegister<E> = {} as EventRegister<E>\n): ProjectionBuilder<E> {\n const defaultResolver: { target: string } | undefined = target\n ? { target }\n : undefined;\n\n const builder: ProjectionBuilder<E> = {\n on: <K extends string, D extends Schema>(entry: EventEntry<K, D>) => {\n const keys = Object.keys(entry);\n if (keys.length !== 1) throw new Error(\".on() requires exactly one key\");\n const event = keys[0] as K;\n const schema = entry[event];\n\n // Register the event schema if not already present\n if (!(event in events)) {\n (events as Record<string, unknown>)[event] = {\n schema,\n reactions: new Map(),\n };\n }\n\n return {\n do: (\n handler: (\n event: Committed<E & { [P in K]: D }, K>,\n stream: string\n ) => Promise<void>\n ) => {\n const reaction: Reaction<E & { [P in K]: D }, K> = {\n handler: handler as ReactionHandler<E & { [P in K]: D }, K>,\n resolver: defaultResolver ?? _this_,\n options: {\n blockOnError: true,\n maxRetries: 3,\n },\n };\n const register = (events as Record<string, any>)[event];\n const name = handler.name || `${event}_${register.reactions.size}`;\n register.reactions.set(name, reaction);\n\n const nextBuilder = projection<E & { [P in K]: D }>(\n target,\n events as EventRegister<E & { [P in K]: D }>\n );\n return {\n ...nextBuilder,\n to(resolver: ReactionResolver<E & { [P in K]: D }, K> | string) {\n register.reactions.set(name, {\n ...reaction,\n resolver:\n typeof resolver === \"string\"\n ? { target: resolver }\n : resolver,\n });\n return nextBuilder;\n },\n void() {\n register.reactions.set(name, {\n ...reaction,\n resolver: _void_,\n });\n return nextBuilder;\n },\n };\n },\n };\n },\n build: () => ({\n _tag: \"Projection\" as const,\n events,\n }),\n events,\n };\n return builder;\n}\n","/**\n * @module slice-builder\n * @category Builders\n *\n * Fluent builder for composing partial states with scoped reactions into\n * self-contained functional slices (vertical slice architecture).\n */\nimport { _this_, _void_, registerState } from \"./merge.js\";\nimport type { Projection } from \"./projection-builder.js\";\nimport type {\n Committed,\n Dispatcher,\n EventRegister,\n Reaction,\n ReactionHandler,\n ReactionOptions,\n ReactionResolver,\n Schema,\n SchemaRegister,\n Schemas,\n Snapshot,\n State,\n} from \"./types/index.js\";\n\n/**\n * A self-contained functional slice grouping partial states with their\n * scoped reactions. Slices are composed into an Act orchestrator via\n * `act().with(slice)`.\n *\n * @template S - Schema register for states\n * @template E - Event schemas from this slice's states\n * @template A - Action schemas from this slice's states\n * @template M - Map of state names to state schemas\n */\nexport type Slice<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n M extends Record<string, Schema> = {},\n> = {\n readonly _tag: \"Slice\";\n readonly states: Map<string, State<any, any, any>>;\n readonly events: EventRegister<E>;\n readonly projections: ReadonlyArray<Projection<any>>;\n /** @internal phantom field for type-level state schema tracking */\n readonly _S?: S;\n /** @internal phantom field for type-level state name tracking */\n readonly _M?: M;\n};\n\n/**\n * Type guard for distinguishing Slice from State objects.\n */\nexport function isSlice(x: any): x is Slice<any, any, any, any> {\n return x != null && x._tag === \"Slice\";\n}\n\n/**\n * Fluent builder interface for composing functional slices.\n *\n * Provides a chainable API for registering states and defining reactions,\n * scoped to the slice's own events. Include all states whose actions your\n * handlers need via `.with()` — the `app` parameter in `.do()` handlers\n * is typed with every action registered in the slice.\n *\n * @template S - Schema register for states\n * @template E - Event schemas\n * @template A - Action schemas\n * @template M - Map of state names to state schemas\n */\nexport type SliceBuilder<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n M extends Record<string, Schema> = {},\n> = {\n /**\n * Registers a partial state definition with the slice.\n *\n * Include every state whose actions your reaction handlers need to\n * dispatch. Duplicate registrations (same state in multiple slices)\n * are handled automatically at composition time.\n */\n with: <\n SX extends Schema,\n EX extends Schemas,\n AX extends Schemas,\n NX extends string = string,\n >(\n state: State<SX, EX, AX, NX>\n ) => SliceBuilder<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX,\n M & { [K in NX]: SX }\n >;\n /**\n * Embeds a built Projection within this slice for encapsulated\n * feature composition. The projection's events must be a subset\n * of events from states already registered via `.with()`.\n * Projection handlers preserve their `(event, stream)` signature\n * and do not receive a Dispatcher.\n */\n projection: <EP extends Schemas>(\n proj: [Exclude<keyof EP, keyof E>] extends [never] ? Projection<EP> : never\n ) => SliceBuilder<S, E, A, M>;\n /**\n * Begins defining a reaction scoped to this slice's events.\n */\n on: <K extends keyof E>(\n event: K\n ) => {\n do: (\n handler: (\n event: Committed<E, K>,\n stream: string,\n app: Dispatcher<A>\n ) => Promise<Snapshot<Schema, E> | void>,\n options?: Partial<ReactionOptions>\n ) => SliceBuilder<S, E, A, M> & {\n to: (\n resolver: ReactionResolver<E, K> | string\n ) => SliceBuilder<S, E, A, M>;\n void: () => SliceBuilder<S, E, A, M>;\n };\n };\n /**\n * Builds and returns the Slice data structure.\n */\n build: () => Slice<S, E, A, M>;\n /**\n * The registered event schemas and their reaction maps.\n */\n readonly events: EventRegister<E>;\n};\n\n/* eslint-disable @typescript-eslint/no-empty-object-type -- {} used as generic defaults */\n\n/**\n * Creates a new slice builder for composing partial states with scoped reactions.\n *\n * Slices enable vertical slice architecture by grouping related states and\n * reactions into self-contained feature modules. Reactions defined in a slice\n * are type-scoped to events from that slice's states only.\n *\n * Include all states whose actions your handlers dispatch via `.with()`.\n * When multiple slices share the same state, duplicates are merged\n * automatically at `act().with(slice)` composition time.\n *\n * @example Single-state slice with typed dispatch\n * ```typescript\n * const CounterSlice = slice()\n * .with(Counter)\n * .on(\"Incremented\")\n * .do(async (event, _stream, app) => {\n * await app.do(\"reset\", target, {});\n * })\n * .void()\n * .build();\n * ```\n *\n * @example Cross-state dispatch (include both states)\n * ```typescript\n * const CreationSlice = slice()\n * .with(TicketCreation)\n * .with(TicketOperations) // handler can dispatch AssignTicket\n * .on(\"TicketOpened\").do(async (event, _stream, app) => {\n * await app.do(\"AssignTicket\", target, payload, event);\n * })\n * .build();\n * ```\n *\n * @see {@link SliceBuilder} for builder methods\n * @see {@link Slice} for the output type\n */\nexport function slice<\n // @ts-expect-error empty schema\n S extends SchemaRegister<A> = {},\n E extends Schemas = {},\n A extends Schemas = {},\n M extends Record<string, Schema> = {},\n>(\n states: Map<string, State<any, any, any>> = new Map(),\n actions: Record<string, any> = {},\n events: EventRegister<E> = {} as EventRegister<E>,\n projections: Projection<any>[] = []\n): SliceBuilder<S, E, A, M> {\n const builder: SliceBuilder<S, E, A, M> = {\n with: <\n SX extends Schema,\n EX extends Schemas,\n AX extends Schemas,\n NX extends string = string,\n >(\n state: State<SX, EX, AX, NX>\n ) => {\n registerState(state, states, actions, events as Record<string, unknown>);\n return slice<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX,\n M & { [K in NX]: SX }\n >(\n states,\n actions,\n events as unknown as EventRegister<E & EX>,\n projections\n );\n },\n projection: <EP extends Schemas>(proj: Projection<EP>) => {\n projections.push(proj);\n return slice<S, E, A, M>(states, actions, events, projections);\n },\n on: <K extends keyof E>(event: K) => ({\n do: (\n handler: (\n event: Committed<E, K>,\n stream: string,\n app: Dispatcher<A>\n ) => Promise<Snapshot<Schema, E> | void>,\n options?: Partial<ReactionOptions>\n ) => {\n const reaction: Reaction<E, K, A> = {\n handler: handler as ReactionHandler<E, K, A>,\n resolver: _this_,\n options: {\n blockOnError: options?.blockOnError ?? true,\n maxRetries: options?.maxRetries ?? 3,\n },\n };\n const name =\n handler.name || `${String(event)}_${events[event].reactions.size}`;\n events[event].reactions.set(name, reaction);\n return {\n ...builder,\n to(resolver: ReactionResolver<E, K> | string) {\n events[event].reactions.set(name, {\n ...reaction,\n resolver:\n typeof resolver === \"string\" ? { target: resolver } : resolver,\n });\n return builder;\n },\n void() {\n events[event].reactions.set(name, {\n ...reaction,\n resolver: _void_,\n });\n return builder;\n },\n };\n },\n }),\n build: () => ({\n _tag: \"Slice\" as const,\n states,\n events,\n projections,\n }),\n events,\n };\n return builder;\n}\n","/**\n * @module act-builder\n * @category Builders\n *\n * Fluent builder for composing event-sourced applications.\n */\nimport { Act } from \"./act.js\";\nimport { _this_, _void_, mergeProjection, registerState } from \"./merge.js\";\nimport { isProjection, type Projection } from \"./projection-builder.js\";\nimport { isSlice, type Slice } from \"./slice-builder.js\";\nimport type {\n Committed,\n Dispatcher,\n EventRegister,\n Reaction,\n ReactionHandler,\n ReactionOptions,\n ReactionResolver,\n Registry,\n Schema,\n SchemaRegister,\n Schemas,\n Snapshot,\n State,\n} from \"./types/index.js\";\n\n/**\n * Fluent builder interface for composing event-sourced applications.\n *\n * Provides a chainable API for:\n * - Registering states or slices via `.with()`\n * - Defining event reactions via `.on()` → `.do()` → `.to()` or `.void()`\n * - Building the orchestrator via `.build()`\n *\n * @template S - Schema register for states (maps action names to state schemas)\n * @template E - Event schemas (maps event names to event data schemas)\n * @template A - Action schemas (maps action names to action payload schemas)\n *\n * @see {@link act} for usage examples\n * @see {@link Act} for the built orchestrator API\n */\nexport type ActBuilder<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n M extends Record<string, Schema> = {},\n> = {\n /**\n * Registers a state definition or a slice with the builder.\n *\n * When receiving a State, it registers the state's actions and events.\n * When receiving a Slice, it merges all the slice's states and reactions.\n * State names, action names, and event names must be unique across the application\n * (partial states with the same name are merged automatically).\n *\n * @throws {Error} If duplicate action or event names are detected\n *\n * @example Register a state\n * ```typescript\n * const app = act().with(Counter).build();\n * ```\n *\n * @example Register a slice\n * ```typescript\n * const CounterSlice = slice().with(Counter).on(\"Incremented\").do(log).void().build();\n * const app = act().with(CounterSlice).build();\n * ```\n */\n with: (<\n SX extends Schema,\n EX extends Schemas,\n AX extends Schemas,\n NX extends string = string,\n >(\n state: State<SX, EX, AX, NX>\n ) => ActBuilder<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX,\n M & { [K in NX]: SX }\n >) &\n (<\n SX extends SchemaRegister<AX>,\n EX extends Schemas,\n AX extends Schemas,\n MX extends Record<string, Schema>,\n >(\n slice: Slice<SX, EX, AX, MX>\n ) => ActBuilder<S & SX, E & EX, A & AX, M & MX>) &\n (<EX extends Schemas>(\n projection: [Exclude<keyof EX, keyof E>] extends [never]\n ? Projection<EX>\n : never\n ) => ActBuilder<S, E, A, M>);\n /**\n * Begins defining a reaction to a specific event.\n *\n * Reactions are event handlers that respond to state changes. They can trigger\n * additional actions, update external systems, or perform side effects. Reactions\n * are processed asynchronously during drain cycles.\n *\n * @template K - Event name (must be a registered event)\n * @param event - The event name to react to\n * @returns An object with `.do()` method to define the reaction handler\n *\n * @example\n * ```typescript\n * const app = act()\n * .with(User)\n * .on(\"UserCreated\") // React to UserCreated events\n * .do(async (event) => {\n * await sendWelcomeEmail(event.data.email);\n * })\n * .void()\n * .build();\n * ```\n */\n on: <K extends keyof E>(\n event: K\n ) => {\n /**\n * Defines the reaction handler function for the event.\n *\n * The handler receives the committed event and can:\n * - Perform side effects (send emails, call APIs, etc.)\n * - Return an action tuple `[actionName, payload]` to trigger another action\n * - Return `void` or `undefined` for side-effect-only reactions\n *\n * @param handler - The reaction handler function\n * @param options - Optional reaction configuration\n * @param options.blockOnError - Block this stream if handler fails (default: true)\n * @param options.maxRetries - Maximum retry attempts on failure (default: 3)\n * @returns The builder with `.to()` and `.void()` methods for routing configuration\n */\n do: (\n handler: (\n event: Committed<E, K>,\n stream: string,\n app: Dispatcher<A>\n ) => Promise<Snapshot<Schema, E> | void>,\n options?: Partial<ReactionOptions>\n ) => ActBuilder<S, E, A, M> & {\n /**\n * Routes the reaction to a specific target stream.\n *\n * @param resolver - Target stream name (string) or resolver function\n * @returns The builder for chaining\n */\n to: (resolver: ReactionResolver<E, K> | string) => ActBuilder<S, E, A, M>;\n /**\n * Marks the reaction as void (side-effect only, no target stream).\n *\n * @returns The builder for chaining\n */\n void: () => ActBuilder<S, E, A, M>;\n };\n };\n /**\n * Builds and returns the Act orchestrator instance.\n *\n * @param drainLimit - Deprecated parameter, no longer used\n * @returns The Act orchestrator instance\n *\n * @see {@link Act} for available orchestrator methods\n */\n build: (drainLimit?: number) => Act<S, E, A, M>;\n /**\n * The registered event schemas and their reaction maps.\n */\n readonly events: EventRegister<E>;\n};\n\n/* eslint-disable @typescript-eslint/no-empty-object-type -- {} used as generic defaults */\n\n/**\n * Creates a new Act orchestrator builder for composing event-sourced applications.\n *\n * The Act orchestrator is responsible for:\n * - Managing state instances (aggregates)\n * - Executing actions and committing events\n * - Processing reactions (event handlers)\n * - Coordinating event-driven workflows\n *\n * Use the fluent API to register states or slices with `.with()`, define event\n * reactions with `.on()`, and build the orchestrator with `.build()`.\n *\n * @template S - State schema register type\n * @template E - Event schemas type\n * @template A - Action schemas type\n * @returns An ActBuilder instance for fluent API configuration\n *\n * @example Basic application with single state\n * ```typescript\n * import { act, state } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const Counter = state({ Counter: z.object({ count: z.number() }) })\n * .init(() => ({ count: 0 }))\n * .emits({ Incremented: z.object({ amount: z.number() }) })\n * .patch({ Incremented: (event, state) => ({ count: state.count + event.data.amount }) })\n * .on({ increment: z.object({ by: z.number() }) })\n * .emit((action) => [\"Incremented\", { amount: action.by }])\n * .build();\n *\n * const app = act()\n * .with(Counter)\n * .build();\n * ```\n *\n * @example Application with slices (vertical slice architecture)\n * ```typescript\n * import { act, slice, state } from \"@rotorsoft/act\";\n *\n * const CounterSlice = slice()\n * .with(Counter)\n * .on(\"Incremented\")\n * .do(async (event) => { console.log(\"incremented!\"); })\n * .void()\n * .build();\n *\n * const app = act()\n * .with(CounterSlice)\n * .build();\n * ```\n *\n * @see {@link ActBuilder} for available builder methods\n * @see {@link Act} for orchestrator API methods\n * @see {@link state} for defining states\n * @see {@link slice} for defining slices\n */\nexport function act<\n // @ts-expect-error empty schema\n S extends SchemaRegister<A> = {},\n E extends Schemas = {},\n A extends Schemas = {},\n M extends Record<string, Schema> = {},\n>(\n states: Map<string, State<any, any, any>> = new Map(),\n registry: Registry<S, E, A> = {\n actions: {} as Registry<S, E, A>[\"actions\"],\n events: {} as Registry<S, E, A>[\"events\"],\n },\n pendingProjections: Projection<any>[] = []\n): ActBuilder<S, E, A, M> {\n const builder: ActBuilder<S, E, A, M> = {\n with: ((\n input: State<any, any, any> | Slice<any, any, any, any> | Projection<any>\n ) => {\n if (isProjection(input)) {\n // PROJECTION: copy event schemas and reactions (no states)\n mergeProjection(input, registry.events);\n return act(\n states,\n registry as Registry<any, any, any>,\n pendingProjections\n );\n }\n if (isSlice(input)) {\n // SLICE: merge all states and copy reactions\n for (const s of input.states.values()) {\n registerState(s, states, registry.actions, registry.events);\n }\n // Copy reactions from slice's event register\n for (const eventName of Object.keys(input.events)) {\n const sliceRegister = input.events[eventName];\n for (const [name, reaction] of sliceRegister.reactions) {\n (\n registry.events as Record<\n string,\n { reactions: Map<string, unknown> }\n >\n )[eventName].reactions.set(name, reaction);\n }\n }\n // Defer embedded projections to build() time\n pendingProjections.push(...input.projections);\n return act(\n states,\n registry as Registry<any, any, any>,\n pendingProjections\n );\n }\n // STATE: register directly\n registerState(input, states, registry.actions, registry.events);\n return act(\n states,\n registry as Registry<any, any, any>,\n pendingProjections\n );\n }) as ActBuilder<S, E, A, M>[\"with\"],\n /**\n * Adds a reaction to an event.\n *\n * @template K The type of event\n * @param event The event to add a reaction to\n * @returns The builder\n */\n on: <K extends keyof E>(event: K) => ({\n do: (\n handler: (\n event: Committed<E, K>,\n stream: string,\n app: Dispatcher<A>\n ) => Promise<Snapshot<Schema, E> | void>,\n options?: Partial<ReactionOptions>\n ) => {\n const reaction: Reaction<E, K, A> = {\n handler: handler as ReactionHandler<E, K, A>,\n resolver: _this_,\n options: {\n blockOnError: options?.blockOnError ?? true,\n maxRetries: options?.maxRetries ?? 3,\n },\n };\n const name =\n handler.name ||\n `${String(event)}_${registry.events[event].reactions.size}`;\n registry.events[event].reactions.set(name, reaction);\n return {\n ...builder,\n to(resolver: ReactionResolver<E, K> | string) {\n registry.events[event].reactions.set(name, {\n ...reaction,\n resolver:\n typeof resolver === \"string\" ? { target: resolver } : resolver,\n });\n return builder;\n },\n void() {\n registry.events[event].reactions.set(name, {\n ...reaction,\n resolver: _void_,\n });\n return builder;\n },\n };\n },\n }),\n build: () => {\n for (const proj of pendingProjections) {\n mergeProjection(proj, registry.events as Record<string, any>);\n }\n return new Act<S, E, A, M>(registry, states);\n },\n events: registry.events,\n };\n return builder;\n}\n","/**\n * @module state-builder\n * @category Builders\n *\n * Fluent interface for defining a strongly-typed state machine using Zod schemas.\n */\nimport { ZodType } from \"zod\";\nimport {\n ActionHandler,\n ActionHandlers,\n GivenHandlers,\n Invariant,\n PatchHandlers,\n Schema,\n Schemas,\n Snapshot,\n State,\n ZodTypes,\n} from \"./types/index.js\";\n\n/**\n * Builder interface for defining a state with event sourcing.\n *\n * Provides a fluent API to configure the initial state, event types,\n * and event handlers (reducers) before moving to action configuration.\n *\n * @template S - State schema type\n *\n * @see {@link state} for usage examples\n * @see {@link ActionBuilder} for action configuration\n */\nexport type StateBuilder<S extends Schema, N extends string = string> = {\n /**\n * Defines the initial state for new state instances.\n *\n * The init function is called when a new stream is created (first event).\n * It can accept initial data or return a default state.\n *\n * @param init - Function returning the initial state\n * @returns A builder with `.emits()` to declare event types\n *\n * @example\n * ```typescript\n * .init(() => ({ count: 0, created: new Date() }))\n * ```\n *\n * @example With initial data\n * ```typescript\n * .init((data) => ({ ...data, createdAt: new Date() }))\n * ```\n */\n init: (init: () => Readonly<S>) => {\n /**\n * Declares the event types that this state can emit.\n *\n * Events represent facts that have happened - they should be named in past tense.\n * Each event is defined with a Zod schema for type safety and runtime validation.\n *\n * @template E - Event schemas type\n * @param events - Object mapping event names to Zod schemas\n * @returns A builder with `.patch()` to define event handlers\n *\n * @example\n * ```typescript\n * .emits({\n * Incremented: z.object({ amount: z.number() }),\n * Decremented: z.object({ amount: z.number() }),\n * Reset: z.object({})\n * })\n * ```\n */\n emits: <E extends Schemas>(\n events: ZodTypes<E>\n ) => {\n /**\n * Defines how each event updates (patches) the state.\n *\n * Patch handlers are reducers - pure functions that take an event and current state,\n * and return the changes to apply. Return partial state objects; unchanged fields\n * are preserved automatically.\n *\n * @param patch - Object mapping event names to patch handler functions\n * @returns An ActionBuilder for defining actions\n *\n * @example\n * ```typescript\n * .patch({\n * Incremented: (event, state) => ({ count: state.count + event.data.amount }),\n * Decremented: (event, state) => ({ count: state.count - event.data.amount }),\n * Reset: () => ({ count: 0 })\n * })\n * ```\n */\n patch: (\n patch: PatchHandlers<S, E>\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- {} avoids string index signature that Record<string, never> would add, keeping keyof A precise\n ) => ActionBuilder<S, E, {}, N>;\n };\n };\n};\n\n/** Helper: a single-key record mapping a state name to its Zod schema. */\ntype StateEntry<K extends string = string, S extends Schema = Schema> = {\n [P in K]: ZodType<S>;\n};\n\n/** Helper: a single-key record mapping an action name to its Zod schema. */\ntype ActionEntry<K extends string = string, AX extends Schema = Schema> = {\n [P in K]: ZodType<AX>;\n};\n\n/**\n * Builder interface for defining actions (commands) on a state.\n *\n * Actions represent user/system intents to modify state. Each action is validated\n * against a schema, can have business rule invariants, and must emit one or more events.\n *\n * @template S - State schema type\n * @template E - Event schemas type\n * @template A - Action schemas type\n *\n * @see {@link state} for complete usage examples\n */\nexport type ActionBuilder<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n N extends string = string,\n> = {\n /**\n * Defines an action (command) that can be executed on this state.\n *\n * Actions represent intents to change state - they should be named in imperative form\n * (e.g., \"CreateUser\", \"IncrementCounter\", \"PlaceOrder\"). Actions are validated against\n * their schema and must emit at least one event.\n *\n * Pass a `{ ActionName: schema }` record — use shorthand `{ ActionName }`\n * when the variable name matches the action name. The key becomes the\n * action name, the value the Zod schema.\n *\n * @template K - Action name (string literal type)\n * @template AX - Action payload schema type\n * @param entry - Single-key record `{ ActionName: schema }`\n * @returns An object with `.given()` and `.emit()` for further configuration\n *\n * @example Simple action without invariants\n * ```typescript\n * .on({ increment: z.object({ by: z.number() }) })\n * .emit((action) => [\"Incremented\", { amount: action.by }])\n * ```\n *\n * @example Action with business rules\n * ```typescript\n * .on({ withdraw: z.object({ amount: z.number() }) })\n * .given([\n * (_, snap) => snap.state.balance >= 0 || \"Account closed\",\n * (_, snap, action) => snap.state.balance >= action.amount || \"Insufficient funds\"\n * ])\n * .emit((action) => [\"Withdrawn\", { amount: action.amount }])\n * ```\n *\n * @example Action with shorthand (variable name matches action name)\n * ```typescript\n * const OpenTicket = z.object({ title: z.string() });\n * .on({ OpenTicket })\n * .emit((action) => [\"TicketOpened\", { title: action.title }])\n * ```\n */\n on: <K extends string, AX extends Schema>(\n entry: ActionEntry<K, AX>\n ) => {\n /**\n * Adds business rule invariants that must hold before the action can execute.\n *\n * Invariants are checked after loading the current state but before emitting events.\n * Each invariant should return `true` or an error message string. All invariants\n * must pass for the action to succeed.\n *\n * @param rules - Array of invariant functions\n * @returns An object with `.emit()` to finalize the action\n *\n * @example\n * ```typescript\n * .given([\n * (_, snap) => snap.state.status === \"active\" || \"Must be active\",\n * (target, snap) => snap.state.ownerId === target.actor.id || \"Not authorized\"\n * ])\n * ```\n */\n given: (rules: Invariant<S>[]) => {\n /**\n * Defines the action handler that emits events.\n *\n * The handler receives the action payload and current state snapshot,\n * and must return one or more events to emit. Events are applied to state\n * via the patch handlers defined earlier.\n *\n * @param handler - Function that returns events to emit\n * @returns The ActionBuilder for chaining more actions\n *\n * @example\n * ```typescript\n * .emit((action, snapshot) => {\n * const newBalance = snapshot.state.balance + action.amount;\n * return [\"Deposited\", { amount: action.amount, newBalance }];\n * })\n * ```\n */\n emit: (\n handler: ActionHandler<S, E, { [P in K]: AX }, K>\n ) => ActionBuilder<S, E, A & { [P in K]: AX }, N>;\n };\n /**\n * Defines the action handler that emits events.\n *\n * The handler receives the action payload and current state snapshot,\n * and must return one or more events to emit. Return a single event as\n * `[\"EventName\", data]` or multiple events as an array of event tuples.\n *\n * @param handler - Function that returns events to emit\n * @returns The ActionBuilder for chaining more actions\n *\n * @example Single event\n * ```typescript\n * .emit((action) => [\"Incremented\", { amount: action.by }])\n * ```\n *\n * @example Multiple events\n * ```typescript\n * .emit((action) => [\n * [\"Incremented\", { amount: action.by }],\n * [\"LogUpdated\", { message: `Incremented by ${action.by}` }]\n * ])\n * ```\n *\n * @example Conditional events\n * ```typescript\n * .emit((action, snapshot) => {\n * if (snapshot.state.count + action.by >= 100) {\n * return [\n * [\"Incremented\", { amount: action.by }],\n * [\"MilestoneReached\", { milestone: 100 }]\n * ];\n * }\n * return [\"Incremented\", { amount: action.by }];\n * })\n * ```\n */\n emit: (\n handler: ActionHandler<S, E, { [P in K]: AX }, K>\n ) => ActionBuilder<S, E, A & { [P in K]: AX }, N>;\n };\n /**\n * Defines a snapshotting strategy to optimize state reconstruction.\n *\n * Snapshots store the current state at a point in time, allowing faster state loading\n * by avoiding replaying all events from the beginning. The snap function is called\n * after each event is applied and should return `true` when a snapshot should be taken.\n *\n * @param snap - Predicate function that returns true when a snapshot should be taken\n * @returns The ActionBuilder for chaining\n *\n * @example Snapshot every 10 events\n * ```typescript\n * .snap((snapshot) => snapshot.patches >= 10)\n * ```\n *\n * @example Snapshot based on state size\n * ```typescript\n * .snap((snapshot) => {\n * const estimatedSize = JSON.stringify(snapshot.state).length;\n * return estimatedSize > 10000 || snapshot.patches >= 50;\n * })\n * ```\n *\n * @example Time-based snapshotting\n * ```typescript\n * .snap((snapshot) => {\n * const hoursSinceLastSnapshot = snapshot.patches * 0.1; // Estimate\n * return hoursSinceLastSnapshot >= 24;\n * })\n * ```\n */\n snap: (\n snap: (snapshot: Snapshot<S, E>) => boolean\n ) => ActionBuilder<S, E, A, N>;\n /**\n * Finalizes and builds the state definition.\n *\n * Call this method after defining all actions, invariants, and patches to create\n * the complete State object that can be registered with Act.\n *\n * @returns The complete strongly-typed State definition\n *\n * @example\n * ```typescript\n * const Counter = state({ Counter: schema })\n * .init(() => ({ count: 0 }))\n * .emits({ Incremented: z.object({ amount: z.number() }) })\n * .patch({ Incremented: (event, state) => ({ count: state.count + event.data.amount }) })\n * .on({ increment: z.object({ by: z.number() }) })\n * .emit((action) => [\"Incremented\", { amount: action.by }])\n * .build(); // Returns State<S, E, A, N>\n * ```\n */\n build: () => State<S, E, A, N>;\n};\n\n/**\n * Creates a new state definition with event sourcing capabilities.\n *\n * States are the core building blocks of Act. Each state represents a consistency\n * boundary (aggregate) that processes actions, emits events, and maintains its own\n * state through event patches (reducers). States use event sourcing to maintain a\n * complete audit trail and enable time-travel capabilities.\n *\n * The state builder provides a fluent API for defining:\n * 1. Initial state via `.init()`\n * 2. Event types via `.emits()`\n * 3. Event handlers (reducers) via `.patch()`\n * 4. Actions (commands) via `.on()` → `.emit()`\n * 5. Business rules (invariants) via `.given()`\n * 6. Snapshotting strategy via `.snap()`\n *\n * @template S - Zod schema type defining the shape of the state\n * @param entry - Single-key record mapping state name to Zod schema (e.g., `{ Counter: z.object({ count: z.number() }) }`)\n * @returns A StateBuilder instance for fluent API configuration\n *\n * @example Basic counter state\n * ```typescript\n * import { state } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const Counter = state({ Counter: z.object({ count: z.number() }) })\n * .init(() => ({ count: 0 }))\n * .emits({\n * Incremented: z.object({ amount: z.number() })\n * })\n * .patch({\n * Incremented: (event, state) => ({ count: state.count + event.data.amount })\n * })\n * .on({ increment: z.object({ by: z.number() }) })\n * .emit((action) => [\"Incremented\", { amount: action.by }])\n * .build();\n * ```\n *\n * @example State with multiple events and invariants\n * ```typescript\n * const BankAccount = state({ BankAccount: z.object({\n * balance: z.number(),\n * currency: z.string(),\n * status: z.enum([\"open\", \"closed\"])\n * }) })\n * .init(() => ({ balance: 0, currency: \"USD\", status: \"open\" }))\n * .emits({\n * Deposited: z.object({ amount: z.number() }),\n * Withdrawn: z.object({ amount: z.number() }),\n * Closed: z.object({})\n * })\n * .patch({\n * Deposited: (event, state) => ({ balance: state.balance + event.data.amount }),\n * Withdrawn: (event, state) => ({ balance: state.balance - event.data.amount }),\n * Closed: () => ({ status: \"closed\", balance: 0 })\n * })\n * .on({ deposit: z.object({ amount: z.number() }) })\n * .given([\n * (_, snap) => snap.state.status === \"open\" || \"Account must be open\"\n * ])\n * .emit((action) => [\"Deposited\", { amount: action.amount }])\n * .on({ withdraw: z.object({ amount: z.number() }) })\n * .given([\n * (_, snap) => snap.state.status === \"open\" || \"Account must be open\",\n * (_, snap, action) =>\n * snap.state.balance >= action.amount || \"Insufficient funds\"\n * ])\n * .emit((action) => [\"Withdrawn\", { amount: action.amount }])\n * .on({ close: z.object({}) })\n * .given([\n * (_, snap) => snap.state.status === \"open\" || \"Already closed\",\n * (_, snap) => snap.state.balance === 0 || \"Balance must be zero\"\n * ])\n * .emit(() => [\"Closed\", {}])\n * .build();\n * ```\n *\n * @example State with snapshotting\n * ```typescript\n * const User = state({ User: z.object({\n * name: z.string(),\n * email: z.string(),\n * loginCount: z.number()\n * }) })\n * .init((data) => ({ ...data, loginCount: 0 }))\n * .emits({\n * UserCreated: z.object({ name: z.string(), email: z.string() }),\n * UserLoggedIn: z.object({})\n * })\n * .patch({\n * UserCreated: (event) => event.data,\n * UserLoggedIn: (_, state) => ({ loginCount: state.loginCount + 1 })\n * })\n * .on({ createUser: z.object({ name: z.string(), email: z.string() }) })\n * .emit((action) => [\"UserCreated\", action])\n * .on({ login: z.object({}) })\n * .emit(() => [\"UserLoggedIn\", {}])\n * .snap((snap) => snap.patches >= 10) // Snapshot every 10 events\n * .build();\n * ```\n *\n * @see {@link StateBuilder} for available builder methods\n * @see {@link ActionBuilder} for action configuration methods\n * @see {@link https://rotorsoft.github.io/act-root/docs/intro | Getting Started Guide}\n * @see {@link https://rotorsoft.github.io/act-root/docs/examples/calculator | Calculator Example}\n */\nexport function state<N extends string, S extends Schema>(\n entry: StateEntry<N, S>\n): StateBuilder<S, N> {\n const keys = Object.keys(entry);\n if (keys.length !== 1) throw new Error(\"state() requires exactly one key\");\n const name = keys[0] as N;\n const stateSchema = (entry as Record<string, ZodType<S>>)[name];\n return {\n init(init: () => Readonly<S>) {\n return {\n emits<E extends Schema>(events: ZodTypes<E>) {\n return {\n patch(patch: PatchHandlers<S, E>) {\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- {} avoids string index signature\n return action_builder<S, E, {}, N>({\n events,\n actions: {},\n state: stateSchema,\n name,\n init,\n patch,\n on: {},\n });\n },\n };\n },\n };\n },\n };\n}\n\nfunction action_builder<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n N extends string = string,\n>(state: State<S, E, A, N>): ActionBuilder<S, E, A, N> {\n return {\n on<K extends string, AX extends Schema>(entry: ActionEntry<K, AX>) {\n const keys = Object.keys(entry);\n if (keys.length !== 1) throw new Error(\".on() requires exactly one key\");\n const action = keys[0] as K;\n const schema = entry[action];\n\n if (action in state.actions)\n throw new Error(`Duplicate action \"${action}\"`);\n\n type NewA = A & { [P in K]: AX };\n const actions = { ...state.actions, [action]: schema } as ZodTypes<NewA>;\n const on = { ...state.on } as ActionHandlers<S, E, NewA>;\n const _given = { ...state.given } as GivenHandlers<S, NewA>;\n\n function given(rules: Invariant<S>[]) {\n _given[action] = rules;\n return { emit };\n }\n\n function emit(handler: ActionHandler<S, E, NewA, K>) {\n on[action] = handler;\n return action_builder<S, E, NewA, N>({\n ...state,\n actions,\n on,\n given: _given,\n });\n }\n\n return { given, emit };\n },\n\n snap(snap: (snapshot: Snapshot<S, E>) => boolean) {\n return action_builder<S, E, A, N>({ ...state, snap });\n },\n\n build(): State<S, E, A, N> {\n return state;\n },\n };\n}\n"],"mappings":"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","names":["action","z","z","pkg","a","b","store","logLevel","stream","randomUUID","state","action","action","lagging","randomUUID","lagging_handled","leading_handled","handled","ZodObject","state","state","patch","state","action","snap"]}
1
+ {"version":3,"sources":["../src/ports.ts","../src/types/errors.ts","../src/utils.ts","../src/config.ts","../src/types/schemas.ts","../src/types/index.ts","../src/adapters/InMemoryStore.ts","../src/signals.ts","../src/act.ts","../src/event-sourcing.ts","../src/merge.ts","../src/act-builder.ts","../src/projection-builder.ts","../src/slice-builder.ts","../src/state-builder.ts"],"sourcesContent":["import { pino } from \"pino\";\nimport { InMemoryStore } from \"./adapters/InMemoryStore.js\";\nimport { config } from \"./config.js\";\nimport type {\n Disposable,\n Disposer,\n Fetch,\n Lease,\n LogLevel,\n Schemas,\n Store,\n} from \"./types/index.js\";\n\n/**\n * Port and adapter utilities for logging, store management, and resource disposal.\n *\n * Provides singleton store and logger instances, and helpers for resource lifecycle management.\n *\n * - Use `store()` to get or inject the event store (in-memory or persistent).\n * - Use `logger` for structured logging.\n * - Use `dispose()` to register resource disposers for graceful shutdown.\n *\n * @module ports\n */\n\n/**\n * List of exit codes for process termination.\n */\nexport const ExitCodes = [\"ERROR\", \"EXIT\"] as const;\n\n/**\n * Type for allowed exit codes.\n */\nexport type ExitCode = (typeof ExitCodes)[number];\n\n/**\n * Singleton logger instance (Pino).\n *\n * Use for structured logging throughout your application.\n *\n * @example\n * logger.info(\"Application started\");\n */\nexport const logger = pino({\n transport:\n config().env !== \"production\"\n ? {\n target: \"pino-pretty\",\n options: {\n ignore: \"pid,hostname\",\n singleLine: config().logSingleLine,\n colorize: true,\n },\n }\n : undefined,\n level: config().logLevel,\n});\n\n/**\n * Helper to create a singleton port (adapter) with optional injection.\n *\n * @param injector The function that creates the port/adapter\n * @returns A function to get or inject the singleton instance\n *\n * @example\n * const store = port((adapter) => adapter || new InMemoryStore());\n * const myStore = store();\n */\ntype Injector<Port extends Disposable> = (adapter?: Port) => Port;\nconst adapters = new Map<string, Disposable>();\nexport function port<Port extends Disposable>(injector: Injector<Port>) {\n return function (adapter?: Port): Port {\n if (!adapters.has(injector.name)) {\n const injected = injector(adapter);\n adapters.set(injector.name, injected);\n logger.info(`🔌 injected ${injector.name}:${injected.constructor.name}`);\n }\n return adapters.get(injector.name) as Port;\n };\n}\n\nconst disposers: Disposer[] = [];\nexport async function disposeAndExit(code: ExitCode = \"EXIT\"): Promise<void> {\n // ignore when errors are caught in production\n if (code === \"ERROR\" && config().env === \"production\") return;\n\n await Promise.all(disposers.map((disposer) => disposer()));\n await Promise.all(\n [...adapters.values()].reverse().map(async (adapter) => {\n await adapter.dispose();\n logger.info(`🔌 disposed ${adapter.constructor.name}`);\n })\n );\n adapters.clear();\n config().env !== \"test\" && process.exit(code === \"ERROR\" ? 1 : 0);\n}\n\n/**\n * Registers resource cleanup functions for graceful shutdown.\n *\n * Disposers are called automatically when the process exits (SIGINT, SIGTERM)\n * or when manually triggered. They execute in reverse registration order,\n * allowing proper cleanup of dependent resources.\n *\n * Act automatically disposes registered stores and adapters. Use this function\n * to register additional cleanup for your own resources (database connections,\n * file handles, timers, etc.).\n *\n * @param disposer - Async function to call during cleanup\n * @returns Function to manually trigger disposal and exit\n *\n * @example Register custom resource cleanup\n * ```typescript\n * import { dispose } from \"@rotorsoft/act\";\n *\n * const redis = createRedisClient();\n *\n * dispose(async () => {\n * console.log(\"Closing Redis connection...\");\n * await redis.quit();\n * });\n *\n * // On SIGINT/SIGTERM, Redis will be cleaned up automatically\n * ```\n *\n * @example Multiple disposers in order\n * ```typescript\n * import { dispose } from \"@rotorsoft/act\";\n *\n * const db = connectDatabase();\n * dispose(async () => {\n * console.log(\"Closing database...\");\n * await db.close();\n * });\n *\n * const cache = connectCache();\n * dispose(async () => {\n * console.log(\"Closing cache...\");\n * await cache.disconnect();\n * });\n *\n * // On exit: cache closes first, then database\n * ```\n *\n * @example Manual cleanup trigger\n * ```typescript\n * import { dispose } from \"@rotorsoft/act\";\n *\n * const shutdown = dispose(async () => {\n * await cleanup();\n * });\n *\n * // Manually trigger cleanup and exit\n * process.on(\"SIGUSR2\", async () => {\n * console.log(\"Manual shutdown requested\");\n * await shutdown(\"EXIT\");\n * });\n * ```\n *\n * @example With error handling\n * ```typescript\n * import { dispose } from \"@rotorsoft/act\";\n *\n * dispose(async () => {\n * try {\n * await expensiveCleanup();\n * } catch (error) {\n * console.error(\"Cleanup failed:\", error);\n * // Error doesn't prevent other disposers from running\n * }\n * });\n * ```\n *\n * @see {@link Disposer} for disposer function type\n * @see {@link Disposable} for disposable interface\n */\nexport function dispose(\n disposer?: Disposer\n): (code?: ExitCode) => Promise<void> {\n disposer && disposers.push(disposer);\n return disposeAndExit;\n}\n\n/**\n * Special event name for snapshot events in the event store.\n */\nexport const SNAP_EVENT = \"__snapshot__\";\n\n/**\n * Gets or injects the singleton event store.\n *\n * By default, Act uses an in-memory store suitable for development and testing.\n * For production, inject a persistent store like PostgresStore before building\n * your application.\n *\n * **Important:** Store injection must happen before creating any Act instances.\n * Once set, the store cannot be changed without restarting the application.\n *\n * @param adapter - Optional store implementation to inject\n * @returns The singleton store instance\n *\n * @example Using default in-memory store\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n *\n * const currentStore = store(); // Returns InMemoryStore\n * ```\n *\n * @example Injecting PostgreSQL store\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n * import { PostgresStore } from \"@rotorsoft/act-pg\";\n *\n * // Inject before building your app\n * store(new PostgresStore({\n * host: \"localhost\",\n * port: 5432,\n * database: \"myapp\",\n * user: \"postgres\",\n * password: \"secret\",\n * schema: \"public\",\n * table: \"events\"\n * }));\n *\n * // Now build your app - it will use PostgreSQL\n * const app = act()\n * .withState(Counter)\n * .build();\n * ```\n *\n * @example With environment-based configuration\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n * import { PostgresStore } from \"@rotorsoft/act-pg\";\n *\n * if (process.env.NODE_ENV === \"production\") {\n * store(new PostgresStore({\n * host: process.env.DB_HOST,\n * port: parseInt(process.env.DB_PORT || \"5432\"),\n * database: process.env.DB_NAME,\n * user: process.env.DB_USER,\n * password: process.env.DB_PASSWORD\n * }));\n * }\n * // Development uses default in-memory store\n * ```\n *\n * @example Testing with fresh store\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n *\n * beforeEach(async () => {\n * // Reset store between tests\n * await store().seed();\n * });\n *\n * afterAll(async () => {\n * // Cleanup\n * await store().drop();\n * });\n * ```\n *\n * @see {@link Store} for the store interface\n * @see {@link InMemoryStore} for the default implementation\n * @see {@link PostgresStore} for production use\n */\nexport const store = port(function store(adapter?: Store) {\n return adapter || new InMemoryStore();\n});\n\n/**\n * Tracer builder for logging fetches, leases, etc.\n */\nexport function build_tracer(logLevel: LogLevel): {\n fetched: <E extends Schemas>(fetched: Fetch<E>) => void;\n correlated: (leases: Lease[]) => void;\n leased: (leases: Lease[]) => void;\n acked: (leases: Lease[]) => void;\n blocked: (leases: Array<Lease & { error: string }>) => void;\n} {\n if (logLevel === \"trace\") {\n return {\n fetched: <E extends Schemas>(fetched: Fetch<E>) => {\n const data = Object.fromEntries(\n fetched.map(({ stream, source, events }) => {\n const key = source ? `${stream}<-${source}` : stream;\n const value = Object.fromEntries(\n events.map(({ id, stream, name }) => [id, { [stream]: name }])\n );\n return [key, value];\n })\n );\n logger.trace(data, \"⚡️ fetch\");\n },\n correlated: (leases: Lease[]) => {\n const data = leases.map(({ stream }) => stream).join(\" \");\n logger.trace(`⚡️ correlate ${data}`);\n },\n leased: (leases: Lease[]) => {\n const data = Object.fromEntries(\n leases.map(({ stream, at, retry }) => [stream, { at, retry }])\n );\n logger.trace(data, \"⚡️ lease\");\n },\n acked: (leases: Lease[]) => {\n const data = Object.fromEntries(\n leases.map(({ stream, at, retry }) => [stream, { at, retry }])\n );\n logger.trace(data, \"⚡️ ack\");\n },\n blocked: (leases: Array<Lease & { error: string }>) => {\n const data = Object.fromEntries(\n leases.map(({ stream, at, retry, error }) => [\n stream,\n { at, retry, error },\n ])\n );\n logger.trace(data, \"⚡️ block\");\n },\n };\n } else {\n return {\n fetched: () => {},\n correlated: () => {},\n leased: () => {},\n acked: () => {},\n blocked: () => {},\n };\n }\n}\n","import type { Message, Schema, Schemas, Snapshot, Target } from \"./action.js\";\n\n/**\n * @packageDocumentation\n * @module act/types\n * @category Types\n * Application error type constants and error classes for the Act Framework.\n *\n * - `ERR_VALIDATION`: Schema validation error\n * - `ERR_INVARIANT`: Invariant validation error\n * - `ERR_CONCURRENCY`: Optimistic concurrency validation error on commits\n */\nexport const Errors = {\n ValidationError: \"ERR_VALIDATION\",\n InvariantError: \"ERR_INVARIANT\",\n ConcurrencyError: \"ERR_CONCURRENCY\",\n} as const;\n\n/**\n * Thrown when an action or event payload fails Zod schema validation.\n *\n * This error indicates that data doesn't match the expected schema defined\n * for an action or event. The `details` property contains the Zod validation\n * error with specific information about what failed.\n *\n * @example Catching validation errors\n * ```typescript\n * import { ValidationError } from \"@rotorsoft/act\";\n *\n * try {\n * await app.do(\"createUser\", target, {\n * email: \"invalid-email\", // Missing @ symbol\n * age: -5 // Negative age\n * });\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * console.error(\"Validation failed for:\", error.target);\n * console.error(\"Invalid payload:\", error.payload);\n * console.error(\"Validation details:\", error.details);\n * // details contains Zod error with field-level info\n * }\n * }\n * ```\n *\n * @example Logging validation details\n * ```typescript\n * try {\n * await app.do(\"updateProfile\", target, payload);\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * error.details.errors.forEach((err) => {\n * console.error(`Field ${err.path.join(\".\")}: ${err.message}`);\n * });\n * }\n * }\n * ```\n *\n * @see {@link https://zod.dev | Zod documentation} for validation details\n */\nexport class ValidationError extends Error {\n constructor(\n /** The type of target being validated (e.g., \"action\", \"event\") */\n public readonly target: string,\n /** The invalid payload that failed validation */\n public readonly payload: any,\n /** Zod validation error details */\n public readonly details: any\n ) {\n super(`Invalid ${target} payload`);\n this.name = Errors.ValidationError;\n }\n}\n\n/**\n * Thrown when a business rule (invariant) is violated during action execution.\n *\n * Invariants are conditions that must hold true for an action to succeed.\n * They're checked after loading the current state but before emitting events.\n * This error provides complete context about what action was attempted and\n * why it was rejected.\n *\n * @template S - State schema type\n * @template E - Event schemas type\n * @template A - Action schemas type\n * @template K - Action name\n *\n * @example Catching invariant violations\n * ```typescript\n * import { InvariantError } from \"@rotorsoft/act\";\n *\n * try {\n * await app.do(\"withdraw\",\n * { stream: \"account-123\", actor: { id: \"user1\", name: \"Alice\" } },\n * { amount: 1000 }\n * );\n * } catch (error) {\n * if (error instanceof InvariantError) {\n * console.error(\"Action:\", error.action);\n * console.error(\"Reason:\", error.description);\n * console.error(\"Current state:\", error.snapshot.state);\n * console.error(\"Attempted payload:\", error.payload);\n * }\n * }\n * ```\n *\n * @example User-friendly error messages\n * ```typescript\n * try {\n * await app.do(\"closeTicket\", target, payload);\n * } catch (error) {\n * if (error instanceof InvariantError) {\n * // Present friendly message to user\n * if (error.description === \"Ticket must be open\") {\n * return { error: \"This ticket is already closed\" };\n * } else if (error.description === \"Not authorized\") {\n * return { error: \"You don't have permission to close this ticket\" };\n * }\n * }\n * }\n * ```\n *\n * @example Logging with context\n * ```typescript\n * try {\n * await app.do(\"transfer\", target, { to: \"account2\", amount: 500 });\n * } catch (error) {\n * if (error instanceof InvariantError) {\n * logger.error({\n * action: error.action,\n * stream: error.target.stream,\n * actor: error.target.actor,\n * reason: error.description,\n * balance: error.snapshot.state.balance,\n * attempted: error.payload.amount\n * }, \"Invariant violation\");\n * }\n * }\n * ```\n *\n * @see {@link Invariant} for defining business rules\n */\nexport class InvariantError<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n K extends keyof A,\n> extends Error {\n constructor(\n /** The action that was attempted */\n readonly action: K,\n /** The action payload that was provided */\n readonly payload: Readonly<A[K]>,\n /** The target stream and actor context */\n readonly target: Target,\n /** The current state snapshot when invariant was checked */\n readonly snapshot: Snapshot<S, E>,\n /** Human-readable description of why the invariant failed */\n readonly description: string\n ) {\n super(`${action as string} failed invariant: ${description}`);\n this.name = Errors.InvariantError;\n }\n}\n\n/**\n * Thrown when optimistic concurrency control detects a conflict.\n *\n * This error occurs when trying to commit events to a stream that has been\n * modified by another process since it was last loaded. The version number\n * doesn't match expectations, indicating a concurrent modification.\n *\n * This is a normal occurrence in distributed systems and should be handled\n * by reloading the current state and retrying the action.\n *\n * @example Handling concurrency conflicts with retry\n * ```typescript\n * import { ConcurrencyError } from \"@rotorsoft/act\";\n *\n * async function transferWithRetry(from, to, amount, maxRetries = 3) {\n * for (let attempt = 0; attempt < maxRetries; attempt++) {\n * try {\n * await app.do(\"transfer\",\n * { stream: from, actor: currentUser },\n * { to, amount }\n * );\n * return { success: true };\n * } catch (error) {\n * if (error instanceof ConcurrencyError) {\n * if (attempt < maxRetries - 1) {\n * console.log(`Concurrent modification detected, retrying... (${attempt + 1}/${maxRetries})`);\n * await sleep(100 * Math.pow(2, attempt)); // Exponential backoff\n * continue;\n * }\n * }\n * throw error;\n * }\n * }\n * return { success: false, reason: \"Too many concurrent modifications\" };\n * }\n * ```\n *\n * @example Logging concurrency conflicts\n * ```typescript\n * try {\n * await app.do(\"updateInventory\", target, payload);\n * } catch (error) {\n * if (error instanceof ConcurrencyError) {\n * logger.warn({\n * stream: error.stream,\n * expectedVersion: error.expectedVersion,\n * actualVersion: error.lastVersion,\n * events: error.events.map(e => e.name)\n * }, \"Concurrent modification detected\");\n * }\n * }\n * ```\n *\n * @example User feedback for conflicts\n * ```typescript\n * try {\n * await app.do(\"editDocument\", target, { content: newContent });\n * } catch (error) {\n * if (error instanceof ConcurrencyError) {\n * return {\n * error: \"This document was modified by another user. Please refresh and try again.\",\n * code: \"CONCURRENT_MODIFICATION\"\n * };\n * }\n * }\n * ```\n *\n * @see {@link Store.commit} for version checking details\n */\nexport class ConcurrencyError extends Error {\n constructor(\n /** The stream that had the concurrent modification */\n public readonly stream: string,\n /** The actual current version in the store */\n public readonly lastVersion: number,\n /** The events that were being committed */\n public readonly events: Message<Schemas, keyof Schemas>[],\n /** The version number that was expected */\n public readonly expectedVersion: number\n ) {\n super(\n `Concurrency error committing \"${events\n .map((e) => `${stream}.${e.name}.${JSON.stringify(e.data)}`)\n .join(\n \", \"\n )}\". Expected version ${expectedVersion} but found version ${lastVersion}.`\n );\n this.name = Errors.ConcurrencyError;\n }\n}\n","import { type ZodError, type ZodType, prettifyError } from \"zod\";\nimport { config } from \"./config.js\";\nimport type { Patch, Schema } from \"./types/index.js\";\nimport { ValidationError } from \"./types/index.js\";\n\n/** These objects are copied instead of deep merged */\nconst UNMERGEABLES = [\n RegExp,\n Date,\n Array,\n Map,\n Set,\n WeakMap,\n WeakSet,\n ArrayBuffer,\n SharedArrayBuffer,\n DataView,\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n Float32Array,\n Float64Array,\n];\n\nconst is_mergeable = (value: any): boolean =>\n !!value &&\n typeof value === \"object\" &&\n !UNMERGEABLES.some((t) => value instanceof t);\n\n/**\n * @module utils\n * @category Utilities\n * Utility functions for patching state, validation, extending objects, and async helpers.\n *\n * - Use `patch()` to immutably update state with patches.\n * - Use `validate()` to validate payloads against Zod schemas.\n * - Use `extend()` to merge and validate configuration objects.\n * - Use `sleep()` for async delays.\n */\n\n/**\n * Immutably applies patches to a state object, creating a new copy.\n *\n * This function performs deep merging for plain objects while preserving\n * immutability. Special types (Arrays, Dates, Maps, etc.) are replaced\n * entirely rather than merged. Setting a property to `undefined` or `null`\n * removes it from the resulting object.\n *\n * Used internally by the framework to apply event patches to state, but\n * can also be used directly for state transformations.\n *\n * **Merging rules:**\n * - Plain objects: Deep merge recursively\n * - Arrays, Dates, RegExp, Maps, Sets, TypedArrays: Replace entirely\n * - `undefined` or `null` values: Delete the property\n * - Primitives: Replace with patch value\n *\n * @param original - The original state object to patch\n * @param patches - The patches to apply (partial state)\n * @returns A new state object with patches applied\n *\n * @example Simple property update\n * ```typescript\n * import { patch } from \"@rotorsoft/act\";\n *\n * const state = { count: 0, name: \"Alice\" };\n * const updated = patch(state, { count: 5 });\n * // Result: { count: 5, name: \"Alice\" }\n * // Original unchanged: { count: 0, name: \"Alice\" }\n * ```\n *\n * @example Nested object patching\n * ```typescript\n * const state = {\n * user: { id: 1, name: \"Alice\", email: \"alice@example.com\" },\n * settings: { theme: \"dark\" }\n * };\n *\n * const updated = patch(state, {\n * user: { email: \"newemail@example.com\" }\n * });\n * // Result: {\n * // user: { id: 1, name: \"Alice\", email: \"newemail@example.com\" },\n * // settings: { theme: \"dark\" }\n * // }\n * ```\n *\n * @example Property deletion\n * ```typescript\n * const state = { count: 5, temp: \"value\", flag: true };\n *\n * const updated = patch(state, {\n * temp: undefined, // Delete temp\n * flag: null // Delete flag\n * });\n * // Result: { count: 5 }\n * ```\n *\n * @example Array replacement (not merged)\n * ```typescript\n * const state = { items: [1, 2, 3], meta: { count: 3 } };\n *\n * const updated = patch(state, {\n * items: [4, 5] // Arrays are replaced, not merged\n * });\n * // Result: { items: [4, 5], meta: { count: 3 } }\n * ```\n *\n * @example In event handlers\n * ```typescript\n * import { state } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const Counter = state({ Counter: z.object({ count: z.number() }) })\n * .init(() => ({ count: 0 }))\n * .emits({ Incremented: z.object({ by: z.number() }) })\n * .patch({\n * Incremented: (event, state) => {\n * // patch() is called internally here\n * return { count: state.count + event.data.by };\n * }\n * });\n * ```\n *\n * @see {@link Patch} for the patch type definition\n */\nexport const patch = <S extends Schema>(\n original: Readonly<S>,\n patches: Readonly<Patch<S>>\n): Readonly<S> => {\n const copy = {} as Record<string, any>;\n Object.keys({ ...original, ...patches }).forEach((key) => {\n const patched_value = patches[key as keyof typeof patches];\n const original_value = original[key as keyof typeof original];\n const patched = patches && key in patches;\n const deleted =\n patched &&\n (typeof patched_value === \"undefined\" || patched_value === null);\n const value = patched && !deleted ? patched_value : original_value;\n !deleted &&\n (copy[key] = is_mergeable(value)\n ? patch(original_value || {}, patched_value || {})\n : value);\n });\n return copy as S;\n};\n\n/**\n * Validates a payload against a Zod schema.\n *\n * This is the primary validation function used throughout the Act framework.\n * It parses the payload using the provided Zod schema and throws a\n * {@link ValidationError} with detailed error information if validation fails.\n *\n * When no schema is provided, the payload is returned as-is without validation.\n * This allows for optional validation in the framework.\n *\n * The framework automatically calls this function when:\n * - Actions are invoked via `app.do()`\n * - Events are emitted from action handlers\n * - States are initialized\n *\n * @param target - Name of the target being validated (used in error messages)\n * @param payload - The data to validate\n * @param schema - Optional Zod schema to validate against\n * @returns The validated and type-safe payload\n * @throws {@link ValidationError} if validation fails with detailed error info\n *\n * @example Basic validation\n * ```typescript\n * import { validate } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const UserSchema = z.object({\n * email: z.string().email(),\n * age: z.number().min(0)\n * });\n *\n * const user = validate(\"User\", { email: \"alice@example.com\", age: 30 }, UserSchema);\n * // Returns: { email: \"alice@example.com\", age: 30 }\n * ```\n *\n * @example Handling validation errors\n * ```typescript\n * import { validate, ValidationError } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const schema = z.object({\n * email: z.string().email(),\n * age: z.number().min(18)\n * });\n *\n * try {\n * validate(\"User\", { email: \"invalid\", age: 15 }, schema);\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * console.error(\"Target:\", error.target); // \"User\"\n * console.error(\"Payload:\", error.payload); // { email: \"invalid\", age: 15 }\n * console.error(\"Details:\", error.details); // Prettified Zod errors\n * // Details shows: email must be valid, age must be >= 18\n * }\n * }\n * ```\n *\n * @example Optional validation\n * ```typescript\n * // When schema is undefined, payload is returned as-is\n * const data = validate(\"Data\", { any: \"value\" });\n * // Returns: { any: \"value\" } without validation\n * ```\n *\n * @example In action definitions\n * ```typescript\n * import { state } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const Counter = state({ Counter: z.object({ count: z.number() }) })\n * .init(() => ({ count: 0 }))\n * .emits({ Incremented: z.object({ by: z.number().positive() }) })\n * .on({ increment: z.object({ by: z.number() }) })\n * .emit((action) => {\n * // validate() is called automatically before this runs\n * // action.by is guaranteed to be a number\n * return [\"Incremented\", { by: action.by }];\n * })\n * .build();\n * ```\n *\n * @example Custom validation in application code\n * ```typescript\n * import { validate } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const ConfigSchema = z.object({\n * apiKey: z.string().min(32),\n * timeout: z.number().positive(),\n * retries: z.number().int().min(0).max(10)\n * });\n *\n * function loadConfig(raw: unknown) {\n * return validate(\"AppConfig\", raw, ConfigSchema);\n * }\n * ```\n *\n * @see {@link ValidationError} for error handling\n * @see {@link https://zod.dev | Zod documentation} for schema definition\n */\nexport const validate = <S>(\n target: string,\n payload: Readonly<S>,\n schema?: ZodType<S>\n): Readonly<S> => {\n try {\n return schema ? schema.parse(payload) : payload;\n } catch (error) {\n if (error instanceof Error && error.name === \"ZodError\") {\n throw new ValidationError(\n target,\n payload,\n prettifyError(error as ZodError)\n );\n }\n throw new ValidationError(target, payload, error);\n }\n};\n\n/**\n * Validates and merges configuration objects.\n *\n * This function first validates the source object against a Zod schema using\n * {@link validate}, then merges it with an optional target object. The source\n * properties override target properties in the result.\n *\n * Primarily used for configuration management where you want to:\n * 1. Define default configuration values\n * 2. Load environment-specific overrides\n * 3. Validate the final configuration\n *\n * The framework uses this internally for the {@link config} function.\n *\n * @template S - Source object type (must be a record)\n * @template T - Target object type (must be a record)\n * @param source - The source object to validate and use as overrides\n * @param schema - Zod schema to validate the source against\n * @param target - Optional target object with default values\n * @returns Merged object with validated source overriding target\n * @throws {@link ValidationError} if source fails schema validation\n *\n * @example Basic configuration merging\n * ```typescript\n * import { extend } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const ConfigSchema = z.object({\n * host: z.string(),\n * port: z.number(),\n * debug: z.boolean()\n * });\n *\n * const defaults = { host: \"localhost\", port: 3000, debug: false };\n * const overrides = { port: 8080, debug: true };\n *\n * const config = extend(overrides, ConfigSchema, defaults);\n * // Result: { host: \"localhost\", port: 8080, debug: true }\n * ```\n *\n * @example Environment-based configuration\n * ```typescript\n * import { extend } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const DbConfigSchema = z.object({\n * host: z.string(),\n * port: z.number(),\n * database: z.string(),\n * user: z.string(),\n * password: z.string()\n * });\n *\n * const defaults = {\n * host: \"localhost\",\n * port: 5432,\n * database: \"myapp_dev\",\n * user: \"postgres\",\n * password: \"dev\"\n * };\n *\n * const envConfig = {\n * host: process.env.DB_HOST || \"localhost\",\n * port: parseInt(process.env.DB_PORT || \"5432\"),\n * database: process.env.DB_NAME || \"myapp_dev\",\n * user: process.env.DB_USER || \"postgres\",\n * password: process.env.DB_PASSWORD || \"dev\"\n * };\n *\n * // Validates environment config and merges with defaults\n * const dbConfig = extend(envConfig, DbConfigSchema, defaults);\n * ```\n *\n * @example Framework usage\n * ```typescript\n * // This is how Act's config() function uses extend internally:\n * import { extend } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const BaseSchema = z.object({\n * env: z.enum([\"development\", \"test\", \"staging\", \"production\"]),\n * logLevel: z.enum([\"fatal\", \"error\", \"warn\", \"info\", \"debug\", \"trace\"]),\n * sleepMs: z.number().int().min(0).max(5000)\n * });\n *\n * const packageData = { name: \"my-app\", version: \"1.0.0\" };\n * const runtimeConfig = { env: \"production\", logLevel: \"info\", sleepMs: 100 };\n *\n * const config = extend(\n * { ...packageData, ...runtimeConfig },\n * BaseSchema,\n * packageData\n * );\n * ```\n *\n * @example With validation error handling\n * ```typescript\n * import { extend, ValidationError } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const schema = z.object({\n * apiKey: z.string().min(32),\n * timeout: z.number().positive()\n * });\n *\n * try {\n * const config = extend(\n * { apiKey: \"short\", timeout: -1 },\n * schema\n * );\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * console.error(\"Invalid configuration:\", error.details);\n * }\n * }\n * ```\n *\n * @see {@link validate} for validation details\n * @see {@link config} for framework configuration\n * @see {@link ValidationError} for error handling\n */\nexport const extend = <\n S extends Record<string, unknown>,\n T extends Record<string, unknown>,\n>(\n source: Readonly<S>,\n schema: ZodType<S>,\n target?: Readonly<T>\n): Readonly<S & T> => {\n const value = validate(\"config\", source, schema);\n return Object.assign(target || {}, value) as Readonly<S & T>;\n};\n\n/**\n * Pauses async execution for a specified duration.\n *\n * This is a simple async utility for adding delays in your code. When called\n * without arguments, it uses the configured sleep duration from `config().sleepMs`,\n * which defaults to 100ms in development and 0ms in test environments.\n *\n * The framework uses this internally in store adapters to simulate I/O delays\n * in the {@link InMemoryStore}.\n *\n * **Note:** In test environments (NODE_ENV=test), the default sleep duration is\n * 0ms to keep tests fast.\n *\n * @param ms - Optional duration in milliseconds (defaults to config().sleepMs)\n * @returns Promise that resolves after the specified delay\n *\n * @example Using default sleep duration\n * ```typescript\n * import { sleep } from \"@rotorsoft/act\";\n *\n * async function processWithDelay() {\n * console.log(\"Starting...\");\n * await sleep(); // Uses config().sleepMs (100ms in dev, 0ms in test)\n * console.log(\"Continued after delay\");\n * }\n * ```\n *\n * @example Custom sleep duration\n * ```typescript\n * import { sleep } from \"@rotorsoft/act\";\n *\n * async function retryWithBackoff(fn: () => Promise<void>, retries = 3) {\n * for (let i = 0; i < retries; i++) {\n * try {\n * await fn();\n * return;\n * } catch (error) {\n * if (i < retries - 1) {\n * const delay = Math.pow(2, i) * 1000; // Exponential backoff\n * console.log(`Retrying in ${delay}ms...`);\n * await sleep(delay);\n * } else {\n * throw error;\n * }\n * }\n * }\n * }\n * ```\n *\n * @example Rate limiting\n * ```typescript\n * import { sleep } from \"@rotorsoft/act\";\n *\n * async function processItems(items: string[]) {\n * for (const item of items) {\n * await processItem(item);\n * await sleep(500); // 500ms between items\n * }\n * }\n * ```\n *\n * @example Framework internal usage\n * ```typescript\n * // InMemoryStore uses sleep to simulate async I/O\n * class InMemoryStore implements Store {\n * async query(...) {\n * await sleep(); // Simulate database latency\n * // ... query logic\n * }\n *\n * async commit(...) {\n * await sleep(); // Simulate write latency\n * // ... commit logic\n * }\n * }\n * ```\n *\n * @example Configuring default sleep duration\n * ```bash\n * # Set custom default sleep duration via environment variable\n * SLEEP_MS=50 npm start\n *\n * # In tests, it's automatically 0\n * NODE_ENV=test npm test\n * ```\n *\n * @see {@link config} for sleep duration configuration\n */\nexport async function sleep(ms?: number) {\n return new Promise((resolve) => setTimeout(resolve, ms ?? config().sleepMs));\n}\n","/**\n * @packageDocumentation\n * Configuration utilities for Act Framework environment, logging, and package metadata.\n *\n * Provides type-safe configuration loading and validation using Zod schemas.\n *\n * @module config\n */\nimport * as fs from \"node:fs\";\nimport { z } from \"zod\";\nimport {\n Environment,\n Environments,\n LogLevel,\n LogLevels,\n} from \"./types/index.js\";\nimport { extend } from \"./utils.js\";\n\n/**\n * Zod schema for validating package.json metadata.\n * @internal\n */\nexport const PackageSchema = z.object({\n name: z.string().min(1),\n version: z.string().min(1),\n description: z.string().min(1).optional(),\n author: z\n .object({ name: z.string().min(1), email: z.string().optional() })\n .optional()\n .or(z.string().min(1))\n .optional(),\n license: z.string().min(1).optional(),\n dependencies: z.record(z.string(), z.string()).optional(),\n});\n\n/**\n * Type representing the validated package.json metadata.\n */\nexport type Package = z.infer<typeof PackageSchema>;\n\n/**\n * Loads and parses the local package.json file as a Package object.\n * @returns The parsed and validated package metadata.\n * @internal\n */\nconst getPackage = (): Package => {\n const pkg = fs.readFileSync(\"package.json\");\n return JSON.parse(pkg.toString()) as Package;\n};\n\n/**\n * Zod schema for the full Act Framework configuration object.\n * Includes package metadata, environment, logging, and timing options.\n * @internal\n */\nconst BaseSchema = PackageSchema.extend({\n env: z.enum(Environments),\n logLevel: z.enum(LogLevels),\n logSingleLine: z.boolean(),\n sleepMs: z.number().int().min(0).max(5000),\n});\n\n/**\n * Type representing the validated Act Framework configuration object.\n */\nexport type Config = z.infer<typeof BaseSchema>;\n\nconst { NODE_ENV, LOG_LEVEL, LOG_SINGLE_LINE, SLEEP_MS } = process.env;\n\nconst env = (NODE_ENV || \"development\") as Environment;\nconst logLevel = (LOG_LEVEL ||\n (NODE_ENV === \"test\"\n ? \"error\"\n : NODE_ENV === \"production\"\n ? \"info\"\n : \"trace\")) as LogLevel;\nconst logSingleLine = (LOG_SINGLE_LINE || \"true\") === \"true\";\nconst sleepMs = parseInt(NODE_ENV === \"test\" ? \"0\" : (SLEEP_MS ?? \"100\"));\n\nconst pkg = getPackage();\n\n/**\n * Gets the current Act Framework configuration.\n *\n * Configuration is loaded from package.json and environment variables, providing\n * type-safe access to application metadata and runtime settings.\n *\n * **Environment Variables:**\n * - `NODE_ENV`: \"development\" | \"test\" | \"staging\" | \"production\" (default: \"development\")\n * - `LOG_LEVEL`: \"fatal\" | \"error\" | \"warn\" | \"info\" | \"debug\" | \"trace\"\n * - `LOG_SINGLE_LINE`: \"true\" | \"false\" (default: \"true\")\n * - `SLEEP_MS`: Milliseconds for sleep utility (default: 100, 0 for tests)\n *\n * **Defaults by environment:**\n * - test: logLevel=\"error\", sleepMs=0\n * - production: logLevel=\"info\"\n * - development: logLevel=\"trace\"\n *\n * @returns The validated configuration object\n *\n * @example Basic usage\n * ```typescript\n * import { config } from \"@rotorsoft/act\";\n *\n * const cfg = config();\n * console.log(`App: ${cfg.name} v${cfg.version}`);\n * console.log(`Environment: ${cfg.env}`);\n * console.log(`Log level: ${cfg.logLevel}`);\n * ```\n *\n * @example Environment-specific behavior\n * ```typescript\n * import { config } from \"@rotorsoft/act\";\n *\n * const cfg = config();\n *\n * if (cfg.env === \"production\") {\n * // Use PostgreSQL in production\n * store(new PostgresStore(prodConfig));\n * } else {\n * // Use in-memory store for dev/test\n * store(new InMemoryStore());\n * }\n * ```\n *\n * @example Adjusting log levels\n * ```typescript\n * // Set via environment variable:\n * // LOG_LEVEL=debug npm start\n *\n * // Or check in code:\n * const cfg = config();\n * if (cfg.logLevel === \"trace\") {\n * logger.trace(\"Detailed debugging enabled\");\n * }\n * ```\n *\n * @see {@link Config} for configuration type\n * @see {@link Package} for package.json metadata\n */\nexport const config = (): Config => {\n return extend({ ...pkg, env, logLevel, logSingleLine, sleepMs }, BaseSchema);\n};\n","import { z, ZodObject, ZodRawShape } from \"zod\";\n\n/**\n * @packageDocumentation\n * @module act/types\n * @category Types\n * Zod schemas and helpers for the Act Framework.\n */\n\n/**\n * An empty Zod schema (no properties).\n */\nexport const ZodEmpty = z.record(z.string(), z.never());\n\n/**\n * Zod schema for an actor (user, system, etc.).\n */\nexport const ActorSchema = z\n .object({\n id: z.string(),\n name: z.string(),\n })\n .readonly();\n\n/**\n * Zod schema for a target (stream and actor info).\n */\nexport const TargetSchema = z\n .object({\n stream: z.string(),\n actor: ActorSchema,\n expectedVersion: z.number().optional(),\n })\n .readonly();\n\n/**\n * Zod schema for causation event metadata.\n */\nexport const CausationEventSchema = z.object({\n id: z.number(),\n name: z.string(),\n stream: z.string(),\n});\n\n/**\n * Zod schema for event metadata (correlation and causation).\n */\nexport const EventMetaSchema = z\n .object({\n correlation: z.string(),\n causation: z.object({\n action: TargetSchema.and(z.object({ name: z.string() })).optional(),\n event: CausationEventSchema.optional(),\n }),\n })\n .readonly();\n\n/**\n * Zod schema for committed event metadata (id, stream, version, created, meta).\n */\nexport const CommittedMetaSchema = z\n .object({\n id: z.number(),\n stream: z.string(),\n version: z.number(),\n created: z.date(),\n meta: EventMetaSchema,\n })\n .readonly();\n\n/**\n * Type representing the full state schema for a domain.\n * @property events - Map of event names to Zod schemas.\n * @property actions - Map of action names to Zod schemas.\n * @property state - Zod schema for the state object.\n */\nexport type StateSchema = Readonly<{\n events: Record<string, ZodObject<ZodRawShape> | typeof ZodEmpty>;\n actions: Record<string, ZodObject<ZodRawShape> | typeof ZodEmpty>;\n state: ZodObject<ZodRawShape>;\n}>;\n\n/**\n * Query options for event store queries.\n */\nexport const QuerySchema = z\n .object({\n stream: z.string().optional(),\n names: z.string().array().optional(),\n before: z.number().optional(),\n after: z.number().optional(),\n limit: z.number().optional(),\n created_before: z.date().optional(),\n created_after: z.date().optional(),\n backward: z.boolean().optional(),\n correlation: z.string().optional(),\n with_snaps: z.boolean().optional(),\n })\n .readonly();\n","/**\n * @packageDocumentation\n * @module act/types\n * Barrel file for Act Framework core types.\n *\n * Re-exports all major type definitions for actions, errors, ports, reactions, registries, and schemas.\n * Also defines common environment and log level types/constants for configuration and logging.\n *\n * @remarks\n * Import from this module to access all core framework types in one place.\n */\nexport type * from \"./action.js\";\nexport * from \"./errors.js\";\nexport type * from \"./ports.js\";\nexport type * from \"./reaction.js\";\nexport type * from \"./registry.js\";\nexport * from \"./schemas.js\";\n\n/**\n * Supported runtime environments for the framework.\n * - `development`: Local development\n * - `test`: Automated testing\n * - `staging`: Pre-production\n * - `production`: Live/production\n */\nexport const Environments = [\n \"development\",\n \"test\",\n \"staging\",\n \"production\",\n] as const;\n\n/**\n * Type representing a valid environment string.\n */\nexport type Environment = (typeof Environments)[number];\n\n/**\n * Supported log levels for framework logging.\n * - `fatal`, `error`, `warn`, `info`, `debug`, `trace`\n */\nexport const LogLevels = [\n \"fatal\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n \"trace\",\n] as const;\n\n/**\n * Type representing a valid log level string.\n */\nexport type LogLevel = (typeof LogLevels)[number];\n","/**\n * @packageDocumentation\n * @module act/adapters\n * In-memory event store adapter for the Act Framework.\n *\n * This adapter implements the Store interface and is suitable for development, testing, and demonstration purposes.\n * All data is stored in memory and lost on process exit.\n *\n * @category Adapters\n */\nimport { SNAP_EVENT } from \"../ports.js\";\nimport { ConcurrencyError } from \"../types/errors.js\";\nimport type {\n Committed,\n EventMeta,\n Lease,\n Message,\n Query,\n Schemas,\n Store,\n} from \"../types/index.js\";\nimport { sleep } from \"../utils.js\";\n\n/**\n * @internal\n * Represents an in-memory stream for event processing and leasing.\n */\nclass InMemoryStream {\n private _at = -1;\n private _retry = -1;\n private _blocked = false;\n private _error = \"\";\n private _leased_by: string | undefined = undefined;\n private _leased_until: Date | undefined = undefined;\n\n constructor(\n readonly stream: string,\n readonly source: string | undefined\n ) {}\n\n get is_avaliable() {\n return (\n !this._blocked &&\n (!this._leased_until || this._leased_until <= new Date())\n );\n }\n\n get at() {\n return this._at;\n }\n\n /**\n * Attempt to lease this stream for processing.\n * @param lease - The lease request.\n * @param millis - Lease duration in milliseconds.\n * @returns The granted lease or undefined if blocked.\n */\n lease(lease: Lease, millis: number): Lease | undefined {\n if (this.is_avaliable) {\n if (millis > 0) {\n this._leased_by = lease.by;\n this._leased_until = new Date(Date.now() + millis);\n this._retry = this._retry + 1;\n }\n return {\n stream: this.stream,\n source: this.source,\n at: lease.at,\n by: lease.by,\n retry: this._retry,\n lagging: lease.lagging,\n };\n }\n }\n\n /**\n * Acknowledge completion of processing for this stream.\n * @param lease - The lease request.\n */\n ack(lease: Lease) {\n if (this._leased_by === lease.by) {\n this._leased_by = undefined;\n this._leased_until = undefined;\n this._at = lease.at;\n this._retry = -1;\n return {\n stream: this.stream,\n source: this.source,\n at: this._at,\n by: lease.by,\n retry: this._retry,\n lagging: lease.lagging,\n };\n }\n }\n\n /**\n * Block a stream for processing after failing to process and reaching max retries with blocking enabled.\n * @param lease - The lease request.\n * @param error Blocked error message.\n */\n block(lease: Lease, error: string) {\n if (this._leased_by === lease.by) {\n this._blocked = true;\n this._error = error;\n return {\n stream: this.stream,\n source: this.source,\n at: this._at,\n by: this._leased_by,\n retry: this._retry,\n error: this._error,\n lagging: lease.lagging,\n };\n }\n }\n}\n\n/**\n * In-memory event store implementation.\n *\n * This is the default store used by Act when no other store is injected.\n * It stores all events in memory and is suitable for:\n * - Development and prototyping\n * - Unit and integration testing\n * - Demonstrations and examples\n *\n * **Not suitable for production** - all data is lost when the process exits.\n * Use {@link PostgresStore} for production deployments.\n *\n * The in-memory store provides:\n * - Full {@link Store} interface implementation\n * - Optimistic concurrency control\n * - Stream leasing for distributed processing simulation\n * - Snapshot support\n * - Fast performance (no I/O overhead)\n *\n * @example Using in tests\n * ```typescript\n * import { store } from \"@rotorsoft/act\";\n *\n * describe(\"Counter\", () => {\n * beforeEach(async () => {\n * // Reset store between tests\n * await store().seed();\n * });\n *\n * it(\"increments\", async () => {\n * await app.do(\"increment\", target, { by: 5 });\n * const snapshot = await app.load(Counter, \"counter-1\");\n * expect(snapshot.state.count).toBe(5);\n * });\n * });\n * ```\n *\n * @example Explicit instantiation\n * ```typescript\n * import { InMemoryStore } from \"@rotorsoft/act\";\n *\n * const testStore = new InMemoryStore();\n * await testStore.seed();\n *\n * // Use for specific test scenarios\n * await testStore.commit(\"test-stream\", events, meta);\n * ```\n *\n * @example Querying events\n * ```typescript\n * const events: any[] = [];\n * await store().query(\n * (event) => events.push(event),\n * { stream: \"test-stream\" }\n * );\n * console.log(`Found ${events.length} events`);\n * ```\n *\n * @see {@link Store} for the interface definition\n * @see {@link PostgresStore} for production use\n * @see {@link store} for injecting stores\n *\n * @category Adapters\n */\nexport class InMemoryStore implements Store {\n // stored events\n private _events: Committed<Schemas, keyof Schemas>[] = [];\n // stored stream positions and other metadata\n private _streams: Map<string, InMemoryStream> = new Map();\n\n /**\n * Dispose of the store and clear all events.\n * @returns Promise that resolves when disposal is complete.\n */\n async dispose() {\n await sleep();\n this._events.length = 0;\n }\n\n /**\n * Seed the store with initial data (no-op for in-memory).\n * @returns Promise that resolves when seeding is complete.\n */\n async seed() {\n await sleep();\n }\n\n /**\n * Drop all data from the store.\n * @returns Promise that resolves when the store is cleared.\n */\n async drop() {\n await sleep();\n this._events.length = 0;\n this._streams = new Map();\n }\n\n private in_query<E extends Schemas>(query: Query, e: Committed<E, keyof E>) {\n if (query.stream && !RegExp(`^${query.stream}$`).test(e.stream))\n return false;\n if (query.names && !query.names.includes(e.name as string)) return false;\n if (query.correlation && e.meta?.correlation !== query.correlation)\n return false;\n if (e.name === SNAP_EVENT && !query.with_snaps) return false;\n return true;\n }\n\n /**\n * Query events in the store, optionally filtered by query options.\n * @param callback - Function to call for each event.\n * @param query - Optional query options.\n * @returns The number of events processed.\n */\n async query<E extends Schemas>(\n callback: (event: Committed<E, keyof E>) => void,\n query?: Query\n ) {\n await sleep();\n let count = 0;\n if (query?.backward) {\n let i = (query?.before || this._events.length) - 1;\n while (i >= 0) {\n const e = this._events[i--];\n if (query && !this.in_query(query, e)) continue;\n if (query?.created_before && e.created >= query.created_before)\n continue;\n if (query.after && e.id <= query.after) break;\n if (query.created_after && e.created <= query.created_after) break;\n callback(e as Committed<E, keyof E>);\n count++;\n if (query?.limit && count >= query.limit) break;\n }\n } else {\n let i = (query?.after ?? -1) + 1;\n while (i < this._events.length) {\n const e = this._events[i++];\n if (query && !this.in_query(query, e)) continue;\n if (query?.created_after && e.created <= query.created_after) continue;\n if (query?.before && e.id >= query.before) break;\n if (query?.created_before && e.created >= query.created_before) break;\n callback(e as Committed<E, keyof E>);\n count++;\n if (query?.limit && count >= query.limit) break;\n }\n }\n return count;\n }\n\n /**\n * Commit one or more events to a stream.\n * @param stream - The stream name.\n * @param msgs - The events/messages to commit.\n * @param meta - Event metadata.\n * @param expectedVersion - Optional optimistic concurrency check.\n * @returns The committed events with metadata.\n * @throws ConcurrencyError if expectedVersion does not match.\n */\n async commit<E extends Schemas>(\n stream: string,\n msgs: Message<E, keyof E>[],\n meta: EventMeta,\n expectedVersion?: number\n ) {\n await sleep();\n const instance = this._events.filter((e) => e.stream === stream); // ignore state events, this is a production optimization\n if (\n typeof expectedVersion === \"number\" &&\n instance.length - 1 !== expectedVersion\n ) {\n throw new ConcurrencyError(\n stream,\n instance.length - 1,\n msgs as Message<Schemas, keyof Schemas>[],\n expectedVersion\n );\n }\n\n let version = instance.length;\n return msgs.map(({ name, data }) => {\n const committed: Committed<E, keyof E> = {\n id: this._events.length,\n stream,\n version,\n created: new Date(),\n name,\n data,\n meta,\n };\n this._events.push(committed as Committed<Schemas, keyof Schemas>);\n version++;\n return committed;\n });\n }\n\n /**\n * Polls the store for unblocked streams needing processing, ordered by lease watermark ascending.\n * @param lagging - Max number of streams to poll in ascending order.\n * @param leading - Max number of streams to poll in descending order.\n * @returns The polled streams.\n */\n async poll(lagging: number, leading: number) {\n await sleep();\n const a = [...this._streams.values()]\n .filter((s) => s.is_avaliable)\n .sort((a, b) => a.at - b.at)\n .slice(0, lagging)\n .map(({ stream, source, at }) => ({\n stream,\n source,\n at,\n lagging: true,\n }));\n const b = [...this._streams.values()]\n .filter((s) => s.is_avaliable)\n .sort((a, b) => b.at - a.at)\n .slice(0, leading)\n .map(({ stream, source, at }) => ({\n stream,\n source,\n at,\n lagging: false,\n }));\n return [...a, ...b];\n }\n\n /**\n * Lease streams for processing (e.g., for distributed consumers).\n * @param leases - Lease requests for streams, including end-of-lease watermark, lease holder, and source stream.\n * @param leaseMilis - Lease duration in milliseconds.\n * @returns Granted leases.\n */\n async lease(leases: Lease[], millis: number) {\n await sleep();\n return leases\n .map((l) => {\n if (!this._streams.has(l.stream)) {\n // store new correlations\n this._streams.set(l.stream, new InMemoryStream(l.stream, l.source));\n }\n return this._streams.get(l.stream)?.lease(l, millis);\n })\n .filter((l) => !!l);\n }\n\n /**\n * Acknowledge completion of processing for leased streams.\n * @param leases - Leases to acknowledge, including last processed watermark and lease holder.\n */\n async ack(leases: Lease[]) {\n await sleep();\n return leases\n .map((l) => this._streams.get(l.stream)?.ack(l))\n .filter((l) => !!l);\n }\n\n /**\n * Block a stream for processing after failing to process and reaching max retries with blocking enabled.\n * @param leases - Leases to block, including lease holder and last error message.\n * @returns Blocked leases.\n */\n async block(leases: Array<Lease & { error: string }>) {\n await sleep();\n return leases\n .map((l) => this._streams.get(l.stream)?.block(l, l.error))\n .filter((l) => !!l);\n }\n}\n","import { disposeAndExit, logger } from \"./ports.js\";\n\n// exit on signals\nprocess.once(\"SIGINT\", async (arg?: any) => {\n logger.info(arg, \"SIGINT\");\n await disposeAndExit(\"EXIT\");\n});\nprocess.once(\"SIGTERM\", async (arg?: any) => {\n logger.info(arg, \"SIGTERM\");\n await disposeAndExit(\"EXIT\");\n});\nprocess.once(\"uncaughtException\", async (arg?: any) => {\n logger.error(arg, \"Uncaught Exception\");\n await disposeAndExit(\"ERROR\");\n});\nprocess.once(\"unhandledRejection\", async (arg?: any) => {\n logger.error(arg, \"Unhandled Rejection\");\n await disposeAndExit(\"ERROR\");\n});\n","import { randomUUID } from \"crypto\";\nimport EventEmitter from \"events\";\nimport { config } from \"./config.js\";\nimport * as es from \"./event-sourcing.js\";\nimport { build_tracer, dispose, logger, store } from \"./ports.js\";\nimport type {\n Committed,\n Drain,\n DrainOptions,\n Lease,\n Query,\n ReactionPayload,\n Registry,\n Schema,\n SchemaRegister,\n Schemas,\n Snapshot,\n State,\n Target,\n} from \"./types/index.js\";\n\nconst tracer = build_tracer(config().logLevel);\n\n/**\n * @category Orchestrator\n * @see Store\n *\n * Main orchestrator for event-sourced state machines and workflows.\n *\n * It manages the lifecycle of actions, reactions, and event streams, providing APIs for loading state, executing actions, querying events, and draining reactions.\n *\n * ## Usage\n *\n * ```typescript\n * const app = new Act(registry, 100);\n * await app.do(\"increment\", { stream: \"counter1\", actor }, { by: 1 });\n * const snapshot = await app.load(Counter, \"counter1\");\n * await app.drain();\n * ```\n *\n * - Register event listeners with `.on(\"committed\", ...)` and `.on(\"acked\", ...)` to react to lifecycle events.\n * - Use `.query()` to analyze event streams for analytics or debugging.\n *\n * @template S SchemaRegister for state\n * @template E Schemas for events\n * @template A Schemas for actions\n */\nexport class Act<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n M extends Record<string, Schema> = Record<string, never>,\n> {\n private _emitter = new EventEmitter();\n private _drain_locked = false;\n private _drain_lag2lead_ratio = 0.5;\n private _correlation_interval: NodeJS.Timeout | undefined = undefined;\n\n /**\n * Emit a lifecycle event (internal use, but can be used for custom listeners).\n *\n * @param event The event name (\"committed\", \"acked\", or \"blocked\")\n * @param args The event payload\n * @returns true if the event had listeners, false otherwise\n */\n emit(event: \"committed\", args: Snapshot<S, E>[]): boolean;\n emit(event: \"acked\", args: Lease[]): boolean;\n emit(event: \"blocked\", args: Array<Lease & { error: string }>): boolean;\n emit(event: string, args: any): boolean {\n return this._emitter.emit(event, args);\n }\n\n /**\n * Register a listener for a lifecycle event (\"committed\", \"acked\", or \"blocked\").\n *\n * @param event The event name\n * @param listener The callback function\n * @returns this (for chaining)\n */\n on(event: \"committed\", listener: (args: Snapshot<S, E>[]) => void): this;\n on(event: \"acked\", listener: (args: Lease[]) => void): this;\n on(\n event: \"blocked\",\n listener: (args: Array<Lease & { error: string }>) => void\n ): this;\n on(event: string, listener: (args: any) => void): this {\n this._emitter.on(event, listener);\n return this;\n }\n\n /**\n * Remove a listener for a lifecycle event.\n *\n * @param event The event name\n * @param listener The callback function\n * @returns this (for chaining)\n */\n off(event: \"committed\", listener: (args: Snapshot<S, E>[]) => void): this;\n off(event: \"acked\", listener: (args: Lease[]) => void): this;\n off(\n event: \"blocked\",\n listener: (args: Array<Lease & { error: string }>) => void\n ): this;\n off(event: string, listener: (args: any) => void): this {\n this._emitter.off(event, listener);\n return this;\n }\n\n /**\n * Create a new Act orchestrator.\n *\n * @param registry The registry of state, event, and action schemas\n * @param states Map of state names to their (potentially merged) state definitions\n */\n constructor(\n public readonly registry: Registry<S, E, A>,\n private readonly _states: Map<string, State<any, any, any>> = new Map()\n ) {\n dispose(() => {\n this._emitter.removeAllListeners();\n this.stop_correlations();\n return Promise.resolve();\n });\n }\n\n /**\n * Executes an action on a state instance, committing resulting events.\n *\n * This is the primary method for modifying state. It:\n * 1. Validates the action payload against the schema\n * 2. Loads the current state snapshot\n * 3. Checks invariants (business rules)\n * 4. Executes the action handler to generate events\n * 5. Applies events to create new state\n * 6. Commits events to the store with optimistic concurrency control\n *\n * @template K - Action name from registered actions\n * @param action - The name of the action to execute\n * @param target - Target specification with stream ID and actor context\n * @param payload - Action payload matching the action's schema\n * @param reactingTo - Optional event that triggered this action (for correlation)\n * @param skipValidation - Skip schema validation (use carefully, for performance)\n * @returns Array of snapshots for all affected states (usually one)\n *\n * @throws {ValidationError} If payload doesn't match action schema\n * @throws {InvariantError} If business rules are violated\n * @throws {ConcurrencyError} If another process modified the stream\n *\n * @example Basic action execution\n * ```typescript\n * const snapshots = await app.do(\n * \"increment\",\n * {\n * stream: \"counter-1\",\n * actor: { id: \"user1\", name: \"Alice\" }\n * },\n * { by: 5 }\n * );\n *\n * console.log(snapshots[0].state.count); // Current count after increment\n * ```\n *\n * @example With error handling\n * ```typescript\n * try {\n * await app.do(\n * \"withdraw\",\n * { stream: \"account-123\", actor: { id: \"user1\", name: \"Alice\" } },\n * { amount: 1000 }\n * );\n * } catch (error) {\n * if (error instanceof InvariantError) {\n * console.error(\"Business rule violated:\", error.description);\n * } else if (error instanceof ConcurrencyError) {\n * console.error(\"Concurrent modification detected, retry...\");\n * } else if (error instanceof ValidationError) {\n * console.error(\"Invalid payload:\", error.details);\n * }\n * }\n * ```\n *\n * @example Reaction triggering another action\n * ```typescript\n * const app = act()\n * .withState(Order)\n * .withState(Inventory)\n * .on(\"OrderPlaced\")\n * .do(async (event, context) => {\n * // This action is triggered by an event\n * const result = await context.app.do(\n * \"reduceStock\",\n * {\n * stream: \"inventory-1\",\n * actor: event.meta.causation.action.actor\n * },\n * { amount: event.data.items.length },\n * event // Pass event for correlation tracking\n * );\n * return result;\n * })\n * .to(\"inventory-1\")\n * .build();\n * ```\n *\n * @see {@link Target} for target structure\n * @see {@link Snapshot} for return value structure\n * @see {@link ValidationError}, {@link InvariantError}, {@link ConcurrencyError}\n */\n async do<K extends keyof A>(\n action: K,\n target: Target,\n payload: Readonly<A[K]>,\n reactingTo?: Committed<E, string & keyof E>,\n skipValidation = false\n ) {\n const snapshots = await es.action(\n this.registry.actions[action],\n action,\n target,\n payload,\n reactingTo,\n skipValidation\n );\n this.emit(\"committed\", snapshots as Snapshot<S, E>[]);\n return snapshots;\n }\n\n /**\n * Loads the current state snapshot for a specific stream.\n *\n * Reconstructs the current state by replaying events from the event store.\n * Uses snapshots when available to optimize loading performance.\n *\n * Accepts either a State definition object or a state name string. When\n * using a string, the merged state (from partial states registered via\n * `.withState()`) is resolved by name.\n *\n * @template SX - State schema type\n * @template EX - Event schemas type\n * @template AX - Action schemas type\n * @param state - The state definition or state name to load\n * @param stream - The stream ID (state instance identifier)\n * @param callback - Optional callback invoked with the loaded snapshot\n * @returns The current state snapshot for the stream\n *\n * @example Load by state definition\n * ```typescript\n * const snapshot = await app.load(Counter, \"counter-1\");\n * console.log(snapshot.state.count); // Current count\n * console.log(snapshot.patches); // Events since last snapshot\n * ```\n *\n * @example Load by state name (useful with partial states)\n * ```typescript\n * const snapshot = await app.load(\"Ticket\", \"ticket-123\");\n * console.log(snapshot.state.title); // Merged state from all partials\n * ```\n *\n * @example Load multiple states\n * ```typescript\n * const [user, account] = await Promise.all([\n * app.load(User, \"user-123\"),\n * app.load(BankAccount, \"account-456\")\n * ]);\n * ```\n *\n * @see {@link Snapshot} for snapshot structure\n */\n async load<SX extends Schema, EX extends Schemas, AX extends Schemas>(\n state: State<SX, EX, AX>,\n stream: string,\n callback?: (snapshot: Snapshot<SX, EX>) => void\n ): Promise<Snapshot<SX, EX>>;\n async load<K extends keyof M & string>(\n name: K,\n stream: string,\n callback?: (snapshot: Snapshot<M[K], E>) => void\n ): Promise<Snapshot<M[K], E>>;\n async load<SX extends Schema>(\n stateOrName: State<SX, any, any> | string,\n stream: string,\n callback?: (snapshot: Snapshot<any, any>) => void\n ): Promise<Snapshot<any, any>> {\n let merged: State<any, any, any>;\n if (typeof stateOrName === \"string\") {\n const found = this._states.get(stateOrName);\n if (!found) throw new Error(`State \"${stateOrName}\" not found`);\n merged = found;\n } else {\n merged = this._states.get(stateOrName.name) || stateOrName;\n }\n return await es.load(merged, stream, callback);\n }\n\n /**\n * Queries the event store for events matching a filter.\n *\n * Use this for analyzing event streams, generating reports, or debugging.\n * The callback is invoked for each matching event, and the method returns\n * summary information (first event, last event, total count).\n *\n * For small result sets, consider using {@link query_array} instead.\n *\n * @param query - The query filter\n * @param query.stream - Filter by stream ID\n * @param query.name - Filter by event name\n * @param query.after - Filter events after this event ID\n * @param query.before - Filter events before this event ID\n * @param query.created_after - Filter events after this timestamp\n * @param query.created_before - Filter events before this timestamp\n * @param query.limit - Maximum number of events to return\n * @param callback - Optional callback invoked for each matching event\n * @returns Object with first event, last event, and total count\n *\n * @example Query all events for a stream\n * ```typescript\n * const { first, last, count } = await app.query(\n * { stream: \"counter-1\" },\n * (event) => console.log(event.name, event.data)\n * );\n * console.log(`Found ${count} events from ${first?.id} to ${last?.id}`);\n * ```\n *\n * @example Query specific event types\n * ```typescript\n * const { count } = await app.query(\n * { name: \"UserCreated\", limit: 100 },\n * (event) => {\n * console.log(\"User created:\", event.data.email);\n * }\n * );\n * ```\n *\n * @example Query events in time range\n * ```typescript\n * const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000);\n * const { count } = await app.query({\n * created_after: yesterday,\n * stream: \"user-123\"\n * });\n * console.log(`User had ${count} events in last 24 hours`);\n * ```\n *\n * @see {@link query_array} for loading events into memory\n */\n async query(\n query: Query,\n callback?: (event: Committed<E, keyof E>) => void\n ): Promise<{\n first?: Committed<E, keyof E>;\n last?: Committed<E, keyof E>;\n count: number;\n }> {\n let first: Committed<E, keyof E> | undefined = undefined,\n last: Committed<E, keyof E> | undefined = undefined;\n const count = await store().query<E>((e) => {\n !first && (first = e);\n last = e;\n callback && callback(e);\n }, query);\n return { first, last, count };\n }\n\n /**\n * Queries the event store and returns all matching events in memory.\n *\n * **Use with caution** - this loads all results into memory. For large result sets,\n * use {@link query} with a callback instead to process events incrementally.\n *\n * @param query - The query filter (same as {@link query})\n * @returns Array of all matching events\n *\n * @example Load all events for a stream\n * ```typescript\n * const events = await app.query_array({ stream: \"counter-1\" });\n * console.log(`Loaded ${events.length} events`);\n * events.forEach(event => console.log(event.name, event.data));\n * ```\n *\n * @example Get recent events\n * ```typescript\n * const recent = await app.query_array({\n * stream: \"user-123\",\n * limit: 10\n * });\n * ```\n *\n * @see {@link query} for large result sets\n */\n async query_array(query: Query): Promise<Committed<E, keyof E>[]> {\n const events: Committed<E, keyof E>[] = [];\n await store().query<E>((e) => events.push(e), query);\n return events;\n }\n\n /**\n * Handles leased reactions.\n *\n * This is called by the main `drain` loop after fetching new events.\n * It handles reactions, supporting retries, blocking, and error handling.\n *\n * @internal\n * @param lease The lease to handle\n * @param payloads The reactions to handle\n * @returns The lease with results\n */\n private async handle(\n lease: Lease,\n payloads: ReactionPayload<E>[]\n ): Promise<{\n readonly lease: Lease;\n readonly handled: number;\n readonly at: number;\n readonly error?: string;\n readonly block?: boolean;\n }> {\n // no payloads, just advance the lease\n if (payloads.length === 0) return { lease, handled: 0, at: lease.at };\n\n const stream = lease.stream;\n let at = payloads.at(0)!.event.id,\n handled = 0;\n\n lease.retry > 0 &&\n logger.warn(`Retrying ${stream}@${at} (${lease.retry}).`);\n\n for (const payload of payloads) {\n const { event, handler, options } = payload;\n try {\n await handler(event, stream, this); // the actual reaction\n at = event.id;\n handled++;\n } catch (error) {\n logger.error(error);\n const block = lease.retry >= options.maxRetries && options.blockOnError;\n block &&\n logger.error(`Blocking ${stream} after ${lease.retry} retries.`);\n return {\n lease,\n handled,\n at,\n // only report error when nothing was handled\n error: handled === 0 ? (error as Error).message : undefined,\n block,\n };\n }\n }\n return { lease, handled, at };\n }\n\n /**\n * Processes pending reactions by draining uncommitted events from the event store.\n *\n * The drain process:\n * 1. Polls the store for streams with uncommitted events\n * 2. Leases streams to prevent concurrent processing\n * 3. Fetches events for each leased stream\n * 4. Executes matching reaction handlers\n * 5. Acknowledges successful reactions or blocks failing ones\n *\n * Drain uses a dual-frontier strategy to balance processing of new streams (lagging)\n * vs active streams (leading). The ratio adapts based on event pressure.\n *\n * Call this method periodically in a background loop, or after committing events.\n *\n * @param options - Drain configuration options\n * @param options.streamLimit - Maximum number of streams to process per cycle (default: 10)\n * @param options.eventLimit - Maximum events to fetch per stream (default: 10)\n * @param options.leaseMillis - Lease duration in milliseconds (default: 10000)\n * @returns Drain statistics with fetched, leased, acked, and blocked counts\n *\n * @example Basic drain loop\n * ```typescript\n * // Process reactions after each action\n * await app.do(\"createUser\", target, payload);\n * await app.drain();\n * ```\n *\n * @example Background drain worker\n * ```typescript\n * setInterval(async () => {\n * try {\n * const result = await app.drain({\n * streamLimit: 20,\n * eventLimit: 50\n * });\n * if (result.acked.length) {\n * console.log(`Processed ${result.acked.length} streams`);\n * }\n * } catch (error) {\n * console.error(\"Drain error:\", error);\n * }\n * }, 5000); // Every 5 seconds\n * ```\n *\n * @example With lifecycle listeners\n * ```typescript\n * app.on(\"acked\", (leases) => {\n * console.log(`Acknowledged ${leases.length} streams`);\n * });\n *\n * app.on(\"blocked\", (blocked) => {\n * console.error(`Blocked ${blocked.length} streams due to errors`);\n * blocked.forEach(({ stream, error }) => {\n * console.error(`Stream ${stream}: ${error}`);\n * });\n * });\n *\n * await app.drain();\n * ```\n *\n * @see {@link correlate} for dynamic stream discovery\n * @see {@link start_correlations} for automatic correlation\n */\n async drain({\n streamLimit = 10,\n eventLimit = 10,\n leaseMillis = 10_000,\n }: DrainOptions = {}): Promise<Drain<E>> {\n if (!this._drain_locked) {\n try {\n this._drain_locked = true;\n const lagging = Math.ceil(streamLimit * this._drain_lag2lead_ratio);\n const leading = streamLimit - lagging;\n const polled = await store().poll(lagging, leading);\n const fetched = await Promise.all(\n polled.map(async ({ stream, source, at, lagging }) => {\n const events = await this.query_array({\n stream: source,\n after: at,\n limit: eventLimit,\n });\n return { stream, source, at, lagging, events } as const;\n })\n );\n if (fetched.length) {\n tracer.fetched(fetched);\n\n const leases = new Map<\n string,\n { lease: Lease; payloads: ReactionPayload<E>[] }\n >();\n\n // compute fetch window max event id\n const fetch_window_at = fetched.reduce(\n (max, { at, events }) => Math.max(max, events.at(-1)?.id || at),\n 0\n );\n\n fetched.forEach(({ stream, lagging, events }) => {\n const payloads = events.flatMap((event) => {\n const register = this.registry.events[event.name];\n if (!register) return [];\n return [...register.reactions.values()]\n .filter((reaction) => {\n const resolved =\n typeof reaction.resolver === \"function\"\n ? reaction.resolver(event)\n : reaction.resolver;\n return resolved && resolved.target === stream;\n })\n .map((reaction) => ({ ...reaction, event }));\n });\n leases.set(stream, {\n lease: {\n stream,\n by: randomUUID(),\n at: events.at(-1)?.id || fetch_window_at, // ff when no matching events\n retry: 0,\n lagging,\n },\n payloads: payloads as ReactionPayload<E>[],\n });\n });\n\n const leased = await store().lease(\n [...leases.values()].map(({ lease }) => lease),\n leaseMillis\n );\n tracer.leased(leased);\n\n const handled = await Promise.all(\n leased.map((lease) =>\n this.handle(lease, leases.get(lease.stream)!.payloads)\n )\n );\n\n // adaptive drain ratio based on handled events, favors frontier with highest pressure (clamped between 20% and 80%)\n const [lagging_handled, leading_handled] = handled.reduce(\n ([lagging_handled, leading_handled], { lease, handled }) => [\n lagging_handled + (lease.lagging ? handled : 0),\n leading_handled + (lease.lagging ? 0 : handled),\n ],\n [0, 0]\n );\n const lagging_avg = lagging > 0 ? lagging_handled / lagging : 0;\n const leading_avg = leading > 0 ? leading_handled / leading : 0;\n const total = lagging_avg + leading_avg;\n this._drain_lag2lead_ratio =\n total > 0 ? Math.max(0.2, Math.min(0.8, lagging_avg / total)) : 0.5;\n\n const acked = await store().ack(\n handled\n .filter(({ error }) => !error)\n .map(({ at, lease }) => ({ ...lease, at }))\n );\n if (acked.length) {\n tracer.acked(acked);\n this.emit(\"acked\", acked);\n }\n\n const blocked = await store().block(\n handled\n .filter(({ block }) => block)\n .map(({ lease, error }) => ({ ...lease, error: error! }))\n );\n if (blocked.length) {\n tracer.blocked(blocked);\n this.emit(\"blocked\", blocked);\n }\n\n return { fetched, leased, acked, blocked };\n }\n } catch (error) {\n logger.error(error);\n } finally {\n this._drain_locked = false;\n }\n }\n\n return { fetched: [], leased: [], acked: [], blocked: [] };\n }\n\n /**\n * Discovers and registers new streams dynamically based on reaction resolvers.\n *\n * Correlation enables \"dynamic reactions\" where target streams are determined at runtime\n * based on event content. For example, you might create a stats stream for each user\n * when they perform certain actions.\n *\n * This method scans events matching the query and identifies new target streams based\n * on reaction resolvers. It then registers these streams so they'll be picked up by\n * the next drain cycle.\n *\n * @param query - Query filter to scan for new correlations\n * @param query.after - Start scanning after this event ID (default: -1)\n * @param query.limit - Maximum events to scan (default: 10)\n * @returns Object with newly leased streams and last scanned event ID\n *\n * @example Manual correlation\n * ```typescript\n * // Scan for new streams\n * const { leased, last_id } = await app.correlate({ after: 0, limit: 100 });\n * console.log(`Found ${leased.length} new streams`);\n *\n * // Save last_id for next scan\n * await saveCheckpoint(last_id);\n * ```\n *\n * @example Dynamic stream creation\n * ```typescript\n * const app = act()\n * .withState(User)\n * .withState(UserStats)\n * .on(\"UserLoggedIn\")\n * .do(async (event) => [\"incrementLoginCount\", {}])\n * .to((event) => ({\n * target: `stats-${event.stream}` // Dynamic target per user\n * }))\n * .build();\n *\n * // Discover stats streams as users log in\n * await app.correlate();\n * ```\n *\n * @see {@link start_correlations} for automatic periodic correlation\n * @see {@link stop_correlations} to stop automatic correlation\n */\n async correlate(\n query: Query = { after: -1, limit: 10 }\n ): Promise<{ leased: Lease[]; last_id: number }> {\n const correlated = new Map<string, ReactionPayload<E>[]>();\n let last_id = query.after || -1;\n await store().query<E>((event) => {\n last_id = event.id;\n const register = this.registry.events[event.name];\n // skip events with no registered reactions\n if (register) {\n for (const reaction of register.reactions.values()) {\n const resolved =\n typeof reaction.resolver === \"function\"\n ? reaction.resolver(event)\n : reaction.resolver;\n resolved &&\n (\n correlated.get(resolved.target) ||\n correlated.set(resolved.target, []).get(resolved.target)!\n ).push({ ...reaction, source: resolved.source, event });\n }\n }\n }, query);\n if (correlated.size) {\n const leases = [...correlated.entries()].map(([stream, payloads]) => ({\n stream,\n // TODO: by convention, the first defined source wins (this can be tricky)\n source: payloads.find((p) => p.source)?.source || undefined,\n by: randomUUID(),\n at: 0,\n retry: 0,\n lagging: true,\n payloads,\n }));\n // register leases with 0ms lease timeout (just to tag the new streams)\n const leased = await store().lease(leases, 0);\n leased.length && tracer.correlated(leased);\n return { leased, last_id };\n }\n return { leased: [], last_id };\n }\n\n /**\n * Starts automatic periodic correlation worker for discovering new streams.\n *\n * The correlation worker runs in the background, scanning for new events and identifying\n * new target streams based on reaction resolvers. It maintains a sliding window that\n * advances with each scan, ensuring all events are eventually correlated.\n *\n * This is useful for dynamic stream creation patterns where you don't know all streams\n * upfront - they're discovered as events arrive.\n *\n * **Note:** Only one correlation worker can run at a time per Act instance.\n *\n * @param query - Query filter for correlation scans\n * @param query.after - Initial starting point (default: -1, start from beginning)\n * @param query.limit - Events to scan per cycle (default: 100)\n * @param frequency - Correlation frequency in milliseconds (default: 10000)\n * @param callback - Optional callback invoked with newly discovered streams\n * @returns `true` if worker started, `false` if already running\n *\n * @example Start automatic correlation\n * ```typescript\n * // Start correlation worker scanning every 5 seconds\n * app.start_correlations(\n * { after: 0, limit: 100 },\n * 5000,\n * (leased) => {\n * console.log(`Discovered ${leased.length} new streams`);\n * }\n * );\n *\n * // Later, stop it\n * app.stop_correlations();\n * ```\n *\n * @example With checkpoint persistence\n * ```typescript\n * // Load last checkpoint\n * const lastId = await loadCheckpoint();\n *\n * app.start_correlations(\n * { after: lastId, limit: 100 },\n * 10000,\n * async (leased) => {\n * // Save checkpoint for next restart\n * if (leased.length) {\n * const maxId = Math.max(...leased.map(l => l.at));\n * await saveCheckpoint(maxId);\n * }\n * }\n * );\n * ```\n *\n * @see {@link correlate} for manual one-time correlation\n * @see {@link stop_correlations} to stop the worker\n */\n start_correlations(\n query: Query = {},\n frequency = 10_000,\n callback?: (leased: Lease[]) => void\n ): boolean {\n if (this._correlation_interval) return false;\n\n const limit = query.limit || 100;\n let after = query.after || -1;\n this._correlation_interval = setInterval(\n () =>\n this.correlate({ ...query, after, limit })\n .then((result) => {\n after = result.last_id;\n if (callback && result.leased.length) callback(result.leased);\n })\n .catch(console.error),\n frequency\n );\n return true;\n }\n\n /**\n * Stops the automatic correlation worker.\n *\n * Call this to stop the background correlation worker started by {@link start_correlations}.\n * This is automatically called when the Act instance is disposed.\n *\n * @example\n * ```typescript\n * // Start correlation\n * app.start_correlations();\n *\n * // Later, stop it\n * app.stop_correlations();\n * ```\n *\n * @see {@link start_correlations}\n */\n stop_correlations() {\n if (this._correlation_interval) {\n clearInterval(this._correlation_interval);\n this._correlation_interval = undefined;\n }\n }\n}\n","/**\n * @module event-sourcing\n * @category Event Sourcing\n *\n * Utilities for event sourcing, snapshotting, and event store interaction.\n */\n\nimport { randomUUID } from \"crypto\";\nimport { logger, SNAP_EVENT, store } from \"./ports.js\";\nimport { InvariantError } from \"./types/errors.js\";\nimport type {\n Committed,\n Emitted,\n EventMeta,\n Schema,\n Schemas,\n Snapshot,\n State,\n Target,\n} from \"./types/index.js\";\nimport { patch, validate } from \"./utils.js\";\n\n/**\n * Event sourcing utilities for snapshotting, loading, and committing actions/events.\n * Used internally by Act and state machines.\n */\n\n/**\n * Saves a snapshot of the state to the store.\n *\n * Snapshots are used to optimize state reconstruction for aggregates with long event streams.\n *\n * @template S The type of state\n * @template E The type of events\n * @param snapshot The snapshot to save\n * @returns Promise that resolves when the snapshot is saved\n *\n * @example\n * await snap(snapshot);\n */\nexport async function snap<S extends Schema, E extends Schemas>(\n snapshot: Snapshot<S, E>\n): Promise<void> {\n try {\n const { id, stream, name, meta, version } = snapshot.event!;\n const snapped = await store().commit(\n stream,\n [{ name: SNAP_EVENT, data: snapshot.state }],\n {\n correlation: meta.correlation,\n causation: { event: { id, name: name as string, stream } },\n },\n version // IMPORTANT! - state events are committed right after the snapshot event\n );\n logger.trace(snapped, \"🟠 snap\");\n } catch (error) {\n logger.error(error);\n }\n}\n\n/**\n * Loads a snapshot of the state from the store by replaying events and applying patches.\n *\n * @template S The type of state\n * @template E The type of events\n * @template A The type of actions\n * @param me The state machine definition\n * @param stream The stream (instance) to load\n * @param callback (Optional) Callback to receive the loaded snapshot as it is built\n * @returns The snapshot of the loaded state\n *\n * @example\n * const snapshot = await load(Counter, \"counter1\");\n */\nexport async function load<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n>(\n me: State<S, E, A>,\n stream: string,\n callback?: (snapshot: Snapshot<S, E>) => void\n): Promise<Snapshot<S, E>> {\n let state = me.init ? me.init() : ({} as S);\n let patches = 0;\n let snaps = 0;\n let event: Committed<E, string> | undefined;\n await store().query(\n (e) => {\n event = e as Committed<E, string>;\n if (e.name === SNAP_EVENT) {\n state = e.data as S;\n snaps++;\n patches = 0;\n } else if (me.patch[e.name]) {\n state = patch(state, me.patch[e.name](event, state));\n patches++;\n }\n callback && callback({ event, state, patches, snaps });\n },\n { stream, with_snaps: true }\n );\n logger.trace(state as object, `🟢 load ${stream}`);\n return { event, state, patches, snaps };\n}\n\n/**\n * Executes an action and emits an event to be committed by the store.\n *\n * This function validates the action, applies business invariants, emits events, and commits them to the event store.\n *\n * @template S The type of state\n * @template E The type of events\n * @template A The type of actionSchemas\n * @template K The type of action to execute\n * @param me The state machine definition\n * @param action The action to execute\n * @param target The target (stream, actor, etc.)\n * @param payload The payload of the action\n * @param reactingTo (Optional) The event that the action is reacting to\n * @param skipValidation (Optional) Whether to skip validation (not recommended)\n * @returns The snapshot of the committed event\n *\n * @example\n * const snapshot = await action(Counter, \"increment\", { stream: \"counter1\", actor }, { by: 1 });\n */\nexport async function action<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n K extends keyof A,\n>(\n me: State<S, E, A>,\n action: K,\n target: Target,\n payload: Readonly<A[K]>,\n reactingTo?: Committed<Schemas, keyof Schemas>,\n skipValidation = false\n): Promise<Snapshot<S, E>[]> {\n const { stream, expectedVersion, actor } = target;\n if (!stream) throw new Error(\"Missing target stream\");\n\n payload = skipValidation\n ? payload\n : validate(action as string, payload, me.actions[action]);\n\n const snapshot = await load(me, stream);\n const expected = expectedVersion || snapshot.event?.version;\n\n logger.trace(\n payload as object,\n `🔵 ${stream}.${action as string}${typeof expected === \"number\" ? `.${expected}` : \"\"}`\n );\n\n if (me.given) {\n const invariants = me.given[action] || [];\n invariants.forEach(({ valid, description }) => {\n if (!valid(snapshot.state, actor))\n throw new InvariantError(\n action,\n payload,\n target,\n snapshot,\n description\n );\n });\n }\n\n const result = me.on[action](payload, snapshot, target);\n if (!result) return [snapshot];\n\n // An empty array means no events were emitted\n if (Array.isArray(result) && result.length === 0) {\n return [snapshot];\n }\n\n const tuples = Array.isArray(result[0])\n ? (result as Emitted<E>[]) // array of tuples\n : ([result] as Emitted<E>[]); // single tuple\n\n const emitted = tuples.map(([name, data]) => ({\n name,\n data: skipValidation\n ? data\n : validate(name as string, data, me.events[name]),\n }));\n\n const meta: EventMeta = {\n correlation: reactingTo?.meta.correlation || randomUUID(),\n causation: {\n action: {\n name: action as string,\n ...target,\n // payload: TODO: flag to include action payload in metadata\n // not included by default to avoid large payloads\n },\n event: reactingTo\n ? {\n id: reactingTo.id,\n name: reactingTo.name,\n stream: reactingTo.stream,\n }\n : undefined,\n },\n };\n\n logger.trace(\n emitted.map((e) => e.data),\n `🔴 commit ${stream}.${emitted.map((e) => e.name).join(\", \")}`\n );\n\n const committed = await store().commit(\n stream,\n emitted,\n meta,\n // TODO: review reactions not enforcing expected version\n reactingTo ? undefined : expected\n );\n\n let { state, patches } = snapshot;\n const snapshots = committed.map((event) => {\n state = patch(state, me.patch[event.name](event, state));\n patches++;\n return { event, state, patches, snaps: snapshot.snaps };\n });\n\n // fire and forget snaps\n const last = snapshots.at(-1)!;\n me.snap && me.snap(last) && void snap(last);\n\n return snapshots;\n}\n","/**\n * @module merge\n * @category Builders\n *\n * Shared utilities for merging partial states and projections across builders.\n */\nimport { ZodObject, type ZodType } from \"zod\";\nimport type { Projection } from \"./projection-builder.js\";\nimport type { Schema, State } from \"./types/index.js\";\n\n/**\n * Unwraps wrapper types (ZodOptional, ZodNullable, ZodDefault, ZodReadonly)\n * to find the base type name, e.g. `z.string().optional()` -> `\"ZodString\"`.\n */\nexport function baseTypeName(zodType: ZodType): string {\n let t: any = zodType;\n while (typeof t.unwrap === \"function\") {\n t = t.unwrap();\n }\n return t.constructor.name;\n}\n\n/**\n * Merges two Zod schemas. If both are ZodObject instances, checks for\n * overlapping shape keys with incompatible base types (throws descriptive\n * error), then merges via `.extend()`. Falls back to keeping existing\n * schema if either is not a ZodObject.\n */\nexport function mergeSchemas(\n existing: ZodType,\n incoming: ZodType,\n stateName: string\n): ZodType {\n if (existing instanceof ZodObject && incoming instanceof ZodObject) {\n const existingShape = existing.shape as Record<string, ZodType>;\n const incomingShape = incoming.shape as Record<string, ZodType>;\n for (const key of Object.keys(incomingShape)) {\n if (key in existingShape) {\n const existingBase = baseTypeName(existingShape[key]);\n const incomingBase = baseTypeName(incomingShape[key]);\n if (existingBase !== incomingBase) {\n throw new Error(\n `Schema conflict in \"${stateName}\": key \"${key}\" has type \"${existingBase}\" but incoming partial declares \"${incomingBase}\"`\n );\n }\n }\n }\n return existing.extend(incomingShape);\n }\n return existing;\n}\n\n/**\n * Merges two init functions by spreading both results together.\n * Each partial only provides its own defaults.\n */\nexport function mergeInits<S extends Schema>(\n existing: () => Readonly<S>,\n incoming: () => Readonly<S>\n): () => Readonly<S> {\n return () => ({ ...existing(), ...incoming() });\n}\n\n/**\n * Registers a state into a states map and action/event registries,\n * merging with existing same-name states (partial state support).\n */\nexport function registerState(\n state: State<any, any, any>,\n states: Map<string, State<any, any, any>>,\n actions: Record<string, any>,\n events: Record<string, any>\n): void {\n if (states.has(state.name)) {\n // MERGE: same state name - combine events, actions, patches, handlers\n const existing = states.get(state.name)!;\n for (const name of Object.keys(state.actions)) {\n // Same schema reference means the same partial re-registered via another slice\n if (existing.actions[name] === state.actions[name]) continue;\n if (actions[name]) throw new Error(`Duplicate action \"${name}\"`);\n }\n for (const name of Object.keys(state.events)) {\n // Same schema reference means the same partial re-registered via another slice\n if (existing.events[name] === state.events[name]) continue;\n if (events[name]) throw new Error(`Duplicate event \"${name}\"`);\n }\n const merged = {\n ...existing,\n state: mergeSchemas(existing.state, state.state, state.name),\n init: mergeInits(existing.init, state.init),\n events: { ...existing.events, ...state.events },\n actions: { ...existing.actions, ...state.actions },\n patch: { ...existing.patch, ...state.patch },\n on: { ...existing.on, ...state.on },\n given: { ...existing.given, ...state.given },\n snap: state.snap || existing.snap,\n };\n states.set(state.name, merged);\n // Update ALL action->state pointers to the merged object\n for (const name of Object.keys(merged.actions)) {\n actions[name] = merged;\n }\n for (const name of Object.keys(state.events)) {\n if (events[name]) continue; // already registered, preserve reactions\n events[name] = {\n schema: state.events[name],\n reactions: new Map(),\n };\n }\n } else {\n // NEW: register state for the first time\n states.set(state.name, state);\n for (const name of Object.keys(state.actions)) {\n if (actions[name]) throw new Error(`Duplicate action \"${name}\"`);\n actions[name] = state;\n }\n for (const name of Object.keys(state.events)) {\n if (events[name]) throw new Error(`Duplicate event \"${name}\"`);\n events[name] = {\n schema: state.events[name],\n reactions: new Map(),\n };\n }\n }\n}\n\n/**\n * Merges a projection's event schemas and reactions into an event registry,\n * deduplicating reaction names by appending \"_p\" on collision.\n */\nexport function mergeProjection(\n proj: Projection<any>,\n events: Record<string, any>\n): void {\n for (const eventName of Object.keys(proj.events)) {\n const projRegister = proj.events[eventName];\n const existing = events[eventName];\n if (!existing) {\n events[eventName] = {\n schema: projRegister.schema,\n reactions: new Map(projRegister.reactions),\n };\n } else {\n for (const [name, reaction] of projRegister.reactions) {\n let key = name;\n while (existing.reactions.has(key)) key = `${key}_p`;\n existing.reactions.set(key, reaction);\n }\n }\n }\n}\n\n// Resolves the event stream as source and target (default)\nexport const _this_ = ({ stream }: { stream: string }) => ({\n source: stream,\n target: stream,\n});\n\n// Resolves to nothing\nexport const _void_ = () => undefined;\n","/**\n * @module act-builder\n * @category Builders\n *\n * Fluent builder for composing event-sourced applications.\n */\nimport { Act } from \"./act.js\";\nimport { _this_, _void_, mergeProjection, registerState } from \"./merge.js\";\nimport type { Projection } from \"./projection-builder.js\";\nimport type { Slice } from \"./slice-builder.js\";\nimport type {\n Committed,\n Dispatcher,\n EventRegister,\n Reaction,\n ReactionHandler,\n ReactionOptions,\n ReactionResolver,\n Registry,\n Schema,\n SchemaRegister,\n Schemas,\n Snapshot,\n State,\n} from \"./types/index.js\";\n\n/**\n * Fluent builder interface for composing event-sourced applications.\n *\n * Provides a chainable API for:\n * - Registering states via `.withState()`\n * - Registering slices via `.withSlice()`\n * - Registering projections via `.withProjection()`\n * - Defining event reactions via `.on()` → `.do()` → `.to()` or `.void()`\n * - Building the orchestrator via `.build()`\n *\n * @template S - Schema register for states (maps action names to state schemas)\n * @template E - Event schemas (maps event names to event data schemas)\n * @template A - Action schemas (maps action names to action payload schemas)\n *\n * @see {@link act} for usage examples\n * @see {@link Act} for the built orchestrator API\n */\nexport type ActBuilder<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n M extends Record<string, Schema> = {},\n> = {\n /**\n * Registers a state definition with the builder.\n *\n * State names, action names, and event names must be unique across the\n * application (partial states with the same name are merged automatically).\n *\n * @throws {Error} If duplicate action or event names are detected\n */\n withState: <\n SX extends Schema,\n EX extends Schemas,\n AX extends Schemas,\n NX extends string = string,\n >(\n state: State<SX, EX, AX, NX>\n ) => ActBuilder<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX,\n M & { [K in NX]: SX }\n >;\n /**\n * Registers a slice with the builder.\n *\n * Merges all the slice's states and reactions into the application.\n * State names, action names, and event names must be unique across the\n * application (partial states with the same name are merged automatically).\n *\n * @throws {Error} If duplicate action or event names are detected\n */\n withSlice: <\n SX extends SchemaRegister<AX>,\n EX extends Schemas,\n AX extends Schemas,\n MX extends Record<string, Schema>,\n >(\n slice: Slice<SX, EX, AX, MX>\n ) => ActBuilder<S & SX, E & EX, A & AX, M & MX>;\n /**\n * Registers a standalone projection with the builder.\n *\n * The projection's events must be a subset of events already registered\n * via `.withState()` or `.withSlice()`.\n */\n withProjection: <EX extends Schemas>(\n projection: [Exclude<keyof EX, keyof E>] extends [never]\n ? Projection<EX>\n : never\n ) => ActBuilder<S, E, A, M>;\n /**\n * Begins defining a reaction to a specific event.\n *\n * Reactions are event handlers that respond to state changes. They can trigger\n * additional actions, update external systems, or perform side effects. Reactions\n * are processed asynchronously during drain cycles.\n *\n * @template K - Event name (must be a registered event)\n * @param event - The event name to react to\n * @returns An object with `.do()` method to define the reaction handler\n */\n on: <K extends keyof E>(\n event: K\n ) => {\n do: (\n handler: (\n event: Committed<E, K>,\n stream: string,\n app: Dispatcher<A>\n ) => Promise<Snapshot<Schema, E> | void>,\n options?: Partial<ReactionOptions>\n ) => ActBuilder<S, E, A, M> & {\n to: (resolver: ReactionResolver<E, K> | string) => ActBuilder<S, E, A, M>;\n void: () => ActBuilder<S, E, A, M>;\n };\n };\n /**\n * Builds and returns the Act orchestrator instance.\n *\n * @param drainLimit - Deprecated parameter, no longer used\n * @returns The Act orchestrator instance\n *\n * @see {@link Act} for available orchestrator methods\n */\n build: (drainLimit?: number) => Act<S, E, A, M>;\n /**\n * The registered event schemas and their reaction maps.\n */\n readonly events: EventRegister<E>;\n};\n\n/* eslint-disable @typescript-eslint/no-empty-object-type -- {} used as generic defaults */\n\n/**\n * Creates a new Act orchestrator builder for composing event-sourced applications.\n *\n * @example Basic application with single state\n * ```typescript\n * const app = act()\n * .withState(Counter)\n * .build();\n * ```\n *\n * @example Application with slices (vertical slice architecture)\n * ```typescript\n * const CounterSlice = slice()\n * .withState(Counter)\n * .on(\"Incremented\")\n * .do(async (event) => { console.log(\"incremented!\"); })\n * .void()\n * .build();\n *\n * const app = act()\n * .withSlice(CounterSlice)\n * .build();\n * ```\n *\n * @see {@link ActBuilder} for available builder methods\n * @see {@link Act} for orchestrator API methods\n * @see {@link state} for defining states\n * @see {@link slice} for defining slices\n */\nexport function act<\n // @ts-expect-error empty schema\n S extends SchemaRegister<A> = {},\n E extends Schemas = {},\n A extends Schemas = {},\n M extends Record<string, Schema> = {},\n>(\n states: Map<string, State<any, any, any>> = new Map(),\n registry: Registry<S, E, A> = {\n actions: {} as Registry<S, E, A>[\"actions\"],\n events: {} as Registry<S, E, A>[\"events\"],\n },\n pendingProjections: Projection<any>[] = []\n): ActBuilder<S, E, A, M> {\n const builder: ActBuilder<S, E, A, M> = {\n withState: <\n SX extends Schema,\n EX extends Schemas,\n AX extends Schemas,\n NX extends string = string,\n >(\n state: State<SX, EX, AX, NX>\n ) => {\n registerState(state, states, registry.actions, registry.events);\n return act<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX,\n M & { [K in NX]: SX }\n >(\n states,\n registry as unknown as Registry<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX\n >,\n pendingProjections\n );\n },\n withSlice: <\n SX extends SchemaRegister<AX>,\n EX extends Schemas,\n AX extends Schemas,\n MX extends Record<string, Schema>,\n >(\n input: Slice<SX, EX, AX, MX>\n ) => {\n for (const s of input.states.values()) {\n registerState(s, states, registry.actions, registry.events);\n }\n for (const eventName of Object.keys(input.events)) {\n const sliceRegister = input.events[eventName];\n for (const [name, reaction] of sliceRegister.reactions) {\n (\n registry.events as Record<\n string,\n { reactions: Map<string, unknown> }\n >\n )[eventName].reactions.set(name, reaction);\n }\n }\n pendingProjections.push(...input.projections);\n return act<S & SX, E & EX, A & AX, M & MX>(\n states,\n registry as unknown as Registry<S & SX, E & EX, A & AX>,\n pendingProjections\n );\n },\n withProjection: <EX extends Schemas>(proj: Projection<EX>) => {\n mergeProjection(proj, registry.events);\n return act<S, E, A, M>(states, registry, pendingProjections);\n },\n on: <K extends keyof E>(event: K) => ({\n do: (\n handler: (\n event: Committed<E, K>,\n stream: string,\n app: Dispatcher<A>\n ) => Promise<Snapshot<Schema, E> | void>,\n options?: Partial<ReactionOptions>\n ) => {\n const reaction: Reaction<E, K, A> = {\n handler: handler as ReactionHandler<E, K, A>,\n resolver: _this_,\n options: {\n blockOnError: options?.blockOnError ?? true,\n maxRetries: options?.maxRetries ?? 3,\n },\n };\n const name =\n handler.name ||\n `${String(event)}_${registry.events[event].reactions.size}`;\n registry.events[event].reactions.set(name, reaction);\n return {\n ...builder,\n to(resolver: ReactionResolver<E, K> | string) {\n registry.events[event].reactions.set(name, {\n ...reaction,\n resolver:\n typeof resolver === \"string\" ? { target: resolver } : resolver,\n });\n return builder;\n },\n void() {\n registry.events[event].reactions.set(name, {\n ...reaction,\n resolver: _void_,\n });\n return builder;\n },\n };\n },\n }),\n build: () => {\n for (const proj of pendingProjections) {\n mergeProjection(proj, registry.events as Record<string, any>);\n }\n return new Act<S, E, A, M>(registry, states);\n },\n events: registry.events,\n };\n return builder;\n}\n","/**\n * @module projection-builder\n * @category Builders\n *\n * Fluent builder for composing projection handlers — read-model updaters\n * that react to events and update external state (databases, caches, etc.).\n *\n * Projections differ from slices: they don't contain states, don't dispatch\n * actions, and are pure side-effect handlers routed to a named stream.\n */\nimport type { ZodType } from \"zod\";\nimport { _this_, _void_ } from \"./merge.js\";\nimport type {\n Committed,\n EventRegister,\n Reaction,\n ReactionHandler,\n ReactionResolver,\n Schema,\n Schemas,\n} from \"./types/index.js\";\n\n/**\n * A self-contained projection grouping read-model update handlers.\n * Projections are composed into an Act orchestrator via `act().withProjection(projection)`.\n *\n * @template E - Event schemas handled by this projection\n */\nexport type Projection<E extends Schemas> = {\n readonly _tag: \"Projection\";\n readonly events: EventRegister<E>;\n};\n\n/** Helper: a single-key record mapping an event name to its Zod schema. */\ntype EventEntry<K extends string = string, D extends Schema = Schema> = {\n [P in K]: ZodType<D>;\n};\n\n/** Infer the handler-result type after registering one event. */\ntype DoResult<\n E extends Schemas,\n K extends string,\n D extends Schema,\n> = ProjectionBuilder<E & { [P in K]: D }> & {\n to: (\n resolver: ReactionResolver<E & { [P in K]: D }, K> | string\n ) => ProjectionBuilder<E & { [P in K]: D }>;\n void: () => ProjectionBuilder<E & { [P in K]: D }>;\n};\n\n/**\n * Fluent builder interface for composing projections.\n *\n * Provides a chainable API for registering event handlers that update\n * read models. Unlike slices, projections have no `.withState()` for states\n * and handlers do not receive a `Dispatcher`.\n *\n * When a default target is provided via `projection(\"target\")`, all\n * handlers inherit that resolver. Per-handler `.to()` or `.void()` can\n * still override it.\n *\n * @template E - Event schemas\n */\nexport type ProjectionBuilder<E extends Schemas> = {\n /**\n * Begins defining a projection handler for a specific event.\n *\n * Pass a `{ EventName: schema }` record — use shorthand `{ EventName }`\n * when the variable name matches the event name. The key becomes the\n * event name, the value the Zod schema.\n */\n on: <K extends string, D extends Schema>(\n entry: EventEntry<K, D>\n ) => {\n do: (\n handler: (\n event: Committed<E & { [P in K]: D }, K>,\n stream: string\n ) => Promise<void>\n ) => DoResult<E, K, D>;\n };\n /**\n * Builds and returns the Projection data structure.\n */\n build: () => Projection<E>;\n /**\n * The registered event schemas and their reaction maps.\n */\n readonly events: EventRegister<E>;\n};\n\n/* eslint-disable @typescript-eslint/no-empty-object-type -- {} used as generic defaults */\n\n/**\n * Creates a new projection builder for composing read-model update handlers.\n *\n * Projections enable separation of read-model concerns from command handling.\n * Each `.on({ Event }).do(handler)` call registers a handler that updates\n * a projection (database table, cache, etc.) in response to events.\n *\n * Pass a target stream name to `projection(\"target\")` so every handler\n * inherits that resolver automatically. Omit it and use per-handler\n * `.to()` / `.void()` when handlers route to different streams.\n *\n * @param target - Optional default target stream for all handlers\n *\n * @example Default target (all handlers routed to \"tickets\")\n * ```typescript\n * const TicketProjection = projection(\"tickets\")\n * .on({ TicketOpened })\n * .do(async ({ stream, data }) => {\n * await db.insert(tickets).values({ id: stream, ...data });\n * })\n * .on({ TicketClosed })\n * .do(async ({ stream, data }) => {\n * await db.update(tickets).set(data).where(eq(tickets.id, stream));\n * })\n * .build();\n * ```\n *\n * @example Per-handler routing\n * ```typescript\n * const MultiProjection = projection()\n * .on({ OrderPlaced })\n * .do(async (event) => { ... })\n * .to(\"orders\")\n * .on({ PaymentReceived })\n * .do(async (event) => { ... })\n * .to(\"payments\")\n * .build();\n * ```\n *\n * @see {@link ProjectionBuilder} for builder methods\n * @see {@link Projection} for the output type\n */\nexport function projection<E extends Schemas = {}>(\n target?: string,\n events: EventRegister<E> = {} as EventRegister<E>\n): ProjectionBuilder<E> {\n const defaultResolver: { target: string } | undefined = target\n ? { target }\n : undefined;\n\n const builder: ProjectionBuilder<E> = {\n on: <K extends string, D extends Schema>(entry: EventEntry<K, D>) => {\n const keys = Object.keys(entry);\n if (keys.length !== 1) throw new Error(\".on() requires exactly one key\");\n const event = keys[0] as K;\n const schema = entry[event];\n\n // Register the event schema if not already present\n if (!(event in events)) {\n (events as Record<string, unknown>)[event] = {\n schema,\n reactions: new Map(),\n };\n }\n\n return {\n do: (\n handler: (\n event: Committed<E & { [P in K]: D }, K>,\n stream: string\n ) => Promise<void>\n ) => {\n const reaction: Reaction<E & { [P in K]: D }, K> = {\n handler: handler as ReactionHandler<E & { [P in K]: D }, K>,\n resolver: defaultResolver ?? _this_,\n options: {\n blockOnError: true,\n maxRetries: 3,\n },\n };\n const register = (events as Record<string, any>)[event];\n const name = handler.name || `${event}_${register.reactions.size}`;\n register.reactions.set(name, reaction);\n\n const nextBuilder = projection<E & { [P in K]: D }>(\n target,\n events as EventRegister<E & { [P in K]: D }>\n );\n return {\n ...nextBuilder,\n to(resolver: ReactionResolver<E & { [P in K]: D }, K> | string) {\n register.reactions.set(name, {\n ...reaction,\n resolver:\n typeof resolver === \"string\"\n ? { target: resolver }\n : resolver,\n });\n return nextBuilder;\n },\n void() {\n register.reactions.set(name, {\n ...reaction,\n resolver: _void_,\n });\n return nextBuilder;\n },\n };\n },\n };\n },\n build: () => ({\n _tag: \"Projection\" as const,\n events,\n }),\n events,\n };\n return builder;\n}\n","/**\n * @module slice-builder\n * @category Builders\n *\n * Fluent builder for composing partial states with scoped reactions into\n * self-contained functional slices (vertical slice architecture).\n */\nimport { _this_, _void_, registerState } from \"./merge.js\";\nimport type { Projection } from \"./projection-builder.js\";\nimport type {\n Committed,\n Dispatcher,\n EventRegister,\n Reaction,\n ReactionHandler,\n ReactionOptions,\n ReactionResolver,\n Schema,\n SchemaRegister,\n Schemas,\n Snapshot,\n State,\n} from \"./types/index.js\";\n\n/**\n * A self-contained functional slice grouping partial states with their\n * scoped reactions. Slices are composed into an Act orchestrator via\n * `act().withSlice(slice)`.\n *\n * @template S - Schema register for states\n * @template E - Event schemas from this slice's states\n * @template A - Action schemas from this slice's states\n * @template M - Map of state names to state schemas\n */\nexport type Slice<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n M extends Record<string, Schema> = {},\n> = {\n readonly _tag: \"Slice\";\n readonly states: Map<string, State<any, any, any>>;\n readonly events: EventRegister<E>;\n readonly projections: ReadonlyArray<Projection<any>>;\n /** @internal phantom field for type-level state schema tracking */\n readonly _S?: S;\n /** @internal phantom field for type-level state name tracking */\n readonly _M?: M;\n};\n\n/**\n * Fluent builder interface for composing functional slices.\n *\n * Provides a chainable API for registering states and projections,\n * and defining reactions scoped to the slice's own events.\n *\n * @template S - Schema register for states\n * @template E - Event schemas\n * @template A - Action schemas\n * @template M - Map of state names to state schemas\n */\nexport type SliceBuilder<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n M extends Record<string, Schema> = {},\n> = {\n /**\n * Registers a state definition with the slice.\n *\n * Include every state whose actions your reaction handlers need to\n * dispatch. Duplicate registrations (same state in multiple slices)\n * are handled automatically at composition time.\n */\n withState: <\n SX extends Schema,\n EX extends Schemas,\n AX extends Schemas,\n NX extends string = string,\n >(\n state: State<SX, EX, AX, NX>\n ) => SliceBuilder<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX,\n M & { [K in NX]: SX }\n >;\n /**\n * Embeds a built Projection within this slice. The projection's events\n * must be a subset of events from states already registered via\n * `.withState()`. Projection handlers preserve their `(event, stream)`\n * signature and do not receive a Dispatcher.\n */\n withProjection: <EP extends Schemas>(\n projection: [Exclude<keyof EP, keyof E>] extends [never]\n ? Projection<EP>\n : never\n ) => SliceBuilder<S, E, A, M>;\n /**\n * Begins defining a reaction scoped to this slice's events.\n */\n on: <K extends keyof E>(\n event: K\n ) => {\n do: (\n handler: (\n event: Committed<E, K>,\n stream: string,\n app: Dispatcher<A>\n ) => Promise<Snapshot<Schema, E> | void>,\n options?: Partial<ReactionOptions>\n ) => SliceBuilder<S, E, A, M> & {\n to: (\n resolver: ReactionResolver<E, K> | string\n ) => SliceBuilder<S, E, A, M>;\n void: () => SliceBuilder<S, E, A, M>;\n };\n };\n /**\n * Builds and returns the Slice data structure.\n */\n build: () => Slice<S, E, A, M>;\n /**\n * The registered event schemas and their reaction maps.\n */\n readonly events: EventRegister<E>;\n};\n\n/* eslint-disable @typescript-eslint/no-empty-object-type -- {} used as generic defaults */\n\n/**\n * Creates a new slice builder for composing partial states with scoped reactions.\n *\n * Slices enable vertical slice architecture by grouping related states and\n * reactions into self-contained feature modules. Reactions defined in a slice\n * are type-scoped to events from that slice's states only.\n *\n * @example Single-state slice with typed dispatch\n * ```typescript\n * const CounterSlice = slice()\n * .withState(Counter)\n * .on(\"Incremented\")\n * .do(async (event, _stream, app) => {\n * await app.do(\"reset\", target, {});\n * })\n * .void()\n * .build();\n * ```\n *\n * @example Cross-state dispatch (include both states)\n * ```typescript\n * const CreationSlice = slice()\n * .withState(TicketCreation)\n * .withState(TicketOperations) // handler can dispatch AssignTicket\n * .on(\"TicketOpened\").do(async (event, _stream, app) => {\n * await app.do(\"AssignTicket\", target, payload, event);\n * })\n * .build();\n * ```\n *\n * @see {@link SliceBuilder} for builder methods\n * @see {@link Slice} for the output type\n */\nexport function slice<\n // @ts-expect-error empty schema\n S extends SchemaRegister<A> = {},\n E extends Schemas = {},\n A extends Schemas = {},\n M extends Record<string, Schema> = {},\n>(\n states: Map<string, State<any, any, any>> = new Map(),\n actions: Record<string, any> = {},\n events: EventRegister<E> = {} as EventRegister<E>,\n projections: Projection<any>[] = []\n): SliceBuilder<S, E, A, M> {\n const builder: SliceBuilder<S, E, A, M> = {\n withState: <\n SX extends Schema,\n EX extends Schemas,\n AX extends Schemas,\n NX extends string = string,\n >(\n state: State<SX, EX, AX, NX>\n ) => {\n registerState(state, states, actions, events as Record<string, unknown>);\n return slice<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX,\n M & { [K in NX]: SX }\n >(\n states,\n actions,\n events as unknown as EventRegister<E & EX>,\n projections\n );\n },\n withProjection: <EP extends Schemas>(proj: Projection<EP>) => {\n projections.push(proj);\n return slice<S, E, A, M>(states, actions, events, projections);\n },\n on: <K extends keyof E>(event: K) => ({\n do: (\n handler: (\n event: Committed<E, K>,\n stream: string,\n app: Dispatcher<A>\n ) => Promise<Snapshot<Schema, E> | void>,\n options?: Partial<ReactionOptions>\n ) => {\n const reaction: Reaction<E, K, A> = {\n handler: handler as ReactionHandler<E, K, A>,\n resolver: _this_,\n options: {\n blockOnError: options?.blockOnError ?? true,\n maxRetries: options?.maxRetries ?? 3,\n },\n };\n const name =\n handler.name || `${String(event)}_${events[event].reactions.size}`;\n events[event].reactions.set(name, reaction);\n return {\n ...builder,\n to(resolver: ReactionResolver<E, K> | string) {\n events[event].reactions.set(name, {\n ...reaction,\n resolver:\n typeof resolver === \"string\" ? { target: resolver } : resolver,\n });\n return builder;\n },\n void() {\n events[event].reactions.set(name, {\n ...reaction,\n resolver: _void_,\n });\n return builder;\n },\n };\n },\n }),\n build: () => ({\n _tag: \"Slice\" as const,\n states,\n events,\n projections,\n }),\n events,\n };\n return builder;\n}\n","/**\n * @module state-builder\n * @category Builders\n *\n * Fluent interface for defining a strongly-typed state machine using Zod schemas.\n */\nimport { ZodType } from \"zod\";\nimport {\n ActionHandler,\n ActionHandlers,\n GivenHandlers,\n Invariant,\n PatchHandlers,\n Schema,\n Schemas,\n Snapshot,\n State,\n ZodTypes,\n} from \"./types/index.js\";\n\n/**\n * Builder interface for defining a state with event sourcing.\n *\n * Provides a fluent API to configure the initial state, event types,\n * and event handlers (reducers) before moving to action configuration.\n *\n * @template S - State schema type\n *\n * @see {@link state} for usage examples\n * @see {@link ActionBuilder} for action configuration\n */\nexport type StateBuilder<S extends Schema, N extends string = string> = {\n /**\n * Defines the initial state for new state instances.\n *\n * The init function is called when a new stream is created (first event).\n * It can accept initial data or return a default state.\n *\n * @param init - Function returning the initial state\n * @returns A builder with `.emits()` to declare event types\n *\n * @example\n * ```typescript\n * .init(() => ({ count: 0, created: new Date() }))\n * ```\n *\n * @example With initial data\n * ```typescript\n * .init((data) => ({ ...data, createdAt: new Date() }))\n * ```\n */\n init: (init: () => Readonly<S>) => {\n /**\n * Declares the event types that this state can emit.\n *\n * Events represent facts that have happened - they should be named in past tense.\n * Each event is defined with a Zod schema for type safety and runtime validation.\n *\n * @template E - Event schemas type\n * @param events - Object mapping event names to Zod schemas\n * @returns A builder with `.patch()` to define event handlers\n *\n * @example\n * ```typescript\n * .emits({\n * Incremented: z.object({ amount: z.number() }),\n * Decremented: z.object({ amount: z.number() }),\n * Reset: z.object({})\n * })\n * ```\n */\n emits: <E extends Schemas>(\n events: ZodTypes<E>\n ) => {\n /**\n * Defines how each event updates (patches) the state.\n *\n * Patch handlers are reducers - pure functions that take an event and current state,\n * and return the changes to apply. Return partial state objects; unchanged fields\n * are preserved automatically.\n *\n * @param patch - Object mapping event names to patch handler functions\n * @returns An ActionBuilder for defining actions\n *\n * @example\n * ```typescript\n * .patch({\n * Incremented: (event, state) => ({ count: state.count + event.data.amount }),\n * Decremented: (event, state) => ({ count: state.count - event.data.amount }),\n * Reset: () => ({ count: 0 })\n * })\n * ```\n */\n patch: (\n patch: PatchHandlers<S, E>\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- {} avoids string index signature that Record<string, never> would add, keeping keyof A precise\n ) => ActionBuilder<S, E, {}, N>;\n };\n };\n};\n\n/** Helper: a single-key record mapping a state name to its Zod schema. */\ntype StateEntry<K extends string = string, S extends Schema = Schema> = {\n [P in K]: ZodType<S>;\n};\n\n/** Helper: a single-key record mapping an action name to its Zod schema. */\ntype ActionEntry<K extends string = string, AX extends Schema = Schema> = {\n [P in K]: ZodType<AX>;\n};\n\n/**\n * Builder interface for defining actions (commands) on a state.\n *\n * Actions represent user/system intents to modify state. Each action is validated\n * against a schema, can have business rule invariants, and must emit one or more events.\n *\n * @template S - State schema type\n * @template E - Event schemas type\n * @template A - Action schemas type\n *\n * @see {@link state} for complete usage examples\n */\nexport type ActionBuilder<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n N extends string = string,\n> = {\n /**\n * Defines an action (command) that can be executed on this state.\n *\n * Actions represent intents to change state - they should be named in imperative form\n * (e.g., \"CreateUser\", \"IncrementCounter\", \"PlaceOrder\"). Actions are validated against\n * their schema and must emit at least one event.\n *\n * Pass a `{ ActionName: schema }` record — use shorthand `{ ActionName }`\n * when the variable name matches the action name. The key becomes the\n * action name, the value the Zod schema.\n *\n * @template K - Action name (string literal type)\n * @template AX - Action payload schema type\n * @param entry - Single-key record `{ ActionName: schema }`\n * @returns An object with `.given()` and `.emit()` for further configuration\n *\n * @example Simple action without invariants\n * ```typescript\n * .on({ increment: z.object({ by: z.number() }) })\n * .emit((action) => [\"Incremented\", { amount: action.by }])\n * ```\n *\n * @example Action with business rules\n * ```typescript\n * .on({ withdraw: z.object({ amount: z.number() }) })\n * .given([\n * (_, snap) => snap.state.balance >= 0 || \"Account closed\",\n * (_, snap, action) => snap.state.balance >= action.amount || \"Insufficient funds\"\n * ])\n * .emit((action) => [\"Withdrawn\", { amount: action.amount }])\n * ```\n *\n * @example Action with shorthand (variable name matches action name)\n * ```typescript\n * const OpenTicket = z.object({ title: z.string() });\n * .on({ OpenTicket })\n * .emit((action) => [\"TicketOpened\", { title: action.title }])\n * ```\n */\n on: <K extends string, AX extends Schema>(\n entry: ActionEntry<K, AX>\n ) => {\n /**\n * Adds business rule invariants that must hold before the action can execute.\n *\n * Invariants are checked after loading the current state but before emitting events.\n * Each invariant should return `true` or an error message string. All invariants\n * must pass for the action to succeed.\n *\n * @param rules - Array of invariant functions\n * @returns An object with `.emit()` to finalize the action\n *\n * @example\n * ```typescript\n * .given([\n * (_, snap) => snap.state.status === \"active\" || \"Must be active\",\n * (target, snap) => snap.state.ownerId === target.actor.id || \"Not authorized\"\n * ])\n * ```\n */\n given: (rules: Invariant<S>[]) => {\n /**\n * Defines the action handler that emits events.\n *\n * The handler receives the action payload and current state snapshot,\n * and must return one or more events to emit. Events are applied to state\n * via the patch handlers defined earlier.\n *\n * @param handler - Function that returns events to emit\n * @returns The ActionBuilder for chaining more actions\n *\n * @example\n * ```typescript\n * .emit((action, snapshot) => {\n * const newBalance = snapshot.state.balance + action.amount;\n * return [\"Deposited\", { amount: action.amount, newBalance }];\n * })\n * ```\n */\n emit: (\n handler: ActionHandler<S, E, { [P in K]: AX }, K>\n ) => ActionBuilder<S, E, A & { [P in K]: AX }, N>;\n };\n /**\n * Defines the action handler that emits events.\n *\n * The handler receives the action payload and current state snapshot,\n * and must return one or more events to emit. Return a single event as\n * `[\"EventName\", data]` or multiple events as an array of event tuples.\n *\n * @param handler - Function that returns events to emit\n * @returns The ActionBuilder for chaining more actions\n *\n * @example Single event\n * ```typescript\n * .emit((action) => [\"Incremented\", { amount: action.by }])\n * ```\n *\n * @example Multiple events\n * ```typescript\n * .emit((action) => [\n * [\"Incremented\", { amount: action.by }],\n * [\"LogUpdated\", { message: `Incremented by ${action.by}` }]\n * ])\n * ```\n *\n * @example Conditional events\n * ```typescript\n * .emit((action, snapshot) => {\n * if (snapshot.state.count + action.by >= 100) {\n * return [\n * [\"Incremented\", { amount: action.by }],\n * [\"MilestoneReached\", { milestone: 100 }]\n * ];\n * }\n * return [\"Incremented\", { amount: action.by }];\n * })\n * ```\n */\n emit: (\n handler: ActionHandler<S, E, { [P in K]: AX }, K>\n ) => ActionBuilder<S, E, A & { [P in K]: AX }, N>;\n };\n /**\n * Defines a snapshotting strategy to optimize state reconstruction.\n *\n * Snapshots store the current state at a point in time, allowing faster state loading\n * by avoiding replaying all events from the beginning. The snap function is called\n * after each event is applied and should return `true` when a snapshot should be taken.\n *\n * @param snap - Predicate function that returns true when a snapshot should be taken\n * @returns The ActionBuilder for chaining\n *\n * @example Snapshot every 10 events\n * ```typescript\n * .snap((snapshot) => snapshot.patches >= 10)\n * ```\n *\n * @example Snapshot based on state size\n * ```typescript\n * .snap((snapshot) => {\n * const estimatedSize = JSON.stringify(snapshot.state).length;\n * return estimatedSize > 10000 || snapshot.patches >= 50;\n * })\n * ```\n *\n * @example Time-based snapshotting\n * ```typescript\n * .snap((snapshot) => {\n * const hoursSinceLastSnapshot = snapshot.patches * 0.1; // Estimate\n * return hoursSinceLastSnapshot >= 24;\n * })\n * ```\n */\n snap: (\n snap: (snapshot: Snapshot<S, E>) => boolean\n ) => ActionBuilder<S, E, A, N>;\n /**\n * Finalizes and builds the state definition.\n *\n * Call this method after defining all actions, invariants, and patches to create\n * the complete State object that can be registered with Act.\n *\n * @returns The complete strongly-typed State definition\n *\n * @example\n * ```typescript\n * const Counter = state({ Counter: schema })\n * .init(() => ({ count: 0 }))\n * .emits({ Incremented: z.object({ amount: z.number() }) })\n * .patch({ Incremented: (event, state) => ({ count: state.count + event.data.amount }) })\n * .on({ increment: z.object({ by: z.number() }) })\n * .emit((action) => [\"Incremented\", { amount: action.by }])\n * .build(); // Returns State<S, E, A, N>\n * ```\n */\n build: () => State<S, E, A, N>;\n};\n\n/**\n * Creates a new state definition with event sourcing capabilities.\n *\n * States are the core building blocks of Act. Each state represents a consistency\n * boundary (aggregate) that processes actions, emits events, and maintains its own\n * state through event patches (reducers). States use event sourcing to maintain a\n * complete audit trail and enable time-travel capabilities.\n *\n * The state builder provides a fluent API for defining:\n * 1. Initial state via `.init()`\n * 2. Event types via `.emits()`\n * 3. Event handlers (reducers) via `.patch()`\n * 4. Actions (commands) via `.on()` → `.emit()`\n * 5. Business rules (invariants) via `.given()`\n * 6. Snapshotting strategy via `.snap()`\n *\n * @template S - Zod schema type defining the shape of the state\n * @param entry - Single-key record mapping state name to Zod schema (e.g., `{ Counter: z.object({ count: z.number() }) }`)\n * @returns A StateBuilder instance for fluent API configuration\n *\n * @example Basic counter state\n * ```typescript\n * import { state } from \"@rotorsoft/act\";\n * import { z } from \"zod\";\n *\n * const Counter = state({ Counter: z.object({ count: z.number() }) })\n * .init(() => ({ count: 0 }))\n * .emits({\n * Incremented: z.object({ amount: z.number() })\n * })\n * .patch({\n * Incremented: (event, state) => ({ count: state.count + event.data.amount })\n * })\n * .on({ increment: z.object({ by: z.number() }) })\n * .emit((action) => [\"Incremented\", { amount: action.by }])\n * .build();\n * ```\n *\n * @example State with multiple events and invariants\n * ```typescript\n * const BankAccount = state({ BankAccount: z.object({\n * balance: z.number(),\n * currency: z.string(),\n * status: z.enum([\"open\", \"closed\"])\n * }) })\n * .init(() => ({ balance: 0, currency: \"USD\", status: \"open\" }))\n * .emits({\n * Deposited: z.object({ amount: z.number() }),\n * Withdrawn: z.object({ amount: z.number() }),\n * Closed: z.object({})\n * })\n * .patch({\n * Deposited: (event, state) => ({ balance: state.balance + event.data.amount }),\n * Withdrawn: (event, state) => ({ balance: state.balance - event.data.amount }),\n * Closed: () => ({ status: \"closed\", balance: 0 })\n * })\n * .on({ deposit: z.object({ amount: z.number() }) })\n * .given([\n * (_, snap) => snap.state.status === \"open\" || \"Account must be open\"\n * ])\n * .emit((action) => [\"Deposited\", { amount: action.amount }])\n * .on({ withdraw: z.object({ amount: z.number() }) })\n * .given([\n * (_, snap) => snap.state.status === \"open\" || \"Account must be open\",\n * (_, snap, action) =>\n * snap.state.balance >= action.amount || \"Insufficient funds\"\n * ])\n * .emit((action) => [\"Withdrawn\", { amount: action.amount }])\n * .on({ close: z.object({}) })\n * .given([\n * (_, snap) => snap.state.status === \"open\" || \"Already closed\",\n * (_, snap) => snap.state.balance === 0 || \"Balance must be zero\"\n * ])\n * .emit(() => [\"Closed\", {}])\n * .build();\n * ```\n *\n * @example State with snapshotting\n * ```typescript\n * const User = state({ User: z.object({\n * name: z.string(),\n * email: z.string(),\n * loginCount: z.number()\n * }) })\n * .init((data) => ({ ...data, loginCount: 0 }))\n * .emits({\n * UserCreated: z.object({ name: z.string(), email: z.string() }),\n * UserLoggedIn: z.object({})\n * })\n * .patch({\n * UserCreated: (event) => event.data,\n * UserLoggedIn: (_, state) => ({ loginCount: state.loginCount + 1 })\n * })\n * .on({ createUser: z.object({ name: z.string(), email: z.string() }) })\n * .emit((action) => [\"UserCreated\", action])\n * .on({ login: z.object({}) })\n * .emit(() => [\"UserLoggedIn\", {}])\n * .snap((snap) => snap.patches >= 10) // Snapshot every 10 events\n * .build();\n * ```\n *\n * @see {@link StateBuilder} for available builder methods\n * @see {@link ActionBuilder} for action configuration methods\n * @see {@link https://rotorsoft.github.io/act-root/docs/intro | Getting Started Guide}\n * @see {@link https://rotorsoft.github.io/act-root/docs/examples/calculator | Calculator Example}\n */\nexport function state<N extends string, S extends Schema>(\n entry: StateEntry<N, S>\n): StateBuilder<S, N> {\n const keys = Object.keys(entry);\n if (keys.length !== 1) throw new Error(\"state() requires exactly one key\");\n const name = keys[0] as N;\n const stateSchema = (entry as Record<string, ZodType<S>>)[name];\n return {\n init(init: () => Readonly<S>) {\n return {\n emits<E extends Schema>(events: ZodTypes<E>) {\n return {\n patch(patch: PatchHandlers<S, E>) {\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- {} avoids string index signature\n return action_builder<S, E, {}, N>({\n events,\n actions: {},\n state: stateSchema,\n name,\n init,\n patch,\n on: {},\n });\n },\n };\n },\n };\n },\n };\n}\n\nfunction action_builder<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n N extends string = string,\n>(state: State<S, E, A, N>): ActionBuilder<S, E, A, N> {\n return {\n on<K extends string, AX extends Schema>(entry: ActionEntry<K, AX>) {\n const keys = Object.keys(entry);\n if (keys.length !== 1) throw new Error(\".on() requires exactly one key\");\n const action = keys[0] as K;\n const schema = entry[action];\n\n if (action in state.actions)\n throw new Error(`Duplicate action \"${action}\"`);\n\n type NewA = A & { [P in K]: AX };\n const actions = { ...state.actions, [action]: schema } as ZodTypes<NewA>;\n const on = { ...state.on } as ActionHandlers<S, E, NewA>;\n const _given = { ...state.given } as GivenHandlers<S, NewA>;\n\n function given(rules: Invariant<S>[]) {\n _given[action] = rules;\n return { emit };\n }\n\n function emit(handler: ActionHandler<S, E, NewA, K>) {\n on[action] = handler;\n return action_builder<S, E, NewA, N>({\n ...state,\n actions,\n on,\n given: _given,\n });\n }\n\n return { given, emit };\n },\n\n snap(snap: (snapshot: Snapshot<S, E>) => boolean) {\n return action_builder<S, E, A, N>({ ...state, snap });\n },\n\n build(): State<S, E, A, N> {\n return state;\n },\n };\n}\n"],"mappings":"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","names":["action","z","z","pkg","a","b","store","logLevel","stream","randomUUID","state","action","action","lagging","randomUUID","lagging_handled","leading_handled","handled","ZodObject","state","state","state","patch","state","action","snap"]}