@rotorsoft/act 0.6.20 → 0.6.22

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../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/act-builder.ts","../src/state-builder.ts"],"sourcesContent":["import \"./signals.js\";\n\n/**\n * @packageDocumentation\n * @module act\n * Main entry point for the Act framework. Re-exports all core APIs.\n */\nexport * from \"./act-builder.js\";\nexport * from \"./act.js\";\nexport * from \"./config.js\";\nexport * from \"./ports.js\";\nexport * from \"./state-builder.js\";\nexport * from \"./types/index.js\";\nexport * from \"./utils.js\";\n","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 disposers that are triggered on process exit.\n *\n * @param disposer The disposer function to register\n * @returns A function that triggers all registered disposers and terminates the process\n *\n * @example\n * dispose(async () => { await myResource.close(); });\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 * Singleton event store port. By default, uses the in-memory store.\n *\n * You can inject a persistent store (e.g., Postgres) by calling `store(myAdapter)`.\n *\n * @example\n * const myStore = store();\n * const customStore = store(new MyCustomStore());\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 a payload fails schema validation.\n * @param target - The name of the target being validated (e.g., event, action).\n * @param payload - The invalid payload.\n * @param details - Additional validation error details.\n * @example\n * throw new ValidationError('event', payload, zodError);\n */\nexport class ValidationError extends Error {\n constructor(\n public readonly target: string,\n public readonly payload: any,\n public readonly details: any\n ) {\n super(`Invalid ${target} payload`);\n this.name = Errors.ValidationError;\n }\n}\n\n/**\n * Thrown when a state invariant is violated after an action or event.\n * @param name - The name of the invariant or action.\n * @param payload - The state or payload that failed the invariant.\n * @param target - The target context (e.g., stream, actor).\n * @param description - Description of the invariant.\n * @example\n * throw new InvariantError('balanceNonNegative', state, target, 'Balance must be >= 0');\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 readonly action: K,\n readonly payload: Readonly<A[K]>,\n readonly target: Target,\n readonly snapshot: Snapshot<S, E>,\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 an optimistic concurrency check fails during event commit.\n * @param lastVersion - The last known version in the stream.\n * @param events - The events being committed.\n * @param expectedVersion - The expected version for the commit.\n * @example\n * throw new ConcurrencyError(2, events, 1);\n */\nexport class ConcurrencyError extends Error {\n constructor(\n public readonly stream: string,\n public readonly lastVersion: number,\n public readonly events: Message<Schemas, keyof Schemas>[],\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 copies state with patches recursively.\n *\n * Keys with `undefined` or `null` values in patch are deleted.\n *\n * @param original The original state object\n * @param patches The patches to merge\n * @returns A new patched state\n *\n * @example\n * const newState = patch(oldState, { count: 5 });\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, throwing a ValidationError on failure.\n *\n * @param target The name of the target (for error reporting)\n * @param payload The payload to validate\n * @param schema (Optional) The Zod schema to validate against\n * @returns The validated payload\n * @throws ValidationError if validation fails\n *\n * @example\n * const valid = validate(\"User\", userPayload, userSchema);\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 * Extends the target payload with the source payload after validating the source.\n *\n * @param source The source object to validate and merge\n * @param schema The Zod schema for the source\n * @param target (Optional) The target object to extend\n * @returns The merged and validated object\n *\n * @example\n * const config = extend(envConfig, configSchema, defaultConfig);\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 * Async helper to pause execution for a given number of milliseconds.\n *\n * @param ms (Optional) Milliseconds to sleep (defaults to config().sleepMs)\n * @returns Promise that resolves after the delay\n *\n * @example\n * await sleep(1000); // sleep for 1 second\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 * Returns the current Act Framework configuration, validated and type-safe.\n *\n * Merges package.json metadata with environment, logging, and timing options.\n * @returns The validated configuration object.\n * @example\n * ```ts\n * const cfg = config();\n * console.log(cfg.env, cfg.logLevel);\n * ```\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 * @category Adapters\n * @see Store\n *\n * In-memory implementation of the Store interface.\n *\n * Suitable for development, testing, and demonstration. Not for production use.\n * All events and streams are stored in memory and lost on process exit.\n *\n * @example\n * const store = new InMemoryStore();\n * await store.commit('streamA', [{ name: 'event', data: {} }], meta);\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> {\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 */\n constructor(public readonly registry: Registry<S, E, A>) {\n dispose(() => {\n this._emitter.removeAllListeners();\n this.stop_correlations();\n return Promise.resolve();\n });\n }\n\n /**\n * Executes an action (command) against a state machine, emitting and committing the resulting event(s).\n *\n * @template K The type of action to execute\n * @param action The action name (key of the action schema)\n * @param target The target (stream and actor) for the action\n * @param payload The action payload (validated against the schema)\n * @param reactingTo (Optional) The event this action is reacting to\n * @param skipValidation (Optional) If true, skips schema validation (not recommended)\n * @returns The snapshot of the committed event\n *\n * @example\n * await app.do(\"increment\", { stream: \"counter1\", actor }, { by: 1 });\n */\n async do<K extends keyof A>(\n action: K,\n target: Target,\n payload: Readonly<A[K]>,\n reactingTo?: Committed<E, keyof E>,\n skipValidation = false\n ) {\n const snapshots = await es.action(\n this.registry.actions[action],\n action,\n target,\n payload,\n // @ts-expect-error type lost\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 given state machine and stream.\n *\n * @template SX The type of state\n * @template EX The type of events\n * @template AX The type of actions\n * @param state The state machine definition\n * @param stream The stream (instance) to load\n * @param callback (Optional) Callback to receive the loaded snapshot\n * @returns The snapshot of the loaded state\n *\n * @example\n * const snapshot = await app.load(Counter, \"counter1\");\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 return await es.load(state, stream, callback);\n }\n\n /**\n * Query the event store for events matching a filter.\n *\n * @param query The query filter (e.g., by stream, event name, or time range)\n * @param callback (Optional) Callback for each event found\n * @returns An object with the first and last event found, and the total count\n *\n * @example\n * const { count } = await app.query({ stream: \"counter1\" }, (event) => console.log(event));\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 * Query the event store for events matching a filter.\n * Use this version with caution, as it return events in memory.\n *\n * @param query The query filter (e.g., by stream, event name, or time range)\n * @returns The matching events\n *\n * @example\n * const { count } = await app.query({ stream: \"counter1\" }, (event) => console.log(event));\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<E extends Schemas>(\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); // 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 * Drains and processes events from the store, triggering reactions and updating state.\n *\n * This is typically called in a background loop or after committing new events.\n *\n * @returns The number of events drained and processed\n *\n * @example\n * await app.drain();\n */\n async drain<E extends Schemas>({\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; lagging: boolean; 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 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 // @ts-expect-error indexed by key\n payloads,\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 // @ts-expect-error key\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 * Correlates streams using reaction resolvers.\n * @param query - The query filter (e.g., by stream, event name, or starting point).\n * @returns The leases of newly correlated streams, and the last seen event ID.\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 correlation worker that identifies and registers new streams using reaction resolvers.\n *\n * Enables \"dynamic reactions\", allowing streams to be auto-discovered based on event content.\n * - Uses a correlation sliding window over the event stream to identify new streams.\n * - Once registered, these streams are picked up by the main `drain` loop.\n * - Users should have full control over their correlation strategy.\n * - The starting point keeps increasing with each new batch of events.\n * - Users are responsible for storing the last seen event ID.\n *\n * @param query - The query filter (e.g., by stream, event name, or starting point).\n * @param frequency - The frequency of correlation checks (in milliseconds).\n * @param callback - Callback to report stats (new strems, last seen event ID, etc.).\n * @returns true if the correlation worker started, false otherwise (already started).\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 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, msg: `🟢 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,\n msg: `🔵 ${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 act-builder\n * @category Builders\n *\n * Fluent builder for composing event-sourced applications.\n */\nimport { Act } from \"./act.js\";\nimport type {\n EventRegister,\n Reaction,\n ReactionHandler,\n ReactionOptions,\n ReactionResolver,\n Registry,\n Schema,\n SchemaRegister,\n Schemas,\n State,\n} from \"./types/index.js\";\n\n// resolves the event stream as source and target (default)\nconst _this_ = ({ stream }: { stream: string }) => ({\n source: stream,\n target: stream,\n});\n// resolves to nothing\nconst _void_ = () => undefined;\n\n/**\n * Fluent builder for composing event-sourced state machines with actions and reactions.\n *\n * Provides a chainable API for registering states, events, and reaction handlers, enabling you to declaratively build complex, reactive applications.\n *\n * @template S SchemaRegister for state\n * @template E Schemas for events\n * @template A Schemas for actions\n *\n * @example\n * const app = act()\n * .with(Counter)\n * .on(\"Incremented\").do(async (event) => { ... })\n * .to(() => \"OtherStream\")\n * .build();\n */\nexport type ActBuilder<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n> = {\n /**\n * Register a state machine with the builder.\n *\n * @template SX The type of state\n * @template EX The type of events\n * @template AX The type of actions\n * @param state The state machine to add\n * @returns The builder (for chaining)\n */\n with: <SX extends Schema, EX extends Schemas, AX extends Schemas>(\n state: State<SX, EX, AX>\n ) => ActBuilder<S & { [K in keyof AX]: SX }, E & EX, A & AX>;\n /**\n * Register a reaction handler for a given event.\n *\n * @template K The event name\n * @param event The event to react to\n * @returns An object with .do(handler) to register the handler\n */\n on: <K extends keyof E>(\n event: K\n ) => {\n /**\n * Register a reaction handler for the event.\n *\n * @param handler The reaction handler function\n * @param options (Optional) Reaction options (retries, blocking, etc.)\n * @returns The builder (for chaining), with .to(resolver) and .void() for advanced routing\n */\n do: (\n handler: ReactionHandler<E, K>,\n options?: Partial<ReactionOptions>\n ) => ActBuilder<S, E, A> & {\n /**\n * Route the reaction to a specific target and optionally source streams (resolver function).\n * @param resolver The resolver function or target stream name (all sources) as a shorthand\n * @returns The builder (for chaining)\n */\n to: (resolver: ReactionResolver<E, K> | string) => ActBuilder<S, E, A>;\n /**\n * Mark the reaction as void (no routing).\n * @returns The builder (for chaining)\n */\n void: () => ActBuilder<S, E, A>;\n };\n };\n /**\n * Build the application and return an Act orchestrator.\n *\n * @param drainLimit (Optional) The maximum number of events to drain per cycle (default: 10)\n * @returns The Act orchestrator instance\n */\n build: (drainLimit?: number) => Act<S, E, A>;\n /**\n * The registered event schemas and reaction maps.\n */\n readonly events: EventRegister<E>;\n};\n\n/* eslint-disable @typescript-eslint/no-empty-object-type */\n\n/**\n * Creates an ActBuilder instance for composing event-sourced applications.\n *\n * Use this function to start building your application by chaining `.with()`, `.on()`, and `.build()` calls.\n *\n * @template S The type of state\n * @template E The type of events\n * @template A The type of actions\n * @returns An ActBuilder instance\n *\n * @example\n * const app = act()\n * .with(Counter)\n * .on(\"Incremented\").do(async (event) => { ... })\n * .build();\n */\nexport function act<\n // @ts-expect-error empty schema\n S extends SchemaRegister<A> = {},\n E extends Schemas = {},\n A extends Schemas = {},\n>(\n states: Set<string> = new Set(),\n registry: Registry<S, E, A> = {\n actions: {} as any,\n events: {} as any,\n }\n): ActBuilder<S, E, A> {\n const builder: ActBuilder<S, E, A> = {\n /**\n * Adds a state to the builder.\n *\n * @template SX The type of state\n * @template EX The type of events\n * @template AX The type of actions\n * @param state The state to add\n * @returns The builder\n */\n with: <SX extends Schema, EX extends Schemas, AX extends Schemas>(\n state: State<SX, EX, AX>\n ) => {\n if (!states.has(state.name)) {\n states.add(state.name);\n for (const name of Object.keys(state.actions)) {\n if (registry.actions[name])\n throw new Error(`Duplicate action \"${name}\"`);\n // @ts-expect-error indexed access\n registry.actions[name] = state;\n }\n for (const name of Object.keys(state.events)) {\n if (registry.events[name])\n throw new Error(`Duplicate event \"${name}\"`);\n // @ts-expect-error indexed access\n registry.events[name] = {\n schema: state.events[name],\n reactions: new Map(),\n };\n }\n }\n return act<S & { [K in keyof AX]: SX }, E & EX, A & AX>(\n states,\n registry as unknown as Registry<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX\n >\n );\n },\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: ReactionHandler<E, K>,\n options?: Partial<ReactionOptions>\n ) => {\n const reaction: Reaction<E, K> = {\n handler,\n resolver: _this_,\n options: {\n blockOnError: options?.blockOnError ?? true,\n maxRetries: options?.maxRetries ?? 3,\n },\n };\n registry.events[event].reactions.set(handler.name, reaction);\n return {\n ...builder,\n to(resolver: ReactionResolver<E, K> | string) {\n registry.events[event].reactions.set(handler.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(handler.name, {\n ...reaction,\n resolver: _void_,\n });\n return builder;\n },\n };\n },\n }),\n build: () => new Act<S, E, A>(registry),\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/* eslint-disable @typescript-eslint/no-empty-object-type */\nexport type StateBuilder<S extends Schema> = {\n /**\n * Define the initial state for the state machine.\n * @param init Function returning the initial state\n * @returns An object with .emits() to declare event types\n */\n init: (init: () => Readonly<S>) => {\n /**\n * Declare the event types the state machine can emit.\n * @param events Zod schemas for each event\n * @returns An object with .patch() to define event handlers\n */\n emits: <E extends Schemas>(\n events: ZodTypes<E>\n ) => {\n /**\n * Define how each event updates state.\n * @param patch Event handler functions\n * @returns An ActionBuilder for defining actions\n */\n patch: (patch: PatchHandlers<S, E>) => ActionBuilder<S, E, {}>;\n };\n };\n};\n\nexport type ActionBuilder<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n> = {\n /**\n * Define an action for the state machine.\n * @param action The action name\n * @param schema The Zod schema for the action payload\n * @returns An object with .given() and .emit() for further configuration\n */\n on: <K extends string, AX extends Schema>(\n action: K,\n schema: ZodType<AX>\n ) => {\n /**\n * Constrain the action with invariants (business rules).\n * @param rules Array of invariants\n * @returns An object with .emit() to finalize the action\n */\n given: (rules: Invariant<S>[]) => {\n /**\n * Finalize the action by providing the event emission handler.\n * @param handler The action handler function\n * @returns The ActionBuilder for chaining\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 * Finalize the action by providing the event emission handler.\n * @param handler The action handler function\n * @returns The ActionBuilder for chaining\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 * Define a snapshotting strategy to reduce recomputations.\n * @param snap Function that determines when to snapshot\n * @returns The ActionBuilder for chaining\n */\n snap: (snap: (snapshot: Snapshot<S, E>) => boolean) => ActionBuilder<S, E, A>;\n /**\n * Finalize and build the state machine definition.\n * @returns The strongly-typed State definition\n */\n build: () => State<S, E, A>;\n};\n\n/**\n * Fluent interface for defining a strongly-typed state machine using Zod schemas.\n *\n * This builder helps you model a system where:\n * - You start by defining the state schema with `state(name, zodSchema)`\n * - Then, provide the initial state using `.init(() => defaultState)`\n * - Declare the event types your system can emit using `.emits({ ... })`\n * - Define how emitted events update state with `.patch({ ... })`\n * - Define actions using `.on(\"actionName\", actionSchema)`\n * - Optionally constrain the action with `.given([...invariants])`\n * - Then finalize the action behavior with `.emit(handler)`\n * - (Optional) Define a `.snap(snapshot => boolean)` function to reduce recomputations\n * - Finalize the state machine definition using `.build()`\n *\n * @template S The type of state\n *\n * @example\n * const machine = state(\"machine\", myStateSchema)\n * .init(() => ({ count: 0 }))\n * .emits({ Incremented: z.object({ amount: z.number() }) })\n * .patch({\n * Incremented: (event, state) => ({ count: state.count + event.amount })\n * })\n * .on(\"increment\", z.object({ by: z.number() }))\n * .given([{ description: \"must be positive\", valid: (s, a) => a?.by > 0 }])\n * .emit((action, state) => ({ type: \"Incremented\", amount: action.by }))\n * .build();\n */\nexport function state<S extends Schema>(\n name: string,\n state: ZodType<S>\n): StateBuilder<S> {\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 return action_builder<S, E, {}>({\n events,\n actions: {},\n state,\n name,\n init,\n patch,\n on: {},\n });\n },\n };\n },\n };\n },\n };\n}\n\nfunction action_builder<S extends Schema, E extends Schemas, A extends Schemas>(\n state: State<S, E, A>\n): ActionBuilder<S, E, A> {\n return {\n on<K extends string, AX extends Schema>(action: K, schema: ZodType<AX>) {\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 ...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>({ ...state, snap });\n },\n\n build(): State<S, E, A> {\n return state;\n },\n };\n}\n"],"mappings":"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","names":["action","import_zod","import_zod","pkg","a","b","store","logLevel","stream","import_crypto","state","action","EventEmitter","action","state","lagging","lagging_handled","leading_handled","handled","state","state","patch","action","snap"]}
1
+ {"version":3,"sources":["../src/index.ts","../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/act-builder.ts","../src/state-builder.ts"],"sourcesContent":["import \"./signals.js\";\n\n/**\n * @packageDocumentation\n * @module act\n * Main entry point for the Act framework. Re-exports all core APIs.\n */\nexport * from \"./act-builder.js\";\nexport * from \"./act.js\";\nexport * from \"./config.js\";\nexport * from \"./ports.js\";\nexport * from \"./state-builder.js\";\nexport * from \"./types/index.js\";\nexport * from \"./utils.js\";\n","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 disposers that are triggered on process exit.\n *\n * @param disposer The disposer function to register\n * @returns A function that triggers all registered disposers and terminates the process\n *\n * @example\n * dispose(async () => { await myResource.close(); });\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 * Singleton event store port. By default, uses the in-memory store.\n *\n * You can inject a persistent store (e.g., Postgres) by calling `store(myAdapter)`.\n *\n * @example\n * const myStore = store();\n * const customStore = store(new MyCustomStore());\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 a payload fails schema validation.\n * @param target - The name of the target being validated (e.g., event, action).\n * @param payload - The invalid payload.\n * @param details - Additional validation error details.\n * @example\n * throw new ValidationError('event', payload, zodError);\n */\nexport class ValidationError extends Error {\n constructor(\n public readonly target: string,\n public readonly payload: any,\n public readonly details: any\n ) {\n super(`Invalid ${target} payload`);\n this.name = Errors.ValidationError;\n }\n}\n\n/**\n * Thrown when a state invariant is violated after an action or event.\n * @param name - The name of the invariant or action.\n * @param payload - The state or payload that failed the invariant.\n * @param target - The target context (e.g., stream, actor).\n * @param description - Description of the invariant.\n * @example\n * throw new InvariantError('balanceNonNegative', state, target, 'Balance must be >= 0');\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 readonly action: K,\n readonly payload: Readonly<A[K]>,\n readonly target: Target,\n readonly snapshot: Snapshot<S, E>,\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 an optimistic concurrency check fails during event commit.\n * @param lastVersion - The last known version in the stream.\n * @param events - The events being committed.\n * @param expectedVersion - The expected version for the commit.\n * @example\n * throw new ConcurrencyError(2, events, 1);\n */\nexport class ConcurrencyError extends Error {\n constructor(\n public readonly stream: string,\n public readonly lastVersion: number,\n public readonly events: Message<Schemas, keyof Schemas>[],\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 copies state with patches recursively.\n *\n * Keys with `undefined` or `null` values in patch are deleted.\n *\n * @param original The original state object\n * @param patches The patches to merge\n * @returns A new patched state\n *\n * @example\n * const newState = patch(oldState, { count: 5 });\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, throwing a ValidationError on failure.\n *\n * @param target The name of the target (for error reporting)\n * @param payload The payload to validate\n * @param schema (Optional) The Zod schema to validate against\n * @returns The validated payload\n * @throws ValidationError if validation fails\n *\n * @example\n * const valid = validate(\"User\", userPayload, userSchema);\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 * Extends the target payload with the source payload after validating the source.\n *\n * @param source The source object to validate and merge\n * @param schema The Zod schema for the source\n * @param target (Optional) The target object to extend\n * @returns The merged and validated object\n *\n * @example\n * const config = extend(envConfig, configSchema, defaultConfig);\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 * Async helper to pause execution for a given number of milliseconds.\n *\n * @param ms (Optional) Milliseconds to sleep (defaults to config().sleepMs)\n * @returns Promise that resolves after the delay\n *\n * @example\n * await sleep(1000); // sleep for 1 second\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 * Returns the current Act Framework configuration, validated and type-safe.\n *\n * Merges package.json metadata with environment, logging, and timing options.\n * @returns The validated configuration object.\n * @example\n * ```ts\n * const cfg = config();\n * console.log(cfg.env, cfg.logLevel);\n * ```\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 * @category Adapters\n * @see Store\n *\n * In-memory implementation of the Store interface.\n *\n * Suitable for development, testing, and demonstration. Not for production use.\n * All events and streams are stored in memory and lost on process exit.\n *\n * @example\n * const store = new InMemoryStore();\n * await store.commit('streamA', [{ name: 'event', data: {} }], meta);\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> {\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 */\n constructor(public readonly registry: Registry<S, E, A>) {\n dispose(() => {\n this._emitter.removeAllListeners();\n this.stop_correlations();\n return Promise.resolve();\n });\n }\n\n /**\n * Executes an action (command) against a state machine, emitting and committing the resulting event(s).\n *\n * @template K The type of action to execute\n * @param action The action name (key of the action schema)\n * @param target The target (stream and actor) for the action\n * @param payload The action payload (validated against the schema)\n * @param reactingTo (Optional) The event this action is reacting to\n * @param skipValidation (Optional) If true, skips schema validation (not recommended)\n * @returns The snapshot of the committed event\n *\n * @example\n * await app.do(\"increment\", { stream: \"counter1\", actor }, { by: 1 });\n */\n async do<K extends keyof A>(\n action: K,\n target: Target,\n payload: Readonly<A[K]>,\n reactingTo?: Committed<E, keyof E>,\n skipValidation = false\n ) {\n const snapshots = await es.action(\n this.registry.actions[action],\n action,\n target,\n payload,\n // @ts-expect-error type lost\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 given state machine and stream.\n *\n * @template SX The type of state\n * @template EX The type of events\n * @template AX The type of actions\n * @param state The state machine definition\n * @param stream The stream (instance) to load\n * @param callback (Optional) Callback to receive the loaded snapshot\n * @returns The snapshot of the loaded state\n *\n * @example\n * const snapshot = await app.load(Counter, \"counter1\");\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 return await es.load(state, stream, callback);\n }\n\n /**\n * Query the event store for events matching a filter.\n *\n * @param query The query filter (e.g., by stream, event name, or time range)\n * @param callback (Optional) Callback for each event found\n * @returns An object with the first and last event found, and the total count\n *\n * @example\n * const { count } = await app.query({ stream: \"counter1\" }, (event) => console.log(event));\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 * Query the event store for events matching a filter.\n * Use this version with caution, as it return events in memory.\n *\n * @param query The query filter (e.g., by stream, event name, or time range)\n * @returns The matching events\n *\n * @example\n * const { count } = await app.query({ stream: \"counter1\" }, (event) => console.log(event));\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<E extends Schemas>(\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); // 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 * Drains and processes events from the store, triggering reactions and updating state.\n *\n * This is typically called in a background loop or after committing new events.\n *\n * @returns The number of events drained and processed\n *\n * @example\n * await app.drain();\n */\n async drain<E extends Schemas>({\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; lagging: boolean; 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 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 // @ts-expect-error indexed by key\n payloads,\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 // @ts-expect-error key\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 * Correlates streams using reaction resolvers.\n * @param query - The query filter (e.g., by stream, event name, or starting point).\n * @returns The leases of newly correlated streams, and the last seen event ID.\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 correlation worker that identifies and registers new streams using reaction resolvers.\n *\n * Enables \"dynamic reactions\", allowing streams to be auto-discovered based on event content.\n * - Uses a correlation sliding window over the event stream to identify new streams.\n * - Once registered, these streams are picked up by the main `drain` loop.\n * - Users should have full control over their correlation strategy.\n * - The starting point keeps increasing with each new batch of events.\n * - Users are responsible for storing the last seen event ID.\n *\n * @param query - The query filter (e.g., by stream, event name, or starting point).\n * @param frequency - The frequency of correlation checks (in milliseconds).\n * @param callback - Callback to report stats (new strems, last seen event ID, etc.).\n * @returns true if the correlation worker started, false otherwise (already started).\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 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 act-builder\n * @category Builders\n *\n * Fluent builder for composing event-sourced applications.\n */\nimport { Act } from \"./act.js\";\nimport type {\n EventRegister,\n Reaction,\n ReactionHandler,\n ReactionOptions,\n ReactionResolver,\n Registry,\n Schema,\n SchemaRegister,\n Schemas,\n State,\n} from \"./types/index.js\";\n\n// resolves the event stream as source and target (default)\nconst _this_ = ({ stream }: { stream: string }) => ({\n source: stream,\n target: stream,\n});\n// resolves to nothing\nconst _void_ = () => undefined;\n\n/**\n * Fluent builder for composing event-sourced state machines with actions and reactions.\n *\n * Provides a chainable API for registering states, events, and reaction handlers, enabling you to declaratively build complex, reactive applications.\n *\n * @template S SchemaRegister for state\n * @template E Schemas for events\n * @template A Schemas for actions\n *\n * @example\n * const app = act()\n * .with(Counter)\n * .on(\"Incremented\").do(async (event) => { ... })\n * .to(() => \"OtherStream\")\n * .build();\n */\nexport type ActBuilder<\n S extends SchemaRegister<A>,\n E extends Schemas,\n A extends Schemas,\n> = {\n /**\n * Register a state machine with the builder.\n *\n * @template SX The type of state\n * @template EX The type of events\n * @template AX The type of actions\n * @param state The state machine to add\n * @returns The builder (for chaining)\n */\n with: <SX extends Schema, EX extends Schemas, AX extends Schemas>(\n state: State<SX, EX, AX>\n ) => ActBuilder<S & { [K in keyof AX]: SX }, E & EX, A & AX>;\n /**\n * Register a reaction handler for a given event.\n *\n * @template K The event name\n * @param event The event to react to\n * @returns An object with .do(handler) to register the handler\n */\n on: <K extends keyof E>(\n event: K\n ) => {\n /**\n * Register a reaction handler for the event.\n *\n * @param handler The reaction handler function\n * @param options (Optional) Reaction options (retries, blocking, etc.)\n * @returns The builder (for chaining), with .to(resolver) and .void() for advanced routing\n */\n do: (\n handler: ReactionHandler<E, K>,\n options?: Partial<ReactionOptions>\n ) => ActBuilder<S, E, A> & {\n /**\n * Route the reaction to a specific target and optionally source streams (resolver function).\n * @param resolver The resolver function or target stream name (all sources) as a shorthand\n * @returns The builder (for chaining)\n */\n to: (resolver: ReactionResolver<E, K> | string) => ActBuilder<S, E, A>;\n /**\n * Mark the reaction as void (no routing).\n * @returns The builder (for chaining)\n */\n void: () => ActBuilder<S, E, A>;\n };\n };\n /**\n * Build the application and return an Act orchestrator.\n *\n * @param drainLimit (Optional) The maximum number of events to drain per cycle (default: 10)\n * @returns The Act orchestrator instance\n */\n build: (drainLimit?: number) => Act<S, E, A>;\n /**\n * The registered event schemas and reaction maps.\n */\n readonly events: EventRegister<E>;\n};\n\n/* eslint-disable @typescript-eslint/no-empty-object-type */\n\n/**\n * Creates an ActBuilder instance for composing event-sourced applications.\n *\n * Use this function to start building your application by chaining `.with()`, `.on()`, and `.build()` calls.\n *\n * @template S The type of state\n * @template E The type of events\n * @template A The type of actions\n * @returns An ActBuilder instance\n *\n * @example\n * const app = act()\n * .with(Counter)\n * .on(\"Incremented\").do(async (event) => { ... })\n * .build();\n */\nexport function act<\n // @ts-expect-error empty schema\n S extends SchemaRegister<A> = {},\n E extends Schemas = {},\n A extends Schemas = {},\n>(\n states: Set<string> = new Set(),\n registry: Registry<S, E, A> = {\n actions: {} as any,\n events: {} as any,\n }\n): ActBuilder<S, E, A> {\n const builder: ActBuilder<S, E, A> = {\n /**\n * Adds a state to the builder.\n *\n * @template SX The type of state\n * @template EX The type of events\n * @template AX The type of actions\n * @param state The state to add\n * @returns The builder\n */\n with: <SX extends Schema, EX extends Schemas, AX extends Schemas>(\n state: State<SX, EX, AX>\n ) => {\n if (!states.has(state.name)) {\n states.add(state.name);\n for (const name of Object.keys(state.actions)) {\n if (registry.actions[name])\n throw new Error(`Duplicate action \"${name}\"`);\n // @ts-expect-error indexed access\n registry.actions[name] = state;\n }\n for (const name of Object.keys(state.events)) {\n if (registry.events[name])\n throw new Error(`Duplicate event \"${name}\"`);\n // @ts-expect-error indexed access\n registry.events[name] = {\n schema: state.events[name],\n reactions: new Map(),\n };\n }\n }\n return act<S & { [K in keyof AX]: SX }, E & EX, A & AX>(\n states,\n registry as unknown as Registry<\n S & { [K in keyof AX]: SX },\n E & EX,\n A & AX\n >\n );\n },\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: ReactionHandler<E, K>,\n options?: Partial<ReactionOptions>\n ) => {\n const reaction: Reaction<E, K> = {\n handler,\n resolver: _this_,\n options: {\n blockOnError: options?.blockOnError ?? true,\n maxRetries: options?.maxRetries ?? 3,\n },\n };\n registry.events[event].reactions.set(handler.name, reaction);\n return {\n ...builder,\n to(resolver: ReactionResolver<E, K> | string) {\n registry.events[event].reactions.set(handler.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(handler.name, {\n ...reaction,\n resolver: _void_,\n });\n return builder;\n },\n };\n },\n }),\n build: () => new Act<S, E, A>(registry),\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/* eslint-disable @typescript-eslint/no-empty-object-type */\nexport type StateBuilder<S extends Schema> = {\n /**\n * Define the initial state for the state machine.\n * @param init Function returning the initial state\n * @returns An object with .emits() to declare event types\n */\n init: (init: () => Readonly<S>) => {\n /**\n * Declare the event types the state machine can emit.\n * @param events Zod schemas for each event\n * @returns An object with .patch() to define event handlers\n */\n emits: <E extends Schemas>(\n events: ZodTypes<E>\n ) => {\n /**\n * Define how each event updates state.\n * @param patch Event handler functions\n * @returns An ActionBuilder for defining actions\n */\n patch: (patch: PatchHandlers<S, E>) => ActionBuilder<S, E, {}>;\n };\n };\n};\n\nexport type ActionBuilder<\n S extends Schema,\n E extends Schemas,\n A extends Schemas,\n> = {\n /**\n * Define an action for the state machine.\n * @param action The action name\n * @param schema The Zod schema for the action payload\n * @returns An object with .given() and .emit() for further configuration\n */\n on: <K extends string, AX extends Schema>(\n action: K,\n schema: ZodType<AX>\n ) => {\n /**\n * Constrain the action with invariants (business rules).\n * @param rules Array of invariants\n * @returns An object with .emit() to finalize the action\n */\n given: (rules: Invariant<S>[]) => {\n /**\n * Finalize the action by providing the event emission handler.\n * @param handler The action handler function\n * @returns The ActionBuilder for chaining\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 * Finalize the action by providing the event emission handler.\n * @param handler The action handler function\n * @returns The ActionBuilder for chaining\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 * Define a snapshotting strategy to reduce recomputations.\n * @param snap Function that determines when to snapshot\n * @returns The ActionBuilder for chaining\n */\n snap: (snap: (snapshot: Snapshot<S, E>) => boolean) => ActionBuilder<S, E, A>;\n /**\n * Finalize and build the state machine definition.\n * @returns The strongly-typed State definition\n */\n build: () => State<S, E, A>;\n};\n\n/**\n * Fluent interface for defining a strongly-typed state machine using Zod schemas.\n *\n * This builder helps you model a system where:\n * - You start by defining the state schema with `state(name, zodSchema)`\n * - Then, provide the initial state using `.init(() => defaultState)`\n * - Declare the event types your system can emit using `.emits({ ... })`\n * - Define how emitted events update state with `.patch({ ... })`\n * - Define actions using `.on(\"actionName\", actionSchema)`\n * - Optionally constrain the action with `.given([...invariants])`\n * - Then finalize the action behavior with `.emit(handler)`\n * - (Optional) Define a `.snap(snapshot => boolean)` function to reduce recomputations\n * - Finalize the state machine definition using `.build()`\n *\n * @template S The type of state\n *\n * @example\n * const machine = state(\"machine\", myStateSchema)\n * .init(() => ({ count: 0 }))\n * .emits({ Incremented: z.object({ amount: z.number() }) })\n * .patch({\n * Incremented: (event, state) => ({ count: state.count + event.amount })\n * })\n * .on(\"increment\", z.object({ by: z.number() }))\n * .given([{ description: \"must be positive\", valid: (s, a) => a?.by > 0 }])\n * .emit((action, state) => ({ type: \"Incremented\", amount: action.by }))\n * .build();\n */\nexport function state<S extends Schema>(\n name: string,\n state: ZodType<S>\n): StateBuilder<S> {\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 return action_builder<S, E, {}>({\n events,\n actions: {},\n state,\n name,\n init,\n patch,\n on: {},\n });\n },\n };\n },\n };\n },\n };\n}\n\nfunction action_builder<S extends Schema, E extends Schemas, A extends Schemas>(\n state: State<S, E, A>\n): ActionBuilder<S, E, A> {\n return {\n on<K extends string, AX extends Schema>(action: K, schema: ZodType<AX>) {\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 ...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>({ ...state, snap });\n },\n\n build(): State<S, E, A> {\n return state;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAqB;;;ACYd,IAAM,SAAS;AAAA,EACpB,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,kBAAkB;AACpB;AAUO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YACkB,QACA,SACA,SAChB;AACA,UAAM,WAAW,MAAM,UAAU;AAJjB;AACA;AACA;AAGhB,SAAK,OAAO,OAAO;AAAA,EACrB;AACF;AAWO,IAAM,iBAAN,cAKG,MAAM;AAAA,EACd,YACWA,SACA,SACA,QACA,UACA,aACT;AACA,UAAM,GAAGA,OAAgB,sBAAsB,WAAW,EAAE;AANnD,kBAAAA;AACA;AACA;AACA;AACA;AAGT,SAAK,OAAO,OAAO;AAAA,EACrB;AACF;AAUO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YACkB,QACA,aACA,QACA,iBAChB;AACA;AAAA,MACE,iCAAiC,OAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE,IAAI,IAAI,KAAK,UAAU,EAAE,IAAI,CAAC,EAAE,EAC1D;AAAA,QACC;AAAA,MACF,CAAC,uBAAuB,eAAe,sBAAsB,WAAW;AAAA,IAC5E;AAXgB;AACA;AACA;AACA;AAShB,SAAK,OAAO,OAAO;AAAA,EACrB;AACF;;;ACxFA,IAAAC,cAA2D;;;ACQ3D,SAAoB;AACpB,IAAAC,cAAkB;;;ACTlB,iBAA0C;AAYnC,IAAM,WAAW,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,MAAM,CAAC;AAK/C,IAAM,cAAc,aACxB,OAAO;AAAA,EACN,IAAI,aAAE,OAAO;AAAA,EACb,MAAM,aAAE,OAAO;AACjB,CAAC,EACA,SAAS;AAKL,IAAM,eAAe,aACzB,OAAO;AAAA,EACN,QAAQ,aAAE,OAAO;AAAA,EACjB,OAAO;AAAA,EACP,iBAAiB,aAAE,OAAO,EAAE,SAAS;AACvC,CAAC,EACA,SAAS;AAKL,IAAM,uBAAuB,aAAE,OAAO;AAAA,EAC3C,IAAI,aAAE,OAAO;AAAA,EACb,MAAM,aAAE,OAAO;AAAA,EACf,QAAQ,aAAE,OAAO;AACnB,CAAC;AAKM,IAAM,kBAAkB,aAC5B,OAAO;AAAA,EACN,aAAa,aAAE,OAAO;AAAA,EACtB,WAAW,aAAE,OAAO;AAAA,IAClB,QAAQ,aAAa,IAAI,aAAE,OAAO,EAAE,MAAM,aAAE,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS;AAAA,IAClE,OAAO,qBAAqB,SAAS;AAAA,EACvC,CAAC;AACH,CAAC,EACA,SAAS;AAKL,IAAM,sBAAsB,aAChC,OAAO;AAAA,EACN,IAAI,aAAE,OAAO;AAAA,EACb,QAAQ,aAAE,OAAO;AAAA,EACjB,SAAS,aAAE,OAAO;AAAA,EAClB,SAAS,aAAE,KAAK;AAAA,EAChB,MAAM;AACR,CAAC,EACA,SAAS;AAiBL,IAAM,cAAc,aACxB,OAAO;AAAA,EACN,QAAQ,aAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,OAAO,aAAE,OAAO,EAAE,MAAM,EAAE,SAAS;AAAA,EACnC,QAAQ,aAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,OAAO,aAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,gBAAgB,aAAE,KAAK,EAAE,SAAS;AAAA,EAClC,eAAe,aAAE,KAAK,EAAE,SAAS;AAAA,EACjC,UAAU,aAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,aAAa,aAAE,OAAO,EAAE,SAAS;AAAA,EACjC,YAAY,aAAE,QAAQ,EAAE,SAAS;AACnC,CAAC,EACA,SAAS;;;ACzEL,IAAM,eAAe;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAWO,IAAM,YAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AF1BO,IAAM,gBAAgB,cAAE,OAAO;AAAA,EACpC,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,SAAS,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,aAAa,cAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACxC,QAAQ,cACL,OAAO,EAAE,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,GAAG,OAAO,cAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAChE,SAAS,EACT,GAAG,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EACpB,SAAS;AAAA,EACZ,SAAS,cAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACpC,cAAc,cAAE,OAAO,cAAE,OAAO,GAAG,cAAE,OAAO,CAAC,EAAE,SAAS;AAC1D,CAAC;AAYD,IAAM,aAAa,MAAe;AAChC,QAAMC,OAAS,gBAAa,cAAc;AAC1C,SAAO,KAAK,MAAMA,KAAI,SAAS,CAAC;AAClC;AAOA,IAAM,aAAa,cAAc,OAAO;AAAA,EACtC,KAAK,cAAE,KAAK,YAAY;AAAA,EACxB,UAAU,cAAE,KAAK,SAAS;AAAA,EAC1B,eAAe,cAAE,QAAQ;AAAA,EACzB,SAAS,cAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI;AAC3C,CAAC;AAOD,IAAM,EAAE,UAAU,WAAW,iBAAiB,SAAS,IAAI,QAAQ;AAEnE,IAAM,MAAO,YAAY;AACzB,IAAM,WAAY,cACf,aAAa,SACV,UACA,aAAa,eACX,SACA;AACR,IAAM,iBAAiB,mBAAmB,YAAY;AACtD,IAAM,UAAU,SAAS,aAAa,SAAS,MAAO,YAAY,KAAM;AAExE,IAAM,MAAM,WAAW;AAahB,IAAM,SAAS,MAAc;AAClC,SAAO,OAAO,EAAE,GAAG,KAAK,KAAK,UAAU,eAAe,QAAQ,GAAG,UAAU;AAC7E;;;ADxFA,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,eAAe,CAAC,UACpB,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,CAAC,aAAa,KAAK,CAAC,MAAM,iBAAiB,CAAC;AAyBvC,IAAM,QAAQ,CACnB,UACA,YACgB;AAChB,QAAM,OAAO,CAAC;AACd,SAAO,KAAK,EAAE,GAAG,UAAU,GAAG,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ;AACxD,UAAM,gBAAgB,QAAQ,GAA2B;AACzD,UAAM,iBAAiB,SAAS,GAA4B;AAC5D,UAAM,UAAU,WAAW,OAAO;AAClC,UAAM,UACJ,YACC,OAAO,kBAAkB,eAAe,kBAAkB;AAC7D,UAAM,QAAQ,WAAW,CAAC,UAAU,gBAAgB;AACpD,KAAC,YACE,KAAK,GAAG,IAAI,aAAa,KAAK,IAC3B,MAAM,kBAAkB,CAAC,GAAG,iBAAiB,CAAC,CAAC,IAC/C;AAAA,EACR,CAAC;AACD,SAAO;AACT;AAcO,IAAM,WAAW,CACtB,QACA,SACA,WACgB;AAChB,MAAI;AACF,WAAO,SAAS,OAAO,MAAM,OAAO,IAAI;AAAA,EAC1C,SAAS,OAAO;AACd,QAAI,iBAAiB,SAAS,MAAM,SAAS,YAAY;AACvD,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,YACA,2BAAc,KAAiB;AAAA,MACjC;AAAA,IACF;AACA,UAAM,IAAI,gBAAgB,QAAQ,SAAS,KAAK;AAAA,EAClD;AACF;AAaO,IAAM,SAAS,CAIpB,QACA,QACA,WACoB;AACpB,QAAM,QAAQ,SAAS,UAAU,QAAQ,MAAM;AAC/C,SAAO,OAAO,OAAO,UAAU,CAAC,GAAG,KAAK;AAC1C;AAWA,eAAsB,MAAM,IAAa;AACvC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,MAAM,OAAO,EAAE,OAAO,CAAC;AAC7E;;;AInHA,IAAM,iBAAN,MAAqB;AAAA,EAQnB,YACW,QACA,QACT;AAFS;AACA;AAAA,EACR;AAAA,EAVK,MAAM;AAAA,EACN,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,aAAiC;AAAA,EACjC,gBAAkC;AAAA,EAO1C,IAAI,eAAe;AACjB,WACE,CAAC,KAAK,aACL,CAAC,KAAK,iBAAiB,KAAK,iBAAiB,oBAAI,KAAK;AAAA,EAE3D;AAAA,EAEA,IAAI,KAAK;AACP,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAc,QAAmC;AACrD,QAAI,KAAK,cAAc;AACrB,UAAI,SAAS,GAAG;AACd,aAAK,aAAa,MAAM;AACxB,aAAK,gBAAgB,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM;AACjD,aAAK,SAAS,KAAK,SAAS;AAAA,MAC9B;AACA,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,QACb,IAAI,MAAM;AAAA,QACV,IAAI,MAAM;AAAA,QACV,OAAO,KAAK;AAAA,QACZ,SAAS,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAc;AAChB,QAAI,KAAK,eAAe,MAAM,IAAI;AAChC,WAAK,aAAa;AAClB,WAAK,gBAAgB;AACrB,WAAK,MAAM,MAAM;AACjB,WAAK,SAAS;AACd,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,QACb,IAAI,KAAK;AAAA,QACT,IAAI,MAAM;AAAA,QACV,OAAO,KAAK;AAAA,QACZ,SAAS,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAc,OAAe;AACjC,QAAI,KAAK,eAAe,MAAM,IAAI;AAChC,WAAK,WAAW;AAChB,WAAK,SAAS;AACd,aAAO;AAAA,QACL,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,QACb,IAAI,KAAK;AAAA,QACT,IAAI,KAAK;AAAA,QACT,OAAO,KAAK;AAAA,QACZ,OAAO,KAAK;AAAA,QACZ,SAAS,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAeO,IAAM,gBAAN,MAAqC;AAAA;AAAA,EAElC,UAA+C,CAAC;AAAA;AAAA,EAEhD,WAAwC,oBAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAMxD,MAAM,UAAU;AACd,UAAM,MAAM;AACZ,SAAK,QAAQ,SAAS;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO;AACX,UAAM,MAAM;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO;AACX,UAAM,MAAM;AACZ,SAAK,QAAQ,SAAS;AACtB,SAAK,WAAW,oBAAI,IAAI;AAAA,EAC1B;AAAA,EAEQ,SAA4B,OAAc,GAA0B;AAC1E,QAAI,MAAM,UAAU,CAAC,OAAO,IAAI,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM;AAC5D,aAAO;AACT,QAAI,MAAM,SAAS,CAAC,MAAM,MAAM,SAAS,EAAE,IAAc,EAAG,QAAO;AACnE,QAAI,MAAM,eAAe,EAAE,MAAM,gBAAgB,MAAM;AACrD,aAAO;AACT,QAAI,EAAE,SAAS,cAAc,CAAC,MAAM,WAAY,QAAO;AACvD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,MACJ,UACA,OACA;AACA,UAAM,MAAM;AACZ,QAAI,QAAQ;AACZ,QAAI,OAAO,UAAU;AACnB,UAAI,KAAK,OAAO,UAAU,KAAK,QAAQ,UAAU;AACjD,aAAO,KAAK,GAAG;AACb,cAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,YAAI,SAAS,CAAC,KAAK,SAAS,OAAO,CAAC,EAAG;AACvC,YAAI,OAAO,kBAAkB,EAAE,WAAW,MAAM;AAC9C;AACF,YAAI,MAAM,SAAS,EAAE,MAAM,MAAM,MAAO;AACxC,YAAI,MAAM,iBAAiB,EAAE,WAAW,MAAM,cAAe;AAC7D,iBAAS,CAA0B;AACnC;AACA,YAAI,OAAO,SAAS,SAAS,MAAM,MAAO;AAAA,MAC5C;AAAA,IACF,OAAO;AACL,UAAI,KAAK,OAAO,SAAS,MAAM;AAC/B,aAAO,IAAI,KAAK,QAAQ,QAAQ;AAC9B,cAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,YAAI,SAAS,CAAC,KAAK,SAAS,OAAO,CAAC,EAAG;AACvC,YAAI,OAAO,iBAAiB,EAAE,WAAW,MAAM,cAAe;AAC9D,YAAI,OAAO,UAAU,EAAE,MAAM,MAAM,OAAQ;AAC3C,YAAI,OAAO,kBAAkB,EAAE,WAAW,MAAM,eAAgB;AAChE,iBAAS,CAA0B;AACnC;AACA,YAAI,OAAO,SAAS,SAAS,MAAM,MAAO;AAAA,MAC5C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,OACJ,QACA,MACA,MACA,iBACA;AACA,UAAM,MAAM;AACZ,UAAM,WAAW,KAAK,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,MAAM;AAC/D,QACE,OAAO,oBAAoB,YAC3B,SAAS,SAAS,MAAM,iBACxB;AACA,YAAM,IAAI;AAAA,QACR;AAAA,QACA,SAAS,SAAS;AAAA,QAClB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU,SAAS;AACvB,WAAO,KAAK,IAAI,CAAC,EAAE,MAAM,KAAK,MAAM;AAClC,YAAM,YAAmC;AAAA,QACvC,IAAI,KAAK,QAAQ;AAAA,QACjB;AAAA,QACA;AAAA,QACA,SAAS,oBAAI,KAAK;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,WAAK,QAAQ,KAAK,SAA8C;AAChE;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,SAAiB,SAAiB;AAC3C,UAAM,MAAM;AACZ,UAAM,IAAI,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,EACjC,OAAO,CAAC,MAAM,EAAE,YAAY,EAC5B,KAAK,CAACC,IAAGC,OAAMD,GAAE,KAAKC,GAAE,EAAE,EAC1B,MAAM,GAAG,OAAO,EAChB,IAAI,CAAC,EAAE,QAAQ,QAAQ,GAAG,OAAO;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACX,EAAE;AACJ,UAAM,IAAI,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,EACjC,OAAO,CAAC,MAAM,EAAE,YAAY,EAC5B,KAAK,CAACD,IAAGC,OAAMA,GAAE,KAAKD,GAAE,EAAE,EAC1B,MAAM,GAAG,OAAO,EAChB,IAAI,CAAC,EAAE,QAAQ,QAAQ,GAAG,OAAO;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACX,EAAE;AACJ,WAAO,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,MAAM,QAAiB,QAAgB;AAC3C,UAAM,MAAM;AACZ,WAAO,OACJ,IAAI,CAAC,MAAM;AACV,UAAI,CAAC,KAAK,SAAS,IAAI,EAAE,MAAM,GAAG;AAEhC,aAAK,SAAS,IAAI,EAAE,QAAQ,IAAI,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC;AAAA,MACpE;AACA,aAAO,KAAK,SAAS,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;AAAA,IACrD,CAAC,EACA,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,QAAiB;AACzB,UAAM,MAAM;AACZ,WAAO,OACJ,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,EAC9C,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAM,QAA0C;AACpD,UAAM,MAAM;AACZ,WAAO,OACJ,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,EAAE,KAAK,CAAC,EACzD,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,EACtB;AACF;;;ANjTO,IAAM,YAAY,CAAC,SAAS,MAAM;AAelC,IAAM,aAAS,kBAAK;AAAA,EACzB,WACE,OAAO,EAAE,QAAQ,eACb;AAAA,IACE,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,YAAY,OAAO,EAAE;AAAA,MACrB,UAAU;AAAA,IACZ;AAAA,EACF,IACA;AAAA,EACN,OAAO,OAAO,EAAE;AAClB,CAAC;AAaD,IAAM,WAAW,oBAAI,IAAwB;AACtC,SAAS,KAA8B,UAA0B;AACtE,SAAO,SAAU,SAAsB;AACrC,QAAI,CAAC,SAAS,IAAI,SAAS,IAAI,GAAG;AAChC,YAAM,WAAW,SAAS,OAAO;AACjC,eAAS,IAAI,SAAS,MAAM,QAAQ;AACpC,aAAO,KAAK,sBAAe,SAAS,IAAI,IAAI,SAAS,YAAY,IAAI,EAAE;AAAA,IACzE;AACA,WAAO,SAAS,IAAI,SAAS,IAAI;AAAA,EACnC;AACF;AAEA,IAAM,YAAwB,CAAC;AAC/B,eAAsB,eAAe,OAAiB,QAAuB;AAE3E,MAAI,SAAS,WAAW,OAAO,EAAE,QAAQ,aAAc;AAEvD,QAAM,QAAQ,IAAI,UAAU,IAAI,CAAC,aAAa,SAAS,CAAC,CAAC;AACzD,QAAM,QAAQ;AAAA,IACZ,CAAC,GAAG,SAAS,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,OAAO,YAAY;AACtD,YAAM,QAAQ,QAAQ;AACtB,aAAO,KAAK,sBAAe,QAAQ,YAAY,IAAI,EAAE;AAAA,IACvD,CAAC;AAAA,EACH;AACA,WAAS,MAAM;AACf,SAAO,EAAE,QAAQ,UAAU,QAAQ,KAAK,SAAS,UAAU,IAAI,CAAC;AAClE;AAWO,SAAS,QACd,UACoC;AACpC,cAAY,UAAU,KAAK,QAAQ;AACnC,SAAO;AACT;AAKO,IAAM,aAAa;AAWnB,IAAM,QAAQ,KAAK,SAASE,OAAM,SAAiB;AACxD,SAAO,WAAW,IAAI,cAAc;AACtC,CAAC;AAKM,SAAS,aAAaC,WAM3B;AACA,MAAIA,cAAa,SAAS;AACxB,WAAO;AAAA,MACL,SAAS,CAAoB,YAAsB;AACjD,cAAM,OAAO,OAAO;AAAA,UAClB,QAAQ,IAAI,CAAC,EAAE,QAAQ,QAAQ,OAAO,MAAM;AAC1C,kBAAM,MAAM,SAAS,GAAG,MAAM,KAAK,MAAM,KAAK;AAC9C,kBAAM,QAAQ,OAAO;AAAA,cACnB,OAAO,IAAI,CAAC,EAAE,IAAI,QAAAC,SAAQ,KAAK,MAAM,CAAC,IAAI,EAAE,CAACA,OAAM,GAAG,KAAK,CAAC,CAAC;AAAA,YAC/D;AACA,mBAAO,CAAC,KAAK,KAAK;AAAA,UACpB,CAAC;AAAA,QACH;AACA,eAAO,MAAM,MAAM,oBAAU;AAAA,MAC/B;AAAA,MACA,YAAY,CAAC,WAAoB;AAC/B,cAAM,OAAO,OAAO,IAAI,CAAC,EAAE,OAAO,MAAM,MAAM,EAAE,KAAK,GAAG;AACxD,eAAO,MAAM,0BAAgB,IAAI,EAAE;AAAA,MACrC;AAAA,MACA,QAAQ,CAAC,WAAoB;AAC3B,cAAM,OAAO,OAAO;AAAA,UAClB,OAAO,IAAI,CAAC,EAAE,QAAQ,IAAI,MAAM,MAAM,CAAC,QAAQ,EAAE,IAAI,MAAM,CAAC,CAAC;AAAA,QAC/D;AACA,eAAO,MAAM,MAAM,oBAAU;AAAA,MAC/B;AAAA,MACA,OAAO,CAAC,WAAoB;AAC1B,cAAM,OAAO,OAAO;AAAA,UAClB,OAAO,IAAI,CAAC,EAAE,QAAQ,IAAI,MAAM,MAAM,CAAC,QAAQ,EAAE,IAAI,MAAM,CAAC,CAAC;AAAA,QAC/D;AACA,eAAO,MAAM,MAAM,kBAAQ;AAAA,MAC7B;AAAA,MACA,SAAS,CAAC,WAA6C;AACrD,cAAM,OAAO,OAAO;AAAA,UAClB,OAAO,IAAI,CAAC,EAAE,QAAQ,IAAI,OAAO,MAAM,MAAM;AAAA,YAC3C;AAAA,YACA,EAAE,IAAI,OAAO,MAAM;AAAA,UACrB,CAAC;AAAA,QACH;AACA,eAAO,MAAM,MAAM,oBAAU;AAAA,MAC/B;AAAA,IACF;AAAA,EACF,OAAO;AACL,WAAO;AAAA,MACL,SAAS,MAAM;AAAA,MAAC;AAAA,MAChB,YAAY,MAAM;AAAA,MAAC;AAAA,MACnB,QAAQ,MAAM;AAAA,MAAC;AAAA,MACf,OAAO,MAAM;AAAA,MAAC;AAAA,MACd,SAAS,MAAM;AAAA,MAAC;AAAA,IAClB;AAAA,EACF;AACF;;;AO3LA,QAAQ,KAAK,UAAU,OAAO,QAAc;AAC1C,SAAO,KAAK,KAAK,QAAQ;AACzB,QAAM,eAAe,MAAM;AAC7B,CAAC;AACD,QAAQ,KAAK,WAAW,OAAO,QAAc;AAC3C,SAAO,KAAK,KAAK,SAAS;AAC1B,QAAM,eAAe,MAAM;AAC7B,CAAC;AACD,QAAQ,KAAK,qBAAqB,OAAO,QAAc;AACrD,SAAO,MAAM,KAAK,oBAAoB;AACtC,QAAM,eAAe,OAAO;AAC9B,CAAC;AACD,QAAQ,KAAK,sBAAsB,OAAO,QAAc;AACtD,SAAO,MAAM,KAAK,qBAAqB;AACvC,QAAM,eAAe,OAAO;AAC9B,CAAC;;;AClBD,IAAAC,iBAA2B;AAC3B,oBAAyB;;;ACMzB,oBAA2B;AAiC3B,eAAsB,KACpB,UACe;AACf,MAAI;AACF,UAAM,EAAE,IAAI,QAAQ,MAAM,MAAM,QAAQ,IAAI,SAAS;AACrD,UAAM,UAAU,MAAM,MAAM,EAAE;AAAA,MAC5B;AAAA,MACA,CAAC,EAAE,MAAM,YAAY,MAAM,SAAS,MAAM,CAAC;AAAA,MAC3C;AAAA,QACE,aAAa,KAAK;AAAA,QAClB,WAAW,EAAE,OAAO,EAAE,IAAI,MAAsB,OAAO,EAAE;AAAA,MAC3D;AAAA,MACA;AAAA;AAAA,IACF;AACA,WAAO,MAAM,SAAS,gBAAS;AAAA,EACjC,SAAS,OAAO;AACd,WAAO,MAAM,KAAK;AAAA,EACpB;AACF;AAgBA,eAAsB,KAKpB,IACA,QACA,UACyB;AACzB,MAAIC,SAAQ,GAAG,OAAO,GAAG,KAAK,IAAK,CAAC;AACpC,MAAI,UAAU;AACd,MAAI,QAAQ;AACZ,MAAI;AACJ,QAAM,MAAM,EAAE;AAAA,IACZ,CAAC,MAAM;AACL,cAAQ;AACR,UAAI,EAAE,SAAS,YAAY;AACzB,QAAAA,SAAQ,EAAE;AACV;AACA,kBAAU;AAAA,MACZ,WAAW,GAAG,MAAM,EAAE,IAAI,GAAG;AAC3B,QAAAA,SAAQ,MAAMA,QAAO,GAAG,MAAM,EAAE,IAAI,EAAE,OAAOA,MAAK,CAAC;AACnD;AAAA,MACF;AACA,kBAAY,SAAS,EAAE,OAAO,OAAAA,QAAO,SAAS,MAAM,CAAC;AAAA,IACvD;AAAA,IACA,EAAE,QAAQ,YAAY,KAAK;AAAA,EAC7B;AACA,SAAO,MAAMA,QAAiB,kBAAW,MAAM,EAAE;AACjD,SAAO,EAAE,OAAO,OAAAA,QAAO,SAAS,MAAM;AACxC;AAsBA,eAAsB,OAMpB,IACAC,SACA,QACA,SACA,YACA,iBAAiB,OACU;AAC3B,QAAM,EAAE,QAAQ,iBAAiB,MAAM,IAAI;AAC3C,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,uBAAuB;AAEpD,YAAU,iBACN,UACA,SAASA,SAAkB,SAAS,GAAG,QAAQA,OAAM,CAAC;AAE1D,QAAM,WAAW,MAAM,KAAK,IAAI,MAAM;AACtC,QAAM,WAAW,mBAAmB,SAAS,OAAO;AAEpD,SAAO;AAAA,IACL;AAAA,IACA,aAAM,MAAM,IAAIA,OAAgB,GAAG,OAAO,aAAa,WAAW,IAAI,QAAQ,KAAK,EAAE;AAAA,EACvF;AAEA,MAAI,GAAG,OAAO;AACZ,UAAM,aAAa,GAAG,MAAMA,OAAM,KAAK,CAAC;AACxC,eAAW,QAAQ,CAAC,EAAE,OAAO,YAAY,MAAM;AAC7C,UAAI,CAAC,MAAM,SAAS,OAAO,KAAK;AAC9B,cAAM,IAAI;AAAA,UACRA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,IACJ,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,GAAG,GAAGA,OAAM,EAAE,SAAS,UAAU,MAAM;AACtD,MAAI,CAAC,OAAQ,QAAO,CAAC,QAAQ;AAG7B,MAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,GAAG;AAChD,WAAO,CAAC,QAAQ;AAAA,EAClB;AAEA,QAAM,SAAS,MAAM,QAAQ,OAAO,CAAC,CAAC,IACjC,SACA,CAAC,MAAM;AAEZ,QAAM,UAAU,OAAO,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO;AAAA,IAC5C;AAAA,IACA,MAAM,iBACF,OACA,SAAS,MAAgB,MAAM,GAAG,OAAO,IAAI,CAAC;AAAA,EACpD,EAAE;AAEF,QAAM,OAAkB;AAAA,IACtB,aAAa,YAAY,KAAK,mBAAe,0BAAW;AAAA,IACxD,WAAW;AAAA,MACT,QAAQ;AAAA,QACN,MAAMA;AAAA,QACN,GAAG;AAAA;AAAA;AAAA,MAGL;AAAA,MACA,OAAO,aACH;AAAA,QACE,IAAI,WAAW;AAAA,QACf,MAAM,WAAW;AAAA,QACjB,QAAQ,WAAW;AAAA,MACrB,IACA;AAAA,IACN;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,IACzB,oBAAa,MAAM,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,EAC9D;AAEA,QAAM,YAAY,MAAM,MAAM,EAAE;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,aAAa,SAAY;AAAA,EAC3B;AAEA,MAAI,EAAE,OAAAD,QAAO,QAAQ,IAAI;AACzB,QAAM,YAAY,UAAU,IAAI,CAAC,UAAU;AACzC,IAAAA,SAAQ,MAAMA,QAAO,GAAG,MAAM,MAAM,IAAI,EAAE,OAAOA,MAAK,CAAC;AACvD;AACA,WAAO,EAAE,OAAO,OAAAA,QAAO,SAAS,OAAO,SAAS,MAAM;AAAA,EACxD,CAAC;AAGD,QAAM,OAAO,UAAU,GAAG,EAAE;AAC5B,KAAG,QAAQ,GAAG,KAAK,IAAI,KAAK,KAAK,KAAK,IAAI;AAE1C,SAAO;AACT;;;ADlNA,IAAM,SAAS,aAAa,OAAO,EAAE,QAAQ;AA0BtC,IAAM,MAAN,MAIL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6DA,YAA4B,UAA6B;AAA7B;AAC1B,YAAQ,MAAM;AACZ,WAAK,SAAS,mBAAmB;AACjC,WAAK,kBAAkB;AACvB,aAAO,QAAQ,QAAQ;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAlEQ,WAAW,IAAI,cAAAE,QAAa;AAAA,EAC5B,gBAAgB;AAAA,EAChB,wBAAwB;AAAA,EACxB,wBAAoD;AAAA,EAY5D,KAAK,OAAe,MAAoB;AACtC,WAAO,KAAK,SAAS,KAAK,OAAO,IAAI;AAAA,EACvC;AAAA,EAeA,GAAG,OAAe,UAAqC;AACrD,SAAK,SAAS,GAAG,OAAO,QAAQ;AAChC,WAAO;AAAA,EACT;AAAA,EAeA,IAAI,OAAe,UAAqC;AACtD,SAAK,SAAS,IAAI,OAAO,QAAQ;AACjC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BA,MAAM,GACJC,SACA,QACA,SACA,YACA,iBAAiB,OACjB;AACA,UAAM,YAAY,MAAS;AAAA,MACzB,KAAK,SAAS,QAAQA,OAAM;AAAA,MAC5BA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,IACF;AACA,SAAK,KAAK,aAAa,SAA6B;AACpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,KACJC,QACA,QACA,UAC2B;AAC3B,WAAO,MAAS,KAAKA,QAAO,QAAQ,QAAQ;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,MACJ,OACA,UAKC;AACD,QAAI,QAA2C,QAC7C,OAA0C;AAC5C,UAAM,QAAQ,MAAM,MAAM,EAAE,MAAS,CAAC,MAAM;AAC1C,OAAC,UAAU,QAAQ;AACnB,aAAO;AACP,kBAAY,SAAS,CAAC;AAAA,IACxB,GAAG,KAAK;AACR,WAAO,EAAE,OAAO,MAAM,MAAM;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,YAAY,OAAgD;AAChE,UAAM,SAAkC,CAAC;AACzC,UAAM,MAAM,EAAE,MAAS,CAAC,MAAM,OAAO,KAAK,CAAC,GAAG,KAAK;AACnD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAc,OACZ,OACA,UAOC;AAED,QAAI,SAAS,WAAW,EAAG,QAAO,EAAE,OAAO,SAAS,GAAG,IAAI,MAAM,GAAG;AAEpE,UAAM,SAAS,MAAM;AACrB,QAAI,KAAK,SAAS,GAAG,CAAC,EAAG,MAAM,IAC7B,UAAU;AAEZ,UAAM,QAAQ,KACZ,OAAO,KAAK,YAAY,MAAM,IAAI,EAAE,KAAK,MAAM,KAAK,IAAI;AAE1D,eAAW,WAAW,UAAU;AAC9B,YAAM,EAAE,OAAO,SAAS,QAAQ,IAAI;AACpC,UAAI;AACF,cAAM,QAAQ,OAAO,MAAM;AAC3B,aAAK,MAAM;AACX;AAAA,MACF,SAAS,OAAO;AACd,eAAO,MAAM,KAAK;AAClB,cAAM,QAAQ,MAAM,SAAS,QAAQ,cAAc,QAAQ;AAC3D,iBACE,OAAO,MAAM,YAAY,MAAM,UAAU,MAAM,KAAK,WAAW;AACjE,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA;AAAA,UAEA,OAAO,YAAY,IAAK,MAAgB,UAAU;AAAA,UAClD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,EAAE,OAAO,SAAS,GAAG;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,MAAyB;AAAA,IAC7B,cAAc;AAAA,IACd,aAAa;AAAA,IACb,cAAc;AAAA,EAChB,IAAkB,CAAC,GAAsB;AACvC,QAAI,CAAC,KAAK,eAAe;AACvB,UAAI;AACF,aAAK,gBAAgB;AACrB,cAAM,UAAU,KAAK,KAAK,cAAc,KAAK,qBAAqB;AAClE,cAAM,UAAU,cAAc;AAC9B,cAAM,SAAS,MAAM,MAAM,EAAE,KAAK,SAAS,OAAO;AAClD,cAAM,UAAU,MAAM,QAAQ;AAAA,UAC5B,OAAO,IAAI,OAAO,EAAE,QAAQ,QAAQ,IAAI,SAAAC,SAAQ,MAAM;AACpD,kBAAM,SAAS,MAAM,KAAK,YAAY;AAAA,cACpC,QAAQ;AAAA,cACR,OAAO;AAAA,cACP,OAAO;AAAA,YACT,CAAC;AACD,mBAAO,EAAE,QAAQ,QAAQ,IAAI,SAAAA,UAAS,OAAO;AAAA,UAC/C,CAAC;AAAA,QACH;AACA,YAAI,QAAQ,QAAQ;AAClB,iBAAO,QAAQ,OAAO;AAEtB,gBAAM,SAAS,oBAAI,IAGjB;AAGF,gBAAM,kBAAkB,QAAQ;AAAA,YAC9B,CAAC,KAAK,EAAE,IAAI,OAAO,MAAM,KAAK,IAAI,KAAK,OAAO,GAAG,EAAE,GAAG,MAAM,EAAE;AAAA,YAC9D;AAAA,UACF;AAEA,kBAAQ,QAAQ,CAAC,EAAE,QAAQ,SAAAA,UAAS,OAAO,MAAM;AAC/C,kBAAM,WAAW,OAAO,QAAQ,CAAC,UAAU;AACzC,oBAAM,WAAW,KAAK,SAAS,OAAO,MAAM,IAAI,KAAK,CAAC;AACtD,qBAAO,CAAC,GAAG,SAAS,UAAU,OAAO,CAAC,EACnC,OAAO,CAAC,aAAa;AACpB,sBAAM,WACJ,OAAO,SAAS,aAAa,aACzB,SAAS,SAAS,KAAK,IACvB,SAAS;AACf,uBAAO,YAAY,SAAS,WAAW;AAAA,cACzC,CAAC,EACA,IAAI,CAAC,cAAc,EAAE,GAAG,UAAU,MAAM,EAAE;AAAA,YAC/C,CAAC;AACD,mBAAO,IAAI,QAAQ;AAAA,cACjB,OAAO;AAAA,gBACL;AAAA,gBACA,QAAI,2BAAW;AAAA,gBACf,IAAI,OAAO,GAAG,EAAE,GAAG,MAAM;AAAA;AAAA,gBACzB,OAAO;AAAA,gBACP,SAAAA;AAAA,cACF;AAAA;AAAA,cAEA;AAAA,YACF,CAAC;AAAA,UACH,CAAC;AAED,gBAAM,SAAS,MAAM,MAAM,EAAE;AAAA,YAC3B,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,MAAM,KAAK;AAAA,YAC7C;AAAA,UACF;AACA,iBAAO,OAAO,MAAM;AAEpB,gBAAM,UAAU,MAAM,QAAQ;AAAA,YAC5B,OAAO;AAAA,cAAI,CAAC,UACV,KAAK,OAAO,OAAO,OAAO,IAAI,MAAM,MAAM,EAAG,QAAQ;AAAA,YACvD;AAAA,UACF;AAGA,gBAAM,CAAC,iBAAiB,eAAe,IAAI,QAAQ;AAAA,YACjD,CAAC,CAACC,kBAAiBC,gBAAe,GAAG,EAAE,OAAO,SAAAC,SAAQ,MAAM;AAAA,cAC1DF,oBAAmB,MAAM,UAAUE,WAAU;AAAA,cAC7CD,oBAAmB,MAAM,UAAU,IAAIC;AAAA,YACzC;AAAA,YACA,CAAC,GAAG,CAAC;AAAA,UACP;AACA,gBAAM,cAAc,UAAU,IAAI,kBAAkB,UAAU;AAC9D,gBAAM,cAAc,UAAU,IAAI,kBAAkB,UAAU;AAC9D,gBAAM,QAAQ,cAAc;AAC5B,eAAK,wBACH,QAAQ,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,cAAc,KAAK,CAAC,IAAI;AAElE,gBAAM,QAAQ,MAAM,MAAM,EAAE;AAAA,YAC1B,QACG,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,KAAK,EAC5B,IAAI,CAAC,EAAE,IAAI,MAAM,OAAO,EAAE,GAAG,OAAO,GAAG,EAAE;AAAA,UAC9C;AACA,cAAI,MAAM,QAAQ;AAChB,mBAAO,MAAM,KAAK;AAClB,iBAAK,KAAK,SAAS,KAAK;AAAA,UAC1B;AAEA,gBAAM,UAAU,MAAM,MAAM,EAAE;AAAA,YAC5B,QACG,OAAO,CAAC,EAAE,MAAM,MAAM,KAAK,EAC3B,IAAI,CAAC,EAAE,OAAO,MAAM,OAAO,EAAE,GAAG,OAAO,MAAc,EAAE;AAAA,UAC5D;AACA,cAAI,QAAQ,QAAQ;AAClB,mBAAO,QAAQ,OAAO;AACtB,iBAAK,KAAK,WAAW,OAAO;AAAA,UAC9B;AAGA,iBAAO,EAAE,SAAS,QAAQ,OAAO,QAAQ;AAAA,QAC3C;AAAA,MACF,SAAS,OAAO;AACd,eAAO,MAAM,KAAK;AAAA,MACpB,UAAE;AACA,aAAK,gBAAgB;AAAA,MACvB;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,GAAG,SAAS,CAAC,EAAE;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UACJ,QAAe,EAAE,OAAO,IAAI,OAAO,GAAG,GACS;AAC/C,UAAM,aAAa,oBAAI,IAAkC;AACzD,QAAI,UAAU,MAAM,SAAS;AAC7B,UAAM,MAAM,EAAE,MAAS,CAAC,UAAU;AAChC,gBAAU,MAAM;AAChB,YAAM,WAAW,KAAK,SAAS,OAAO,MAAM,IAAI;AAEhD,UAAI,UAAU;AACZ,mBAAW,YAAY,SAAS,UAAU,OAAO,GAAG;AAClD,gBAAM,WACJ,OAAO,SAAS,aAAa,aACzB,SAAS,SAAS,KAAK,IACvB,SAAS;AACf,uBAEI,WAAW,IAAI,SAAS,MAAM,KAC9B,WAAW,IAAI,SAAS,QAAQ,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,GACvD,KAAK,EAAE,GAAG,UAAU,QAAQ,SAAS,QAAQ,MAAM,CAAC;AAAA,QAC1D;AAAA,MACF;AAAA,IACF,GAAG,KAAK;AACR,QAAI,WAAW,MAAM;AACnB,YAAM,SAAS,CAAC,GAAG,WAAW,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,QAAQ,OAAO;AAAA,QACpE;AAAA;AAAA,QAEA,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU;AAAA,QAClD,QAAI,2BAAW;AAAA,QACf,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,SAAS;AAAA,QACT;AAAA,MACF,EAAE;AAEF,YAAM,SAAS,MAAM,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC5C,aAAO,UAAU,OAAO,WAAW,MAAM;AACzC,aAAO,EAAE,QAAQ,QAAQ;AAAA,IAC3B;AACA,WAAO,EAAE,QAAQ,CAAC,GAAG,QAAQ;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,mBACE,QAAe,CAAC,GAChB,YAAY,KACZ,UACS;AACT,QAAI,KAAK,sBAAuB,QAAO;AAEvC,UAAM,QAAQ,MAAM,SAAS;AAC7B,QAAI,QAAQ,MAAM,SAAS;AAC3B,SAAK,wBAAwB;AAAA,MAC3B,MACE,KAAK,UAAU,EAAE,GAAG,OAAO,OAAO,MAAM,CAAC,EACtC,KAAK,CAAC,WAAW;AAChB,gBAAQ,OAAO;AACf,YAAI,YAAY,OAAO,OAAO,OAAQ,UAAS,OAAO,MAAM;AAAA,MAC9D,CAAC,EACA,MAAM,QAAQ,KAAK;AAAA,MACxB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB;AAClB,QAAI,KAAK,uBAAuB;AAC9B,oBAAc,KAAK,qBAAqB;AACxC,WAAK,wBAAwB;AAAA,IAC/B;AAAA,EACF;AACF;;;AE1dA,IAAM,SAAS,CAAC,EAAE,OAAO,OAA2B;AAAA,EAClD,QAAQ;AAAA,EACR,QAAQ;AACV;AAEA,IAAM,SAAS,MAAM;AAoGd,SAAS,IAMd,SAAsB,oBAAI,IAAI,GAC9B,WAA8B;AAAA,EAC5B,SAAS,CAAC;AAAA,EACV,QAAQ,CAAC;AACX,GACqB;AACrB,QAAM,UAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUnC,MAAM,CACJC,WACG;AACH,UAAI,CAAC,OAAO,IAAIA,OAAM,IAAI,GAAG;AAC3B,eAAO,IAAIA,OAAM,IAAI;AACrB,mBAAW,QAAQ,OAAO,KAAKA,OAAM,OAAO,GAAG;AAC7C,cAAI,SAAS,QAAQ,IAAI;AACvB,kBAAM,IAAI,MAAM,qBAAqB,IAAI,GAAG;AAE9C,mBAAS,QAAQ,IAAI,IAAIA;AAAA,QAC3B;AACA,mBAAW,QAAQ,OAAO,KAAKA,OAAM,MAAM,GAAG;AAC5C,cAAI,SAAS,OAAO,IAAI;AACtB,kBAAM,IAAI,MAAM,oBAAoB,IAAI,GAAG;AAE7C,mBAAS,OAAO,IAAI,IAAI;AAAA,YACtB,QAAQA,OAAM,OAAO,IAAI;AAAA,YACzB,WAAW,oBAAI,IAAI;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,MAKF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA,IAAI,CAAoB,WAAc;AAAA,MACpC,IAAI,CACF,SACA,YACG;AACH,cAAM,WAA2B;AAAA,UAC/B;AAAA,UACA,UAAU;AAAA,UACV,SAAS;AAAA,YACP,cAAc,SAAS,gBAAgB;AAAA,YACvC,YAAY,SAAS,cAAc;AAAA,UACrC;AAAA,QACF;AACA,iBAAS,OAAO,KAAK,EAAE,UAAU,IAAI,QAAQ,MAAM,QAAQ;AAC3D,eAAO;AAAA,UACL,GAAG;AAAA,UACH,GAAG,UAA2C;AAC5C,qBAAS,OAAO,KAAK,EAAE,UAAU,IAAI,QAAQ,MAAM;AAAA,cACjD,GAAG;AAAA,cACH,UACE,OAAO,aAAa,WAAW,EAAE,QAAQ,SAAS,IAAI;AAAA,YAC1D,CAAC;AACD,mBAAO;AAAA,UACT;AAAA,UACA,OAAO;AACL,qBAAS,OAAO,KAAK,EAAE,UAAU,IAAI,QAAQ,MAAM;AAAA,cACjD,GAAG;AAAA,cACH,UAAU;AAAA,YACZ,CAAC;AACD,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,OAAO,MAAM,IAAI,IAAa,QAAQ;AAAA,IACtC,QAAQ,SAAS;AAAA,EACnB;AACA,SAAO;AACT;;;ACjGO,SAAS,MACd,MACAC,QACiB;AACjB,SAAO;AAAA,IACL,KAAK,MAAyB;AAC5B,aAAO;AAAA,QACL,MAAwB,QAAqB;AAC3C,iBAAO;AAAA,YACL,MAAMC,QAA4B;AAChC,qBAAO,eAAyB;AAAA,gBAC9B;AAAA,gBACA,SAAS,CAAC;AAAA,gBACV,OAAAD;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,OAAAC;AAAA,gBACA,IAAI,CAAC;AAAA,cACP,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,eACPD,QACwB;AACxB,SAAO;AAAA,IACL,GAAwCE,SAAW,QAAqB;AACtE,UAAIA,WAAUF,OAAM;AAClB,cAAM,IAAI,MAAM,qBAAqBE,OAAM,GAAG;AAGhD,YAAM,UAAU,EAAE,GAAGF,OAAM,SAAS,CAACE,OAAM,GAAG,OAAO;AACrD,YAAM,KAAK,EAAE,GAAGF,OAAM,GAAG;AACzB,YAAM,SAAS,EAAE,GAAGA,OAAM,MAAM;AAEhC,eAAS,MAAM,OAAuB;AACpC,eAAOE,OAAM,IAAI;AACjB,eAAO,EAAE,KAAK;AAAA,MAChB;AAEA,eAAS,KAAK,SAAuC;AACnD,WAAGA,OAAM,IAAI;AACb,eAAO,eAA2B;AAAA,UAChC,GAAGF;AAAA,UACH;AAAA,UACA;AAAA,UACA,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA,aAAO,EAAE,OAAO,KAAK;AAAA,IACvB;AAAA,IAEA,KAAKG,OAA6C;AAChD,aAAO,eAAwB,EAAE,GAAGH,QAAO,MAAAG,MAAK,CAAC;AAAA,IACnD;AAAA,IAEA,QAAwB;AACtB,aAAOH;AAAA,IACT;AAAA,EACF;AACF;","names":["action","import_zod","import_zod","pkg","a","b","store","logLevel","stream","import_crypto","state","action","EventEmitter","action","state","lagging","lagging_handled","leading_handled","handled","state","state","patch","action","snap"]}
package/dist/index.js CHANGED
@@ -608,7 +608,7 @@ async function load(me, stream, callback) {
608
608
  },
609
609
  { stream, with_snaps: true }
610
610
  );
611
- logger.trace({ ...state2, msg: `\u{1F7E2} load ${stream}` });
611
+ logger.trace(state2, `\u{1F7E2} load ${stream}`);
612
612
  return { event, state: state2, patches, snaps };
613
613
  }
614
614
  async function action(me, action2, target, payload, reactingTo, skipValidation = false) {
@@ -617,10 +617,10 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
617
617
  payload = skipValidation ? payload : validate(action2, payload, me.actions[action2]);
618
618
  const snapshot = await load(me, stream);
619
619
  const expected = expectedVersion || snapshot.event?.version;
620
- logger.trace({
621
- ...payload,
622
- msg: `\u{1F535} ${stream}.${action2}${typeof expected === "number" ? `.${expected}` : ""}`
623
- });
620
+ logger.trace(
621
+ payload,
622
+ `\u{1F535} ${stream}.${action2}${typeof expected === "number" ? `.${expected}` : ""}`
623
+ );
624
624
  if (me.given) {
625
625
  const invariants = me.given[action2] || [];
626
626
  invariants.forEach(({ valid, description }) => {