@rotorsoft/act 0.5.2 → 0.5.3

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 { Disposable, Disposer, Store } 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","import type { Message, Schema, Schemas, 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 extends Error {\n public readonly details;\n constructor(\n name: string,\n payload: Schema,\n target: Target,\n description: string\n ) {\n super(`${name} failed invariant: ${description}`);\n this.name = Errors.InvariantError;\n this.details = { name, payload, target, description };\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 lastVersion: number,\n public readonly events: Message<Schemas, keyof Schemas>[],\n public readonly expectedVersion: number\n ) {\n super(\n `Concurrency error committing event \"${\n events.at(0)?.name\n }\". Expected version ${expectedVersion} but found version ${lastVersion}.`\n );\n this.name = Errors.ConcurrencyError;\n }\n}\n","import { ZodError, type ZodType, prettifyError } from \"zod/v4\";\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/v4\";\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 : LOG_LEVEL === \"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/v4\";\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 * Builds a Zod schema for a snapshot of state and the most recent event.\n * @param s - The state schema definition.\n * @returns A Zod schema for the snapshot object.\n */\nexport function buildSnapshotSchema<S extends StateSchema>(s: S) {\n const events = Object.entries(s.events).map(([name, zod]) =>\n z.object({\n name: z.literal(name),\n data: zod,\n id: z.number(),\n stream: z.string(),\n version: z.number(),\n created: z.date(),\n meta: EventMetaSchema,\n })\n );\n return z.object({\n state: s.state.readonly(),\n event: z.union([events[0], events[1], ...events.slice(2)]).optional(),\n patches: z.number(),\n snaps: z.number(),\n });\n}\n\n/**\n * Query options for event store queries.\n *\n * - `stream?`: Filter by stream name\n * - `names?`: Filter by event names\n * - `before?`: Filter events before this id\n * - `after?`: Filter events after this id\n * - `limit?`: Limit the number of events to return\n * - `created_before?`: Filter events created before this date/time\n * - `created_after?`: Filter events created after this date/time\n * - `backward?`: Order descending when true\n * - `correlation?`: Filter by correlation\n * - `actor?`: Filter by actor id (mainly used to reduce process managers)\n * - `loading?`: Flag when loading to optimize queries\n */\nexport const QuerySchema = z.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});\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 _at = -1;\n _retry = -1;\n _lease: Lease | undefined;\n _blocked = false;\n\n constructor(public readonly stream: string) {}\n\n /**\n * Attempt to lease this stream for processing.\n * @param lease - Lease request.\n * @returns The granted lease or undefined if blocked.\n */\n lease(lease: Lease): Lease | undefined {\n if (!this._blocked && lease.at > this._at) {\n this._lease = { ...lease, retry: this._retry + 1 };\n return this._lease;\n }\n }\n\n /**\n * Acknowledge completion of processing for this stream.\n * @param lease - Lease to acknowledge.\n */\n ack(lease: Lease) {\n if (this._lease && lease.at >= this._at) {\n this._retry = lease.retry;\n this._blocked = lease.block;\n if (!this._blocked && !lease.error) {\n this._at = lease.at;\n this._retry = 0;\n }\n this._lease = undefined;\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 }\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 const {\n stream,\n names,\n before,\n after = -1,\n limit,\n created_before,\n created_after,\n correlation,\n } = query || {};\n let i = after + 1,\n count = 0;\n while (i < this._events.length) {\n const e = this._events[i++];\n if (stream && e.stream !== stream) continue;\n if (names && !names.includes(e.name)) continue;\n if (correlation && e.meta?.correlation !== correlation) continue;\n if (created_after && e.created <= created_after) continue;\n if (before && e.id >= before) break;\n if (created_before && e.created >= created_before) break;\n callback(e as Committed<E, keyof E>);\n count++;\n if (limit && count >= limit) break;\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 instance.length - 1,\n msgs as Message<Schemas, keyof Schemas>[],\n expectedVersion\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 * Fetches new events from stream watermarks for processing.\n * @param limit - Maximum number of streams to fetch.\n * @returns Fetched streams and events.\n */\n async fetch<E extends Schemas>(limit: number) {\n const streams = [...this._streams.values()]\n .filter((s) => !s._blocked)\n .sort((a, b) => a._at - b._at)\n .slice(0, limit);\n\n const after = streams.length\n ? streams.reduce(\n (min, s) => Math.min(min, s._at),\n Number.MAX_SAFE_INTEGER\n )\n : -1;\n\n const events: Committed<E, keyof E>[] = [];\n await this.query<E>((e) => e.name !== SNAP_EVENT && events.push(e), {\n after,\n limit,\n });\n return { streams: streams.map(({ stream }) => stream), events };\n }\n\n /**\n * Lease streams for processing (e.g., for distributed consumers).\n * @param leases - Lease requests.\n * @returns Granted leases.\n */\n async lease(leases: Lease[]) {\n await sleep();\n return leases\n .map((lease) => {\n const stream =\n this._streams.get(lease.stream) ||\n // store new correlations\n this._streams\n .set(lease.stream, new InMemoryStream(lease.stream))\n .get(lease.stream)!;\n return stream.lease(lease);\n })\n .filter((l): l is Lease => !!l);\n }\n\n /**\n * Acknowledge completion of processing for leased streams.\n * @param leases - Leases to acknowledge.\n */\n async ack(leases: Lease[]) {\n await sleep();\n leases.forEach((lease) => this._streams.get(lease.stream)?.ack(lease));\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 * as es from \"./event-sourcing.js\";\nimport { logger, store } from \"./ports.js\";\nimport { ValidationError } from \"./types/errors.js\";\nimport type {\n Committed,\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\ntype SnapshotArgs = Snapshot<Schemas, Schema>;\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(\"drained\", ...)` 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\n /**\n * Emit a lifecycle event (internal use, but can be used for custom listeners).\n *\n * @param event The event name (\"committed\" or \"drained\")\n * @param args The event payload\n * @returns true if the event had listeners, false otherwise\n */\n emit(event: \"committed\", args: SnapshotArgs): boolean;\n emit(event: \"drained\", args: Lease[]): 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\" or \"drained\").\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: SnapshotArgs) => void): this;\n on(event: \"drained\", listener: (args: Lease[]) => void): 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: SnapshotArgs) => void): this;\n off(event: \"drained\", listener: (args: Lease[]) => void): this;\n off(event: string, listener: (args: any) => void): this {\n this._emitter.off(event, listener);\n return this;\n }\n\n /**\n * Create a new Act orchestrator.\n *\n * @param registry The registry of state, event, and action schemas\n * @param drainLimit The maximum number of events to drain per cycle\n */\n constructor(\n public readonly registry: Registry<S, E, A>,\n public readonly drainLimit: number\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 snapshot = await es.action(\n this.registry.actions[action],\n action,\n target,\n payload,\n reactingTo as Committed<Schemas, keyof Schemas>,\n skipValidation\n );\n this.emit(\"committed\", snapshot as SnapshotArgs);\n return snapshot;\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 * Handles leased reactions.\n *\n * @internal\n * @param lease The lease to handle\n * @param reactions The reactions to handle\n * @returns The lease\n */\n private async handle(\n lease: Lease,\n reactions: ReactionPayload<E>[]\n ): Promise<Lease> {\n const stream = lease.stream;\n\n lease.retry > 0 &&\n logger.warn(`Retrying ${stream}@${lease.at} (${lease.retry}).`);\n\n for (const reaction of reactions) {\n const { event, handler, options } = reaction;\n try {\n await handler(event, stream); // the actual reaction\n lease.at = event.id;\n } catch (error) {\n lease.error = error;\n if (error instanceof ValidationError)\n logger.error({ stream, error }, error.message);\n else logger.error(error);\n\n if (lease.retry < options.maxRetries) lease.retry++;\n else if (options.blockOnError) {\n lease.block = true;\n logger.error(`Blocked ${stream} after ${lease.retry} retries.`);\n }\n break;\n }\n }\n return lease;\n }\n\n private drainLocked = false;\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(): Promise<number> {\n if (this.drainLocked) return 0;\n this.drainLocked = true;\n\n const drained: Lease[] = [];\n const { streams, events } = await store().fetch<E>(this.drainLimit);\n\n if (events.length) {\n logger.trace(\n events\n .map(({ id, stream, name }) => ({ id, stream, name }))\n .reduce(\n (a, { id, stream, name }) => ({ ...a, [id]: { [stream]: name } }),\n {}\n ),\n \"⚡️ fetch\"\n );\n\n // correlate events to streams by reaction resolvers\n const resolved = new Set<string>(streams);\n const correlated = new Map<string, ReactionPayload<E>[]>();\n for (const event of events) {\n const register = this.registry.events[event.name];\n if (!register) continue; // skip events with no registered reactions\n for (const reaction of register.reactions.values()) {\n const stream =\n typeof reaction.resolver === \"string\"\n ? reaction.resolver\n : reaction.resolver(event);\n if (stream) {\n resolved.add(stream);\n (\n correlated.get(stream) || correlated.set(stream, []).get(stream)!\n ).push({ ...reaction, event: event });\n }\n }\n }\n\n // lease fetched & resolved streams to the position of the last fetched event\n const last = events.at(-1)!.id;\n const leases = [...resolved.values()].map((stream) => ({\n by: randomUUID(),\n stream,\n at: last,\n retry: 0,\n block: false,\n }));\n const leased = await store().lease(leases);\n logger.trace(\n leased\n .map(({ stream, at, retry }) => ({ stream, at, retry }))\n .reduce(\n (a, { stream, at, retry }) => ({ ...a, [stream]: { at, retry } }),\n {}\n ),\n \"⚡️ lease\"\n );\n\n const handling = leased\n .map((lease) => ({\n lease,\n reactions: correlated.get(lease.stream) || [],\n }))\n .filter(({ reactions }) => reactions.length);\n\n if (handling.length) {\n await Promise.allSettled(\n handling.map(({ lease, reactions }) => this.handle(lease, reactions))\n ).then(\n (promise) => {\n promise.forEach((result) => {\n if (result.status === \"rejected\") logger.error(result.reason);\n else if (!result.value.error) drained.push(result.value);\n });\n },\n (error) => logger.error(error)\n );\n drained.length && this.emit(\"drained\", drained);\n }\n\n // acknowledge leases\n await store().ack(leased);\n logger.trace(\n leased\n .map(({ stream, at, retry, block, error }) => ({\n stream,\n at,\n retry,\n block,\n error,\n }))\n .reduce(\n (a, { stream, at, retry, block, error }) => ({\n ...a,\n [stream]: { at, retry, block, error },\n }),\n {}\n ),\n \"⚡️ ack\"\n );\n }\n\n this.drainLocked = false;\n return drained.length;\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 },\n true\n );\n logger.trace({ stream, patches, snaps, state }, \"🟢 load\");\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 logger.trace(\n payload,\n `🔵 ${action as string} \"${stream}${expectedVersion ? `@${expectedVersion}` : \"\"}\"`\n );\n\n let snapshot = await load(me, stream);\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 as string,\n payload,\n target,\n description\n );\n });\n }\n\n let { state, patches } = snapshot;\n const result = me.on[action](payload, state, 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 const committed = await store().commit(\n stream,\n emitted,\n meta,\n // TODO: review reactions not enforcing expected version\n reactingTo ? undefined : expectedVersion || snapshot.event?.version\n );\n\n snapshot = committed\n .map((event) => {\n state = patch(state, me.patch[event.name](event, state));\n patches++;\n logger.trace({ event, state }, \"🔴 commit\");\n return { event, state, patches, snaps: snapshot.snaps };\n })\n .at(-1)!;\n\n me.snap && me.snap(snapshot) && void snap(snapshot); // fire and forget snaps\n return snapshot;\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 to the event stream (default)\nconst _this_ = ({ stream }: { stream: string }) => stream;\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 stream (resolver function).\n * @param resolver The resolver function\n * @returns The builder (for chaining)\n */\n to: (resolver: ReactionResolver<E, K>) => 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 retryDelayMs: options?.retryDelayMs ?? 1000,\n },\n };\n registry.events[event].reactions.set(handler.name, reaction);\n return {\n ...builder,\n to(resolver: ReactionResolver<E, K>) {\n registry.events[event].reactions.set(handler.name, {\n ...reaction,\n 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: (drainLimit = 10) => new Act<S, E, A>(registry, drainLimit),\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/v4\";\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":["import_v4","import_v4","pkg","store","import_crypto","state","action","EventEmitter","action","state","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 { Disposable, Disposer, Store } 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","import type { Message, Schema, Schemas, 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 extends Error {\n public readonly details;\n constructor(\n name: string,\n payload: Schema,\n target: Target,\n description: string\n ) {\n super(`${name} failed invariant: ${description}`);\n this.name = Errors.InvariantError;\n this.details = { name, payload, target, description };\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 lastVersion: number,\n public readonly events: Message<Schemas, keyof Schemas>[],\n public readonly expectedVersion: number\n ) {\n super(\n `Concurrency error committing event \"${\n events.at(0)?.name\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/v4\";\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/v4\";\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 : LOG_LEVEL === \"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/v4\";\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 *\n * - `stream?`: Filter by stream name\n * - `names?`: Filter by event names\n * - `before?`: Filter events before this id\n * - `after?`: Filter events after this id\n * - `limit?`: Limit the number of events to return\n * - `created_before?`: Filter events created before this date/time\n * - `created_after?`: Filter events created after this date/time\n * - `backward?`: Order descending when true\n * - `correlation?`: Filter by correlation\n * - `actor?`: Filter by actor id (mainly used to reduce process managers)\n * - `loading?`: Flag when loading to optimize queries\n */\nexport const QuerySchema = z.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});\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 _at = -1;\n _retry = -1;\n _lease: Lease | undefined;\n _blocked = false;\n\n constructor(public readonly stream: string) {}\n\n /**\n * Attempt to lease this stream for processing.\n * @param lease - Lease request.\n * @returns The granted lease or undefined if blocked.\n */\n lease(lease: Lease): Lease | undefined {\n if (!this._blocked && lease.at > this._at) {\n this._lease = { ...lease, retry: this._retry + 1 };\n return this._lease;\n }\n }\n\n /**\n * Acknowledge completion of processing for this stream.\n * @param lease - Lease to acknowledge.\n */\n ack(lease: Lease) {\n if (this._lease && lease.at >= this._at) {\n this._retry = lease.retry;\n this._blocked = lease.block;\n if (!this._blocked && !lease.error) {\n this._at = lease.at;\n this._retry = 0;\n }\n this._lease = undefined;\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 }\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 const {\n stream,\n names,\n before,\n after = -1,\n limit,\n created_before,\n created_after,\n correlation,\n } = query || {};\n let i = after + 1,\n count = 0;\n while (i < this._events.length) {\n const e = this._events[i++];\n if (stream && e.stream !== stream) continue;\n if (names && !names.includes(e.name)) continue;\n if (correlation && e.meta?.correlation !== correlation) continue;\n if (created_after && e.created <= created_after) continue;\n if (before && e.id >= before) break;\n if (created_before && e.created >= created_before) break;\n callback(e as Committed<E, keyof E>);\n count++;\n if (limit && count >= limit) break;\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 instance.length - 1,\n msgs as Message<Schemas, keyof Schemas>[],\n expectedVersion\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 * Fetches new events from stream watermarks for processing.\n * @param limit - Maximum number of streams to fetch.\n * @returns Fetched streams and events.\n */\n async fetch<E extends Schemas>(limit: number) {\n const streams = [...this._streams.values()]\n .filter((s) => !s._blocked)\n .sort((a, b) => a._at - b._at)\n .slice(0, limit);\n\n const after = streams.length\n ? streams.reduce(\n (min, s) => Math.min(min, s._at),\n Number.MAX_SAFE_INTEGER\n )\n : -1;\n\n const events: Committed<E, keyof E>[] = [];\n await this.query<E>((e) => e.name !== SNAP_EVENT && events.push(e), {\n after,\n limit,\n });\n return { streams: streams.map(({ stream }) => stream), events };\n }\n\n /**\n * Lease streams for processing (e.g., for distributed consumers).\n * @param leases - Lease requests.\n * @returns Granted leases.\n */\n async lease(leases: Lease[]) {\n await sleep();\n return leases\n .map((lease) => {\n const stream =\n this._streams.get(lease.stream) ||\n // store new correlations\n this._streams\n .set(lease.stream, new InMemoryStream(lease.stream))\n .get(lease.stream)!;\n return stream.lease(lease);\n })\n .filter((l): l is Lease => !!l);\n }\n\n /**\n * Acknowledge completion of processing for leased streams.\n * @param leases - Leases to acknowledge.\n */\n async ack(leases: Lease[]) {\n await sleep();\n leases.forEach((lease) => this._streams.get(lease.stream)?.ack(lease));\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 * as es from \"./event-sourcing.js\";\nimport { logger, store } from \"./ports.js\";\nimport { ValidationError } from \"./types/errors.js\";\nimport type {\n Committed,\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\ntype SnapshotArgs = Snapshot<Schemas, Schema>;\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(\"drained\", ...)` 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\n /**\n * Emit a lifecycle event (internal use, but can be used for custom listeners).\n *\n * @param event The event name (\"committed\" or \"drained\")\n * @param args The event payload\n * @returns true if the event had listeners, false otherwise\n */\n emit(event: \"committed\", args: SnapshotArgs): boolean;\n emit(event: \"drained\", args: Lease[]): 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\" or \"drained\").\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: SnapshotArgs) => void): this;\n on(event: \"drained\", listener: (args: Lease[]) => void): 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: SnapshotArgs) => void): this;\n off(event: \"drained\", listener: (args: Lease[]) => void): this;\n off(event: string, listener: (args: any) => void): this {\n this._emitter.off(event, listener);\n return this;\n }\n\n /**\n * Create a new Act orchestrator.\n *\n * @param registry The registry of state, event, and action schemas\n * @param drainLimit The maximum number of events to drain per cycle\n */\n constructor(\n public readonly registry: Registry<S, E, A>,\n public readonly drainLimit: number\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 snapshot = await es.action(\n this.registry.actions[action],\n action,\n target,\n payload,\n reactingTo as Committed<Schemas, keyof Schemas>,\n skipValidation\n );\n this.emit(\"committed\", snapshot as SnapshotArgs);\n return snapshot;\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 * Handles leased reactions.\n *\n * @internal\n * @param lease The lease to handle\n * @param reactions The reactions to handle\n * @returns The lease\n */\n private async handle(\n lease: Lease,\n reactions: ReactionPayload<E>[]\n ): Promise<Lease> {\n const stream = lease.stream;\n\n lease.retry > 0 &&\n logger.warn(`Retrying ${stream}@${lease.at} (${lease.retry}).`);\n\n for (const reaction of reactions) {\n const { event, handler, options } = reaction;\n try {\n await handler(event, stream); // the actual reaction\n lease.at = event.id;\n } catch (error) {\n lease.error = error;\n if (error instanceof ValidationError)\n logger.error({ stream, error }, error.message);\n else logger.error(error);\n\n if (lease.retry < options.maxRetries) lease.retry++;\n else if (options.blockOnError) {\n lease.block = true;\n logger.error(`Blocked ${stream} after ${lease.retry} retries.`);\n }\n break;\n }\n }\n return lease;\n }\n\n private drainLocked = false;\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(): Promise<number> {\n if (this.drainLocked) return 0;\n this.drainLocked = true;\n\n const drained: Lease[] = [];\n const { streams, events } = await store().fetch<E>(this.drainLimit);\n\n if (events.length) {\n logger.trace(\n events\n .map(({ id, stream, name }) => ({ id, stream, name }))\n .reduce(\n (a, { id, stream, name }) => ({ ...a, [id]: { [stream]: name } }),\n {}\n ),\n \"⚡️ fetch\"\n );\n\n // correlate events to streams by reaction resolvers\n const resolved = new Set<string>(streams);\n const correlated = new Map<string, ReactionPayload<E>[]>();\n for (const event of events) {\n const register = this.registry.events[event.name];\n if (!register) continue; // skip events with no registered reactions\n for (const reaction of register.reactions.values()) {\n const stream =\n typeof reaction.resolver === \"string\"\n ? reaction.resolver\n : reaction.resolver(event);\n if (stream) {\n resolved.add(stream);\n (\n correlated.get(stream) || correlated.set(stream, []).get(stream)!\n ).push({ ...reaction, event: event });\n }\n }\n }\n\n // lease fetched & resolved streams to the position of the last fetched event\n const last = events.at(-1)!.id;\n const leases = [...resolved.values()].map((stream) => ({\n by: randomUUID(),\n stream,\n at: last,\n retry: 0,\n block: false,\n }));\n const leased = await store().lease(leases);\n logger.trace(\n leased\n .map(({ stream, at, retry }) => ({ stream, at, retry }))\n .reduce(\n (a, { stream, at, retry }) => ({ ...a, [stream]: { at, retry } }),\n {}\n ),\n \"⚡️ lease\"\n );\n\n const handling = leased\n .map((lease) => ({\n lease,\n reactions: correlated.get(lease.stream) || [],\n }))\n .filter(({ reactions }) => reactions.length);\n\n if (handling.length) {\n await Promise.allSettled(\n handling.map(({ lease, reactions }) => this.handle(lease, reactions))\n ).then(\n (promise) => {\n promise.forEach((result) => {\n if (result.status === \"rejected\") logger.error(result.reason);\n else if (!result.value.error) drained.push(result.value);\n });\n },\n (error) => logger.error(error)\n );\n drained.length && this.emit(\"drained\", drained);\n }\n\n // acknowledge leases\n await store().ack(leased);\n logger.trace(\n leased\n .map(({ stream, at, retry, block, error }) => ({\n stream,\n at,\n retry,\n block,\n error,\n }))\n .reduce(\n (a, { stream, at, retry, block, error }) => ({\n ...a,\n [stream]: { at, retry, block, error },\n }),\n {}\n ),\n \"⚡️ ack\"\n );\n }\n\n this.drainLocked = false;\n return drained.length;\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 },\n true\n );\n logger.trace({ stream, patches, snaps, state }, \"🟢 load\");\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 logger.trace(\n payload,\n `🔵 ${action as string} \"${stream}${expectedVersion ? `@${expectedVersion}` : \"\"}\"`\n );\n\n let snapshot = await load(me, stream);\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 as string,\n payload,\n target,\n description\n );\n });\n }\n\n let { state, patches } = snapshot;\n const result = me.on[action](payload, state, 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 const committed = await store().commit(\n stream,\n emitted,\n meta,\n // TODO: review reactions not enforcing expected version\n reactingTo ? undefined : expectedVersion || snapshot.event?.version\n );\n\n snapshot = committed\n .map((event) => {\n state = patch(state, me.patch[event.name](event, state));\n patches++;\n logger.trace({ event, state }, \"🔴 commit\");\n return { event, state, patches, snaps: snapshot.snaps };\n })\n .at(-1)!;\n\n me.snap && me.snap(snapshot) && void snap(snapshot); // fire and forget snaps\n return snapshot;\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 to the event stream (default)\nconst _this_ = ({ stream }: { stream: string }) => stream;\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 stream (resolver function).\n * @param resolver The resolver function\n * @returns The builder (for chaining)\n */\n to: (resolver: ReactionResolver<E, K>) => 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 retryDelayMs: options?.retryDelayMs ?? 1000,\n },\n };\n registry.events[event].reactions.set(handler.name, reaction);\n return {\n ...builder,\n to(resolver: ReactionResolver<E, K>) {\n registry.events[event].reactions.set(handler.name, {\n ...reaction,\n 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: (drainLimit = 10) => new Act<S, E, A>(registry, drainLimit),\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/v4\";\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;;;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,cAA6B,MAAM;AAAA,EACxB;AAAA,EAChB,YACE,MACA,SACA,QACA,aACA;AACA,UAAM,GAAG,IAAI,sBAAsB,WAAW,EAAE;AAChD,SAAK,OAAO,OAAO;AACnB,SAAK,UAAU,EAAE,MAAM,SAAS,QAAQ,YAAY;AAAA,EACtD;AACF;AAUO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YACkB,aACA,QACA,iBAChB;AACA;AAAA,MACE,uCACE,OAAO,GAAG,CAAC,GAAG,IAChB,uBAAuB,eAAe,sBAAsB,WAAW;AAAA,IACzE;AARgB;AACA;AACA;AAOhB,SAAK,OAAO,OAAO;AAAA,EACrB;AACF;;;ACjFA,IAAAA,aAA2D;;;ACQ3D,SAAoB;AACpB,IAAAC,aAAkB;;;ACTlB,gBAA0C;AAYnC,IAAM,WAAW,YAAE,OAAO,YAAE,OAAO,GAAG,YAAE,MAAM,CAAC;AAK/C,IAAM,cAAc,YACxB,OAAO;AAAA,EACN,IAAI,YAAE,OAAO;AAAA,EACb,MAAM,YAAE,OAAO;AACjB,CAAC,EACA,SAAS;AAKL,IAAM,eAAe,YACzB,OAAO;AAAA,EACN,QAAQ,YAAE,OAAO;AAAA,EACjB,OAAO;AAAA,EACP,iBAAiB,YAAE,OAAO,EAAE,SAAS;AACvC,CAAC,EACA,SAAS;AAKL,IAAM,uBAAuB,YAAE,OAAO;AAAA,EAC3C,IAAI,YAAE,OAAO;AAAA,EACb,MAAM,YAAE,OAAO;AAAA,EACf,QAAQ,YAAE,OAAO;AACnB,CAAC;AAKM,IAAM,kBAAkB,YAC5B,OAAO;AAAA,EACN,aAAa,YAAE,OAAO;AAAA,EACtB,WAAW,YAAE,OAAO;AAAA,IAClB,QAAQ,aAAa,IAAI,YAAE,OAAO,EAAE,MAAM,YAAE,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS;AAAA,IAClE,OAAO,qBAAqB,SAAS;AAAA,EACvC,CAAC;AACH,CAAC,EACA,SAAS;AAKL,IAAM,sBAAsB,YAChC,OAAO;AAAA,EACN,IAAI,YAAE,OAAO;AAAA,EACb,QAAQ,YAAE,OAAO;AAAA,EACjB,SAAS,YAAE,OAAO;AAAA,EAClB,SAAS,YAAE,KAAK;AAAA,EAChB,MAAM;AACR,CAAC,EACA,SAAS;AA6BL,IAAM,cAAc,YAAE,OAAO;AAAA,EAClC,QAAQ,YAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,OAAO,YAAE,OAAO,EAAE,MAAM,EAAE,SAAS;AAAA,EACnC,QAAQ,YAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,OAAO,YAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,OAAO,YAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,gBAAgB,YAAE,KAAK,EAAE,SAAS;AAAA,EAClC,eAAe,YAAE,KAAK,EAAE,SAAS;AAAA,EACjC,UAAU,YAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,aAAa,YAAE,OAAO,EAAE,SAAS;AACnC,CAAC;;;AClFM,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,aAAE,OAAO;AAAA,EACpC,MAAM,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,SAAS,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,aAAa,aAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACxC,QAAQ,aACL,OAAO,EAAE,MAAM,aAAE,OAAO,EAAE,IAAI,CAAC,GAAG,OAAO,aAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAChE,SAAS,EACT,GAAG,aAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EACpB,SAAS;AAAA,EACZ,SAAS,aAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACpC,cAAc,aAAE,OAAO,aAAE,OAAO,GAAG,aAAE,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,aAAE,KAAK,YAAY;AAAA,EACxB,UAAU,aAAE,KAAK,SAAS;AAAA,EAC1B,eAAe,aAAE,QAAQ;AAAA,EACzB,SAAS,aAAE,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,cAAc,eACZ,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,0BAAc,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,EAMnB,YAA4B,QAAgB;AAAhB;AAAA,EAAiB;AAAA,EAL7C,MAAM;AAAA,EACN,SAAS;AAAA,EACT;AAAA,EACA,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASX,MAAM,OAAiC;AACrC,QAAI,CAAC,KAAK,YAAY,MAAM,KAAK,KAAK,KAAK;AACzC,WAAK,SAAS,EAAE,GAAG,OAAO,OAAO,KAAK,SAAS,EAAE;AACjD,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAc;AAChB,QAAI,KAAK,UAAU,MAAM,MAAM,KAAK,KAAK;AACvC,WAAK,SAAS,MAAM;AACpB,WAAK,WAAW,MAAM;AACtB,UAAI,CAAC,KAAK,YAAY,CAAC,MAAM,OAAO;AAClC,aAAK,MAAM,MAAM;AACjB,aAAK,SAAS;AAAA,MAChB;AACA,WAAK,SAAS;AAAA,IAChB;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;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,MACJ,UACA,OACA;AACA,UAAM,MAAM;AACZ,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,SAAS,CAAC;AACd,QAAI,IAAI,QAAQ,GACd,QAAQ;AACV,WAAO,IAAI,KAAK,QAAQ,QAAQ;AAC9B,YAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,UAAI,UAAU,EAAE,WAAW,OAAQ;AACnC,UAAI,SAAS,CAAC,MAAM,SAAS,EAAE,IAAI,EAAG;AACtC,UAAI,eAAe,EAAE,MAAM,gBAAgB,YAAa;AACxD,UAAI,iBAAiB,EAAE,WAAW,cAAe;AACjD,UAAI,UAAU,EAAE,MAAM,OAAQ;AAC9B,UAAI,kBAAkB,EAAE,WAAW,eAAgB;AACnD,eAAS,CAA0B;AACnC;AACA,UAAI,SAAS,SAAS,MAAO;AAAA,IAC/B;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;AAExB,YAAM,IAAI;AAAA,QACR,SAAS,SAAS;AAAA,QAClB;AAAA,QACA;AAAA,MACF;AAEF,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,EAOA,MAAM,MAAyB,OAAe;AAC5C,UAAM,UAAU,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,EACvC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EACzB,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,EAC5B,MAAM,GAAG,KAAK;AAEjB,UAAM,QAAQ,QAAQ,SAClB,QAAQ;AAAA,MACN,CAAC,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,GAAG;AAAA,MAC/B,OAAO;AAAA,IACT,IACA;AAEJ,UAAM,SAAkC,CAAC;AACzC,UAAM,KAAK,MAAS,CAAC,MAAM,EAAE,SAAS,cAAc,OAAO,KAAK,CAAC,GAAG;AAAA,MAClE;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,EAAE,SAAS,QAAQ,IAAI,CAAC,EAAE,OAAO,MAAM,MAAM,GAAG,OAAO;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAM,QAAiB;AAC3B,UAAM,MAAM;AACZ,WAAO,OACJ,IAAI,CAAC,UAAU;AACd,YAAM,SACJ,KAAK,SAAS,IAAI,MAAM,MAAM;AAAA,MAE9B,KAAK,SACF,IAAI,MAAM,QAAQ,IAAI,eAAe,MAAM,MAAM,CAAC,EAClD,IAAI,MAAM,MAAM;AACrB,aAAO,OAAO,MAAM,KAAK;AAAA,IAC3B,CAAC,EACA,OAAO,CAAC,MAAkB,CAAC,CAAC,CAAC;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,QAAiB;AACzB,UAAM,MAAM;AACZ,WAAO,QAAQ,CAAC,UAAU,KAAK,SAAS,IAAI,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC;AAAA,EACvE;AACF;;;ANjOO,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,SAASC,OAAM,SAAiB;AACxD,SAAO,WAAW,IAAI,cAAc;AACtC,CAAC;;;AOtHD,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,OAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO,MAAM,EAAE,QAAQ,SAAS,OAAO,OAAAA,OAAM,GAAG,gBAAS;AACzD,SAAO,EAAE,OAAO,OAAAA,QAAO,SAAS,MAAM;AACxC;AAsBA,eAAsB,OAMpB,IACAC,SACA,QACA,SACA,YACA,iBAAiB,OACQ;AACzB,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;AAC1D,SAAO;AAAA,IACL;AAAA,IACA,aAAMA,OAAgB,KAAK,MAAM,GAAG,kBAAkB,IAAI,eAAe,KAAK,EAAE;AAAA,EAClF;AAEA,MAAI,WAAW,MAAM,KAAK,IAAI,MAAM;AACpC,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,QACF;AAAA,IACJ,CAAC;AAAA,EACH;AAEA,MAAI,EAAE,OAAAD,QAAO,QAAQ,IAAI;AACzB,QAAM,SAAS,GAAG,GAAGC,OAAM,EAAE,SAASD,QAAO,MAAM;AACnD,MAAI,CAAC,OAAQ,QAAO;AAGpB,MAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,GAAG;AAChD,WAAO;AAAA,EACT;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,MAAMC;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,QAAM,YAAY,MAAM,MAAM,EAAE;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,aAAa,SAAY,mBAAmB,SAAS,OAAO;AAAA,EAC9D;AAEA,aAAW,UACR,IAAI,CAAC,UAAU;AACd,IAAAD,SAAQ,MAAMA,QAAO,GAAG,MAAM,MAAM,IAAI,EAAE,OAAOA,MAAK,CAAC;AACvD;AACA,WAAO,MAAM,EAAE,OAAO,OAAAA,OAAM,GAAG,kBAAW;AAC1C,WAAO,EAAE,OAAO,OAAAA,QAAO,SAAS,OAAO,SAAS,MAAM;AAAA,EACxD,CAAC,EACA,GAAG,EAAE;AAER,KAAG,QAAQ,GAAG,KAAK,QAAQ,KAAK,KAAK,KAAK,QAAQ;AAClD,SAAO;AACT;;;ADlLO,IAAM,MAAN,MAIL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkDA,YACkB,UACA,YAChB;AAFgB;AACA;AAAA,EACf;AAAA,EApDK,WAAW,IAAI,cAAAE,QAAa;AAAA,EAWpC,KAAK,OAAe,MAAoB;AACtC,WAAO,KAAK,SAAS,KAAK,OAAO,IAAI;AAAA,EACvC;AAAA,EAWA,GAAG,OAAe,UAAqC;AACrD,SAAK,SAAS,GAAG,OAAO,QAAQ;AAChC,WAAO;AAAA,EACT;AAAA,EAWA,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,EA2BA,MAAM,GACJC,SACA,QACA,SACA,YACA,iBAAiB,OACjB;AACA,UAAM,WAAW,MAAS;AAAA,MACxB,KAAK,SAAS,QAAQA,OAAM;AAAA,MAC5BA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,KAAK,aAAa,QAAwB;AAC/C,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,EAUA,MAAc,OACZ,OACA,WACgB;AAChB,UAAM,SAAS,MAAM;AAErB,UAAM,QAAQ,KACZ,OAAO,KAAK,YAAY,MAAM,IAAI,MAAM,EAAE,KAAK,MAAM,KAAK,IAAI;AAEhE,eAAW,YAAY,WAAW;AAChC,YAAM,EAAE,OAAO,SAAS,QAAQ,IAAI;AACpC,UAAI;AACF,cAAM,QAAQ,OAAO,MAAM;AAC3B,cAAM,KAAK,MAAM;AAAA,MACnB,SAAS,OAAO;AACd,cAAM,QAAQ;AACd,YAAI,iBAAiB;AACnB,iBAAO,MAAM,EAAE,QAAQ,MAAM,GAAG,MAAM,OAAO;AAAA,YAC1C,QAAO,MAAM,KAAK;AAEvB,YAAI,MAAM,QAAQ,QAAQ,WAAY,OAAM;AAAA,iBACnC,QAAQ,cAAc;AAC7B,gBAAM,QAAQ;AACd,iBAAO,MAAM,WAAW,MAAM,UAAU,MAAM,KAAK,WAAW;AAAA,QAChE;AACA;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYtB,MAAM,QAAyB;AAC7B,QAAI,KAAK,YAAa,QAAO;AAC7B,SAAK,cAAc;AAEnB,UAAM,UAAmB,CAAC;AAC1B,UAAM,EAAE,SAAS,OAAO,IAAI,MAAM,MAAM,EAAE,MAAS,KAAK,UAAU;AAElE,QAAI,OAAO,QAAQ;AACjB,aAAO;AAAA,QACL,OACG,IAAI,CAAC,EAAE,IAAI,QAAQ,KAAK,OAAO,EAAE,IAAI,QAAQ,KAAK,EAAE,EACpD;AAAA,UACC,CAAC,GAAG,EAAE,IAAI,QAAQ,KAAK,OAAO,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,GAAG,KAAK,EAAE;AAAA,UAC/D,CAAC;AAAA,QACH;AAAA,QACF;AAAA,MACF;AAGA,YAAM,WAAW,IAAI,IAAY,OAAO;AACxC,YAAM,aAAa,oBAAI,IAAkC;AACzD,iBAAW,SAAS,QAAQ;AAC1B,cAAM,WAAW,KAAK,SAAS,OAAO,MAAM,IAAI;AAChD,YAAI,CAAC,SAAU;AACf,mBAAW,YAAY,SAAS,UAAU,OAAO,GAAG;AAClD,gBAAM,SACJ,OAAO,SAAS,aAAa,WACzB,SAAS,WACT,SAAS,SAAS,KAAK;AAC7B,cAAI,QAAQ;AACV,qBAAS,IAAI,MAAM;AACnB,aACE,WAAW,IAAI,MAAM,KAAK,WAAW,IAAI,QAAQ,CAAC,CAAC,EAAE,IAAI,MAAM,GAC/D,KAAK,EAAE,GAAG,UAAU,MAAa,CAAC;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAGA,YAAM,OAAO,OAAO,GAAG,EAAE,EAAG;AAC5B,YAAM,SAAS,CAAC,GAAG,SAAS,OAAO,CAAC,EAAE,IAAI,CAAC,YAAY;AAAA,QACrD,QAAI,2BAAW;AAAA,QACf;AAAA,QACA,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,OAAO;AAAA,MACT,EAAE;AACF,YAAM,SAAS,MAAM,MAAM,EAAE,MAAM,MAAM;AACzC,aAAO;AAAA,QACL,OACG,IAAI,CAAC,EAAE,QAAQ,IAAI,MAAM,OAAO,EAAE,QAAQ,IAAI,MAAM,EAAE,EACtD;AAAA,UACC,CAAC,GAAG,EAAE,QAAQ,IAAI,MAAM,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,GAAG,EAAE,IAAI,MAAM,EAAE;AAAA,UAC/D,CAAC;AAAA,QACH;AAAA,QACF;AAAA,MACF;AAEA,YAAM,WAAW,OACd,IAAI,CAAC,WAAW;AAAA,QACf;AAAA,QACA,WAAW,WAAW,IAAI,MAAM,MAAM,KAAK,CAAC;AAAA,MAC9C,EAAE,EACD,OAAO,CAAC,EAAE,UAAU,MAAM,UAAU,MAAM;AAE7C,UAAI,SAAS,QAAQ;AACnB,cAAM,QAAQ;AAAA,UACZ,SAAS,IAAI,CAAC,EAAE,OAAO,UAAU,MAAM,KAAK,OAAO,OAAO,SAAS,CAAC;AAAA,QACtE,EAAE;AAAA,UACA,CAAC,YAAY;AACX,oBAAQ,QAAQ,CAAC,WAAW;AAC1B,kBAAI,OAAO,WAAW,WAAY,QAAO,MAAM,OAAO,MAAM;AAAA,uBACnD,CAAC,OAAO,MAAM,MAAO,SAAQ,KAAK,OAAO,KAAK;AAAA,YACzD,CAAC;AAAA,UACH;AAAA,UACA,CAAC,UAAU,OAAO,MAAM,KAAK;AAAA,QAC/B;AACA,gBAAQ,UAAU,KAAK,KAAK,WAAW,OAAO;AAAA,MAChD;AAGA,YAAM,MAAM,EAAE,IAAI,MAAM;AACxB,aAAO;AAAA,QACL,OACG,IAAI,CAAC,EAAE,QAAQ,IAAI,OAAO,OAAO,MAAM,OAAO;AAAA,UAC7C;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,EACD;AAAA,UACC,CAAC,GAAG,EAAE,QAAQ,IAAI,OAAO,OAAO,MAAM,OAAO;AAAA,YAC3C,GAAG;AAAA,YACH,CAAC,MAAM,GAAG,EAAE,IAAI,OAAO,OAAO,MAAM;AAAA,UACtC;AAAA,UACA,CAAC;AAAA,QACH;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,SAAK,cAAc;AACnB,WAAO,QAAQ;AAAA,EACjB;AACF;;;AElUA,IAAM,SAAS,CAAC,EAAE,OAAO,MAA0B;AAEnD,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,YACnC,cAAc,SAAS,gBAAgB;AAAA,UACzC;AAAA,QACF;AACA,iBAAS,OAAO,KAAK,EAAE,UAAU,IAAI,QAAQ,MAAM,QAAQ;AAC3D,eAAO;AAAA,UACL,GAAG;AAAA,UACH,GAAG,UAAkC;AACnC,qBAAS,OAAO,KAAK,EAAE,UAAU,IAAI,QAAQ,MAAM;AAAA,cACjD,GAAG;AAAA,cACH;AAAA,YACF,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,CAAC,aAAa,OAAO,IAAI,IAAa,UAAU,UAAU;AAAA,IACjE,QAAQ,SAAS;AAAA,EACnB;AACA,SAAO;AACT;;;AC9FO,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":["import_v4","import_v4","pkg","store","import_crypto","state","action","EventEmitter","action","state","state","state","patch","action","snap"]}
package/dist/index.js CHANGED
@@ -74,25 +74,6 @@ var CommittedMetaSchema = z.object({
74
74
  created: z.date(),
75
75
  meta: EventMetaSchema
76
76
  }).readonly();
77
- function buildSnapshotSchema(s) {
78
- const events = Object.entries(s.events).map(
79
- ([name, zod]) => z.object({
80
- name: z.literal(name),
81
- data: zod,
82
- id: z.number(),
83
- stream: z.string(),
84
- version: z.number(),
85
- created: z.date(),
86
- meta: EventMetaSchema
87
- })
88
- );
89
- return z.object({
90
- state: s.state.readonly(),
91
- event: z.union([events[0], events[1], ...events.slice(2)]).optional(),
92
- patches: z.number(),
93
- snaps: z.number()
94
- });
95
- }
96
77
  var QuerySchema = z.object({
97
78
  stream: z.string().optional(),
98
79
  names: z.string().array().optional(),
@@ -924,7 +905,6 @@ export {
924
905
  ValidationError,
925
906
  ZodEmpty,
926
907
  act,
927
- buildSnapshotSchema,
928
908
  config,
929
909
  dispose,
930
910
  disposeAndExit,