@walkeros/collector 4.7.0 → 4.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/code.ts","../src/constants.ts","../src/consent.ts","../src/collector-next.ts","../src/destination.ts","../src/observerEmit.ts","../src/wrapEnv.ts","../src/sanitizeArgs.ts","../src/on.ts","../src/report-error.ts","../src/buffers.ts","../src/breaker.ts","../src/source.ts","../src/transformer.ts","../src/cache.ts","../src/timeout.ts","../src/pending.ts","../src/handle.ts","../src/shutdown.ts","../src/flow.ts","../src/collector.ts","../src/push.ts","../src/command.ts","../src/elb.ts","../src/store.ts","../src/cache-store.ts","../src/store-cache-wrapper.ts"],"sourcesContent":["export * from './types';\n\nexport * from './constants';\n\nexport * from './consent';\nexport { runCollectorNext } from './collector-next';\nexport type { CollectorNextResult } from './collector-next';\nexport * from './flow';\nexport * from './push';\nexport * from './report-error';\nexport {\n isBreakerProbePermitted,\n resolveBreakerConfig,\n DEFAULT_BREAKER_THRESHOLD,\n DEFAULT_BREAKER_COOLDOWN_MS,\n} from './breaker';\nexport type { BreakerConfig, StepOutcome } from './breaker';\nexport {\n addDestination,\n createPushResult,\n destinationInit,\n destinationPush,\n initDestinations,\n mergeEnvironments,\n pushToDestinations,\n registerDestination,\n} from './destination';\nexport {\n commonHandleCommand,\n completeEvent,\n createEvent,\n enrichEvent,\n prepareEvent,\n runCollector,\n} from './handle';\nexport {\n callDestinationOn,\n enterCascade,\n fireCallbacks,\n isRequireSatisfied,\n isStateDelivery,\n isStatePresent,\n on,\n onApply,\n redeliverStateAtRun,\n setMark,\n shouldDeliver,\n} from './on';\nexport * from './source';\nexport {\n runTransformerChain,\n runTransformerBefore,\n transformerPush,\n transformerInit,\n} from './transformer';\nexport { wrapEnv } from './wrapEnv';\nexport { getCacheStore } from './cache';\n","import type { Destination, Mapping, On, WalkerOS } from '@walkeros/core';\n\nexport interface Settings {\n scripts?: string[];\n init?: string;\n on?: string;\n push?: string;\n pushBatch?: string;\n}\n\nexport interface CodeMapping extends Mapping.Rule<CodeMapping> {\n push?: string;\n pushBatch?: string;\n}\n\nexport type Types = Destination.Types<Settings, CodeMapping>;\nexport type Config = Destination.Config<Types>;\nexport type Context = Destination.Context<Types>;\nexport type PushContext = Destination.PushContext<Types>;\nexport type PushBatchContext = Destination.PushBatchContext<Types>;\n\nexport type InitFn = (context: Context) => void;\nexport type OnFn = (type: On.Types, context: Context) => void;\nexport type PushFn = (event: WalkerOS.Event, context: PushContext) => void;\nexport type PushBatchFn = (\n batch: Destination.Batch<CodeMapping>,\n context: PushBatchContext,\n) => WalkerOS.PromiseOrValue<void | Destination.BatchOutcome>;\n","import type { Collector } from '@walkeros/core';\nimport type { CommandTypes, StorageType } from './types/collector';\n\nexport const Commands: Record<CommandTypes, Collector.CommandType> = {\n Action: 'action',\n Actions: 'actions',\n Config: 'config',\n Consent: 'consent',\n Context: 'context',\n Custom: 'custom',\n Destination: 'destination',\n Elb: 'elb',\n Globals: 'globals',\n Hook: 'hook',\n Init: 'init',\n Link: 'link',\n On: 'on',\n Prefix: 'data-elb',\n Ready: 'ready',\n Run: 'run',\n Scoped: '_',\n Session: 'session',\n Shutdown: 'shutdown',\n User: 'user',\n Walker: 'walker',\n} as const;\n\nconst UtilsStorage: { [key: string]: StorageType } = {\n Cookie: 'cookie',\n Local: 'local',\n Session: 'session',\n} as const;\n\nconst Utils = {\n Storage: UtilsStorage,\n};\n\nexport const Const = {\n Commands,\n Utils,\n};\n\nexport default Const;\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport { assign } from '@walkeros/core';\n\n/**\n * Processes consent data: coerces to boolean, updates collector state.\n * Does NOT notify or process queues — caller handles that.\n */\nexport function processConsent(\n collector: Collector.Instance,\n data: WalkerOS.Consent,\n): { update: WalkerOS.Consent } {\n const update: WalkerOS.Consent = {};\n Object.entries(data).forEach(([name, granted]) => {\n update[name] = !!granted;\n });\n\n collector.consent = assign(collector.consent, update);\n\n return { update };\n}\n","import type {\n Collector,\n Ingest,\n RespondFn,\n Transformer,\n WalkerOS,\n} from '@walkeros/core';\nimport { createIngest } from '@walkeros/core';\nimport { completeEvent } from './handle';\nimport { emitCollectorDrop } from './observerEmit';\nimport { runTransformerChain } from './transformer';\n\n/** Chain path of the collector's own chain (`collector.config.next`). */\nexport const COLLECTOR_NEXT_PATH = 'collector.next';\n\n/** What `collector.next` hands to the destination fan-out. */\nexport interface CollectorNextResult {\n /**\n * Every finished copy, in order, with its own ingest; each event is\n * completed to a full event. One copy without a fork, one per surviving\n * fork after a `many` or a `Result[]` return, and none when the chain\n * dropped or halted the event.\n */\n copies: Transformer.ChainCopy<WalkerOS.Event>[];\n /** The respond in scope after the chain (a wrapped one if the chain set it). */\n respond?: RespondFn;\n /** Set when a route stop or a transformer ended every copy. */\n dropped?: true;\n}\n\n/**\n * Runs the collector's own chain (`collector.config.next`) for one completed\n * event, through the one chain runner. Called once per event by\n * `pushToDestinations`, before the event enters `collector.queue` and the\n * destination fan-out, so consent replay and late-destination backfill\n * deliver post-chain events and never run it again.\n *\n * A drop (route `stop` or a transformer returning `false`) on every copy\n * emits one `collector.push` `skip` / `dropped` record and counts the event\n * in; a `cache.stop` HIT halts delivery without a drop record, as at\n * `source.next`.\n */\nexport async function runCollectorNext(\n collector: Collector.Instance,\n event: WalkerOS.Event,\n meta: { id?: string; ingest?: Ingest; respond?: RespondFn } = {},\n): Promise<CollectorNextResult> {\n const ingest = meta.ingest ?? createIngest(meta.id || 'unknown');\n const next = collector.config.next;\n if (next === undefined) {\n return { copies: [{ event, ingest }], respond: meta.respond };\n }\n\n const result = await runTransformerChain(\n collector,\n collector.transformers || {},\n next,\n event,\n ingest,\n meta.respond,\n COLLECTOR_NEXT_PATH,\n );\n const respond = result.respond ?? meta.respond;\n\n if (result.copies.length === 0) {\n collector.logger.debug(\n `Event dropped by collector.next${\n result.droppedBy ? ` (${result.droppedBy})` : ''\n }`,\n );\n emitCollectorDrop(\n collector,\n event,\n ingest,\n result.droppedBy,\n COLLECTOR_NEXT_PATH,\n );\n return { copies: [], respond, dropped: true };\n }\n\n // A `cache.stop` HIT: the chain halted on purpose, nothing is delivered.\n if (result.stopped) return { copies: [], respond };\n\n // The runner owns identity (every copy keeps or derives its id). Only\n // missing fields are completed: the chain's edits to globals, user and\n // consent stand.\n return {\n copies: result.copies.map((copy) => ({\n event: completeEvent(collector, copy.event, copy.ingest),\n ingest: copy.ingest,\n })),\n respond,\n };\n}\n","import type {\n Cache,\n Collector,\n WalkerOS,\n Elb,\n Destination,\n Transformer,\n Ingest,\n RespondFn,\n Simulation,\n} from '@walkeros/core';\nimport {\n assign,\n createMappingRoot,\n clone,\n compileCache,\n checkCache,\n storeCache,\n createIngest,\n debounce,\n emitStep,\n getId,\n getGrantedConsent,\n isDefined,\n isFunction,\n isObject,\n OBSERVE_ENV_KEY,\n processEventMapping,\n stepId,\n tryCatchAsync,\n useHooks,\n compileState,\n applyState,\n} from '@walkeros/core';\nimport { buildBaseState, journeyFields } from './observerEmit';\nimport { wrapEnv } from './wrapEnv';\nimport { sanitizeCalls } from './sanitizeArgs';\nimport {\n beginInitFlush,\n callDestinationOn,\n catchUpDestinationState,\n endInitFlush,\n enterCascade,\n getStateHold,\n isStateDelivery,\n isStateDeliveryInFlight,\n markStateLost,\n owesDestinationState,\n} from './on';\nimport type { DestinationDelivery } from './on';\nimport { resolveDestinationTimeout, withTimeout } from './timeout';\nimport { runTransformerChain, extractChainProperty } from './transformer';\nimport { getCacheStore, getStateStore } from './cache';\nimport { pushBounded, resetOverflowFlag, warnOverflowOnce } from './buffers';\nimport {\n DEFAULT_DLQ_MAX,\n bumpDropped,\n ensureDestStatus,\n buildReportError,\n errorMeta,\n} from './report-error';\nimport { reconcilePending } from './pending';\nimport { runCollectorNext } from './collector-next';\nimport {\n isBreakerOpen,\n recordStepOutcome,\n releaseProbe,\n resolveBreakerConfig,\n} from './breaker';\n\nconst DEFAULT_QUEUE_MAX = 1_000;\n/** Default upper-bound on entries per batch. Caps unbounded growth under sustained load. */\nconst DEFAULT_BATCH_SIZE = 1_000;\n/** Default upper-bound on batch age in ms. Forces flush even if debounce keeps resetting. */\nconst DEFAULT_BATCH_AGE = 30_000;\n\n/**\n * Sentinel returned by {@link destinationPush} when an event was enqueued\n * into a batch (not delivered synchronously). The aggregation pass in\n * {@link pushToDestinations} reads this to skip the per-event `count`\n * increment; counters are bumped by the flush callback instead, after\n * `pushBatch` resolves. Per PROD-004 plan Q9: increment on successful\n * flush per entry, not on enqueue.\n */\nconst BATCHED_RESULT: { batched: true } = Object.freeze({ batched: true });\n\nfunction isBatchedResult(value: unknown): boolean {\n return value === BATCHED_RESULT;\n}\n\n/**\n * Narrows a `pushBatch` return value to a {@link Destination.BatchOutcome}.\n * A destination returning `void` (the historical contract) yields whole-batch\n * semantics and never enters the partial-failure path.\n */\nfunction isBatchOutcome(value: unknown): value is Destination.BatchOutcome {\n return (\n isObject(value) && Array.isArray((value as { failed?: unknown }).failed)\n );\n}\n\n/**\n * Reserved buffer key for the destination-wide default batch created by\n * `config.batch`. A produced mappingKey is `\"<entity> <action>\"` with both\n * segments guaranteed non-empty (getMappingEvent returns no key when either\n * is empty, packages/core/src/mapping.ts:24-25), so no event-derived key can\n * begin with a space. The leading space here therefore never collides with a\n * rule buffer or the `'* *'` fallback.\n */\nconst BATCH_ALL_KEY = ' batch-all';\n\n/**\n * Normalize a batch config value to the canonical `{ wait?, size?, age? }`\n * shape. A bare number is treated as `wait` (legacy form). `undefined`\n * normalizes to an empty object so callers can chain `??` lookups.\n */\nfunction normalizeBatchOptions(\n value: number | Destination.BatchOptions | undefined,\n): { wait?: number; size?: number; age?: number } {\n if (value === undefined) return {};\n if (typeof value === 'number') return { wait: value };\n return { wait: value.wait, size: value.size, age: value.age };\n}\n\n/**\n * Adds a new destination to the collector.\n *\n * @param collector - The walkerOS collector instance.\n * @param data - The destination's init data.\n * @returns The result of the push operation.\n */\nexport async function addDestination(\n collector: Collector.Instance,\n data: Destination.Init,\n): Promise<Elb.PushResult> {\n const {\n code,\n config: dataConfig = {},\n env = {},\n before,\n next,\n cache,\n state,\n } = data;\n\n // Validate that code has a push method\n if (!isFunction(code.push)) {\n return createPushResult({\n ok: false,\n failed: {\n invalid: {\n type: 'invalid',\n error: 'Destination code must have a push method',\n },\n },\n });\n }\n\n // Code defaults sit under the caller's config, the same merge\n // registerDestination applies, so a runtime destination keeps defaults such\n // as a code-level `batch` and the require check below sees them too.\n const baseConfig = { ...code.config, ...(dataConfig || { init: false }) };\n // Merge before, next, and cache into config if provided at root level\n let config = before ? { ...baseConfig, before } : { ...baseConfig };\n if (next) config = { ...config, next };\n if (cache) config = { ...config, cache };\n if (state !== undefined && config.state === undefined)\n config = { ...config, state };\n\n let id = config.id; // Use given id\n if (!id) {\n // Generate a new id if none was given (lowercase alpha only for readability)\n do {\n id = getId(5, 'abcdefghijklmnopqrstuvwxyz');\n } while (collector.destinations[id] || collector.pending.destinations[id]);\n }\n\n // Honor `require`: a runtime destination with a require gate must wait for the\n // collector's current state to satisfy it, exactly like a startup destination\n // (initDestinations). Without this, addDestination registered + pushed\n // regardless of require. Route it through pending + reconcile: reconcile\n // activates it immediately if current state already satisfies it, otherwise it\n // stays pending until a later state change/run reconcile.\n if (config.require?.length) {\n // Store the raw Init def (before/next/cache/state at root) exactly as\n // initDestinations does; registerDestination folds the chain props on\n // activation. The map key carries the resolved id.\n collector.pending.destinations[id] = data;\n await reconcilePending(collector);\n const activated = collector.destinations[id];\n if (activated) {\n return pushToDestinations(collector, undefined, {}, { [id]: activated });\n }\n return createPushResult({ ok: true });\n }\n\n const destination: Destination.Instance = {\n ...code,\n config,\n env: mergeEnvironments(code.env, env),\n };\n\n // Add the destination\n collector.destinations[id] = destination;\n\n // Process previous events if not disabled\n if (destination.config.queue !== false)\n destination.queuePush = [...collector.queue];\n\n // A runtime destination catches up on state recorded before it existed, the\n // same way a pending destination does on activation, so its on() runs\n // before the replayed events are pushed.\n await catchUpDestinationState(collector, destination, id);\n\n return pushToDestinations(collector, undefined, {}, { [id]: destination });\n}\n\n/**\n * Mark the started destination deliveries whose destination is held right\n * now, just before a flush: that flush parks their events.\n */\nexport function markHeldForDrain(deliveries: DestinationDelivery[]): void {\n for (const delivery of deliveries)\n if (getStateHold(delivery.destination)) delivery.drain = true;\n}\n\n/**\n * Wait for started destination deliveries, each on its own: as soon as one\n * settles and its destination is no longer held, the events parked for it\n * during the flush are pushed to that destination alone. A slow delivery\n * delays only its own destination. A FatalError from a delivery propagates.\n * Returns the result of every such push.\n */\nexport async function settleDestinationDeliveries(\n collector: Collector.Instance,\n deliveries: DestinationDelivery[],\n): Promise<Elb.PushResult[]> {\n const drained = await Promise.all(\n deliveries.map(async ({ id, destination, done, drain }) => {\n await done;\n if (\n drain &&\n collector.allowed &&\n !getStateHold(destination) &&\n destination.queuePush?.length &&\n collector.destinations[id] === destination\n )\n return pushToDestinations(\n collector,\n undefined,\n {},\n { [id]: destination },\n );\n return undefined;\n }),\n );\n return drained.filter(isDefined);\n}\n\n/**\n * Fold the results of per-destination drains into a flush result, so a\n * command reports every destination its events reached. A destination queued\n * in the flush and done or failed after its drain is reported by its latest\n * outcome.\n */\nexport function mergePushResults(\n base: Elb.PushResult,\n drains: Elb.PushResult[],\n): Elb.PushResult {\n if (!drains.length) return base;\n const done = { ...(base.done ?? {}) };\n const queued = { ...(base.queued ?? {}) };\n const failed = { ...(base.failed ?? {}) };\n for (const drain of drains) {\n for (const [id, ref] of Object.entries(drain.done ?? {})) {\n done[id] = ref;\n delete queued[id];\n }\n for (const [id, ref] of Object.entries(drain.failed ?? {})) {\n failed[id] = ref;\n delete queued[id];\n }\n Object.assign(queued, drain.queued ?? {});\n }\n const merged: Elb.PushResult = {\n ...base,\n ok: base.ok && drains.every((drain) => drain.ok),\n };\n delete merged.done;\n delete merged.queued;\n delete merged.failed;\n if (Object.keys(done).length) merged.done = done;\n if (Object.keys(queued).length) merged.queued = queued;\n if (Object.keys(failed).length) merged.failed = failed;\n return merged;\n}\n\n/**\n * Pushes an event to all or a subset of destinations.\n *\n * A completed event first runs the collector's own chain\n * (`collector.config.next`), once, and every copy it hands back is delivered.\n * A flush call (no event) delivers what the destinations have queued and\n * never runs the chain: queued events are already post-chain.\n *\n * @param collector - The walkerOS collector instance.\n * @param event - The event to push.\n * @param meta - Optional metadata with id and ingest.\n * @param destinations - The destinations to push to.\n * @returns The result of the push operation.\n */\nexport async function pushToDestinations(\n collector: Collector.Instance,\n event?: WalkerOS.Event,\n meta: {\n id?: string;\n ingest?: Ingest;\n respond?: RespondFn;\n } = {},\n destinations?: Collector.Destinations,\n): Promise<Elb.PushResult> {\n // Check if collector is allowed to push\n if (!collector.allowed) return createPushResult({ ok: false });\n\n if (!event)\n return deliverToDestinations(collector, undefined, meta, destinations);\n\n const next = await runCollectorNext(collector, event, meta);\n if (next.copies.length === 0)\n return createPushResult({\n ok: true,\n ...(next.dropped ? { dropped: true } : {}),\n });\n\n // Each copy is delivered in order, as its own event with its own ingest.\n // The first delivery's result is reported, as for a source-level fan-out.\n const results: Elb.PushResult[] = [];\n for (const copy of next.copies) {\n results.push(\n await deliverToDestinations(\n collector,\n copy.event,\n { id: meta.id, ingest: copy.ingest, respond: next.respond },\n destinations,\n ),\n );\n }\n return results[0];\n}\n\n/**\n * Delivers one event (or, without one, the queued events only) to all or a\n * subset of destinations. Module-private: every caller goes through\n * `pushToDestinations`, so `collector.next` runs exactly once per event.\n */\nasync function deliverToDestinations(\n collector: Collector.Instance,\n event: WalkerOS.Event | undefined,\n meta: {\n id?: string;\n ingest?: Ingest;\n respond?: RespondFn;\n },\n destinations?: Collector.Destinations,\n): Promise<Elb.PushResult> {\n const { user } = collector;\n\n // Add event to the collector queue (bounded; FIFO drop-oldest on overflow)\n if (event) {\n const queueMax = collector.config.queueMax;\n if (queueMax === undefined) {\n throw new Error(\n 'Collector.Config.queueMax is undefined; defaults must be seeded by collector()',\n );\n }\n const result = pushBounded(collector.queue, event, { max: queueMax });\n if (result.dropped > 0) {\n const droppedCount = bumpDropped(\n collector.status,\n stepId('collector'),\n 'queue',\n result.dropped,\n );\n warnOverflowOnce(\n collector.queue,\n collector.logger,\n 'collector.queue overflow; oldest events dropped',\n {\n buffer: 'queue',\n cap: queueMax,\n droppedCount,\n },\n );\n } else if (collector.queue.length < queueMax) {\n resetOverflowFlag(collector.queue);\n }\n collector.status.in++;\n }\n\n // Use given destinations or use internal destinations\n if (!destinations) destinations = collector.destinations;\n\n // Tests and partially initialized collectors may leave `transformers`\n // unset; routes then resolve against an empty set.\n const transformers: Transformer.Transformers = collector.transformers || {};\n\n const results = await Promise.all(\n // Process all destinations in parallel\n Object.entries(destinations || {}).map(async ([id, destination]) => {\n // Disabled destinations are completely skipped — no queuing, no init, no processing\n if (destination.config.disabled) {\n return { id, destination, skipped: true };\n }\n\n // Canonical id: the breaker gate, the failure/success accounting, and any\n // aggregation MUST all key on the SAME id. A destination whose runtime\n // `config.id` differs from its map key would otherwise touch two\n // different breaker entries (gate vs accounting), so failures never\n // accumulate against the entry the gate inspects and the breaker never\n // opens. Resolve once here and thread it through the result.\n const canonicalId = destination.config.id || id;\n const breakerKey = stepId('destination', canonicalId);\n const breakerConfig = resolveBreakerConfig(destination.config.breaker);\n\n // Circuit-breaker gate (same precedence as `config.disabled`): when the\n // breaker is open, skip the event (counted as skipped, never pushed).\n // Presence-gated: inert unless `config.breaker` is set.\n if (\n breakerConfig &&\n isBreakerOpen(\n collector.status.breakers,\n breakerKey,\n breakerConfig.cooldown,\n )\n ) {\n return { id, destination, skipped: true };\n }\n\n // Probe-settle helpers. When the gate above admitted a half-open probe,\n // EVERY post-gate path must settle it: either record an outcome (the\n // event reached the transport) or release the probe (it never did).\n // Otherwise `probing` stays true and the breaker deadlocks half-open.\n // Both are presence-gated and internally no-op unless half-open+probing.\n const recordProbe = (outcome: 'transport-failure' | 'success') => {\n if (breakerConfig) {\n recordStepOutcome(\n collector.status.breakers,\n breakerKey,\n outcome,\n breakerConfig.threshold,\n breakerConfig.cooldown,\n );\n }\n };\n const releaseProbeSlot = () => {\n if (breakerConfig) releaseProbe(collector.status.breakers, breakerKey);\n };\n\n // Return events to this destination's own queue. Bounded; FIFO\n // drop-oldest on overflow.\n const requeue = (events: WalkerOS.Events) => {\n if (!events.length) return;\n if (!destination.queuePush) destination.queuePush = [];\n const queuePush = destination.queuePush;\n const destId = destination.config.id || id;\n const bound = {\n max: destination.config.queueMax ?? DEFAULT_QUEUE_MAX,\n };\n let totalDropped = 0;\n for (const queued of events) {\n const r = pushBounded(queuePush, queued, bound);\n totalDropped += r.dropped;\n }\n if (totalDropped > 0) {\n // Ensure status entry exists for early-overflow paths.\n ensureDestStatus(collector, destId);\n const droppedCount = bumpDropped(\n collector.status,\n stepId('destination', destId),\n 'queue',\n totalDropped,\n );\n warnOverflowOnce(\n queuePush,\n collector.logger.scope(destination.type || 'unknown'),\n 'destination.queuePush overflow; oldest events dropped',\n {\n buffer: 'queuePush',\n destination: destId,\n cap: bound.max,\n droppedCount,\n },\n );\n } else if (queuePush.length < bound.max) {\n resetOverflowFlag(queuePush);\n }\n };\n\n // A held destination retries its owed state before its push, so a\n // handler that failed once and would settle now recovers without waiting\n // for another state command. Rate-limited by the hold's own age to one\n // attempt per timeout window, and never while a state delivery to it is\n // running: a permanently hung handler costs one bounded wait per window,\n // never one per event. The retry is inside this destination's own\n // closure, so siblings are untouched.\n // An initialized destination that is not held but owes state (a cell\n // merged at `walker run` before the run's re-delivery reached it)\n // receives that state before this push, the same way a held one\n // retries, but without waiting for a window.\n if (\n destination.on &&\n destination.config.init &&\n !getStateHold(destination) &&\n !isStateDeliveryInFlight(destination) &&\n owesDestinationState(collector, destination)\n )\n await catchUpDestinationState(collector, destination, id);\n\n const hold = getStateHold(destination);\n if (\n hold &&\n !isStateDeliveryInFlight(destination) &&\n Date.now() - hold.since >=\n resolveDestinationTimeout(destination.config.timeout)\n )\n await catchUpDestinationState(collector, destination, id);\n\n // State hold: a state delivery to this destination is running or did\n // not settle. Its events stay in its own queue, nothing is delivered,\n // and the queue is not drained. Held, not dropped.\n if (getStateHold(destination)) {\n releaseProbeSlot(); // probe admitted but the destination is held\n if (!event) return { id, destination, skipped: true };\n const held = [clone(event)];\n requeue(held);\n return { id, destination, queue: held };\n }\n\n // Queued events: refresh consent (full replace — stale consent must not persist).\n // User merge happens for all events below in allowedEvents.map.\n let currentQueue = (destination.queuePush || []).map((event) => ({\n ...event,\n consent: collector.consent,\n }));\n destination.queuePush = [];\n\n // Current event: added as-is (consent is already fresh from createEvent).\n if (event) currentQueue.push(clone(event));\n\n // Clone ingest for this destination (prevents cross-destination races in Promise.all)\n const destIngest: Ingest = meta.ingest\n ? {\n ...meta.ingest,\n _meta: { ...meta.ingest._meta, path: [...meta.ingest._meta.path] },\n }\n : createIngest('unknown');\n\n // If no events and no queued on events, skip this destination\n if (!currentQueue.length && !destination.queueOn?.length) {\n releaseProbeSlot(); // probe admitted but no event to push\n return { id, destination, skipped: true };\n }\n\n // If only on events queued (no push events), still init to flush queueOn.\n // Direct try/catch + logger.error here is intentional. Previously this\n // used tryCatchAsync(destinationInit) without an onError callback, which\n // silently returned undefined when init threw, hiding real failures on\n // the queueOn-only path. Mirrors the same pattern used below at the main\n // init call site so failures are never silent on either branch.\n if (!currentQueue.length && destination.queueOn?.length) {\n // Consent gate (sole-gate invariant): this branch would init the\n // destination purely to flush queued on() events, but there is no push\n // event whose individual consent could apply, so collector consent is\n // the complete basis. Never init a consent-gated destination while its\n // required consent is denied. Self-heals: handle.ts runs\n // pushToDestinations after every state command, so the grant command\n // re-enters here with consent satisfied and inits then.\n if (!getGrantedConsent(destination.config.consent, collector.consent)) {\n releaseProbeSlot(); // probe admitted but consent gate denies push\n return { id, destination, skipped: true };\n }\n let isInitialized = false;\n try {\n isInitialized = await destinationInit(\n collector,\n destination,\n id,\n true,\n );\n } catch (err) {\n collector.status.failed++;\n const destType = destination.type || 'unknown';\n collector.logger.scope(destType).error('destination init failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n // A probe whose init throws is a real transport failure: re-open.\n recordProbe('transport-failure');\n }\n // The flush held the destination: there are no events of this call\n // to requeue, and any parked by a concurrent push stay queued.\n if (getStateHold(destination)) {\n releaseProbeSlot();\n return { id, destination, skipped: true };\n }\n // Events parked by a concurrent push while the flush was running go\n // out with this call, through the consent gate below.\n if (isInitialized && destination.queuePush?.length) {\n currentQueue = destination.queuePush.map((queued) => ({\n ...queued,\n consent: collector.consent,\n }));\n destination.queuePush = [];\n } else {\n // queueOn-only flush exercises no push, so a successful/false-returning\n // init releases the probe (the transport-failure path already re-opened\n // it, where release is a no-op).\n releaseProbeSlot();\n return { id, destination, skipped: !isInitialized };\n }\n }\n\n // Per-event consent gate: granted events keep only their granted\n // states and are delivered, denied events emit a skip state so\n // observers see the gate decision, and stay queued. The collector state\n // is read at call time: this closure awaits, and a consent command can\n // run in between.\n const admit = (queue: WalkerOS.Events) => {\n const consent = collector.consent;\n const allowed: WalkerOS.Events = [];\n const skipped = queue.filter((queuedEvent) => {\n const grantedConsent = getGrantedConsent(\n destination.config.consent, // Required\n consent, // Current collector state\n queuedEvent.consent, // Individual event state\n );\n\n if (grantedConsent) {\n queuedEvent.consent = grantedConsent; // Save granted consent states only\n\n allowed.push(queuedEvent); // Add to allowed queue\n return false; // Remove from destination queue\n }\n\n const skipState = buildBaseState(collector, {\n stepId: stepId('destination', id),\n stepType: 'destination',\n phase: 'skip',\n eventId: typeof queuedEvent.id === 'string' ? queuedEvent.id : '',\n now: Date.now(),\n ...journeyFields(queuedEvent, destIngest, collector),\n });\n skipState.skipReason = 'consent';\n if (consent) skipState.consent = { ...consent };\n if (destination.config.consent) {\n skipState.meta = { required: { ...destination.config.consent } };\n }\n emitStep(collector, skipState);\n\n return true; // Keep denied events in the queue\n });\n return { allowed, skipped };\n };\n\n const admittedWith = collector.consent;\n const { allowed: allowedEvents, skipped: skippedEvents } =\n admit(currentQueue);\n\n // Add skipped (consent-denied) events back to the queue.\n requeue(skippedEvents);\n\n // Execution shall not pass if no events are allowed\n if (!allowedEvents.length) {\n releaseProbeSlot(); // probe admitted but every event was re-queued\n return { id, destination, queue: currentQueue }; // Don't push if not allowed\n }\n\n // Events present in the queue before init: the consent-denied ones just\n // requeued. Anything else found there after init was parked by a\n // concurrent push while the init flush was running.\n const parked = new Set(destination.queuePush);\n\n // Initialize the destination if needed.\n // Direct try/catch + logger.error here is intentional. Previously this\n // used tryCatchAsync(destinationInit) without an onError callback, which\n // silently returned undefined when init threw, hiding real failures. The\n // destination itself may also log a more specific error before throwing;\n // this is the boundary safety net so failures are never silent.\n // Allowed: at least one event cleared the per-event consent gate above,\n // so initialization is authorized (true) for the chokepoint guard.\n let isInitialized = false;\n try {\n isInitialized = await destinationInit(collector, destination, id, true);\n } catch (err) {\n collector.status.failed++;\n const destType = destination.type || 'unknown';\n collector.logger.scope(destType).error('destination init failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n // A probe whose init throws is a real transport failure (the down\n // destination is exactly the one whose init throws): re-open with a\n // fresh window so self-heal does not deadlock.\n recordProbe('transport-failure');\n }\n\n if (!isInitialized) {\n // Init returned false (no throw): the probe never pushed, so release it\n // (no-op if the throw path above already re-opened).\n releaseProbeSlot();\n return { id, destination, queue: currentQueue };\n }\n\n // The init flush held the destination: a state delivery did not settle.\n // The allowed events go back to its queue; the denied ones are there\n // already.\n if (getStateHold(destination)) {\n releaseProbeSlot();\n requeue(allowedEvents);\n return { id, destination, queue: allowedEvents };\n }\n\n // A consent command ran while init was awaited: the events admitted\n // before it pass the gate again with the consent that holds now.\n const deniedAfter: WalkerOS.Events = [];\n if (collector.consent !== admittedWith) {\n const regated = admit(\n allowedEvents.map((queued) => ({\n ...queued,\n consent: collector.consent,\n })),\n );\n allowedEvents.splice(0, allowedEvents.length, ...regated.allowed);\n deniedAfter.push(...regated.skipped);\n }\n\n // Events parked by a concurrent push while the init flush was running\n // pass the same consent gate, with the consent that holds now, and go\n // out with this call.\n const queuedAfter = destination.queuePush || [];\n const arrived = queuedAfter.filter((queued) => !parked.has(queued));\n if (arrived.length) {\n destination.queuePush = queuedAfter.filter((queued) =>\n parked.has(queued),\n );\n const late = admit(\n arrived.map((queued) => ({ ...queued, consent: collector.consent })),\n );\n allowedEvents.push(...late.allowed);\n deniedAfter.push(...late.skipped);\n }\n requeue(deniedAfter);\n\n if (!allowedEvents.length) {\n releaseProbeSlot(); // every event was denied after init\n return deniedAfter.length\n ? { id, destination, queue: deniedAfter }\n : { id, destination, skipped: true };\n }\n\n // Process the destinations event queue\n let error: unknown;\n let response: unknown;\n if (!destination.dlq) destination.dlq = [];\n\n // The before and next routes; each resolves per event, hop by hop,\n // with `{ ingest, event }` (the runner resolves nothing ahead).\n const before = destination.config.before;\n const nextConfig = destination.config.next;\n\n // Compile destination cache once per batch (not per-event).\n // Destination caches operate on events (HIT/MISS keyed by event fields),\n // so the rule shape is always EventCacheRule, not StoreCacheRule.\n const destCacheConfig = destination.config?.cache as\n | Cache.Cache<Cache.EventCacheRule>\n | undefined;\n const compiledDCache = destCacheConfig\n ? compileCache(destCacheConfig)\n : undefined;\n const dCacheStore = compiledDCache\n ? getCacheStore(compiledDCache, collector)\n : undefined;\n\n // Compile declarative state entries once per batch. `get` runs before\n // the mapping-to-payload push (so it can shape the pushed event); `set`\n // runs after a successful send.\n const dStateEntries = destination.config?.state\n ? compileState(destination.config.state)\n : undefined;\n const dStateGet = dStateEntries?.filter((entry) => entry.mode === 'get');\n const dStateSet = dStateEntries?.filter((entry) => entry.mode === 'set');\n\n // Process allowed events and store failed ones in the dead letter queue (DLQ)\n let totalDuration = 0;\n // Count of events enqueued into a batch in this pass; the aggregation\n // below uses this to skip the synchronous `count++` for batched events\n // (counters move to the flush callback per PROD-004 plan Q9).\n let batchedCount = 0;\n // Events the destination actually received. A before-chain fan-out makes\n // this exceed allowedEvents.length, which counts what entered.\n let pushedCount = 0;\n await Promise.all(\n allowedEvents.map(async (event) => {\n // Merge collector user into event (collector as base, event overrides)\n event.user = assign(user, event.user);\n\n // Full cache check: before the before chain (skips everything on HIT)\n let cacheMiss: { key: string; ttl: number } | undefined;\n let cacheValue: unknown;\n if (compiledDCache?.stop && dCacheStore) {\n const cacheContext = createMappingRoot(destIngest, event);\n const cacheResult = await checkCache(\n compiledDCache,\n dCacheStore,\n cacheContext,\n );\n if (cacheResult?.status === 'HIT') {\n return event; // Skip before chain + push\n }\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\n }\n }\n\n // Run post-collector transformer chain if configured for this destination\n let children: Array<{ event: WalkerOS.Event; ingest: Ingest }> = [\n { event, ingest: destIngest },\n ];\n let destRespond = meta.respond;\n if (before !== undefined) {\n const chainPath = `destination.${id}.before`;\n const chainResult = await runTransformerChain(\n collector,\n transformers,\n before,\n event,\n destIngest,\n meta.respond,\n chainPath,\n );\n\n if (chainResult.copies.length === 0) {\n // Dropped or stopped: THIS destination skips the event; other\n // destinations are unaffected.\n const skipState = buildBaseState(collector, {\n stepId: stepId('destination', id),\n stepType: 'destination',\n phase: 'skip',\n eventId: typeof event.id === 'string' ? event.id : '',\n now: Date.now(),\n ...journeyFields(event, destIngest, collector),\n });\n skipState.skipReason = 'dropped';\n skipState.meta = {\n by: chainResult.droppedBy ?? 'route',\n at: chainPath,\n };\n emitStep(collector, skipState);\n return event;\n }\n\n // Update respond if the chain produced a wrapped one\n if (chainResult.respond) destRespond = chainResult.respond;\n\n // A before chain may fan one event into several. Every child is\n // delivered, each with the ingest it finished with.\n children = chainResult.copies.map((copy) => ({\n event: copy.event as WalkerOS.Event,\n ingest: copy.ingest,\n }));\n }\n\n // Delivers one child of the before chain, from the step-level cache\n // check through the destination.next chain. Runs once per child, so\n // a fan-out reaches the destination in full. Returns whether the\n // child was actually delivered.\n const deliverOne = async (\n processedEvent: WalkerOS.Event | null,\n childIngest: Ingest,\n sharedMiss: { key: string; ttl: number } | undefined,\n ): Promise<boolean> => {\n // The pre-chain key is derived from the one event that entered, so\n // a fan-out shares it and one write covers every child. A\n // step-level key is derived from THIS child, so it is the child's\n // own and must be written here.\n let cacheMiss = sharedMiss;\n let ownKey = false;\n\n // Step-level cache check: after before chain, skip only push on HIT\n if (compiledDCache && !compiledDCache.stop && dCacheStore) {\n const cacheContext = createMappingRoot(\n childIngest,\n processedEvent ?? undefined,\n );\n const cacheResult = await checkCache(\n compiledDCache,\n dCacheStore,\n cacheContext,\n );\n if (cacheResult?.status === 'HIT') {\n return false; // Skip push, deduplicated\n }\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\n ownKey = true;\n }\n }\n\n // state[get]: enrich the event before the mapping-to-payload push.\n if (dStateGet && dStateGet.length > 0 && processedEvent) {\n processedEvent = await applyState(\n dStateGet,\n (storeId) => getStateStore(storeId, collector),\n processedEvent,\n collector,\n childIngest,\n );\n }\n\n const pushStart = Date.now();\n let pushFailed = false;\n const result = await tryCatchAsync(destinationPush, (err) => {\n // Log the error with destination scope\n const destType = destination.type || 'unknown';\n collector.logger.scope(destType).error('Push failed', {\n ...errorMeta(err),\n event: processedEvent!.name,\n });\n error = err; // oh no\n pushFailed = true;\n\n // Add failed event to destinations DLQ (bounded; FIFO drop-oldest)\n const dlq = destination.dlq!;\n const destId = destination.config.id || id;\n const dlqBound = {\n max: destination.config.dlqMax ?? DEFAULT_DLQ_MAX,\n };\n const dlqResult = pushBounded(\n dlq,\n [processedEvent!, err],\n dlqBound,\n );\n if (dlqResult.dropped > 0) {\n ensureDestStatus(collector, destId);\n const droppedCount = bumpDropped(\n collector.status,\n stepId('destination', destId),\n 'dlq',\n dlqResult.dropped,\n );\n warnOverflowOnce(\n dlq,\n collector.logger.scope(destination.type || 'unknown'),\n 'destination.dlq overflow; oldest entries dropped',\n {\n buffer: 'dlq',\n destination: destId,\n cap: dlqBound.max,\n droppedCount,\n },\n );\n } else if (dlq.length < dlqBound.max) {\n resetOverflowFlag(dlq);\n }\n\n return undefined;\n })(\n collector,\n destination,\n id,\n processedEvent!,\n childIngest,\n destRespond,\n );\n totalDuration += Date.now() - pushStart;\n\n // Destination cache MISS. A per-child key is written now; the\n // shared pre-chain key is recorded and written once after every\n // child settles. The stored value is a dedup marker, since neither\n // cache check reads it back.\n if (\n cacheMiss &&\n dCacheStore &&\n destination.config.mock === undefined\n ) {\n if (ownKey) {\n storeCache(\n dCacheStore,\n cacheMiss.key,\n result ?? true,\n cacheMiss.ttl,\n );\n } else if (cacheValue === undefined) {\n cacheValue = result ?? true;\n }\n }\n\n // state[set]: stash from the event after a successful send. A\n // batched-enqueue is not a real send (the sentinel is returned\n // before delivery), so set is deferred until flush. The flush-path\n // write is a documented follow-up, not handled here yet.\n if (\n !pushFailed &&\n !isBatchedResult(result) &&\n dStateSet &&\n dStateSet.length > 0 &&\n processedEvent\n ) {\n processedEvent = await applyState(\n dStateSet,\n (storeId) => getStateStore(storeId, collector),\n processedEvent,\n collector,\n childIngest,\n );\n }\n\n // Capture the last response (for single event pushes).\n // Batched-enqueue sentinel is NOT a real response; don't surface it.\n if (result !== undefined && !isBatchedResult(result)) {\n response = result;\n }\n if (isBatchedResult(result)) batchedCount++;\n\n // Run destination.next chain after successful push\n if (!pushFailed && nextConfig) {\n // Write push response to ingest for destination.next transformers\n if (result !== undefined) {\n childIngest._response = result;\n }\n\n // Delivery already happened: a stop only ends this chain.\n const nextResult = await runTransformerChain(\n collector,\n transformers,\n nextConfig,\n processedEvent!,\n childIngest,\n destRespond,\n `destination.${id}.next`,\n );\n if (nextResult.respond) destRespond = nextResult.respond;\n }\n\n return true;\n };\n\n for (const child of children) {\n // Each child gets its own step-level cache decision; the full-check\n // miss recorded before the chain is shared, since it was computed\n // from the one event that entered. Only a child that actually\n // reached the destination counts as delivered.\n if (await deliverOne(child.event, child.ingest, cacheMiss))\n pushedCount++;\n }\n\n // One write per request, after every child settled.\n if (\n cacheMiss &&\n dCacheStore &&\n cacheValue !== undefined &&\n destination.config.mock === undefined\n ) {\n storeCache(dCacheStore, cacheMiss.key, cacheValue, cacheMiss.ttl);\n }\n\n return event;\n }),\n );\n\n return {\n id,\n destination,\n error,\n response,\n totalDuration,\n batchedCount,\n allowedCount: allowedEvents.length,\n pushedCount,\n canonicalId,\n breakerConfig,\n };\n }),\n );\n\n // Build result objects\n const done: Record<string, Destination.Ref> = {};\n const queued: Record<string, Destination.Ref> = {};\n const failed: Record<string, Destination.Ref> = {};\n\n for (const result of results) {\n if (result.skipped) continue;\n\n const destination = result.destination;\n const ref: Destination.Ref = {\n type: destination.type || 'unknown',\n data: result.response, // Capture push() return value\n };\n\n // Ensure destination status entry exists\n ensureDestStatus(collector, result.id);\n const destStatus = collector.status.destinations[result.id];\n const now = Date.now();\n\n // Refresh point-in-time buffer sizes after the destination's push pass.\n destStatus.queuePushSize = destination.queuePush?.length ?? 0;\n destStatus.dlqSize = destination.dlq?.length ?? 0;\n\n // Circuit-breaker accounting keys on the canonical stepId so it matches the\n // gate exactly. Presence-gated: only when this destination has a breaker.\n const breakerConfig = result.breakerConfig;\n const breakerKey = result.canonicalId\n ? stepId('destination', result.canonicalId)\n : undefined;\n const recordBreaker = (outcome: 'transport-failure' | 'success') => {\n if (breakerConfig && breakerKey) {\n recordStepOutcome(\n collector.status.breakers,\n breakerKey,\n outcome,\n breakerConfig.threshold,\n breakerConfig.cooldown,\n );\n }\n };\n\n if (result.error) {\n ref.error = result.error;\n failed[result.id] = ref;\n destStatus.failed++;\n destStatus.lastAt = now;\n destStatus.duration += result.totalDuration || 0;\n collector.status.failed++;\n // A single-event push that threw/timed out is a transport failure.\n recordBreaker('transport-failure');\n } else if (result.queue && result.queue.length) {\n // Events already re-queued at destination.queuePush via skippedEvents push\n queued[result.id] = ref;\n } else {\n // If every allowed event was enqueued into a batch, success counters\n // belong to the flush callback (PROD-004 plan Q9): don't increment\n // here and don't mark `done`. The flush bumps `count` and `out` when\n // pushBatch resolves. If only some events were batched, count the\n // synchronously-delivered ones.\n const batchedCount = result.batchedCount ?? 0;\n const allowedCount = result.allowedCount ?? 0;\n // What the destination actually received. A before-chain fan-out makes\n // this exceed allowedCount, which counts what entered.\n const deliveredCount = result.pushedCount ?? allowedCount;\n const syncDelivered = Math.max(0, deliveredCount - batchedCount);\n if (syncDelivered > 0 || allowedCount === 0) {\n done[result.id] = ref;\n // For non-batched destinations preserve the historical semantics\n // (one bump per pushToDestinations call, regardless of allowed\n // events count, since the original code only bumped once).\n destStatus.count++;\n destStatus.lastAt = now;\n destStatus.duration += result.totalDuration || 0;\n collector.status.out++;\n // A synchronously-delivered single-event push is a success: reset and\n // close the breaker. (Fully-batched passes settle in the flush\n // callback instead, which records its own outcome.)\n recordBreaker('success');\n }\n }\n }\n\n return createPushResult({\n event,\n ...(Object.keys(done).length && { done }),\n ...(Object.keys(queued).length && { queued }),\n ...(Object.keys(failed).length && { failed }),\n });\n}\n\n/**\n * Initializes a destination.\n *\n * @template Destination\n * @param collector - The walkerOS collector instance.\n * @param destination - The destination to initialize.\n * @param destId - The destination ID.\n * @returns Whether the destination was initialized successfully.\n */\n/**\n * A destination declares a consent requirement when its config.consent has at\n * least one key. Such a destination must never be initialized without a cleared\n * consent gate (see destinationInit's `allowed` parameter).\n */\nfunction hasConsentRequirement(destination: Destination.Instance): boolean {\n const required = destination.config.consent;\n return !!required && Object.keys(required).length > 0;\n}\n\n/**\n * Run a destination's own `init()` and return the config to install, marked\n * initialized, or false when `init()` returned false. The caller installs it.\n */\nasync function runDestinationInit(\n collector: Collector.Instance,\n destination: Destination.Instance,\n init: NonNullable<Destination.Instance['init']>,\n destId: string,\n): Promise<false | Destination.Config> {\n // Create scoped logger for this destination: [type:id] or [unknown:id]\n const destType = destination.type || 'unknown';\n const destLogger = collector.logger.scope(destType);\n\n const context: Destination.Context = {\n collector,\n logger: destLogger,\n id: destId,\n config: destination.config,\n env: mergeEnvironments(destination.env, destination.config.env),\n reportError: buildReportError(\n collector,\n 'destination',\n destId,\n destLogger,\n destination,\n ),\n };\n\n destLogger.debug('init');\n\n const initStarted = Date.now();\n emitStep(\n collector,\n buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'init',\n eventId: '',\n now: initStarted,\n }),\n );\n\n let configResult;\n try {\n configResult = await useHooks(\n init,\n 'DestinationInit',\n collector.hooks,\n collector.logger,\n )(context);\n } catch (err) {\n const initErrFinished = Date.now();\n const errState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'error',\n eventId: '',\n now: initErrFinished,\n });\n errState.durationMs = initErrFinished - initStarted;\n errState.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n emitStep(collector, errState);\n throw err;\n }\n\n // Actively check for errors (when false)\n if (configResult === false) return false; // don't push if init is false\n\n // The config to install, marked initialized; the caller installs it.\n return {\n ...(configResult || destination.config),\n init: true, // Remember that the destination was initialized\n };\n}\n\n/**\n * Initialize a destination and flush its queued `on()` deliveries. Installing\n * the initialized config and opening the flush happen in one synchronous\n * step: no delivery can see the destination initialized while its older\n * queued entries are not yet flushing, so nothing overtakes them.\n */\nasync function initAndFlush(\n collector: Collector.Instance,\n destination: Destination.Instance,\n init: NonNullable<Destination.Instance['init']>,\n destId: string,\n): Promise<boolean> {\n const config = await runDestinationInit(collector, destination, init, destId);\n if (config === false) return false; // don't push if init is false\n destination.config = config;\n\n // Flush queued on() events now that destination is initialized. The\n // queue stays live while the flush runs: a delivery that arrives in the\n // meantime is appended behind the older entries (see\n // `deliverStateToDestination`), so deliveries to this destination reach\n // its handler strictly in order. `config.init` is already set, so a\n // concurrent push would go straight out: while the flush carries a state\n // entry the hold covers the whole flush and is released once at its end.\n if (destination.queueOn?.length) {\n // The flush runs inside a cascade (the command's own, when one is open):\n // a handler that re-emits state reaches the same bound as on the live\n // path instead of appending to this queue without end.\n const exitCascade = enterCascade(collector);\n beginInitFlush(destination);\n try {\n for (\n let current = destination.queueOn?.shift();\n current;\n current = destination.queueOn?.shift()\n ) {\n await callDestinationOn(\n collector,\n destination,\n destId,\n current.type,\n current.data,\n );\n }\n } catch (err) {\n // A FatalError stopped the flush. The state entries it never reached\n // were marked when queued; they did not reach the handler, so they\n // are lost and the destination stays held until they are delivered.\n for (const { type } of destination.queueOn || []) {\n if (isStateDelivery(type)) markStateLost(collector, destination, type);\n }\n destination.queueOn = [];\n throw err;\n } finally {\n endInitFlush(collector, destination);\n exitCascade();\n }\n }\n\n collector.logger.scope(destination.type || 'unknown').debug('init done');\n return true;\n}\n\n/**\n * Inits in progress (init plus flush), per destination: a second caller (a\n * runtime add and a state command overlapping) waits for the running one\n * instead of starting another `init()`.\n */\nconst initsRunning = new WeakMap<Destination.Instance, Promise<boolean>>();\n\nexport async function destinationInit<Destination extends Destination.Instance>(\n collector: Collector.Instance,\n destination: Destination,\n destId: string,\n // Fail-closed consent gate. Callers MUST pass an affirmative allow decision\n // (per-event on the push path, collector-consent on the queueOn path). The\n // default is false so any future call site that forgets fails closed: a\n // consent-gated destination is never initialized without a cleared gate.\n allowed = false,\n): Promise<boolean> {\n // Check if the destination was initialized properly or try to do so\n if (destination.init && !destination.config.init) {\n // Defense-in-depth: refuse to init a destination that declares a consent\n // requirement unless the gate was cleared. We do NOT re-derive consent from\n // collector state here, because the push path's decision may rest on an\n // event's individual consent this function cannot see; re-deriving would\n // wrongly block a legitimate event-level override.\n if (!allowed && hasConsentRequirement(destination)) {\n collector.logger\n .scope(destination.type || 'unknown')\n .debug('init blocked: consent gate not cleared');\n return false;\n }\n // One init per destination, init and its queue flush as one unit: a\n // concurrent caller waits until the destination is initialized and\n // flushed instead of starting another init().\n const running = initsRunning.get(destination);\n if (running) return running;\n const started = initAndFlush(\n collector,\n destination,\n destination.init,\n destId,\n );\n initsRunning.set(destination, started);\n try {\n return await started;\n } finally {\n initsRunning.delete(destination);\n }\n }\n\n return true; // Destination is ready to push\n}\n\n/**\n * Pushes an event to a single destination.\n * Handles mapping, batching, and consent checks.\n *\n * @template Destination\n * @param collector - The walkerOS collector instance.\n * @param destination - The destination to push to.\n * @param destId - The destination ID.\n * @param event - The event to push.\n * @param ingest - Mutable ingest context flowing through the pipeline.\n * @returns Whether the event was pushed successfully.\n */\nexport async function destinationPush<Destination extends Destination.Instance>(\n collector: Collector.Instance,\n destination: Destination,\n destId: string,\n event: WalkerOS.Event,\n ingest?: Ingest,\n respond?: import('@walkeros/core').RespondFn,\n): Promise<unknown> {\n const { config } = destination;\n\n const processed = await processEventMapping(event, config, collector);\n\n if (processed.ignore) return false;\n\n // Create scoped logger for this destination: [type] or [unknown]\n const destType = destination.type || 'unknown';\n const destLogger = collector.logger.scope(destType);\n\n const context: Destination.PushContext = {\n collector,\n logger: destLogger,\n id: destId,\n config,\n data: processed.data,\n rule: processed.mapping,\n ingest: ingest!,\n env: {\n ...mergeEnvironments(destination.env, config.env),\n ...(respond ? { respond } : {}),\n },\n reportError: buildReportError(\n collector,\n 'destination',\n destId,\n destLogger,\n destination,\n ),\n };\n\n // Mock interception — replaces the actual destination.push() call\n if (config.mock !== undefined) {\n destLogger.debug('mock', { event: processed.event.name });\n return config.mock;\n }\n\n const eventMapping = processed.mapping;\n // Presence, not truthiness: batch: 0 is a valid 0 ms wait, not \"disabled\".\n const ruleHasBatch = eventMapping?.batch !== undefined;\n const mappingKey = ruleHasBatch\n ? processed.mappingKey || '* *'\n : BATCH_ALL_KEY;\n\n if (\n (ruleHasBatch || config.batch !== undefined) &&\n destination.pushBatch &&\n config.mock === undefined\n ) {\n // Initialize batch registry on destination (not on shared mapping config)\n destination.batches = destination.batches || {};\n\n // Get or create batch state for this mapping key\n if (!destination.batches[mappingKey]) {\n const batched: Destination.Batch<unknown> = {\n key: mappingKey,\n entries: [],\n events: [],\n data: [],\n };\n\n // Resolve scheduling options: mapping-level overrides destination-level.\n // Mapping rule `batch` (number form = wait; object = wait/size/age).\n // Destination config `batch` (number = wait; object = wait/size/age).\n const ruleOpts = normalizeBatchOptions(eventMapping?.batch);\n const destOpts = normalizeBatchOptions(config.batch);\n const wait =\n ruleOpts.wait ??\n destOpts.wait ??\n // No wait at either layer means \"rely on size/age only\"; pick a\n // long debounce so wait is effectively never the trigger.\n DEFAULT_BATCH_AGE;\n const size = ruleOpts.size ?? destOpts.size ?? DEFAULT_BATCH_SIZE;\n const age = ruleOpts.age ?? destOpts.age ?? DEFAULT_BATCH_AGE;\n\n // Capture references the flush closure needs. ingest, respond, and\n // per-event eventMapping are read from `entries`, NOT from this scope,\n // so the closure does NOT leak the first event's context.\n const baseEnv = mergeEnvironments(destination.env, config.env);\n\n const flushBatch = async (): Promise<void> => {\n const batchState = destination.batches![mappingKey];\n const currentBatched = batchState.batched;\n if (currentBatched.entries.length === 0) return;\n\n const snapshot: Destination.Batch<unknown> = {\n key: currentBatched.key,\n entries: currentBatched.entries,\n events: currentBatched.events,\n data: currentBatched.data,\n };\n currentBatched.entries = [];\n currentBatched.events = [];\n currentBatched.data = [];\n\n const rep = snapshot.entries[0];\n const batchContext: Destination.PushBatchContext = {\n collector,\n logger: destLogger,\n id: destId,\n config,\n data: undefined,\n rule: batchState.isDefault ? undefined : rep.rule,\n ingest: rep.ingest!,\n env: {\n ...baseEnv,\n ...(rep.respond ? { respond: rep.respond } : {}),\n },\n reportError: buildReportError(\n collector,\n 'destination',\n destId,\n destLogger,\n destination,\n ),\n };\n\n destLogger.debug('push batch', { events: snapshot.entries.length });\n\n const destIdResolved = destination.config.id || destId;\n const destStatus = ensureDestStatus(collector, destIdResolved);\n\n // Circuit-breaker accounting for the batch path. Keys on the canonical\n // stepId so it matches the gate. Presence-gated. A whole-batch throw is\n // a transport failure; any delivered rows (full or partial success) are\n // a success. Partial-failure rows themselves are breaker-neutral.\n const flushBreakerConfig = resolveBreakerConfig(\n destination.config.breaker,\n );\n const flushBreakerKey = stepId('destination', destIdResolved);\n const recordFlushBreaker = (\n outcome: 'transport-failure' | 'success',\n ) => {\n if (flushBreakerConfig) {\n recordStepOutcome(\n collector.status.breakers,\n flushBreakerKey,\n outcome,\n flushBreakerConfig.threshold,\n flushBreakerConfig.cooldown,\n );\n }\n };\n\n const flushStarted = Date.now();\n\n // Rows the destination named as failed, index -> that row's error. A\n // whole-batch throw fails every row instead, tracked separately so a\n // thrown `undefined` still counts as a failure.\n const failedRows = new Map<number, unknown>();\n let batchThrew = false;\n let batchError: unknown;\n\n // Routes a set of [event, error] pairs to this destination's DLQ,\n // applying the bound and emitting the overflow warning once. Shared by\n // the whole-batch failure path (pushBatch threw) and the partial-row\n // failure path (pushBatch returned a BatchOutcome).\n const routeToDlq = (failures: Array<[WalkerOS.Event, unknown]>) => {\n const dlq = (destination.dlq = destination.dlq || []);\n const dlqBound = {\n max: destination.config.dlqMax ?? DEFAULT_DLQ_MAX,\n };\n let totalDropped = 0;\n for (const pair of failures) {\n const r = pushBounded(dlq, pair, dlqBound);\n totalDropped += r.dropped;\n }\n if (totalDropped > 0) {\n const droppedCount = bumpDropped(\n collector.status,\n stepId('destination', destIdResolved),\n 'dlq',\n totalDropped,\n );\n warnOverflowOnce(\n dlq,\n destLogger,\n 'destination.dlq overflow; oldest entries dropped',\n {\n buffer: 'dlq',\n destination: destIdResolved,\n cap: dlqBound.max,\n droppedCount,\n },\n );\n } else if (dlq.length < dlqBound.max) {\n resetOverflowFlag(dlq);\n }\n destStatus.failed += failures.length;\n destStatus.dlqSize = dlq.length;\n collector.status.failed += failures.length;\n };\n\n // Number of entries treated as delivered after the flush settles.\n // Whole-batch success (void) = all; whole-batch failure (throw) = 0;\n // partial outcome = total minus the entries reported failed.\n let succeededCount = snapshot.entries.length;\n\n const batchTimeoutMs = resolveDestinationTimeout(config.timeout);\n const outcome = await tryCatchAsync(\n (\n batchArg: Destination.Batch<unknown>,\n ctxArg: Destination.PushBatchContext,\n ) =>\n withTimeout(\n Promise.resolve(\n useHooks(\n destination.pushBatch!,\n 'DestinationPushBatch',\n collector.hooks,\n collector.logger,\n )(batchArg, ctxArg),\n ),\n batchTimeoutMs,\n `Destination \"${destId}\" batch delivery timed out after ${batchTimeoutMs}ms`,\n ),\n (err) => {\n succeededCount = 0;\n batchThrew = true;\n batchError = err;\n // Route the entire batch to DLQ on a thrown/whole-batch failure.\n routeToDlq(snapshot.entries.map((entry) => [entry.event, err]));\n // Whole-batch throw is a transport failure for the breaker.\n recordFlushBreaker('transport-failure');\n destLogger.error('Push batch failed', {\n error: err instanceof Error ? err.message : String(err),\n entries: snapshot.entries.length,\n });\n return undefined;\n },\n )(snapshot, batchContext);\n\n // Partial-failure path: pushBatch resolved a BatchOutcome listing the\n // entries that did not succeed. DLQ and fail-count only those; the rest\n // are delivered. Out-of-range indices are ignored defensively.\n if (isBatchOutcome(outcome) && outcome.failed.length > 0) {\n const failedPairs: Array<[WalkerOS.Event, unknown]> = [];\n for (const failure of outcome.failed) {\n const entry = snapshot.entries[failure.index];\n if (!entry || failedRows.has(failure.index)) continue;\n const rowError =\n failure.error ??\n new Error(\n `Push batch entry ${failure.index} failed (no per-row error provided)`,\n );\n failedRows.set(failure.index, rowError);\n failedPairs.push([entry.event, rowError]);\n }\n if (failedPairs.length > 0) {\n routeToDlq(failedPairs);\n succeededCount = Math.max(\n 0,\n snapshot.entries.length - failedPairs.length,\n );\n // One entry per failure cause: the error's `code`, else its\n // `name`, with a count and the first message as a sample.\n const causes = new Map<\n string,\n { code: string; count: number; message: string }\n >();\n for (const [, rowError] of failedPairs) {\n const code =\n rowError instanceof Error &&\n 'code' in rowError &&\n typeof rowError.code === 'string'\n ? rowError.code\n : rowError instanceof Error\n ? rowError.name\n : 'Error';\n const cause = causes.get(code);\n if (cause) cause.count++;\n else\n causes.set(code, {\n code,\n count: 1,\n message:\n rowError instanceof Error\n ? rowError.message\n : String(rowError),\n });\n }\n destLogger.error('Push batch partial failure', {\n failed: failedPairs.length,\n delivered: succeededCount,\n entries: snapshot.entries.length,\n causes: [...causes.values()],\n });\n }\n }\n\n // Batch outcomes fan out one frame per entry, emitted once the flush\n // has settled so each frame states that entry's real outcome. A single\n // batch-level frame covered N events and identified none, so a failure\n // marked no event errored and every entry kept reading as delivered.\n // Each entry gets exactly one frame: a flush frame only if the\n // destination delivered that row, an error frame if it failed it (a\n // throw fails every row, a BatchOutcome fails the rows it names). A\n // failed row therefore can never also carry a delivery confirmation,\n // and the partition matches the one the DLQ and counters used above.\n // An error frame here means the row was not delivered and will not be\n // retried: nothing drains `destination.dlq`, which is a bounded\n // in-memory buffer kept for inspection and evicted oldest-first.\n const settledAt = Date.now();\n snapshot.entries.forEach((entry, index) => {\n const failed = batchThrew || failedRows.has(index);\n const journey = journeyFields(entry.event, entry.ingest, collector);\n const state = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: failed ? 'error' : 'flush',\n eventId: typeof entry.event.id === 'string' ? entry.event.id : '',\n now: settledAt,\n traceId: journey.traceId,\n sourceId: journey.sourceId,\n parentEventId: journey.parentEventId,\n });\n state.batch = { size: snapshot.entries.length, index };\n // Every frame carries the transport latency, so a batched delivery\n // is as measurable as the non-batched `out` path.\n state.durationMs = settledAt - flushStarted;\n if (failed) {\n const err = batchThrew ? batchError : failedRows.get(index);\n state.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n }\n emitStep(collector, state);\n });\n\n destLogger.debug('push batch done');\n\n // Decrement in-flight regardless of outcome.\n destStatus.inFlightBatch = Math.max(\n 0,\n (destStatus.inFlightBatch ?? 0) - snapshot.entries.length,\n );\n\n if (succeededCount > 0) {\n destStatus.count += succeededCount;\n destStatus.lastAt = Date.now();\n collector.status.out += succeededCount;\n // Any delivered rows mean the transport worked: success closes the\n // breaker. Partial-failure rows are breaker-neutral (handled by the\n // absence of a transport-failure record for them above).\n recordFlushBreaker('success');\n }\n };\n\n const scheduler = debounce(flushBatch, {\n wait,\n size,\n age,\n });\n\n destination.batches[mappingKey] = {\n batched,\n isDefault: !ruleHasBatch, // created via config.batch, not a rule's own batch\n batchFn: () => {\n void scheduler();\n },\n flush: async () => {\n await scheduler.flush();\n },\n };\n }\n\n // Add per-event entry into the batch.\n const batchState = destination.batches[mappingKey];\n batchState.batched.entries.push({\n event: processed.event,\n ingest,\n respond,\n rule: eventMapping,\n data: processed.data,\n });\n batchState.batched.events.push(processed.event);\n if (isDefined(processed.data)) batchState.batched.data.push(processed.data);\n\n // Emit a per-event in/out pair at enqueue time so observers see every\n // event that entered the batch, not just the later flush frame. Enqueue is\n // synchronous, so there is no vendor call to time and no durationMs. The\n // terminal out record carries the batch coordinates the assembler reads to\n // confirm batched delivery: size is the queue length after this enqueue,\n // index is this entry's slot. The coordinates live on the out record only.\n const batchEventId =\n typeof processed.event.id === 'string' ? processed.event.id : '';\n const batchJourney = journeyFields(event, ingest, collector);\n const enqueuedAt = Date.now();\n const batchInState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'in',\n eventId: batchEventId,\n now: enqueuedAt,\n traceId: batchJourney.traceId,\n sourceId: batchJourney.sourceId,\n parentEventId: batchJourney.parentEventId,\n });\n if (processed.mappingKey) batchInState.mappingKey = processed.mappingKey;\n if (processed.event.consent) {\n batchInState.consent = { ...processed.event.consent };\n }\n batchInState.inEvent = processed.event;\n emitStep(collector, batchInState);\n\n const batchOutState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'out',\n eventId: batchEventId,\n now: enqueuedAt,\n traceId: batchJourney.traceId,\n sourceId: batchJourney.sourceId,\n parentEventId: batchJourney.parentEventId,\n });\n if (processed.mappingKey) batchOutState.mappingKey = processed.mappingKey;\n batchOutState.outEvent = processed.event;\n batchOutState.batch = {\n size: batchState.batched.entries.length,\n index: batchState.batched.entries.length - 1,\n };\n emitStep(collector, batchOutState);\n\n // In-flight bookkeeping for operational visibility.\n const destIdResolved = destination.config.id || destId;\n const destStatus = ensureDestStatus(collector, destIdResolved);\n destStatus.inFlightBatch = (destStatus.inFlightBatch ?? 0) + 1;\n\n // Trigger debounced batch (also handles size/age caps internally).\n batchState.batchFn();\n\n // Signal \"enqueued to batch, not delivered\" so the aggregation pass\n // in pushToDestinations skips the synchronous `count` increment.\n return BATCHED_RESULT;\n } else {\n destLogger.debug('push', { event: processed.event.name });\n\n // Trace-level vendor-call capture (presence-gated). Only when an\n // observeLevel supplier reports 'trace' AND this destination declares\n // observable callables do we wrap the merged env with recording proxies\n // for this push. wrapEnv deep-clones the env per push, so this must never\n // run on the default path; prod stays zero-cost beyond the guard check.\n let recordedCalls: Simulation.Call[] | undefined;\n if (\n collector.observeLevel?.() === 'trace' &&\n Array.isArray(destination.calls) &&\n destination.calls.length > 0\n ) {\n const wrapped = wrapEnv({\n ...context.env,\n simulation: destination.calls,\n });\n context.env = wrapped.wrappedEnv;\n recordedCalls = wrapped.calls;\n\n // Paths wrapEnv could not resolve here (e.g. a live-web global not yet\n // installed) travel to the resolution-point wrapper (web-core getEnv) as\n // a typed recorder. Both channels push onto the SAME calls array, so the\n // out-record attach + sanitize below covers wrapped and recorded calls\n // alike. getEnv strips this key before the destination sees the env.\n if (wrapped.unresolved.length > 0) {\n wrapped.wrappedEnv[OBSERVE_ENV_KEY] = {\n paths: wrapped.unresolved,\n record: (fn, args) =>\n wrapped.calls.push({ fn, args, ts: Date.now() }),\n } satisfies Destination.EnvObserve;\n }\n }\n\n // Emit a per-event observer pair around the destination.push call so\n // observers see the work this destination did for this event.\n const eventIdValue =\n typeof processed.event.id === 'string' ? processed.event.id : '';\n const { traceId, sourceId, parentEventId } = journeyFields(\n event,\n ingest,\n collector,\n );\n const pushStarted = Date.now();\n const inState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'in',\n eventId: eventIdValue,\n now: pushStarted,\n traceId,\n sourceId,\n parentEventId,\n });\n if (processed.mappingKey) inState.mappingKey = processed.mappingKey;\n if (processed.event.consent) {\n inState.consent = { ...processed.event.consent };\n }\n inState.inEvent = processed.event;\n emitStep(collector, inState);\n\n try {\n // It's time to go to the destination's side now. Race the push against a\n // per-destination timeout so a hung delivery becomes a thrown failure\n // that flows into the SAME catch -> tryCatchAsync onError -> DLQ path a\n // real throw uses. The race is per call, so it never affects siblings.\n const timeoutMs = resolveDestinationTimeout(config.timeout);\n const response = await withTimeout(\n Promise.resolve(\n useHooks(\n destination.push,\n 'DestinationPush',\n collector.hooks,\n collector.logger,\n )(processed.event, context),\n ),\n timeoutMs,\n `Destination \"${destId}\" delivery timed out after ${timeoutMs}ms`,\n );\n\n const pushFinished = Date.now();\n const outState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'out',\n eventId: eventIdValue,\n now: pushFinished,\n traceId,\n sourceId,\n parentEventId,\n });\n outState.durationMs = pushFinished - pushStarted;\n outState.outEvent = processed.event;\n // Attach the vendor calls recorded during this push, sanitized to a\n // JSON-safe projection. Only when trace capture ran and something was\n // recorded.\n if (recordedCalls && recordedCalls.length > 0) {\n outState.calls = sanitizeCalls(recordedCalls);\n }\n if (isDefined(response)) {\n outState.meta = { ...outState.meta, response };\n }\n if (processed.mappingKey) outState.mappingKey = processed.mappingKey;\n emitStep(collector, outState);\n\n destLogger.debug('push done');\n\n return response;\n } catch (err) {\n const pushFinished = Date.now();\n const errState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'error',\n eventId: eventIdValue,\n now: pushFinished,\n traceId,\n sourceId,\n parentEventId,\n });\n errState.durationMs = pushFinished - pushStarted;\n errState.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n // Surface the vendor calls recorded before the failure, sanitized to a\n // JSON-safe projection, so a mid-push error doesn't discard them.\n if (recordedCalls && recordedCalls.length > 0) {\n errState.calls = sanitizeCalls(recordedCalls);\n }\n if (processed.mappingKey) errState.mappingKey = processed.mappingKey;\n emitStep(collector, errState);\n throw err;\n }\n }\n}\n\n/**\n * Creates a standardized result object for push operations.\n *\n * @param partialResult - A partial result to merge with the default result.\n * @returns The push result.\n */\nexport function createPushResult(\n partialResult?: Partial<Elb.PushResult>,\n): Elb.PushResult {\n return {\n ok: !partialResult?.failed,\n ...partialResult,\n };\n}\n\n/**\n * Register a single destination from its init definition.\n * Merges code config, user config, and chain config.\n * Used by initDestinations and activatePending.\n */\nexport function registerDestination(\n def: Destination.Init,\n): Destination.Instance {\n const { code, config = {}, env = {}, cache, state } = def;\n const { config: configWithBefore } = extractChainProperty(def, 'before');\n const { config: configWithChains } = extractChainProperty(\n { ...def, config: configWithBefore },\n 'next',\n );\n const mergedConfig = { ...code.config, ...config, ...configWithChains };\n // Merge definition-level cache into config for runtime access\n if (cache) mergedConfig.cache = cache;\n // Merge definition-level state into config; a config-level state wins.\n if (state !== undefined && mergedConfig.state === undefined)\n mergedConfig.state = state;\n const mergedEnv = mergeEnvironments(code.env, env);\n return { ...code, config: mergedConfig, env: mergedEnv };\n}\n\n/**\n * Initializes a map of destinations using ONLY the unified code/config/env pattern.\n * Does NOT call destination.init() - that happens later during push with proper consent checks.\n *\n * @param destinations - The destinations to initialize.\n * @param collector - The collector instance for destination init context.\n * @returns The initialized destinations.\n */\nexport async function initDestinations(\n collector: Collector.Instance,\n destinations: Destination.InitDestinations = {},\n): Promise<Collector.Destinations> {\n const result: Collector.Destinations = {};\n\n for (const [id, def] of Object.entries(destinations)) {\n if (def.config?.require?.length) {\n collector.pending.destinations[id] = def;\n continue;\n }\n result[id] = registerDestination(def);\n }\n\n return result;\n}\n\n/**\n * Merges destination environment with config environment\n * Config env takes precedence over destination env for overrides\n */\nexport function mergeEnvironments(\n destinationEnv?: Destination.Env,\n configEnv?: Destination.Env,\n): Destination.Env {\n // If neither environment exists, return empty object\n if (!destinationEnv && !configEnv) return {};\n\n // If only one exists, return it\n if (!configEnv) return destinationEnv!;\n if (!destinationEnv) return configEnv;\n\n // Both exist - merge objects with configEnv taking precedence\n if (isObject(destinationEnv) && isObject(configEnv)) {\n return { ...destinationEnv, ...configEnv };\n }\n\n // If they're not both objects, config env overrides destination env\n return configEnv;\n}\n","import type { Collector, FlowState, Ingest, WalkerOS } from '@walkeros/core';\nimport { emitStep } from '@walkeros/core';\n\n/** Journey-correlation trio shared by every FlowState-stamping site. */\nexport interface JourneyFields {\n traceId?: string;\n sourceId?: string;\n parentEventId?: string;\n}\n\n/**\n * Resolve the journey-correlation trio for a stamping site. Trace precedence:\n * a payload `event.source.trace` (origin identity) wins; a header-derived\n * `ingest._meta.trace` fills the gap; the run-scoped `collector.trace` is the\n * final fallback. `sourceId` and `parentEventId` come from the ingest context\n * threaded through the pipeline. The event accepts both a full event and a\n * DeepPartial incoming shape, since sites stamp at both pre- and\n * post-enrichment positions.\n */\nexport function journeyFields(\n event: WalkerOS.Event | WalkerOS.DeepPartialEvent,\n ingest: Ingest | undefined,\n collector: Collector.Instance,\n): JourneyFields {\n return {\n // Must match createEvent's trace precedence (handle.ts).\n traceId: event.source?.trace ?? ingest?._meta.trace ?? collector.trace,\n sourceId: ingest?._meta.path[0],\n parentEventId: ingest?._meta.parentEventId,\n };\n}\n\nexport interface BuildBaseStateArgs {\n stepId: string;\n stepType: FlowState['stepType'];\n phase: FlowState['phase'];\n eventId: string;\n now: number;\n /** W3C 32-hex trace id of the originating run (from event.source.trace). */\n traceId?: string;\n /** Originating source id (Ingest._meta.path[0]), when known. */\n sourceId?: string;\n /** Upstream runtime's event.id from an inbound $flow crossing. */\n parentEventId?: string;\n}\n\n/**\n * Build a `FlowState` carrying the six always-populated fields. Callers\n * fill in additional fields (consent, batch, error, meta, inEvent,\n * outEvent, mappingKey, durationMs) as relevant for the step site.\n *\n * `flowId` is the collector's static flow `name`, falling back to `'default'`\n * when the flow is unnamed.\n */\nexport function buildBaseState(\n collector: Collector.Instance,\n args: BuildBaseStateArgs,\n): FlowState {\n const startedAt = collector.status.startedAt;\n const state: FlowState = {\n flowId: collector.name ?? 'default',\n stepId: args.stepId,\n stepType: args.stepType,\n phase: args.phase,\n eventId: args.eventId,\n timestamp: new Date(args.now).toISOString(),\n elapsedMs: args.now - startedAt,\n };\n // Stamp journey-correlation fields only when a truthy value is in scope;\n // an undefined trace/source/parent must not appear as an explicit key.\n if (args.traceId) state.traceId = args.traceId;\n if (args.sourceId) state.sourceId = args.sourceId;\n if (args.parentEventId) state.parentEventId = args.parentEventId;\n return state;\n}\n\n/**\n * Convenience wrapper: build the base state and fan out to observers in\n * one call. Returns no value; callers that need to add trailing fields\n * before observers see them should call `buildBaseState` + `emitStep`\n * directly instead.\n */\nexport function emit(\n collector: Collector.Instance,\n args: BuildBaseStateArgs,\n): void {\n emitStep(collector, buildBaseState(collector, args));\n}\n\n/**\n * A drop at a collector-owned chain position (`source.before`,\n * `source.next`, `collector.next`): the event never reaches the\n * destinations. Emits one `collector.push` `skip` with `skipReason:\n * 'dropped'` (the same hop as the wrap's in/out, which the skip outranks as\n * the terminal phase), naming what dropped it\n * (`by`: the transformer id, or `'route'` for a route `stop`) and where\n * (`at`: the chain path). The event counts as received (`status.in`), with\n * no `out` and no counter of its own.\n */\nexport function emitCollectorDrop(\n collector: Collector.Instance,\n event: WalkerOS.DeepPartialEvent,\n ingest: Ingest | undefined,\n by: string | undefined,\n at: string,\n): void {\n collector.status.in++;\n const state = buildBaseState(collector, {\n stepId: 'collector.push',\n stepType: 'collector',\n phase: 'skip',\n eventId: typeof event.id === 'string' ? event.id : '',\n now: Date.now(),\n ...journeyFields(event, ingest, collector),\n });\n state.skipReason = 'dropped';\n state.meta = { by: by ?? 'route', at };\n emitStep(collector, state);\n}\n","import type { Simulation } from '@walkeros/core';\nimport { observeEnv } from '@walkeros/core';\n\ninterface WrapResult {\n /** Env view whose tracked paths record each call */\n wrappedEnv: Record<string, unknown>;\n /** Mutable array — calls are pushed here during step execution */\n calls: Simulation.Call[];\n /**\n * Well-formed declared paths whose object intermediates or leaf are absent\n * at wrap time, as the post-`call:` dot-path (what the recorder records as\n * `fn`). This list feeds `EnvObserve.paths` directly, so malformed paths\n * (`parseCallPath` returned `[]`) are skipped entirely. A path that\n * continues through a function (constructor, factory, method result)\n * resolves at call time and is not listed.\n */\n unresolved: string[];\n}\n\n/**\n * Structural-clone depth cap. Beyond this depth the ORIGINAL reference is\n * reused instead of cloned: the wrapped env is what the destination executes\n * against, so the fallback must stay functional (never a marker string).\n */\nconst CLONE_MAX_DEPTH = 8;\n\n/** Plain objects and arrays are data to copy; anything else is kept as is. */\nfunction isPlainData(value: object): boolean {\n if (Array.isArray(value)) return true;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Visit-once structural clone of plain objects and arrays, so writes a step\n * makes to its env stay in this push. The memo maps each source object to its\n * single clone, so cycles terminate and shared references stay shared.\n * Functions and class instances are kept by reference: an instance copied\n * into a plain object would lose its prototype and `#private` fields.\n */\nfunction deepClone(\n obj: unknown,\n memo: WeakMap<object, unknown>,\n depth: number,\n): unknown {\n if (obj === null || typeof obj !== 'object') return obj;\n if (depth >= CLONE_MAX_DEPTH || !isPlainData(obj)) return obj;\n const existing = memo.get(obj);\n if (existing !== undefined) return existing;\n if (Array.isArray(obj)) {\n const cloneArr: unknown[] = [];\n memo.set(obj, cloneArr);\n for (const item of obj) {\n cloneArr.push(deepClone(item, memo, depth + 1));\n }\n return cloneArr;\n }\n const clone: Record<string, unknown> = {};\n memo.set(obj, clone);\n for (const [key, value] of Object.entries(obj)) {\n clone[key] =\n typeof value === 'function' ? value : deepClone(value, memo, depth + 1);\n }\n return clone;\n}\n\n/**\n * Record calls on tracked paths of a destination env.\n *\n * The env object must include a `simulation: string[]` declaring which\n * dot-paths to intercept. Returns a view of a cloned env (without\n * `simulation`) where those paths record every call into the `calls` array.\n * Recording is the shared core recorder `observeEnv`, so constructors,\n * method results and Promises on a path work the same as in web-core `getEnv`.\n */\nexport function wrapEnv(\n env: Record<string, unknown> & { simulation: string[] },\n): WrapResult {\n const { simulation, ...rest } = env;\n const cloned: Record<string, unknown> = {};\n const memo = new WeakMap<object, unknown>();\n for (const [key, value] of Object.entries(rest)) {\n cloned[key] =\n typeof value === 'function' ? value : deepClone(value, memo, 1);\n }\n\n const observed = observeEnv(cloned, simulation);\n return {\n wrappedEnv: observed.env,\n calls: observed.calls,\n unresolved: observed.unresolved,\n };\n}\n","import type { Simulation } from '@walkeros/core';\n\n/** Depth beyond which sanitizeArgs stops descending and emits a marker. */\nconst SANITIZE_MAX_DEPTH = 6;\n\n/**\n * True only for plain objects (prototype is Object.prototype or null). DOM\n * nodes, class instances, Dates, Errors, etc. are non-plain and get tagged\n * rather than deep-copied.\n */\nfunction isPlainObject(value: object): value is Record<string, unknown> {\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Read one property without letting a hostile getter escape. Sanitization\n * runs inside the push try-block after a successful delivery, so a throwing\n * getter must degrade to a marker, never surface as a push failure.\n */\nfunction readProp(source: Record<string, unknown>, key: string): unknown {\n try {\n return source[key];\n } catch {\n return '[unreadable]';\n }\n}\n\n/**\n * Stable string tag for a non-plain object (DOM node, class instance, ...).\n * Falls back to a generic marker if the value's own String() throws.\n */\nfunction objectTag(value: object): string {\n try {\n return String(value);\n } catch {\n return '[object]';\n }\n}\n\n/**\n * Produce a JSON-safe deep copy of recorded vendor-call arguments. Vendor\n * calls can receive functions, DOM nodes, or cyclic structures that break or\n * silently vanish under the poster's JSON.stringify. Replace those leaves with\n * stable marker strings so the recorded calls always serialize:\n * functions -> '[function]', non-plain objects -> their String() tag, cyclic\n * refs -> '[circular]', anything past SANITIZE_MAX_DEPTH -> '[truncated]',\n * and values a throwing getter/hostile proxy makes unreadable -> '[unreadable]'.\n * Never throws: a sanitize failure must not alter push semantics.\n */\nexport function sanitizeArgs(args: unknown[]): unknown[] {\n const seen = new WeakSet<object>();\n\n const walk = (value: unknown, depth: number): unknown => {\n if (value === null) return null;\n if (typeof value === 'function') return '[function]';\n if (typeof value === 'string' || typeof value === 'boolean') return value;\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : null;\n }\n if (typeof value === 'bigint') return String(value);\n if (typeof value !== 'object') return undefined; // symbol/undefined: JSON-invisible\n\n const obj = value;\n if (seen.has(obj)) return '[circular]';\n if (depth >= SANITIZE_MAX_DEPTH) return '[truncated]';\n seen.add(obj);\n\n // Structurally hostile values (revoked proxies, throwing ownKeys traps)\n // must degrade to a marker: any throw here would surface inside the push\n // try-block and convert a successful delivery into a failure. Property\n // getters are additionally guarded per-value via readProp so one bad\n // getter only marks its own slot.\n let result: unknown;\n try {\n if (Array.isArray(obj)) {\n result = obj.map((item) => walk(item, depth + 1));\n } else if (isPlainObject(obj)) {\n const copy: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n copy[key] = walk(readProp(obj, key), depth + 1);\n }\n result = copy;\n } else {\n result = objectTag(obj);\n }\n } catch {\n result = '[unreadable]';\n }\n\n // Remove on exit so only ancestors (true cycles) count, not repeated\n // siblings referencing the same object.\n seen.delete(obj);\n return result;\n };\n\n return args.map((arg) => walk(arg, 0));\n}\n\n/**\n * Sanitize every recorded call's args into a JSON-safe projection. `fn` and\n * `ts` are already primitives; only `args` needs the deep pass.\n */\nexport function sanitizeCalls(calls: Simulation.Call[]): Simulation.Call[] {\n return calls.map((call) => ({\n fn: call.fn,\n args: sanitizeArgs(call.args),\n ts: call.ts,\n }));\n}\n","import type {\n Collector,\n On,\n WalkerOS,\n Destination,\n Source,\n Logger,\n} from '@walkeros/core';\nimport { isArray, FatalError } from '@walkeros/core';\nimport { Const } from './constants';\nimport { tryCatch, tryCatchAsync } from '@walkeros/core';\nimport { mergeEnvironments, pushToDestinations } from './destination';\nimport { buildReportError, errorMeta } from './report-error';\nimport { reconcilePending } from './pending';\nimport { flushSourceQueueOn, isSourceStarted } from './source';\nimport {\n DEFAULT_DESTINATION_TIMEOUT_MS,\n DestinationTimeoutError,\n resolveDestinationTimeout,\n withTimeout,\n} from './timeout';\n\n/**\n * Type guard: is `value` a genuine collector instance? A real collector ALWAYS\n * carries a `.logger` with a `.scope` function (see `collector.ts`, which\n * assigns `logger: createLogger(...)` unconditionally; `createLogger` never\n * returns undefined). So a value that fails this check can ONLY be a\n * foreign/non-collector caller; it can never be a real internal dispatch.\n * Cast-free: narrows via `typeof`/`in` only.\n */\nfunction isCollectorInstance(value: unknown): value is Collector.Instance {\n if (typeof value !== 'object' || value === null) return false;\n if (!('logger' in value)) return false;\n const logger = value.logger;\n if (typeof logger !== 'object' || logger === null) return false;\n return 'scope' in logger && typeof logger.scope === 'function';\n}\n\n/**\n * One-time, logger-less warning for a foreign dispatch. There is no collector\n * (hence no scoped logger) to use, so fall back to `console.warn`, guarded for\n * environments without a console, and fire at most once total to avoid spamming\n * a host page that may be calling a leaked global repeatedly.\n */\nlet warnedForeignDispatch = false;\nfunction warnForeignDispatch(): void {\n if (warnedForeignDispatch) return;\n warnedForeignDispatch = true;\n if (typeof console !== 'undefined' && typeof console.warn === 'function')\n console.warn(\n 'walkerOS: ignored an on-dispatch call with a non-collector argument',\n );\n}\n\ntype OnCallbackKind =\n | 'destination'\n | 'generic'\n | 'source'\n | 'consent'\n | 'ready'\n | 'run'\n | 'session';\n\n/**\n * Log a thrown error from a user-supplied `on` callback.\n *\n * Category B (user code): visibility via the scoped 'on' logger only.\n * `status.failed` is reserved for pipeline failures and stays untouched\n * here so it remains a clean health signal.\n *\n * Rethrows `FatalError` to let runtime supervisors fail fast on explicit\n * abort signals. Both `tryCatch` and `tryCatchAsync` propagate throws\n * raised inside onError, so this rethrow surfaces at the caller.\n */\nfunction logOnCallbackError(\n collector: Collector.Instance,\n kind: OnCallbackKind,\n error: unknown,\n extra?: Record<string, unknown>,\n): void {\n if (error instanceof FatalError) throw error;\n collector.logger.scope('on').error('on callback failed', {\n kind,\n ...extra,\n ...errorMeta(error),\n });\n}\n\n/**\n * The reactive state cells: the only commands that bump `collector.stateVersion`\n * and carry the per-subscriber exactly-once + `allowed` gate. Single source of\n * truth for \"which types are state cells\" — every list/membership check derives\n * from here, so adding a cell is a one-line change (no silently-missed site).\n */\nconst STATE_CELLS: readonly On.Types[] = [\n Const.Commands.Consent,\n Const.Commands.User,\n Const.Commands.Globals,\n Const.Commands.Custom,\n];\n\n/**\n * State-delivery event types: the reactive-state commands that bump\n * `collector.stateVersion` (see handle.ts). These are the only deliveries\n * subject to the per-subscriber high-water-mark + `allowed` gate. Lifecycle\n * types (ready/run/session) and non-reactive config keep their own gating\n * (onReady/onRun check `allowed`, onSession checks `session`).\n */\nexport function isStateDelivery(type: On.Types): boolean {\n return STATE_CELLS.includes(type);\n}\n\n/**\n * Is a recorded state CELL present (non-empty)? The single source of truth for\n * \"cell X has a value\", shared by `isRequireSatisfied` (require gating) and\n * `redeliverStateAtRun` (run-barrier re-delivery) so the presence semantics\n * never drift between the two. PRESENCE, not grant: a denied consent\n * (`{marketing:false}`) counts as present. Non-cell types return `false` here;\n * their satisfaction (session/run/ready/arbitrary) is handled by the callers.\n *\n * Note: `globals` is seeded from `config.globalsStatic` at construction, so it\n * reads present whenever a static global exists, before any `command('globals')`\n * fires. That is intentional and presence-based.\n */\nexport function isStatePresent(\n collector: Collector.Instance,\n type: On.Types,\n): boolean {\n switch (type) {\n case Const.Commands.Consent:\n return Object.keys(collector.consent).length > 0;\n case Const.Commands.User:\n return Object.keys(collector.user).length > 0;\n case Const.Commands.Globals:\n return Object.keys(collector.globals).length > 0;\n case Const.Commands.Custom:\n return Object.keys(collector.custom).length > 0;\n default:\n return false;\n }\n}\n\n/**\n * Predicate: is a `require` entry satisfied by the collector's CURRENT recorded\n * state? This is the level-not-edge core of order-independent activation: a\n * step's gate is checked against the present state, not against whether the\n * required type fired before or after the step registered.\n *\n * Cell-backed types defer to `isStatePresent` (presence, not grant — the\n * destination send-gate `getGrantedConsent` remains a separate concern).\n * `run`/`ready` map to `allowed`. Any other type (including `session`) is\n * satisfied once it has been broadcast (recorded in `seenEvents`), which also\n * recovers a broadcast that fired before the requiring step registered.\n *\n * `session` deliberately uses the `seenEvents` path, not a cell check:\n * `collector.session` is vestigial (never written), so gating on it would park\n * a `require:[\"session\"]` step forever. The session source signals via\n * `command('session', …)`, which records `session` in `seenEvents`, so this\n * keeps `session` order-independent like every other type.\n */\nexport function isRequireSatisfied(\n collector: Collector.Instance,\n type: On.Types,\n): boolean {\n switch (type) {\n case Const.Commands.Consent:\n case Const.Commands.User:\n case Const.Commands.Globals:\n case Const.Commands.Custom:\n return isStatePresent(collector, type);\n case Const.Commands.Run:\n case Const.Commands.Ready:\n return collector.allowed === true;\n default:\n return collector.seenEvents.has(String(type));\n }\n}\n\n/**\n * Read a subscriber's high-water mark FOR A CELL. A subscriber that has never\n * been delivered that cell has no entry; we read that as the sentinel -1\n * (\"-infinity\"). Since `stateVersion` starts at 0, the sentinel makes\n * registration catch-up fire (`stateVersion(0) > -1`) even when no version bump\n * has occurred yet.\n *\n * Marks are per `(subscriber, cell-type)`: a subscriber owed two distinct cells\n * at the same `stateVersion` must receive both, so each cell carries its own\n * mark. Subscriber identity keys are objects: a `ConsentRule` object (marked per\n * rule-OBJECT, coarser than per-key but sufficient for single-grant\n * exactly-once), a generic-fn, or a source instance.\n */\nfunction getMark(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): number {\n const marks = collector.delivery.get(subscriber);\n const mark = marks?.[String(type)];\n return mark === undefined ? -1 : mark;\n}\n\n/**\n * The version at which a CELL last changed. A single global `stateVersion`\n * cannot gate per-cell delivery: a later bump to cell B would make an\n * already-delivered cell A look stale. `cellVersion[type]` advances only when\n * that cell changes, so each cell's freshness is independent. A cell never\n * mutated via a command (e.g. `globalsStatic` seeded at construction) reads 0,\n * the construction baseline, so it still delivers once at the run barrier.\n */\nfunction cellVersionOf(collector: Collector.Instance, type: On.Types): number {\n // Read before every destination state delivery, including from callers\n // that hand in a partial collector without version state.\n return collector.cellVersion?.[String(type)] ?? 0;\n}\n\n/**\n * Advance a subscriber's mark for a cell to that cell's current version after\n * an invocation. Only the delivered cell's mark moves; other cells stay owed.\n */\nexport function setMark(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): void {\n let marks = collector.delivery.get(subscriber);\n if (!marks) {\n marks = {};\n collector.delivery.set(subscriber, marks);\n }\n marks[String(type)] = cellVersionOf(collector, type);\n}\n\n/**\n * A subscriber is invoked for a state delivery iff that CELL has advanced past\n * its per-cell mark AND the collector is allowed. While `!allowed`, deliveries\n * are deferred (not fired, mark not advanced) so the subscriber stays \"owed\".\n */\nexport function shouldDeliver(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): boolean {\n return (\n collector.allowed &&\n cellVersionOf(collector, type) > getMark(collector, subscriber, type)\n );\n}\n\n/**\n * Bounded recursion guard. A state-delivery callback may emit a new state\n * command, re-entering the cascade. A cyclic cascade (A reacts to user by\n * emitting consent, B reacts to consent by emitting user, with ever-changing\n * values that keep bumping `stateVersion`) would recurse until stack overflow.\n *\n * This is a terminate-and-log bound, NOT a fixpoint: when a single\n * `(subscriber, cell-type)` pair would be delivered more than\n * `MAX_DELIVERY_REVISIONS` times within ONE top-level command's cascade, the\n * pair stops delivering and a single non-convergence error is logged. State is\n * left at its last recorded value (no rollback); the outer command finishes and\n * flushes once. Legitimate wide fan-out does not trip: only the SAME\n * `(subscriber, cell-type)` revisited past the bound bails.\n */\nconst MAX_DELIVERY_REVISIONS = 8;\n\n/**\n * Open the cascade-tracking structure for the OUTERMOST top-level state command\n * (or an init flush) and return a teardown. Nested commands emitted by\n * reacting callbacks find `collector.cascade` already set and join it, so the\n * counters are scoped to the originating command; the cascade is cleared when\n * its last holder leaves. Re-entrancy is detected by the presence of\n * `collector.cascade`.\n *\n * Assumes top-level state commands run serially on a given collector;\n * concurrent overlapping state commands on one shared collector are not\n * supported (web is serial; the server per-request path is event push, not\n * state commands).\n */\nexport function enterCascade(collector: Collector.Instance): () => void {\n const open = collector.cascade;\n // A cascade this function did not open is left to whoever set it.\n if (open && !cascadeHolders.has(open)) return () => undefined;\n\n const cascade = open || { counts: new WeakMap() };\n collector.cascade = cascade;\n cascadeHolders.set(cascade, (cascadeHolders.get(cascade) || 0) + 1);\n\n // Reference-counted: the cascade stays open until its last holder leaves,\n // so a command that opened it and finishes first does not end it under an\n // init flush or a nested command still running in it.\n let left = false;\n return () => {\n if (left) return;\n left = true;\n const holders = (cascadeHolders.get(cascade) || 1) - 1;\n if (holders > 0) {\n cascadeHolders.set(cascade, holders);\n return;\n }\n cascadeHolders.delete(cascade);\n if (collector.cascade === cascade) collector.cascade = undefined;\n };\n}\n\n/** Open holders per cascade opened by `enterCascade`. */\nconst cascadeHolders = new WeakMap<Collector.Cascade, number>();\n\n/**\n * Check-and-increment the per-`(subscriber, cell-type)` delivery count for the\n * current cascade. Returns `true` when the delivery is allowed, `false` when the\n * pair has exceeded `MAX_DELIVERY_REVISIONS` (the caller must then skip the\n * delivery). On the single bailing transition, logs the non-convergence error\n * once per pair. Outside a cascade (no `collector.cascade`) it always allows.\n *\n * `subscriber` is the identity object (an `on()` rule, generic-fn, or source\n * instance); `type` is the cell type (consent/user/globals/custom).\n */\nfunction cascadeAllow(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): boolean {\n const cascade = collector.cascade;\n if (!cascade) return true;\n\n let byType = cascade.counts.get(subscriber);\n if (!byType) {\n byType = {};\n cascade.counts.set(subscriber, byType);\n }\n\n const key = String(type);\n const next = (byType[key] || 0) + 1;\n byType[key] = next;\n\n if (next <= MAX_DELIVERY_REVISIONS) return true;\n\n // Past the bound: skip the delivery. Log exactly once per `(subscriber,\n // cell-type)`: the count crosses `MAX + 1` exactly once, so logging on that\n // single transition avoids spam without a separate bail flag.\n if (next === MAX_DELIVERY_REVISIONS + 1)\n collector.logger.error('state delivery did not converge', { type: key });\n\n return false;\n}\n\n/**\n * Build the unified On.Context passed to every subscription callback.\n * Mirrors the Mapping.Context posture: collector + scoped logger only.\n */\nfunction buildOnContext(\n collector: Collector.Instance,\n type: On.Types,\n): On.Context {\n return {\n collector,\n logger: collector.logger.scope('on').scope(String(type)),\n };\n}\n\n/**\n * Registers a callback for a specific event type.\n *\n * @param collector The walkerOS collector instance.\n * @param type The type of the event to listen for.\n * @param option The callback function or an array of callback functions.\n */\nexport async function on(\n collector: Collector.Instance,\n type: On.Types,\n option: WalkerOS.SingleOrArray<On.Subscription>,\n) {\n // Fail closed against a FOREIGN/non-collector caller (see fireCallbacks and\n // isCollectorInstance). `on` dereferences `collector.on` immediately, so it\n // would throw before reaching the dispatch; guard at the top, no state\n // mutated. A real collector always has `.logger`, so this only ever catches a\n // foreign caller.\n if (!isCollectorInstance(collector)) {\n warnForeignDispatch();\n return;\n }\n\n const on = collector.on;\n const onType: Array<On.Subscription> = on[type] || [];\n const options = isArray(option) ? option : [option];\n\n options.forEach((option) => {\n onType.push(option);\n });\n\n // Update collector on state\n (on[type] as typeof onType) = onType;\n\n // Execute the on function directly\n fireCallbacks(collector, type, options);\n}\n\n/**\n * Calls a destination's on() handler with proper context and waits for it to\n * settle. Used by onApply() for live deliveries and by destinationInit() for\n * flushing queued deliveries; both await it, so a handler's side effect (a\n * vendor consent update, an SDK opt-out) lands before the destination's next\n * push. The wait is bounded by the destination's `config.timeout`, the same\n * window as a push.\n *\n * Returns whether the handler settled. A state delivery holds the destination\n * while it runs, and keeps holding it when it does not settle:\n * `pushToDestinations` then keeps its events in `queuePush` rather than\n * sending them to a vendor whose consent state was not set. The hold clears\n * once no state delivery to the destination is in flight and every present\n * state cell has reached the handler.\n *\n * One state handler call runs per destination at a time, so the state the\n * vendor applies last is always the newest. A state delivery that arrives\n * while a call runs does not call the handler: its cell stays owed, and the\n * current cells are delivered right after the running call ends. A call that\n * timed out stays in flight until its handler settles; its late settle marks\n * nothing, and the current cells, then the held events, follow from there.\n * Deferring rather than waiting keeps a handler that issues a state command\n * itself from waiting on its own call.\n *\n * A state delivery carries the command's delta when the destination has\n * received every earlier change of that cell, and the whole cell otherwise\n * (after a failed delivery, or when its mark trails by more than one change),\n * so a settled delivery never marks content it did not carry.\n */\nexport async function callDestinationOn(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n type: On.Types,\n data: unknown,\n): Promise<boolean> {\n const handler = destination.on;\n if (!handler) return true;\n\n // Only a state cell (consent, user, globals, custom) has a push that depends\n // on it; a lifecycle delivery neither holds nor marks. The version is the\n // one this delivery carries, captured before anything can change the cell.\n const gated = isStateDelivery(type);\n\n // A handler call to this destination is still running: a second call\n // could settle first and be overwritten by the older state. The cell stays\n // owed instead. A call that settles in time delivers the current state\n // right after it; one that timed out does so when it finally settles.\n if (\n gated &&\n (overdueDeliveries.get(destination) || stateCalls.has(destination))\n ) {\n markStateLost(collector, destination, type);\n if (!overdueDeliveries.get(destination))\n deferredDuringCall.add(destination);\n return false;\n }\n\n const version = gated ? cellVersionOf(collector, type) : 0;\n const payload =\n gated && owesMoreThanDelta(collector, destination, type, version)\n ? resolveDeliveryData(collector, type)\n : data;\n\n const destType = destination.type || 'unknown';\n const destLogger = collector.logger.scope(destType).scope('on').scope(type);\n\n const context: Destination.Context = {\n collector,\n logger: destLogger,\n id: destId,\n config: destination.config,\n data: payload as Destination.Data,\n env: mergeEnvironments(destination.env, destination.config.env),\n reportError: buildReportError(\n collector,\n 'destination',\n destId,\n destLogger,\n destination,\n ),\n };\n\n // The hold goes up before the handler runs, so an event pushed by another\n // caller while the handler is still running is parked rather than\n // overtaking it: pushes are not serialized with state commands.\n if (gated) {\n openStateDelivery(destination, type);\n setInFlightVersion(destination, type, version);\n stateCalls.add(destination);\n }\n\n const timeoutMs = resolveDestinationTimeout(destination.config.timeout);\n // The handler's own promise, kept for a delivery that times out.\n let running: Promise<unknown> = Promise.resolve();\n let settled = true;\n let timedOut = false;\n let threw = true;\n try {\n await tryCatchAsync(\n () => {\n running = Promise.resolve(handler(type, context));\n return withTimeout(\n running,\n timeoutMs,\n `Destination \"${destId}\" on(${type}) did not settle within ${timeoutMs}ms`,\n );\n },\n (err) => {\n settled = false;\n if (err instanceof DestinationTimeoutError) timedOut = true;\n logOnCallbackError(collector, 'destination', err, { destId, type });\n },\n )();\n threw = false;\n } finally {\n // Also runs when a FatalError propagates: the delivery counts as failed\n // and the window closes, so a later settled delivery can release the hold.\n // No follow-up runs then, so nothing stays deferred.\n if (gated) {\n stateCalls.delete(destination);\n if (threw) deferredDuringCall.delete(destination);\n const lost = lostCells.get(destination);\n if (settled) {\n advanceMark(collector, destination, type, version);\n lost?.delete(String(type));\n } else {\n markStateLost(collector, destination, type);\n }\n if (timedOut) {\n awaitOverdueDelivery(\n collector,\n destination,\n destId,\n type,\n version,\n running,\n destLogger,\n );\n } else {\n clearInFlightVersion(destination, type, version);\n closeStateDelivery(collector, destination);\n }\n }\n }\n\n // State that arrived while the handler ran follows now, as current cells.\n if (gated && !timedOut && deferredDuringCall.delete(destination))\n await catchUpDestinationState(collector, destination, destId);\n\n return settled;\n}\n\n/**\n * Timed-out state deliveries to a destination whose handler has not settled\n * yet. While one runs, no other state delivery to the destination starts.\n */\nconst overdueDeliveries = new WeakMap<Destination.Instance, number>();\n\n/**\n * Destinations whose state handler call is running. Only one runs at a time:\n * a state delivery that arrives meanwhile is deferred.\n */\nconst stateCalls = new WeakSet<Destination.Instance>();\n\n/**\n * Destinations with a state delivery deferred behind a running call. When\n * that call ends in time, the destination catches up on the current state.\n */\nconst deferredDuringCall = new WeakSet<Destination.Instance>();\n\n/**\n * Keep a timed-out state delivery in flight until its handler settles, then\n * close its window. The cell was recorded as lost at the timeout and stays\n * owed, whatever the late outcome, so the hold is released only by a later\n * delivery that carries the current cell and settles in time. That delivery\n * starts from the settle itself, followed by the held events. A handler that\n * never settles keeps the destination held.\n */\nfunction awaitOverdueDelivery(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n type: On.Types,\n version: number,\n running: Promise<unknown>,\n logger: Logger.Instance,\n): void {\n overdueDeliveries.set(\n destination,\n (overdueDeliveries.get(destination) || 0) + 1,\n );\n const settle = () => {\n const count = (overdueDeliveries.get(destination) || 0) - 1;\n if (count > 0) overdueDeliveries.set(destination, count);\n else overdueDeliveries.delete(destination);\n const lost = lostCells.get(destination);\n if (lost) lost.add(String(type));\n else lostCells.set(destination, new Set([String(type)]));\n clearInFlightVersion(destination, type, version);\n closeStateDelivery(collector, destination);\n logger.debug('late settle after timeout');\n deferredDuringCall.delete(destination);\n if (collector.allowed && collector.destinations[destId] === destination)\n recoverDestinationState(collector, destination, destId, logger);\n };\n running.then(settle, settle);\n}\n\n/**\n * Deliver the state a destination still owes, then push the events held for\n * it, without waiting for its next push.\n */\nfunction recoverDestinationState(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n logger: Logger.Instance,\n): void {\n tryCatchAsync(\n async () => {\n await catchUpDestinationState(collector, destination, destId);\n if (!getStateHold(destination) && destination.queuePush?.length)\n await pushToDestinations(\n collector,\n undefined,\n {},\n {\n [destId]: destination,\n },\n );\n },\n (err) => {\n logger.error('state recovery failed', errorMeta(err));\n },\n )();\n}\n\n/**\n * A destination's state hold: set while a state delivery (consent, user,\n * globals, custom) to its `on` handler is running, and kept when it does not\n * settle. While it is set the collector delivers no events to it: they stay in\n * its `queuePush`. Cleared once every present state cell has reached the\n * handler. Collector-internal bookkeeping, keyed by the destination instance.\n */\nexport interface StateHold {\n type: On.Types;\n since: number;\n}\n\nconst stateHolds = new WeakMap<Destination.Instance, StateHold>();\n\n/** The destination's current state hold, if it is held. */\nexport function getStateHold(\n destination: Destination.Instance,\n): StateHold | undefined {\n return stateHolds.get(destination);\n}\n\n/**\n * State deliveries to a destination that have started and not yet ended. The\n * hold is never released while one is running.\n */\nconst stateInFlight = new WeakMap<Destination.Instance, number>();\n\n/**\n * Per destination and cell, the newest version a running delivery carries. A\n * second delivery of a version that is already on its way is not started.\n */\nconst inFlightVersions = new WeakMap<\n Destination.Instance,\n Record<string, number>\n>();\n\nfunction setInFlightVersion(\n destination: Destination.Instance,\n type: On.Types,\n version: number,\n): void {\n let versions = inFlightVersions.get(destination);\n if (!versions) {\n versions = {};\n inFlightVersions.set(destination, versions);\n }\n const key = String(type);\n const current = versions[key];\n if (current === undefined || current < version) versions[key] = version;\n}\n\nfunction clearInFlightVersion(\n destination: Destination.Instance,\n type: On.Types,\n version: number,\n): void {\n const versions = inFlightVersions.get(destination);\n if (versions && versions[String(type)] === version)\n delete versions[String(type)];\n}\n\n/**\n * Cells whose last delivery to a destination did not settle. The next\n * delivery of such a cell carries the whole cell, and the hold stays until it\n * settles.\n */\nconst lostCells = new WeakMap<Destination.Instance, Set<string>>();\n\n/**\n * Destinations whose init flush is running. `held` records whether the flush\n * opened a state delivery window, closed once when the flush ends.\n */\nconst initFlushes = new WeakMap<Destination.Instance, { held: boolean }>();\n\n/**\n * Start a destination's init flush. While it runs, new deliveries to the\n * destination are queued behind the flush's entries. When the queue carries a\n * state entry the hold covers the whole flush, lifecycle entries before it\n * included, so no push slips in between two entries.\n */\nexport function beginInitFlush(destination: Destination.Instance): void {\n const first = destination.queueOn?.find(({ type }) => isStateDelivery(type));\n if (first) openStateDelivery(destination, first.type);\n initFlushes.set(destination, { held: !!first });\n}\n\n/** End a destination's init flush, releasing its window if it opened one. */\nexport function endInitFlush(\n collector: Collector.Instance,\n destination: Destination.Instance,\n): void {\n const flush = initFlushes.get(destination);\n initFlushes.delete(destination);\n if (flush?.held) closeStateDelivery(collector, destination);\n}\n\n/**\n * Record that a state cell did not reach a destination's handler: the mark is\n * taken back, the next delivery of the cell carries all of it, and the\n * destination is held, dated now, until that delivery settles. Used for a\n * delivery that failed, one the init flush never reached, and one the cascade\n * bound suppressed.\n */\nexport function markStateLost(\n collector: Collector.Instance,\n destination: Destination.Instance,\n type: On.Types,\n): void {\n clearMark(collector, destination, type);\n const lost = lostCells.get(destination);\n if (lost) lost.add(String(type));\n else lostCells.set(destination, new Set([String(type)]));\n stateHolds.set(destination, { type, since: Date.now() });\n}\n\n/**\n * Whether a destination is owed state: a cell whose delivery was lost, or a\n * present cell it has not received at its current version. False while the\n * collector is not allowed (nothing is deliverable yet).\n */\nexport function owesDestinationState(\n collector: Collector.Instance,\n destination: Destination.Instance,\n): boolean {\n if (lostCells.get(destination)?.size) return true;\n return STATE_CELLS.some(\n (cell) =>\n isStatePresent(collector, cell) &&\n shouldDeliver(collector, destination, cell),\n );\n}\n\n/**\n * Start a state delivery window on a destination: raise the hold and count\n * the window as in flight. Every call is paired with `closeStateDelivery`.\n * Used per delivery by `callDestinationOn`, and around the whole init flush by\n * `destinationInit`, so no push slips in between two queued entries.\n */\nexport function openStateDelivery(\n destination: Destination.Instance,\n type: On.Types,\n): void {\n stateInFlight.set(destination, (stateInFlight.get(destination) || 0) + 1);\n stateHolds.set(destination, { type, since: Date.now() });\n}\n\n/**\n * End a state delivery window, then release the hold if nothing else is in\n * flight and nothing is owed.\n */\nexport function closeStateDelivery(\n collector: Collector.Instance,\n destination: Destination.Instance,\n): void {\n const count = (stateInFlight.get(destination) || 0) - 1;\n if (count > 0) stateInFlight.set(destination, count);\n else stateInFlight.delete(destination);\n releaseHoldIfCurrent(collector, destination);\n}\n\n/**\n * Whether a delivery of `type` at `version` would leave a gap if it carried\n * only the command's delta: the cell's last delivery failed, the destination\n * has no mark for the cell (it never received it, so earlier content may be\n * missing), or its mark trails by more than one change. Every activation path\n * marks the present cells first, so in the init flush (entries marked when\n * queued) and on the live path the delta is what gets delivered.\n */\nfunction owesMoreThanDelta(\n collector: Collector.Instance,\n destination: Destination.Instance,\n type: On.Types,\n version: number,\n): boolean {\n if (lostCells.get(destination)?.has(String(type))) return true;\n const mark = collector.delivery?.get(destination)?.[String(type)];\n return mark === undefined || mark < version - 1;\n}\n\n/**\n * Advance a subscriber's mark for a cell to the version a delivery carried.\n * Marks only move forward: a slower delivery of an older version that settles\n * after a newer one does not take the mark back.\n */\nfunction advanceMark(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n version: number,\n): void {\n let marks = collector.delivery.get(subscriber);\n if (!marks) {\n marks = {};\n collector.delivery.set(subscriber, marks);\n }\n const key = String(type);\n const current = marks[key];\n if (current === undefined || current < version) marks[key] = version;\n}\n\n/**\n * Take a delivery mark back, so the cell reads as owed again. The mirror of\n * `setMark`: a delivery that was committed (called, or queued for the init\n * flush) but did not settle has not happened, and the subscriber must be\n * offered it again.\n */\nexport function clearMark(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): void {\n // Reached on every failed state delivery, including from callers that\n // hand in a partial collector without delivery marks.\n const marks = collector.delivery?.get(subscriber);\n if (marks) delete marks[String(type)];\n}\n\n/**\n * Clear a destination's hold only when no state delivery to it is in flight,\n * no delivery of a cell is outstanding after a failure, and every present\n * state cell has reached its `on` handler. A settled delivery of one cell\n * says nothing about another: a `user` delivery must not open the gate while\n * `consent` is still owed.\n */\nfunction releaseHoldIfCurrent(\n collector: Collector.Instance,\n destination: Destination.Instance,\n): void {\n if (!stateHolds.has(destination)) return;\n if (stateInFlight.get(destination)) return;\n if (lostCells.get(destination)?.size) return;\n const owed = STATE_CELLS.some(\n (cell) =>\n isStatePresent(collector, cell) &&\n shouldDeliver(collector, destination, cell),\n );\n if (!owed) stateHolds.delete(destination);\n}\n\n/**\n * Fire a set of registered `on` callbacks against current collector state.\n *\n * Used by both `on()` (when registering a new callback, to fire it against\n * current state) and `onApply()` (when dispatching a state-change command to\n * every registered callback of that type). Separating this from `onApply`\n * ensures `on()` does NOT trigger `onApply`'s source/destination broadcast,\n * which would cause infinite recursion if a source's `on` handler registers\n * another callback of the same type.\n */\nexport function fireCallbacks(\n collector: Collector.Instance,\n type: On.Types,\n options: Array<On.Subscription>,\n config?: unknown,\n): void {\n // Fail closed against a FOREIGN/non-collector caller. Threat: a minified\n // build can leak this helper onto a global that collides with another\n // library's API (e.g. a global named `ga`), which then invokes it with\n // foreign args like `(\"sent\",\"event\")`. The string \"sent\" would arrive here\n // as `collector` and crash on `\"sent\".logger.scope`. A genuine collector\n // ALWAYS has `.logger` (collector.ts assigns `logger: createLogger(...)`\n // unconditionally and createLogger never returns undefined), so this guard\n // can ONLY catch a foreign caller; it can never mask a real internal dispatch.\n if (!isCollectorInstance(collector)) {\n warnForeignDispatch();\n return;\n }\n\n // Calculate context data once for all sources and destinations.\n const contextData = resolveDeliveryData(collector, type, config);\n\n if (!options.length) return;\n\n switch (type) {\n case Const.Commands.Consent:\n onConsent(\n collector,\n options as Array<On.ConsentRule>,\n config as WalkerOS.Consent,\n );\n break;\n case Const.Commands.Ready:\n onReady(collector, options as Array<On.ReadyFn>);\n break;\n case Const.Commands.Run:\n onRun(collector, options as Array<On.RunFn>);\n break;\n case Const.Commands.Session:\n onSession(collector, options as Array<On.SessionFn>);\n break;\n default: {\n // Generic handler for user, custom, globals, config, and arbitrary events\n const ctx = buildOnContext(collector, type);\n const gated = isStateDelivery(type);\n options.forEach((func) => {\n if (typeof func !== 'function') return;\n // State-delivery generics (user/custom/globals) carry the per-subscriber\n // exactly-once + `allowed` gate. Non-reactive generics (config, arbitrary\n // events) keep their previous unconditional behavior.\n if (gated && !shouldDeliver(collector, func, type)) return;\n // Bounded recursion guard: a reacting generic that re-emits state could\n // cascade cyclically. Stop delivering this (func, cell-type) past the\n // bound (logs once); leave state at its last value.\n if (gated && !cascadeAllow(collector, func, type)) return;\n tryCatch(func as On.GenericFn, (err) =>\n logOnCallbackError(collector, 'generic', err, { type }),\n )(contextData, ctx);\n if (gated) setMark(collector, func, type);\n });\n break;\n }\n }\n}\n\n/**\n * Resolve the broadcast payload for a state/lifecycle delivery. An explicit\n * `config` (the command's update payload) wins; otherwise the current cell on\n * the collector is read. Shared by `onApply` and the run-barrier re-delivery so\n * both broadcast identical data.\n */\nfunction resolveDeliveryData(\n collector: Collector.Instance,\n type: On.Types,\n config?: unknown,\n): unknown {\n switch (type) {\n case Const.Commands.Consent:\n return config || collector.consent;\n case Const.Commands.Session:\n return collector.session;\n case Const.Commands.User:\n return config || collector.user;\n case Const.Commands.Custom:\n return config || collector.custom;\n case Const.Commands.Globals:\n return config || collector.globals;\n case Const.Commands.Config:\n return config || collector.config;\n default:\n return undefined;\n }\n}\n\n/**\n * Deliver a single state/lifecycle event to one started source's `on` handler,\n * carrying the per-subscriber exactly-once + `allowed` gate for state\n * deliveries. Returns `true` when the handler vetoed (returned `false`).\n *\n * Shared by the live `onApply` broadcast and the run-barrier re-delivery. It\n * does NOT touch `config.require` or `queueOn`: those belong to the live\n * command path's unstarted-source handling, not the barrier.\n */\nasync function deliverStateToSource(\n collector: Collector.Instance,\n source: Source.Instance,\n sourceId: string,\n type: On.Types,\n contextData: unknown,\n): Promise<boolean> {\n if (!source.on) return false;\n\n // State deliveries (consent/user/globals/custom) carry the per-subscriber\n // exactly-once + `allowed` gate keyed by the source instance. While !allowed\n // a state delivery is deferred (not invoked, mark not advanced). Lifecycle\n // deliveries (ready/run/session/config) are not gated here.\n if (isStateDelivery(type) && !shouldDeliver(collector, source, type))\n return false;\n\n // Bounded recursion guard: a source `on` handler that re-emits state could\n // cascade cyclically. Stop delivering this (source, cell-type) past the bound\n // (logs once); leave state at its last value.\n if (isStateDelivery(type) && !cascadeAllow(collector, source, type))\n return false;\n\n // One state handler call runs per source at a time, as for destinations: a\n // state delivery that arrives meanwhile leaves its cell owed, and the\n // current cells follow once the running call ends.\n const gated = isStateDelivery(type);\n if (gated && sourceStateCalls.has(source)) {\n deferredSourceCalls.add(source);\n return false;\n }\n const version = gated ? cellVersionOf(collector, type) : 0;\n if (gated) sourceStateCalls.add(source);\n\n // Sources carry no per-step timeout config and share the destination\n // default, so one hung source handler cannot stall the delivery pass.\n const handler = source.on;\n let running: Promise<unknown> = Promise.resolve();\n let timedOut = false;\n let result: unknown;\n try {\n result = await tryCatchAsync(\n () => {\n running = Promise.resolve(handler(type, contextData));\n return withTimeout(\n running,\n DEFAULT_DESTINATION_TIMEOUT_MS,\n `Source \"${sourceId}\" on(${type}) did not settle within ${DEFAULT_DESTINATION_TIMEOUT_MS}ms`,\n );\n },\n (err) => {\n if (err instanceof DestinationTimeoutError) timedOut = true;\n logOnCallbackError(collector, 'source', err, { sourceId, type });\n },\n )();\n } finally {\n // A timed-out call stays running until its handler settles.\n if (gated && !timedOut) sourceStateCalls.delete(source);\n }\n\n if (gated) {\n if (timedOut) {\n // A timed-out delivery has not happened: the mark stays, the cell stays\n // owed, and the current cells follow the late settle.\n const settle = () => {\n sourceStateCalls.delete(source);\n deferredSourceCalls.delete(source);\n if (collector.allowed && collector.sources[sourceId] === source)\n tryCatchAsync(\n () => catchUpSourceState(collector, source, sourceId),\n (err) => {\n collector.logger\n .scope('on')\n .error('state recovery failed', errorMeta(err));\n },\n )();\n };\n running.then(settle, settle);\n } else {\n advanceMark(collector, source, type, version);\n if (deferredSourceCalls.delete(source))\n await catchUpSourceState(collector, source, sourceId);\n }\n }\n\n return result === false;\n}\n\n/** Sources whose state handler call is running. */\nconst sourceStateCalls = new WeakSet<Source.Instance>();\n\n/** Sources with a state delivery deferred behind a running call. */\nconst deferredSourceCalls = new WeakSet<Source.Instance>();\n\n/** Deliver every state cell a started source still owes. */\nasync function catchUpSourceState(\n collector: Collector.Instance,\n source: Source.Instance,\n sourceId: string,\n): Promise<void> {\n // Opened or joined here, as for destinations, so the bound applies. Every\n // owed cell is delivered, one with no content included: a deferred update\n // reaches the source as it would have without the running call.\n const exitCascade = enterCascade(collector);\n try {\n for (const type of STATE_CELLS) {\n await deliverStateToSource(\n collector,\n source,\n sourceId,\n type,\n resolveDeliveryData(collector, type),\n );\n }\n } finally {\n exitCascade();\n }\n}\n\n/**\n * Deliver one state or lifecycle event to a registered destination's `on`\n * handler. State deliveries (consent/user/globals/custom) carry the same\n * per-subscriber exactly-once + `allowed` gate as sources and `on` rules,\n * keyed by the destination instance: while `!allowed` the delivery is deferred\n * (not queued, mark not advanced) and the run barrier delivers it; once\n * allowed, each cell change reaches the destination exactly once. Lifecycle\n * deliveries (ready/run/session/config/arbitrary) are unconditional.\n *\n * A delivery is committed either by calling `on()` now (initialized\n * destination, marked by `callDestinationOn` when it settles) or by appending\n * to `queueOn`, which `destinationInit` flushes before the destination's first\n * push. The queue branch marks the cell itself: a cell already waiting in\n * `queueOn` is not owed, so the run barrier, which fires on every navigation,\n * does not append it again. A queued entry whose flush fails takes its mark\n * back in `callDestinationOn`, and the next delivery carries the whole cell.\n */\nexport async function deliverStateToDestination(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n type: On.Types,\n data: unknown,\n): Promise<void> {\n if (!destination.on) return;\n\n const gated = isStateDelivery(type);\n if (gated && !shouldDeliver(collector, destination, type)) return;\n // The current version of the cell is already on its way to the handler.\n const inFlight = inFlightVersions.get(destination)?.[String(type)];\n if (\n gated &&\n inFlight !== undefined &&\n inFlight >= cellVersionOf(collector, type)\n )\n return;\n // Bounded recursion guard: a destination `on` handler that re-emits state\n // could cascade cyclically. Past the bound the delivery is skipped (logged\n // once). An initialized destination records the cell as lost, so it is held\n // until a later delivery of it settles. An uninitialized one runs no handler\n // here, so nothing can recurse: the whole cell is queued for its init flush\n // instead of this delta, replacing a trailing entry of the same cell.\n if (gated && !cascadeAllow(collector, destination, type)) {\n if (destination.config.init) {\n markStateLost(collector, destination, type);\n return;\n }\n const queue = (destination.queueOn = destination.queueOn || []);\n const entry = { type, data: resolveDeliveryData(collector, type) };\n const last = queue[queue.length - 1];\n if (last && last.type === type) queue[queue.length - 1] = entry;\n else queue.push(entry);\n setMark(collector, destination, type);\n lostCells.get(destination)?.delete(String(type));\n return;\n }\n\n // Uninitialized, or its init flush is still running: the delivery joins\n // the queue behind the older entries, so it never overtakes them.\n const flush = initFlushes.get(destination);\n if (!destination.config.init || flush) {\n destination.queueOn = destination.queueOn || [];\n destination.queueOn.push({ type, data });\n if (gated) {\n setMark(collector, destination, type);\n // A state entry joining a running flush holds the destination for the\n // rest of the flush.\n if (flush && !flush.held) {\n openStateDelivery(destination, type);\n flush.held = true;\n }\n }\n return;\n }\n\n await callDestinationOn(collector, destination, destId, type, data);\n}\n\n/**\n * Registration catch-up for a destination that just became active: a pending\n * `require` gate satisfied, or a runtime `walker destination`. Delivers every\n * present state cell as a snapshot through the same gate as a live broadcast,\n * so the destination's `on` handler sees the state that activated it before\n * its queued events are pushed, and holds a mark for every present cell\n * before any later delta reaches it. While `!allowed` this is inert and the\n * run barrier delivers instead. Also the retry of a held destination: only the\n * cells it still owes pass the gate.\n */\nexport async function catchUpDestinationState(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n): Promise<void> {\n if (!destination.on) return;\n // Opened or joined here, so a catch-up outside a command (a push's retry, a\n // late settle) still counts a handler that re-emits state against the bound.\n const exitCascade = enterCascade(collector);\n try {\n for (const type of STATE_CELLS) {\n // A cell with no content is not owed, unless its delivery was lost\n // (failed, or deferred behind a running call): that one still holds the\n // destination until it arrives.\n if (\n !isStatePresent(collector, type) &&\n !lostCells.get(destination)?.has(String(type))\n )\n continue;\n await deliverStateToDestination(\n collector,\n destination,\n destId,\n type,\n resolveDeliveryData(collector, type),\n );\n }\n } finally {\n exitCascade();\n }\n}\n\n/**\n * Whether a state delivery to the destination is running right now (a live\n * delivery or an init flush). A held destination is not retried while one is.\n */\nexport function isStateDeliveryInFlight(\n destination: Destination.Instance,\n): boolean {\n return (stateInFlight.get(destination) || 0) > 0;\n}\n\n/**\n * Run-barrier re-delivery. Called once from `runCollector` after the collector\n * becomes `allowed` and the RunState merge has bumped `stateVersion` for any\n * merged cells. Re-broadcasts each non-empty recorded state cell to its OWED\n * subscribers (mark < stateVersion) exactly once, so reactions deferred while\n * `!allowed` now emit into the open, consent-gated pipeline.\n *\n * Narrow path: it fires `collector.on` rules/fns via `fireCallbacks`, the\n * gated `source.on` handlers via `deliverStateToSource`, and the gated\n * destination `on` handlers via `deliverStateToDestination` (queued for an\n * uninitialized destination's init flush). It deliberately skips the\n * `require`-decrement and `queueOn`-flush machinery in `onApply` (those are\n * live-command concerns). Exactly-once is free from the `shouldDeliver` gate:\n * already-delivered subscribers (mark == stateVersion) are skipped.\n */\nexport async function redeliverStateAtRun(\n collector: Collector.Instance,\n): Promise<void> {\n const deliveries = await startRunRedelivery(collector);\n await Promise.all(deliveries.map(({ done }) => done));\n}\n\n/**\n * The run barrier without waiting for destinations. Rules and started sources\n * are re-delivered per cell and awaited (sources bounded); each destination\n * gets its own sequence of owed cells, started here and returned, so one slow\n * destination handler delays no other destination's run flush. A destination\n * is held from the start of its first delivery until nothing is owed.\n */\nexport async function startRunRedelivery(\n collector: Collector.Instance,\n): Promise<DestinationDelivery[]> {\n // Fail closed against a FOREIGN/non-collector caller (see fireCallbacks and\n // isCollectorInstance). This dereferences the collector's state cells, so\n // guard at the top, no state mutated, neutral result. A real collector\n // always has `.logger`, so this only ever catches a foreign caller.\n if (!isCollectorInstance(collector)) {\n warnForeignDispatch();\n return [];\n }\n\n // Each registered destination receives every owed cell, in cell order, as\n // a snapshot of the cell when its turn comes.\n const deliveries: DestinationDelivery[] = [];\n for (const [destId, destination] of Object.entries(collector.destinations)) {\n if (!destination.on) continue;\n const sequence = async () => {\n for (const type of STATE_CELLS) {\n if (!isStatePresent(collector, type)) continue;\n await deliverStateToDestination(\n collector,\n destination,\n destId,\n type,\n resolveDeliveryData(collector, type),\n );\n }\n };\n deliveries.push(startDelivery(destId, destination, sequence()));\n }\n\n for (const type of STATE_CELLS) {\n if (!isStatePresent(collector, type)) continue;\n\n const contextData = resolveDeliveryData(collector, type);\n\n // Re-deliver to registered collector.on rules/fns. fireCallbacks carries\n // the same per-subscriber gate, so owed rules fire once and advance.\n fireCallbacks(collector, type, collector.on[type] || []);\n\n // Re-deliver to started sources through the gated helper, concurrently:\n // one slow source handler does not cost the others their own timeout.\n await Promise.all(\n Object.entries(collector.sources)\n .filter(([, source]) => isSourceStarted(source))\n .map(([sourceId, source]) =>\n deliverStateToSource(collector, source, sourceId, type, contextData),\n ),\n );\n }\n\n return deliveries;\n}\n\n/**\n * Applies all registered callbacks for a specific event type.\n *\n * @param collector The walkerOS collector instance.\n * @param type The type of the event to apply the callbacks for.\n * @param options The options for the callbacks.\n * @param config The consent configuration.\n */\nexport async function onApply(\n collector: Collector.Instance,\n type: On.Types,\n options?: Array<On.Subscription>,\n config?: unknown,\n): Promise<boolean> {\n const { ok, deliveries } = await onApplyDeferred(\n collector,\n type,\n options,\n config,\n );\n await Promise.all(deliveries.map(({ done }) => done));\n return ok;\n}\n\n/**\n * A destination's `on()` delivery that a command started and did not wait\n * for. `drain` is set by the caller just before its flush when the\n * destination was held then: its events were parked, and once `done` settles\n * they are pushed for that destination alone.\n */\nexport interface DestinationDelivery {\n id: string;\n destination: Destination.Instance;\n done: Promise<void>;\n drain?: boolean;\n}\n\n/**\n * Start a destination delivery without waiting for it. A rejection (a\n * FatalError) stays on `done` for the caller that settles it; the handler\n * attached here only keeps it from surfacing as unhandled in between.\n */\nfunction startDelivery(\n id: string,\n destination: Destination.Instance,\n done: Promise<void>,\n): DestinationDelivery {\n done.catch(() => undefined);\n return { id, destination, done };\n}\n\n/**\n * `onApply` without waiting for destination deliveries. Sources are awaited\n * (bounded); every destination's `on()` delivery is started and returned, so\n * the caller can flush every destination at once: a destination whose\n * delivery is still running is held, its events wait for its own delivery,\n * and no other destination waits for it.\n */\nexport async function onApplyDeferred(\n collector: Collector.Instance,\n type: On.Types,\n options?: Array<On.Subscription>,\n config?: unknown,\n): Promise<{ ok: boolean; deliveries: DestinationDelivery[] }> {\n // Fail closed against a FOREIGN/non-collector caller (see fireCallbacks and\n // isCollectorInstance). `onApply` dereferences `collector.seenEvents`\n // immediately, so it would throw before reaching the dispatch; guard at the\n // top, no state mutated. Return the neutral not-vetoed result (`true`). A real\n // collector always has `.logger`, so this only ever catches a foreign caller.\n if (!isCollectorInstance(collector)) {\n warnForeignDispatch();\n return { ok: true, deliveries: [] };\n }\n\n // Record every broadcast type so a `require:[<arbitrary>]` gate stays\n // satisfiable from current state (incl. a broadcast that fired before the\n // requiring step registered). Cell-backed types are level-checked separately.\n collector.seenEvents.add(String(type));\n\n // Use the optionally provided options\n let onConfig = options || [];\n\n if (!options) {\n // Get the collector on events\n onConfig = collector.on[type] || [];\n }\n\n // Calculate context data once for source/destination broadcast.\n const contextData = resolveDeliveryData(collector, type, config);\n\n // Synchronous bookkeeping first, in subscriber order: the per-source require\n // decrement, queueOn buffering for unstarted sources and uninitialized\n // destinations, and the list of handlers that receive this delivery now.\n // Sources are not \"started\" until config.init === true AND config.require\n // is empty; their queued on() events are replayed once they start.\n const sourceDeliveries: Array<Promise<boolean>> = [];\n for (const [sourceId, source] of Object.entries(collector.sources)) {\n if (source.config.require?.length) {\n const idx = source.config.require.indexOf(type);\n if (idx !== -1) source.config.require.splice(idx, 1);\n }\n\n if (!source.on) continue;\n\n if (isSourceStarted(source)) {\n sourceDeliveries.push(\n deliverStateToSource(collector, source, sourceId, type, contextData),\n );\n } else {\n source.queueOn = source.queueOn || [];\n source.queueOn.push({ type, data: contextData });\n }\n }\n\n // Destinations: state deliveries are gated (exactly-once, deferred while\n // not allowed); an uninitialized destination's delivery is queued for its\n // init flush, synchronously, inside deliverStateToDestination.\n const deliveries: DestinationDelivery[] = [];\n for (const [destId, destination] of Object.entries(collector.destinations)) {\n if (!destination.on) continue;\n deliveries.push(\n startDelivery(\n destId,\n destination,\n deliverStateToDestination(\n collector,\n destination,\n destId,\n type,\n contextData,\n ),\n ),\n );\n }\n\n // Source handlers run concurrently, each bounded by the default timeout.\n // Destination deliveries are not awaited here: each is held while it runs\n // and the caller settles them after its flush. With no source handler to\n // wait for there is no await, which keeps the synchronous ordering the\n // bounded-recursion cascade relies on.\n let vetoed = false;\n if (sourceDeliveries.length) {\n const sourceVetoes = await Promise.all(sourceDeliveries);\n vetoed = sourceVetoes.some(Boolean);\n }\n\n // Sources whose require was just emptied AND init has run: flush their\n // queueOn now (the require-completing event was queued in the gated\n // branch above, so flushing here delivers it without losing ordering).\n for (const [sourceId, source] of Object.entries(collector.sources)) {\n if (isSourceStarted(source) && source.queueOn?.length) {\n await flushSourceQueueOn(collector, source, sourceId);\n }\n }\n\n // Activate any pending source/destination whose require is now satisfied by\n // current state. Level-based and additive: the per-source broadcast decrement\n // above still handles started-source delivery + queueOn buffering; reconcile\n // additionally activates steps satisfied by the recorded cell (or by an\n // arbitrary type already in `seenEvents`), so order does not matter.\n //\n // Gate the await on there being actual pending work: with nothing to\n // reconcile this is a no-op, and skipping the await preserves the\n // synchronous microtask ordering the bounded-recursion cascade relies on.\n const hasUnstartedSource = Object.values(collector.sources).some(\n (source) => !isSourceStarted(source) && source.config.require?.length,\n );\n if (\n Object.keys(collector.pending.destinations).length > 0 ||\n hasUnstartedSource\n ) {\n await reconcilePending(collector);\n }\n\n fireCallbacks(collector, type, onConfig, config);\n\n return { ok: !vetoed, deliveries };\n}\n\nfunction onConsent(\n collector: Collector.Instance,\n onConfig: Array<On.ConsentRule>,\n currentConsent?: WalkerOS.Consent,\n): void {\n const consentState = currentConsent || collector.consent;\n const ctx = buildOnContext(collector, Const.Commands.Consent);\n\n onConfig.forEach((rule) => {\n // Per-subscriber exactly-once gate, keyed by the rule OBJECT (coarser than\n // per-key, but sufficient for single-grant exactly-once). While !allowed\n // the delivery is deferred: don't invoke, don't advance the mark.\n if (!shouldDeliver(collector, rule, Const.Commands.Consent)) return;\n\n // Bounded recursion guard: a consent rule that re-emits state could cascade\n // cyclically. Stop delivering this (rule, consent) past the bound (logs\n // once); leave state at its last value.\n if (!cascadeAllow(collector, rule, Const.Commands.Consent)) return;\n\n // Execute every handler whose consent key is present in the current state.\n Object.keys(consentState)\n .filter((key) => key in rule)\n .forEach((key) => {\n tryCatch(rule[key], (err) =>\n logOnCallbackError(collector, 'consent', err, { key }),\n )(consentState, ctx);\n });\n\n // Advance the mark after an allowed invocation.\n setMark(collector, rule, Const.Commands.Consent);\n });\n}\n\nfunction onReady(\n collector: Collector.Instance,\n onConfig: Array<On.ReadyFn>,\n): void {\n if (!collector.allowed) return;\n const ctx = buildOnContext(collector, Const.Commands.Ready);\n onConfig.forEach((func) => {\n tryCatch(func, (err) => logOnCallbackError(collector, 'ready', err))(\n undefined,\n ctx,\n );\n });\n}\n\nfunction onRun(collector: Collector.Instance, onConfig: Array<On.RunFn>): void {\n if (!collector.allowed) return;\n const ctx = buildOnContext(collector, Const.Commands.Run);\n onConfig.forEach((func) => {\n tryCatch(func, (err) => logOnCallbackError(collector, 'run', err))(\n undefined,\n ctx,\n );\n });\n}\n\nfunction onSession(\n collector: Collector.Instance,\n onConfig: Array<On.SessionFn>,\n): void {\n if (!collector.session) return;\n const ctx = buildOnContext(collector, Const.Commands.Session);\n onConfig.forEach((func) => {\n tryCatch(func, (err) => logOnCallbackError(collector, 'session', err))(\n collector.session,\n ctx,\n );\n });\n}\n","import type {\n Collector,\n Context,\n Destination,\n Logger,\n StepKind,\n WalkerOS,\n} from '@walkeros/core';\nimport { stepId } from '@walkeros/core';\nimport { pushBounded, resetOverflowFlag, warnOverflowOnce } from './buffers';\nimport { recordStepOutcome, resolveBreakerConfig } from './breaker';\n\n/**\n * Maximum number of failed-push entries retained per destination DLQ before\n * FIFO drop-oldest. Mirrored by `Destination.Config.dlqMax`.\n */\nexport const DEFAULT_DLQ_MAX = 100;\n\n/**\n * Ensure a per-destination status entry exists and return it.\n */\nexport function ensureDestStatus(\n collector: Collector.Instance,\n destId: string,\n): Collector.DestinationStatus {\n if (!collector.status.destinations[destId]) {\n collector.status.destinations[destId] = {\n count: 0,\n failed: 0,\n duration: 0,\n queuePushSize: 0,\n dlqSize: 0,\n };\n }\n return collector.status.destinations[destId];\n}\n\n/**\n * Bump a drop counter under `status.dropped[stepId][buffer]`. Lazily\n * creates the per-step entry; returns the new counter value so callers\n * can pass it straight into the warn-once log payload.\n */\nexport function bumpDropped(\n status: Collector.Status,\n id: string,\n buffer: 'queue' | 'dlq',\n n: number,\n): number {\n if (!status.dropped[id]) status.dropped[id] = {};\n const entry = status.dropped[id];\n entry[buffer] = (entry[buffer] ?? 0) + n;\n return entry[buffer]!;\n}\n\n/**\n * Routes a single event/error pair to a destination's DLQ with the bounded\n * write, overflow-warn-once, and full failure accounting (`destStatus.failed`\n * + `collector.status.failed`). This mirrors the batch flush's `routeToDlq`\n * for the single-event case: write to the DLQ AND bump the failed counters in\n * one place. (The per-event in-band push path bumps `failed` later in the\n * aggregation pass instead, so it does NOT call this; this helper is for the\n * out-of-band `reportError(err, event)` seam that has no aggregation pass.)\n */\nfunction routeEventToDlq(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n event: WalkerOS.Event,\n err: unknown,\n logger: Logger.Instance,\n): void {\n const dlq = (destination.dlq = destination.dlq || []);\n const dlqBound = { max: destination.config.dlqMax ?? DEFAULT_DLQ_MAX };\n const dlqResult = pushBounded(dlq, [event, err], dlqBound);\n if (dlqResult.dropped > 0) {\n const droppedCount = bumpDropped(\n collector.status,\n stepId('destination', destId),\n 'dlq',\n dlqResult.dropped,\n );\n warnOverflowOnce(\n dlq,\n logger,\n 'destination.dlq overflow; oldest entries dropped',\n {\n buffer: 'dlq',\n destination: destId,\n cap: dlqBound.max,\n droppedCount,\n },\n );\n } else if (dlq.length < dlqBound.max) {\n resetOverflowFlag(dlq);\n }\n const destStatus = ensureDestStatus(collector, destId);\n destStatus.failed++;\n destStatus.dlqSize = dlq.length;\n collector.status.failed++;\n\n // A connection-level error that DLQs a specific event is a transport\n // failure: feed it to the circuit breaker so the gate picks it up.\n // Presence-gated and keyed on the canonical stepId (matching the push gate).\n const breakerConfig = resolveBreakerConfig(destination.config.breaker);\n if (breakerConfig) {\n const canonicalId = destination.config.id || destId;\n recordStepOutcome(\n collector.status.breakers,\n stepId('destination', canonicalId),\n 'transport-failure',\n breakerConfig.threshold,\n breakerConfig.cooldown,\n );\n }\n}\n\n/**\n * Extract loggable metadata from an unknown error: the message plus, when\n * present, the error's `name` (skipped for the default 'Error', which adds no\n * signal) and its transport `code` (gRPC status number or HTTP status). Keeps\n * connection-error lines diagnosable from logs alone (WHICH status killed a\n * stream), without serializing whole error objects into the log payload.\n */\nexport function errorMeta(err: unknown): {\n error: string;\n name?: string;\n code?: string | number;\n} {\n const meta: { error: string; name?: string; code?: string | number } = {\n error: err instanceof Error ? err.message : String(err),\n };\n if (err instanceof Error && err.name && err.name !== 'Error') {\n meta.name = err.name;\n }\n if (typeof err === 'object' && err !== null && 'code' in err) {\n const withCode: { code?: unknown } = err;\n if (\n typeof withCode.code === 'number' ||\n typeof withCode.code === 'string'\n ) {\n meta.code = withCode.code;\n }\n }\n return meta;\n}\n\n/**\n * Builds the step-general `reportError` callback for one step's context.\n *\n * This is the runtime behind `Context.Base.reportError`. It is captured ONCE\n * when a step's context is built and closes over `(collector, kind, id,\n * logger, destination)`, so a long-lived connection that holds the reference\n * keeps a valid callback for its whole lifetime — it is never rebuilt per\n * push. It runs on a detached emitter tick, so every path is internally\n * try/catch-guarded; a throw inside it would reintroduce the very\n * uncaughtException it exists to contain.\n *\n * - orphan (`reportError(err)`): bump `status.connectionErrors[stepId]` and\n * `logger.error`. Does NOT bump `failed` (no event lost at this instant;\n * counting it against `failed` would double-count the next push that hits\n * the broken writer and gets DLQ'd).\n * - event-bearing (`reportError(err, event)`): route the event through the\n * same DLQ + failure accounting an in-band push failure uses (for a\n * destination). A step kind without a DLQ (or a destination not passed)\n * still gets `failed`-counted and logged, never silently dropped.\n *\n * The with-event path deliberately funnels through the normal failure\n * accounting so that when circuit-breaker accounting is later attached to that\n * path, `reportError(err, event)` picks it up with no further wiring here.\n */\nexport function buildReportError(\n collector: Collector.Instance,\n kind: Exclude<StepKind, 'collector'>,\n id: string,\n logger: Logger.Instance,\n destination?: Destination.Instance,\n): NonNullable<Context.Base['reportError']> {\n const key = stepId(kind, id);\n return (err: unknown, event?: WalkerOS.Event): void => {\n try {\n if (event) {\n if (destination) {\n routeEventToDlq(collector, destination, id, event, err, logger);\n } else {\n // No DLQ buffer for this step kind: still account + surface the\n // lost event so it is never silent.\n collector.status.failed++;\n }\n logger.error('report error', {\n ...errorMeta(err),\n event: event.name,\n });\n return;\n }\n\n // Orphan / connection-level error: count it under connectionErrors,\n // not failed.\n collector.status.connectionErrors[key] =\n (collector.status.connectionErrors[key] ?? 0) + 1;\n logger.error('connection error', errorMeta(err));\n } catch {\n // Contained: reportError runs on a detached tick and must never throw.\n }\n };\n}\n","import type { Logger } from '@walkeros/core';\n\n/**\n * Bounded-append helpers for collector internal buffers.\n *\n * Three collector buffers are size-bounded:\n * - `collector.queue` (replay buffer for late-registered destinations)\n * - `destination.queuePush` (consent-denied buffer, per destination)\n * - `destination.dlq` (failed-push dead-letter queue, per destination)\n *\n * All three share the same FIFO ring-buffer eviction semantics, so the\n * append logic lives in one place. `pushBounded` performs the size check,\n * evicts oldest entries (or refuses the new one for `dropNewest`), and\n * reports drops back to the caller via the typed result + optional callback.\n *\n * Caller responsibility: increment the appropriate status counter\n * under `status.dropped[stepId]` (see `stepId()` in @walkeros/core)\n * and emit the warn-once-on-transition log. The helper stays pure: no logger\n * coupling, no collector reference.\n */\n\nexport type BufferOverflowPolicy = 'dropOldest' | 'dropNewest';\n\nexport interface BufferBound {\n max: number;\n onOverflow?: BufferOverflowPolicy;\n}\n\nexport interface PushBoundedResult {\n /** Whether the new item was appended to the buffer. */\n appended: boolean;\n /** Number of items dropped on this call (0 in the happy path). */\n dropped: number;\n}\n\n/**\n * Append `item` to `buffer`, respecting `bound.max`. On overflow, evict\n * per `bound.onOverflow` (defaults to `'dropOldest'`).\n *\n * @param buffer - In-place mutated array.\n * @param item - Item to append.\n * @param bound - Cap + overflow policy.\n * @param onDrop - Optional callback receiving the dropped items (oldest\n * evictions on `dropOldest`, or the rejected new item on `dropNewest`).\n * Called once per overflow event with all dropped items batched.\n * @returns `{ appended, dropped }`.\n */\nexport function pushBounded<T>(\n buffer: T[],\n item: T,\n bound: BufferBound,\n onDrop?: (dropped: T[]) => void,\n): PushBoundedResult {\n if (!Number.isFinite(bound.max) || bound.max <= 0) {\n throw new Error(`pushBounded: max must be > 0 (got ${bound.max})`);\n }\n\n const policy: BufferOverflowPolicy = bound.onOverflow ?? 'dropOldest';\n\n if (policy === 'dropNewest') {\n if (buffer.length >= bound.max) {\n if (onDrop) onDrop([item]);\n return { appended: false, dropped: 1 };\n }\n buffer.push(item);\n return { appended: true, dropped: 0 };\n }\n\n // dropOldest\n const dropped: T[] = [];\n while (buffer.length >= bound.max) {\n // Length-guarded shift; never undefined here (max > 0, length > 0).\n dropped.push(buffer.shift()!);\n }\n buffer.push(item);\n if (dropped.length > 0 && onDrop) onDrop(dropped);\n return { appended: true, dropped: dropped.length };\n}\n\n/**\n * Per-buffer overflow log state. Used to emit a single warn when a buffer\n * crosses from below-cap to at-cap, suppressing further warns until the\n * buffer drains below cap and overflows again (per Q13).\n */\nconst overflowState = new WeakMap<object, boolean>();\n\n/**\n * Emit a warn-once log on the transition into overflow. Subsequent drops\n * within the same overflow window stay silent until the buffer drains\n * (the caller signals \"below-cap again\" by calling `resetOverflow`).\n *\n * The cumulative drop counter is still incremented on every drop by the\n * caller, so operators retain rate signal via `collector.status.dropped[stepId]`.\n */\nexport function warnOverflowOnce(\n buffer: object,\n logger: Logger.Instance,\n message: string,\n context: Record<string, unknown>,\n): void {\n if (overflowState.get(buffer)) return;\n overflowState.set(buffer, true);\n logger.warn(message, context);\n}\n\n/**\n * Reset the overflow flag when a buffer drains below cap, so the next\n * overflow transition will warn again.\n */\nexport function resetOverflowFlag(buffer: object): void {\n overflowState.delete(buffer);\n}\n","import type { BreakerState, Destination } from '@walkeros/core';\n\n/**\n * Step-general circuit breaker.\n *\n * State lives in `collector.status.breakers`, keyed by `stepId()` so the\n * breaker is step-agnostic (destinations are the primary use today). All sites\n * — the skip gate, the per-event failure/success accounting, the batch flush —\n * drive their state changes through this one module so the gate and the\n * accounting can never disagree about a step's health.\n *\n * The breaker is presence-gated: a step with no `breaker` config never trips\n * (the caller skips this module entirely when {@link resolveBreakerConfig}\n * returns `undefined`).\n *\n * Time is read through an injectable `now()` so open→half-open transitions are\n * deterministic in tests without fake timers (mirrors `ErrorRing` in the cli).\n */\n\nexport const DEFAULT_BREAKER_THRESHOLD = 5;\nexport const DEFAULT_BREAKER_COOLDOWN_MS = 30_000;\n\n/** Resolved, presence-checked breaker tuning for one step. */\nexport interface BreakerConfig {\n threshold: number;\n cooldown: number;\n}\n\n/**\n * The kind of transport outcome a step site reports. `transport-failure`\n * counts toward opening; `success` resets and closes; `partial` is a\n * deliberate no-op (row-level batch failures must not trip a healthy\n * destination).\n */\nexport type StepOutcome = 'transport-failure' | 'success' | 'partial';\n\n/**\n * Injectable clock. Default reads wall time; tests swap it via\n * {@link __setBreakerNow} so open→half-open is deterministic.\n */\nlet nowFn: () => number = () => Date.now();\n\n/** Test-only: override the breaker clock. */\nexport function __setBreakerNow(fn: () => number): void {\n nowFn = fn;\n}\n\n/** Test-only: restore the real-time breaker clock. */\nexport function __resetBreakerNow(): void {\n nowFn = () => Date.now();\n}\n\n/** Current breaker time (injectable). */\nexport function breakerNow(): number {\n return nowFn();\n}\n\n/**\n * Resolve a destination's `breaker` config into tuned values, or `undefined`\n * when no breaker is configured (presence-gating: the breaker stays inert).\n * A bare number is the threshold.\n */\nexport function resolveBreakerConfig(\n breaker: Destination.Config['breaker'],\n): BreakerConfig | undefined {\n if (breaker === undefined) return undefined;\n if (typeof breaker === 'number') {\n return { threshold: breaker, cooldown: DEFAULT_BREAKER_COOLDOWN_MS };\n }\n return {\n threshold: breaker.threshold ?? DEFAULT_BREAKER_THRESHOLD,\n cooldown: breaker.cooldown ?? DEFAULT_BREAKER_COOLDOWN_MS,\n };\n}\n\n/** Lazily create and return the breaker state for a step. */\nexport function ensureBreakerState(\n breakers: Record<string, BreakerState>,\n key: string,\n): BreakerState {\n if (!breakers[key]) {\n breakers[key] = { state: 'closed', consecutiveFailures: 0 };\n }\n return breakers[key];\n}\n\n/**\n * The skip gate. Returns true when the step should be skipped (breaker open\n * and no probe slot available for this caller).\n *\n * On the open→half-open boundary the transition is atomic within this\n * synchronous call: the FIRST event at/after `openUntil` claims the probe\n * (sets `state='half-open'`, `probing=true`, re-arms `openUntil`) and is\n * admitted; every concurrent event then sees half-open with the probe taken\n * and skips. Single-threaded JS guarantees this mutate-before-return is not\n * interleaved with another gate call.\n */\nexport function isBreakerOpen(\n breakers: Record<string, BreakerState>,\n key: string,\n cooldown: number,\n): boolean {\n const breaker = breakers[key];\n if (!breaker || breaker.state === 'closed') return false;\n\n if (breaker.state === 'half-open') {\n // Probe slot already claimed by an earlier event in this window.\n return breaker.probing === true;\n }\n\n // state === 'open'\n const now = nowFn();\n if (breaker.openUntil !== undefined && now < breaker.openUntil) {\n return true; // still cooling down\n }\n\n // Cooldown elapsed: this caller becomes the single probe. Re-arm the window\n // and take the probe slot so concurrent callers still skip.\n breaker.state = 'half-open';\n breaker.probing = true;\n breaker.openUntil = now + cooldown;\n return false;\n}\n\n/**\n * Record a transport outcome for a step and apply the resulting state\n * transition. The single accounting authority for all sites.\n */\nexport function recordStepOutcome(\n breakers: Record<string, BreakerState>,\n key: string,\n outcome: StepOutcome,\n threshold: number,\n cooldown: number,\n): void {\n if (outcome === 'partial') return; // breaker-neutral\n\n const breaker = ensureBreakerState(breakers, key);\n\n if (outcome === 'success') {\n breaker.consecutiveFailures = 0;\n breaker.state = 'closed';\n breaker.probing = false;\n breaker.openUntil = undefined;\n return;\n }\n\n // transport-failure\n breaker.consecutiveFailures += 1;\n\n if (breaker.state === 'half-open') {\n // The probe failed: re-open with a fresh cooldown window.\n breaker.state = 'open';\n breaker.probing = false;\n breaker.openUntil = nowFn() + cooldown;\n return;\n }\n\n if (breaker.consecutiveFailures >= threshold) {\n breaker.state = 'open';\n breaker.probing = false;\n breaker.openUntil = nowFn() + cooldown;\n }\n}\n\n/**\n * Release a half-open probe slot WITHOUT recording an outcome. Called when an\n * admitted probe event settles on a path that never exercised the transport\n * (consent-denied, empty queue, queueOn-only, re-queued). The probe never\n * tested transport health, so it must not count as a failure or a success;\n * instead the breaker reverts half-open → open, keeping `consecutiveFailures`\n * intact, so the next event at/after the (already re-armed) `openUntil` can\n * probe again. Without this, an admitted probe that never pushes would leave\n * `probing=true` forever and the breaker would deadlock half-open.\n *\n * No-op unless the breaker is currently half-open with a probe in flight.\n */\nexport function releaseProbe(\n breakers: Record<string, BreakerState>,\n key: string,\n): void {\n const breaker = breakers[key];\n if (!breaker || breaker.state !== 'half-open' || breaker.probing !== true) {\n return;\n }\n breaker.state = 'open';\n breaker.probing = false;\n}\n\n/**\n * Predicate exposed for the BigQuery self-heal re-open (Task 4): true when a\n * probe would be permitted at `now` — the breaker is closed, half-open, or\n * open with its cooldown elapsed. Task 4 gates its re-open on this.\n */\nexport function isBreakerProbePermitted(\n breaker: BreakerState | undefined,\n now: number,\n): boolean {\n if (!breaker) return true;\n if (breaker.state === 'closed' || breaker.state === 'half-open') return true;\n return breaker.openUntil !== undefined && now >= breaker.openUntil;\n}\n","import type {\n Cache,\n Collector,\n Elb,\n Ingest,\n Source,\n Transformer,\n WalkerOS,\n} from '@walkeros/core';\nimport type { RespondFn, RespondOptions } from '@walkeros/core';\nimport {\n createIngest,\n FatalError,\n getMappingValue,\n getSpanId,\n parseTraceparent,\n isScope,\n tryCatchAsync,\n compileCache,\n checkCache,\n storeCache,\n applyUpdate,\n createMappingRoot,\n compileState,\n applyState,\n} from '@walkeros/core';\nimport { runTransformerChain } from './transformer';\nimport { buildReportError, errorMeta } from './report-error';\nimport { isStateDelivery, shouldDeliver, setMark } from './on';\nimport { reconcilePending } from './pending';\nimport { createPushResult } from './destination';\nimport { emitCollectorDrop } from './observerEmit';\nimport { getCacheStore, getStateStore } from './cache';\nimport {\n DEFAULT_DESTINATION_TIMEOUT_MS,\n DestinationTimeoutError,\n withTimeout,\n} from './timeout';\n\n/**\n * Flush a source's queueOn buffer. Called when the source becomes \"started\"\n * (config.init === true AND config.require is empty/absent). Idempotent:\n * the buffer is cleared before iteration, so re-entry from within an `on`\n * handler does not re-fire the same items.\n *\n * A throw inside `source.on` is treated as a pipeline failure: log via the\n * scoped 'source' logger and increment `status.failed`. The flush itself\n * is walkerOS-orchestrated startup; the throw represents the source's\n * inability to consume a buffered state-change event. A handler that does\n * not settle within the default destination timeout is logged the same way\n * but not counted, matching the live delivery path.\n *\n * State-delivery entries (consent/user/globals/custom) are gated through the\n * same per-source high-water mark as the direct `onApply` broadcast: while\n * `!allowed` they defer (not invoked, mark not advanced — the source stays\n * \"owed\" for the run-barrier re-delivery), and an allowed delivery advances\n * the source mark so a later broadcast at the same version does not double\n * deliver. Lifecycle/arbitrary entries (ready/run/session/config) flush with\n * their unchanged behavior.\n */\nexport async function flushSourceQueueOn(\n collector: Collector.Instance,\n source: Source.Instance,\n sourceId?: string,\n): Promise<void> {\n if (!source.on || !source.queueOn?.length) return;\n const queue = source.queueOn;\n source.queueOn = [];\n const id = sourceId || source.config?.id || 'unknown';\n for (const { type, data } of queue) {\n // Defer state deliveries while !allowed: leave them owed (drop the queued\n // entry without firing or advancing the mark). The run-barrier re-delivery\n // (a later task) re-broadcasts owed state to behind-mark subscribers.\n if (isStateDelivery(type) && !shouldDeliver(collector, source, type))\n continue;\n\n // Bounded like a live delivery: sources carry no per-step timeout config\n // and share the destination default.\n const handler = source.on;\n let timedOut = false;\n await tryCatchAsync(\n () =>\n withTimeout(\n Promise.resolve(handler(type, data)),\n DEFAULT_DESTINATION_TIMEOUT_MS,\n `Source \"${id}\" on(${type}) did not settle within ${DEFAULT_DESTINATION_TIMEOUT_MS}ms`,\n ),\n (err: unknown): undefined => {\n if (err instanceof FatalError) throw err;\n // A handler that did not settle in time is logged, as on the live\n // delivery path, and is not a pipeline failure.\n if (err instanceof DestinationTimeoutError) timedOut = true;\n else collector.status.failed++;\n collector.logger.scope('source').error('source on flush failed', {\n sourceId: id,\n type,\n ...errorMeta(err),\n });\n return undefined;\n },\n )();\n\n // A timed-out delivery has not happened: the mark stays, the cell stays owed.\n if (isStateDelivery(type) && !timedOut) setMark(collector, source, type);\n }\n}\n\n/**\n * A source is \"started\" — eligible to receive on() events directly — when\n * its init has run and any require gate is satisfied.\n */\nexport function isSourceStarted(source: Source.Instance): boolean {\n return Boolean(source.config.init) && !source.config.require?.length;\n}\n\n/**\n * Initialize a single source. Extracted from the initSources loop body\n * so it can be reused by the pending-source activator.\n */\nexport async function initSource(\n collector: Collector.Instance,\n sourceId: string,\n sourceDefinition: Source.InitSource,\n): Promise<Source.Instance | undefined> {\n const {\n code,\n config = {},\n env = {},\n primary,\n next,\n before,\n cache,\n terminus,\n } = sourceDefinition;\n\n // Compile declarative state entries once. For a source, all state entries\n // run before handing the event to `collector.push` (get enriches the event\n // the collector receives, set stashes from it), so they execute together in\n // array order. A config-level `state` takes precedence over the\n // definition-level one.\n const sourceState = config.state ?? sourceDefinition.state;\n const stateEntries = sourceState ? compileState(sourceState) : undefined;\n\n // Compile source cache config (if configured).\n // Source caches operate on events (request-scoped HIT/MISS keyed by event\n // fields), so the rule shape is always EventCacheRule, not StoreCacheRule.\n const sourceCacheConfig = cache as\n | Cache.Cache<Cache.EventCacheRule>\n | undefined;\n const compiledSourceCache = sourceCacheConfig\n ? compileCache({\n ...sourceCacheConfig,\n stop: sourceCacheConfig.stop ?? true,\n })\n : undefined;\n\n // The pipeline's end. `terminus` replaces the collector entirely; see the\n // field's doc on Source.InitSource for the full (total) semantics.\n const terminalPush: Collector.PushFn = terminus ?? collector.push;\n const hasTerminus = Boolean(terminus);\n\n /**\n * Execute the source pipeline for a single push call. Operates ONLY on\n * the per-call `scope` parameter — never reads source-factory closure\n * variables for ingest/respond. The scope is the unit of cross-request\n * isolation.\n *\n * The function may mutate `scope.respond` (cache MISS wraps it to\n * intercept the cached value before forwarding). That mutation is\n * scope-local: a concurrent call with its own scope is unaffected.\n */\n const executePush = async (\n rawEvent: WalkerOS.DeepPartialEvent,\n options: Collector.PushOptions,\n scope: { ingest: Ingest; respond: RespondFn | undefined },\n ): Promise<Elb.PushResult> => {\n // Total bypass: the terminus owns the pipeline and receives the raw event.\n // One early return instead of a per-stage conditional, so \"bypass\" cannot\n // drift into \"bypass some stages\".\n if (hasTerminus) return terminalPush(rawEvent);\n\n let pendingRespond: Promise<void> | undefined;\n\n // Mint the event's span id HERE when absent, so the source.before chain's\n // records carry the same id as the collector.push and destination records\n // of the same event; minting only at the collector wrap would leave every\n // before-chain record anonymous. The wrap then finds `id` set and keeps\n // it, as does `createEvent` (handle.ts): one span per event, end to end.\n const identified =\n typeof rawEvent.id === 'string' && rawEvent.id !== ''\n ? rawEvent\n : { ...rawEvent, id: getSpanId() };\n\n // The before chain may fan out (return an array of events). The cache\n // check and destination push must run once per event so fan-out is\n // preserved end-to-end. Cache logic is request-scoped (keyed by the\n // scope's ingest), so it lives outside the loop. The actual pipeline\n // (preChain + collector.push) runs inside the loop, once per event.\n let copies: Transformer.ChainCopy[] = [\n { event: identified, ingest: scope.ingest },\n ];\n\n // Run source.before chain (consent-exempt, pre-source preprocessing).\n // The route resolves hop by hop with `{ ingest, event }`, the event being\n // the source's raw output with its span id already minted.\n if (before !== undefined) {\n const chainPath = `source.${sourceId}.before`;\n const beforeResult = await runTransformerChain(\n collector,\n collector.transformers || {},\n before,\n identified,\n scope.ingest,\n scope.respond,\n chainPath,\n );\n if (beforeResult.copies.length === 0) {\n // Dropped or stopped: the event never reaches the collector.\n emitCollectorDrop(\n collector,\n identified,\n scope.ingest,\n beforeResult.droppedBy,\n chainPath,\n );\n return createPushResult({ ok: true, dropped: true });\n }\n // Pipeline-halt signal from a `cache.stop: true` HIT inside the\n // source.before chain. Do NOT invoke collector.push — drop the event\n // before it enters the collector pipeline.\n if (beforeResult.stopped) {\n if (beforeResult.respond) scope.respond = beforeResult.respond;\n return { ok: true } as Elb.PushResult;\n }\n if (beforeResult.respond) scope.respond = beforeResult.respond;\n\n // Every finished copy goes on with its own ingest and the id the\n // runner gave it (a single copy keeps the source-minted id).\n copies = beforeResult.copies;\n }\n\n // Source cache check (full=true by default for sources)\n if (compiledSourceCache) {\n const cacheStore = getCacheStore(compiledSourceCache, collector);\n if (cacheStore) {\n const cacheContext = createMappingRoot(scope.ingest);\n const cacheResult = await checkCache(\n compiledSourceCache,\n cacheStore,\n cacheContext,\n // no per-step prefix — cache keys honor user-provided namespace only\n );\n\n if (cacheResult) {\n if (cacheResult.status === 'HIT' && cacheResult.value !== undefined) {\n if (compiledSourceCache.stop) {\n // stop=true (default): respond with cached value, skip pipeline\n let respondValue: unknown = cacheResult.value;\n if (cacheResult.rule.update) {\n respondValue = await applyUpdate(\n respondValue,\n cacheResult.rule.update as Record<string, unknown>,\n { ...cacheContext, cache: { status: 'HIT' } },\n collector,\n );\n }\n scope.respond?.(respondValue as Record<string, unknown>);\n return { ok: true } as Elb.PushResult;\n }\n // stop=false: cached value unused — HIT signals \"seen before\", pipeline continues\n }\n\n if (\n cacheResult.status === 'MISS' &&\n compiledSourceCache.stop &&\n scope.respond\n ) {\n // stop=true MISS: wrap respond to intercept and cache the value.\n // Store original in cache, then apply update rules with MISS\n // status before responding (mirrors HIT path which applies\n // with HIT status).\n //\n // When `update` is configured the update step is async, so\n // the wrapper captures its promise in `pendingRespond`.\n // `executePush` awaits that promise before returning, so any\n // source fallback that runs after `await env.push(...)` (e.g.\n // the express source's transparent-GIF default) sees\n // `createRespond`'s first-call-wins flag already set and\n // correctly no-ops. Without this, the fallback would win\n // the race and the real response would be lost.\n const unwrappedRespond = scope.respond;\n const missUpdate = cacheResult.rule.update;\n const missContext = { ...cacheContext, cache: { status: 'MISS' } };\n const missKey = cacheResult.key;\n const missTtl = cacheResult.rule.ttl;\n\n const missRespond: RespondFn = (respondOptions) => {\n storeCache(cacheStore, missKey, respondOptions, missTtl);\n\n if (!missUpdate) {\n unwrappedRespond(respondOptions);\n return;\n }\n\n pendingRespond = (async () => {\n const updated = await applyUpdate(\n respondOptions,\n missUpdate as Record<string, unknown>,\n missContext,\n collector,\n );\n unwrappedRespond(updated as RespondOptions);\n })();\n };\n\n scope.respond = missRespond;\n }\n\n // stop=false MISS: store sentinel so subsequent requests get a HIT\n if (cacheResult.status === 'MISS' && !compiledSourceCache.stop) {\n storeCache(cacheStore, cacheResult.key, true, cacheResult.rule.ttl);\n }\n }\n }\n }\n\n // Apply declarative state per event before handing off to the collector.\n // Entries run sequentially in array order at this single pipeline point.\n if (stateEntries && stateEntries.length > 0) {\n copies = await Promise.all(\n copies.map(async (copy) => ({\n event: await applyState(\n stateEntries,\n (id) => getStateStore(id, collector),\n copy.event,\n collector,\n copy.ingest,\n ),\n ingest: copy.ingest,\n })),\n );\n }\n\n // Push each event independently through the post-before pipeline. The\n // source's `next` route travels as the pre-collector chain and resolves\n // per event, after the source's state, inside `collector.push`.\n let pushResult: Elb.PushResult = { ok: true } as Elb.PushResult;\n for (const copy of copies) {\n pushResult = await terminalPush(copy.event, {\n ...options,\n id: sourceId,\n ingest: copy.ingest,\n respond: scope.respond,\n mapping: config,\n preChain: next,\n });\n }\n\n // Wait for any deferred MISS update work to land on the source's\n // respond sender before returning control to the source. This\n // ensures source-level fallbacks (e.g. transparent GIFs) run after\n // the real response has been committed via first-call-wins.\n if (pendingRespond) await pendingRespond;\n\n return pushResult;\n };\n\n /**\n * Build a fresh per-scope `Ingest` from raw scope input by applying\n * `config.ingest` mapping if present. Always produces a typed Ingest\n * with valid `_meta`. Pure: returns a new object, never reads or\n * writes source-factory state.\n */\n const extractIngest = async (\n rawScope: Source.Scope | undefined,\n ): Promise<Ingest> => {\n const fresh = createIngest(sourceId);\n // Adopt an inbound W3C traceparent from the scope's header bag so every\n // server source gains trace continuity + parent-span linkage. The final\n // return reuses `fresh._meta` by reference, so stamping here holds for\n // both the mapped and unmapped paths. Sources can be user authored, so the\n // declared type is not assumed to hold at runtime; a miss resolves\n // nothing, which is the honest outcome.\n const traceparent = parseTraceparent(\n isScope(rawScope) ? rawScope?.headers?.traceparent : undefined,\n );\n if (traceparent) {\n fresh._meta.trace = traceparent.trace;\n fresh._meta.parentEventId = traceparent.parentSpan;\n }\n if (!config.ingest || rawScope === undefined) return fresh;\n const extracted = await getMappingValue(rawScope, config.ingest, {\n collector,\n });\n return {\n ...fresh,\n ...(extracted as Record<string, unknown>),\n _meta: fresh._meta, // protect _meta from being overwritten\n };\n };\n\n // Factory-default push: each call gets a fresh Ingest and no respond.\n // Sources with a single logical scope (browser, dataLayer) call this\n // directly via `env.push`. Server sources handling concurrent requests\n // call `context.withScope(...)` instead, which threads a per-scope\n // ingest/respond into the same pipeline.\n const wrappedPush: Collector.PushFn = async (\n rawEvent: WalkerOS.DeepPartialEvent,\n options: Collector.PushOptions = {},\n ) => {\n const scope = {\n ingest: createIngest(sourceId),\n respond: undefined as RespondFn | undefined,\n };\n return executePush(rawEvent, options, scope);\n };\n\n // Create initial logger scoped to sourceId (type will be added after init)\n const initialLogger = collector.logger.scope('source').scope(sourceId);\n\n // `env` is the source's dependency bag: the author owns it. The five\n // capabilities the collector provides are applied LAST so they always win,\n // uniformly. Writing one of them in `env` is therefore inert rather than\n // partially effective; to end the pipeline somewhere else, use\n // `InitSource.terminus`, which says so explicitly.\n const cleanEnv: Source.Env = {\n ...env,\n push: wrappedPush,\n command: collector.command,\n sources: collector.sources,\n elb: collector.elb,\n logger: initialLogger,\n };\n\n /**\n * Bind ingest and respond to a single scope of work. Each invocation\n * builds a fresh `Ingest`, captures the given `respond`, and runs the\n * caller's `body` with a per-scope env whose `push` carries both. The\n * scope is the unit of cross-call isolation — concurrent withScope\n * invocations never share ingest or respond.\n */\n const withScope: Source.Context['withScope'] = async (\n rawScope,\n respond,\n body,\n ) => {\n const scope: { ingest: Ingest; respond: RespondFn | undefined } = {\n ingest: await extractIngest(rawScope),\n respond,\n };\n const scopePush: Collector.PushFn = (rawEvent, options = {}) =>\n executePush(rawEvent, options, scope);\n const scopeEnv: Source.ScopeEnv = {\n ...cleanEnv,\n push: scopePush,\n ingest: scope.ingest,\n respond: scope.respond,\n };\n return body(scopeEnv);\n };\n\n const sourceContext: Source.Context = {\n collector,\n logger: initialLogger,\n id: sourceId,\n config,\n env: cleanEnv,\n withScope,\n reportError: buildReportError(collector, 'source', sourceId, initialLogger),\n };\n\n const sourceInstance = await tryCatchAsync(\n code,\n (err: unknown): undefined => {\n if (err instanceof FatalError) throw err;\n collector.status.failed++;\n collector.logger.scope('source').error('source factory failed', {\n sourceId,\n ...errorMeta(err),\n });\n return undefined;\n },\n )(sourceContext);\n if (!sourceInstance) return undefined;\n\n const sourceType = sourceInstance.type || 'unknown';\n const sourceLogger = collector.logger.scope(sourceType).scope(sourceId);\n cleanEnv.logger = sourceLogger;\n\n if (primary) {\n sourceInstance.config = { ...sourceInstance.config, primary };\n }\n\n return sourceInstance;\n}\n\n/**\n * Initialize sources. Sources with `require` are deferred to collector.pending.\n */\nexport async function initSources(\n collector: Collector.Instance,\n sources: Source.InitSources = {},\n): Promise<Collector.Sources> {\n const result: Collector.Sources = {};\n\n // Pass 1: register every source via its factory.\n for (const [sourceId, sourceDefinition] of Object.entries(sources)) {\n const sourceInstance = await initSource(\n collector,\n sourceId,\n sourceDefinition,\n );\n if (!sourceInstance) continue;\n // Propagate orchestration fields from the user's source definition into\n // the registered instance config. The factory does not know about\n // `require` — it's an InitSource-level concern that the collector owns.\n // Clone the array so per-source decrement (in onApply) doesn't mutate\n // the caller's config.\n const userRequire = sourceDefinition.config?.require;\n sourceInstance.config = {\n ...sourceInstance.config,\n init: false,\n ...(userRequire ? { require: [...userRequire] } : {}),\n };\n result[sourceId] = sourceInstance;\n }\n\n // Merge into collector.sources BEFORE pass 2 so that any onApply\n // broadcast triggered during init can find every source.\n Object.assign(collector.sources, result);\n\n // Pass 2: init each source. Side effects allowed here.\n for (const sourceId of Object.keys(result)) {\n const instance = collector.sources[sourceId];\n let initFailed = false;\n if (instance.init) {\n await tryCatchAsync(instance.init.bind(instance), (err: unknown) => {\n if (err instanceof FatalError) throw err;\n initFailed = true;\n collector.status.failed++;\n collector.logger.scope('source').error('source init failed', {\n sourceId,\n ...errorMeta(err),\n });\n })();\n }\n // Control-flow fix: a throw inside `init()` previously left the source\n // marked `config.init = true` despite never having completed setup.\n // Operators reading `source.config.init` would see a healthy source\n // that was actually broken. Skip the rest of the loop on failure so\n // the source stays in `config.init = false` and is visibly stuck.\n if (initFailed) continue;\n instance.config.init = true;\n if (isSourceStarted(instance)) {\n await flushSourceQueueOn(collector, instance, sourceId);\n }\n }\n\n // Registration trigger: a source's factory or init (Pass 2) may have recorded\n // state that satisfies another source's/destination's `require`. The live\n // broadcast can miss a step that was not yet merged into collector.sources\n // when the state fired (a factory emit during Pass 1), so reconcile once over\n // the now-fully-registered set to activate any step satisfied by current\n // state. This is the load-bearing fix for order-independent activation.\n await reconcilePending(collector);\n\n return result;\n}\n","/**\n * @module transformer\n *\n * Transformer Chains\n * ==================\n *\n * The one chain runner of walkerOS. Every chain position (`source.before`,\n * `source.next`, `transformer.before`, `destination.before`,\n * `destination.next`) and the CLI simulation run through\n * `runTransformerChain`.\n *\n * A chain starts from a Route (or a continuation of one). The runner loops\n * `advanceChain` from `@walkeros/core`, which resolves the route hop by hop\n * with the root the previous step left (`{ ingest, event }`):\n *\n * - `run`: the member runs (cache, `before`, `state`, push); its own `next`\n * is inserted right after it, then the explicit array continues.\n * - `fork` (a `many`, or a transformer returning `Result[]`): each copy\n * finishes the whole rest of the path on its own, with its own span id\n * (`deriveSpanId`) and a cloned ingest. Copies never merge; every finished\n * copy is handed back as its own event.\n * - `stop`: the running copy ends (`copies: []`, `stopped: true`).\n *\n * Chain termination per member:\n * - returns false or throws: the copy is dropped (`droppedBy`)\n * - returns void: continue with the unchanged event\n * - returns `{ event }`: continue with the new event\n * - returns `{ next }`: that route runs right after the member, in place of\n * the member's own `next`, then the array continues\n */\nimport type {\n Cache,\n ChainContinuation,\n Collector,\n RespondFn,\n Transformer,\n WalkerOS,\n Ingest,\n} from '@walkeros/core';\nimport {\n advanceChain,\n clone,\n createIngest,\n deriveSpanId,\n emitStep,\n FatalError,\n isChainContinuation,\n isObject,\n startChain,\n stepId,\n tryCatchAsync,\n useHooks,\n compileCache,\n checkCache,\n storeCache,\n createMappingRoot,\n validateStepEntry,\n processEventMapping,\n compileState,\n applyState,\n} from '@walkeros/core';\nimport { buildBaseState, journeyFields } from './observerEmit';\nimport { getCacheStore, getStateStore } from './cache';\nimport { buildReportError, errorMeta } from './report-error';\n\n/**\n * Extracts chain property from definition and merges into config.\n * Provides unified handling for source.next, destination.before, and transformer.next.\n *\n * @param definition - Component definition with optional chain property\n * @param propertyName - Name of chain property ('next' or 'before')\n * @returns Object with merged config and extracted chain value\n */\nexport function extractChainProperty<\n T extends { config?: Record<string, unknown>; [key: string]: unknown },\n>(\n definition: T,\n propertyName: 'next' | 'before',\n): {\n config: Record<string, unknown>;\n chainValue: string | string[] | undefined;\n} {\n const config = (definition.config || {}) as Record<string, unknown>;\n const chainValue = definition[propertyName] as string | string[] | undefined;\n\n if (chainValue !== undefined) {\n return {\n config: { ...config, [propertyName]: chainValue },\n chainValue,\n };\n }\n\n return { config, chainValue: undefined };\n}\n\n/**\n * Initializes transformer instances from configuration.\n * Does NOT call transformer.init() - that happens lazily before first push.\n *\n * @param collector - The collector instance\n * @param initTransformers - Transformer initialization configurations\n * @returns Initialized transformer instances\n */\nexport async function initTransformers(\n collector: Collector.Instance,\n initTransformers: Transformer.InitTransformers = {},\n): Promise<Transformer.Transformers> {\n const result: Transformer.Transformers = {};\n\n for (const [transformerId, transformerDef] of Object.entries(\n initTransformers,\n )) {\n const { code, env = {} } = transformerDef;\n\n // Validate the entry via the shared predicate. A code-less entry must\n // declare at least one operative field (package, before, next, cache,\n // state, mapping). Unknown keys and code+package conflicts are also\n // rejected.\n const validation = validateStepEntry(\n transformerDef as Record<string, unknown>,\n 'Transformer',\n );\n if (!validation.ok) {\n collector.logger.warn(\n `Transformer ${transformerId} invalid (${validation.code}): ${validation.reason}. Skipping.`,\n );\n continue;\n }\n\n // Use unified chain property extractor for both before and next\n const { config: configWithBefore } = extractChainProperty(\n transformerDef,\n 'before',\n );\n const { config: configWithChain } = extractChainProperty(\n { ...transformerDef, config: configWithBefore },\n 'next',\n );\n\n // Merge definition-level env into config so it's available during push.\n // transformerPush reads transformer.config.env to build the push context.\n const configWithEnv =\n Object.keys(env).length > 0\n ? { ...configWithChain, env: env as Transformer.Env }\n : configWithChain;\n\n // Merge definition-level cache into config for runtime access\n const { cache } = transformerDef;\n const configWithCache = cache ? { ...configWithEnv, cache } : configWithEnv;\n\n // Merge definition-level state into config for runtime access. A\n // config-level `state` (if present) takes precedence over def-level.\n const resolvedState = transformerDef.config?.state ?? transformerDef.state;\n const configWithState =\n resolvedState !== undefined && configWithCache.state === undefined\n ? { ...configWithCache, state: resolvedState }\n : configWithCache;\n\n // Build transformer context for init\n const transformerLogger = collector.logger\n .scope('transformer')\n .scope(transformerId);\n\n const context = {\n collector,\n logger: transformerLogger,\n id: transformerId,\n ingest: createIngest(transformerId),\n config: configWithState,\n env: env as Transformer.Env,\n reportError: buildReportError(\n collector,\n 'transformer',\n transformerId,\n transformerLogger,\n ),\n };\n\n // Synthesize a passthrough instance when `code` is absent.\n // This makes the entry a \"pass\" — a named, code-less hop. Two flavors:\n // 1. mapping-aware: when `mapping` is declared, the synthesized push\n // runs `processEventMapping` and forwards the transformed event\n // (or drops it when a rule has `ignore: true`).\n // 2. plain passthrough: when only `before` / `next` / `cache` are\n // declared, the push returns the event unchanged.\n const codeFn =\n code ??\n ((ctx: Transformer.Context) => {\n const stepMapping = transformerDef.mapping;\n if (stepMapping) {\n // Warn once per init if vendor-payload fields are present at the\n // transformer position. Only event-mutating fields apply here.\n // Note: `MappingConfig` has no top-level `silent` field — that\n // lives on `Rule` only, so the config-level check is `data` only.\n const meaninglessFields: string[] = [];\n if (stepMapping.data !== undefined) meaninglessFields.push('data');\n // Walk rules for per-rule data/silent\n if (stepMapping.mapping) {\n for (const [entity, actions] of Object.entries(\n stepMapping.mapping,\n )) {\n if (typeof actions !== 'object' || actions === null) continue;\n for (const [action, rule] of Object.entries(\n actions as Record<string, unknown>,\n )) {\n if (typeof rule !== 'object' || rule === null) continue;\n const r = rule as Record<string, unknown>;\n if (r.data !== undefined)\n meaninglessFields.push(`mapping[${entity}][${action}].data`);\n if (r.silent !== undefined)\n meaninglessFields.push(\n `mapping[${entity}][${action}].silent`,\n );\n }\n }\n }\n if (meaninglessFields.length > 0) {\n ctx.collector.logger.warn(\n `Transformer ${transformerId}: \\`${meaninglessFields.join(', ')}\\` ignored at transformer position (only event-mutating fields apply).`,\n );\n }\n\n return {\n type: 'pass',\n config: ctx.config,\n push: async (event: WalkerOS.DeepPartialEvent) => {\n const r = await processEventMapping(\n event,\n stepMapping,\n ctx.collector,\n );\n if (r.ignore) return false;\n return { event: r.event };\n },\n };\n }\n return {\n type: 'pass',\n config: ctx.config,\n push: (event: WalkerOS.DeepPartialEvent) => ({ event }),\n };\n });\n\n // Initialize the transformer instance with context\n const instance = await codeFn(context);\n\n // Bug 2 fix: propagate def-level before/next to instance.config when\n // not already set by the code function. The recursive chain walker\n // reads instance.config.before; for synthesized pass-throughs and\n // well-behaved user code that returns a fresh config object, the\n // def-level value needs to land on instance.config explicitly.\n // User-supplied code that sets its own config.before is preserved.\n if (\n transformerDef.before !== undefined &&\n instance.config?.before === undefined\n ) {\n instance.config = {\n ...(instance.config ?? {}),\n before: transformerDef.before,\n };\n }\n if (\n transformerDef.next !== undefined &&\n instance.config?.next === undefined\n ) {\n instance.config = {\n ...(instance.config ?? {}),\n next: transformerDef.next,\n };\n }\n // Propagate the precedence-resolved state (config-level wins over\n // def-level) onto instance.config when a custom factory dropped it.\n if (resolvedState !== undefined && instance.config?.state === undefined) {\n instance.config = {\n ...(instance.config ?? {}),\n state: resolvedState,\n };\n }\n\n result[transformerId] = instance;\n }\n\n return result;\n}\n\n/**\n * Initializes a transformer if it hasn't been initialized yet.\n * Called lazily before first push.\n *\n * @param collector - The collector instance\n * @param transformer - The transformer to initialize\n * @param transformerId - The transformer ID\n * @returns Whether initialization succeeded\n */\nexport async function transformerInit(\n collector: Collector.Instance,\n transformer: Transformer.Instance,\n transformerId: string,\n): Promise<boolean> {\n // Check if already initialized\n if (transformer.init && !transformer.config.init) {\n const transformerType = transformer.type || 'unknown';\n const transformerLogger = collector.logger.scope(\n `transformer:${transformerType}`,\n );\n\n const context: Transformer.Context = {\n collector,\n logger: transformerLogger,\n id: transformerId,\n ingest: createIngest(transformerId),\n config: transformer.config,\n env: mergeTransformerEnvironments(transformer.config.env),\n reportError: buildReportError(\n collector,\n 'transformer',\n transformerId,\n transformerLogger,\n ),\n };\n\n transformerLogger.debug('init');\n\n const configResult = await useHooks(\n transformer.init,\n 'TransformerInit',\n collector.hooks,\n collector.logger,\n )(context);\n\n // Check for initialization failure\n if (configResult === false) return false;\n\n // Update config if returned, preserving env from definition\n transformer.config = {\n ...(configResult || transformer.config),\n env:\n ((configResult as Record<string, unknown>)?.env as Transformer.Env) ||\n transformer.config.env,\n init: true,\n };\n\n transformerLogger.debug('init done');\n }\n\n return true;\n}\n\n/**\n * Pushes an event through a single transformer.\n *\n * @param collector - The collector instance\n * @param transformer - The transformer to push to\n * @param transformerId - The transformer ID\n * @param event - The event to process\n * @param ingest - Mutable ingest context flowing through the pipeline\n * @returns The processed event, void for passthrough, or false to stop chain\n */\nexport async function transformerPush(\n collector: Collector.Instance,\n transformer: Transformer.Instance,\n transformerId: string,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n respond?: import('@walkeros/core').RespondFn,\n): Promise<Transformer.Result | Transformer.Result[] | false | void> {\n const transformerType = transformer.type || 'unknown';\n const transformerLogger = collector.logger.scope(\n `transformer:${transformerType}`,\n );\n\n const context: Transformer.Context = {\n collector,\n logger: transformerLogger,\n id: transformerId,\n ingest: ingest!, // Mutable shared context\n config: transformer.config,\n env: {\n ...mergeTransformerEnvironments(transformer.config.env),\n ...(respond ? { respond } : {}),\n },\n reportError: buildReportError(\n collector,\n 'transformer',\n transformerId,\n transformerLogger,\n ),\n };\n\n transformerLogger.debug('push', { event: (event as { name?: string }).name });\n\n const eventId = typeof event.id === 'string' ? event.id : '';\n const { traceId, sourceId, parentEventId } = journeyFields(\n event,\n ingest,\n collector,\n );\n const started = Date.now();\n const inState = buildBaseState(collector, {\n stepId: stepId('transformer', transformerId),\n stepType: 'transformer',\n phase: 'in',\n eventId,\n now: started,\n traceId,\n sourceId,\n parentEventId,\n });\n inState.inEvent = event;\n emitStep(collector, inState);\n\n try {\n const result = await useHooks(\n transformer.push,\n 'TransformerPush',\n collector.hooks,\n collector.logger,\n )(event, context);\n\n const finished = Date.now();\n const outState = buildBaseState(collector, {\n stepId: stepId('transformer', transformerId),\n stepType: 'transformer',\n phase: 'out',\n eventId,\n now: finished,\n traceId,\n sourceId,\n parentEventId,\n });\n outState.durationMs = finished - started;\n outState.outEvent = result;\n emitStep(collector, outState);\n\n transformerLogger.debug('push done');\n\n return result;\n } catch (err) {\n const finished = Date.now();\n const errState = buildBaseState(collector, {\n stepId: stepId('transformer', transformerId),\n stepType: 'transformer',\n phase: 'error',\n eventId,\n now: finished,\n traceId,\n sourceId,\n parentEventId,\n });\n errState.durationMs = finished - started;\n errState.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n emitStep(collector, errState);\n throw err;\n }\n}\n\n/**\n * Clone an ingest for an independent copy (a fork). The top level and\n * `_meta` are shallow-copied and `_meta.path` is duplicated, so the path\n * budget and hop count of one copy never leak into a sibling.\n */\nexport function cloneIngest(ingest: Ingest): Ingest {\n return {\n ...ingest,\n _meta: { ...ingest._meta, path: [...ingest._meta.path] },\n };\n}\n\n/** Safety valve against unbounded path growth, per copy. */\nconst MAX_PATH_LENGTH = 256;\n\n/** What every copy of one chain run shares. */\ninterface ChainRun {\n collector: Collector.Instance;\n transformers: Transformer.Transformers;\n chainContext?: string;\n}\n\n/** A cache MISS of a member, written once the member settled. */\ninterface CacheMiss {\n key: string;\n ttl: number;\n}\n\n/** A member about to run, as `advanceChain` handed it out. */\ninterface Member {\n id: string;\n ancestry: readonly string[];\n /** The stack after the member; carries its own `next` on top if any. */\n rest: ChainContinuation;\n /** Whether `rest` carries the member's own `next` on top. */\n ownNext: boolean;\n}\n\n/**\n * A member that resumes after its `before` chain fanned out: each child\n * runs the member's own push (no second `before`, path and cache already\n * accounted for by the parent copy).\n */\ninterface Resume {\n member: Member;\n cacheMiss?: CacheMiss;\n}\n\n/** One independent copy of the event walking the chain. */\ninterface Copy {\n stack: ChainContinuation;\n event: WalkerOS.DeepPartialEvent;\n ingest: Ingest;\n respond: RespondFn | undefined;\n resume?: Resume;\n}\n\ntype MemberOutcome =\n | { kind: 'halt'; result: Transformer.ChainResult }\n | { kind: 'fork'; copies: Copy[] }\n | {\n kind: 'continue';\n event: WalkerOS.DeepPartialEvent;\n respond: RespondFn | undefined;\n stack: ChainContinuation;\n };\n\n/** The event's id, or '' when it has none. */\nfunction idOf(event: WalkerOS.DeepPartialEvent): string {\n return typeof event.id === 'string' ? event.id : '';\n}\n\n/**\n * Identity along one copy: an event a member handed on without an id (a\n * rebuilt event, a mock, a cached value) is still the event the member\n * received, so it keeps that id. The one identity rule for a single path;\n * forks derive theirs in `forkOf`.\n */\nfunction keepIdentity(\n received: WalkerOS.DeepPartialEvent,\n event: WalkerOS.DeepPartialEvent,\n): WalkerOS.DeepPartialEvent {\n const id = idOf(received);\n return id !== '' && idOf(event) === '' ? { ...event, id } : event;\n}\n\n/**\n * A fork child: a deep copy of the event (siblings run concurrently and\n * must never share nested objects), with its own cloned ingest. A child\n * still carrying the parent's id (or no id) gets a span id derived from the\n * parent id and its position, so forks never collapse on `event.id`; a\n * child with an id of its own keeps it. The ingest records the parent as\n * `parentEventId`, which links the fork into the parent's journey.\n */\nfunction forkOf(\n parent: WalkerOS.DeepPartialEvent,\n child: WalkerOS.DeepPartialEvent,\n ingest: Ingest,\n position: number,\n): { event: WalkerOS.DeepPartialEvent; ingest: Ingest } {\n const forkIngest = cloneIngest(ingest);\n const event = clone(child);\n const parentId = idOf(parent);\n if (parentId === '') return { event, ingest: forkIngest };\n forkIngest._meta.parentEventId = parentId;\n const childId = idOf(event);\n if (childId === '' || childId === parentId)\n event.id = deriveSpanId(parentId, position);\n return { event, ingest: forkIngest };\n}\n\n/** A finished result: every copy that continues, with its ingest. */\nfunction finished(\n copies: Transformer.ChainCopy[],\n respond: RespondFn | undefined,\n): Transformer.ChainResult {\n return { copies, respond };\n}\n\n/** The stack after a member, with a route pushed on its behalf. */\nfunction withMemberRoute(\n member: Member,\n route: Transformer.Route | undefined,\n): ChainContinuation {\n if (route === undefined) return member.rest;\n // A route the member returned replaces the member's own `next`.\n const below = member.ownNext ? member.rest.slice(1) : member.rest;\n return [{ route, ancestry: member.ancestry }, ...below];\n}\n\n/**\n * Runs every copy of a fork to its end, each isolated (a throw in one copy\n * never starves its siblings). Finished copies are handed back one by one;\n * a copy that was dropped or stopped contributes nothing. A copy started\n * without `respond` cannot hand a respond back (no respond across `many`).\n */\nasync function runForks(\n run: ChainRun,\n copies: Copy[],\n respond: RespondFn | undefined,\n): Promise<Transformer.ChainResult> {\n const results = await Promise.all(\n copies.map((copy, index) =>\n tryCatchAsync(runCopy, (err): Transformer.ChainResult => {\n run.collector.logger\n .scope('transformer:fork')\n .error(`fork ${index} failed`, errorMeta(err));\n return { copies: [] };\n })(run, copy),\n ),\n );\n\n const survivors: Transformer.ChainCopy[] = [];\n let lastRespond = respond;\n let allStopped = results.length > 0;\n let droppedBy: string | undefined;\n results.forEach((result, index) => {\n if (copies[index].respond !== undefined && result.respond)\n lastRespond = result.respond;\n if (!result.stopped) allStopped = false;\n // A dropped or stopped copy (route stop or cache.stop halt) ends here.\n if (result.stopped || result.copies.length === 0) {\n if (droppedBy === undefined) droppedBy = result.droppedBy;\n return;\n }\n survivors.push(...result.copies);\n });\n\n if (survivors.length === 0) {\n return {\n copies: survivors,\n respond: lastRespond,\n ...(allStopped ? { stopped: true as const } : {}),\n ...(droppedBy !== undefined ? { droppedBy } : {}),\n };\n }\n return finished(survivors, lastRespond);\n}\n\n/** Walks one copy to its end: loops `advanceChain`, runs each member. */\nasync function runCopy(\n run: ChainRun,\n copy: Copy,\n): Promise<Transformer.ChainResult> {\n const { ingest } = copy;\n let { stack, event, respond } = copy;\n let resume = copy.resume;\n\n for (;;) {\n let member: Member;\n let resumed: Resume | undefined;\n if (resume) {\n member = resume.member;\n resumed = resume;\n resume = undefined;\n } else {\n const step = advanceChain(\n stack,\n createMappingRoot(ingest, event),\n run.transformers,\n );\n if (step.kind === 'done') return finished([{ event, ingest }], respond);\n if (step.kind === 'stop') {\n return {\n copies: [],\n respond,\n stopped: true,\n ...(step.owner !== undefined ? { droppedBy: step.owner } : {}),\n };\n }\n if (step.kind === 'fork') {\n const parent = event;\n return runForks(\n run,\n step.branches.map((branch, position) => ({\n stack: branch,\n ...forkOf(parent, parent, ingest, position),\n respond: undefined,\n })),\n respond,\n );\n }\n const transformer = run.transformers[step.id];\n member = {\n id: step.id,\n ancestry: step.ancestry,\n rest: step.rest,\n ownNext: transformer ? transformer.config.next !== undefined : false,\n };\n }\n\n const outcome = await runMember(\n run,\n member,\n event,\n ingest,\n respond,\n resumed,\n );\n if (outcome.kind === 'halt') return outcome.result;\n if (outcome.kind === 'fork') return runForks(run, outcome.copies, respond);\n event = outcome.event;\n respond = outcome.respond;\n stack = outcome.stack;\n }\n}\n\n/**\n * Runs one member: path accounting, init, mocks, cache, its `before` chain,\n * `state`, the push, and the result handling. Returns how the copy goes on.\n */\nasync function runMember(\n run: ChainRun,\n member: Member,\n event: WalkerOS.DeepPartialEvent,\n ingest: Ingest,\n respond: RespondFn | undefined,\n resumed: Resume | undefined,\n): Promise<MemberOutcome> {\n const { collector, transformers, chainContext } = run;\n const transformerName = member.id;\n const transformer = transformers[transformerName];\n let processedEvent = event;\n let currentRespond = respond;\n const goOn = (stack: ChainContinuation = member.rest): MemberOutcome => ({\n kind: 'continue',\n event: keepIdentity(event, processedEvent),\n respond: currentRespond,\n stack,\n });\n // A dropped or route-stopped copy hands nothing on (`copies: []`); a\n // `cache.stop` halt hands its cached copy on, flagged `stopped`, for the\n // caller to decide.\n const halt = (result: Transformer.ChainResult): MemberOutcome => ({\n kind: 'halt',\n result,\n });\n\n if (!transformer) {\n collector.logger.warn(`Transformer not found: ${transformerName}`);\n return goOn();\n }\n\n // Compile transformer cache once (reused for HIT check and MISS store).\n // Transformer caches operate on events (step-level HIT/MISS keyed by event\n // fields), so the rule shape is always EventCacheRule, not StoreCacheRule.\n const tCacheConfig = transformer.config?.cache as\n | Cache.Cache<Cache.EventCacheRule>\n | undefined;\n const compiledTCache = tCacheConfig ? compileCache(tCacheConfig) : undefined;\n const tCacheStore = compiledTCache\n ? getCacheStore(compiledTCache, collector)\n : undefined;\n\n let cacheMiss: CacheMiss | undefined = resumed?.cacheMiss;\n\n if (!resumed) {\n // Safety valve: prevent unbounded path growth\n if (ingest._meta.path.length > MAX_PATH_LENGTH) {\n collector.logger.error(`Max path length exceeded at ${transformerName}`);\n return halt({ copies: [], respond: currentRespond });\n }\n\n // Track step in _meta (runtime-managed)\n ingest._meta.hops++;\n ingest._meta.path.push(transformerName);\n\n // Initialize transformer if needed. The wrap surfaces a thrown init\n // (misconfiguration, missing env, etc.) with full cause via the scoped\n // logger and counts it on `status.failed`. A non-throw `false` return\n // from transformerInit itself flows through the same early return below.\n const isInitialized = await tryCatchAsync(\n transformerInit,\n (err: unknown): boolean => {\n if (err instanceof FatalError) throw err;\n collector.status.failed++;\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .error('transformer init failed', {\n transformer: transformerName,\n ...errorMeta(err),\n });\n return false;\n },\n )(collector, transformer, transformerName);\n\n if (!isInitialized) return halt({ copies: [], respond: currentRespond });\n\n // Path-specific mock check (takes precedence)\n if (\n chainContext &&\n transformer.config?.chainMocks?.[chainContext] !== undefined\n ) {\n const chainMock = transformer.config.chainMocks[chainContext];\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .debug('chainMock', { chain: chainContext });\n processedEvent = chainMock as WalkerOS.DeepPartialEvent;\n return goOn();\n }\n\n // Global mock check\n if (transformer.config?.mock !== undefined) {\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .debug('mock');\n processedEvent = transformer.config.mock as WalkerOS.DeepPartialEvent;\n return goOn();\n }\n\n // Disabled check\n if (transformer.config?.disabled) return goOn();\n\n // Check transformer cache (step-level: skip push, continue chain)\n if (compiledTCache && tCacheStore) {\n const cacheResult = await checkCache(\n compiledTCache,\n tCacheStore,\n createMappingRoot(ingest, processedEvent),\n );\n\n if (cacheResult?.status === 'HIT' && cacheResult.value) {\n processedEvent = cacheResult.value as WalkerOS.DeepPartialEvent;\n // stop=true: stop the chain AND halt the pipeline at this position.\n // Callers branch on `stopped` to skip downstream stages.\n if (compiledTCache.stop) {\n const cached = keepIdentity(event, processedEvent);\n return halt({\n copies: [{ event: cached, ingest }],\n respond: currentRespond,\n stopped: true,\n });\n }\n return goOn(); // stop=false: next member\n }\n\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\n }\n }\n\n // The member's `before` chain (mandatory preparation).\n if (transformer.config.before !== undefined) {\n const before = await runTransformerBefore(\n collector,\n transformers,\n transformerName,\n processedEvent,\n ingest,\n currentRespond,\n chainContext,\n );\n const beforeRespond = before.respond ?? currentRespond;\n // Dropped, stopped, or a nested `cache.stop: true` HIT: the copy halts\n // with what the before chain handed back.\n if (before.copies.length === 0 || before.stopped) {\n return halt({ ...before, respond: beforeRespond });\n }\n currentRespond = beforeRespond;\n const [first] = before.copies;\n if (before.copies.length > 1 || first.ingest !== ingest) {\n // The before chain forked: every surviving copy runs this member and\n // the rest of the path as its own copy, with its own ingest and id\n // (both set by the fork inside the before chain).\n const resume: Resume = { member, cacheMiss };\n return {\n kind: 'fork',\n copies: before.copies.map((copy) => ({\n stack: member.rest,\n event: copy.event,\n ingest: copy.ingest,\n respond: undefined,\n resume,\n })),\n };\n }\n processedEvent = first.event;\n }\n }\n\n // Compile declarative state entries. `get` runs before the push (so the\n // mapping can read fetched values); `set` runs after the push settled the\n // event and before the member's route resolves.\n const stateEntries = transformer.config?.state\n ? compileState(transformer.config.state)\n : undefined;\n const stateGet = stateEntries?.filter((entry) => entry.mode === 'get');\n const stateSet = stateEntries?.filter((entry) => entry.mode === 'set');\n\n const applyStateSet = async (\n evt: WalkerOS.DeepPartialEvent,\n ): Promise<WalkerOS.DeepPartialEvent> => {\n if (!stateSet || stateSet.length === 0) return evt;\n return applyState(\n stateSet,\n (id) => getStateStore(id, collector),\n evt,\n collector,\n ingest,\n );\n };\n\n if (stateGet && stateGet.length > 0) {\n processedEvent = await applyState(\n stateGet,\n (id) => getStateStore(id, collector),\n processedEvent,\n collector,\n ingest,\n );\n }\n\n // Run the transformer\n const result = await tryCatchAsync(transformerPush, (err) => {\n collector.status.failed++;\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .error('Push failed', errorMeta(err));\n return false as const; // Stop chain on error\n })(\n collector,\n transformer,\n transformerName,\n processedEvent,\n ingest,\n currentRespond,\n );\n\n // Returned false, or threw and was converted to false above.\n if (result === false) {\n return halt({\n copies: [],\n respond: currentRespond,\n droppedBy: transformerName,\n });\n }\n\n // `Result[]`: every result is a fork that finishes the rest of the path.\n if (Array.isArray(result) && result.length !== 1) {\n if (result.length === 0)\n return halt({ copies: [], respond: currentRespond });\n const parent = processedEvent;\n const copies: Copy[] = [];\n for (let position = 0; position < result.length; position++) {\n const forkResult = result[position];\n const settled = await applyStateSet(forkResult.event || parent);\n copies.push({\n stack: withMemberRoute(member, forkResult.next),\n ...forkOf(parent, settled, ingest, position),\n respond: currentRespond,\n });\n }\n return { kind: 'fork', copies };\n }\n\n // One result (a one-element `Result[]` continues in place, like a `many`\n // with one match).\n const single = Array.isArray(result) ? result[0] : result;\n let resultNext: Transformer.Route | undefined;\n if (single && typeof single === 'object') {\n if (single.respond) currentRespond = single.respond;\n if (single.event) processedEvent = single.event;\n resultNext = single.next;\n }\n\n processedEvent = await applyStateSet(processedEvent);\n\n // Cache MISS: store the processed event after push\n if (cacheMiss && tCacheStore) {\n storeCache(tCacheStore, cacheMiss.key, processedEvent, cacheMiss.ttl);\n }\n\n return goOn(withMemberRoute(member, resultNext));\n}\n\n/**\n * Runs an event through a chain: the one chain runner.\n *\n * @param collector - The collector instance with transformers\n * @param transformers - Map of transformer instances\n * @param start - The route to run (a chain field such as `source.next`), or\n * a continuation of one; `undefined` runs nothing\n * @param event - The event to process\n * @param ingest - Mutable ingest context flowing through the pipeline\n * @param respond - The respond function in scope\n * @param chainContext - Chain path (e.g. `destination.ga4.before`), recorded\n * as `ingest._meta.chainPath` and keying `chainMocks`\n * @returns Every finished copy with its own ingest (`copies`, empty when\n * dropped or stopped) and the respond in scope afterwards\n */\nexport async function runTransformerChain(\n collector: Collector.Instance,\n transformers: Transformer.Transformers,\n start: Transformer.Route | ChainContinuation | undefined,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n respond?: RespondFn,\n chainContext?: string,\n): Promise<Transformer.ChainResult> {\n // Ensure an ingest exists so the per-copy path budget engages regardless\n // of the caller.\n const chainIngest =\n ingest ?? createIngest(typeof start === 'string' ? start : 'chain');\n if (start === undefined)\n return finished([{ event, ingest: chainIngest }], respond);\n if (chainContext) chainIngest._meta.chainPath = chainContext;\n\n return runCopy(\n { collector, transformers, chainContext },\n {\n stack: isChainContinuation(start) ? start : startChain(start),\n event,\n ingest: chainIngest,\n respond,\n },\n );\n}\n\n/**\n * Runs a transformer's `before` chain: the one implementation, used by the\n * chain runner for every member and by the CLI simulation. A `stop` that\n * the before route itself resolved is attributed to the transformer.\n */\nexport async function runTransformerBefore(\n collector: Collector.Instance,\n transformers: Transformer.Transformers,\n transformerId: string,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n respond?: RespondFn,\n chainContext?: string,\n): Promise<Transformer.ChainResult> {\n const transformer = transformers[transformerId];\n const before = transformer ? transformer.config.before : undefined;\n const result = await runTransformerChain(\n collector,\n transformers,\n before,\n event,\n ingest,\n respond,\n chainContext,\n );\n if (result.stopped && result.copies.length === 0 && !result.droppedBy)\n return { ...result, droppedBy: transformerId };\n return result;\n}\n\n/**\n * Merges transformer environments.\n */\nfunction mergeTransformerEnvironments(\n configEnv?: Transformer.Env,\n): Transformer.Env {\n if (!configEnv) return {};\n if (isObject(configEnv)) return configEnv;\n return {};\n}\n","import type { Collector, Store } from '@walkeros/core';\nimport type { CompiledCache } from '@walkeros/core';\n\n/**\n * Returns the store for a compiled cache config.\n * Uses the explicit store reference if provided, otherwise falls back to the\n * collector's default __cache store.\n */\nexport function getCacheStore(\n compiled: CompiledCache,\n collector: Collector.Instance,\n): Store.Instance | undefined {\n if (compiled.storeId && collector.stores[compiled.storeId]) {\n return collector.stores[compiled.storeId];\n }\n return collector.stores.__cache;\n}\n\n/**\n * Returns the store for a declarative `state` operation.\n * An explicit store id resolves to `collector.stores[id]` (or `undefined`\n * when that store is not declared). An omitted id falls back to the default\n * in-memory `__cache` store.\n */\nexport function getStateStore(\n storeId: string | undefined,\n collector: Pick<Collector.Instance, 'stores'>,\n): Store.Instance | undefined {\n if (storeId) return collector.stores[storeId];\n return collector.stores.__cache;\n}\n","/**\n * Default per-destination delivery timeout in ms. Applied when a destination's\n * `config.timeout` is `0` or undefined. A hung delivery is converted into a\n * counted DLQ failure after this window so one slow destination never wedges\n * the collector push.\n */\nexport const DEFAULT_DESTINATION_TIMEOUT_MS = 10_000;\n\n/**\n * Resolve the effective delivery timeout for a destination. A positive number\n * wins; `0` or undefined falls back to {@link DEFAULT_DESTINATION_TIMEOUT_MS}.\n */\nexport function resolveDestinationTimeout(timeout?: number): number {\n return typeof timeout === 'number' && timeout > 0\n ? timeout\n : DEFAULT_DESTINATION_TIMEOUT_MS;\n}\n\n/**\n * Error thrown when a destination delivery does not settle within its timeout.\n * The dedicated `name` lets DLQ consumers discriminate a timeout from a\n * destination-thrown error without substring matching the message.\n */\nexport class DestinationTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DestinationTimeoutError';\n }\n}\n\n/**\n * Races a delivery promise against a per-destination timeout. If the work does\n * not settle within `ms`, the returned promise rejects with a\n * {@link DestinationTimeoutError}; the timer is always cleared on settle so no\n * dangling timer remains. The race is constructed per call site, so each\n * destination times out independently and one hang never affects another.\n */\nexport function withTimeout<T>(\n work: Promise<T>,\n ms: number,\n message: string,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new DestinationTimeoutError(message)), ms);\n });\n return Promise.race([work, timeout]).finally(() => {\n if (timer) clearTimeout(timer);\n });\n}\n","import type { Collector } from '@walkeros/core';\nimport { registerDestination } from './destination';\nimport { catchUpDestinationState, isRequireSatisfied } from './on';\nimport { flushSourceQueueOn, isSourceStarted } from './source';\n\n/**\n * Drive activation of every not-yet-active source or destination whose\n * `require` gate is now fully satisfied by the collector's CURRENT recorded\n * state. This is the load-bearing, order-independent safety net: a step\n * activates from the present state regardless of whether the required type\n * fired before or after the step registered (the level, not the broadcast\n * edge). Runs at four triggers (source registration, every state change, the\n * run barrier, dynamic destination add); each call is idempotent.\n *\n * Guards:\n * - Additive. A `require` entry is removed IFF `isRequireSatisfied` (a\n * cell-backed type is present, or an arbitrary type was recorded in\n * `seenEvents`). The broadcast-decrement path in `onApply` stays fully\n * intact, so non-state/arbitrary `require` remains broadcast-satisfiable.\n * - Monotonic + idempotent. A step transitions pending→active exactly once:\n * started sources and already-registered destinations are excluded from the\n * worklist, and `flushSourceQueueOn` clears the buffer it drains.\n * - Delivery-inert while `!allowed`. A source it starts flushes its queueOn,\n * but `flushSourceQueueOn` defers state deliveries (no `on` call, no\n * `setMark`) until allowed. An activated destination only seeds `queuePush`;\n * its `init()`/send stay behind the `!allowed` gate in `pushToDestinations`.\n * - An activated destination also catches up on the present state cells\n * through the gated delivery, so its `on` handler sees the state that\n * activated it before its queue drains; while `!allowed` that catch-up is\n * inert and the run barrier delivers instead.\n *\n * Worklist is scoped to not-yet-active steps only (`pending.destinations` plus\n * unstarted sources); the live `collector.destinations`/started sources are\n * never rescanned.\n */\nexport async function reconcilePending(\n collector: Collector.Instance,\n): Promise<void> {\n // Sources: drop satisfied require entries; flush any that transition to\n // started (init done AND require now empty).\n for (const [sourceId, source] of Object.entries(collector.sources)) {\n if (isSourceStarted(source)) continue;\n const require = source.config.require;\n if (!require?.length) continue;\n\n const remaining = require.filter((t) => !isRequireSatisfied(collector, t));\n if (remaining.length === require.length) continue; // nothing newly satisfied\n\n source.config.require = remaining;\n if (isSourceStarted(source)) {\n await flushSourceQueueOn(collector, source, sourceId);\n }\n }\n\n // Destinations: drop satisfied require entries; register + seed queuePush for\n // any whose require fully empties.\n for (const [id, def] of Object.entries(collector.pending.destinations)) {\n if (!collector.pending.destinations[id] || collector.destinations[id])\n continue;\n\n const require = def.config?.require;\n if (!require) continue;\n\n const remaining = require.filter((t) => !isRequireSatisfied(collector, t));\n if (def.config) def.config.require = remaining;\n if (remaining.length > 0) continue;\n\n delete collector.pending.destinations[id];\n const instance = registerDestination(def);\n if (instance.config.queue !== false) {\n instance.queuePush = [...collector.queue];\n }\n collector.destinations[id] = instance;\n await catchUpDestinationState(collector, instance, id);\n }\n}\n","import type {\n Collector,\n WalkerOS,\n Destination,\n Elb,\n Hooks,\n Ingest,\n On,\n} from '@walkeros/core';\nimport { Const } from './constants';\nimport {\n addDestination,\n markHeldForDrain,\n mergePushResults,\n pushToDestinations,\n settleDestinationDeliveries,\n createPushResult,\n} from './destination';\nimport {\n assign,\n getSpanId,\n getTraceId,\n InvalidEventError,\n isFunction,\n isString,\n} from '@walkeros/core';\nimport { isObject } from '@walkeros/core';\nimport { processConsent } from './consent';\nimport { on, onApplyDeferred, startRunRedelivery, enterCascade } from './on';\nimport type { DestinationDelivery } from './on';\nimport { reconcilePending } from './pending';\nimport { destroyAllSteps } from './shutdown';\nimport type { RunState } from './types/collector';\n\n// Replaced at build time by tsup's `define` (see packages/config/tsup).\ndeclare const __VERSION__: string;\n\n/**\n * Record a reactive-state mutation: bump the global `stateVersion` and stamp the\n * changed cell's own version. The per-cell stamp lets delivery dedup be per-cell\n * (a subscriber owed two cells at once receives both), while `stateVersion`\n * stays the monotonic tick used by the cascade guard.\n */\nfunction bumpCell(collector: Collector.Instance, type: string): void {\n collector.stateVersion++;\n collector.cellVersion[type] = collector.stateVersion;\n}\n\n/**\n * Handles common commands.\n *\n * @param collector The walkerOS collector instance.\n * @param action The action to handle.\n * @param data The data to handle.\n * @returns A promise that resolves with the push result or undefined.\n */\nexport async function commonHandleCommand(\n collector: Collector.Instance,\n action: string,\n data?: unknown,\n): Promise<Elb.PushResult> {\n let result: Elb.PushResult | undefined;\n let onData: unknown;\n let shouldNotify = false;\n // Destination `on()` deliveries this command started and did not wait for.\n const deliveries: DestinationDelivery[] = [];\n\n // Open the bounded-recursion cascade tracker for the OUTERMOST top-level\n // command. Nested commands emitted by reacting state callbacks find it\n // already open and reuse it; teardown is a no-op for them, so the\n // per-(subscriber, cell-type) counters are scoped to this top-level command\n // and reset when it returns.\n const exitCascade = enterCascade(collector);\n try {\n return await runHandleCommand();\n } finally {\n exitCascade();\n }\n\n async function runHandleCommand(): Promise<Elb.PushResult> {\n switch (action) {\n case Const.Commands.Config:\n if (isObject(data)) {\n // `merge: false`: a config array (the `next` route) is replaced,\n // never unioned with the previous one.\n assign(collector.config, data as Partial<Collector.Config>, {\n shallow: false,\n merge: false,\n });\n onData = data;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.Consent:\n if (isObject(data)) {\n const { update } = processConsent(\n collector,\n data as WalkerOS.Consent,\n );\n bumpCell(collector, Const.Commands.Consent);\n onData = update;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.Custom:\n if (isObject(data)) {\n collector.custom = assign(\n collector.custom,\n data as WalkerOS.Properties,\n );\n bumpCell(collector, Const.Commands.Custom);\n onData = data;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.Destination:\n if (\n isObject(data) &&\n 'code' in data &&\n isObject((data as Destination.Init).code)\n ) {\n result = await addDestination(collector, data as Destination.Init);\n }\n break;\n\n case Const.Commands.Globals:\n if (isObject(data)) {\n collector.globals = assign(\n collector.globals,\n data as WalkerOS.Properties,\n );\n bumpCell(collector, Const.Commands.Globals);\n onData = data;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.Hook:\n if (\n isObject(data) &&\n isString((data as { name?: unknown }).name) &&\n isFunction((data as { fn?: unknown }).fn)\n ) {\n const { name, fn } = data as {\n name: string;\n fn: WalkerOS.AnyFunction;\n };\n collector.hooks[name as keyof Hooks.Functions] = fn;\n onData = data;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.On:\n if (isObject(data) && isString((data as { type?: unknown }).type)) {\n const { type, rules } = data as {\n type: On.Types;\n rules: WalkerOS.SingleOrArray<On.Subscription>;\n };\n await on(collector, type, rules);\n }\n break;\n\n case Const.Commands.Ready:\n shouldNotify = true;\n break;\n\n case Const.Commands.Run:\n result = await runCollectorDeferred(\n collector,\n data as RunState,\n deliveries,\n );\n shouldNotify = true;\n break;\n\n case Const.Commands.Session:\n shouldNotify = true;\n break;\n\n case Const.Commands.Shutdown:\n // Idempotency guard: re-entrancy must not re-run destroyAllSteps and\n // double-close writers, destinations, or stores. The first shutdown\n // sets the flag and runs the full sequence; a second command no-ops.\n if (!collector.hasShutdown) {\n collector.hasShutdown = true;\n await destroyAllSteps(collector);\n }\n break;\n\n case Const.Commands.User:\n if (isObject(data)) {\n assign(collector.user, data as WalkerOS.User, { shallow: false });\n bumpCell(collector, Const.Commands.User);\n onData = data;\n shouldNotify = true;\n }\n break;\n\n default:\n collector.logger.warn('unknown command', { command: action });\n return createPushResult({ ok: false });\n }\n\n // Single notification + flush point for all state-mutation commands\n if (shouldNotify) {\n const applied = await onApplyDeferred(\n collector,\n action as On.Types,\n undefined,\n onData,\n );\n deliveries.push(...applied.deliveries);\n markHeldForDrain(applied.deliveries);\n // Every destination is flushed now. One whose delivery is still running\n // is held, so its events wait for that delivery alone; the settle below\n // pushes them as soon as it is done, without delaying any other\n // destination.\n const flushed = mergePushResults(\n await pushToDestinations(collector),\n await settleDestinationDeliveries(collector, deliveries),\n );\n // `run` is the only command that sets `result` before this point (from\n // runCollector). Overwriting it outright would discard that outcome, so a\n // pre-run event that failed on replay would be invisible: its original\n // caller already got `ok: true` at hold time and there is no other place\n // it can surface. Every other command leaves `result` undefined here, so\n // this merge is a no-op for them.\n if (result && result.ok === false) {\n const failed = { ...(flushed.failed ?? {}), ...(result.failed ?? {}) };\n result = {\n ...flushed,\n ok: false,\n ...(Object.keys(failed).length > 0 ? { failed } : {}),\n };\n } else {\n result = flushed;\n }\n }\n\n return result || createPushResult({ ok: true });\n }\n}\n\n/**\n * Builds the partial event handed to `createEvent`, injecting the default\n * `timing` (elapsed since the collector started) and the collector `source`\n * meta. Event-provided values override the defaults.\n *\n * @param collector The walkerOS collector instance.\n * @param event The incoming partial event.\n * @returns The partial event with defaults applied.\n */\nexport function prepareEvent(\n collector: Collector.Instance,\n event: WalkerOS.DeepPartialEvent,\n): WalkerOS.PartialEvent {\n return {\n timing: Math.round((Date.now() - collector.timing) / 10) / 100,\n source: { type: 'collector', schema: '4' },\n ...event,\n } as WalkerOS.PartialEvent;\n}\n\n/**\n * Collector state an event is floored with: its globals under the event's\n * own, its user and consent when the event has none.\n */\ninterface EventFloors {\n globals: WalkerOS.Properties;\n user: WalkerOS.User;\n consent: WalkerOS.Consent;\n}\n\n/**\n * Creates a full event from a partial event, floored with the collector's\n * current state (globals, user, consent).\n *\n * @param collector The walkerOS collector instance.\n * @param partialEvent The partial event to transform.\n * @returns The full event.\n */\nexport function createEvent(\n collector: Collector.Instance,\n partialEvent: WalkerOS.PartialEvent,\n ingest?: Ingest,\n): WalkerOS.Event {\n return buildEvent(collector, partialEvent, ingest, {\n globals: collector.globals,\n user: collector.user,\n consent: collector.consent,\n });\n}\n\n/**\n * Completes an event that was already created and then edited by a chain\n * (`collector.next`): fills only the fields that are missing, never floors\n * globals, user or consent again, so a step that removed one keeps it\n * removed.\n */\nexport function completeEvent(\n collector: Collector.Instance,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n): WalkerOS.Event {\n return buildEvent(collector, prepareEvent(collector, event), ingest, {\n globals: {},\n user: {},\n consent: {},\n });\n}\n\n/** Shape completion shared by `createEvent` and `completeEvent`. */\nfunction buildEvent(\n collector: Collector.Instance,\n partialEvent: WalkerOS.PartialEvent,\n ingest: Ingest | undefined,\n floors: EventFloors,\n): WalkerOS.Event {\n // The name arrives from client-controlled input, so its declared type is a\n // claim rather than a guarantee. A wrong-typed value must be rejected here:\n // reaching split() below throws a TypeError, which the push boundary reads as\n // a pipeline fault and answers with a 500 instead of a 400.\n const rawName = partialEvent.name;\n if (typeof rawName !== 'string')\n throw new InvalidEventError(\n rawName === undefined\n ? 'Event name is required'\n : 'Event name is invalid',\n );\n if (!rawName) throw new InvalidEventError('Event name is required');\n\n const [entityValue, actionValue] = rawName.split(' ');\n if (!entityValue || !actionValue)\n throw new InvalidEventError('Event name is invalid');\n\n const {\n timestamp = Date.now(),\n name = `${entityValue} ${actionValue}`,\n data = {},\n context = {},\n globals = {},\n custom = {},\n user = floors.user,\n nested = [],\n consent = floors.consent,\n // A supplied id is preserved: sources and the push wrap mint the span\n // early so pre-enrichment records can carry it.\n id = getSpanId(),\n trigger = '',\n entity = entityValue,\n action = actionValue,\n timing = 0,\n source = { type: 'collector', schema: '4' },\n } = partialEvent;\n\n // Stamp the per-run sequence and trace, but only when absent so forwarded\n // events (web -> api -> server) keep their origin identity. Trace precedence:\n // a payload trace wins; a header-derived ingest trace fills the gap; the\n // run-scoped collector trace is the final fallback.\n // A destructuring default fills `undefined` only, so an explicit null source\n // arrives as null and must be normalized before it is dereferenced.\n const sourceValue: WalkerOS.Source = source ?? {\n type: 'collector',\n schema: '4',\n };\n const count = sourceValue.count ?? (collector.count += 1);\n // Must match journeyFields' trace precedence (observerEmit.ts).\n const trace = sourceValue.trace ?? ingest?._meta.trace ?? collector.trace;\n const stampedSource: WalkerOS.Source = { ...sourceValue, count };\n if (trace !== undefined) stampedSource.trace = trace;\n\n // Spread the incoming map so entries from upstream flows survive the crossing\n // and the local flow's release is appended; release thus accumulates across a\n // full-event walkerOS→walkerOS crossing.\n const releaseKey = collector.name ?? sourceValue.platform ?? 'default';\n const releaseValue = collector.release ?? __VERSION__;\n stampedSource.release = {\n ...sourceValue.release,\n [releaseKey]: releaseValue,\n };\n\n // The collector's globals (config statics plus `walker globals`) are the\n // floor for every created event; values the event carries win per key.\n const mergedGlobals = assign(floors.globals, globals);\n\n return {\n name,\n data,\n context,\n globals: mergedGlobals,\n custom,\n user,\n nested,\n consent,\n id,\n trigger,\n entity,\n action,\n timestamp,\n timing,\n source: stampedSource,\n };\n}\n\n/**\n * Enriches a partial event into a full event by applying the collector defaults\n * (`prepareEvent`) and then building the complete event (`createEvent`). This is\n * the single enrichment entry point shared by the production push path and\n * simulation, so both produce identical events.\n *\n * @param collector The walkerOS collector instance.\n * @param event The incoming partial event.\n * @returns The full event.\n */\nexport function enrichEvent(\n collector: Collector.Instance,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n): WalkerOS.Event {\n return createEvent(collector, prepareEvent(collector, event), ingest);\n}\n\n/**\n * Runs the collector by setting it to allowed state and processing queued events.\n *\n * @param collector The walkerOS collector instance.\n * @param state Optional state to merge with the collector (user, globals, consent, custom).\n * @returns A promise that resolves with the push result.\n */\nexport async function runCollector(\n collector: Collector.Instance,\n state?: RunState,\n): Promise<Elb.PushResult> {\n const deliveries: DestinationDelivery[] = [];\n const result = await runCollectorDeferred(collector, state, deliveries);\n return mergePushResults(\n result,\n await settleDestinationDeliveries(collector, deliveries),\n );\n}\n\n/**\n * `runCollector` without waiting for the destinations' run re-delivery: their\n * deliveries are appended to `deliveries` for the caller to settle after its\n * own flush, so one slow destination handler delays no other destination.\n */\nexport async function runCollectorDeferred(\n collector: Collector.Instance,\n state: RunState | undefined,\n deliveries: DestinationDelivery[],\n): Promise<Elb.PushResult> {\n // Set the collector to allowed state\n collector.allowed = true;\n\n // Update timing for this run\n collector.timing = Date.now();\n\n // Each run starts a new trace and resets the per-run emission counter.\n collector.trace = getTraceId();\n collector.count = 0;\n\n // Update collector state if provided\n if (state) {\n // Update consent if provided\n if (state.consent) {\n collector.consent = assign(collector.consent, state.consent);\n bumpCell(collector, Const.Commands.Consent);\n }\n\n // Update user if provided\n if (state.user) {\n collector.user = assign(collector.user, state.user);\n bumpCell(collector, Const.Commands.User);\n }\n\n // Update globals if provided\n if (state.globals) {\n collector.globals = assign(\n collector.config.globalsStatic || {},\n state.globals,\n );\n bumpCell(collector, Const.Commands.Globals);\n }\n\n // Update custom if provided\n if (state.custom) {\n collector.custom = assign(collector.custom, state.custom);\n bumpCell(collector, Const.Commands.Custom);\n }\n }\n\n // Reset destination queues\n Object.values(collector.destinations).forEach((destination) => {\n destination.queuePush = [];\n });\n\n // Reset collector queue for this run\n collector.queue = [];\n\n // Increase round counter\n collector.round++;\n\n // Run barrier — activate first, then re-deliver. The collector just became\n // `allowed` and any RunState cells were merged + bumped above, so a step\n // parked on `require` (e.g. a source gated on consent that only arrives via\n // the run state) can now activate. Reconcile BEFORE redeliver so the\n // freshly-started step is in `collector.sources` when redeliver re-broadcasts\n // owed state, and thus receives its consent/user/globals/custom delivery at\n // the barrier rather than missing it.\n await reconcilePending(collector);\n\n // Run barrier: the collector just became `allowed`. Re-deliver each non-empty\n // recorded state cell to subscribers owed a pre-run deferral (mark <\n // stateVersion) exactly once, so their reactions (e.g. a session source's\n // `session start` push) emit into the now-open, consent-gated pipeline. The\n // per-subscriber high-water mark guarantees exactly-once; this is the narrow\n // path (no require-decrement / queueOn flush). The subsequent `onApply(…,\n // 'run', …)` from commonHandleCommand is a lifecycle broadcast and does not\n // collide with these state re-deliveries.\n const redelivered = await startRunRedelivery(collector);\n\n // Replay events held while the collector was dormant (FIFO, wall-clock\n // order). Splice first so replayed pushes (now allowed) can never\n // re-enter the buffer, and a second run finds it empty.\n //\n // A replayed event's original caller already got `ok: true` (accepted-and-\n // held), so a later failure has no caller left to report to. The run result\n // is the only place it can surface, and it must: this run already reports\n // failures from the OTHER buffer it flushes below, so staying silent here\n // would make the same command inconsistent across its two buffers.\n let replayOk = true;\n const replayFailed: NonNullable<Elb.PushResult['failed']> = {};\n if (collector.preRunQueue.length) {\n const held = collector.preRunQueue.splice(0);\n collector.logger.debug('replaying pre-run events', { count: held.length });\n for (const { event, options } of held) {\n const replayResult = await collector.push(event, options);\n if (replayResult.ok === false) replayOk = false;\n // Carry per-destination detail when there is any. A push that threw\n // reports `ok: false` with no `failed` map (see push.ts's catch), so the\n // boolean is tracked separately rather than derived from the map.\n if (replayResult.failed) Object.assign(replayFailed, replayResult.failed);\n }\n }\n\n // Process any queued events now that the collector is allowed\n // Each destination's run re-delivery runs on its own: a destination still\n // receiving it is held and its events wait for it; the others go out now.\n markHeldForDrain(redelivered);\n const result = await pushToDestinations(collector);\n deliveries.push(...redelivered);\n\n if (replayOk) return result;\n\n const failed = { ...(result.failed ?? {}), ...replayFailed };\n return {\n ...result,\n ok: false,\n ...(Object.keys(failed).length > 0 ? { failed } : {}),\n };\n}\n","import type { Collector, Lifecycle, Logger } from '@walkeros/core';\n\nconst STEP_TIMEOUT = 5000;\n\n/**\n * Destroy all steps in pipeline order: sources → destinations → transformers.\n * Called by the collector's `shutdown` command handler.\n */\nexport async function destroyAllSteps(\n collector: Collector.Instance,\n): Promise<void> {\n const logger = collector.logger;\n\n // Phase 1: Sources (stop intake)\n await destroyStepGroup(collector.sources, 'source', logger);\n\n // Phase 2: Destinations, flush pending batches first, then close connections.\n await flushDestinationBatches(collector.destinations, logger);\n await destroyStepGroup(collector.destinations, 'destination', logger);\n\n // Phase 3: Transformers (release caches)\n await destroyStepGroup(collector.transformers, 'transformer', logger);\n\n // Phase 4: Stores (release storage — last, so transformers can flush during their destroy)\n await destroyStepGroup(collector.stores, 'store', logger);\n}\n\nasync function flushDestinationBatches(\n destinations: Collector.Instance['destinations'],\n rootLogger: Logger.Instance,\n): Promise<void> {\n const promises = Object.entries(destinations).flatMap(([id, dest]) => {\n const batches = dest.batches;\n if (!batches) return [];\n const logger = rootLogger.scope(dest.type || 'destination');\n return Object.values(batches).map(async (b) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n b.flush(),\n new Promise<void>((_, reject) => {\n timer = setTimeout(\n () =>\n reject(new Error(`destination '${id}' batch flush timed out`)),\n STEP_TIMEOUT,\n );\n }),\n ]);\n } catch (err) {\n logger.error(`destination '${id}' batch flush failed: ${err}`);\n } finally {\n if (timer) clearTimeout(timer);\n }\n });\n });\n await Promise.allSettled(promises);\n}\n\nasync function destroyStepGroup<\n T extends { config: unknown; env?: unknown; type?: string },\n>(\n steps: Record<string, T>,\n label: string,\n rootLogger: Logger.Instance,\n): Promise<void> {\n const promises = Object.entries(steps).map(async ([id, step]) => {\n // Access destroy via cast: its DestroyContext<C,E> generic is contravariant,\n // so concrete step types aren't assignable to a structural destroy signature.\n // Safe because we pass each step's own config/env back to its own destroy.\n const destroy = (\n step as {\n destroy?: (ctx: Lifecycle.DestroyContext) => void | Promise<void>;\n }\n ).destroy;\n if (!destroy) return;\n\n const stepType = step.type || 'unknown';\n const logger = rootLogger.scope(stepType);\n\n const context: Lifecycle.DestroyContext = {\n id,\n config: step.config,\n env: step.env ?? {},\n logger,\n };\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n destroy(context),\n new Promise<void>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`${label} '${id}' destroy timed out`)),\n STEP_TIMEOUT,\n );\n }),\n ]);\n } catch (err) {\n logger.error(`${label} '${id}' destroy failed: ${err}`);\n } finally {\n if (timer) clearTimeout(timer);\n }\n });\n\n await Promise.allSettled(promises);\n}\n","import type { Collector, Elb, EmitFn, ObserverFn } from '@walkeros/core';\nimport {\n OBSERVE_STORAGE_KEY,\n createBatchedPoster,\n createTelemetryObserver,\n parseObserveCredential,\n} from '@walkeros/core';\nimport type { StartFlow } from './types';\nimport { collector } from './collector';\nimport { initSources } from './source';\n\n// Structural slices of the browser globals the web-arm credential read\n// touches. The collector runs platform-neutral, so window/URLSearchParams\n// are read off globalThis behind guards -- the same pattern core's\n// preview.ts activator uses. On a server runtime both lookups resolve to\n// undefined and the web arm reads \"absent\" (zero work).\ninterface ObserveGlobals {\n window?: {\n location: { href: string; search: string };\n history: { replaceState(data: unknown, title: string, url: string): void };\n localStorage: {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n };\n };\n URLSearchParams?: new (init: string) => {\n getAll(name: string): string[];\n delete(name: string): void;\n toString(): string;\n };\n}\n\nconst G = globalThis as ObserveGlobals;\n\n/**\n * Last `elbObserve` URL param value, or null. The param name and the\n * storage slot share the `elbObserve` key by design (the preview activator\n * ferries the former into the latter). Never throws.\n */\nfunction readObserveParam(): string | null {\n const win = G.window;\n const USP = G.URLSearchParams;\n if (!win || !USP) return null;\n try {\n const search = new USP(win.location.search.replace(/^\\?/, ''));\n const values = search.getAll(OBSERVE_STORAGE_KEY);\n return values.length > 0 ? (values[values.length - 1] ?? null) : null;\n } catch {\n return null;\n }\n}\n\n/** Stored `elbObserve` slot, or null. Never throws (Safari private mode). */\nfunction readObserveSlot(): string | null {\n try {\n return G.window?.localStorage.getItem(OBSERVE_STORAGE_KEY) ?? null;\n } catch {\n return null;\n }\n}\n\nfunction writeObserveSlot(value: string): void {\n try {\n G.window?.localStorage.setItem(OBSERVE_STORAGE_KEY, value);\n } catch {\n // Slot persistence is best-effort; the session still attaches this page.\n }\n}\n\n/**\n * CAS-style slot clear: remove the slot only when it still holds exactly\n * `expected`, so a credential re-minted by another tab (or a later\n * activation) is never destroyed by a stale poster's self-heal.\n */\nfunction clearObserveSlotIf(expected: string): void {\n try {\n const win = G.window;\n if (!win) return;\n if (win.localStorage.getItem(OBSERVE_STORAGE_KEY) === expected) {\n win.localStorage.removeItem(OBSERVE_STORAGE_KEY);\n }\n } catch {\n // Storage unavailable: nothing to heal.\n }\n}\n\n/**\n * Remove the `elbObserve` param from the address bar after it has been\n * persisted to the slot, keeping every other param and the hash intact.\n * Same history.replaceState mechanics as core preview.ts's stripParam, but\n * scoped to the one param this wiring owns.\n */\nfunction stripObserveParam(): void {\n const win = G.window;\n const USP = G.URLSearchParams;\n if (!win || !USP) return;\n try {\n const href = win.location.href;\n const hashIdx = href.indexOf('#');\n const hash = hashIdx >= 0 ? href.slice(hashIdx) : '';\n const withoutHash = hashIdx >= 0 ? href.slice(0, hashIdx) : href;\n const qIdx = withoutHash.indexOf('?');\n const path = qIdx >= 0 ? withoutHash.slice(0, qIdx) : withoutHash;\n const params = new USP(qIdx >= 0 ? withoutHash.slice(qIdx + 1) : '');\n params.delete(OBSERVE_STORAGE_KEY);\n const query = params.toString();\n win.history.replaceState(\n {},\n '',\n `${path}${query ? `?${query}` : ''}${hash}`,\n );\n } catch {\n // A page that forbids history writes still attaches; the param stays.\n }\n}\n\n/**\n * Stamp the runtime's release provenance onto every posted record. Like\n * `flowId`, `release` is baked by the wiring layer so emitting sites never\n * see it. Identity when the runtime has no release id.\n */\nfunction withRelease(post: EmitFn, release: string | undefined): EmitFn {\n if (release === undefined) return post;\n return (state) => post({ ...state, release });\n}\n\n/**\n * Override the record's flowId on every posted record. The emit sites stamp\n * `collector.name`; a baked connect config (e.g. a preview artifact) may\n * carry the platform's flow id instead, so the posting layer rewrites it\n * without the emit sites ever knowing. Identity when no override is baked.\n */\nfunction withFlowId(post: EmitFn, flowId: string | undefined): EmitFn {\n if (flowId === undefined) return post;\n return (state) => post({ ...state, flowId });\n}\n\n/**\n * Install the advisory observation channel configured on `initConfig`:\n * caller-supplied `observers` land in the advisory Set verbatim, and an\n * `observe` connect config attaches a telemetry poster for its arm. Runs\n * after the collector instance exists and before `command('run')`, so\n * run-phase records are captured. Everything installed here is advisory:\n * observers run inside `emitStep`'s try/catch and the poster swallows\n * transport errors, so nothing on this path can break event processing.\n */\nfunction installObserve(\n instance: Collector.Instance,\n initConfig: Collector.InitConfig,\n): void {\n if (initConfig.observers) {\n for (const observer of initConfig.observers) {\n instance.observers.add(observer);\n }\n }\n\n const observe = initConfig.observe;\n if (!observe) return;\n\n const flowId = instance.name ?? 'default';\n\n if ('binding' in observe) {\n // Web arm: the credential arrives out-of-band via the elbObserve URL\n // param (or the storage slot the preview activator ferries it into).\n // Truly absent means zero work: no parse, no storage write, no observer.\n const param = readObserveParam();\n const raw = param ?? readObserveSlot();\n if (!raw) return;\n\n // A present-but-broken credential is warned, never silently dropped;\n // only the truly-absent case above is silent (zero-work contract).\n const credential = parseObserveCredential(raw);\n if (!credential) {\n if (param === null) {\n // Slot-sourced garbage: stored state clears on its own failure, so\n // self-heal instead of warning on every pageview.\n instance.logger.warn('observe: malformed stored credential cleared');\n clearObserveSlotIf(raw);\n } else {\n // URL-sourced garbage never touches stored state (anti-griefing).\n instance.logger.warn('observe: malformed credential ignored');\n }\n return;\n }\n if (credential.pb !== observe.binding) {\n instance.logger.warn(\n 'observe: credential binding mismatch, credential ignored',\n );\n return;\n }\n\n writeObserveSlot(raw);\n // The credential is persisted; a URL-borne copy is now redundant and,\n // being a bearer credential, must not linger in the address bar.\n if (param !== null) stripObserveParam();\n\n let observer: ObserverFn | undefined;\n const post = createBatchedPoster({\n url: `${observe.url}/ingest/${credential.ses}`,\n token: credential.secret,\n headers: { 'X-Walkeros-Binding': observe.binding },\n onStatus: (status) => {\n if (status !== 401) return;\n // The observer rejected this credential (session ended or token\n // revoked): self-heal the slot -- CAS, only while it still holds\n // exactly this credential -- and detach, so posting stops and the\n // next pageview is back on the silent zero-work path.\n clearObserveSlotIf(raw);\n if (observer) instance.observers.delete(observer);\n },\n });\n // Baked scoping: a wrap (e.g. a preview artifact) may carry a public\n // flowId/level/sample on the connect config. flowId overrides the local\n // config name on every posted record so they land under the platform's\n // flow id; a baked level also drives the collector-wide capture supplier\n // so destination call capture runs at trace.\n observer = createTelemetryObserver(\n withFlowId(withRelease(post, instance.release), observe.flowId),\n {\n flowId: observe.flowId ?? flowId,\n ...(observe.level !== undefined ? { level: observe.level } : {}),\n ...(observe.sample !== undefined ? { sample: observe.sample } : {}),\n },\n );\n instance.observers.add(observer);\n const bakedLevel = observe.level;\n if (bakedLevel !== undefined) {\n instance.observeLevel = () => bakedLevel;\n }\n return;\n }\n\n // Server arm: the config trio is the credential; attach directly.\n // 'off' opts out entirely (no observer, zero emit-path work).\n if (observe.level === 'off') return;\n // Mirror the web arm: a configured level also drives the collector-wide\n // capture supplier, so 'trace' enables destination call capture.\n const serverLevel = observe.level;\n if (serverLevel !== undefined) {\n instance.observeLevel = () => serverLevel;\n }\n instance.observers.add(\n createTelemetryObserver(\n withRelease(\n createBatchedPoster({\n url: `${observe.url}/ingest/${observe.sessionId}`,\n token: observe.token,\n }),\n instance.release,\n ),\n { flowId, level: observe.level, sample: observe.sample },\n ),\n );\n}\n\nexport async function startFlow<ElbPush extends Elb.Fn = Elb.Fn>(\n initConfig?: Collector.InitConfig,\n): Promise<StartFlow<ElbPush>> {\n initConfig = initConfig || {};\n const instance = await collector(initConfig);\n\n // Attach the advisory observation channel before source init and the run\n // command, so source-init and run-phase records are captured.\n installObserve(instance, initConfig);\n\n // Initialize sources; the collector's elb adapter is already available\n await initSources(instance, initConfig.sources || {});\n\n const { consent, user, globals, custom } = initConfig;\n\n // Route all four startup state cells through `command` so each bumps\n // `stateVersion`, broadcasts to subscribers, and triggers reconcile. A bare\n // `Object.assign` for globals/custom would silently skip those, leaving a\n // `require:[\"globals\"]` step un-reconciled and `on('globals')` subscribers\n // un-notified at startup.\n if (consent) await instance.command('consent', consent);\n if (user) await instance.command('user', user);\n if (globals) await instance.command('globals', globals);\n if (custom) await instance.command('custom', custom);\n\n if (instance.config.run) await instance.command('run');\n\n // Determine the primary elb:\n // 1. Use explicitly marked primary source\n // 2. Use first source if any exist\n // 3. Fallback to the collector's elb adapter\n let primaryElb: Elb.Fn = instance.elb;\n\n const sources = Object.values(instance.sources);\n\n // First, check for explicitly marked primary source. `initSources` mirrors a\n // top-level `InitSource.primary` onto the instance config, so both spellings\n // are visible here.\n const markedPrimary = sources.find((source) => source.config.primary);\n\n if (markedPrimary) {\n primaryElb = markedPrimary.push as Elb.Fn;\n } else if (sources.length > 0) {\n // Use first source as default\n primaryElb = sources[0].push as Elb.Fn;\n }\n\n return {\n collector: instance,\n elb: primaryElb as ElbPush,\n };\n}\n","import type { Collector, Elb, Logger, WalkerOS } from '@walkeros/core';\nimport { assign, createLogger } from '@walkeros/core';\nimport { commonHandleCommand, prepareEvent } from './handle';\nimport { initDestinations } from './destination';\nimport { initTransformers } from './transformer';\nimport { createPush } from './push';\nimport { createCommand } from './command';\nimport { createElb } from './elb';\nimport { initSources } from './source';\nimport { initStores, resolveStoreReferences } from './store';\nimport { createCacheStore } from './cache-store';\n\nexport async function collector(\n initConfig: Collector.InitConfig,\n): Promise<Collector.Instance> {\n const defaultConfig: Collector.Config = {\n globalsStatic: {},\n sessionStatic: {},\n run: true,\n queueMax: 1_000,\n };\n\n const config: Collector.Config = assign(defaultConfig, initConfig, {\n merge: false,\n extend: false,\n });\n\n // Create logger with config from initConfig\n const loggerConfig: Logger.Config = {\n level: initConfig.logger?.level,\n handler: initConfig.logger?.handler,\n };\n const logger = createLogger(loggerConfig);\n\n // Enhanced globals with static globals from config\n const finalGlobals = { ...config.globalsStatic, ...initConfig.globals };\n\n const collector: Collector.Instance = {\n allowed: false,\n config,\n consent: initConfig.consent || {},\n custom: initConfig.custom || {},\n destinations: {},\n transformers: {},\n stores: {},\n globals: finalGlobals,\n hooks: initConfig.hooks || {},\n observers: new Set(),\n logger,\n on: {},\n queue: [],\n preRunQueue: [],\n round: 0,\n count: 0,\n stateVersion: 0,\n cellVersion: {},\n delivery: new WeakMap(),\n session: undefined,\n status: {\n startedAt: Date.now(),\n in: 0,\n out: 0,\n failed: 0,\n sources: {},\n destinations: {},\n dropped: {},\n connectionErrors: {},\n breakers: {},\n },\n timing: Date.now(),\n user: initConfig.user || {},\n sources: {},\n pending: { destinations: {} },\n hasShutdown: false,\n seenEvents: new Set(),\n push: undefined as unknown as Collector.PushFn, // Placeholder, will be set below\n command: undefined as unknown as Collector.CommandFn, // Placeholder, will be set below\n elb: undefined as unknown as Elb.Fn, // Placeholder, will be set below\n };\n\n // Mirror static flow identity from initConfig onto the instance.\n // `assign(defaultConfig, initConfig, { extend: false })` copies a key only\n // if it already exists in defaultConfig, so name/release never reach\n // `collector.config`; read them from initConfig directly, once, at\n // construction (they are static, unlike the per-run `trace`).\n if (initConfig.name !== undefined) collector.name = initConfig.name;\n if (initConfig.release !== undefined) collector.release = initConfig.release;\n\n // `next` has no default, so the `extend: false` assign above drops it; seed\n // the collector chain explicitly.\n if (initConfig.next !== undefined) config.next = initConfig.next;\n\n // Set the push and command functions with the collector reference\n collector.push = createPush(collector, (event) =>\n prepareEvent(collector, event),\n );\n\n collector.command = createCommand(collector, commonHandleCommand);\n\n // Attach the elb adapter so it exists before any source init\n collector.elb = createElb(collector);\n\n // Initialize stores (first - other components may depend on them)\n const rawStores = initConfig.stores || {};\n collector.stores = await initStores(collector, rawStores);\n\n // Resolve store references in component env values.\n // The bundler emits `$store.gcs` as a direct reference to `stores.gcs`\n // (the raw {code, config} definition). After initialization, replace\n // these raw references with the actual Store.Instance objects.\n resolveStoreReferences(rawStores, collector.stores, initConfig);\n\n // Create default cache store for steps that use cache without explicit store.\n // Uses LRU + entry cap + batched eviction + active TTL sweep. See\n // `cache-store.ts` for the full semantics.\n if (!collector.stores.__cache) {\n collector.stores.__cache = createCacheStore();\n }\n\n // Initialize destinations after collector is fully created\n // Sources are initialized in startFlow after ELB source is created\n collector.destinations = await initDestinations(\n collector,\n initConfig.destinations || {},\n );\n\n // Initialize transformers\n collector.transformers = await initTransformers(\n collector,\n initConfig.transformers || {},\n );\n\n return collector;\n}\n","import type { Collector, WalkerOS, Elb, Ingest } from '@walkeros/core';\nimport {\n createIngest,\n emitStep,\n FatalError,\n getGrantedConsent,\n getSpanId,\n InvalidEventError,\n processEventMapping,\n tryCatchAsync,\n useHooks,\n} from '@walkeros/core';\nimport { pushBounded, resetOverflowFlag, warnOverflowOnce } from './buffers';\nimport { bumpDropped, errorMeta } from './report-error';\nimport { createEvent, enrichEvent } from './handle';\nimport { pushToDestinations, createPushResult } from './destination';\nimport {\n buildBaseState,\n emitCollectorDrop,\n journeyFields,\n} from './observerEmit';\nimport { runTransformerChain } from './transformer';\n\nfunction filterDestinations(\n destinations: Collector.Destinations,\n include?: string[],\n exclude?: string[],\n): Collector.Destinations {\n let filtered = destinations;\n if (include) {\n filtered = Object.fromEntries(\n Object.entries(filtered).filter(([id]) => include.includes(id)),\n );\n }\n if (exclude) {\n filtered = Object.fromEntries(\n Object.entries(filtered).filter(([id]) => !exclude.includes(id)),\n );\n }\n return filtered;\n}\n\n/**\n * Creates the push function for the collector.\n * Handles source mapping, event creation, and routing to destinations.\n *\n * @param collector - The walkerOS collector instance\n * @param prepareEvent - Function to enrich partial events\n * @returns The push function\n */\nexport function createPush<T extends Collector.Instance>(\n collector: T,\n prepareEvent: (event: WalkerOS.DeepPartialEvent) => WalkerOS.PartialEvent,\n): Collector.PushFn {\n const innerPush = useHooks(\n async (\n event: WalkerOS.DeepPartialEvent,\n options: Collector.PushOptions = {},\n ): Promise<Elb.PushResult> => {\n return await tryCatchAsync(\n async (): Promise<Elb.PushResult> => {\n // Dormant hold: an event born before run is held raw and replayed\n // by runCollector, so the pipeline (mapping, chains, enrichment)\n // runs exactly once, with post-run state. See prerun-hold.test.ts.\n if (!collector.allowed) {\n const max = collector.config.queueMax;\n if (max === undefined) {\n throw new Error(\n 'Collector.Config.queueMax is undefined; defaults must be seeded by collector()',\n );\n }\n const held = pushBounded(\n collector.preRunQueue,\n { event, options },\n { max },\n );\n if (held.dropped > 0) {\n // Counted under its own step id, NOT `stepId('collector')`: that\n // one's `queue` counter is the post-run replay buffer, and\n // pre-run loss is a different problem with a different fix, so\n // the two stay separately diagnosable.\n const droppedCount = bumpDropped(\n collector.status,\n 'collector.preRun',\n 'queue',\n held.dropped,\n );\n warnOverflowOnce(\n collector.preRunQueue,\n collector.logger,\n 'collector.preRunQueue overflow; oldest events dropped',\n { buffer: 'queue', cap: max, droppedCount },\n );\n } else if (collector.preRunQueue.length < max) {\n resetOverflowFlag(collector.preRunQueue);\n }\n collector.logger.debug('event held until run', {\n name: event.name,\n dropped: held.dropped,\n });\n return createPushResult({ ok: true });\n }\n\n const pushStart = Date.now();\n const {\n id,\n ingest,\n respond: initialRespond,\n mapping,\n preChain,\n include,\n exclude,\n } = options;\n let respond = initialRespond;\n let partialEvent = event;\n\n // Build filtered destination set if include/exclude specified\n const filteredDests =\n include || exclude\n ? filterDestinations(collector.destinations, include, exclude)\n : undefined;\n\n // Create mutable Ingest — accumulates context through the pipeline\n let pipelineIngest: Ingest =\n (ingest as Ingest | undefined) ?? createIngest(id || 'unknown');\n\n // Apply source mapping if provided in options\n if (mapping) {\n const processed = await processEventMapping(\n partialEvent,\n mapping,\n collector,\n );\n\n // Check ignore flag\n if (processed.ignore) {\n return createPushResult({ ok: true });\n }\n\n // Check consent requirements\n if (mapping.consent) {\n const grantedConsent = getGrantedConsent(\n mapping.consent,\n collector.consent,\n processed.event.consent as WalkerOS.Consent | undefined,\n );\n\n if (!grantedConsent) {\n return createPushResult({ ok: true });\n }\n }\n\n partialEvent = processed.event;\n }\n\n // Run the pre-collector chain (the source's `next` route). It\n // resolves hop by hop with `{ ingest, event }`, after the source's\n // mapping and state.\n if (preChain !== undefined) {\n const chainPath = id ? `source.${id}.next` : undefined;\n const chainResult = await runTransformerChain(\n collector,\n collector.transformers || {},\n preChain,\n partialEvent,\n pipelineIngest,\n respond,\n chainPath,\n );\n\n // Dropped or stopped: the event never reaches the collector.\n if (chainResult.copies.length === 0) {\n collector.logger.debug(\n `Event dropped by transformer chain${\n chainResult.droppedBy ? ` (${chainResult.droppedBy})` : ''\n }`,\n );\n emitCollectorDrop(\n collector,\n partialEvent,\n pipelineIngest,\n chainResult.droppedBy,\n chainPath ?? 'collector.push.preChain',\n );\n return createPushResult({ ok: true, dropped: true });\n }\n\n // Pipeline-halt signal from a pre-collector `cache.stop: true`\n // HIT. The event is intentionally NOT forwarded to destinations;\n // duplicates are suppressed at the source.next boundary per the\n // documented \"downstream transformers and destinations are\n // skipped\" semantic in transformers/cache.mdx.\n if (chainResult.stopped) {\n if (chainResult.respond) respond = chainResult.respond;\n return createPushResult({ ok: true });\n }\n\n // Update respond if the chain produced a wrapped one\n if (chainResult.respond) respond = chainResult.respond;\n\n // Every finished copy goes on with its own ingest. The runner\n // owns identity: a single copy keeps the chain input's id, a fork\n // copy carries its derived id.\n if (chainResult.copies.length > 1) {\n // Process each forked copy through the rest of the pipeline\n const forkResults = await Promise.all(\n chainResult.copies.map(async (copy) => {\n const full = createEvent(\n collector,\n prepareEvent(copy.event),\n copy.ingest,\n );\n return pushToDestinations(\n collector,\n full,\n { id, ingest: copy.ingest, respond },\n filteredDests,\n );\n }),\n );\n\n // Update source status\n if (id) {\n if (!collector.status.sources[id]) {\n collector.status.sources[id] = {\n count: 0,\n duration: 0,\n };\n }\n const sourceStatus = collector.status.sources[id];\n sourceStatus.count += chainResult.copies.length;\n sourceStatus.lastAt = Date.now();\n sourceStatus.duration += Date.now() - pushStart;\n }\n\n return forkResults[0] ?? createPushResult({ ok: true });\n }\n\n partialEvent = chainResult.copies[0].event;\n pipelineIngest = chainResult.copies[0].ingest;\n }\n\n // Enrich into a full event (timing, source info, defaults)\n const fullEvent = enrichEvent(\n collector,\n partialEvent,\n pipelineIngest,\n );\n\n // Push to destinations with id and ingest\n const result = await pushToDestinations(\n collector,\n fullEvent,\n {\n id,\n ingest: pipelineIngest,\n respond,\n },\n filteredDests,\n );\n\n // Update source status\n if (id) {\n if (!collector.status.sources[id]) {\n collector.status.sources[id] = {\n count: 0,\n duration: 0,\n };\n }\n const sourceStatus = collector.status.sources[id];\n sourceStatus.count++;\n sourceStatus.lastAt = Date.now();\n sourceStatus.duration += Date.now() - pushStart;\n }\n\n return result;\n },\n (err: unknown) => {\n if (err instanceof FatalError) throw err;\n if (err instanceof InvalidEventError) {\n // Client input fault, not a pipeline failure: warn without a\n // stack, count it as a source rejection, and hand the caller a\n // discriminated result it can map to a 4xx response.\n // `id` is destructured inside the try body, which this sibling\n // callback does not see, so the source id comes from `options`.\n const sourceId = options.id;\n if (sourceId) {\n if (!collector.status.sources[sourceId]) {\n collector.status.sources[sourceId] = { count: 0, duration: 0 };\n }\n const sourceStatus = collector.status.sources[sourceId];\n sourceStatus.rejected = (sourceStatus.rejected ?? 0) + 1;\n }\n collector.logger.warn('invalid event rejected', {\n error: err.message,\n });\n return createPushResult({\n ok: false,\n invalid: true,\n error: err.message,\n });\n }\n collector.status.failed++;\n // Identify the event by NAME only. The log context is serialized\n // into stderr, the error ring and the managed-run jsonl sink, so it\n // stays primitive and low-cardinality: the full event (user,\n // consent, data) and the raw ingest payload would be a PII egress,\n // and per-event values would make every failure look distinct to\n // the ring's message dedup.\n collector.logger.error('push failed', {\n ...errorMeta(err),\n event: event.name,\n });\n return createPushResult({ ok: false });\n },\n )();\n },\n 'Push',\n collector.hooks,\n collector.logger,\n );\n\n const wrapped: Collector.PushFn = async (event, options) => {\n // Mint the event's span id HERE when absent, so every record of this\n // event carries it, the wrap's own in record included. This is the id the\n // identified event carries into `createEvent`, which preserves a supplied\n // id (handle.ts). The copy never mutates the caller's object.\n const identified =\n typeof event.id === 'string' && event.id !== ''\n ? event\n : { ...event, id: getSpanId() };\n const eventId = typeof identified.id === 'string' ? identified.id : '';\n // Journey correlation from what is in scope at the wrap boundary: the\n // incoming event's trace, then the header-derived ingest trace, then the\n // run trace, plus the source context threaded through `options.ingest`.\n // The processed full event is not visible here, so out/error reuse the\n // same incoming-event trace (identical value in the common case).\n const { traceId, sourceId, parentEventId } = journeyFields(\n identified,\n options?.ingest,\n collector,\n );\n const started = Date.now();\n const inState = buildBaseState(collector, {\n stepId: 'collector.push',\n stepType: 'collector',\n phase: 'in',\n eventId,\n now: started,\n traceId,\n sourceId,\n parentEventId,\n });\n inState.inEvent = identified;\n emitStep(collector, inState);\n\n try {\n const result = await innerPush(identified, options);\n const finished = Date.now();\n const outState = buildBaseState(collector, {\n stepId: 'collector.push',\n stepType: 'collector',\n phase: 'out',\n // The same id as the in record. Reading it off the result instead\n // would split the wrap's own pair across two journeys whenever the\n // result reports a different event: a fan-out reporting its first\n // child, or a `prePush` hook that swapped the event.\n eventId,\n now: finished,\n traceId,\n sourceId,\n parentEventId,\n });\n outState.durationMs = finished - started;\n outState.outEvent = result;\n emitStep(collector, outState);\n return result;\n } catch (err) {\n const finished = Date.now();\n const errState = buildBaseState(collector, {\n stepId: 'collector.push',\n stepType: 'collector',\n phase: 'error',\n eventId,\n now: finished,\n traceId,\n sourceId,\n parentEventId,\n });\n errState.durationMs = finished - started;\n errState.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n emitStep(collector, errState);\n throw err;\n }\n };\n\n return wrapped;\n}\n","import type { Collector, Elb } from '@walkeros/core';\nimport type { HandleCommandFn } from './types/collector';\nimport { FatalError, useHooks, tryCatchAsync } from '@walkeros/core';\nimport { createPushResult } from './destination';\nimport { errorMeta } from './report-error';\n\n/**\n * Creates the command function for the collector.\n * Handles walker commands (config, consent, destination, etc.)\n *\n * @param collector - The walkerOS collector instance\n * @param handleCommand - Command handler function\n * @returns The command function\n */\nexport function createCommand<T extends Collector.Instance>(\n collector: T,\n handleCommand: HandleCommandFn<T>,\n): Collector.CommandFn {\n return useHooks(\n async (\n command: string,\n data?: unknown,\n options?: unknown,\n ): Promise<Elb.PushResult> => {\n return await tryCatchAsync(\n async (): Promise<Elb.PushResult> => {\n return await handleCommand(collector, command, data, options);\n },\n (err: unknown) => {\n if (err instanceof FatalError) throw err;\n collector.status.failed++;\n // `command` is a low-cardinality identifier and stays; the\n // arbitrary `data` payload does not. Log context is serialized into\n // stderr, the error ring and the jsonl sink, where a command's\n // operand (consent state, user fields) would be a PII egress.\n collector.logger.error('command failed', {\n ...errorMeta(err),\n command,\n });\n return createPushResult({ ok: false });\n },\n )();\n },\n 'Command',\n collector.hooks,\n collector.logger,\n );\n}\n","import type { Collector, WalkerOS, Elb } from '@walkeros/core';\nimport { createPushResult } from './destination';\n\n/**\n * Creates the default ELB adapter.\n * Routes between collector.push and collector.command based on input.\n * Provides backward-compatible flexible argument interface.\n *\n * @param collector - The walkerOS collector instance\n * @returns ELB adapter function\n */\nexport function createElb(collector: Collector.Instance): Elb.Fn {\n return async (\n eventOrCommand?: unknown,\n data?: unknown,\n context?: unknown,\n nested?: WalkerOS.Entities,\n custom?: WalkerOS.Properties,\n ): Promise<Elb.PushResult> => {\n // Detect walker commands\n if (\n typeof eventOrCommand === 'string' &&\n eventOrCommand.startsWith('walker ')\n ) {\n const command = eventOrCommand.replace('walker ', '');\n return collector.command(command, data);\n }\n\n // Build event object\n let event: WalkerOS.DeepPartialEvent;\n\n if (typeof eventOrCommand === 'string') {\n // Convert string to object: elb('page view', { title: 'Home' })\n event = { name: eventOrCommand };\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n event.data = data as WalkerOS.Properties;\n }\n } else if (\n eventOrCommand &&\n typeof eventOrCommand === 'object' &&\n // Exclude arrays passed by untyped runtime callers; Elb.Fn already forbids them\n !Array.isArray(eventOrCommand)\n ) {\n // Use object directly: elb({ name: 'page view', data: {...} })\n // Shallow-clone so adapter writes never leak onto the caller's object\n event = { ...(eventOrCommand as WalkerOS.DeepPartialEvent) };\n // Merge additional data if provided\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n event.data = {\n ...(event.data || {}),\n ...(data as WalkerOS.Properties),\n };\n }\n } else {\n // Invalid input\n return createPushResult({ ok: false });\n }\n\n // Add optional properties if provided\n if (context && typeof context === 'object') {\n event.context = context as WalkerOS.OrderedProperties;\n }\n if (nested && Array.isArray(nested)) {\n event.nested = nested;\n }\n if (custom && typeof custom === 'object') {\n event.custom = custom as WalkerOS.Properties;\n }\n\n // Call collector.push with event object\n return collector.push(event);\n };\n}\n","import type { Cache, Collector, Store } from '@walkeros/core';\nimport { emitStep, useHooks } from '@walkeros/core';\nimport { createCacheStore } from './cache-store';\nimport { buildBaseState } from './observerEmit';\nimport { wrapStoreWithCache } from './store-cache-wrapper';\nimport { buildReportError } from './report-error';\n\n/**\n * Narrowed view of a `Store.InitStore` entry that also carries the optional\n * `cache` configuration emitted by the bundler. The runtime `Store.InitStores`\n * map is loosely typed at the core level so it can carry pass-through fields\n * (`cache`, `variables`, etc.) without coupling the core `Store.InitStore`\n * shape to flow-level concerns. Phase 2 reads `cache` through this local view.\n */\ntype InitStoreWithCache = Store.InitStore & {\n cache?: Cache.Cache<Cache.StoreCacheRule>;\n};\n\n/**\n * Hook wrapping and observer emission for a single store instance.\n * Mutates `instance` in place.\n *\n * Called once per store, AFTER any cache wrapping in phase 2. Wrapping the\n * outer (wrapper) instance means observers see the consumer-facing\n * boundary: they fire on every `wrapped.get` regardless of cache HIT/MISS,\n * and only once per `wrapped.set` (not also for the wrapper's internal\n * write into `cacheStore`). If the store has no cache wrapper, the bare\n * backing is wrapped instead, preserving observability.\n *\n * Two responsibilities per op:\n * 1. Inner `useHooks(..., 'StoreGet', ...)` wrap keeps the generic\n * user-declared hook contract working (`preStoreGet`, `postStoreSet`,\n * etc.).\n * 2. Outer self-emit wrap pushes `FlowState` (`stepType: 'store'`) into\n * `collector.observers` directly, so per-store telemetry no longer\n * needs a separate hook bag.\n */\nfunction applyStoreHooks(\n collector: Collector.Instance,\n instance: Store.Instance,\n storeId: string,\n): void {\n const stepIdFor = `store.${storeId}`;\n\n const innerGet = useHooks(\n instance.get,\n 'StoreGet',\n collector.hooks,\n collector.logger,\n );\n const innerSet = useHooks(\n instance.set,\n 'StoreSet',\n collector.hooks,\n collector.logger,\n );\n const innerDelete = useHooks(\n instance.delete,\n 'StoreDelete',\n collector.hooks,\n collector.logger,\n );\n\n instance.get = async (key: string): Promise<Store.StoreValue | undefined> => {\n const started = Date.now();\n const inState = buildBaseState(collector, {\n stepId: stepIdFor,\n stepType: 'store',\n phase: 'in',\n eventId: '',\n now: started,\n });\n inState.meta = { op: 'get', key };\n emitStep(collector, inState);\n\n try {\n const result = await innerGet(key);\n const finished = Date.now();\n const outState = buildBaseState(collector, {\n stepId: stepIdFor,\n stepType: 'store',\n phase: 'out',\n eventId: '',\n now: finished,\n });\n outState.durationMs = finished - started;\n outState.meta = { op: 'get', key };\n emitStep(collector, outState);\n return result;\n } catch (err) {\n const finished = Date.now();\n const errState = buildBaseState(collector, {\n stepId: stepIdFor,\n stepType: 'store',\n phase: 'error',\n eventId: '',\n now: finished,\n });\n errState.durationMs = finished - started;\n errState.meta = { op: 'get', key };\n errState.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n emitStep(collector, errState);\n throw err;\n }\n };\n\n instance.set = async (\n key: string,\n value: Store.StoreValue,\n ttl?: number,\n ): Promise<void> => {\n const started = Date.now();\n const inState = buildBaseState(collector, {\n stepId: stepIdFor,\n stepType: 'store',\n phase: 'in',\n eventId: '',\n now: started,\n });\n // Store values can be secrets or PII: emit only the op + key, never the\n // raw value, on any phase (in/out/error). Observers see what happened,\n // not what was written.\n inState.meta = { op: 'set', key };\n emitStep(collector, inState);\n\n try {\n await innerSet(key, value, ttl);\n const finished = Date.now();\n const outState = buildBaseState(collector, {\n stepId: stepIdFor,\n stepType: 'store',\n phase: 'out',\n eventId: '',\n now: finished,\n });\n outState.durationMs = finished - started;\n outState.meta = { op: 'set', key };\n emitStep(collector, outState);\n } catch (err) {\n const finished = Date.now();\n const errState = buildBaseState(collector, {\n stepId: stepIdFor,\n stepType: 'store',\n phase: 'error',\n eventId: '',\n now: finished,\n });\n errState.durationMs = finished - started;\n errState.meta = { op: 'set', key };\n errState.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n emitStep(collector, errState);\n throw err;\n }\n };\n\n instance.delete = async (key: string): Promise<void> => {\n const started = Date.now();\n const inState = buildBaseState(collector, {\n stepId: stepIdFor,\n stepType: 'store',\n phase: 'in',\n eventId: '',\n now: started,\n });\n inState.meta = { op: 'delete', key };\n emitStep(collector, inState);\n\n try {\n await innerDelete(key);\n const finished = Date.now();\n const outState = buildBaseState(collector, {\n stepId: stepIdFor,\n stepType: 'store',\n phase: 'out',\n eventId: '',\n now: finished,\n });\n outState.durationMs = finished - started;\n outState.meta = { op: 'delete', key };\n emitStep(collector, outState);\n } catch (err) {\n const finished = Date.now();\n const errState = buildBaseState(collector, {\n stepId: stepIdFor,\n stepType: 'store',\n phase: 'error',\n eventId: '',\n now: finished,\n });\n errState.durationMs = finished - started;\n errState.meta = { op: 'delete', key };\n errState.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n emitStep(collector, errState);\n throw err;\n }\n };\n}\n\n/**\n * Walks the `cache.store` graph in topological order (terminals first) and\n * reports each store id together with its cache config. Detects cycles via\n * three-color DFS (WHITE → GRAY → BLACK) and rejects references to unknown\n * store ids. Throws on the first problem with a message naming the path.\n *\n * The returned order is suitable for wrapping: when a wrapper is built for\n * store X, its `cache.store` target (if any) has already been wrapped.\n */\nfunction topoOrderForCacheWrap(\n defs: Record<string, InitStoreWithCache>,\n): string[] {\n type Color = 'WHITE' | 'GRAY' | 'BLACK';\n const color: Record<string, Color> = {};\n for (const id of Object.keys(defs)) color[id] = 'WHITE';\n\n const order: string[] = [];\n const stack: string[] = [];\n\n function visit(id: string): void {\n const c = color[id];\n if (c === 'BLACK') return;\n if (c === 'GRAY') {\n const cycleStart = stack.indexOf(id);\n const cyclePath = stack\n .slice(cycleStart === -1 ? 0 : cycleStart)\n .concat(id)\n .join(' -> ');\n throw new Error(`Cycle in cache.store chain: ${cyclePath}`);\n }\n\n color[id] = 'GRAY';\n stack.push(id);\n\n const target = defs[id].cache?.store;\n if (target !== undefined) {\n if (!(target in defs)) {\n throw new Error(\n `Store \"${id}\" cache.store references \"${target}\", which is not declared in flow.stores`,\n );\n }\n visit(target);\n }\n\n stack.pop();\n color[id] = 'BLACK';\n order.push(id);\n }\n\n for (const id of Object.keys(defs)) {\n if (color[id] === 'WHITE') visit(id);\n }\n\n return order;\n}\n\n/**\n * Initialize store instances from configuration.\n *\n * Three-phase init:\n * Phase 1, instantiate: call `code(context)` for every declared store.\n * Order is not significant in this phase. Hooks are NOT installed yet —\n * they wrap the outer boundary in phase 3.\n * Phase 2, topologically wrap: walk the `cache.store` graph, detect cycles\n * and unknown targets, then visit terminals first so any cache wrapper\n * installed in Task 7+ can rely on its backing being already wrapped.\n * Phase 3, install hooks: wrap the final instance (wrapper if cache was\n * applied, otherwise the bare backing) so hooks fire at the consumer\n * boundary and observe cache HIT/MISS behavior.\n *\n * Phase 2 must run before `resolveStoreReferences` in `collector.ts` so that\n * env-reference replacement uses the wrapped instance (referential identity\n * matters for the resolver).\n */\nexport async function initStores(\n collector: Collector.Instance,\n initStores: Store.InitStores = {},\n): Promise<Store.Stores> {\n const result: Store.Stores = {};\n\n // Phase 1: instantiate every store. Hooks are deferred to phase 3 so they\n // can wrap the outer (cache-wrapped) instance and observe HIT/MISS at the\n // consumer-facing boundary.\n for (const [storeId, storeDef] of Object.entries(initStores)) {\n const { code, config = {}, env = {} } = storeDef;\n\n const storeLogger = collector.logger.scope('store').scope(storeId);\n\n const context = {\n collector,\n logger: storeLogger,\n id: storeId,\n config,\n env,\n reportError: buildReportError(collector, 'store', storeId, storeLogger),\n };\n\n const instance = await code(context);\n result[storeId] = instance;\n }\n\n // Phase 2: validate the cache.store graph and wrap in topological order.\n // Cycle and missing-target errors propagate out of `topoOrderForCacheWrap`.\n // Read-through wrapping is delegated to `wrapStoreWithCache`. The cache\n // layer is either a user-declared store (resolved against the in-progress\n // `result` map) or the default `__cache`, which is created lazily here so\n // it ends up assigned to `collector.stores` together with the rest.\n const defsWithCache = initStores as Record<string, InitStoreWithCache>;\n const order = topoOrderForCacheWrap(defsWithCache);\n for (const storeId of order) {\n const cacheConfig = defsWithCache[storeId].cache;\n if (!cacheConfig) continue;\n\n let cacheStore: Store.Instance;\n let cacheStoreId: string;\n if (cacheConfig.store !== undefined) {\n // Missing-target validation already ran in `topoOrderForCacheWrap`, so\n // this lookup is guaranteed to hit.\n cacheStore = result[cacheConfig.store];\n cacheStoreId = cacheConfig.store;\n } else {\n if (!result.__cache) {\n result.__cache = createCacheStore();\n }\n cacheStore = result.__cache;\n cacheStoreId = '__cache';\n }\n\n // Schema rejects `namespace: \"\"` for store caches, so the only way the\n // wrapper sees an absent namespace is when the user omitted it entirely.\n // In that case default to the host store id so multiple wrapped stores\n // sharing `__cache` cannot collide on raw keys.\n const resolvedNamespace = cacheConfig.namespace ?? storeId;\n\n // One startup log line per wrapped store. Operators inspecting the cache\n // layer see prefixed keys (e.g. `api:K`); surfacing the resolved namespace\n // and cache-store id here keeps that defaulting from feeling like hidden\n // magic. Scope mirrors the wrapper's own scope (Task 8) so all\n // cache-related output groups under `store-cache:<id>`.\n collector.logger\n .scope('store-cache')\n .scope(storeId)\n .info(\n `store \"${storeId}\" caches with namespace \"${resolvedNamespace}:\" via ${cacheStoreId}`,\n );\n\n result[storeId] = wrapStoreWithCache(result[storeId], {\n storeId,\n cacheConfig,\n cacheStore,\n namespace: resolvedNamespace,\n logger: collector.logger.scope('store-cache').scope(storeId),\n collector,\n });\n }\n\n // Phase 3: install hooks on the final instance for every user-declared\n // store. Wrapping the OUTER instance (wrapper if a cache was applied,\n // bare backing otherwise) means the hook fires at the consumer-facing\n // boundary and observes cache HIT/MISS. The auto-created default\n // `__cache` is skipped — it has no consumer-facing contract; users never\n // call `__cache.get` directly. Skipping it also prevents the wrapper's\n // internal writes into the default cache from double-firing\n // `preStoreSet` against the consumer-facing boundary.\n for (const [storeId, instance] of Object.entries(result)) {\n if (storeId === '__cache') continue;\n applyStoreHooks(collector, instance, storeId);\n }\n\n return result;\n}\n\n/**\n * Resolve store references in component env values.\n *\n * The bundler resolves `$store.gcs` to a direct JS reference to the raw\n * store definition object (`stores.gcs = { code, config }`). After stores\n * are initialized, this function walks transformer/destination/source env\n * objects and replaces any raw store definition reference with the\n * corresponding initialized Store.Instance.\n *\n * IMPORTANT: Uses referential identity (`===`) to match env values against\n * raw store definitions. This works because the bundler generates code where\n * env values are direct references to the same objects in the `stores` map.\n * Programmatic configs must use the same object reference — copies won't match.\n *\n * Only resolves top-level env keys. Nested store references are not supported.\n */\nexport function resolveStoreReferences(\n rawStores: Store.InitStores,\n initializedStores: Store.Stores,\n initConfig: Collector.InitConfig,\n): void {\n // Build a lookup: raw store def → initialized instance (O(1) per env value)\n const lookup = new Map<object, Store.Instance>();\n for (const [storeId, rawDef] of Object.entries(rawStores)) {\n if (initializedStores[storeId])\n lookup.set(rawDef, initializedStores[storeId]);\n }\n if (lookup.size === 0) return;\n\n function resolveEnv(env: Record<string, unknown> | undefined) {\n if (!env) return;\n for (const [key, value] of Object.entries(env)) {\n if (typeof value === 'object' && value !== null) {\n const instance = lookup.get(value);\n if (instance) env[key] = instance;\n }\n }\n }\n\n // Walk all component types that may have env values\n for (const defs of [\n initConfig.transformers,\n initConfig.destinations,\n initConfig.sources,\n ]) {\n if (!defs) continue;\n for (const def of Object.values(defs)) {\n resolveEnv((def as { env?: Record<string, unknown> }).env);\n }\n }\n}\n","import type { Store } from '@walkeros/core';\n\n/**\n * Options for the built-in collector cache store (`__cache`).\n *\n * The default cache is an entry-capped LRU with active TTL sweep. Byte-size\n * accounting is opt-in: when `maxSize` is `undefined`, no byte budget is\n * enforced.\n */\nexport interface CacheStoreOptions {\n /** Hard cap on entries. Defaults to 10000. */\n maxEntries?: number;\n /**\n * Optional byte budget for the cache. When set, byte-sized eviction is\n * enabled in addition to entry-count eviction. Defaults to `undefined`\n * (no byte budget).\n */\n maxSize?: number;\n /**\n * Active sweep interval (ms) for purging expired entries even when they\n * are never read. Defaults to 60_000 (60 seconds). Pass 0 to disable.\n */\n sweepIntervalMs?: number;\n /**\n * Fraction of `maxEntries` to keep after a batched eviction pass. Defaults\n * to 0.8. The cache trims to `maxEntries * lowWaterMark` in one pass on\n * overflow.\n */\n lowWaterMark?: number;\n}\n\n/**\n * Operational counters exposed by the cache store. All counters are\n * monotonic for the lifetime of the cache instance.\n */\nexport interface CacheStoreCounters {\n /** Successful `get` calls that returned a live cached value. */\n hits: number;\n /** `get` calls that found no entry (cold) or only an expired one. */\n misses: number;\n /** `set` calls that created a new key (first-time population). */\n populates: number;\n /** All `set` calls (populates + overwrites). */\n writes: number;\n /** All `delete` calls that removed an existing key. */\n deletes: number;\n /** Entries removed because the cache hit `maxEntries`. */\n evictions_entries: number;\n /** Entries removed because their TTL expired (sweep or lazy). */\n evictions_ttl: number;\n}\n\ninterface CacheEntry {\n value: Store.StoreValue;\n expires?: number;\n}\n\n/**\n * The upgraded `__cache` store. Backward-compatible with the existing\n * `Store.Instance` shape — callers see `get(key)`, `set(key, value, ttl?)`,\n * `delete(key)`. Adds an observability surface via `counters` and an active\n * TTL sweep that runs on a timer.\n *\n * Eviction model:\n * - Map iteration order is insertion order; oldest insertion is the FIFO head.\n * - `get` reorders the entry to most-recently-used (delete + re-insert).\n * - On insert overflow (size > maxEntries), evict in one pass down to\n * `lowWaterMark * maxEntries` (default 80%).\n *\n * Active TTL sweep: every `sweepIntervalMs` ms, walk the map and drop any\n * entries past `expires`. The interval is cleared in `destroy()`.\n */\nexport type CacheStore = Store.Instance & {\n readonly counters: CacheStoreCounters;\n destroy: () => void;\n};\n\nconst DEFAULT_MAX_ENTRIES = 10000;\nconst DEFAULT_SWEEP_INTERVAL_MS = 60_000;\nconst DEFAULT_LOW_WATER_MARK = 0.8;\n\nexport function createCacheStore(options: CacheStoreOptions = {}): CacheStore {\n const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;\n const lowWaterMark = options.lowWaterMark ?? DEFAULT_LOW_WATER_MARK;\n const sweepIntervalMs = options.sweepIntervalMs ?? DEFAULT_SWEEP_INTERVAL_MS;\n const targetSize = Math.floor(maxEntries * lowWaterMark);\n\n const entries = new Map<string, CacheEntry>();\n\n const counters: CacheStoreCounters = {\n hits: 0,\n misses: 0,\n populates: 0,\n writes: 0,\n deletes: 0,\n evictions_entries: 0,\n evictions_ttl: 0,\n };\n\n function evictOverflow(): void {\n if (entries.size <= maxEntries) return;\n // Trim in one pass down to targetSize using insertion-order iteration\n // (oldest first). LRU is preserved because `get` re-inserts on access.\n const toRemove = entries.size - targetSize;\n let removed = 0;\n for (const key of entries.keys()) {\n if (removed >= toRemove) break;\n entries.delete(key);\n removed++;\n }\n counters.evictions_entries += removed;\n }\n\n function sweep(): void {\n const now = Date.now();\n let removed = 0;\n for (const [key, entry] of entries) {\n if (entry.expires !== undefined && entry.expires <= now) {\n entries.delete(key);\n removed++;\n }\n }\n counters.evictions_ttl += removed;\n }\n\n let sweepTimer: ReturnType<typeof setInterval> | undefined;\n if (sweepIntervalMs > 0) {\n sweepTimer = setInterval(sweep, sweepIntervalMs);\n // Don't keep the Node.js event loop alive solely for the cache sweep.\n if (\n sweepTimer &&\n typeof (sweepTimer as { unref?: () => void }).unref === 'function'\n ) {\n (sweepTimer as { unref: () => void }).unref();\n }\n }\n\n const store: CacheStore = {\n type: 'memory',\n config: {},\n\n get(key: string): Store.StoreValue | undefined {\n const entry = entries.get(key);\n if (!entry) {\n counters.misses++;\n return undefined;\n }\n\n if (entry.expires !== undefined && entry.expires <= Date.now()) {\n entries.delete(key);\n counters.evictions_ttl++;\n counters.misses++;\n return undefined;\n }\n\n // LRU: move to most-recently-used position.\n entries.delete(key);\n entries.set(key, entry);\n counters.hits++;\n return entry.value;\n },\n\n set(key: string, value: Store.StoreValue, ttl?: number): void {\n const isNew = !entries.has(key);\n // Always delete first so re-insert puts the entry at the\n // most-recently-used position regardless of overwrite or new.\n if (!isNew) entries.delete(key);\n\n entries.set(key, {\n value,\n expires: ttl !== undefined ? Date.now() + ttl : undefined,\n });\n\n counters.writes++;\n if (isNew) counters.populates++;\n\n if (entries.size > maxEntries) evictOverflow();\n },\n\n delete(key: string): void {\n if (entries.delete(key)) counters.deletes++;\n },\n\n get counters() {\n // Return a snapshot so external callers can't mutate internal state.\n return { ...counters };\n },\n\n destroy(): void {\n if (sweepTimer !== undefined) {\n clearInterval(sweepTimer);\n sweepTimer = undefined;\n }\n entries.clear();\n },\n };\n\n return store;\n}\n","import type { Cache, Collector, Logger, Store } from '@walkeros/core';\nimport {\n compileMatcher,\n emitStep,\n readCacheEnvelope,\n wrapCacheEnvelope,\n} from '@walkeros/core';\nimport { buildBaseState } from './observerEmit';\nimport { errorMeta } from './report-error';\n\n/**\n * Options passed to `wrapStoreWithCache`. Pre-resolved by `initStores` phase\n * 2 so the wrapper itself stays small and side-effect free at construction.\n *\n * - `cacheStore` is the store layer where cached values live. Defaults to\n * the collector's `__cache` instance, but may be any other initialized\n * store (e.g. a fs-backed cache for cross-process sharing).\n * - `namespace` is the prefix prepended to every key written to the cache\n * layer. Defaults to `storeId` when the user did not override\n * `cache.namespace`.\n * - `logger` is the collector's scoped logger, used for the best-effort\n * warnings emitted when a cache-side write or delete fails. Optional only\n * to keep test setups lightweight — production call sites pass\n * `collector.logger`.\n */\nexport interface WrappedStoreOptions {\n storeId: string;\n cacheConfig: Cache.Cache<Cache.StoreCacheRule>;\n cacheStore: Store.Instance;\n namespace: string;\n logger?: Logger.Instance;\n /**\n * Optional collector reference for cache-level observability. When\n * provided, the wrapper emits a `FlowState` (`stepType: 'store'`,\n * `meta.op: 'cache'`) on every wrapped `get`, carrying the resolved\n * cache status (`'hit'` or `'miss'`) and the key. Observers attached\n * to `collector.observers` see HIT/MISS without coupling to wrapper\n * internals. Optional only to keep unit-test setups lightweight;\n * production call sites pass it.\n */\n collector?: Collector.Instance;\n}\n\ninterface CompiledStoreCacheRule {\n match: (context: Record<string, unknown>) => boolean;\n ttl: number;\n}\n\n/**\n * Per-wrapped-store observability counters. The `evictions_*` counters live on\n * the underlying cache store (`createCacheStore` returns its own counters\n * surface for the global `__cache`), so they are deliberately absent here.\n *\n * Semantics:\n * - `hits` — `cacheStore.get` returned a defined value.\n * - `misses` — cache returned undefined AND no in-flight Promise was joined\n * (this caller is the one driving the backing fetch).\n * - `populates` — the wrapper wrote into the cache after a backing MISS that\n * returned a defined value AND matched a rule.\n * - `writes` — every call to `wrapper.set`, regardless of cache outcome.\n * - `deletes` — every call to `wrapper.delete`.\n * - `inflight_dedups` — a get found an in-flight Promise on the same key and\n * joined it instead of starting a new backing call.\n */\nexport interface WrappedStoreCounters {\n hits: number;\n misses: number;\n populates: number;\n writes: number;\n deletes: number;\n inflight_dedups: number;\n}\n\n/**\n * Public-facing extension of `Store.Instance` with the per-wrapper counter\n * surface. Consumers that need observability (operator UIs, debug endpoints)\n * cast to this type via `as WrappedStoreInstance`; everything else continues\n * to see the canonical `Store.Instance` shape and stays decoupled from the\n * wrapper's internals.\n */\nexport interface WrappedStoreInstance extends Store.Instance {\n /**\n * Snapshot accessor: returns a fresh copy of the counter map on every\n * access. Mutating the returned object never affects internal state, so\n * callers can serialize, diff, or send the snapshot freely. The returned\n * object always carries every counter key, zero-initialized.\n */\n readonly counters: WrappedStoreCounters;\n}\n\n/**\n * Wrap a backing `Store.Instance` with a read-through cache layer.\n *\n * Read semantics:\n * 1. Probe the cache at `namespace:key` and interpret the stored\n * `{value, exp}` envelope via `readCacheEnvelope`. A live envelope is a\n * HIT. An expired envelope is best-effort purged and treated as a MISS.\n * 2. On MISS, delegate to `backing.get(key)`.\n * 3. If the backing returned a defined value AND a rule matches the\n * `{ key, value }` context, populate the cache with the value wrapped in\n * a `{value, exp}` envelope (exp = now + `rule.ttl * 1000` ms) AND pass\n * the `ttl` arg so a TTL-native tier can proactively evict (dual-write).\n * The envelope `exp` is authoritative; the `ttl` arg is an eviction hint.\n * Negative caching (caching `undefined`) is intentionally not supported.\n *\n * Multi-tier: each wrapper wraps independently. When the cache tier is itself\n * a wrapped store, the value is enveloped once per tier (nested envelopes), and\n * each tier strips exactly its own outer envelope on read, so the read chain\n * unwraps as many layers as it wrapped. Nesting depth and payload grow with the\n * number of tiers (negligible for the typical 2-3 tier chain). Each tier owns\n * its own `exp` from its own rule, so the staleness bound is per tier.\n *\n * Write semantics (`set` / `delete`) follow the \"cache is advisory\" policy\n * documented in `docs/plans/2026-05-13-store-cache-design.md` (Write path and\n * error policy):\n * - Backing first. If `backing.set`/`backing.delete` throws, the wrapper\n * throws and the cache layer is never touched. The backing is the source\n * of truth and its failures must surface to the caller.\n * - Cache best-effort. After a successful backing write, attempt the cache\n * write. A throwing cache layer is logged via `logger.warn` and swallowed\n * so the wrapper still resolves successfully, the next read will MISS\n * and re-populate. Failed cache deletes leave a stale entry that serves\n * until TTL; the warning lets operators react.\n */\nexport function wrapStoreWithCache(\n backing: Store.Instance,\n opts: WrappedStoreOptions,\n): WrappedStoreInstance {\n const { cacheConfig, cacheStore, namespace, logger, storeId, collector } =\n opts;\n\n // Cache observability. Each wrapped `get` resolves to a HIT or MISS;\n // the wrapper emits a `FlowState` on the collector so observers can\n // record cache metadata without coupling to wrapper internals. When\n // `collector` is absent (unit-test path), reporting is skipped.\n const reportCacheStatus = (key: string, status: 'hit' | 'miss'): void => {\n if (!collector) return;\n const state = buildBaseState(collector, {\n stepId: `store.${storeId}`,\n stepType: 'store',\n phase: 'in',\n eventId: '',\n now: Date.now(),\n });\n state.meta = {\n op: 'cache',\n cached: status === 'hit',\n status,\n key,\n };\n emitStep(collector, state);\n };\n\n // Closure-scoped counters. Mutated directly at each path; the public\n // `counters` accessor on the returned instance returns a fresh shallow copy\n // so external consumers cannot mutate internal state.\n const counters: WrappedStoreCounters = {\n hits: 0,\n misses: 0,\n populates: 0,\n writes: 0,\n deletes: 0,\n inflight_dedups: 0,\n };\n\n // Pre-compile each rule's matcher once at wrap time. Rules without a `match`\n // clause are treated as always-matching, mirroring the EventCacheRule\n // helpers in `packages/core/src/cache.ts`.\n const compiledRules: CompiledStoreCacheRule[] = cacheConfig.rules.map(\n (rule) => ({\n match: rule.match ? compileMatcher(rule.match) : () => true,\n ttl: rule.ttl,\n }),\n );\n\n const prefixed = (key: string): string => `${namespace}:${key}`;\n\n function findMatchingRule(\n key: string,\n value: Store.StoreValue | undefined,\n ): CompiledStoreCacheRule | undefined {\n // Store-cache context shape is `{ key, value? }` — no `ingest`. The value\n // is omitted when the caller has not yet read from the backing (e.g.\n // future write-path callers).\n const ctx: Record<string, unknown> =\n value === undefined ? { key } : { key, value };\n return compiledRules.find((r) => r.match(ctx));\n }\n\n // Closure-scoped in-flight registry: N concurrent gets on the same cold key\n // share one backing call. Keyed by the namespaced cache key so distinct\n // backing keys never collide. The entry is removed in `finally` so a\n // settled (resolved or rejected) Promise never lingers — a subsequent get\n // either hits the now-populated cache or retries the backing.\n const inFlight = new Map<string, Promise<Store.StoreValue | undefined>>();\n\n return {\n type: backing.type,\n config: backing.config,\n setup: backing.setup,\n\n // Snapshot accessor. Returning a fresh shallow copy on every read keeps\n // the internal counter object un-aliased: consumers that store, diff, or\n // serialize the snapshot cannot inadvertently mutate state.\n get counters(): WrappedStoreCounters {\n return { ...counters };\n },\n\n async get(key: string): Promise<Store.StoreValue | undefined> {\n const ns = prefixed(key);\n const stored = await cacheStore.get(ns);\n const envelope = readCacheEnvelope(stored);\n if (envelope !== undefined) {\n if ('expired' in envelope) {\n // Expired entry: best-effort purge from the cache tier, then fall\n // through to the backing as a MISS. A throwing delete must not\n // surface to the caller; a stale entry serving until the next read\n // is acceptable.\n try {\n await cacheStore.delete(ns);\n } catch (error) {\n warnCacheFailure('delete', key, error);\n }\n } else {\n counters.hits++;\n reportCacheStatus(key, 'hit');\n return envelope.value;\n }\n }\n\n // Single-flight: if another caller is already fetching this key, join\n // their Promise rather than starting a second backing call.\n const existing = inFlight.get(ns);\n if (existing) {\n counters.inflight_dedups++;\n reportCacheStatus(key, 'hit');\n return existing;\n }\n\n // This caller drives the backing fetch — count the MISS once here so\n // joined callers above are not double-counted as misses too.\n counters.misses++;\n reportCacheStatus(key, 'miss');\n\n const promise = (async () => {\n try {\n const value = await backing.get(key);\n if (value === undefined) return undefined;\n\n const rule = findMatchingRule(key, value);\n if (rule) {\n // Best-effort cache populate. Mirrors the write-path\n // policy: backing has already returned, so a throwing cache layer\n // must not surface as an unhandled rejection on the shared\n // Promise that other concurrent callers are awaiting.\n try {\n // `cache.ttl` is documented in seconds; the envelope `exp` and\n // the TTL-native eviction hint both want ms. Multiply once at the\n // boundary to keep the rest of the pipeline consistent with\n // EventCache semantics. Dual-write: the `{value, exp}` envelope\n // is authoritative for expiry (every backing tier honors it),\n // and the `ttl` arg lets a TTL-native tier (`__cache`, Redis)\n // proactively evict.\n const ttlMs = rule.ttl * 1000;\n await cacheStore.set(ns, wrapCacheEnvelope(value, ttlMs), ttlMs);\n // Count the populate only after the cache write resolves so a\n // failed populate (logged below) does not inflate the counter.\n counters.populates++;\n } catch (error) {\n warnCacheFailure('set', key, error);\n }\n }\n return value;\n } finally {\n // Always release the slot — on resolve so the next read hits the\n // now-populated cache, on reject so a transient backing failure\n // doesn't freeze the key forever behind a dead Promise.\n inFlight.delete(ns);\n }\n })();\n inFlight.set(ns, promise);\n return promise;\n },\n\n async set(\n key: string,\n value: Store.StoreValue,\n ttl?: number,\n ): Promise<void> {\n // Count every set the moment the wrapper is entered, before any IO.\n // The counter reflects intent (how many writes the wrapper has been\n // asked to perform), independent of backing or cache success.\n counters.writes++;\n\n // Backing first. A throw here propagates: backing is the source of\n // truth, callers must see real write failures.\n await backing.set(key, value, ttl);\n\n const rule = findMatchingRule(key, value);\n if (!rule) return;\n\n // Best-effort cache populate. Wrap only the cache-side call: backing\n // errors above have already propagated, so this try/catch is scoped to\n // the advisory layer. Same dual-write as the read-path populate: store\n // the `{value, exp}` envelope and pass the `ttl` eviction hint.\n try {\n const ttlMs = rule.ttl * 1000;\n await cacheStore.set(\n prefixed(key),\n wrapCacheEnvelope(value, ttlMs),\n ttlMs,\n );\n } catch (error) {\n warnCacheFailure('set', key, error);\n }\n },\n\n async delete(key: string): Promise<void> {\n // Mirrors `writes`: count intent at entry, before backing or cache IO.\n counters.deletes++;\n\n // Backing first; same propagation rules as `set`.\n await backing.delete(key);\n\n try {\n await cacheStore.delete(prefixed(key));\n } catch (error) {\n warnCacheFailure('delete', key, error);\n }\n },\n };\n\n function warnCacheFailure(\n op: 'set' | 'delete',\n key: string,\n error: unknown,\n ): void {\n const message = `store-cache(${storeId}): cache ${op} failed for \"${key}\"; backing succeeded, continuing`;\n if (logger) {\n logger.warn(message, errorMeta(error));\n } else {\n // Defensive fallback so unit tests that do not thread a logger still\n // surface the failure rather than swallowing it silently. Production\n // call sites in `store.ts` always pass `collector.logger`.\n // eslint-disable-next-line no-console\n console.warn(message, error);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;;;ACGO,IAAM,WAAwD;AAAA,EACnE,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AACV;AAEA,IAAM,eAA+C;AAAA,EACnD,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AACX;AAEA,IAAM,QAAQ;AAAA,EACZ,SAAS;AACX;AAEO,IAAM,QAAQ;AAAA,EACnB;AAAA,EACA;AACF;;;ACvCA,kBAAuB;AAMhB,SAAS,eACdA,YACA,MAC8B;AAC9B,QAAM,SAA2B,CAAC;AAClC,SAAO,QAAQ,IAAI,EAAE,QAAQ,CAAC,CAAC,MAAM,OAAO,MAAM;AAChD,WAAO,IAAI,IAAI,CAAC,CAAC;AAAA,EACnB,CAAC;AAED,EAAAA,WAAU,cAAU,oBAAOA,WAAU,SAAS,MAAM;AAEpD,SAAO,EAAE,OAAO;AAClB;;;ACZA,IAAAC,gBAA6B;;;ACI7B,IAAAC,eAsBO;;;AChCP,IAAAC,eAAyB;AAkBlB,SAAS,cACd,OACA,QACAC,YACe;AACf,SAAO;AAAA;AAAA,IAEL,SAAS,MAAM,QAAQ,SAAS,QAAQ,MAAM,SAASA,WAAU;AAAA,IACjE,UAAU,QAAQ,MAAM,KAAK,CAAC;AAAA,IAC9B,eAAe,QAAQ,MAAM;AAAA,EAC/B;AACF;AAwBO,SAAS,eACdA,YACA,MACW;AACX,QAAM,YAAYA,WAAU,OAAO;AACnC,QAAM,QAAmB;AAAA,IACvB,QAAQA,WAAU,QAAQ;AAAA,IAC1B,QAAQ,KAAK;AAAA,IACb,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,SAAS,KAAK;AAAA,IACd,WAAW,IAAI,KAAK,KAAK,GAAG,EAAE,YAAY;AAAA,IAC1C,WAAW,KAAK,MAAM;AAAA,EACxB;AAGA,MAAI,KAAK,QAAS,OAAM,UAAU,KAAK;AACvC,MAAI,KAAK,SAAU,OAAM,WAAW,KAAK;AACzC,MAAI,KAAK,cAAe,OAAM,gBAAgB,KAAK;AACnD,SAAO;AACT;AAyBO,SAAS,kBACdC,YACA,OACA,QACA,IACA,IACM;AACN,EAAAA,WAAU,OAAO;AACjB,QAAM,QAAQ,eAAeA,YAAW;AAAA,IACtC,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,OAAO;AAAA,IACP,SAAS,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK;AAAA,IACnD,KAAK,KAAK,IAAI;AAAA,IACd,GAAG,cAAc,OAAO,QAAQA,UAAS;AAAA,EAC3C,CAAC;AACD,QAAM,aAAa;AACnB,QAAM,OAAO,EAAE,IAAI,MAAM,SAAS,GAAG;AACrC,6BAASA,YAAW,KAAK;AAC3B;;;ACrHA,IAAAC,eAA2B;AAuB3B,IAAM,kBAAkB;AAGxB,SAAS,YAAY,OAAwB;AAC3C,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,QAAM,QAAiB,OAAO,eAAe,KAAK;AAClD,SAAO,UAAU,OAAO,aAAa,UAAU;AACjD;AASA,SAAS,UACP,KACA,MACA,OACS;AACT,MAAI,QAAQ,QAAQ,OAAO,QAAQ,SAAU,QAAO;AACpD,MAAI,SAAS,mBAAmB,CAAC,YAAY,GAAG,EAAG,QAAO;AAC1D,QAAM,WAAW,KAAK,IAAI,GAAG;AAC7B,MAAI,aAAa,OAAW,QAAO;AACnC,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,UAAM,WAAsB,CAAC;AAC7B,SAAK,IAAI,KAAK,QAAQ;AACtB,eAAW,QAAQ,KAAK;AACtB,eAAS,KAAK,UAAU,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AACA,QAAMC,SAAiC,CAAC;AACxC,OAAK,IAAI,KAAKA,MAAK;AACnB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,IAAAA,OAAM,GAAG,IACP,OAAO,UAAU,aAAa,QAAQ,UAAU,OAAO,MAAM,QAAQ,CAAC;AAAA,EAC1E;AACA,SAAOA;AACT;AAWO,SAAS,QACd,KACY;AACZ,QAAM,EAAE,YAAY,GAAG,KAAK,IAAI;AAChC,QAAM,SAAkC,CAAC;AACzC,QAAM,OAAO,oBAAI,QAAyB;AAC1C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,WAAO,GAAG,IACR,OAAO,UAAU,aAAa,QAAQ,UAAU,OAAO,MAAM,CAAC;AAAA,EAClE;AAEA,QAAM,eAAW,yBAAW,QAAQ,UAAU;AAC9C,SAAO;AAAA,IACL,YAAY,SAAS;AAAA,IACrB,OAAO,SAAS;AAAA,IAChB,YAAY,SAAS;AAAA,EACvB;AACF;;;ACzFA,IAAM,qBAAqB;AAO3B,SAAS,cAAc,OAAiD;AACtE,QAAM,QAAQ,OAAO,eAAe,KAAK;AACzC,SAAO,UAAU,OAAO,aAAa,UAAU;AACjD;AAOA,SAAS,SAAS,QAAiC,KAAsB;AACvE,MAAI;AACF,WAAO,OAAO,GAAG;AAAA,EACnB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMA,SAAS,UAAU,OAAuB;AACxC,MAAI;AACF,WAAO,OAAO,KAAK;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAYO,SAAS,aAAa,MAA4B;AACvD,QAAM,OAAO,oBAAI,QAAgB;AAEjC,QAAM,OAAO,CAAC,OAAgB,UAA2B;AACvD,QAAI,UAAU,KAAM,QAAO;AAC3B,QAAI,OAAO,UAAU,WAAY,QAAO;AACxC,QAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAW,QAAO;AACpE,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAAA,IAC1C;AACA,QAAI,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAClD,QAAI,OAAO,UAAU,SAAU,QAAO;AAEtC,UAAM,MAAM;AACZ,QAAI,KAAK,IAAI,GAAG,EAAG,QAAO;AAC1B,QAAI,SAAS,mBAAoB,QAAO;AACxC,SAAK,IAAI,GAAG;AAOZ,QAAI;AACJ,QAAI;AACF,UAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,iBAAS,IAAI,IAAI,CAAC,SAAS,KAAK,MAAM,QAAQ,CAAC,CAAC;AAAA,MAClD,WAAW,cAAc,GAAG,GAAG;AAC7B,cAAM,OAAgC,CAAC;AACvC,mBAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAClC,eAAK,GAAG,IAAI,KAAK,SAAS,KAAK,GAAG,GAAG,QAAQ,CAAC;AAAA,QAChD;AACA,iBAAS;AAAA,MACX,OAAO;AACL,iBAAS,UAAU,GAAG;AAAA,MACxB;AAAA,IACF,QAAQ;AACN,eAAS;AAAA,IACX;AAIA,SAAK,OAAO,GAAG;AACf,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,CAAC;AACvC;AAMO,SAAS,cAAc,OAA6C;AACzE,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC1B,IAAI,KAAK;AAAA,IACT,MAAM,aAAa,KAAK,IAAI;AAAA,IAC5B,IAAI,KAAK;AAAA,EACX,EAAE;AACJ;;;ACrGA,IAAAC,eAAoC;AAEpC,IAAAC,eAAwC;;;ACFxC,IAAAC,eAAuB;;;ACuChB,SAAS,YACd,QACA,MACA,OACA,QACmB;AACnB,MAAI,CAAC,OAAO,SAAS,MAAM,GAAG,KAAK,MAAM,OAAO,GAAG;AACjD,UAAM,IAAI,MAAM,qCAAqC,MAAM,GAAG,GAAG;AAAA,EACnE;AAEA,QAAM,SAA+B,MAAM,cAAc;AAEzD,MAAI,WAAW,cAAc;AAC3B,QAAI,OAAO,UAAU,MAAM,KAAK;AAC9B,UAAI,OAAQ,QAAO,CAAC,IAAI,CAAC;AACzB,aAAO,EAAE,UAAU,OAAO,SAAS,EAAE;AAAA,IACvC;AACA,WAAO,KAAK,IAAI;AAChB,WAAO,EAAE,UAAU,MAAM,SAAS,EAAE;AAAA,EACtC;AAGA,QAAM,UAAe,CAAC;AACtB,SAAO,OAAO,UAAU,MAAM,KAAK;AAEjC,YAAQ,KAAK,OAAO,MAAM,CAAE;AAAA,EAC9B;AACA,SAAO,KAAK,IAAI;AAChB,MAAI,QAAQ,SAAS,KAAK,OAAQ,QAAO,OAAO;AAChD,SAAO,EAAE,UAAU,MAAM,SAAS,QAAQ,OAAO;AACnD;AAOA,IAAM,gBAAgB,oBAAI,QAAyB;AAU5C,SAAS,iBACd,QACA,QACA,SACA,SACM;AACN,MAAI,cAAc,IAAI,MAAM,EAAG;AAC/B,gBAAc,IAAI,QAAQ,IAAI;AAC9B,SAAO,KAAK,SAAS,OAAO;AAC9B;AAMO,SAAS,kBAAkB,QAAsB;AACtD,gBAAc,OAAO,MAAM;AAC7B;;;AC5FO,IAAM,4BAA4B;AAClC,IAAM,8BAA8B;AAoB3C,IAAI,QAAsB,MAAM,KAAK,IAAI;AAsBlC,SAAS,qBACd,SAC2B;AAC3B,MAAI,YAAY,OAAW,QAAO;AAClC,MAAI,OAAO,YAAY,UAAU;AAC/B,WAAO,EAAE,WAAW,SAAS,UAAU,4BAA4B;AAAA,EACrE;AACA,SAAO;AAAA,IACL,WAAW,QAAQ,aAAa;AAAA,IAChC,UAAU,QAAQ,YAAY;AAAA,EAChC;AACF;AAGO,SAAS,mBACd,UACA,KACc;AACd,MAAI,CAAC,SAAS,GAAG,GAAG;AAClB,aAAS,GAAG,IAAI,EAAE,OAAO,UAAU,qBAAqB,EAAE;AAAA,EAC5D;AACA,SAAO,SAAS,GAAG;AACrB;AAaO,SAAS,cACd,UACA,KACA,UACS;AACT,QAAM,UAAU,SAAS,GAAG;AAC5B,MAAI,CAAC,WAAW,QAAQ,UAAU,SAAU,QAAO;AAEnD,MAAI,QAAQ,UAAU,aAAa;AAEjC,WAAO,QAAQ,YAAY;AAAA,EAC7B;AAGA,QAAM,MAAM,MAAM;AAClB,MAAI,QAAQ,cAAc,UAAa,MAAM,QAAQ,WAAW;AAC9D,WAAO;AAAA,EACT;AAIA,UAAQ,QAAQ;AAChB,UAAQ,UAAU;AAClB,UAAQ,YAAY,MAAM;AAC1B,SAAO;AACT;AAMO,SAAS,kBACd,UACA,KACA,SACA,WACA,UACM;AACN,MAAI,YAAY,UAAW;AAE3B,QAAM,UAAU,mBAAmB,UAAU,GAAG;AAEhD,MAAI,YAAY,WAAW;AACzB,YAAQ,sBAAsB;AAC9B,YAAQ,QAAQ;AAChB,YAAQ,UAAU;AAClB,YAAQ,YAAY;AACpB;AAAA,EACF;AAGA,UAAQ,uBAAuB;AAE/B,MAAI,QAAQ,UAAU,aAAa;AAEjC,YAAQ,QAAQ;AAChB,YAAQ,UAAU;AAClB,YAAQ,YAAY,MAAM,IAAI;AAC9B;AAAA,EACF;AAEA,MAAI,QAAQ,uBAAuB,WAAW;AAC5C,YAAQ,QAAQ;AAChB,YAAQ,UAAU;AAClB,YAAQ,YAAY,MAAM,IAAI;AAAA,EAChC;AACF;AAcO,SAAS,aACd,UACA,KACM;AACN,QAAM,UAAU,SAAS,GAAG;AAC5B,MAAI,CAAC,WAAW,QAAQ,UAAU,eAAe,QAAQ,YAAY,MAAM;AACzE;AAAA,EACF;AACA,UAAQ,QAAQ;AAChB,UAAQ,UAAU;AACpB;AAOO,SAAS,wBACd,SACA,KACS;AACT,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI,QAAQ,UAAU,YAAY,QAAQ,UAAU,YAAa,QAAO;AACxE,SAAO,QAAQ,cAAc,UAAa,OAAO,QAAQ;AAC3D;;;AFzLO,IAAM,kBAAkB;AAKxB,SAAS,iBACdC,YACA,QAC6B;AAC7B,MAAI,CAACA,WAAU,OAAO,aAAa,MAAM,GAAG;AAC1C,IAAAA,WAAU,OAAO,aAAa,MAAM,IAAI;AAAA,MACtC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,eAAe;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AACA,SAAOA,WAAU,OAAO,aAAa,MAAM;AAC7C;AAOO,SAAS,YACd,QACA,IACA,QACA,GACQ;AACR,MAAI,CAAC,OAAO,QAAQ,EAAE,EAAG,QAAO,QAAQ,EAAE,IAAI,CAAC;AAC/C,QAAM,QAAQ,OAAO,QAAQ,EAAE;AAC/B,QAAM,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK;AACvC,SAAO,MAAM,MAAM;AACrB;AAWA,SAAS,gBACPA,YACA,aACA,QACA,OACA,KACA,QACM;AACN,QAAM,MAAO,YAAY,MAAM,YAAY,OAAO,CAAC;AACnD,QAAM,WAAW,EAAE,KAAK,YAAY,OAAO,UAAU,gBAAgB;AACrE,QAAM,YAAY,YAAY,KAAK,CAAC,OAAO,GAAG,GAAG,QAAQ;AACzD,MAAI,UAAU,UAAU,GAAG;AACzB,UAAM,eAAe;AAAA,MACnBA,WAAU;AAAA,UACV,qBAAO,eAAe,MAAM;AAAA,MAC5B;AAAA,MACA,UAAU;AAAA,IACZ;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,KAAK,SAAS;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAAA,EACF,WAAW,IAAI,SAAS,SAAS,KAAK;AACpC,sBAAkB,GAAG;AAAA,EACvB;AACA,QAAM,aAAa,iBAAiBA,YAAW,MAAM;AACrD,aAAW;AACX,aAAW,UAAU,IAAI;AACzB,EAAAA,WAAU,OAAO;AAKjB,QAAM,gBAAgB,qBAAqB,YAAY,OAAO,OAAO;AACrE,MAAI,eAAe;AACjB,UAAM,cAAc,YAAY,OAAO,MAAM;AAC7C;AAAA,MACEA,WAAU,OAAO;AAAA,UACjB,qBAAO,eAAe,WAAW;AAAA,MACjC;AAAA,MACA,cAAc;AAAA,MACd,cAAc;AAAA,IAChB;AAAA,EACF;AACF;AASO,SAAS,UAAU,KAIxB;AACA,QAAM,OAAiE;AAAA,IACrE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,EACxD;AACA,MAAI,eAAe,SAAS,IAAI,QAAQ,IAAI,SAAS,SAAS;AAC5D,SAAK,OAAO,IAAI;AAAA,EAClB;AACA,MAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,UAAU,KAAK;AAC5D,UAAM,WAA+B;AACrC,QACE,OAAO,SAAS,SAAS,YACzB,OAAO,SAAS,SAAS,UACzB;AACA,WAAK,OAAO,SAAS;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;AA0BO,SAAS,iBACdA,YACA,MACA,IACA,QACA,aAC0C;AAC1C,QAAM,UAAM,qBAAO,MAAM,EAAE;AAC3B,SAAO,CAAC,KAAc,UAAiC;AACrD,QAAI;AACF,UAAI,OAAO;AACT,YAAI,aAAa;AACf,0BAAgBA,YAAW,aAAa,IAAI,OAAO,KAAK,MAAM;AAAA,QAChE,OAAO;AAGL,UAAAA,WAAU,OAAO;AAAA,QACnB;AACA,eAAO,MAAM,gBAAgB;AAAA,UAC3B,GAAG,UAAU,GAAG;AAAA,UAChB,OAAO,MAAM;AAAA,QACf,CAAC;AACD;AAAA,MACF;AAIA,MAAAA,WAAU,OAAO,iBAAiB,GAAG,KAClCA,WAAU,OAAO,iBAAiB,GAAG,KAAK,KAAK;AAClD,aAAO,MAAM,oBAAoB,UAAU,GAAG,CAAC;AAAA,IACjD,QAAQ;AAAA,IAER;AAAA,EACF;AACF;;;AGlMA,IAAAC,eAeO;;;ACcP,IAAAC,eAqBO;;;ACpDA,SAAS,cACd,UACAC,YAC4B;AAC5B,MAAI,SAAS,WAAWA,WAAU,OAAO,SAAS,OAAO,GAAG;AAC1D,WAAOA,WAAU,OAAO,SAAS,OAAO;AAAA,EAC1C;AACA,SAAOA,WAAU,OAAO;AAC1B;AAQO,SAAS,cACd,SACAA,YAC4B;AAC5B,MAAI,QAAS,QAAOA,WAAU,OAAO,OAAO;AAC5C,SAAOA,WAAU,OAAO;AAC1B;;;AD2CO,SAAS,qBAGd,YACA,cAIA;AACA,QAAM,SAAU,WAAW,UAAU,CAAC;AACtC,QAAM,aAAa,WAAW,YAAY;AAE1C,MAAI,eAAe,QAAW;AAC5B,WAAO;AAAA,MACL,QAAQ,EAAE,GAAG,QAAQ,CAAC,YAAY,GAAG,WAAW;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,YAAY,OAAU;AACzC;AAUA,eAAsB,iBACpBC,YACAC,oBAAiD,CAAC,GACf;AACnC,QAAM,SAAmC,CAAC;AAE1C,aAAW,CAAC,eAAe,cAAc,KAAK,OAAO;AAAA,IACnDA;AAAA,EACF,GAAG;AACD,UAAM,EAAE,MAAM,MAAM,CAAC,EAAE,IAAI;AAM3B,UAAM,iBAAa;AAAA,MACjB;AAAA,MACA;AAAA,IACF;AACA,QAAI,CAAC,WAAW,IAAI;AAClB,MAAAD,WAAU,OAAO;AAAA,QACf,eAAe,aAAa,aAAa,WAAW,IAAI,MAAM,WAAW,MAAM;AAAA,MACjF;AACA;AAAA,IACF;AAGA,UAAM,EAAE,QAAQ,iBAAiB,IAAI;AAAA,MACnC;AAAA,MACA;AAAA,IACF;AACA,UAAM,EAAE,QAAQ,gBAAgB,IAAI;AAAA,MAClC,EAAE,GAAG,gBAAgB,QAAQ,iBAAiB;AAAA,MAC9C;AAAA,IACF;AAIA,UAAM,gBACJ,OAAO,KAAK,GAAG,EAAE,SAAS,IACtB,EAAE,GAAG,iBAAiB,IAA4B,IAClD;AAGN,UAAM,EAAE,MAAM,IAAI;AAClB,UAAM,kBAAkB,QAAQ,EAAE,GAAG,eAAe,MAAM,IAAI;AAI9D,UAAM,gBAAgB,eAAe,QAAQ,SAAS,eAAe;AACrE,UAAM,kBACJ,kBAAkB,UAAa,gBAAgB,UAAU,SACrD,EAAE,GAAG,iBAAiB,OAAO,cAAc,IAC3C;AAGN,UAAM,oBAAoBA,WAAU,OACjC,MAAM,aAAa,EACnB,MAAM,aAAa;AAEtB,UAAM,UAAU;AAAA,MACd,WAAAA;AAAA,MACA,QAAQ;AAAA,MACR,IAAI;AAAA,MACJ,YAAQ,2BAAa,aAAa;AAAA,MAClC,QAAQ;AAAA,MACR;AAAA,MACA,aAAa;AAAA,QACXA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AASA,UAAM,SACJ,SACC,CAAC,QAA6B;AAC7B,YAAM,cAAc,eAAe;AACnC,UAAI,aAAa;AAKf,cAAM,oBAA8B,CAAC;AACrC,YAAI,YAAY,SAAS,OAAW,mBAAkB,KAAK,MAAM;AAEjE,YAAI,YAAY,SAAS;AACvB,qBAAW,CAAC,QAAQ,OAAO,KAAK,OAAO;AAAA,YACrC,YAAY;AAAA,UACd,GAAG;AACD,gBAAI,OAAO,YAAY,YAAY,YAAY,KAAM;AACrD,uBAAW,CAAC,QAAQ,IAAI,KAAK,OAAO;AAAA,cAClC;AAAA,YACF,GAAG;AACD,kBAAI,OAAO,SAAS,YAAY,SAAS,KAAM;AAC/C,oBAAM,IAAI;AACV,kBAAI,EAAE,SAAS;AACb,kCAAkB,KAAK,WAAW,MAAM,KAAK,MAAM,QAAQ;AAC7D,kBAAI,EAAE,WAAW;AACf,kCAAkB;AAAA,kBAChB,WAAW,MAAM,KAAK,MAAM;AAAA,gBAC9B;AAAA,YACJ;AAAA,UACF;AAAA,QACF;AACA,YAAI,kBAAkB,SAAS,GAAG;AAChC,cAAI,UAAU,OAAO;AAAA,YACnB,eAAe,aAAa,OAAO,kBAAkB,KAAK,IAAI,CAAC;AAAA,UACjE;AAAA,QACF;AAEA,eAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ,IAAI;AAAA,UACZ,MAAM,OAAO,UAAqC;AAChD,kBAAM,IAAI,UAAM;AAAA,cACd;AAAA,cACA;AAAA,cACA,IAAI;AAAA,YACN;AACA,gBAAI,EAAE,OAAQ,QAAO;AACrB,mBAAO,EAAE,OAAO,EAAE,MAAM;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,IAAI;AAAA,QACZ,MAAM,CAAC,WAAsC,EAAE,MAAM;AAAA,MACvD;AAAA,IACF;AAGF,UAAM,WAAW,MAAM,OAAO,OAAO;AAQrC,QACE,eAAe,WAAW,UAC1B,SAAS,QAAQ,WAAW,QAC5B;AACA,eAAS,SAAS;AAAA,QAChB,GAAI,SAAS,UAAU,CAAC;AAAA,QACxB,QAAQ,eAAe;AAAA,MACzB;AAAA,IACF;AACA,QACE,eAAe,SAAS,UACxB,SAAS,QAAQ,SAAS,QAC1B;AACA,eAAS,SAAS;AAAA,QAChB,GAAI,SAAS,UAAU,CAAC;AAAA,QACxB,MAAM,eAAe;AAAA,MACvB;AAAA,IACF;AAGA,QAAI,kBAAkB,UAAa,SAAS,QAAQ,UAAU,QAAW;AACvE,eAAS,SAAS;AAAA,QAChB,GAAI,SAAS,UAAU,CAAC;AAAA,QACxB,OAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO,aAAa,IAAI;AAAA,EAC1B;AAEA,SAAO;AACT;AAWA,eAAsB,gBACpBA,YACA,aACA,eACkB;AAElB,MAAI,YAAY,QAAQ,CAAC,YAAY,OAAO,MAAM;AAChD,UAAM,kBAAkB,YAAY,QAAQ;AAC5C,UAAM,oBAAoBA,WAAU,OAAO;AAAA,MACzC,eAAe,eAAe;AAAA,IAChC;AAEA,UAAM,UAA+B;AAAA,MACnC,WAAAA;AAAA,MACA,QAAQ;AAAA,MACR,IAAI;AAAA,MACJ,YAAQ,2BAAa,aAAa;AAAA,MAClC,QAAQ,YAAY;AAAA,MACpB,KAAK,6BAA6B,YAAY,OAAO,GAAG;AAAA,MACxD,aAAa;AAAA,QACXA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,sBAAkB,MAAM,MAAM;AAE9B,UAAM,eAAe,UAAM;AAAA,MACzB,YAAY;AAAA,MACZ;AAAA,MACAA,WAAU;AAAA,MACVA,WAAU;AAAA,IACZ,EAAE,OAAO;AAGT,QAAI,iBAAiB,MAAO,QAAO;AAGnC,gBAAY,SAAS;AAAA,MACnB,GAAI,gBAAgB,YAAY;AAAA,MAChC,KACI,cAA0C,OAC5C,YAAY,OAAO;AAAA,MACrB,MAAM;AAAA,IACR;AAEA,sBAAkB,MAAM,WAAW;AAAA,EACrC;AAEA,SAAO;AACT;AAYA,eAAsB,gBACpBA,YACA,aACA,eACA,OACA,QACA,SACmE;AACnE,QAAM,kBAAkB,YAAY,QAAQ;AAC5C,QAAM,oBAAoBA,WAAU,OAAO;AAAA,IACzC,eAAe,eAAe;AAAA,EAChC;AAEA,QAAM,UAA+B;AAAA,IACnC,WAAAA;AAAA,IACA,QAAQ;AAAA,IACR,IAAI;AAAA,IACJ;AAAA;AAAA,IACA,QAAQ,YAAY;AAAA,IACpB,KAAK;AAAA,MACH,GAAG,6BAA6B,YAAY,OAAO,GAAG;AAAA,MACtD,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC/B;AAAA,IACA,aAAa;AAAA,MACXA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,oBAAkB,MAAM,QAAQ,EAAE,OAAQ,MAA4B,KAAK,CAAC;AAE5E,QAAM,UAAU,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK;AAC1D,QAAM,EAAE,SAAS,UAAU,cAAc,IAAI;AAAA,IAC3C;AAAA,IACA;AAAA,IACAA;AAAA,EACF;AACA,QAAM,UAAU,KAAK,IAAI;AACzB,QAAM,UAAU,eAAeA,YAAW;AAAA,IACxC,YAAQ,qBAAO,eAAe,aAAa;AAAA,IAC3C,UAAU;AAAA,IACV,OAAO;AAAA,IACP;AAAA,IACA,KAAK;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,UAAQ,UAAU;AAClB,6BAASA,YAAW,OAAO;AAE3B,MAAI;AACF,UAAM,SAAS,UAAM;AAAA,MACnB,YAAY;AAAA,MACZ;AAAA,MACAA,WAAU;AAAA,MACVA,WAAU;AAAA,IACZ,EAAE,OAAO,OAAO;AAEhB,UAAME,YAAW,KAAK,IAAI;AAC1B,UAAM,WAAW,eAAeF,YAAW;AAAA,MACzC,YAAQ,qBAAO,eAAe,aAAa;AAAA,MAC3C,UAAU;AAAA,MACV,OAAO;AAAA,MACP;AAAA,MACA,KAAKE;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,aAAS,aAAaA,YAAW;AACjC,aAAS,WAAW;AACpB,+BAASF,YAAW,QAAQ;AAE5B,sBAAkB,MAAM,WAAW;AAEnC,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,UAAME,YAAW,KAAK,IAAI;AAC1B,UAAM,WAAW,eAAeF,YAAW;AAAA,MACzC,YAAQ,qBAAO,eAAe,aAAa;AAAA,MAC3C,UAAU;AAAA,MACV,OAAO;AAAA,MACP;AAAA,MACA,KAAKE;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,aAAS,aAAaA,YAAW;AACjC,aAAS,QACP,eAAe,QACX,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,IACvC,EAAE,SAAS,OAAO,GAAG,EAAE;AAC7B,+BAASF,YAAW,QAAQ;AAC5B,UAAM;AAAA,EACR;AACF;AAOO,SAAS,YAAY,QAAwB;AAClD,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,EAAE,GAAG,OAAO,OAAO,MAAM,CAAC,GAAG,OAAO,MAAM,IAAI,EAAE;AAAA,EACzD;AACF;AAGA,IAAM,kBAAkB;AAuDxB,SAAS,KAAK,OAA0C;AACtD,SAAO,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK;AACnD;AAQA,SAAS,aACP,UACA,OAC2B;AAC3B,QAAM,KAAK,KAAK,QAAQ;AACxB,SAAO,OAAO,MAAM,KAAK,KAAK,MAAM,KAAK,EAAE,GAAG,OAAO,GAAG,IAAI;AAC9D;AAUA,SAAS,OACP,QACA,OACA,QACA,UACsD;AACtD,QAAM,aAAa,YAAY,MAAM;AACrC,QAAM,YAAQ,oBAAM,KAAK;AACzB,QAAM,WAAW,KAAK,MAAM;AAC5B,MAAI,aAAa,GAAI,QAAO,EAAE,OAAO,QAAQ,WAAW;AACxD,aAAW,MAAM,gBAAgB;AACjC,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,YAAY,MAAM,YAAY;AAChC,UAAM,SAAK,2BAAa,UAAU,QAAQ;AAC5C,SAAO,EAAE,OAAO,QAAQ,WAAW;AACrC;AAGA,SAAS,SACP,QACA,SACyB;AACzB,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAGA,SAAS,gBACP,QACA,OACmB;AACnB,MAAI,UAAU,OAAW,QAAO,OAAO;AAEvC,QAAM,QAAQ,OAAO,UAAU,OAAO,KAAK,MAAM,CAAC,IAAI,OAAO;AAC7D,SAAO,CAAC,EAAE,OAAO,UAAU,OAAO,SAAS,GAAG,GAAG,KAAK;AACxD;AAQA,eAAe,SACb,KACA,QACA,SACkC;AAClC,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,OAAO;AAAA,MAAI,CAAC,MAAM,cAChB,4BAAc,SAAS,CAAC,QAAiC;AACvD,YAAI,UAAU,OACX,MAAM,kBAAkB,EACxB,MAAM,QAAQ,KAAK,WAAW,UAAU,GAAG,CAAC;AAC/C,eAAO,EAAE,QAAQ,CAAC,EAAE;AAAA,MACtB,CAAC,EAAE,KAAK,IAAI;AAAA,IACd;AAAA,EACF;AAEA,QAAM,YAAqC,CAAC;AAC5C,MAAI,cAAc;AAClB,MAAI,aAAa,QAAQ,SAAS;AAClC,MAAI;AACJ,UAAQ,QAAQ,CAAC,QAAQ,UAAU;AACjC,QAAI,OAAO,KAAK,EAAE,YAAY,UAAa,OAAO;AAChD,oBAAc,OAAO;AACvB,QAAI,CAAC,OAAO,QAAS,cAAa;AAElC,QAAI,OAAO,WAAW,OAAO,OAAO,WAAW,GAAG;AAChD,UAAI,cAAc,OAAW,aAAY,OAAO;AAChD;AAAA,IACF;AACA,cAAU,KAAK,GAAG,OAAO,MAAM;AAAA,EACjC,CAAC;AAED,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,GAAI,aAAa,EAAE,SAAS,KAAc,IAAI,CAAC;AAAA,MAC/C,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjD;AAAA,EACF;AACA,SAAO,SAAS,WAAW,WAAW;AACxC;AAGA,eAAe,QACb,KACA,MACkC;AAClC,QAAM,EAAE,OAAO,IAAI;AACnB,MAAI,EAAE,OAAO,OAAO,QAAQ,IAAI;AAChC,MAAI,SAAS,KAAK;AAElB,aAAS;AACP,QAAI;AACJ,QAAI;AACJ,QAAI,QAAQ;AACV,eAAS,OAAO;AAChB,gBAAU;AACV,eAAS;AAAA,IACX,OAAO;AACL,YAAM,WAAO;AAAA,QACX;AAAA,YACA,gCAAkB,QAAQ,KAAK;AAAA,QAC/B,IAAI;AAAA,MACN;AACA,UAAI,KAAK,SAAS,OAAQ,QAAO,SAAS,CAAC,EAAE,OAAO,OAAO,CAAC,GAAG,OAAO;AACtE,UAAI,KAAK,SAAS,QAAQ;AACxB,eAAO;AAAA,UACL,QAAQ,CAAC;AAAA,UACT;AAAA,UACA,SAAS;AAAA,UACT,GAAI,KAAK,UAAU,SAAY,EAAE,WAAW,KAAK,MAAM,IAAI,CAAC;AAAA,QAC9D;AAAA,MACF;AACA,UAAI,KAAK,SAAS,QAAQ;AACxB,cAAM,SAAS;AACf,eAAO;AAAA,UACL;AAAA,UACA,KAAK,SAAS,IAAI,CAAC,QAAQ,cAAc;AAAA,YACvC,OAAO;AAAA,YACP,GAAG,OAAO,QAAQ,QAAQ,QAAQ,QAAQ;AAAA,YAC1C,SAAS;AAAA,UACX,EAAE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,cAAc,IAAI,aAAa,KAAK,EAAE;AAC5C,eAAS;AAAA,QACP,IAAI,KAAK;AAAA,QACT,UAAU,KAAK;AAAA,QACf,MAAM,KAAK;AAAA,QACX,SAAS,cAAc,YAAY,OAAO,SAAS,SAAY;AAAA,MACjE;AAAA,IACF;AAEA,UAAM,UAAU,MAAM;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,QAAQ,SAAS,OAAQ,QAAO,QAAQ;AAC5C,QAAI,QAAQ,SAAS,OAAQ,QAAO,SAAS,KAAK,QAAQ,QAAQ,OAAO;AACzE,YAAQ,QAAQ;AAChB,cAAU,QAAQ;AAClB,YAAQ,QAAQ;AAAA,EAClB;AACF;AAMA,eAAe,UACb,KACA,QACA,OACA,QACA,SACA,SACwB;AACxB,QAAM,EAAE,WAAAA,YAAW,cAAc,aAAa,IAAI;AAClD,QAAM,kBAAkB,OAAO;AAC/B,QAAM,cAAc,aAAa,eAAe;AAChD,MAAI,iBAAiB;AACrB,MAAI,iBAAiB;AACrB,QAAM,OAAO,CAAC,QAA2B,OAAO,UAAyB;AAAA,IACvE,MAAM;AAAA,IACN,OAAO,aAAa,OAAO,cAAc;AAAA,IACzC,SAAS;AAAA,IACT;AAAA,EACF;AAIA,QAAM,OAAO,CAACG,aAAoD;AAAA,IAChE,MAAM;AAAA,IACN,QAAAA;AAAA,EACF;AAEA,MAAI,CAAC,aAAa;AAChB,IAAAH,WAAU,OAAO,KAAK,0BAA0B,eAAe,EAAE;AACjE,WAAO,KAAK;AAAA,EACd;AAKA,QAAM,eAAe,YAAY,QAAQ;AAGzC,QAAM,iBAAiB,mBAAe,2BAAa,YAAY,IAAI;AACnE,QAAM,cAAc,iBAChB,cAAc,gBAAgBA,UAAS,IACvC;AAEJ,MAAI,YAAmC,SAAS;AAEhD,MAAI,CAAC,SAAS;AAEZ,QAAI,OAAO,MAAM,KAAK,SAAS,iBAAiB;AAC9C,MAAAA,WAAU,OAAO,MAAM,+BAA+B,eAAe,EAAE;AACvE,aAAO,KAAK,EAAE,QAAQ,CAAC,GAAG,SAAS,eAAe,CAAC;AAAA,IACrD;AAGA,WAAO,MAAM;AACb,WAAO,MAAM,KAAK,KAAK,eAAe;AAMtC,UAAM,gBAAgB,UAAM;AAAA,MAC1B;AAAA,MACA,CAAC,QAA0B;AACzB,YAAI,eAAe,wBAAY,OAAM;AACrC,QAAAA,WAAU,OAAO;AACjB,QAAAA,WAAU,OACP,MAAM,eAAe,YAAY,QAAQ,SAAS,EAAE,EACpD,MAAM,2BAA2B;AAAA,UAChC,aAAa;AAAA,UACb,GAAG,UAAU,GAAG;AAAA,QAClB,CAAC;AACH,eAAO;AAAA,MACT;AAAA,IACF,EAAEA,YAAW,aAAa,eAAe;AAEzC,QAAI,CAAC,cAAe,QAAO,KAAK,EAAE,QAAQ,CAAC,GAAG,SAAS,eAAe,CAAC;AAGvE,QACE,gBACA,YAAY,QAAQ,aAAa,YAAY,MAAM,QACnD;AACA,YAAM,YAAY,YAAY,OAAO,WAAW,YAAY;AAC5D,MAAAA,WAAU,OACP,MAAM,eAAe,YAAY,QAAQ,SAAS,EAAE,EACpD,MAAM,aAAa,EAAE,OAAO,aAAa,CAAC;AAC7C,uBAAiB;AACjB,aAAO,KAAK;AAAA,IACd;AAGA,QAAI,YAAY,QAAQ,SAAS,QAAW;AAC1C,MAAAA,WAAU,OACP,MAAM,eAAe,YAAY,QAAQ,SAAS,EAAE,EACpD,MAAM,MAAM;AACf,uBAAiB,YAAY,OAAO;AACpC,aAAO,KAAK;AAAA,IACd;AAGA,QAAI,YAAY,QAAQ,SAAU,QAAO,KAAK;AAG9C,QAAI,kBAAkB,aAAa;AACjC,YAAM,cAAc,UAAM;AAAA,QACxB;AAAA,QACA;AAAA,YACA,gCAAkB,QAAQ,cAAc;AAAA,MAC1C;AAEA,UAAI,aAAa,WAAW,SAAS,YAAY,OAAO;AACtD,yBAAiB,YAAY;AAG7B,YAAI,eAAe,MAAM;AACvB,gBAAM,SAAS,aAAa,OAAO,cAAc;AACjD,iBAAO,KAAK;AAAA,YACV,QAAQ,CAAC,EAAE,OAAO,QAAQ,OAAO,CAAC;AAAA,YAClC,SAAS;AAAA,YACT,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AACA,eAAO,KAAK;AAAA,MACd;AAEA,UAAI,aAAa,WAAW,QAAQ;AAClC,oBAAY,EAAE,KAAK,YAAY,KAAK,KAAK,YAAY,KAAK,IAAI;AAAA,MAChE;AAAA,IACF;AAGA,QAAI,YAAY,OAAO,WAAW,QAAW;AAC3C,YAAM,SAAS,MAAM;AAAA,QACnBA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,gBAAgB,OAAO,WAAW;AAGxC,UAAI,OAAO,OAAO,WAAW,KAAK,OAAO,SAAS;AAChD,eAAO,KAAK,EAAE,GAAG,QAAQ,SAAS,cAAc,CAAC;AAAA,MACnD;AACA,uBAAiB;AACjB,YAAM,CAAC,KAAK,IAAI,OAAO;AACvB,UAAI,OAAO,OAAO,SAAS,KAAK,MAAM,WAAW,QAAQ;AAIvD,cAAM,SAAiB,EAAE,QAAQ,UAAU;AAC3C,eAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ,OAAO,OAAO,IAAI,CAAC,UAAU;AAAA,YACnC,OAAO,OAAO;AAAA,YACd,OAAO,KAAK;AAAA,YACZ,QAAQ,KAAK;AAAA,YACb,SAAS;AAAA,YACT;AAAA,UACF,EAAE;AAAA,QACJ;AAAA,MACF;AACA,uBAAiB,MAAM;AAAA,IACzB;AAAA,EACF;AAKA,QAAM,eAAe,YAAY,QAAQ,YACrC,2BAAa,YAAY,OAAO,KAAK,IACrC;AACJ,QAAM,WAAW,cAAc,OAAO,CAAC,UAAU,MAAM,SAAS,KAAK;AACrE,QAAM,WAAW,cAAc,OAAO,CAAC,UAAU,MAAM,SAAS,KAAK;AAErE,QAAM,gBAAgB,OACpB,QACuC;AACvC,QAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO;AAC/C,eAAO;AAAA,MACL;AAAA,MACA,CAAC,OAAO,cAAc,IAAIA,UAAS;AAAA,MACnC;AAAA,MACAA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY,SAAS,SAAS,GAAG;AACnC,qBAAiB,UAAM;AAAA,MACrB;AAAA,MACA,CAAC,OAAO,cAAc,IAAIA,UAAS;AAAA,MACnC;AAAA,MACAA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,UAAM,4BAAc,iBAAiB,CAAC,QAAQ;AAC3D,IAAAA,WAAU,OAAO;AACjB,IAAAA,WAAU,OACP,MAAM,eAAe,YAAY,QAAQ,SAAS,EAAE,EACpD,MAAM,eAAe,UAAU,GAAG,CAAC;AACtC,WAAO;AAAA,EACT,CAAC;AAAA,IACCA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,MAAI,WAAW,OAAO;AACpB,WAAO,KAAK;AAAA,MACV,QAAQ,CAAC;AAAA,MACT,SAAS;AAAA,MACT,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAGA,MAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,GAAG;AAChD,QAAI,OAAO,WAAW;AACpB,aAAO,KAAK,EAAE,QAAQ,CAAC,GAAG,SAAS,eAAe,CAAC;AACrD,UAAM,SAAS;AACf,UAAM,SAAiB,CAAC;AACxB,aAAS,WAAW,GAAG,WAAW,OAAO,QAAQ,YAAY;AAC3D,YAAM,aAAa,OAAO,QAAQ;AAClC,YAAM,UAAU,MAAM,cAAc,WAAW,SAAS,MAAM;AAC9D,aAAO,KAAK;AAAA,QACV,OAAO,gBAAgB,QAAQ,WAAW,IAAI;AAAA,QAC9C,GAAG,OAAO,QAAQ,SAAS,QAAQ,QAAQ;AAAA,QAC3C,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AACA,WAAO,EAAE,MAAM,QAAQ,OAAO;AAAA,EAChC;AAIA,QAAM,SAAS,MAAM,QAAQ,MAAM,IAAI,OAAO,CAAC,IAAI;AACnD,MAAI;AACJ,MAAI,UAAU,OAAO,WAAW,UAAU;AACxC,QAAI,OAAO,QAAS,kBAAiB,OAAO;AAC5C,QAAI,OAAO,MAAO,kBAAiB,OAAO;AAC1C,iBAAa,OAAO;AAAA,EACtB;AAEA,mBAAiB,MAAM,cAAc,cAAc;AAGnD,MAAI,aAAa,aAAa;AAC5B,iCAAW,aAAa,UAAU,KAAK,gBAAgB,UAAU,GAAG;AAAA,EACtE;AAEA,SAAO,KAAK,gBAAgB,QAAQ,UAAU,CAAC;AACjD;AAiBA,eAAsB,oBACpBA,YACA,cACA,OACA,OACA,QACA,SACA,cACkC;AAGlC,QAAM,cACJ,cAAU,2BAAa,OAAO,UAAU,WAAW,QAAQ,OAAO;AACpE,MAAI,UAAU;AACZ,WAAO,SAAS,CAAC,EAAE,OAAO,QAAQ,YAAY,CAAC,GAAG,OAAO;AAC3D,MAAI,aAAc,aAAY,MAAM,YAAY;AAEhD,SAAO;AAAA,IACL,EAAE,WAAAA,YAAW,cAAc,aAAa;AAAA,IACxC;AAAA,MACE,WAAO,kCAAoB,KAAK,IAAI,YAAQ,yBAAW,KAAK;AAAA,MAC5D;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAOA,eAAsB,qBACpBA,YACA,cACA,eACA,OACA,QACA,SACA,cACkC;AAClC,QAAM,cAAc,aAAa,aAAa;AAC9C,QAAM,SAAS,cAAc,YAAY,OAAO,SAAS;AACzD,QAAM,SAAS,MAAM;AAAA,IACnBA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,OAAO,WAAW,OAAO,OAAO,WAAW,KAAK,CAAC,OAAO;AAC1D,WAAO,EAAE,GAAG,QAAQ,WAAW,cAAc;AAC/C,SAAO;AACT;AAKA,SAAS,6BACP,WACiB;AACjB,MAAI,CAAC,UAAW,QAAO,CAAC;AACxB,UAAI,uBAAS,SAAS,EAAG,QAAO;AAChC,SAAO,CAAC;AACV;;;AE1hCO,IAAM,iCAAiC;AAMvC,SAAS,0BAA0B,SAA0B;AAClE,SAAO,OAAO,YAAY,YAAY,UAAU,IAC5C,UACA;AACN;AAOO,IAAM,0BAAN,cAAsC,MAAM;AAAA,EACjD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AASO,SAAS,YACd,MACA,IACA,SACY;AACZ,MAAI;AACJ,QAAM,UAAU,IAAI,QAAe,CAAC,GAAG,WAAW;AAChD,YAAQ,WAAW,MAAM,OAAO,IAAI,wBAAwB,OAAO,CAAC,GAAG,EAAE;AAAA,EAC3E,CAAC;AACD,SAAO,QAAQ,KAAK,CAAC,MAAM,OAAO,CAAC,EAAE,QAAQ,MAAM;AACjD,QAAI,MAAO,cAAa,KAAK;AAAA,EAC/B,CAAC;AACH;;;AHWA,eAAsB,mBACpBI,YACA,QACA,UACe;AACf,MAAI,CAAC,OAAO,MAAM,CAAC,OAAO,SAAS,OAAQ;AAC3C,QAAM,QAAQ,OAAO;AACrB,SAAO,UAAU,CAAC;AAClB,QAAM,KAAK,YAAY,OAAO,QAAQ,MAAM;AAC5C,aAAW,EAAE,MAAM,KAAK,KAAK,OAAO;AAIlC,QAAI,gBAAgB,IAAI,KAAK,CAAC,cAAcA,YAAW,QAAQ,IAAI;AACjE;AAIF,UAAM,UAAU,OAAO;AACvB,QAAI,WAAW;AACf,cAAM;AAAA,MACJ,MACE;AAAA,QACE,QAAQ,QAAQ,QAAQ,MAAM,IAAI,CAAC;AAAA,QACnC;AAAA,QACA,WAAW,EAAE,QAAQ,IAAI,2BAA2B,8BAA8B;AAAA,MACpF;AAAA,MACF,CAAC,QAA4B;AAC3B,YAAI,eAAe,wBAAY,OAAM;AAGrC,YAAI,eAAe,wBAAyB,YAAW;AAAA,YAClD,CAAAA,WAAU,OAAO;AACtB,QAAAA,WAAU,OAAO,MAAM,QAAQ,EAAE,MAAM,0BAA0B;AAAA,UAC/D,UAAU;AAAA,UACV;AAAA,UACA,GAAG,UAAU,GAAG;AAAA,QAClB,CAAC;AACD,eAAO;AAAA,MACT;AAAA,IACF,EAAE;AAGF,QAAI,gBAAgB,IAAI,KAAK,CAAC,SAAU,SAAQA,YAAW,QAAQ,IAAI;AAAA,EACzE;AACF;AAMO,SAAS,gBAAgB,QAAkC;AAChE,SAAO,QAAQ,OAAO,OAAO,IAAI,KAAK,CAAC,OAAO,OAAO,SAAS;AAChE;AAMA,eAAsB,WACpBA,YACA,UACA,kBACsC;AACtC,QAAM;AAAA,IACJ;AAAA,IACA,SAAS,CAAC;AAAA,IACV,MAAM,CAAC;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAOJ,QAAM,cAAc,OAAO,SAAS,iBAAiB;AACrD,QAAM,eAAe,kBAAc,2BAAa,WAAW,IAAI;AAK/D,QAAM,oBAAoB;AAG1B,QAAM,sBAAsB,wBACxB,2BAAa;AAAA,IACX,GAAG;AAAA,IACH,MAAM,kBAAkB,QAAQ;AAAA,EAClC,CAAC,IACD;AAIJ,QAAM,eAAiC,YAAYA,WAAU;AAC7D,QAAM,cAAc,QAAQ,QAAQ;AAYpC,QAAM,cAAc,OAClB,UACA,SACA,UAC4B;AAI5B,QAAI,YAAa,QAAO,aAAa,QAAQ;AAE7C,QAAI;AAOJ,UAAM,aACJ,OAAO,SAAS,OAAO,YAAY,SAAS,OAAO,KAC/C,WACA,EAAE,GAAG,UAAU,QAAI,wBAAU,EAAE;AAOrC,QAAI,SAAkC;AAAA,MACpC,EAAE,OAAO,YAAY,QAAQ,MAAM,OAAO;AAAA,IAC5C;AAKA,QAAI,WAAW,QAAW;AACxB,YAAM,YAAY,UAAU,QAAQ;AACpC,YAAM,eAAe,MAAM;AAAA,QACzBA;AAAA,QACAA,WAAU,gBAAgB,CAAC;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,MACF;AACA,UAAI,aAAa,OAAO,WAAW,GAAG;AAEpC;AAAA,UACEA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,aAAa;AAAA,UACb;AAAA,QACF;AACA,eAAO,iBAAiB,EAAE,IAAI,MAAM,SAAS,KAAK,CAAC;AAAA,MACrD;AAIA,UAAI,aAAa,SAAS;AACxB,YAAI,aAAa,QAAS,OAAM,UAAU,aAAa;AACvD,eAAO,EAAE,IAAI,KAAK;AAAA,MACpB;AACA,UAAI,aAAa,QAAS,OAAM,UAAU,aAAa;AAIvD,eAAS,aAAa;AAAA,IACxB;AAGA,QAAI,qBAAqB;AACvB,YAAM,aAAa,cAAc,qBAAqBA,UAAS;AAC/D,UAAI,YAAY;AACd,cAAM,mBAAe,gCAAkB,MAAM,MAAM;AACnD,cAAM,cAAc,UAAM;AAAA,UACxB;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAEF;AAEA,YAAI,aAAa;AACf,cAAI,YAAY,WAAW,SAAS,YAAY,UAAU,QAAW;AACnE,gBAAI,oBAAoB,MAAM;AAE5B,kBAAI,eAAwB,YAAY;AACxC,kBAAI,YAAY,KAAK,QAAQ;AAC3B,+BAAe,UAAM;AAAA,kBACnB;AAAA,kBACA,YAAY,KAAK;AAAA,kBACjB,EAAE,GAAG,cAAc,OAAO,EAAE,QAAQ,MAAM,EAAE;AAAA,kBAC5CA;AAAA,gBACF;AAAA,cACF;AACA,oBAAM,UAAU,YAAuC;AACvD,qBAAO,EAAE,IAAI,KAAK;AAAA,YACpB;AAAA,UAEF;AAEA,cACE,YAAY,WAAW,UACvB,oBAAoB,QACpB,MAAM,SACN;AAcA,kBAAM,mBAAmB,MAAM;AAC/B,kBAAM,aAAa,YAAY,KAAK;AACpC,kBAAM,cAAc,EAAE,GAAG,cAAc,OAAO,EAAE,QAAQ,OAAO,EAAE;AACjE,kBAAM,UAAU,YAAY;AAC5B,kBAAM,UAAU,YAAY,KAAK;AAEjC,kBAAM,cAAyB,CAAC,mBAAmB;AACjD,2CAAW,YAAY,SAAS,gBAAgB,OAAO;AAEvD,kBAAI,CAAC,YAAY;AACf,iCAAiB,cAAc;AAC/B;AAAA,cACF;AAEA,gCAAkB,YAAY;AAC5B,sBAAM,UAAU,UAAM;AAAA,kBACpB;AAAA,kBACA;AAAA,kBACA;AAAA,kBACAA;AAAA,gBACF;AACA,iCAAiB,OAAyB;AAAA,cAC5C,GAAG;AAAA,YACL;AAEA,kBAAM,UAAU;AAAA,UAClB;AAGA,cAAI,YAAY,WAAW,UAAU,CAAC,oBAAoB,MAAM;AAC9D,yCAAW,YAAY,YAAY,KAAK,MAAM,YAAY,KAAK,GAAG;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAIA,QAAI,gBAAgB,aAAa,SAAS,GAAG;AAC3C,eAAS,MAAM,QAAQ;AAAA,QACrB,OAAO,IAAI,OAAO,UAAU;AAAA,UAC1B,OAAO,UAAM;AAAA,YACX;AAAA,YACA,CAAC,OAAO,cAAc,IAAIA,UAAS;AAAA,YACnC,KAAK;AAAA,YACLA;AAAA,YACA,KAAK;AAAA,UACP;AAAA,UACA,QAAQ,KAAK;AAAA,QACf,EAAE;AAAA,MACJ;AAAA,IACF;AAKA,QAAI,aAA6B,EAAE,IAAI,KAAK;AAC5C,eAAW,QAAQ,QAAQ;AACzB,mBAAa,MAAM,aAAa,KAAK,OAAO;AAAA,QAC1C,GAAG;AAAA,QACH,IAAI;AAAA,QACJ,QAAQ,KAAK;AAAA,QACb,SAAS,MAAM;AAAA,QACf,SAAS;AAAA,QACT,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAMA,QAAI,eAAgB,OAAM;AAE1B,WAAO;AAAA,EACT;AAQA,QAAM,gBAAgB,OACpB,aACoB;AACpB,UAAM,YAAQ,2BAAa,QAAQ;AAOnC,UAAM,kBAAc;AAAA,UAClB,sBAAQ,QAAQ,IAAI,UAAU,SAAS,cAAc;AAAA,IACvD;AACA,QAAI,aAAa;AACf,YAAM,MAAM,QAAQ,YAAY;AAChC,YAAM,MAAM,gBAAgB,YAAY;AAAA,IAC1C;AACA,QAAI,CAAC,OAAO,UAAU,aAAa,OAAW,QAAO;AACrD,UAAM,YAAY,UAAM,8BAAgB,UAAU,OAAO,QAAQ;AAAA,MAC/D,WAAAA;AAAA,IACF,CAAC;AACD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAI;AAAA,MACJ,OAAO,MAAM;AAAA;AAAA,IACf;AAAA,EACF;AAOA,QAAM,cAAgC,OACpC,UACA,UAAiC,CAAC,MAC/B;AACH,UAAM,QAAQ;AAAA,MACZ,YAAQ,2BAAa,QAAQ;AAAA,MAC7B,SAAS;AAAA,IACX;AACA,WAAO,YAAY,UAAU,SAAS,KAAK;AAAA,EAC7C;AAGA,QAAM,gBAAgBA,WAAU,OAAO,MAAM,QAAQ,EAAE,MAAM,QAAQ;AAOrE,QAAM,WAAuB;AAAA,IAC3B,GAAG;AAAA,IACH,MAAM;AAAA,IACN,SAASA,WAAU;AAAA,IACnB,SAASA,WAAU;AAAA,IACnB,KAAKA,WAAU;AAAA,IACf,QAAQ;AAAA,EACV;AASA,QAAM,YAAyC,OAC7C,UACA,SACA,SACG;AACH,UAAM,QAA4D;AAAA,MAChE,QAAQ,MAAM,cAAc,QAAQ;AAAA,MACpC;AAAA,IACF;AACA,UAAM,YAA8B,CAAC,UAAU,UAAU,CAAC,MACxD,YAAY,UAAU,SAAS,KAAK;AACtC,UAAM,WAA4B;AAAA,MAChC,GAAG;AAAA,MACH,MAAM;AAAA,MACN,QAAQ,MAAM;AAAA,MACd,SAAS,MAAM;AAAA,IACjB;AACA,WAAO,KAAK,QAAQ;AAAA,EACtB;AAEA,QAAM,gBAAgC;AAAA,IACpC,WAAAA;AAAA,IACA,QAAQ;AAAA,IACR,IAAI;AAAA,IACJ;AAAA,IACA,KAAK;AAAA,IACL;AAAA,IACA,aAAa,iBAAiBA,YAAW,UAAU,UAAU,aAAa;AAAA,EAC5E;AAEA,QAAM,iBAAiB,UAAM;AAAA,IAC3B;AAAA,IACA,CAAC,QAA4B;AAC3B,UAAI,eAAe,wBAAY,OAAM;AACrC,MAAAA,WAAU,OAAO;AACjB,MAAAA,WAAU,OAAO,MAAM,QAAQ,EAAE,MAAM,yBAAyB;AAAA,QAC9D;AAAA,QACA,GAAG,UAAU,GAAG;AAAA,MAClB,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF,EAAE,aAAa;AACf,MAAI,CAAC,eAAgB,QAAO;AAE5B,QAAM,aAAa,eAAe,QAAQ;AAC1C,QAAM,eAAeA,WAAU,OAAO,MAAM,UAAU,EAAE,MAAM,QAAQ;AACtE,WAAS,SAAS;AAElB,MAAI,SAAS;AACX,mBAAe,SAAS,EAAE,GAAG,eAAe,QAAQ,QAAQ;AAAA,EAC9D;AAEA,SAAO;AACT;AAKA,eAAsB,YACpBA,YACA,UAA8B,CAAC,GACH;AAC5B,QAAM,SAA4B,CAAC;AAGnC,aAAW,CAAC,UAAU,gBAAgB,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClE,UAAM,iBAAiB,MAAM;AAAA,MAC3BA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,CAAC,eAAgB;AAMrB,UAAM,cAAc,iBAAiB,QAAQ;AAC7C,mBAAe,SAAS;AAAA,MACtB,GAAG,eAAe;AAAA,MAClB,MAAM;AAAA,MACN,GAAI,cAAc,EAAE,SAAS,CAAC,GAAG,WAAW,EAAE,IAAI,CAAC;AAAA,IACrD;AACA,WAAO,QAAQ,IAAI;AAAA,EACrB;AAIA,SAAO,OAAOA,WAAU,SAAS,MAAM;AAGvC,aAAW,YAAY,OAAO,KAAK,MAAM,GAAG;AAC1C,UAAM,WAAWA,WAAU,QAAQ,QAAQ;AAC3C,QAAI,aAAa;AACjB,QAAI,SAAS,MAAM;AACjB,gBAAM,4BAAc,SAAS,KAAK,KAAK,QAAQ,GAAG,CAAC,QAAiB;AAClE,YAAI,eAAe,wBAAY,OAAM;AACrC,qBAAa;AACb,QAAAA,WAAU,OAAO;AACjB,QAAAA,WAAU,OAAO,MAAM,QAAQ,EAAE,MAAM,sBAAsB;AAAA,UAC3D;AAAA,UACA,GAAG,UAAU,GAAG;AAAA,QAClB,CAAC;AAAA,MACH,CAAC,EAAE;AAAA,IACL;AAMA,QAAI,WAAY;AAChB,aAAS,OAAO,OAAO;AACvB,QAAI,gBAAgB,QAAQ,GAAG;AAC7B,YAAM,mBAAmBA,YAAW,UAAU,QAAQ;AAAA,IACxD;AAAA,EACF;AAQA,QAAM,iBAAiBA,UAAS;AAEhC,SAAO;AACT;;;AIphBA,eAAsB,iBACpBC,YACe;AAGf,aAAW,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQA,WAAU,OAAO,GAAG;AAClE,QAAI,gBAAgB,MAAM,EAAG;AAC7B,UAAMC,WAAU,OAAO,OAAO;AAC9B,QAAI,CAACA,UAAS,OAAQ;AAEtB,UAAM,YAAYA,SAAQ,OAAO,CAAC,MAAM,CAAC,mBAAmBD,YAAW,CAAC,CAAC;AACzE,QAAI,UAAU,WAAWC,SAAQ,OAAQ;AAEzC,WAAO,OAAO,UAAU;AACxB,QAAI,gBAAgB,MAAM,GAAG;AAC3B,YAAM,mBAAmBD,YAAW,QAAQ,QAAQ;AAAA,IACtD;AAAA,EACF;AAIA,aAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQA,WAAU,QAAQ,YAAY,GAAG;AACtE,QAAI,CAACA,WAAU,QAAQ,aAAa,EAAE,KAAKA,WAAU,aAAa,EAAE;AAClE;AAEF,UAAMC,WAAU,IAAI,QAAQ;AAC5B,QAAI,CAACA,SAAS;AAEd,UAAM,YAAYA,SAAQ,OAAO,CAAC,MAAM,CAAC,mBAAmBD,YAAW,CAAC,CAAC;AACzE,QAAI,IAAI,OAAQ,KAAI,OAAO,UAAU;AACrC,QAAI,UAAU,SAAS,EAAG;AAE1B,WAAOA,WAAU,QAAQ,aAAa,EAAE;AACxC,UAAM,WAAW,oBAAoB,GAAG;AACxC,QAAI,SAAS,OAAO,UAAU,OAAO;AACnC,eAAS,YAAY,CAAC,GAAGA,WAAU,KAAK;AAAA,IAC1C;AACA,IAAAA,WAAU,aAAa,EAAE,IAAI;AAC7B,UAAM,wBAAwBA,YAAW,UAAU,EAAE;AAAA,EACvD;AACF;;;AR7CA,SAAS,oBAAoB,OAA6C;AACxE,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,MAAI,EAAE,YAAY,OAAQ,QAAO;AACjC,QAAM,SAAS,MAAM;AACrB,MAAI,OAAO,WAAW,YAAY,WAAW,KAAM,QAAO;AAC1D,SAAO,WAAW,UAAU,OAAO,OAAO,UAAU;AACtD;AAQA,IAAI,wBAAwB;AAC5B,SAAS,sBAA4B;AACnC,MAAI,sBAAuB;AAC3B,0BAAwB;AACxB,MAAI,OAAO,YAAY,eAAe,OAAO,QAAQ,SAAS;AAC5D,YAAQ;AAAA,MACN;AAAA,IACF;AACJ;AAsBA,SAAS,mBACPE,YACA,MACA,OACA,OACM;AACN,MAAI,iBAAiB,wBAAY,OAAM;AACvC,EAAAA,WAAU,OAAO,MAAM,IAAI,EAAE,MAAM,sBAAsB;AAAA,IACvD;AAAA,IACA,GAAG;AAAA,IACH,GAAG,UAAU,KAAK;AAAA,EACpB,CAAC;AACH;AAQA,IAAM,cAAmC;AAAA,EACvC,MAAM,SAAS;AAAA,EACf,MAAM,SAAS;AAAA,EACf,MAAM,SAAS;AAAA,EACf,MAAM,SAAS;AACjB;AASO,SAAS,gBAAgB,MAAyB;AACvD,SAAO,YAAY,SAAS,IAAI;AAClC;AAcO,SAAS,eACdA,YACA,MACS;AACT,UAAQ,MAAM;AAAA,IACZ,KAAK,MAAM,SAAS;AAClB,aAAO,OAAO,KAAKA,WAAU,OAAO,EAAE,SAAS;AAAA,IACjD,KAAK,MAAM,SAAS;AAClB,aAAO,OAAO,KAAKA,WAAU,IAAI,EAAE,SAAS;AAAA,IAC9C,KAAK,MAAM,SAAS;AAClB,aAAO,OAAO,KAAKA,WAAU,OAAO,EAAE,SAAS;AAAA,IACjD,KAAK,MAAM,SAAS;AAClB,aAAO,OAAO,KAAKA,WAAU,MAAM,EAAE,SAAS;AAAA,IAChD;AACE,aAAO;AAAA,EACX;AACF;AAoBO,SAAS,mBACdA,YACA,MACS;AACT,UAAQ,MAAM;AAAA,IACZ,KAAK,MAAM,SAAS;AAAA,IACpB,KAAK,MAAM,SAAS;AAAA,IACpB,KAAK,MAAM,SAAS;AAAA,IACpB,KAAK,MAAM,SAAS;AAClB,aAAO,eAAeA,YAAW,IAAI;AAAA,IACvC,KAAK,MAAM,SAAS;AAAA,IACpB,KAAK,MAAM,SAAS;AAClB,aAAOA,WAAU,YAAY;AAAA,IAC/B;AACE,aAAOA,WAAU,WAAW,IAAI,OAAO,IAAI,CAAC;AAAA,EAChD;AACF;AAeA,SAAS,QACPA,YACA,YACA,MACQ;AACR,QAAM,QAAQA,WAAU,SAAS,IAAI,UAAU;AAC/C,QAAM,OAAO,QAAQ,OAAO,IAAI,CAAC;AACjC,SAAO,SAAS,SAAY,KAAK;AACnC;AAUA,SAAS,cAAcA,YAA+B,MAAwB;AAG5E,SAAOA,WAAU,cAAc,OAAO,IAAI,CAAC,KAAK;AAClD;AAMO,SAAS,QACdA,YACA,YACA,MACM;AACN,MAAI,QAAQA,WAAU,SAAS,IAAI,UAAU;AAC7C,MAAI,CAAC,OAAO;AACV,YAAQ,CAAC;AACT,IAAAA,WAAU,SAAS,IAAI,YAAY,KAAK;AAAA,EAC1C;AACA,QAAM,OAAO,IAAI,CAAC,IAAI,cAAcA,YAAW,IAAI;AACrD;AAOO,SAAS,cACdA,YACA,YACA,MACS;AACT,SACEA,WAAU,WACV,cAAcA,YAAW,IAAI,IAAI,QAAQA,YAAW,YAAY,IAAI;AAExE;AAgBA,IAAM,yBAAyB;AAexB,SAAS,aAAaA,YAA2C;AACtE,QAAM,OAAOA,WAAU;AAEvB,MAAI,QAAQ,CAAC,eAAe,IAAI,IAAI,EAAG,QAAO,MAAM;AAEpD,QAAM,UAAU,QAAQ,EAAE,QAAQ,oBAAI,QAAQ,EAAE;AAChD,EAAAA,WAAU,UAAU;AACpB,iBAAe,IAAI,UAAU,eAAe,IAAI,OAAO,KAAK,KAAK,CAAC;AAKlE,MAAI,OAAO;AACX,SAAO,MAAM;AACX,QAAI,KAAM;AACV,WAAO;AACP,UAAM,WAAW,eAAe,IAAI,OAAO,KAAK,KAAK;AACrD,QAAI,UAAU,GAAG;AACf,qBAAe,IAAI,SAAS,OAAO;AACnC;AAAA,IACF;AACA,mBAAe,OAAO,OAAO;AAC7B,QAAIA,WAAU,YAAY,QAAS,CAAAA,WAAU,UAAU;AAAA,EACzD;AACF;AAGA,IAAM,iBAAiB,oBAAI,QAAmC;AAY9D,SAAS,aACPA,YACA,YACA,MACS;AACT,QAAM,UAAUA,WAAU;AAC1B,MAAI,CAAC,QAAS,QAAO;AAErB,MAAI,SAAS,QAAQ,OAAO,IAAI,UAAU;AAC1C,MAAI,CAAC,QAAQ;AACX,aAAS,CAAC;AACV,YAAQ,OAAO,IAAI,YAAY,MAAM;AAAA,EACvC;AAEA,QAAM,MAAM,OAAO,IAAI;AACvB,QAAM,QAAQ,OAAO,GAAG,KAAK,KAAK;AAClC,SAAO,GAAG,IAAI;AAEd,MAAI,QAAQ,uBAAwB,QAAO;AAK3C,MAAI,SAAS,yBAAyB;AACpC,IAAAA,WAAU,OAAO,MAAM,mCAAmC,EAAE,MAAM,IAAI,CAAC;AAEzE,SAAO;AACT;AAMA,SAAS,eACPA,YACA,MACY;AACZ,SAAO;AAAA,IACL,WAAAA;AAAA,IACA,QAAQA,WAAU,OAAO,MAAM,IAAI,EAAE,MAAM,OAAO,IAAI,CAAC;AAAA,EACzD;AACF;AASA,eAAsB,GACpBA,YACA,MACA,QACA;AAMA,MAAI,CAAC,oBAAoBA,UAAS,GAAG;AACnC,wBAAoB;AACpB;AAAA,EACF;AAEA,QAAMC,MAAKD,WAAU;AACrB,QAAM,SAAiCC,IAAG,IAAI,KAAK,CAAC;AACpD,QAAM,cAAU,sBAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAElD,UAAQ,QAAQ,CAACC,YAAW;AAC1B,WAAO,KAAKA,OAAM;AAAA,EACpB,CAAC;AAGD,EAACD,IAAG,IAAI,IAAsB;AAG9B,gBAAcD,YAAW,MAAM,OAAO;AACxC;AA+BA,eAAsB,kBACpBA,YACA,aACA,QACA,MACA,MACkB;AAClB,QAAM,UAAU,YAAY;AAC5B,MAAI,CAAC,QAAS,QAAO;AAKrB,QAAM,QAAQ,gBAAgB,IAAI;AAMlC,MACE,UACC,kBAAkB,IAAI,WAAW,KAAK,WAAW,IAAI,WAAW,IACjE;AACA,kBAAcA,YAAW,aAAa,IAAI;AAC1C,QAAI,CAAC,kBAAkB,IAAI,WAAW;AACpC,yBAAmB,IAAI,WAAW;AACpC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,QAAQ,cAAcA,YAAW,IAAI,IAAI;AACzD,QAAM,UACJ,SAAS,kBAAkBA,YAAW,aAAa,MAAM,OAAO,IAC5D,oBAAoBA,YAAW,IAAI,IACnC;AAEN,QAAM,WAAW,YAAY,QAAQ;AACrC,QAAM,aAAaA,WAAU,OAAO,MAAM,QAAQ,EAAE,MAAM,IAAI,EAAE,MAAM,IAAI;AAE1E,QAAM,UAA+B;AAAA,IACnC,WAAAA;AAAA,IACA,QAAQ;AAAA,IACR,IAAI;AAAA,IACJ,QAAQ,YAAY;AAAA,IACpB,MAAM;AAAA,IACN,KAAK,kBAAkB,YAAY,KAAK,YAAY,OAAO,GAAG;AAAA,IAC9D,aAAa;AAAA,MACXA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAKA,MAAI,OAAO;AACT,sBAAkB,aAAa,IAAI;AACnC,uBAAmB,aAAa,MAAM,OAAO;AAC7C,eAAW,IAAI,WAAW;AAAA,EAC5B;AAEA,QAAM,YAAY,0BAA0B,YAAY,OAAO,OAAO;AAEtE,MAAI,UAA4B,QAAQ,QAAQ;AAChD,MAAI,UAAU;AACd,MAAI,WAAW;AACf,MAAI,QAAQ;AACZ,MAAI;AACF,cAAM;AAAA,MACJ,MAAM;AACJ,kBAAU,QAAQ,QAAQ,QAAQ,MAAM,OAAO,CAAC;AAChD,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,gBAAgB,MAAM,QAAQ,IAAI,2BAA2B,SAAS;AAAA,QACxE;AAAA,MACF;AAAA,MACA,CAAC,QAAQ;AACP,kBAAU;AACV,YAAI,eAAe,wBAAyB,YAAW;AACvD,2BAAmBA,YAAW,eAAe,KAAK,EAAE,QAAQ,KAAK,CAAC;AAAA,MACpE;AAAA,IACF,EAAE;AACF,YAAQ;AAAA,EACV,UAAE;AAIA,QAAI,OAAO;AACT,iBAAW,OAAO,WAAW;AAC7B,UAAI,MAAO,oBAAmB,OAAO,WAAW;AAChD,YAAM,OAAO,UAAU,IAAI,WAAW;AACtC,UAAI,SAAS;AACX,oBAAYA,YAAW,aAAa,MAAM,OAAO;AACjD,cAAM,OAAO,OAAO,IAAI,CAAC;AAAA,MAC3B,OAAO;AACL,sBAAcA,YAAW,aAAa,IAAI;AAAA,MAC5C;AACA,UAAI,UAAU;AACZ;AAAA,UACEA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,OAAO;AACL,6BAAqB,aAAa,MAAM,OAAO;AAC/C,2BAAmBA,YAAW,WAAW;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAGA,MAAI,SAAS,CAAC,YAAY,mBAAmB,OAAO,WAAW;AAC7D,UAAM,wBAAwBA,YAAW,aAAa,MAAM;AAE9D,SAAO;AACT;AAMA,IAAM,oBAAoB,oBAAI,QAAsC;AAMpE,IAAM,aAAa,oBAAI,QAA8B;AAMrD,IAAM,qBAAqB,oBAAI,QAA8B;AAU7D,SAAS,qBACPA,YACA,aACA,QACA,MACA,SACA,SACA,QACM;AACN,oBAAkB;AAAA,IAChB;AAAA,KACC,kBAAkB,IAAI,WAAW,KAAK,KAAK;AAAA,EAC9C;AACA,QAAM,SAAS,MAAM;AACnB,UAAM,SAAS,kBAAkB,IAAI,WAAW,KAAK,KAAK;AAC1D,QAAI,QAAQ,EAAG,mBAAkB,IAAI,aAAa,KAAK;AAAA,QAClD,mBAAkB,OAAO,WAAW;AACzC,UAAM,OAAO,UAAU,IAAI,WAAW;AACtC,QAAI,KAAM,MAAK,IAAI,OAAO,IAAI,CAAC;AAAA,QAC1B,WAAU,IAAI,aAAa,oBAAI,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;AACvD,yBAAqB,aAAa,MAAM,OAAO;AAC/C,uBAAmBA,YAAW,WAAW;AACzC,WAAO,MAAM,2BAA2B;AACxC,uBAAmB,OAAO,WAAW;AACrC,QAAIA,WAAU,WAAWA,WAAU,aAAa,MAAM,MAAM;AAC1D,8BAAwBA,YAAW,aAAa,QAAQ,MAAM;AAAA,EAClE;AACA,UAAQ,KAAK,QAAQ,MAAM;AAC7B;AAMA,SAAS,wBACPA,YACA,aACA,QACA,QACM;AACN;AAAA,IACE,YAAY;AACV,YAAM,wBAAwBA,YAAW,aAAa,MAAM;AAC5D,UAAI,CAAC,aAAa,WAAW,KAAK,YAAY,WAAW;AACvD,cAAM;AAAA,UACJA;AAAA,UACA;AAAA,UACA,CAAC;AAAA,UACD;AAAA,YACE,CAAC,MAAM,GAAG;AAAA,UACZ;AAAA,QACF;AAAA,IACJ;AAAA,IACA,CAAC,QAAQ;AACP,aAAO,MAAM,yBAAyB,UAAU,GAAG,CAAC;AAAA,IACtD;AAAA,EACF,EAAE;AACJ;AAcA,IAAM,aAAa,oBAAI,QAAyC;AAGzD,SAAS,aACd,aACuB;AACvB,SAAO,WAAW,IAAI,WAAW;AACnC;AAMA,IAAM,gBAAgB,oBAAI,QAAsC;AAMhE,IAAM,mBAAmB,oBAAI,QAG3B;AAEF,SAAS,mBACP,aACA,MACA,SACM;AACN,MAAI,WAAW,iBAAiB,IAAI,WAAW;AAC/C,MAAI,CAAC,UAAU;AACb,eAAW,CAAC;AACZ,qBAAiB,IAAI,aAAa,QAAQ;AAAA,EAC5C;AACA,QAAM,MAAM,OAAO,IAAI;AACvB,QAAM,UAAU,SAAS,GAAG;AAC5B,MAAI,YAAY,UAAa,UAAU,QAAS,UAAS,GAAG,IAAI;AAClE;AAEA,SAAS,qBACP,aACA,MACA,SACM;AACN,QAAM,WAAW,iBAAiB,IAAI,WAAW;AACjD,MAAI,YAAY,SAAS,OAAO,IAAI,CAAC,MAAM;AACzC,WAAO,SAAS,OAAO,IAAI,CAAC;AAChC;AAOA,IAAM,YAAY,oBAAI,QAA2C;AAMjE,IAAM,cAAc,oBAAI,QAAiD;AAQlE,SAAS,eAAe,aAAyC;AACtE,QAAM,QAAQ,YAAY,SAAS,KAAK,CAAC,EAAE,KAAK,MAAM,gBAAgB,IAAI,CAAC;AAC3E,MAAI,MAAO,mBAAkB,aAAa,MAAM,IAAI;AACpD,cAAY,IAAI,aAAa,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC;AAChD;AAGO,SAAS,aACdA,YACA,aACM;AACN,QAAM,QAAQ,YAAY,IAAI,WAAW;AACzC,cAAY,OAAO,WAAW;AAC9B,MAAI,OAAO,KAAM,oBAAmBA,YAAW,WAAW;AAC5D;AASO,SAAS,cACdA,YACA,aACA,MACM;AACN,YAAUA,YAAW,aAAa,IAAI;AACtC,QAAM,OAAO,UAAU,IAAI,WAAW;AACtC,MAAI,KAAM,MAAK,IAAI,OAAO,IAAI,CAAC;AAAA,MAC1B,WAAU,IAAI,aAAa,oBAAI,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;AACvD,aAAW,IAAI,aAAa,EAAE,MAAM,OAAO,KAAK,IAAI,EAAE,CAAC;AACzD;AAOO,SAAS,qBACdA,YACA,aACS;AACT,MAAI,UAAU,IAAI,WAAW,GAAG,KAAM,QAAO;AAC7C,SAAO,YAAY;AAAA,IACjB,CAAC,SACC,eAAeA,YAAW,IAAI,KAC9B,cAAcA,YAAW,aAAa,IAAI;AAAA,EAC9C;AACF;AAQO,SAAS,kBACd,aACA,MACM;AACN,gBAAc,IAAI,cAAc,cAAc,IAAI,WAAW,KAAK,KAAK,CAAC;AACxE,aAAW,IAAI,aAAa,EAAE,MAAM,OAAO,KAAK,IAAI,EAAE,CAAC;AACzD;AAMO,SAAS,mBACdA,YACA,aACM;AACN,QAAM,SAAS,cAAc,IAAI,WAAW,KAAK,KAAK;AACtD,MAAI,QAAQ,EAAG,eAAc,IAAI,aAAa,KAAK;AAAA,MAC9C,eAAc,OAAO,WAAW;AACrC,uBAAqBA,YAAW,WAAW;AAC7C;AAUA,SAAS,kBACPA,YACA,aACA,MACA,SACS;AACT,MAAI,UAAU,IAAI,WAAW,GAAG,IAAI,OAAO,IAAI,CAAC,EAAG,QAAO;AAC1D,QAAM,OAAOA,WAAU,UAAU,IAAI,WAAW,IAAI,OAAO,IAAI,CAAC;AAChE,SAAO,SAAS,UAAa,OAAO,UAAU;AAChD;AAOA,SAAS,YACPA,YACA,YACA,MACA,SACM;AACN,MAAI,QAAQA,WAAU,SAAS,IAAI,UAAU;AAC7C,MAAI,CAAC,OAAO;AACV,YAAQ,CAAC;AACT,IAAAA,WAAU,SAAS,IAAI,YAAY,KAAK;AAAA,EAC1C;AACA,QAAM,MAAM,OAAO,IAAI;AACvB,QAAM,UAAU,MAAM,GAAG;AACzB,MAAI,YAAY,UAAa,UAAU,QAAS,OAAM,GAAG,IAAI;AAC/D;AAQO,SAAS,UACdA,YACA,YACA,MACM;AAGN,QAAM,QAAQA,WAAU,UAAU,IAAI,UAAU;AAChD,MAAI,MAAO,QAAO,MAAM,OAAO,IAAI,CAAC;AACtC;AASA,SAAS,qBACPA,YACA,aACM;AACN,MAAI,CAAC,WAAW,IAAI,WAAW,EAAG;AAClC,MAAI,cAAc,IAAI,WAAW,EAAG;AACpC,MAAI,UAAU,IAAI,WAAW,GAAG,KAAM;AACtC,QAAM,OAAO,YAAY;AAAA,IACvB,CAAC,SACC,eAAeA,YAAW,IAAI,KAC9B,cAAcA,YAAW,aAAa,IAAI;AAAA,EAC9C;AACA,MAAI,CAAC,KAAM,YAAW,OAAO,WAAW;AAC1C;AAYO,SAAS,cACdA,YACA,MACA,SACA,QACM;AASN,MAAI,CAAC,oBAAoBA,UAAS,GAAG;AACnC,wBAAoB;AACpB;AAAA,EACF;AAGA,QAAM,cAAc,oBAAoBA,YAAW,MAAM,MAAM;AAE/D,MAAI,CAAC,QAAQ,OAAQ;AAErB,UAAQ,MAAM;AAAA,IACZ,KAAK,MAAM,SAAS;AAClB;AAAA,QACEA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF,KAAK,MAAM,SAAS;AAClB,cAAQA,YAAW,OAA4B;AAC/C;AAAA,IACF,KAAK,MAAM,SAAS;AAClB,YAAMA,YAAW,OAA0B;AAC3C;AAAA,IACF,KAAK,MAAM,SAAS;AAClB,gBAAUA,YAAW,OAA8B;AACnD;AAAA,IACF,SAAS;AAEP,YAAM,MAAM,eAAeA,YAAW,IAAI;AAC1C,YAAM,QAAQ,gBAAgB,IAAI;AAClC,cAAQ,QAAQ,CAAC,SAAS;AACxB,YAAI,OAAO,SAAS,WAAY;AAIhC,YAAI,SAAS,CAAC,cAAcA,YAAW,MAAM,IAAI,EAAG;AAIpD,YAAI,SAAS,CAAC,aAAaA,YAAW,MAAM,IAAI,EAAG;AACnD;AAAA,UAAS;AAAA,UAAsB,CAAC,QAC9B,mBAAmBA,YAAW,WAAW,KAAK,EAAE,KAAK,CAAC;AAAA,QACxD,EAAE,aAAa,GAAG;AAClB,YAAI,MAAO,SAAQA,YAAW,MAAM,IAAI;AAAA,MAC1C,CAAC;AACD;AAAA,IACF;AAAA,EACF;AACF;AAQA,SAAS,oBACPA,YACA,MACA,QACS;AACT,UAAQ,MAAM;AAAA,IACZ,KAAK,MAAM,SAAS;AAClB,aAAO,UAAUA,WAAU;AAAA,IAC7B,KAAK,MAAM,SAAS;AAClB,aAAOA,WAAU;AAAA,IACnB,KAAK,MAAM,SAAS;AAClB,aAAO,UAAUA,WAAU;AAAA,IAC7B,KAAK,MAAM,SAAS;AAClB,aAAO,UAAUA,WAAU;AAAA,IAC7B,KAAK,MAAM,SAAS;AAClB,aAAO,UAAUA,WAAU;AAAA,IAC7B,KAAK,MAAM,SAAS;AAClB,aAAO,UAAUA,WAAU;AAAA,IAC7B;AACE,aAAO;AAAA,EACX;AACF;AAWA,eAAe,qBACbA,YACA,QACA,UACA,MACA,aACkB;AAClB,MAAI,CAAC,OAAO,GAAI,QAAO;AAMvB,MAAI,gBAAgB,IAAI,KAAK,CAAC,cAAcA,YAAW,QAAQ,IAAI;AACjE,WAAO;AAKT,MAAI,gBAAgB,IAAI,KAAK,CAAC,aAAaA,YAAW,QAAQ,IAAI;AAChE,WAAO;AAKT,QAAM,QAAQ,gBAAgB,IAAI;AAClC,MAAI,SAAS,iBAAiB,IAAI,MAAM,GAAG;AACzC,wBAAoB,IAAI,MAAM;AAC9B,WAAO;AAAA,EACT;AACA,QAAM,UAAU,QAAQ,cAAcA,YAAW,IAAI,IAAI;AACzD,MAAI,MAAO,kBAAiB,IAAI,MAAM;AAItC,QAAM,UAAU,OAAO;AACvB,MAAI,UAA4B,QAAQ,QAAQ;AAChD,MAAI,WAAW;AACf,MAAI;AACJ,MAAI;AACF,aAAS,UAAM;AAAA,MACb,MAAM;AACJ,kBAAU,QAAQ,QAAQ,QAAQ,MAAM,WAAW,CAAC;AACpD,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,WAAW,QAAQ,QAAQ,IAAI,2BAA2B,8BAA8B;AAAA,QAC1F;AAAA,MACF;AAAA,MACA,CAAC,QAAQ;AACP,YAAI,eAAe,wBAAyB,YAAW;AACvD,2BAAmBA,YAAW,UAAU,KAAK,EAAE,UAAU,KAAK,CAAC;AAAA,MACjE;AAAA,IACF,EAAE;AAAA,EACJ,UAAE;AAEA,QAAI,SAAS,CAAC,SAAU,kBAAiB,OAAO,MAAM;AAAA,EACxD;AAEA,MAAI,OAAO;AACT,QAAI,UAAU;AAGZ,YAAM,SAAS,MAAM;AACnB,yBAAiB,OAAO,MAAM;AAC9B,4BAAoB,OAAO,MAAM;AACjC,YAAIA,WAAU,WAAWA,WAAU,QAAQ,QAAQ,MAAM;AACvD;AAAA,YACE,MAAM,mBAAmBA,YAAW,QAAQ,QAAQ;AAAA,YACpD,CAAC,QAAQ;AACP,cAAAA,WAAU,OACP,MAAM,IAAI,EACV,MAAM,yBAAyB,UAAU,GAAG,CAAC;AAAA,YAClD;AAAA,UACF,EAAE;AAAA,MACN;AACA,cAAQ,KAAK,QAAQ,MAAM;AAAA,IAC7B,OAAO;AACL,kBAAYA,YAAW,QAAQ,MAAM,OAAO;AAC5C,UAAI,oBAAoB,OAAO,MAAM;AACnC,cAAM,mBAAmBA,YAAW,QAAQ,QAAQ;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,WAAW;AACpB;AAGA,IAAM,mBAAmB,oBAAI,QAAyB;AAGtD,IAAM,sBAAsB,oBAAI,QAAyB;AAGzD,eAAe,mBACbA,YACA,QACA,UACe;AAIf,QAAM,cAAc,aAAaA,UAAS;AAC1C,MAAI;AACF,eAAW,QAAQ,aAAa;AAC9B,YAAM;AAAA,QACJA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,oBAAoBA,YAAW,IAAI;AAAA,MACrC;AAAA,IACF;AAAA,EACF,UAAE;AACA,gBAAY;AAAA,EACd;AACF;AAmBA,eAAsB,0BACpBA,YACA,aACA,QACA,MACA,MACe;AACf,MAAI,CAAC,YAAY,GAAI;AAErB,QAAM,QAAQ,gBAAgB,IAAI;AAClC,MAAI,SAAS,CAAC,cAAcA,YAAW,aAAa,IAAI,EAAG;AAE3D,QAAM,WAAW,iBAAiB,IAAI,WAAW,IAAI,OAAO,IAAI,CAAC;AACjE,MACE,SACA,aAAa,UACb,YAAY,cAAcA,YAAW,IAAI;AAEzC;AAOF,MAAI,SAAS,CAAC,aAAaA,YAAW,aAAa,IAAI,GAAG;AACxD,QAAI,YAAY,OAAO,MAAM;AAC3B,oBAAcA,YAAW,aAAa,IAAI;AAC1C;AAAA,IACF;AACA,UAAM,QAAS,YAAY,UAAU,YAAY,WAAW,CAAC;AAC7D,UAAM,QAAQ,EAAE,MAAM,MAAM,oBAAoBA,YAAW,IAAI,EAAE;AACjE,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,QAAI,QAAQ,KAAK,SAAS,KAAM,OAAM,MAAM,SAAS,CAAC,IAAI;AAAA,QACrD,OAAM,KAAK,KAAK;AACrB,YAAQA,YAAW,aAAa,IAAI;AACpC,cAAU,IAAI,WAAW,GAAG,OAAO,OAAO,IAAI,CAAC;AAC/C;AAAA,EACF;AAIA,QAAM,QAAQ,YAAY,IAAI,WAAW;AACzC,MAAI,CAAC,YAAY,OAAO,QAAQ,OAAO;AACrC,gBAAY,UAAU,YAAY,WAAW,CAAC;AAC9C,gBAAY,QAAQ,KAAK,EAAE,MAAM,KAAK,CAAC;AACvC,QAAI,OAAO;AACT,cAAQA,YAAW,aAAa,IAAI;AAGpC,UAAI,SAAS,CAAC,MAAM,MAAM;AACxB,0BAAkB,aAAa,IAAI;AACnC,cAAM,OAAO;AAAA,MACf;AAAA,IACF;AACA;AAAA,EACF;AAEA,QAAM,kBAAkBA,YAAW,aAAa,QAAQ,MAAM,IAAI;AACpE;AAYA,eAAsB,wBACpBA,YACA,aACA,QACe;AACf,MAAI,CAAC,YAAY,GAAI;AAGrB,QAAM,cAAc,aAAaA,UAAS;AAC1C,MAAI;AACF,eAAW,QAAQ,aAAa;AAI9B,UACE,CAAC,eAAeA,YAAW,IAAI,KAC/B,CAAC,UAAU,IAAI,WAAW,GAAG,IAAI,OAAO,IAAI,CAAC;AAE7C;AACF,YAAM;AAAA,QACJA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,oBAAoBA,YAAW,IAAI;AAAA,MACrC;AAAA,IACF;AAAA,EACF,UAAE;AACA,gBAAY;AAAA,EACd;AACF;AAMO,SAAS,wBACd,aACS;AACT,UAAQ,cAAc,IAAI,WAAW,KAAK,KAAK;AACjD;AAiBA,eAAsB,oBACpBA,YACe;AACf,QAAM,aAAa,MAAM,mBAAmBA,UAAS;AACrD,QAAM,QAAQ,IAAI,WAAW,IAAI,CAAC,EAAE,KAAK,MAAM,IAAI,CAAC;AACtD;AASA,eAAsB,mBACpBA,YACgC;AAKhC,MAAI,CAAC,oBAAoBA,UAAS,GAAG;AACnC,wBAAoB;AACpB,WAAO,CAAC;AAAA,EACV;AAIA,QAAM,aAAoC,CAAC;AAC3C,aAAW,CAAC,QAAQ,WAAW,KAAK,OAAO,QAAQA,WAAU,YAAY,GAAG;AAC1E,QAAI,CAAC,YAAY,GAAI;AACrB,UAAM,WAAW,YAAY;AAC3B,iBAAW,QAAQ,aAAa;AAC9B,YAAI,CAAC,eAAeA,YAAW,IAAI,EAAG;AACtC,cAAM;AAAA,UACJA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,oBAAoBA,YAAW,IAAI;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AACA,eAAW,KAAK,cAAc,QAAQ,aAAa,SAAS,CAAC,CAAC;AAAA,EAChE;AAEA,aAAW,QAAQ,aAAa;AAC9B,QAAI,CAAC,eAAeA,YAAW,IAAI,EAAG;AAEtC,UAAM,cAAc,oBAAoBA,YAAW,IAAI;AAIvD,kBAAcA,YAAW,MAAMA,WAAU,GAAG,IAAI,KAAK,CAAC,CAAC;AAIvD,UAAM,QAAQ;AAAA,MACZ,OAAO,QAAQA,WAAU,OAAO,EAC7B,OAAO,CAAC,CAAC,EAAE,MAAM,MAAM,gBAAgB,MAAM,CAAC,EAC9C;AAAA,QAAI,CAAC,CAAC,UAAU,MAAM,MACrB,qBAAqBA,YAAW,QAAQ,UAAU,MAAM,WAAW;AAAA,MACrE;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AACT;AAUA,eAAsB,QACpBA,YACA,MACA,SACA,QACkB;AAClB,QAAM,EAAE,IAAI,WAAW,IAAI,MAAM;AAAA,IAC/BA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,WAAW,IAAI,CAAC,EAAE,KAAK,MAAM,IAAI,CAAC;AACpD,SAAO;AACT;AAoBA,SAAS,cACP,IACA,aACA,MACqB;AACrB,OAAK,MAAM,MAAM,MAAS;AAC1B,SAAO,EAAE,IAAI,aAAa,KAAK;AACjC;AASA,eAAsB,gBACpBA,YACA,MACA,SACA,QAC6D;AAM7D,MAAI,CAAC,oBAAoBA,UAAS,GAAG;AACnC,wBAAoB;AACpB,WAAO,EAAE,IAAI,MAAM,YAAY,CAAC,EAAE;AAAA,EACpC;AAKA,EAAAA,WAAU,WAAW,IAAI,OAAO,IAAI,CAAC;AAGrC,MAAI,WAAW,WAAW,CAAC;AAE3B,MAAI,CAAC,SAAS;AAEZ,eAAWA,WAAU,GAAG,IAAI,KAAK,CAAC;AAAA,EACpC;AAGA,QAAM,cAAc,oBAAoBA,YAAW,MAAM,MAAM;AAO/D,QAAM,mBAA4C,CAAC;AACnD,aAAW,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQA,WAAU,OAAO,GAAG;AAClE,QAAI,OAAO,OAAO,SAAS,QAAQ;AACjC,YAAM,MAAM,OAAO,OAAO,QAAQ,QAAQ,IAAI;AAC9C,UAAI,QAAQ,GAAI,QAAO,OAAO,QAAQ,OAAO,KAAK,CAAC;AAAA,IACrD;AAEA,QAAI,CAAC,OAAO,GAAI;AAEhB,QAAI,gBAAgB,MAAM,GAAG;AAC3B,uBAAiB;AAAA,QACf,qBAAqBA,YAAW,QAAQ,UAAU,MAAM,WAAW;AAAA,MACrE;AAAA,IACF,OAAO;AACL,aAAO,UAAU,OAAO,WAAW,CAAC;AACpC,aAAO,QAAQ,KAAK,EAAE,MAAM,MAAM,YAAY,CAAC;AAAA,IACjD;AAAA,EACF;AAKA,QAAM,aAAoC,CAAC;AAC3C,aAAW,CAAC,QAAQ,WAAW,KAAK,OAAO,QAAQA,WAAU,YAAY,GAAG;AAC1E,QAAI,CAAC,YAAY,GAAI;AACrB,eAAW;AAAA,MACT;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,UACEA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAOA,MAAI,SAAS;AACb,MAAI,iBAAiB,QAAQ;AAC3B,UAAM,eAAe,MAAM,QAAQ,IAAI,gBAAgB;AACvD,aAAS,aAAa,KAAK,OAAO;AAAA,EACpC;AAKA,aAAW,CAAC,UAAU,MAAM,KAAK,OAAO,QAAQA,WAAU,OAAO,GAAG;AAClE,QAAI,gBAAgB,MAAM,KAAK,OAAO,SAAS,QAAQ;AACrD,YAAM,mBAAmBA,YAAW,QAAQ,QAAQ;AAAA,IACtD;AAAA,EACF;AAWA,QAAM,qBAAqB,OAAO,OAAOA,WAAU,OAAO,EAAE;AAAA,IAC1D,CAAC,WAAW,CAAC,gBAAgB,MAAM,KAAK,OAAO,OAAO,SAAS;AAAA,EACjE;AACA,MACE,OAAO,KAAKA,WAAU,QAAQ,YAAY,EAAE,SAAS,KACrD,oBACA;AACA,UAAM,iBAAiBA,UAAS;AAAA,EAClC;AAEA,gBAAcA,YAAW,MAAM,UAAU,MAAM;AAE/C,SAAO,EAAE,IAAI,CAAC,QAAQ,WAAW;AACnC;AAEA,SAAS,UACPA,YACA,UACA,gBACM;AACN,QAAM,eAAe,kBAAkBA,WAAU;AACjD,QAAM,MAAM,eAAeA,YAAW,MAAM,SAAS,OAAO;AAE5D,WAAS,QAAQ,CAAC,SAAS;AAIzB,QAAI,CAAC,cAAcA,YAAW,MAAM,MAAM,SAAS,OAAO,EAAG;AAK7D,QAAI,CAAC,aAAaA,YAAW,MAAM,MAAM,SAAS,OAAO,EAAG;AAG5D,WAAO,KAAK,YAAY,EACrB,OAAO,CAAC,QAAQ,OAAO,IAAI,EAC3B,QAAQ,CAAC,QAAQ;AAChB;AAAA,QAAS,KAAK,GAAG;AAAA,QAAG,CAAC,QACnB,mBAAmBA,YAAW,WAAW,KAAK,EAAE,IAAI,CAAC;AAAA,MACvD,EAAE,cAAc,GAAG;AAAA,IACrB,CAAC;AAGH,YAAQA,YAAW,MAAM,MAAM,SAAS,OAAO;AAAA,EACjD,CAAC;AACH;AAEA,SAAS,QACPA,YACA,UACM;AACN,MAAI,CAACA,WAAU,QAAS;AACxB,QAAM,MAAM,eAAeA,YAAW,MAAM,SAAS,KAAK;AAC1D,WAAS,QAAQ,CAAC,SAAS;AACzB,+BAAS,MAAM,CAAC,QAAQ,mBAAmBA,YAAW,SAAS,GAAG,CAAC;AAAA,MACjE;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,MAAMA,YAA+B,UAAiC;AAC7E,MAAI,CAACA,WAAU,QAAS;AACxB,QAAM,MAAM,eAAeA,YAAW,MAAM,SAAS,GAAG;AACxD,WAAS,QAAQ,CAAC,SAAS;AACzB,+BAAS,MAAM,CAAC,QAAQ,mBAAmBA,YAAW,OAAO,GAAG,CAAC;AAAA,MAC/D;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,UACPA,YACA,UACM;AACN,MAAI,CAACA,WAAU,QAAS;AACxB,QAAM,MAAM,eAAeA,YAAW,MAAM,SAAS,OAAO;AAC5D,WAAS,QAAQ,CAAC,SAAS;AACzB,+BAAS,MAAM,CAAC,QAAQ,mBAAmBA,YAAW,WAAW,GAAG,CAAC;AAAA,MACnEA,WAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AJz9CA,IAAM,oBAAoB;AAE1B,IAAM,qBAAqB;AAE3B,IAAM,oBAAoB;AAU1B,IAAM,iBAAoC,OAAO,OAAO,EAAE,SAAS,KAAK,CAAC;AAEzE,SAAS,gBAAgB,OAAyB;AAChD,SAAO,UAAU;AACnB;AAOA,SAAS,eAAe,OAAmD;AACzE,aACE,uBAAS,KAAK,KAAK,MAAM,QAAS,MAA+B,MAAM;AAE3E;AAUA,IAAM,gBAAgB;AAOtB,SAAS,sBACP,OACgD;AAChD,MAAI,UAAU,OAAW,QAAO,CAAC;AACjC,MAAI,OAAO,UAAU,SAAU,QAAO,EAAE,MAAM,MAAM;AACpD,SAAO,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,KAAK,MAAM,IAAI;AAC9D;AASA,eAAsB,eACpBG,YACA,MACyB;AACzB,QAAM;AAAA,IACJ;AAAA,IACA,QAAQ,aAAa,CAAC;AAAA,IACtB,MAAM,CAAC;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAGJ,MAAI,KAAC,yBAAW,KAAK,IAAI,GAAG;AAC1B,WAAO,iBAAiB;AAAA,MACtB,IAAI;AAAA,MACJ,QAAQ;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAKA,QAAM,aAAa,EAAE,GAAG,KAAK,QAAQ,GAAI,cAAc,EAAE,MAAM,MAAM,EAAG;AAExE,MAAI,SAAS,SAAS,EAAE,GAAG,YAAY,OAAO,IAAI,EAAE,GAAG,WAAW;AAClE,MAAI,KAAM,UAAS,EAAE,GAAG,QAAQ,KAAK;AACrC,MAAI,MAAO,UAAS,EAAE,GAAG,QAAQ,MAAM;AACvC,MAAI,UAAU,UAAa,OAAO,UAAU;AAC1C,aAAS,EAAE,GAAG,QAAQ,MAAM;AAE9B,MAAI,KAAK,OAAO;AAChB,MAAI,CAAC,IAAI;AAEP,OAAG;AACD,eAAK,oBAAM,GAAG,4BAA4B;AAAA,IAC5C,SAASA,WAAU,aAAa,EAAE,KAAKA,WAAU,QAAQ,aAAa,EAAE;AAAA,EAC1E;AAQA,MAAI,OAAO,SAAS,QAAQ;AAI1B,IAAAA,WAAU,QAAQ,aAAa,EAAE,IAAI;AACrC,UAAM,iBAAiBA,UAAS;AAChC,UAAM,YAAYA,WAAU,aAAa,EAAE;AAC3C,QAAI,WAAW;AACb,aAAO,mBAAmBA,YAAW,QAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC;AAAA,IACzE;AACA,WAAO,iBAAiB,EAAE,IAAI,KAAK,CAAC;AAAA,EACtC;AAEA,QAAM,cAAoC;AAAA,IACxC,GAAG;AAAA,IACH;AAAA,IACA,KAAK,kBAAkB,KAAK,KAAK,GAAG;AAAA,EACtC;AAGA,EAAAA,WAAU,aAAa,EAAE,IAAI;AAG7B,MAAI,YAAY,OAAO,UAAU;AAC/B,gBAAY,YAAY,CAAC,GAAGA,WAAU,KAAK;AAK7C,QAAM,wBAAwBA,YAAW,aAAa,EAAE;AAExD,SAAO,mBAAmBA,YAAW,QAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,YAAY,CAAC;AAC3E;AAMO,SAAS,iBAAiB,YAAyC;AACxE,aAAW,YAAY;AACrB,QAAI,aAAa,SAAS,WAAW,EAAG,UAAS,QAAQ;AAC7D;AASA,eAAsB,4BACpBA,YACA,YAC2B;AAC3B,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,WAAW,IAAI,OAAO,EAAE,IAAI,aAAa,MAAM,MAAM,MAAM;AACzD,YAAM;AACN,UACE,SACAA,WAAU,WACV,CAAC,aAAa,WAAW,KACzB,YAAY,WAAW,UACvBA,WAAU,aAAa,EAAE,MAAM;AAE/B,eAAO;AAAA,UACLA;AAAA,UACA;AAAA,UACA,CAAC;AAAA,UACD,EAAE,CAAC,EAAE,GAAG,YAAY;AAAA,QACtB;AACF,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,SAAO,QAAQ,OAAO,sBAAS;AACjC;AAQO,SAAS,iBACd,MACA,QACgB;AAChB,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,QAAM,OAAO,EAAE,GAAI,KAAK,QAAQ,CAAC,EAAG;AACpC,QAAM,SAAS,EAAE,GAAI,KAAK,UAAU,CAAC,EAAG;AACxC,QAAM,SAAS,EAAE,GAAI,KAAK,UAAU,CAAC,EAAG;AACxC,aAAW,SAAS,QAAQ;AAC1B,eAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQ,MAAM,QAAQ,CAAC,CAAC,GAAG;AACxD,WAAK,EAAE,IAAI;AACX,aAAO,OAAO,EAAE;AAAA,IAClB;AACA,eAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC,GAAG;AAC1D,aAAO,EAAE,IAAI;AACb,aAAO,OAAO,EAAE;AAAA,IAClB;AACA,WAAO,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC;AAAA,EAC1C;AACA,QAAM,SAAyB;AAAA,IAC7B,GAAG;AAAA,IACH,IAAI,KAAK,MAAM,OAAO,MAAM,CAAC,UAAU,MAAM,EAAE;AAAA,EACjD;AACA,SAAO,OAAO;AACd,SAAO,OAAO;AACd,SAAO,OAAO;AACd,MAAI,OAAO,KAAK,IAAI,EAAE,OAAQ,QAAO,OAAO;AAC5C,MAAI,OAAO,KAAK,MAAM,EAAE,OAAQ,QAAO,SAAS;AAChD,MAAI,OAAO,KAAK,MAAM,EAAE,OAAQ,QAAO,SAAS;AAChD,SAAO;AACT;AAgBA,eAAsB,mBACpBA,YACA,OACA,OAII,CAAC,GACL,cACyB;AAEzB,MAAI,CAACA,WAAU,QAAS,QAAO,iBAAiB,EAAE,IAAI,MAAM,CAAC;AAE7D,MAAI,CAAC;AACH,WAAO,sBAAsBA,YAAW,QAAW,MAAM,YAAY;AAEvE,QAAM,OAAO,MAAM,iBAAiBA,YAAW,OAAO,IAAI;AAC1D,MAAI,KAAK,OAAO,WAAW;AACzB,WAAO,iBAAiB;AAAA,MACtB,IAAI;AAAA,MACJ,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,IAC1C,CAAC;AAIH,QAAM,UAA4B,CAAC;AACnC,aAAW,QAAQ,KAAK,QAAQ;AAC9B,YAAQ;AAAA,MACN,MAAM;AAAA,QACJA;AAAA,QACA,KAAK;AAAA,QACL,EAAE,IAAI,KAAK,IAAI,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,QAAQ,CAAC;AAClB;AAOA,eAAe,sBACbA,YACA,OACA,MAKA,cACyB;AACzB,QAAM,EAAE,KAAK,IAAIA;AAGjB,MAAI,OAAO;AACT,UAAM,WAAWA,WAAU,OAAO;AAClC,QAAI,aAAa,QAAW;AAC1B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,SAAS,YAAYA,WAAU,OAAO,OAAO,EAAE,KAAK,SAAS,CAAC;AACpE,QAAI,OAAO,UAAU,GAAG;AACtB,YAAM,eAAe;AAAA,QACnBA,WAAU;AAAA,YACV,qBAAO,WAAW;AAAA,QAClB;AAAA,QACA,OAAO;AAAA,MACT;AACA;AAAA,QACEA,WAAU;AAAA,QACVA,WAAU;AAAA,QACV;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,KAAK;AAAA,UACL;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAWA,WAAU,MAAM,SAAS,UAAU;AAC5C,wBAAkBA,WAAU,KAAK;AAAA,IACnC;AACA,IAAAA,WAAU,OAAO;AAAA,EACnB;AAGA,MAAI,CAAC,aAAc,gBAAeA,WAAU;AAI5C,QAAM,eAAyCA,WAAU,gBAAgB,CAAC;AAE1E,QAAM,UAAU,MAAM,QAAQ;AAAA;AAAA,IAE5B,OAAO,QAAQ,gBAAgB,CAAC,CAAC,EAAE,IAAI,OAAO,CAAC,IAAI,WAAW,MAAM;AAElE,UAAI,YAAY,OAAO,UAAU;AAC/B,eAAO,EAAE,IAAI,aAAa,SAAS,KAAK;AAAA,MAC1C;AAQA,YAAM,cAAc,YAAY,OAAO,MAAM;AAC7C,YAAM,iBAAa,qBAAO,eAAe,WAAW;AACpD,YAAM,gBAAgB,qBAAqB,YAAY,OAAO,OAAO;AAKrE,UACE,iBACA;AAAA,QACEA,WAAU,OAAO;AAAA,QACjB;AAAA,QACA,cAAc;AAAA,MAChB,GACA;AACA,eAAO,EAAE,IAAI,aAAa,SAAS,KAAK;AAAA,MAC1C;AAOA,YAAM,cAAc,CAAC,YAA6C;AAChE,YAAI,eAAe;AACjB;AAAA,YACEA,WAAU,OAAO;AAAA,YACjB;AAAA,YACA;AAAA,YACA,cAAc;AAAA,YACd,cAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AACA,YAAM,mBAAmB,MAAM;AAC7B,YAAI,cAAe,cAAaA,WAAU,OAAO,UAAU,UAAU;AAAA,MACvE;AAIA,YAAM,UAAU,CAAC,WAA4B;AAC3C,YAAI,CAAC,OAAO,OAAQ;AACpB,YAAI,CAAC,YAAY,UAAW,aAAY,YAAY,CAAC;AACrD,cAAM,YAAY,YAAY;AAC9B,cAAM,SAAS,YAAY,OAAO,MAAM;AACxC,cAAM,QAAQ;AAAA,UACZ,KAAK,YAAY,OAAO,YAAY;AAAA,QACtC;AACA,YAAI,eAAe;AACnB,mBAAWC,WAAU,QAAQ;AAC3B,gBAAM,IAAI,YAAY,WAAWA,SAAQ,KAAK;AAC9C,0BAAgB,EAAE;AAAA,QACpB;AACA,YAAI,eAAe,GAAG;AAEpB,2BAAiBD,YAAW,MAAM;AAClC,gBAAM,eAAe;AAAA,YACnBA,WAAU;AAAA,gBACV,qBAAO,eAAe,MAAM;AAAA,YAC5B;AAAA,YACA;AAAA,UACF;AACA;AAAA,YACE;AAAA,YACAA,WAAU,OAAO,MAAM,YAAY,QAAQ,SAAS;AAAA,YACpD;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,aAAa;AAAA,cACb,KAAK,MAAM;AAAA,cACX;AAAA,YACF;AAAA,UACF;AAAA,QACF,WAAW,UAAU,SAAS,MAAM,KAAK;AACvC,4BAAkB,SAAS;AAAA,QAC7B;AAAA,MACF;AAaA,UACE,YAAY,MACZ,YAAY,OAAO,QACnB,CAAC,aAAa,WAAW,KACzB,CAAC,wBAAwB,WAAW,KACpC,qBAAqBA,YAAW,WAAW;AAE3C,cAAM,wBAAwBA,YAAW,aAAa,EAAE;AAE1D,YAAM,OAAO,aAAa,WAAW;AACrC,UACE,QACA,CAAC,wBAAwB,WAAW,KACpC,KAAK,IAAI,IAAI,KAAK,SAChB,0BAA0B,YAAY,OAAO,OAAO;AAEtD,cAAM,wBAAwBA,YAAW,aAAa,EAAE;AAK1D,UAAI,aAAa,WAAW,GAAG;AAC7B,yBAAiB;AACjB,YAAI,CAAC,MAAO,QAAO,EAAE,IAAI,aAAa,SAAS,KAAK;AACpD,cAAM,OAAO,KAAC,oBAAM,KAAK,CAAC;AAC1B,gBAAQ,IAAI;AACZ,eAAO,EAAE,IAAI,aAAa,OAAO,KAAK;AAAA,MACxC;AAIA,UAAI,gBAAgB,YAAY,aAAa,CAAC,GAAG,IAAI,CAACE,YAAW;AAAA,QAC/D,GAAGA;AAAA,QACH,SAASF,WAAU;AAAA,MACrB,EAAE;AACF,kBAAY,YAAY,CAAC;AAGzB,UAAI,MAAO,cAAa,SAAK,oBAAM,KAAK,CAAC;AAGzC,YAAM,aAAqB,KAAK,SAC5B;AAAA,QACE,GAAG,KAAK;AAAA,QACR,OAAO,EAAE,GAAG,KAAK,OAAO,OAAO,MAAM,CAAC,GAAG,KAAK,OAAO,MAAM,IAAI,EAAE;AAAA,MACnE,QACA,2BAAa,SAAS;AAG1B,UAAI,CAAC,aAAa,UAAU,CAAC,YAAY,SAAS,QAAQ;AACxD,yBAAiB;AACjB,eAAO,EAAE,IAAI,aAAa,SAAS,KAAK;AAAA,MAC1C;AAQA,UAAI,CAAC,aAAa,UAAU,YAAY,SAAS,QAAQ;AAQvD,YAAI,KAAC,gCAAkB,YAAY,OAAO,SAASA,WAAU,OAAO,GAAG;AACrE,2BAAiB;AACjB,iBAAO,EAAE,IAAI,aAAa,SAAS,KAAK;AAAA,QAC1C;AACA,YAAIG,iBAAgB;AACpB,YAAI;AACF,UAAAA,iBAAgB,MAAM;AAAA,YACpBH;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,UAAAA,WAAU,OAAO;AACjB,gBAAM,WAAW,YAAY,QAAQ;AACrC,UAAAA,WAAU,OAAO,MAAM,QAAQ,EAAE,MAAM,2BAA2B;AAAA,YAChE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,UACxD,CAAC;AAED,sBAAY,mBAAmB;AAAA,QACjC;AAGA,YAAI,aAAa,WAAW,GAAG;AAC7B,2BAAiB;AACjB,iBAAO,EAAE,IAAI,aAAa,SAAS,KAAK;AAAA,QAC1C;AAGA,YAAIG,kBAAiB,YAAY,WAAW,QAAQ;AAClD,yBAAe,YAAY,UAAU,IAAI,CAACF,aAAY;AAAA,YACpD,GAAGA;AAAA,YACH,SAASD,WAAU;AAAA,UACrB,EAAE;AACF,sBAAY,YAAY,CAAC;AAAA,QAC3B,OAAO;AAIL,2BAAiB;AACjB,iBAAO,EAAE,IAAI,aAAa,SAAS,CAACG,eAAc;AAAA,QACpD;AAAA,MACF;AAOA,YAAM,QAAQ,CAAC,UAA2B;AACxC,cAAM,UAAUH,WAAU;AAC1B,cAAM,UAA2B,CAAC;AAClC,cAAM,UAAU,MAAM,OAAO,CAAC,gBAAgB;AAC5C,gBAAM,qBAAiB;AAAA,YACrB,YAAY,OAAO;AAAA;AAAA,YACnB;AAAA;AAAA,YACA,YAAY;AAAA;AAAA,UACd;AAEA,cAAI,gBAAgB;AAClB,wBAAY,UAAU;AAEtB,oBAAQ,KAAK,WAAW;AACxB,mBAAO;AAAA,UACT;AAEA,gBAAM,YAAY,eAAeA,YAAW;AAAA,YAC1C,YAAQ,qBAAO,eAAe,EAAE;AAAA,YAChC,UAAU;AAAA,YACV,OAAO;AAAA,YACP,SAAS,OAAO,YAAY,OAAO,WAAW,YAAY,KAAK;AAAA,YAC/D,KAAK,KAAK,IAAI;AAAA,YACd,GAAG,cAAc,aAAa,YAAYA,UAAS;AAAA,UACrD,CAAC;AACD,oBAAU,aAAa;AACvB,cAAI,QAAS,WAAU,UAAU,EAAE,GAAG,QAAQ;AAC9C,cAAI,YAAY,OAAO,SAAS;AAC9B,sBAAU,OAAO,EAAE,UAAU,EAAE,GAAG,YAAY,OAAO,QAAQ,EAAE;AAAA,UACjE;AACA,qCAASA,YAAW,SAAS;AAE7B,iBAAO;AAAA,QACT,CAAC;AACD,eAAO,EAAE,SAAS,QAAQ;AAAA,MAC5B;AAEA,YAAM,eAAeA,WAAU;AAC/B,YAAM,EAAE,SAAS,eAAe,SAAS,cAAc,IACrD,MAAM,YAAY;AAGpB,cAAQ,aAAa;AAGrB,UAAI,CAAC,cAAc,QAAQ;AACzB,yBAAiB;AACjB,eAAO,EAAE,IAAI,aAAa,OAAO,aAAa;AAAA,MAChD;AAKA,YAAM,SAAS,IAAI,IAAI,YAAY,SAAS;AAU5C,UAAI,gBAAgB;AACpB,UAAI;AACF,wBAAgB,MAAM,gBAAgBA,YAAW,aAAa,IAAI,IAAI;AAAA,MACxE,SAAS,KAAK;AACZ,QAAAA,WAAU,OAAO;AACjB,cAAM,WAAW,YAAY,QAAQ;AACrC,QAAAA,WAAU,OAAO,MAAM,QAAQ,EAAE,MAAM,2BAA2B;AAAA,UAChE,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACxD,CAAC;AAID,oBAAY,mBAAmB;AAAA,MACjC;AAEA,UAAI,CAAC,eAAe;AAGlB,yBAAiB;AACjB,eAAO,EAAE,IAAI,aAAa,OAAO,aAAa;AAAA,MAChD;AAKA,UAAI,aAAa,WAAW,GAAG;AAC7B,yBAAiB;AACjB,gBAAQ,aAAa;AACrB,eAAO,EAAE,IAAI,aAAa,OAAO,cAAc;AAAA,MACjD;AAIA,YAAM,cAA+B,CAAC;AACtC,UAAIA,WAAU,YAAY,cAAc;AACtC,cAAM,UAAU;AAAA,UACd,cAAc,IAAI,CAACC,aAAY;AAAA,YAC7B,GAAGA;AAAA,YACH,SAASD,WAAU;AAAA,UACrB,EAAE;AAAA,QACJ;AACA,sBAAc,OAAO,GAAG,cAAc,QAAQ,GAAG,QAAQ,OAAO;AAChE,oBAAY,KAAK,GAAG,QAAQ,OAAO;AAAA,MACrC;AAKA,YAAM,cAAc,YAAY,aAAa,CAAC;AAC9C,YAAM,UAAU,YAAY,OAAO,CAACC,YAAW,CAAC,OAAO,IAAIA,OAAM,CAAC;AAClE,UAAI,QAAQ,QAAQ;AAClB,oBAAY,YAAY,YAAY;AAAA,UAAO,CAACA,YAC1C,OAAO,IAAIA,OAAM;AAAA,QACnB;AACA,cAAM,OAAO;AAAA,UACX,QAAQ,IAAI,CAACA,aAAY,EAAE,GAAGA,SAAQ,SAASD,WAAU,QAAQ,EAAE;AAAA,QACrE;AACA,sBAAc,KAAK,GAAG,KAAK,OAAO;AAClC,oBAAY,KAAK,GAAG,KAAK,OAAO;AAAA,MAClC;AACA,cAAQ,WAAW;AAEnB,UAAI,CAAC,cAAc,QAAQ;AACzB,yBAAiB;AACjB,eAAO,YAAY,SACf,EAAE,IAAI,aAAa,OAAO,YAAY,IACtC,EAAE,IAAI,aAAa,SAAS,KAAK;AAAA,MACvC;AAGA,UAAI;AACJ,UAAI;AACJ,UAAI,CAAC,YAAY,IAAK,aAAY,MAAM,CAAC;AAIzC,YAAM,SAAS,YAAY,OAAO;AAClC,YAAM,aAAa,YAAY,OAAO;AAKtC,YAAM,kBAAkB,YAAY,QAAQ;AAG5C,YAAM,iBAAiB,sBACnB,2BAAa,eAAe,IAC5B;AACJ,YAAM,cAAc,iBAChB,cAAc,gBAAgBA,UAAS,IACvC;AAKJ,YAAM,gBAAgB,YAAY,QAAQ,YACtC,2BAAa,YAAY,OAAO,KAAK,IACrC;AACJ,YAAM,YAAY,eAAe,OAAO,CAAC,UAAU,MAAM,SAAS,KAAK;AACvE,YAAM,YAAY,eAAe,OAAO,CAAC,UAAU,MAAM,SAAS,KAAK;AAGvE,UAAI,gBAAgB;AAIpB,UAAI,eAAe;AAGnB,UAAI,cAAc;AAClB,YAAM,QAAQ;AAAA,QACZ,cAAc,IAAI,OAAOE,WAAU;AAEjC,UAAAA,OAAM,WAAO,qBAAO,MAAMA,OAAM,IAAI;AAGpC,cAAI;AACJ,cAAI;AACJ,cAAI,gBAAgB,QAAQ,aAAa;AACvC,kBAAM,mBAAe,gCAAkB,YAAYA,MAAK;AACxD,kBAAM,cAAc,UAAM;AAAA,cACxB;AAAA,cACA;AAAA,cACA;AAAA,YACF;AACA,gBAAI,aAAa,WAAW,OAAO;AACjC,qBAAOA;AAAA,YACT;AACA,gBAAI,aAAa,WAAW,QAAQ;AAClC,0BAAY,EAAE,KAAK,YAAY,KAAK,KAAK,YAAY,KAAK,IAAI;AAAA,YAChE;AAAA,UACF;AAGA,cAAI,WAA6D;AAAA,YAC/D,EAAE,OAAAA,QAAO,QAAQ,WAAW;AAAA,UAC9B;AACA,cAAI,cAAc,KAAK;AACvB,cAAI,WAAW,QAAW;AACxB,kBAAM,YAAY,eAAe,EAAE;AACnC,kBAAM,cAAc,MAAM;AAAA,cACxBF;AAAA,cACA;AAAA,cACA;AAAA,cACAE;AAAA,cACA;AAAA,cACA,KAAK;AAAA,cACL;AAAA,YACF;AAEA,gBAAI,YAAY,OAAO,WAAW,GAAG;AAGnC,oBAAM,YAAY,eAAeF,YAAW;AAAA,gBAC1C,YAAQ,qBAAO,eAAe,EAAE;AAAA,gBAChC,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,SAAS,OAAOE,OAAM,OAAO,WAAWA,OAAM,KAAK;AAAA,gBACnD,KAAK,KAAK,IAAI;AAAA,gBACd,GAAG,cAAcA,QAAO,YAAYF,UAAS;AAAA,cAC/C,CAAC;AACD,wBAAU,aAAa;AACvB,wBAAU,OAAO;AAAA,gBACf,IAAI,YAAY,aAAa;AAAA,gBAC7B,IAAI;AAAA,cACN;AACA,yCAASA,YAAW,SAAS;AAC7B,qBAAOE;AAAA,YACT;AAGA,gBAAI,YAAY,QAAS,eAAc,YAAY;AAInD,uBAAW,YAAY,OAAO,IAAI,CAAC,UAAU;AAAA,cAC3C,OAAO,KAAK;AAAA,cACZ,QAAQ,KAAK;AAAA,YACf,EAAE;AAAA,UACJ;AAMA,gBAAM,aAAa,OACjB,gBACA,aACA,eACqB;AAKrB,gBAAIE,aAAY;AAChB,gBAAI,SAAS;AAGb,gBAAI,kBAAkB,CAAC,eAAe,QAAQ,aAAa;AACzD,oBAAM,mBAAe;AAAA,gBACnB;AAAA,gBACA,kBAAkB;AAAA,cACpB;AACA,oBAAM,cAAc,UAAM;AAAA,gBACxB;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AACA,kBAAI,aAAa,WAAW,OAAO;AACjC,uBAAO;AAAA,cACT;AACA,kBAAI,aAAa,WAAW,QAAQ;AAClC,gBAAAA,aAAY,EAAE,KAAK,YAAY,KAAK,KAAK,YAAY,KAAK,IAAI;AAC9D,yBAAS;AAAA,cACX;AAAA,YACF;AAGA,gBAAI,aAAa,UAAU,SAAS,KAAK,gBAAgB;AACvD,+BAAiB,UAAM;AAAA,gBACrB;AAAA,gBACA,CAAC,YAAY,cAAc,SAASJ,UAAS;AAAA,gBAC7C;AAAA,gBACAA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAEA,kBAAM,YAAY,KAAK,IAAI;AAC3B,gBAAI,aAAa;AACjB,kBAAM,SAAS,UAAM,4BAAc,iBAAiB,CAAC,QAAQ;AAE3D,oBAAM,WAAW,YAAY,QAAQ;AACrC,cAAAA,WAAU,OAAO,MAAM,QAAQ,EAAE,MAAM,eAAe;AAAA,gBACpD,GAAG,UAAU,GAAG;AAAA,gBAChB,OAAO,eAAgB;AAAA,cACzB,CAAC;AACD,sBAAQ;AACR,2BAAa;AAGb,oBAAM,MAAM,YAAY;AACxB,oBAAM,SAAS,YAAY,OAAO,MAAM;AACxC,oBAAM,WAAW;AAAA,gBACf,KAAK,YAAY,OAAO,UAAU;AAAA,cACpC;AACA,oBAAM,YAAY;AAAA,gBAChB;AAAA,gBACA,CAAC,gBAAiB,GAAG;AAAA,gBACrB;AAAA,cACF;AACA,kBAAI,UAAU,UAAU,GAAG;AACzB,iCAAiBA,YAAW,MAAM;AAClC,sBAAM,eAAe;AAAA,kBACnBA,WAAU;AAAA,sBACV,qBAAO,eAAe,MAAM;AAAA,kBAC5B;AAAA,kBACA,UAAU;AAAA,gBACZ;AACA;AAAA,kBACE;AAAA,kBACAA,WAAU,OAAO,MAAM,YAAY,QAAQ,SAAS;AAAA,kBACpD;AAAA,kBACA;AAAA,oBACE,QAAQ;AAAA,oBACR,aAAa;AAAA,oBACb,KAAK,SAAS;AAAA,oBACd;AAAA,kBACF;AAAA,gBACF;AAAA,cACF,WAAW,IAAI,SAAS,SAAS,KAAK;AACpC,kCAAkB,GAAG;AAAA,cACvB;AAEA,qBAAO;AAAA,YACT,CAAC;AAAA,cACCA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AACA,6BAAiB,KAAK,IAAI,IAAI;AAM9B,gBACEI,cACA,eACA,YAAY,OAAO,SAAS,QAC5B;AACA,kBAAI,QAAQ;AACV;AAAA,kBACE;AAAA,kBACAA,WAAU;AAAA,kBACV,UAAU;AAAA,kBACVA,WAAU;AAAA,gBACZ;AAAA,cACF,WAAW,eAAe,QAAW;AACnC,6BAAa,UAAU;AAAA,cACzB;AAAA,YACF;AAMA,gBACE,CAAC,cACD,CAAC,gBAAgB,MAAM,KACvB,aACA,UAAU,SAAS,KACnB,gBACA;AACA,+BAAiB,UAAM;AAAA,gBACrB;AAAA,gBACA,CAAC,YAAY,cAAc,SAASJ,UAAS;AAAA,gBAC7C;AAAA,gBACAA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAIA,gBAAI,WAAW,UAAa,CAAC,gBAAgB,MAAM,GAAG;AACpD,yBAAW;AAAA,YACb;AACA,gBAAI,gBAAgB,MAAM,EAAG;AAG7B,gBAAI,CAAC,cAAc,YAAY;AAE7B,kBAAI,WAAW,QAAW;AACxB,4BAAY,YAAY;AAAA,cAC1B;AAGA,oBAAM,aAAa,MAAM;AAAA,gBACvBA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,eAAe,EAAE;AAAA,cACnB;AACA,kBAAI,WAAW,QAAS,eAAc,WAAW;AAAA,YACnD;AAEA,mBAAO;AAAA,UACT;AAEA,qBAAW,SAAS,UAAU;AAK5B,gBAAI,MAAM,WAAW,MAAM,OAAO,MAAM,QAAQ,SAAS;AACvD;AAAA,UACJ;AAGA,cACE,aACA,eACA,eAAe,UACf,YAAY,OAAO,SAAS,QAC5B;AACA,yCAAW,aAAa,UAAU,KAAK,YAAY,UAAU,GAAG;AAAA,UAClE;AAEA,iBAAOE;AAAA,QACT,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc,cAAc;AAAA,QAC5B;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,OAAwC,CAAC;AAC/C,QAAM,SAA0C,CAAC;AACjD,QAAM,SAA0C,CAAC;AAEjD,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,QAAS;AAEpB,UAAM,cAAc,OAAO;AAC3B,UAAM,MAAuB;AAAA,MAC3B,MAAM,YAAY,QAAQ;AAAA,MAC1B,MAAM,OAAO;AAAA;AAAA,IACf;AAGA,qBAAiBF,YAAW,OAAO,EAAE;AACrC,UAAM,aAAaA,WAAU,OAAO,aAAa,OAAO,EAAE;AAC1D,UAAM,MAAM,KAAK,IAAI;AAGrB,eAAW,gBAAgB,YAAY,WAAW,UAAU;AAC5D,eAAW,UAAU,YAAY,KAAK,UAAU;AAIhD,UAAM,gBAAgB,OAAO;AAC7B,UAAM,aAAa,OAAO,kBACtB,qBAAO,eAAe,OAAO,WAAW,IACxC;AACJ,UAAM,gBAAgB,CAAC,YAA6C;AAClE,UAAI,iBAAiB,YAAY;AAC/B;AAAA,UACEA,WAAU,OAAO;AAAA,UACjB;AAAA,UACA;AAAA,UACA,cAAc;AAAA,UACd,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,OAAO,OAAO;AAChB,UAAI,QAAQ,OAAO;AACnB,aAAO,OAAO,EAAE,IAAI;AACpB,iBAAW;AACX,iBAAW,SAAS;AACpB,iBAAW,YAAY,OAAO,iBAAiB;AAC/C,MAAAA,WAAU,OAAO;AAEjB,oBAAc,mBAAmB;AAAA,IACnC,WAAW,OAAO,SAAS,OAAO,MAAM,QAAQ;AAE9C,aAAO,OAAO,EAAE,IAAI;AAAA,IACtB,OAAO;AAML,YAAM,eAAe,OAAO,gBAAgB;AAC5C,YAAM,eAAe,OAAO,gBAAgB;AAG5C,YAAM,iBAAiB,OAAO,eAAe;AAC7C,YAAM,gBAAgB,KAAK,IAAI,GAAG,iBAAiB,YAAY;AAC/D,UAAI,gBAAgB,KAAK,iBAAiB,GAAG;AAC3C,aAAK,OAAO,EAAE,IAAI;AAIlB,mBAAW;AACX,mBAAW,SAAS;AACpB,mBAAW,YAAY,OAAO,iBAAiB;AAC/C,QAAAA,WAAU,OAAO;AAIjB,sBAAc,SAAS;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAEA,SAAO,iBAAiB;AAAA,IACtB;AAAA,IACA,GAAI,OAAO,KAAK,IAAI,EAAE,UAAU,EAAE,KAAK;AAAA,IACvC,GAAI,OAAO,KAAK,MAAM,EAAE,UAAU,EAAE,OAAO;AAAA,IAC3C,GAAI,OAAO,KAAK,MAAM,EAAE,UAAU,EAAE,OAAO;AAAA,EAC7C,CAAC;AACH;AAgBA,SAAS,sBAAsB,aAA4C;AACzE,QAAM,WAAW,YAAY,OAAO;AACpC,SAAO,CAAC,CAAC,YAAY,OAAO,KAAK,QAAQ,EAAE,SAAS;AACtD;AAMA,eAAe,mBACbA,YACA,aACA,MACA,QACqC;AAErC,QAAM,WAAW,YAAY,QAAQ;AACrC,QAAM,aAAaA,WAAU,OAAO,MAAM,QAAQ;AAElD,QAAM,UAA+B;AAAA,IACnC,WAAAA;AAAA,IACA,QAAQ;AAAA,IACR,IAAI;AAAA,IACJ,QAAQ,YAAY;AAAA,IACpB,KAAK,kBAAkB,YAAY,KAAK,YAAY,OAAO,GAAG;AAAA,IAC9D,aAAa;AAAA,MACXA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,aAAW,MAAM,MAAM;AAEvB,QAAM,cAAc,KAAK,IAAI;AAC7B;AAAA,IACEA;AAAA,IACA,eAAeA,YAAW;AAAA,MACxB,YAAQ,qBAAO,eAAe,MAAM;AAAA,MACpC,UAAU;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAEA,MAAI;AACJ,MAAI;AACF,mBAAe,UAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACAA,WAAU;AAAA,MACVA,WAAU;AAAA,IACZ,EAAE,OAAO;AAAA,EACX,SAAS,KAAK;AACZ,UAAM,kBAAkB,KAAK,IAAI;AACjC,UAAM,WAAW,eAAeA,YAAW;AAAA,MACzC,YAAQ,qBAAO,eAAe,MAAM;AAAA,MACpC,UAAU;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AACD,aAAS,aAAa,kBAAkB;AACxC,aAAS,QACP,eAAe,QACX,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,IACvC,EAAE,SAAS,OAAO,GAAG,EAAE;AAC7B,+BAASA,YAAW,QAAQ;AAC5B,UAAM;AAAA,EACR;AAGA,MAAI,iBAAiB,MAAO,QAAO;AAGnC,SAAO;AAAA,IACL,GAAI,gBAAgB,YAAY;AAAA,IAChC,MAAM;AAAA;AAAA,EACR;AACF;AAQA,eAAe,aACbA,YACA,aACA,MACA,QACkB;AAClB,QAAM,SAAS,MAAM,mBAAmBA,YAAW,aAAa,MAAM,MAAM;AAC5E,MAAI,WAAW,MAAO,QAAO;AAC7B,cAAY,SAAS;AASrB,MAAI,YAAY,SAAS,QAAQ;AAI/B,UAAM,cAAc,aAAaA,UAAS;AAC1C,mBAAe,WAAW;AAC1B,QAAI;AACF,eACM,UAAU,YAAY,SAAS,MAAM,GACzC,SACA,UAAU,YAAY,SAAS,MAAM,GACrC;AACA,cAAM;AAAA,UACJA;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AAIZ,iBAAW,EAAE,KAAK,KAAK,YAAY,WAAW,CAAC,GAAG;AAChD,YAAI,gBAAgB,IAAI,EAAG,eAAcA,YAAW,aAAa,IAAI;AAAA,MACvE;AACA,kBAAY,UAAU,CAAC;AACvB,YAAM;AAAA,IACR,UAAE;AACA,mBAAaA,YAAW,WAAW;AACnC,kBAAY;AAAA,IACd;AAAA,EACF;AAEA,EAAAA,WAAU,OAAO,MAAM,YAAY,QAAQ,SAAS,EAAE,MAAM,WAAW;AACvE,SAAO;AACT;AAOA,IAAM,eAAe,oBAAI,QAAgD;AAEzE,eAAsB,gBACpBA,YACA,aACA,QAKA,UAAU,OACQ;AAElB,MAAI,YAAY,QAAQ,CAAC,YAAY,OAAO,MAAM;AAMhD,QAAI,CAAC,WAAW,sBAAsB,WAAW,GAAG;AAClD,MAAAA,WAAU,OACP,MAAM,YAAY,QAAQ,SAAS,EACnC,MAAM,wCAAwC;AACjD,aAAO;AAAA,IACT;AAIA,UAAM,UAAU,aAAa,IAAI,WAAW;AAC5C,QAAI,QAAS,QAAO;AACpB,UAAM,UAAU;AAAA,MACdA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,IACF;AACA,iBAAa,IAAI,aAAa,OAAO;AACrC,QAAI;AACF,aAAO,MAAM;AAAA,IACf,UAAE;AACA,mBAAa,OAAO,WAAW;AAAA,IACjC;AAAA,EACF;AAEA,SAAO;AACT;AAcA,eAAsB,gBACpBA,YACA,aACA,QACA,OACA,QACA,SACkB;AAClB,QAAM,EAAE,OAAO,IAAI;AAEnB,QAAM,YAAY,UAAM,kCAAoB,OAAO,QAAQA,UAAS;AAEpE,MAAI,UAAU,OAAQ,QAAO;AAG7B,QAAM,WAAW,YAAY,QAAQ;AACrC,QAAM,aAAaA,WAAU,OAAO,MAAM,QAAQ;AAElD,QAAM,UAAmC;AAAA,IACvC,WAAAA;AAAA,IACA,QAAQ;AAAA,IACR,IAAI;AAAA,IACJ;AAAA,IACA,MAAM,UAAU;AAAA,IAChB,MAAM,UAAU;AAAA,IAChB;AAAA,IACA,KAAK;AAAA,MACH,GAAG,kBAAkB,YAAY,KAAK,OAAO,GAAG;AAAA,MAChD,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC/B;AAAA,IACA,aAAa;AAAA,MACXA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,SAAS,QAAW;AAC7B,eAAW,MAAM,QAAQ,EAAE,OAAO,UAAU,MAAM,KAAK,CAAC;AACxD,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,eAAe,UAAU;AAE/B,QAAM,eAAe,cAAc,UAAU;AAC7C,QAAM,aAAa,eACf,UAAU,cAAc,QACxB;AAEJ,OACG,gBAAgB,OAAO,UAAU,WAClC,YAAY,aACZ,OAAO,SAAS,QAChB;AAEA,gBAAY,UAAU,YAAY,WAAW,CAAC;AAG9C,QAAI,CAAC,YAAY,QAAQ,UAAU,GAAG;AACpC,YAAM,UAAsC;AAAA,QAC1C,KAAK;AAAA,QACL,SAAS,CAAC;AAAA,QACV,QAAQ,CAAC;AAAA,QACT,MAAM,CAAC;AAAA,MACT;AAKA,YAAM,WAAW,sBAAsB,cAAc,KAAK;AAC1D,YAAM,WAAW,sBAAsB,OAAO,KAAK;AACnD,YAAM,OACJ,SAAS,QACT,SAAS;AAAA;AAAA,MAGT;AACF,YAAM,OAAO,SAAS,QAAQ,SAAS,QAAQ;AAC/C,YAAM,MAAM,SAAS,OAAO,SAAS,OAAO;AAK5C,YAAM,UAAU,kBAAkB,YAAY,KAAK,OAAO,GAAG;AAE7D,YAAM,aAAa,YAA2B;AAC5C,cAAMK,cAAa,YAAY,QAAS,UAAU;AAClD,cAAM,iBAAiBA,YAAW;AAClC,YAAI,eAAe,QAAQ,WAAW,EAAG;AAEzC,cAAM,WAAuC;AAAA,UAC3C,KAAK,eAAe;AAAA,UACpB,SAAS,eAAe;AAAA,UACxB,QAAQ,eAAe;AAAA,UACvB,MAAM,eAAe;AAAA,QACvB;AACA,uBAAe,UAAU,CAAC;AAC1B,uBAAe,SAAS,CAAC;AACzB,uBAAe,OAAO,CAAC;AAEvB,cAAM,MAAM,SAAS,QAAQ,CAAC;AAC9B,cAAM,eAA6C;AAAA,UACjD,WAAAL;AAAA,UACA,QAAQ;AAAA,UACR,IAAI;AAAA,UACJ;AAAA,UACA,MAAM;AAAA,UACN,MAAMK,YAAW,YAAY,SAAY,IAAI;AAAA,UAC7C,QAAQ,IAAI;AAAA,UACZ,KAAK;AAAA,YACH,GAAG;AAAA,YACH,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;AAAA,UAChD;AAAA,UACA,aAAa;AAAA,YACXL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,MAAM,cAAc,EAAE,QAAQ,SAAS,QAAQ,OAAO,CAAC;AAElE,cAAMM,kBAAiB,YAAY,OAAO,MAAM;AAChD,cAAMC,cAAa,iBAAiBP,YAAWM,eAAc;AAM7D,cAAM,qBAAqB;AAAA,UACzB,YAAY,OAAO;AAAA,QACrB;AACA,cAAM,sBAAkB,qBAAO,eAAeA,eAAc;AAC5D,cAAM,qBAAqB,CACzBE,aACG;AACH,cAAI,oBAAoB;AACtB;AAAA,cACER,WAAU,OAAO;AAAA,cACjB;AAAA,cACAQ;AAAA,cACA,mBAAmB;AAAA,cACnB,mBAAmB;AAAA,YACrB;AAAA,UACF;AAAA,QACF;AAEA,cAAM,eAAe,KAAK,IAAI;AAK9B,cAAM,aAAa,oBAAI,IAAqB;AAC5C,YAAI,aAAa;AACjB,YAAI;AAMJ,cAAM,aAAa,CAAC,aAA+C;AACjE,gBAAM,MAAO,YAAY,MAAM,YAAY,OAAO,CAAC;AACnD,gBAAM,WAAW;AAAA,YACf,KAAK,YAAY,OAAO,UAAU;AAAA,UACpC;AACA,cAAI,eAAe;AACnB,qBAAW,QAAQ,UAAU;AAC3B,kBAAM,IAAI,YAAY,KAAK,MAAM,QAAQ;AACzC,4BAAgB,EAAE;AAAA,UACpB;AACA,cAAI,eAAe,GAAG;AACpB,kBAAM,eAAe;AAAA,cACnBR,WAAU;AAAA,kBACV,qBAAO,eAAeM,eAAc;AAAA,cACpC;AAAA,cACA;AAAA,YACF;AACA;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,gBACE,QAAQ;AAAA,gBACR,aAAaA;AAAA,gBACb,KAAK,SAAS;AAAA,gBACd;AAAA,cACF;AAAA,YACF;AAAA,UACF,WAAW,IAAI,SAAS,SAAS,KAAK;AACpC,8BAAkB,GAAG;AAAA,UACvB;AACA,UAAAC,YAAW,UAAU,SAAS;AAC9B,UAAAA,YAAW,UAAU,IAAI;AACzB,UAAAP,WAAU,OAAO,UAAU,SAAS;AAAA,QACtC;AAKA,YAAI,iBAAiB,SAAS,QAAQ;AAEtC,cAAM,iBAAiB,0BAA0B,OAAO,OAAO;AAC/D,cAAM,UAAU,UAAM;AAAA,UACpB,CACE,UACA,WAEA;AAAA,YACE,QAAQ;AAAA,kBACN;AAAA,gBACE,YAAY;AAAA,gBACZ;AAAA,gBACAA,WAAU;AAAA,gBACVA,WAAU;AAAA,cACZ,EAAE,UAAU,MAAM;AAAA,YACpB;AAAA,YACA;AAAA,YACA,gBAAgB,MAAM,oCAAoC,cAAc;AAAA,UAC1E;AAAA,UACF,CAAC,QAAQ;AACP,6BAAiB;AACjB,yBAAa;AACb,yBAAa;AAEb,uBAAW,SAAS,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AAE9D,+BAAmB,mBAAmB;AACtC,uBAAW,MAAM,qBAAqB;AAAA,cACpC,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,cACtD,SAAS,SAAS,QAAQ;AAAA,YAC5B,CAAC;AACD,mBAAO;AAAA,UACT;AAAA,QACF,EAAE,UAAU,YAAY;AAKxB,YAAI,eAAe,OAAO,KAAK,QAAQ,OAAO,SAAS,GAAG;AACxD,gBAAM,cAAgD,CAAC;AACvD,qBAAW,WAAW,QAAQ,QAAQ;AACpC,kBAAM,QAAQ,SAAS,QAAQ,QAAQ,KAAK;AAC5C,gBAAI,CAAC,SAAS,WAAW,IAAI,QAAQ,KAAK,EAAG;AAC7C,kBAAM,WACJ,QAAQ,SACR,IAAI;AAAA,cACF,oBAAoB,QAAQ,KAAK;AAAA,YACnC;AACF,uBAAW,IAAI,QAAQ,OAAO,QAAQ;AACtC,wBAAY,KAAK,CAAC,MAAM,OAAO,QAAQ,CAAC;AAAA,UAC1C;AACA,cAAI,YAAY,SAAS,GAAG;AAC1B,uBAAW,WAAW;AACtB,6BAAiB,KAAK;AAAA,cACpB;AAAA,cACA,SAAS,QAAQ,SAAS,YAAY;AAAA,YACxC;AAGA,kBAAM,SAAS,oBAAI,IAGjB;AACF,uBAAW,CAAC,EAAE,QAAQ,KAAK,aAAa;AACtC,oBAAM,OACJ,oBAAoB,SACpB,UAAU,YACV,OAAO,SAAS,SAAS,WACrB,SAAS,OACT,oBAAoB,QAClB,SAAS,OACT;AACR,oBAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,kBAAI,MAAO,OAAM;AAAA;AAEf,uBAAO,IAAI,MAAM;AAAA,kBACf;AAAA,kBACA,OAAO;AAAA,kBACP,SACE,oBAAoB,QAChB,SAAS,UACT,OAAO,QAAQ;AAAA,gBACvB,CAAC;AAAA,YACL;AACA,uBAAW,MAAM,8BAA8B;AAAA,cAC7C,QAAQ,YAAY;AAAA,cACpB,WAAW;AAAA,cACX,SAAS,SAAS,QAAQ;AAAA,cAC1B,QAAQ,CAAC,GAAG,OAAO,OAAO,CAAC;AAAA,YAC7B,CAAC;AAAA,UACH;AAAA,QACF;AAcA,cAAM,YAAY,KAAK,IAAI;AAC3B,iBAAS,QAAQ,QAAQ,CAAC,OAAO,UAAU;AACzC,gBAAM,SAAS,cAAc,WAAW,IAAI,KAAK;AACjD,gBAAM,UAAU,cAAc,MAAM,OAAO,MAAM,QAAQA,UAAS;AAClE,gBAAM,QAAQ,eAAeA,YAAW;AAAA,YACtC,YAAQ,qBAAO,eAAe,MAAM;AAAA,YACpC,UAAU;AAAA,YACV,OAAO,SAAS,UAAU;AAAA,YAC1B,SAAS,OAAO,MAAM,MAAM,OAAO,WAAW,MAAM,MAAM,KAAK;AAAA,YAC/D,KAAK;AAAA,YACL,SAAS,QAAQ;AAAA,YACjB,UAAU,QAAQ;AAAA,YAClB,eAAe,QAAQ;AAAA,UACzB,CAAC;AACD,gBAAM,QAAQ,EAAE,MAAM,SAAS,QAAQ,QAAQ,MAAM;AAGrD,gBAAM,aAAa,YAAY;AAC/B,cAAI,QAAQ;AACV,kBAAM,MAAM,aAAa,aAAa,WAAW,IAAI,KAAK;AAC1D,kBAAM,QACJ,eAAe,QACX,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,IACvC,EAAE,SAAS,OAAO,GAAG,EAAE;AAAA,UAC/B;AACA,qCAASA,YAAW,KAAK;AAAA,QAC3B,CAAC;AAED,mBAAW,MAAM,iBAAiB;AAGlC,QAAAO,YAAW,gBAAgB,KAAK;AAAA,UAC9B;AAAA,WACCA,YAAW,iBAAiB,KAAK,SAAS,QAAQ;AAAA,QACrD;AAEA,YAAI,iBAAiB,GAAG;AACtB,UAAAA,YAAW,SAAS;AACpB,UAAAA,YAAW,SAAS,KAAK,IAAI;AAC7B,UAAAP,WAAU,OAAO,OAAO;AAIxB,6BAAmB,SAAS;AAAA,QAC9B;AAAA,MACF;AAEA,YAAM,gBAAY,uBAAS,YAAY;AAAA,QACrC;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,kBAAY,QAAQ,UAAU,IAAI;AAAA,QAChC;AAAA,QACA,WAAW,CAAC;AAAA;AAAA,QACZ,SAAS,MAAM;AACb,eAAK,UAAU;AAAA,QACjB;AAAA,QACA,OAAO,YAAY;AACjB,gBAAM,UAAU,MAAM;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAGA,UAAM,aAAa,YAAY,QAAQ,UAAU;AACjD,eAAW,QAAQ,QAAQ,KAAK;AAAA,MAC9B,OAAO,UAAU;AAAA,MACjB;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,MAAM,UAAU;AAAA,IAClB,CAAC;AACD,eAAW,QAAQ,OAAO,KAAK,UAAU,KAAK;AAC9C,YAAI,wBAAU,UAAU,IAAI,EAAG,YAAW,QAAQ,KAAK,KAAK,UAAU,IAAI;AAQ1E,UAAM,eACJ,OAAO,UAAU,MAAM,OAAO,WAAW,UAAU,MAAM,KAAK;AAChE,UAAM,eAAe,cAAc,OAAO,QAAQA,UAAS;AAC3D,UAAM,aAAa,KAAK,IAAI;AAC5B,UAAM,eAAe,eAAeA,YAAW;AAAA,MAC7C,YAAQ,qBAAO,eAAe,MAAM;AAAA,MACpC,UAAU;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK;AAAA,MACL,SAAS,aAAa;AAAA,MACtB,UAAU,aAAa;AAAA,MACvB,eAAe,aAAa;AAAA,IAC9B,CAAC;AACD,QAAI,UAAU,WAAY,cAAa,aAAa,UAAU;AAC9D,QAAI,UAAU,MAAM,SAAS;AAC3B,mBAAa,UAAU,EAAE,GAAG,UAAU,MAAM,QAAQ;AAAA,IACtD;AACA,iBAAa,UAAU,UAAU;AACjC,+BAASA,YAAW,YAAY;AAEhC,UAAM,gBAAgB,eAAeA,YAAW;AAAA,MAC9C,YAAQ,qBAAO,eAAe,MAAM;AAAA,MACpC,UAAU;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK;AAAA,MACL,SAAS,aAAa;AAAA,MACtB,UAAU,aAAa;AAAA,MACvB,eAAe,aAAa;AAAA,IAC9B,CAAC;AACD,QAAI,UAAU,WAAY,eAAc,aAAa,UAAU;AAC/D,kBAAc,WAAW,UAAU;AACnC,kBAAc,QAAQ;AAAA,MACpB,MAAM,WAAW,QAAQ,QAAQ;AAAA,MACjC,OAAO,WAAW,QAAQ,QAAQ,SAAS;AAAA,IAC7C;AACA,+BAASA,YAAW,aAAa;AAGjC,UAAM,iBAAiB,YAAY,OAAO,MAAM;AAChD,UAAM,aAAa,iBAAiBA,YAAW,cAAc;AAC7D,eAAW,iBAAiB,WAAW,iBAAiB,KAAK;AAG7D,eAAW,QAAQ;AAInB,WAAO;AAAA,EACT,OAAO;AACL,eAAW,MAAM,QAAQ,EAAE,OAAO,UAAU,MAAM,KAAK,CAAC;AAOxD,QAAI;AACJ,QACEA,WAAU,eAAe,MAAM,WAC/B,MAAM,QAAQ,YAAY,KAAK,KAC/B,YAAY,MAAM,SAAS,GAC3B;AACA,YAAM,UAAU,QAAQ;AAAA,QACtB,GAAG,QAAQ;AAAA,QACX,YAAY,YAAY;AAAA,MAC1B,CAAC;AACD,cAAQ,MAAM,QAAQ;AACtB,sBAAgB,QAAQ;AAOxB,UAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,gBAAQ,WAAW,4BAAe,IAAI;AAAA,UACpC,OAAO,QAAQ;AAAA,UACf,QAAQ,CAAC,IAAI,SACX,QAAQ,MAAM,KAAK,EAAE,IAAI,MAAM,IAAI,KAAK,IAAI,EAAE,CAAC;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAIA,UAAM,eACJ,OAAO,UAAU,MAAM,OAAO,WAAW,UAAU,MAAM,KAAK;AAChE,UAAM,EAAE,SAAS,UAAU,cAAc,IAAI;AAAA,MAC3C;AAAA,MACA;AAAA,MACAA;AAAA,IACF;AACA,UAAM,cAAc,KAAK,IAAI;AAC7B,UAAM,UAAU,eAAeA,YAAW;AAAA,MACxC,YAAQ,qBAAO,eAAe,MAAM;AAAA,MACpC,UAAU;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,UAAU,WAAY,SAAQ,aAAa,UAAU;AACzD,QAAI,UAAU,MAAM,SAAS;AAC3B,cAAQ,UAAU,EAAE,GAAG,UAAU,MAAM,QAAQ;AAAA,IACjD;AACA,YAAQ,UAAU,UAAU;AAC5B,+BAASA,YAAW,OAAO;AAE3B,QAAI;AAKF,YAAM,YAAY,0BAA0B,OAAO,OAAO;AAC1D,YAAM,WAAW,MAAM;AAAA,QACrB,QAAQ;AAAA,cACN;AAAA,YACE,YAAY;AAAA,YACZ;AAAA,YACAA,WAAU;AAAA,YACVA,WAAU;AAAA,UACZ,EAAE,UAAU,OAAO,OAAO;AAAA,QAC5B;AAAA,QACA;AAAA,QACA,gBAAgB,MAAM,8BAA8B,SAAS;AAAA,MAC/D;AAEA,YAAM,eAAe,KAAK,IAAI;AAC9B,YAAM,WAAW,eAAeA,YAAW;AAAA,QACzC,YAAQ,qBAAO,eAAe,MAAM;AAAA,QACpC,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD,eAAS,aAAa,eAAe;AACrC,eAAS,WAAW,UAAU;AAI9B,UAAI,iBAAiB,cAAc,SAAS,GAAG;AAC7C,iBAAS,QAAQ,cAAc,aAAa;AAAA,MAC9C;AACA,cAAI,wBAAU,QAAQ,GAAG;AACvB,iBAAS,OAAO,EAAE,GAAG,SAAS,MAAM,SAAS;AAAA,MAC/C;AACA,UAAI,UAAU,WAAY,UAAS,aAAa,UAAU;AAC1D,iCAASA,YAAW,QAAQ;AAE5B,iBAAW,MAAM,WAAW;AAE5B,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAM,eAAe,KAAK,IAAI;AAC9B,YAAM,WAAW,eAAeA,YAAW;AAAA,QACzC,YAAQ,qBAAO,eAAe,MAAM;AAAA,QACpC,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD,eAAS,aAAa,eAAe;AACrC,eAAS,QACP,eAAe,QACX,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,IACvC,EAAE,SAAS,OAAO,GAAG,EAAE;AAG7B,UAAI,iBAAiB,cAAc,SAAS,GAAG;AAC7C,iBAAS,QAAQ,cAAc,aAAa;AAAA,MAC9C;AACA,UAAI,UAAU,WAAY,UAAS,aAAa,UAAU;AAC1D,iCAASA,YAAW,QAAQ;AAC5B,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAQO,SAAS,iBACd,eACgB;AAChB,SAAO;AAAA,IACL,IAAI,CAAC,eAAe;AAAA,IACpB,GAAG;AAAA,EACL;AACF;AAOO,SAAS,oBACd,KACsB;AACtB,QAAM,EAAE,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,GAAG,OAAO,MAAM,IAAI;AACtD,QAAM,EAAE,QAAQ,iBAAiB,IAAI,qBAAqB,KAAK,QAAQ;AACvE,QAAM,EAAE,QAAQ,iBAAiB,IAAI;AAAA,IACnC,EAAE,GAAG,KAAK,QAAQ,iBAAiB;AAAA,IACnC;AAAA,EACF;AACA,QAAM,eAAe,EAAE,GAAG,KAAK,QAAQ,GAAG,QAAQ,GAAG,iBAAiB;AAEtE,MAAI,MAAO,cAAa,QAAQ;AAEhC,MAAI,UAAU,UAAa,aAAa,UAAU;AAChD,iBAAa,QAAQ;AACvB,QAAM,YAAY,kBAAkB,KAAK,KAAK,GAAG;AACjD,SAAO,EAAE,GAAG,MAAM,QAAQ,cAAc,KAAK,UAAU;AACzD;AAUA,eAAsB,iBACpBA,YACA,eAA6C,CAAC,GACb;AACjC,QAAM,SAAiC,CAAC;AAExC,aAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQ,YAAY,GAAG;AACpD,QAAI,IAAI,QAAQ,SAAS,QAAQ;AAC/B,MAAAA,WAAU,QAAQ,aAAa,EAAE,IAAI;AACrC;AAAA,IACF;AACA,WAAO,EAAE,IAAI,oBAAoB,GAAG;AAAA,EACtC;AAEA,SAAO;AACT;AAMO,SAAS,kBACd,gBACA,WACiB;AAEjB,MAAI,CAAC,kBAAkB,CAAC,UAAW,QAAO,CAAC;AAG3C,MAAI,CAAC,UAAW,QAAO;AACvB,MAAI,CAAC,eAAgB,QAAO;AAG5B,UAAI,uBAAS,cAAc,SAAK,uBAAS,SAAS,GAAG;AACnD,WAAO,EAAE,GAAG,gBAAgB,GAAG,UAAU;AAAA,EAC3C;AAGA,SAAO;AACT;;;Aa9/DA,IAAAS,gBAOO;AACP,IAAAA,gBAAyB;;;ACxBzB,IAAM,eAAe;AAMrB,eAAsB,gBACpBC,YACe;AACf,QAAM,SAASA,WAAU;AAGzB,QAAM,iBAAiBA,WAAU,SAAS,UAAU,MAAM;AAG1D,QAAM,wBAAwBA,WAAU,cAAc,MAAM;AAC5D,QAAM,iBAAiBA,WAAU,cAAc,eAAe,MAAM;AAGpE,QAAM,iBAAiBA,WAAU,cAAc,eAAe,MAAM;AAGpE,QAAM,iBAAiBA,WAAU,QAAQ,SAAS,MAAM;AAC1D;AAEA,eAAe,wBACb,cACA,YACe;AACf,QAAM,WAAW,OAAO,QAAQ,YAAY,EAAE,QAAQ,CAAC,CAAC,IAAI,IAAI,MAAM;AACpE,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,QAAS,QAAO,CAAC;AACtB,UAAM,SAAS,WAAW,MAAM,KAAK,QAAQ,aAAa;AAC1D,WAAO,OAAO,OAAO,OAAO,EAAE,IAAI,OAAO,MAAM;AAC7C,UAAI;AACJ,UAAI;AACF,cAAM,QAAQ,KAAK;AAAA,UACjB,EAAE,MAAM;AAAA,UACR,IAAI,QAAc,CAAC,GAAG,WAAW;AAC/B,oBAAQ;AAAA,cACN,MACE,OAAO,IAAI,MAAM,gBAAgB,EAAE,yBAAyB,CAAC;AAAA,cAC/D;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,eAAO,MAAM,gBAAgB,EAAE,yBAAyB,GAAG,EAAE;AAAA,MAC/D,UAAE;AACA,YAAI,MAAO,cAAa,KAAK;AAAA,MAC/B;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,QAAM,QAAQ,WAAW,QAAQ;AACnC;AAEA,eAAe,iBAGb,OACA,OACA,YACe;AACf,QAAM,WAAW,OAAO,QAAQ,KAAK,EAAE,IAAI,OAAO,CAAC,IAAI,IAAI,MAAM;AAI/D,UAAM,UACJ,KAGA;AACF,QAAI,CAAC,QAAS;AAEd,UAAM,WAAW,KAAK,QAAQ;AAC9B,UAAM,SAAS,WAAW,MAAM,QAAQ;AAExC,UAAM,UAAoC;AAAA,MACxC;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,KAAK,KAAK,OAAO,CAAC;AAAA,MAClB;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,YAAM,QAAQ,KAAK;AAAA,QACjB,QAAQ,OAAO;AAAA,QACf,IAAI,QAAc,CAAC,GAAG,WAAW;AAC/B,kBAAQ;AAAA,YACN,MAAM,OAAO,IAAI,MAAM,GAAG,KAAK,KAAK,EAAE,qBAAqB,CAAC;AAAA,YAC5D;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,aAAO,MAAM,GAAG,KAAK,KAAK,EAAE,qBAAqB,GAAG,EAAE;AAAA,IACxD,UAAE;AACA,UAAI,MAAO,cAAa,KAAK;AAAA,IAC/B;AAAA,EACF,CAAC;AAED,QAAM,QAAQ,WAAW,QAAQ;AACnC;;;AD9DA,SAAS,SAASC,YAA+B,MAAoB;AACnE,EAAAA,WAAU;AACV,EAAAA,WAAU,YAAY,IAAI,IAAIA,WAAU;AAC1C;AAUA,eAAsB,oBACpBA,YACA,QACA,MACyB;AACzB,MAAI;AACJ,MAAI;AACJ,MAAI,eAAe;AAEnB,QAAM,aAAoC,CAAC;AAO3C,QAAM,cAAc,aAAaA,UAAS;AAC1C,MAAI;AACF,WAAO,MAAM,iBAAiB;AAAA,EAChC,UAAE;AACA,gBAAY;AAAA,EACd;AAEA,iBAAe,mBAA4C;AACzD,YAAQ,QAAQ;AAAA,MACd,KAAK,MAAM,SAAS;AAClB,gBAAI,wBAAS,IAAI,GAAG;AAGlB,oCAAOA,WAAU,QAAQ,MAAmC;AAAA,YAC1D,SAAS;AAAA,YACT,OAAO;AAAA,UACT,CAAC;AACD,mBAAS;AACT,yBAAe;AAAA,QACjB;AACA;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,gBAAI,wBAAS,IAAI,GAAG;AAClB,gBAAM,EAAE,OAAO,IAAI;AAAA,YACjBA;AAAA,YACA;AAAA,UACF;AACA,mBAASA,YAAW,MAAM,SAAS,OAAO;AAC1C,mBAAS;AACT,yBAAe;AAAA,QACjB;AACA;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,gBAAI,wBAAS,IAAI,GAAG;AAClB,UAAAA,WAAU,aAAS;AAAA,YACjBA,WAAU;AAAA,YACV;AAAA,UACF;AACA,mBAASA,YAAW,MAAM,SAAS,MAAM;AACzC,mBAAS;AACT,yBAAe;AAAA,QACjB;AACA;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,gBACE,wBAAS,IAAI,KACb,UAAU,YACV,wBAAU,KAA0B,IAAI,GACxC;AACA,mBAAS,MAAM,eAAeA,YAAW,IAAwB;AAAA,QACnE;AACA;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,gBAAI,wBAAS,IAAI,GAAG;AAClB,UAAAA,WAAU,cAAU;AAAA,YAClBA,WAAU;AAAA,YACV;AAAA,UACF;AACA,mBAASA,YAAW,MAAM,SAAS,OAAO;AAC1C,mBAAS;AACT,yBAAe;AAAA,QACjB;AACA;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,gBACE,wBAAS,IAAI,SACb,wBAAU,KAA4B,IAAI,SAC1C,0BAAY,KAA0B,EAAE,GACxC;AACA,gBAAM,EAAE,MAAM,GAAG,IAAI;AAIrB,UAAAA,WAAU,MAAM,IAA6B,IAAI;AACjD,mBAAS;AACT,yBAAe;AAAA,QACjB;AACA;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,gBAAI,wBAAS,IAAI,SAAK,wBAAU,KAA4B,IAAI,GAAG;AACjE,gBAAM,EAAE,MAAM,MAAM,IAAI;AAIxB,gBAAM,GAAGA,YAAW,MAAM,KAAK;AAAA,QACjC;AACA;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,uBAAe;AACf;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,iBAAS,MAAM;AAAA,UACbA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,uBAAe;AACf;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,uBAAe;AACf;AAAA,MAEF,KAAK,MAAM,SAAS;AAIlB,YAAI,CAACA,WAAU,aAAa;AAC1B,UAAAA,WAAU,cAAc;AACxB,gBAAM,gBAAgBA,UAAS;AAAA,QACjC;AACA;AAAA,MAEF,KAAK,MAAM,SAAS;AAClB,gBAAI,wBAAS,IAAI,GAAG;AAClB,oCAAOA,WAAU,MAAM,MAAuB,EAAE,SAAS,MAAM,CAAC;AAChE,mBAASA,YAAW,MAAM,SAAS,IAAI;AACvC,mBAAS;AACT,yBAAe;AAAA,QACjB;AACA;AAAA,MAEF;AACE,QAAAA,WAAU,OAAO,KAAK,mBAAmB,EAAE,SAAS,OAAO,CAAC;AAC5D,eAAO,iBAAiB,EAAE,IAAI,MAAM,CAAC;AAAA,IACzC;AAGA,QAAI,cAAc;AAChB,YAAM,UAAU,MAAM;AAAA,QACpBA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,iBAAW,KAAK,GAAG,QAAQ,UAAU;AACrC,uBAAiB,QAAQ,UAAU;AAKnC,YAAM,UAAU;AAAA,QACd,MAAM,mBAAmBA,UAAS;AAAA,QAClC,MAAM,4BAA4BA,YAAW,UAAU;AAAA,MACzD;AAOA,UAAI,UAAU,OAAO,OAAO,OAAO;AACjC,cAAM,SAAS,EAAE,GAAI,QAAQ,UAAU,CAAC,GAAI,GAAI,OAAO,UAAU,CAAC,EAAG;AACrE,iBAAS;AAAA,UACP,GAAG;AAAA,UACH,IAAI;AAAA,UACJ,GAAI,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,QACrD;AAAA,MACF,OAAO;AACL,iBAAS;AAAA,MACX;AAAA,IACF;AAEA,WAAO,UAAU,iBAAiB,EAAE,IAAI,KAAK,CAAC;AAAA,EAChD;AACF;AAWO,SAAS,aACdA,YACA,OACuB;AACvB,SAAO;AAAA,IACL,QAAQ,KAAK,OAAO,KAAK,IAAI,IAAIA,WAAU,UAAU,EAAE,IAAI;AAAA,IAC3D,QAAQ,EAAE,MAAM,aAAa,QAAQ,IAAI;AAAA,IACzC,GAAG;AAAA,EACL;AACF;AAoBO,SAAS,YACdA,YACA,cACA,QACgB;AAChB,SAAO,WAAWA,YAAW,cAAc,QAAQ;AAAA,IACjD,SAASA,WAAU;AAAA,IACnB,MAAMA,WAAU;AAAA,IAChB,SAASA,WAAU;AAAA,EACrB,CAAC;AACH;AAQO,SAAS,cACdA,YACA,OACA,QACgB;AAChB,SAAO,WAAWA,YAAW,aAAaA,YAAW,KAAK,GAAG,QAAQ;AAAA,IACnE,SAAS,CAAC;AAAA,IACV,MAAM,CAAC;AAAA,IACP,SAAS,CAAC;AAAA,EACZ,CAAC;AACH;AAGA,SAAS,WACPA,YACA,cACA,QACA,QACgB;AAKhB,QAAM,UAAU,aAAa;AAC7B,MAAI,OAAO,YAAY;AACrB,UAAM,IAAI;AAAA,MACR,YAAY,SACR,2BACA;AAAA,IACN;AACF,MAAI,CAAC,QAAS,OAAM,IAAI,gCAAkB,wBAAwB;AAElE,QAAM,CAAC,aAAa,WAAW,IAAI,QAAQ,MAAM,GAAG;AACpD,MAAI,CAAC,eAAe,CAAC;AACnB,UAAM,IAAI,gCAAkB,uBAAuB;AAErD,QAAM;AAAA,IACJ,YAAY,KAAK,IAAI;AAAA,IACrB,OAAO,GAAG,WAAW,IAAI,WAAW;AAAA,IACpC,OAAO,CAAC;AAAA,IACR,UAAU,CAAC;AAAA,IACX,UAAU,CAAC;AAAA,IACX,SAAS,CAAC;AAAA,IACV,OAAO,OAAO;AAAA,IACd,SAAS,CAAC;AAAA,IACV,UAAU,OAAO;AAAA;AAAA;AAAA,IAGjB,SAAK,yBAAU;AAAA,IACf,UAAU;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS,EAAE,MAAM,aAAa,QAAQ,IAAI;AAAA,EAC5C,IAAI;AAQJ,QAAM,cAA+B,UAAU;AAAA,IAC7C,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AACA,QAAM,QAAQ,YAAY,UAAUA,WAAU,SAAS;AAEvD,QAAM,QAAQ,YAAY,SAAS,QAAQ,MAAM,SAASA,WAAU;AACpE,QAAM,gBAAiC,EAAE,GAAG,aAAa,MAAM;AAC/D,MAAI,UAAU,OAAW,eAAc,QAAQ;AAK/C,QAAM,aAAaA,WAAU,QAAQ,YAAY,YAAY;AAC7D,QAAM,eAAeA,WAAU,WAAW;AAC1C,gBAAc,UAAU;AAAA,IACtB,GAAG,YAAY;AAAA,IACf,CAAC,UAAU,GAAG;AAAA,EAChB;AAIA,QAAM,oBAAgB,sBAAO,OAAO,SAAS,OAAO;AAEpD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV;AACF;AAYO,SAAS,YACdA,YACA,OACA,QACgB;AAChB,SAAO,YAAYA,YAAW,aAAaA,YAAW,KAAK,GAAG,MAAM;AACtE;AASA,eAAsB,aACpBA,YACA,OACyB;AACzB,QAAM,aAAoC,CAAC;AAC3C,QAAM,SAAS,MAAM,qBAAqBA,YAAW,OAAO,UAAU;AACtE,SAAO;AAAA,IACL;AAAA,IACA,MAAM,4BAA4BA,YAAW,UAAU;AAAA,EACzD;AACF;AAOA,eAAsB,qBACpBA,YACA,OACA,YACyB;AAEzB,EAAAA,WAAU,UAAU;AAGpB,EAAAA,WAAU,SAAS,KAAK,IAAI;AAG5B,EAAAA,WAAU,YAAQ,0BAAW;AAC7B,EAAAA,WAAU,QAAQ;AAGlB,MAAI,OAAO;AAET,QAAI,MAAM,SAAS;AACjB,MAAAA,WAAU,cAAU,sBAAOA,WAAU,SAAS,MAAM,OAAO;AAC3D,eAASA,YAAW,MAAM,SAAS,OAAO;AAAA,IAC5C;AAGA,QAAI,MAAM,MAAM;AACd,MAAAA,WAAU,WAAO,sBAAOA,WAAU,MAAM,MAAM,IAAI;AAClD,eAASA,YAAW,MAAM,SAAS,IAAI;AAAA,IACzC;AAGA,QAAI,MAAM,SAAS;AACjB,MAAAA,WAAU,cAAU;AAAA,QAClBA,WAAU,OAAO,iBAAiB,CAAC;AAAA,QACnC,MAAM;AAAA,MACR;AACA,eAASA,YAAW,MAAM,SAAS,OAAO;AAAA,IAC5C;AAGA,QAAI,MAAM,QAAQ;AAChB,MAAAA,WAAU,aAAS,sBAAOA,WAAU,QAAQ,MAAM,MAAM;AACxD,eAASA,YAAW,MAAM,SAAS,MAAM;AAAA,IAC3C;AAAA,EACF;AAGA,SAAO,OAAOA,WAAU,YAAY,EAAE,QAAQ,CAAC,gBAAgB;AAC7D,gBAAY,YAAY,CAAC;AAAA,EAC3B,CAAC;AAGD,EAAAA,WAAU,QAAQ,CAAC;AAGnB,EAAAA,WAAU;AASV,QAAM,iBAAiBA,UAAS;AAUhC,QAAM,cAAc,MAAM,mBAAmBA,UAAS;AAWtD,MAAI,WAAW;AACf,QAAM,eAAsD,CAAC;AAC7D,MAAIA,WAAU,YAAY,QAAQ;AAChC,UAAM,OAAOA,WAAU,YAAY,OAAO,CAAC;AAC3C,IAAAA,WAAU,OAAO,MAAM,4BAA4B,EAAE,OAAO,KAAK,OAAO,CAAC;AACzE,eAAW,EAAE,OAAO,QAAQ,KAAK,MAAM;AACrC,YAAM,eAAe,MAAMA,WAAU,KAAK,OAAO,OAAO;AACxD,UAAI,aAAa,OAAO,MAAO,YAAW;AAI1C,UAAI,aAAa,OAAQ,QAAO,OAAO,cAAc,aAAa,MAAM;AAAA,IAC1E;AAAA,EACF;AAKA,mBAAiB,WAAW;AAC5B,QAAM,SAAS,MAAM,mBAAmBA,UAAS;AACjD,aAAW,KAAK,GAAG,WAAW;AAE9B,MAAI,SAAU,QAAO;AAErB,QAAM,SAAS,EAAE,GAAI,OAAO,UAAU,CAAC,GAAI,GAAG,aAAa;AAC3D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI;AAAA,IACJ,GAAI,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,EACrD;AACF;;;AdviBO,IAAM,sBAAsB;AA6BnC,eAAsB,iBACpBC,YACA,OACA,OAA8D,CAAC,GACjC;AAC9B,QAAM,SAAS,KAAK,cAAU,4BAAa,KAAK,MAAM,SAAS;AAC/D,QAAM,OAAOA,WAAU,OAAO;AAC9B,MAAI,SAAS,QAAW;AACtB,WAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,OAAO,CAAC,GAAG,SAAS,KAAK,QAAQ;AAAA,EAC9D;AAEA,QAAM,SAAS,MAAM;AAAA,IACnBA;AAAA,IACAA,WAAU,gBAAgB,CAAC;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL;AAAA,EACF;AACA,QAAM,UAAU,OAAO,WAAW,KAAK;AAEvC,MAAI,OAAO,OAAO,WAAW,GAAG;AAC9B,IAAAA,WAAU,OAAO;AAAA,MACf,kCACE,OAAO,YAAY,KAAK,OAAO,SAAS,MAAM,EAChD;AAAA,IACF;AACA;AAAA,MACEA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP;AAAA,IACF;AACA,WAAO,EAAE,QAAQ,CAAC,GAAG,SAAS,SAAS,KAAK;AAAA,EAC9C;AAGA,MAAI,OAAO,QAAS,QAAO,EAAE,QAAQ,CAAC,GAAG,QAAQ;AAKjD,SAAO;AAAA,IACL,QAAQ,OAAO,OAAO,IAAI,CAAC,UAAU;AAAA,MACnC,OAAO,cAAcA,YAAW,KAAK,OAAO,KAAK,MAAM;AAAA,MACvD,QAAQ,KAAK;AAAA,IACf,EAAE;AAAA,IACF;AAAA,EACF;AACF;;;AgB5FA,IAAAC,gBAKO;;;ACLP,IAAAC,gBAAqC;;;ACArC,IAAAC,gBAUO;AAYP,SAAS,mBACP,cACA,SACA,SACwB;AACxB,MAAI,WAAW;AACf,MAAI,SAAS;AACX,eAAW,OAAO;AAAA,MAChB,OAAO,QAAQ,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,MAAM,QAAQ,SAAS,EAAE,CAAC;AAAA,IAChE;AAAA,EACF;AACA,MAAI,SAAS;AACX,eAAW,OAAO;AAAA,MAChB,OAAO,QAAQ,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,SAAS,EAAE,CAAC;AAAA,IACjE;AAAA,EACF;AACA,SAAO;AACT;AAUO,SAAS,WACdC,YACAC,eACkB;AAClB,QAAM,gBAAY;AAAA,IAChB,OACE,OACA,UAAiC,CAAC,MACN;AAC5B,aAAO,UAAM;AAAA,QACX,YAAqC;AAInC,cAAI,CAACD,WAAU,SAAS;AACtB,kBAAM,MAAMA,WAAU,OAAO;AAC7B,gBAAI,QAAQ,QAAW;AACrB,oBAAM,IAAI;AAAA,gBACR;AAAA,cACF;AAAA,YACF;AACA,kBAAM,OAAO;AAAA,cACXA,WAAU;AAAA,cACV,EAAE,OAAO,QAAQ;AAAA,cACjB,EAAE,IAAI;AAAA,YACR;AACA,gBAAI,KAAK,UAAU,GAAG;AAKpB,oBAAM,eAAe;AAAA,gBACnBA,WAAU;AAAA,gBACV;AAAA,gBACA;AAAA,gBACA,KAAK;AAAA,cACP;AACA;AAAA,gBACEA,WAAU;AAAA,gBACVA,WAAU;AAAA,gBACV;AAAA,gBACA,EAAE,QAAQ,SAAS,KAAK,KAAK,aAAa;AAAA,cAC5C;AAAA,YACF,WAAWA,WAAU,YAAY,SAAS,KAAK;AAC7C,gCAAkBA,WAAU,WAAW;AAAA,YACzC;AACA,YAAAA,WAAU,OAAO,MAAM,wBAAwB;AAAA,cAC7C,MAAM,MAAM;AAAA,cACZ,SAAS,KAAK;AAAA,YAChB,CAAC;AACD,mBAAO,iBAAiB,EAAE,IAAI,KAAK,CAAC;AAAA,UACtC;AAEA,gBAAM,YAAY,KAAK,IAAI;AAC3B,gBAAM;AAAA,YACJ;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF,IAAI;AACJ,cAAI,UAAU;AACd,cAAI,eAAe;AAGnB,gBAAM,gBACJ,WAAW,UACP,mBAAmBA,WAAU,cAAc,SAAS,OAAO,IAC3D;AAGN,cAAI,iBACD,cAAiC,4BAAa,MAAM,SAAS;AAGhE,cAAI,SAAS;AACX,kBAAM,YAAY,UAAM;AAAA,cACtB;AAAA,cACA;AAAA,cACAA;AAAA,YACF;AAGA,gBAAI,UAAU,QAAQ;AACpB,qBAAO,iBAAiB,EAAE,IAAI,KAAK,CAAC;AAAA,YACtC;AAGA,gBAAI,QAAQ,SAAS;AACnB,oBAAM,qBAAiB;AAAA,gBACrB,QAAQ;AAAA,gBACRA,WAAU;AAAA,gBACV,UAAU,MAAM;AAAA,cAClB;AAEA,kBAAI,CAAC,gBAAgB;AACnB,uBAAO,iBAAiB,EAAE,IAAI,KAAK,CAAC;AAAA,cACtC;AAAA,YACF;AAEA,2BAAe,UAAU;AAAA,UAC3B;AAKA,cAAI,aAAa,QAAW;AAC1B,kBAAM,YAAY,KAAK,UAAU,EAAE,UAAU;AAC7C,kBAAM,cAAc,MAAM;AAAA,cACxBA;AAAA,cACAA,WAAU,gBAAgB,CAAC;AAAA,cAC3B;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAGA,gBAAI,YAAY,OAAO,WAAW,GAAG;AACnC,cAAAA,WAAU,OAAO;AAAA,gBACf,qCACE,YAAY,YAAY,KAAK,YAAY,SAAS,MAAM,EAC1D;AAAA,cACF;AACA;AAAA,gBACEA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,YAAY;AAAA,gBACZ,aAAa;AAAA,cACf;AACA,qBAAO,iBAAiB,EAAE,IAAI,MAAM,SAAS,KAAK,CAAC;AAAA,YACrD;AAOA,gBAAI,YAAY,SAAS;AACvB,kBAAI,YAAY,QAAS,WAAU,YAAY;AAC/C,qBAAO,iBAAiB,EAAE,IAAI,KAAK,CAAC;AAAA,YACtC;AAGA,gBAAI,YAAY,QAAS,WAAU,YAAY;AAK/C,gBAAI,YAAY,OAAO,SAAS,GAAG;AAEjC,oBAAM,cAAc,MAAM,QAAQ;AAAA,gBAChC,YAAY,OAAO,IAAI,OAAO,SAAS;AACrC,wBAAM,OAAO;AAAA,oBACXA;AAAA,oBACAC,cAAa,KAAK,KAAK;AAAA,oBACvB,KAAK;AAAA,kBACP;AACA,yBAAO;AAAA,oBACLD;AAAA,oBACA;AAAA,oBACA,EAAE,IAAI,QAAQ,KAAK,QAAQ,QAAQ;AAAA,oBACnC;AAAA,kBACF;AAAA,gBACF,CAAC;AAAA,cACH;AAGA,kBAAI,IAAI;AACN,oBAAI,CAACA,WAAU,OAAO,QAAQ,EAAE,GAAG;AACjC,kBAAAA,WAAU,OAAO,QAAQ,EAAE,IAAI;AAAA,oBAC7B,OAAO;AAAA,oBACP,UAAU;AAAA,kBACZ;AAAA,gBACF;AACA,sBAAM,eAAeA,WAAU,OAAO,QAAQ,EAAE;AAChD,6BAAa,SAAS,YAAY,OAAO;AACzC,6BAAa,SAAS,KAAK,IAAI;AAC/B,6BAAa,YAAY,KAAK,IAAI,IAAI;AAAA,cACxC;AAEA,qBAAO,YAAY,CAAC,KAAK,iBAAiB,EAAE,IAAI,KAAK,CAAC;AAAA,YACxD;AAEA,2BAAe,YAAY,OAAO,CAAC,EAAE;AACrC,6BAAiB,YAAY,OAAO,CAAC,EAAE;AAAA,UACzC;AAGA,gBAAM,YAAY;AAAA,YAChBA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAGA,gBAAM,SAAS,MAAM;AAAA,YACnBA;AAAA,YACA;AAAA,YACA;AAAA,cACE;AAAA,cACA,QAAQ;AAAA,cACR;AAAA,YACF;AAAA,YACA;AAAA,UACF;AAGA,cAAI,IAAI;AACN,gBAAI,CAACA,WAAU,OAAO,QAAQ,EAAE,GAAG;AACjC,cAAAA,WAAU,OAAO,QAAQ,EAAE,IAAI;AAAA,gBAC7B,OAAO;AAAA,gBACP,UAAU;AAAA,cACZ;AAAA,YACF;AACA,kBAAM,eAAeA,WAAU,OAAO,QAAQ,EAAE;AAChD,yBAAa;AACb,yBAAa,SAAS,KAAK,IAAI;AAC/B,yBAAa,YAAY,KAAK,IAAI,IAAI;AAAA,UACxC;AAEA,iBAAO;AAAA,QACT;AAAA,QACA,CAAC,QAAiB;AAChB,cAAI,eAAe,yBAAY,OAAM;AACrC,cAAI,eAAe,iCAAmB;AAMpC,kBAAM,WAAW,QAAQ;AACzB,gBAAI,UAAU;AACZ,kBAAI,CAACA,WAAU,OAAO,QAAQ,QAAQ,GAAG;AACvC,gBAAAA,WAAU,OAAO,QAAQ,QAAQ,IAAI,EAAE,OAAO,GAAG,UAAU,EAAE;AAAA,cAC/D;AACA,oBAAM,eAAeA,WAAU,OAAO,QAAQ,QAAQ;AACtD,2BAAa,YAAY,aAAa,YAAY,KAAK;AAAA,YACzD;AACA,YAAAA,WAAU,OAAO,KAAK,0BAA0B;AAAA,cAC9C,OAAO,IAAI;AAAA,YACb,CAAC;AACD,mBAAO,iBAAiB;AAAA,cACtB,IAAI;AAAA,cACJ,SAAS;AAAA,cACT,OAAO,IAAI;AAAA,YACb,CAAC;AAAA,UACH;AACA,UAAAA,WAAU,OAAO;AAOjB,UAAAA,WAAU,OAAO,MAAM,eAAe;AAAA,YACpC,GAAG,UAAU,GAAG;AAAA,YAChB,OAAO,MAAM;AAAA,UACf,CAAC;AACD,iBAAO,iBAAiB,EAAE,IAAI,MAAM,CAAC;AAAA,QACvC;AAAA,MACF,EAAE;AAAA,IACJ;AAAA,IACA;AAAA,IACAA,WAAU;AAAA,IACVA,WAAU;AAAA,EACZ;AAEA,QAAM,UAA4B,OAAO,OAAO,YAAY;AAK1D,UAAM,aACJ,OAAO,MAAM,OAAO,YAAY,MAAM,OAAO,KACzC,QACA,EAAE,GAAG,OAAO,QAAI,yBAAU,EAAE;AAClC,UAAM,UAAU,OAAO,WAAW,OAAO,WAAW,WAAW,KAAK;AAMpE,UAAM,EAAE,SAAS,UAAU,cAAc,IAAI;AAAA,MAC3C;AAAA,MACA,SAAS;AAAA,MACTA;AAAA,IACF;AACA,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,UAAU,eAAeA,YAAW;AAAA,MACxC,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,MACP;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,YAAQ,UAAU;AAClB,gCAASA,YAAW,OAAO;AAE3B,QAAI;AACF,YAAM,SAAS,MAAM,UAAU,YAAY,OAAO;AAClD,YAAME,YAAW,KAAK,IAAI;AAC1B,YAAM,WAAW,eAAeF,YAAW;AAAA,QACzC,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,QAKP;AAAA,QACA,KAAKE;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD,eAAS,aAAaA,YAAW;AACjC,eAAS,WAAW;AACpB,kCAASF,YAAW,QAAQ;AAC5B,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAME,YAAW,KAAK,IAAI;AAC1B,YAAM,WAAW,eAAeF,YAAW;AAAA,QACzC,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,OAAO;AAAA,QACP;AAAA,QACA,KAAKE;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD,eAAS,aAAaA,YAAW;AACjC,eAAS,QACP,eAAe,QACX,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,IACvC,EAAE,SAAS,OAAO,GAAG,EAAE;AAC7B,kCAASF,YAAW,QAAQ;AAC5B,YAAM;AAAA,IACR;AAAA,EACF;AAEA,SAAO;AACT;;;AC9YA,IAAAG,gBAAoD;AAY7C,SAAS,cACdC,YACA,eACqB;AACrB,aAAO;AAAA,IACL,OACE,SACA,MACA,YAC4B;AAC5B,aAAO,UAAM;AAAA,QACX,YAAqC;AACnC,iBAAO,MAAM,cAAcA,YAAW,SAAS,MAAM,OAAO;AAAA,QAC9D;AAAA,QACA,CAAC,QAAiB;AAChB,cAAI,eAAe,yBAAY,OAAM;AACrC,UAAAA,WAAU,OAAO;AAKjB,UAAAA,WAAU,OAAO,MAAM,kBAAkB;AAAA,YACvC,GAAG,UAAU,GAAG;AAAA,YAChB;AAAA,UACF,CAAC;AACD,iBAAO,iBAAiB,EAAE,IAAI,MAAM,CAAC;AAAA,QACvC;AAAA,MACF,EAAE;AAAA,IACJ;AAAA,IACA;AAAA,IACAA,WAAU;AAAA,IACVA,WAAU;AAAA,EACZ;AACF;;;ACpCO,SAAS,UAAUC,YAAuC;AAC/D,SAAO,OACL,gBACA,MACA,SACA,QACA,WAC4B;AAE5B,QACE,OAAO,mBAAmB,YAC1B,eAAe,WAAW,SAAS,GACnC;AACA,YAAM,UAAU,eAAe,QAAQ,WAAW,EAAE;AACpD,aAAOA,WAAU,QAAQ,SAAS,IAAI;AAAA,IACxC;AAGA,QAAI;AAEJ,QAAI,OAAO,mBAAmB,UAAU;AAEtC,cAAQ,EAAE,MAAM,eAAe;AAC/B,UAAI,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAG;AAC5D,cAAM,OAAO;AAAA,MACf;AAAA,IACF,WACE,kBACA,OAAO,mBAAmB;AAAA,IAE1B,CAAC,MAAM,QAAQ,cAAc,GAC7B;AAGA,cAAQ,EAAE,GAAI,eAA6C;AAE3D,UAAI,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAG;AAC5D,cAAM,OAAO;AAAA,UACX,GAAI,MAAM,QAAQ,CAAC;AAAA,UACnB,GAAI;AAAA,QACN;AAAA,MACF;AAAA,IACF,OAAO;AAEL,aAAO,iBAAiB,EAAE,IAAI,MAAM,CAAC;AAAA,IACvC;AAGA,QAAI,WAAW,OAAO,YAAY,UAAU;AAC1C,YAAM,UAAU;AAAA,IAClB;AACA,QAAI,UAAU,MAAM,QAAQ,MAAM,GAAG;AACnC,YAAM,SAAS;AAAA,IACjB;AACA,QAAI,UAAU,OAAO,WAAW,UAAU;AACxC,YAAM,SAAS;AAAA,IACjB;AAGA,WAAOA,WAAU,KAAK,KAAK;AAAA,EAC7B;AACF;;;ACvEA,IAAAC,gBAAmC;;;AC4EnC,IAAM,sBAAsB;AAC5B,IAAM,4BAA4B;AAClC,IAAM,yBAAyB;AAExB,SAAS,iBAAiB,UAA6B,CAAC,GAAe;AAC5E,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,kBAAkB,QAAQ,mBAAmB;AACnD,QAAM,aAAa,KAAK,MAAM,aAAa,YAAY;AAEvD,QAAM,UAAU,oBAAI,IAAwB;AAE5C,QAAM,WAA+B;AAAA,IACnC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,eAAe;AAAA,EACjB;AAEA,WAAS,gBAAsB;AAC7B,QAAI,QAAQ,QAAQ,WAAY;AAGhC,UAAM,WAAW,QAAQ,OAAO;AAChC,QAAI,UAAU;AACd,eAAW,OAAO,QAAQ,KAAK,GAAG;AAChC,UAAI,WAAW,SAAU;AACzB,cAAQ,OAAO,GAAG;AAClB;AAAA,IACF;AACA,aAAS,qBAAqB;AAAA,EAChC;AAEA,WAAS,QAAc;AACrB,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,UAAU;AACd,eAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAClC,UAAI,MAAM,YAAY,UAAa,MAAM,WAAW,KAAK;AACvD,gBAAQ,OAAO,GAAG;AAClB;AAAA,MACF;AAAA,IACF;AACA,aAAS,iBAAiB;AAAA,EAC5B;AAEA,MAAI;AACJ,MAAI,kBAAkB,GAAG;AACvB,iBAAa,YAAY,OAAO,eAAe;AAE/C,QACE,cACA,OAAQ,WAAsC,UAAU,YACxD;AACA,MAAC,WAAqC,MAAM;AAAA,IAC9C;AAAA,EACF;AAEA,QAAM,QAAoB;AAAA,IACxB,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IAET,IAAI,KAA2C;AAC7C,YAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,UAAI,CAAC,OAAO;AACV,iBAAS;AACT,eAAO;AAAA,MACT;AAEA,UAAI,MAAM,YAAY,UAAa,MAAM,WAAW,KAAK,IAAI,GAAG;AAC9D,gBAAQ,OAAO,GAAG;AAClB,iBAAS;AACT,iBAAS;AACT,eAAO;AAAA,MACT;AAGA,cAAQ,OAAO,GAAG;AAClB,cAAQ,IAAI,KAAK,KAAK;AACtB,eAAS;AACT,aAAO,MAAM;AAAA,IACf;AAAA,IAEA,IAAI,KAAa,OAAyB,KAAoB;AAC5D,YAAM,QAAQ,CAAC,QAAQ,IAAI,GAAG;AAG9B,UAAI,CAAC,MAAO,SAAQ,OAAO,GAAG;AAE9B,cAAQ,IAAI,KAAK;AAAA,QACf;AAAA,QACA,SAAS,QAAQ,SAAY,KAAK,IAAI,IAAI,MAAM;AAAA,MAClD,CAAC;AAED,eAAS;AACT,UAAI,MAAO,UAAS;AAEpB,UAAI,QAAQ,OAAO,WAAY,eAAc;AAAA,IAC/C;AAAA,IAEA,OAAO,KAAmB;AACxB,UAAI,QAAQ,OAAO,GAAG,EAAG,UAAS;AAAA,IACpC;AAAA,IAEA,IAAI,WAAW;AAEb,aAAO,EAAE,GAAG,SAAS;AAAA,IACvB;AAAA,IAEA,UAAgB;AACd,UAAI,eAAe,QAAW;AAC5B,sBAAc,UAAU;AACxB,qBAAa;AAAA,MACf;AACA,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;;;ACrMA,IAAAC,gBAKO;AAsHA,SAAS,mBACd,SACA,MACsB;AACtB,QAAM,EAAE,aAAa,YAAY,WAAW,QAAQ,SAAS,WAAAC,WAAU,IACrE;AAMF,QAAM,oBAAoB,CAAC,KAAa,WAAiC;AACvE,QAAI,CAACA,WAAW;AAChB,UAAM,QAAQ,eAAeA,YAAW;AAAA,MACtC,QAAQ,SAAS,OAAO;AAAA,MACxB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK,KAAK,IAAI;AAAA,IAChB,CAAC;AACD,UAAM,OAAO;AAAA,MACX,IAAI;AAAA,MACJ,QAAQ,WAAW;AAAA,MACnB;AAAA,MACA;AAAA,IACF;AACA,gCAASA,YAAW,KAAK;AAAA,EAC3B;AAKA,QAAM,WAAiC;AAAA,IACrC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,iBAAiB;AAAA,EACnB;AAKA,QAAM,gBAA0C,YAAY,MAAM;AAAA,IAChE,CAAC,UAAU;AAAA,MACT,OAAO,KAAK,YAAQ,8BAAe,KAAK,KAAK,IAAI,MAAM;AAAA,MACvD,KAAK,KAAK;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,WAAW,CAAC,QAAwB,GAAG,SAAS,IAAI,GAAG;AAE7D,WAAS,iBACP,KACA,OACoC;AAIpC,UAAM,MACJ,UAAU,SAAY,EAAE,IAAI,IAAI,EAAE,KAAK,MAAM;AAC/C,WAAO,cAAc,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC;AAAA,EAC/C;AAOA,QAAM,WAAW,oBAAI,IAAmD;AAExE,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd,QAAQ,QAAQ;AAAA,IAChB,OAAO,QAAQ;AAAA;AAAA;AAAA;AAAA,IAKf,IAAI,WAAiC;AACnC,aAAO,EAAE,GAAG,SAAS;AAAA,IACvB;AAAA,IAEA,MAAM,IAAI,KAAoD;AAC5D,YAAM,KAAK,SAAS,GAAG;AACvB,YAAM,SAAS,MAAM,WAAW,IAAI,EAAE;AACtC,YAAM,eAAW,iCAAkB,MAAM;AACzC,UAAI,aAAa,QAAW;AAC1B,YAAI,aAAa,UAAU;AAKzB,cAAI;AACF,kBAAM,WAAW,OAAO,EAAE;AAAA,UAC5B,SAAS,OAAO;AACd,6BAAiB,UAAU,KAAK,KAAK;AAAA,UACvC;AAAA,QACF,OAAO;AACL,mBAAS;AACT,4BAAkB,KAAK,KAAK;AAC5B,iBAAO,SAAS;AAAA,QAClB;AAAA,MACF;AAIA,YAAM,WAAW,SAAS,IAAI,EAAE;AAChC,UAAI,UAAU;AACZ,iBAAS;AACT,0BAAkB,KAAK,KAAK;AAC5B,eAAO;AAAA,MACT;AAIA,eAAS;AACT,wBAAkB,KAAK,MAAM;AAE7B,YAAM,WAAW,YAAY;AAC3B,YAAI;AACF,gBAAM,QAAQ,MAAM,QAAQ,IAAI,GAAG;AACnC,cAAI,UAAU,OAAW,QAAO;AAEhC,gBAAM,OAAO,iBAAiB,KAAK,KAAK;AACxC,cAAI,MAAM;AAKR,gBAAI;AAQF,oBAAM,QAAQ,KAAK,MAAM;AACzB,oBAAM,WAAW,IAAI,QAAI,iCAAkB,OAAO,KAAK,GAAG,KAAK;AAG/D,uBAAS;AAAA,YACX,SAAS,OAAO;AACd,+BAAiB,OAAO,KAAK,KAAK;AAAA,YACpC;AAAA,UACF;AACA,iBAAO;AAAA,QACT,UAAE;AAIA,mBAAS,OAAO,EAAE;AAAA,QACpB;AAAA,MACF,GAAG;AACH,eAAS,IAAI,IAAI,OAAO;AACxB,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,IACJ,KACA,OACA,KACe;AAIf,eAAS;AAIT,YAAM,QAAQ,IAAI,KAAK,OAAO,GAAG;AAEjC,YAAM,OAAO,iBAAiB,KAAK,KAAK;AACxC,UAAI,CAAC,KAAM;AAMX,UAAI;AACF,cAAM,QAAQ,KAAK,MAAM;AACzB,cAAM,WAAW;AAAA,UACf,SAAS,GAAG;AAAA,cACZ,iCAAkB,OAAO,KAAK;AAAA,UAC9B;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,yBAAiB,OAAO,KAAK,KAAK;AAAA,MACpC;AAAA,IACF;AAAA,IAEA,MAAM,OAAO,KAA4B;AAEvC,eAAS;AAGT,YAAM,QAAQ,OAAO,GAAG;AAExB,UAAI;AACF,cAAM,WAAW,OAAO,SAAS,GAAG,CAAC;AAAA,MACvC,SAAS,OAAO;AACd,yBAAiB,UAAU,KAAK,KAAK;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,WAAS,iBACP,IACA,KACA,OACM;AACN,UAAM,UAAU,eAAe,OAAO,YAAY,EAAE,gBAAgB,GAAG;AACvE,QAAI,QAAQ;AACV,aAAO,KAAK,SAAS,UAAU,KAAK,CAAC;AAAA,IACvC,OAAO;AAKL,cAAQ,KAAK,SAAS,KAAK;AAAA,IAC7B;AAAA,EACF;AACF;;;AFvTA,SAAS,gBACPC,YACA,UACA,SACM;AACN,QAAM,YAAY,SAAS,OAAO;AAElC,QAAM,eAAW;AAAA,IACf,SAAS;AAAA,IACT;AAAA,IACAA,WAAU;AAAA,IACVA,WAAU;AAAA,EACZ;AACA,QAAM,eAAW;AAAA,IACf,SAAS;AAAA,IACT;AAAA,IACAA,WAAU;AAAA,IACVA,WAAU;AAAA,EACZ;AACA,QAAM,kBAAc;AAAA,IAClB,SAAS;AAAA,IACT;AAAA,IACAA,WAAU;AAAA,IACVA,WAAU;AAAA,EACZ;AAEA,WAAS,MAAM,OAAO,QAAuD;AAC3E,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,UAAU,eAAeA,YAAW;AAAA,MACxC,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AACD,YAAQ,OAAO,EAAE,IAAI,OAAO,IAAI;AAChC,gCAASA,YAAW,OAAO;AAE3B,QAAI;AACF,YAAM,SAAS,MAAM,SAAS,GAAG;AACjC,YAAMC,YAAW,KAAK,IAAI;AAC1B,YAAM,WAAW,eAAeD,YAAW;AAAA,QACzC,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,KAAKC;AAAA,MACP,CAAC;AACD,eAAS,aAAaA,YAAW;AACjC,eAAS,OAAO,EAAE,IAAI,OAAO,IAAI;AACjC,kCAASD,YAAW,QAAQ;AAC5B,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAMC,YAAW,KAAK,IAAI;AAC1B,YAAM,WAAW,eAAeD,YAAW;AAAA,QACzC,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,KAAKC;AAAA,MACP,CAAC;AACD,eAAS,aAAaA,YAAW;AACjC,eAAS,OAAO,EAAE,IAAI,OAAO,IAAI;AACjC,eAAS,QACP,eAAe,QACX,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,IACvC,EAAE,SAAS,OAAO,GAAG,EAAE;AAC7B,kCAASD,YAAW,QAAQ;AAC5B,YAAM;AAAA,IACR;AAAA,EACF;AAEA,WAAS,MAAM,OACb,KACA,OACA,QACkB;AAClB,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,UAAU,eAAeA,YAAW;AAAA,MACxC,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AAID,YAAQ,OAAO,EAAE,IAAI,OAAO,IAAI;AAChC,gCAASA,YAAW,OAAO;AAE3B,QAAI;AACF,YAAM,SAAS,KAAK,OAAO,GAAG;AAC9B,YAAMC,YAAW,KAAK,IAAI;AAC1B,YAAM,WAAW,eAAeD,YAAW;AAAA,QACzC,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,KAAKC;AAAA,MACP,CAAC;AACD,eAAS,aAAaA,YAAW;AACjC,eAAS,OAAO,EAAE,IAAI,OAAO,IAAI;AACjC,kCAASD,YAAW,QAAQ;AAAA,IAC9B,SAAS,KAAK;AACZ,YAAMC,YAAW,KAAK,IAAI;AAC1B,YAAM,WAAW,eAAeD,YAAW;AAAA,QACzC,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,KAAKC;AAAA,MACP,CAAC;AACD,eAAS,aAAaA,YAAW;AACjC,eAAS,OAAO,EAAE,IAAI,OAAO,IAAI;AACjC,eAAS,QACP,eAAe,QACX,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,IACvC,EAAE,SAAS,OAAO,GAAG,EAAE;AAC7B,kCAASD,YAAW,QAAQ;AAC5B,YAAM;AAAA,IACR;AAAA,EACF;AAEA,WAAS,SAAS,OAAO,QAA+B;AACtD,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,UAAU,eAAeA,YAAW;AAAA,MACxC,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,OAAO;AAAA,MACP,SAAS;AAAA,MACT,KAAK;AAAA,IACP,CAAC;AACD,YAAQ,OAAO,EAAE,IAAI,UAAU,IAAI;AACnC,gCAASA,YAAW,OAAO;AAE3B,QAAI;AACF,YAAM,YAAY,GAAG;AACrB,YAAMC,YAAW,KAAK,IAAI;AAC1B,YAAM,WAAW,eAAeD,YAAW;AAAA,QACzC,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,KAAKC;AAAA,MACP,CAAC;AACD,eAAS,aAAaA,YAAW;AACjC,eAAS,OAAO,EAAE,IAAI,UAAU,IAAI;AACpC,kCAASD,YAAW,QAAQ;AAAA,IAC9B,SAAS,KAAK;AACZ,YAAMC,YAAW,KAAK,IAAI;AAC1B,YAAM,WAAW,eAAeD,YAAW;AAAA,QACzC,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,KAAKC;AAAA,MACP,CAAC;AACD,eAAS,aAAaA,YAAW;AACjC,eAAS,OAAO,EAAE,IAAI,UAAU,IAAI;AACpC,eAAS,QACP,eAAe,QACX,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,IACvC,EAAE,SAAS,OAAO,GAAG,EAAE;AAC7B,kCAASD,YAAW,QAAQ;AAC5B,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAWA,SAAS,sBACP,MACU;AAEV,QAAM,QAA+B,CAAC;AACtC,aAAW,MAAM,OAAO,KAAK,IAAI,EAAG,OAAM,EAAE,IAAI;AAEhD,QAAM,QAAkB,CAAC;AACzB,QAAM,QAAkB,CAAC;AAEzB,WAAS,MAAM,IAAkB;AAC/B,UAAM,IAAI,MAAM,EAAE;AAClB,QAAI,MAAM,QAAS;AACnB,QAAI,MAAM,QAAQ;AAChB,YAAM,aAAa,MAAM,QAAQ,EAAE;AACnC,YAAM,YAAY,MACf,MAAM,eAAe,KAAK,IAAI,UAAU,EACxC,OAAO,EAAE,EACT,KAAK,MAAM;AACd,YAAM,IAAI,MAAM,+BAA+B,SAAS,EAAE;AAAA,IAC5D;AAEA,UAAM,EAAE,IAAI;AACZ,UAAM,KAAK,EAAE;AAEb,UAAM,SAAS,KAAK,EAAE,EAAE,OAAO;AAC/B,QAAI,WAAW,QAAW;AACxB,UAAI,EAAE,UAAU,OAAO;AACrB,cAAM,IAAI;AAAA,UACR,UAAU,EAAE,6BAA6B,MAAM;AAAA,QACjD;AAAA,MACF;AACA,YAAM,MAAM;AAAA,IACd;AAEA,UAAM,IAAI;AACV,UAAM,EAAE,IAAI;AACZ,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,aAAW,MAAM,OAAO,KAAK,IAAI,GAAG;AAClC,QAAI,MAAM,EAAE,MAAM,QAAS,OAAM,EAAE;AAAA,EACrC;AAEA,SAAO;AACT;AAoBA,eAAsB,WACpBA,YACAE,cAA+B,CAAC,GACT;AACvB,QAAM,SAAuB,CAAC;AAK9B,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQA,WAAU,GAAG;AAC5D,UAAM,EAAE,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE,IAAI;AAExC,UAAM,cAAcF,WAAU,OAAO,MAAM,OAAO,EAAE,MAAM,OAAO;AAEjE,UAAM,UAAU;AAAA,MACd,WAAAA;AAAA,MACA,QAAQ;AAAA,MACR,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA,aAAa,iBAAiBA,YAAW,SAAS,SAAS,WAAW;AAAA,IACxE;AAEA,UAAM,WAAW,MAAM,KAAK,OAAO;AACnC,WAAO,OAAO,IAAI;AAAA,EACpB;AAQA,QAAM,gBAAgBE;AACtB,QAAM,QAAQ,sBAAsB,aAAa;AACjD,aAAW,WAAW,OAAO;AAC3B,UAAM,cAAc,cAAc,OAAO,EAAE;AAC3C,QAAI,CAAC,YAAa;AAElB,QAAI;AACJ,QAAI;AACJ,QAAI,YAAY,UAAU,QAAW;AAGnC,mBAAa,OAAO,YAAY,KAAK;AACrC,qBAAe,YAAY;AAAA,IAC7B,OAAO;AACL,UAAI,CAAC,OAAO,SAAS;AACnB,eAAO,UAAU,iBAAiB;AAAA,MACpC;AACA,mBAAa,OAAO;AACpB,qBAAe;AAAA,IACjB;AAMA,UAAM,oBAAoB,YAAY,aAAa;AAOnD,IAAAF,WAAU,OACP,MAAM,aAAa,EACnB,MAAM,OAAO,EACb;AAAA,MACC,UAAU,OAAO,4BAA4B,iBAAiB,UAAU,YAAY;AAAA,IACtF;AAEF,WAAO,OAAO,IAAI,mBAAmB,OAAO,OAAO,GAAG;AAAA,MACpD;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,QAAQA,WAAU,OAAO,MAAM,aAAa,EAAE,MAAM,OAAO;AAAA,MAC3D,WAAAA;AAAA,IACF,CAAC;AAAA,EACH;AAUA,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,MAAM,GAAG;AACxD,QAAI,YAAY,UAAW;AAC3B,oBAAgBA,YAAW,UAAU,OAAO;AAAA,EAC9C;AAEA,SAAO;AACT;AAkBO,SAAS,uBACd,WACA,mBACA,YACM;AAEN,QAAM,SAAS,oBAAI,IAA4B;AAC/C,aAAW,CAAC,SAAS,MAAM,KAAK,OAAO,QAAQ,SAAS,GAAG;AACzD,QAAI,kBAAkB,OAAO;AAC3B,aAAO,IAAI,QAAQ,kBAAkB,OAAO,CAAC;AAAA,EACjD;AACA,MAAI,OAAO,SAAS,EAAG;AAEvB,WAAS,WAAW,KAA0C;AAC5D,QAAI,CAAC,IAAK;AACV,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC9C,UAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,cAAM,WAAW,OAAO,IAAI,KAAK;AACjC,YAAI,SAAU,KAAI,GAAG,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAGA,aAAW,QAAQ;AAAA,IACjB,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,EACb,GAAG;AACD,QAAI,CAAC,KAAM;AACX,eAAW,OAAO,OAAO,OAAO,IAAI,GAAG;AACrC,iBAAY,IAA0C,GAAG;AAAA,IAC3D;AAAA,EACF;AACF;;;AJjaA,eAAsB,UACpB,YAC6B;AAC7B,QAAM,gBAAkC;AAAA,IACtC,eAAe,CAAC;AAAA,IAChB,eAAe,CAAC;AAAA,IAChB,KAAK;AAAA,IACL,UAAU;AAAA,EACZ;AAEA,QAAM,aAA2B,sBAAO,eAAe,YAAY;AAAA,IACjE,OAAO;AAAA,IACP,QAAQ;AAAA,EACV,CAAC;AAGD,QAAM,eAA8B;AAAA,IAClC,OAAO,WAAW,QAAQ;AAAA,IAC1B,SAAS,WAAW,QAAQ;AAAA,EAC9B;AACA,QAAM,aAAS,4BAAa,YAAY;AAGxC,QAAM,eAAe,EAAE,GAAG,OAAO,eAAe,GAAG,WAAW,QAAQ;AAEtE,QAAMG,aAAgC;AAAA,IACpC,SAAS;AAAA,IACT;AAAA,IACA,SAAS,WAAW,WAAW,CAAC;AAAA,IAChC,QAAQ,WAAW,UAAU,CAAC;AAAA,IAC9B,cAAc,CAAC;AAAA,IACf,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,IACT,SAAS;AAAA,IACT,OAAO,WAAW,SAAS,CAAC;AAAA,IAC5B,WAAW,oBAAI,IAAI;AAAA,IACnB;AAAA,IACA,IAAI,CAAC;AAAA,IACL,OAAO,CAAC;AAAA,IACR,aAAa,CAAC;AAAA,IACd,OAAO;AAAA,IACP,OAAO;AAAA,IACP,cAAc;AAAA,IACd,aAAa,CAAC;AAAA,IACd,UAAU,oBAAI,QAAQ;AAAA,IACtB,SAAS;AAAA,IACT,QAAQ;AAAA,MACN,WAAW,KAAK,IAAI;AAAA,MACpB,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,CAAC;AAAA,MACV,cAAc,CAAC;AAAA,MACf,SAAS,CAAC;AAAA,MACV,kBAAkB,CAAC;AAAA,MACnB,UAAU,CAAC;AAAA,IACb;AAAA,IACA,QAAQ,KAAK,IAAI;AAAA,IACjB,MAAM,WAAW,QAAQ,CAAC;AAAA,IAC1B,SAAS,CAAC;AAAA,IACV,SAAS,EAAE,cAAc,CAAC,EAAE;AAAA,IAC5B,aAAa;AAAA,IACb,YAAY,oBAAI,IAAI;AAAA,IACpB,MAAM;AAAA;AAAA,IACN,SAAS;AAAA;AAAA,IACT,KAAK;AAAA;AAAA,EACP;AAOA,MAAI,WAAW,SAAS,OAAW,CAAAA,WAAU,OAAO,WAAW;AAC/D,MAAI,WAAW,YAAY,OAAW,CAAAA,WAAU,UAAU,WAAW;AAIrE,MAAI,WAAW,SAAS,OAAW,QAAO,OAAO,WAAW;AAG5D,EAAAA,WAAU,OAAO;AAAA,IAAWA;AAAA,IAAW,CAAC,UACtC,aAAaA,YAAW,KAAK;AAAA,EAC/B;AAEA,EAAAA,WAAU,UAAU,cAAcA,YAAW,mBAAmB;AAGhE,EAAAA,WAAU,MAAM,UAAUA,UAAS;AAGnC,QAAM,YAAY,WAAW,UAAU,CAAC;AACxC,EAAAA,WAAU,SAAS,MAAM,WAAWA,YAAW,SAAS;AAMxD,yBAAuB,WAAWA,WAAU,QAAQ,UAAU;AAK9D,MAAI,CAACA,WAAU,OAAO,SAAS;AAC7B,IAAAA,WAAU,OAAO,UAAU,iBAAiB;AAAA,EAC9C;AAIA,EAAAA,WAAU,eAAe,MAAM;AAAA,IAC7BA;AAAA,IACA,WAAW,gBAAgB,CAAC;AAAA,EAC9B;AAGA,EAAAA,WAAU,eAAe,MAAM;AAAA,IAC7BA;AAAA,IACA,WAAW,gBAAgB,CAAC;AAAA,EAC9B;AAEA,SAAOA;AACT;;;ADpGA,IAAM,IAAI;AAOV,SAAS,mBAAkC;AACzC,QAAM,MAAM,EAAE;AACd,QAAM,MAAM,EAAE;AACd,MAAI,CAAC,OAAO,CAAC,IAAK,QAAO;AACzB,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,IAAI,SAAS,OAAO,QAAQ,OAAO,EAAE,CAAC;AAC7D,UAAM,SAAS,OAAO,OAAO,iCAAmB;AAChD,WAAO,OAAO,SAAS,IAAK,OAAO,OAAO,SAAS,CAAC,KAAK,OAAQ;AAAA,EACnE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,kBAAiC;AACxC,MAAI;AACF,WAAO,EAAE,QAAQ,aAAa,QAAQ,iCAAmB,KAAK;AAAA,EAChE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBAAiB,OAAqB;AAC7C,MAAI;AACF,MAAE,QAAQ,aAAa,QAAQ,mCAAqB,KAAK;AAAA,EAC3D,QAAQ;AAAA,EAER;AACF;AAOA,SAAS,mBAAmB,UAAwB;AAClD,MAAI;AACF,UAAM,MAAM,EAAE;AACd,QAAI,CAAC,IAAK;AACV,QAAI,IAAI,aAAa,QAAQ,iCAAmB,MAAM,UAAU;AAC9D,UAAI,aAAa,WAAW,iCAAmB;AAAA,IACjD;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAQA,SAAS,oBAA0B;AACjC,QAAM,MAAM,EAAE;AACd,QAAM,MAAM,EAAE;AACd,MAAI,CAAC,OAAO,CAAC,IAAK;AAClB,MAAI;AACF,UAAM,OAAO,IAAI,SAAS;AAC1B,UAAM,UAAU,KAAK,QAAQ,GAAG;AAChC,UAAM,OAAO,WAAW,IAAI,KAAK,MAAM,OAAO,IAAI;AAClD,UAAM,cAAc,WAAW,IAAI,KAAK,MAAM,GAAG,OAAO,IAAI;AAC5D,UAAM,OAAO,YAAY,QAAQ,GAAG;AACpC,UAAM,OAAO,QAAQ,IAAI,YAAY,MAAM,GAAG,IAAI,IAAI;AACtD,UAAM,SAAS,IAAI,IAAI,QAAQ,IAAI,YAAY,MAAM,OAAO,CAAC,IAAI,EAAE;AACnE,WAAO,OAAO,iCAAmB;AACjC,UAAM,QAAQ,OAAO,SAAS;AAC9B,QAAI,QAAQ;AAAA,MACV,CAAC;AAAA,MACD;AAAA,MACA,GAAG,IAAI,GAAG,QAAQ,IAAI,KAAK,KAAK,EAAE,GAAG,IAAI;AAAA,IAC3C;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAOA,SAAS,YAAY,MAAc,SAAqC;AACtE,MAAI,YAAY,OAAW,QAAO;AAClC,SAAO,CAAC,UAAU,KAAK,EAAE,GAAG,OAAO,QAAQ,CAAC;AAC9C;AAQA,SAAS,WAAW,MAAc,QAAoC;AACpE,MAAI,WAAW,OAAW,QAAO;AACjC,SAAO,CAAC,UAAU,KAAK,EAAE,GAAG,OAAO,OAAO,CAAC;AAC7C;AAWA,SAAS,eACP,UACA,YACM;AACN,MAAI,WAAW,WAAW;AACxB,eAAW,YAAY,WAAW,WAAW;AAC3C,eAAS,UAAU,IAAI,QAAQ;AAAA,IACjC;AAAA,EACF;AAEA,QAAM,UAAU,WAAW;AAC3B,MAAI,CAAC,QAAS;AAEd,QAAM,SAAS,SAAS,QAAQ;AAEhC,MAAI,aAAa,SAAS;AAIxB,UAAM,QAAQ,iBAAiB;AAC/B,UAAM,MAAM,SAAS,gBAAgB;AACrC,QAAI,CAAC,IAAK;AAIV,UAAM,iBAAa,sCAAuB,GAAG;AAC7C,QAAI,CAAC,YAAY;AACf,UAAI,UAAU,MAAM;AAGlB,iBAAS,OAAO,KAAK,8CAA8C;AACnE,2BAAmB,GAAG;AAAA,MACxB,OAAO;AAEL,iBAAS,OAAO,KAAK,uCAAuC;AAAA,MAC9D;AACA;AAAA,IACF;AACA,QAAI,WAAW,OAAO,QAAQ,SAAS;AACrC,eAAS,OAAO;AAAA,QACd;AAAA,MACF;AACA;AAAA,IACF;AAEA,qBAAiB,GAAG;AAGpB,QAAI,UAAU,KAAM,mBAAkB;AAEtC,QAAI;AACJ,UAAM,WAAO,mCAAoB;AAAA,MAC/B,KAAK,GAAG,QAAQ,GAAG,WAAW,WAAW,GAAG;AAAA,MAC5C,OAAO,WAAW;AAAA,MAClB,SAAS,EAAE,sBAAsB,QAAQ,QAAQ;AAAA,MACjD,UAAU,CAAC,WAAW;AACpB,YAAI,WAAW,IAAK;AAKpB,2BAAmB,GAAG;AACtB,YAAI,SAAU,UAAS,UAAU,OAAO,QAAQ;AAAA,MAClD;AAAA,IACF,CAAC;AAMD,mBAAW;AAAA,MACT,WAAW,YAAY,MAAM,SAAS,OAAO,GAAG,QAAQ,MAAM;AAAA,MAC9D;AAAA,QACE,QAAQ,QAAQ,UAAU;AAAA,QAC1B,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,QAC9D,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACnE;AAAA,IACF;AACA,aAAS,UAAU,IAAI,QAAQ;AAC/B,UAAM,aAAa,QAAQ;AAC3B,QAAI,eAAe,QAAW;AAC5B,eAAS,eAAe,MAAM;AAAA,IAChC;AACA;AAAA,EACF;AAIA,MAAI,QAAQ,UAAU,MAAO;AAG7B,QAAM,cAAc,QAAQ;AAC5B,MAAI,gBAAgB,QAAW;AAC7B,aAAS,eAAe,MAAM;AAAA,EAChC;AACA,WAAS,UAAU;AAAA,QACjB;AAAA,MACE;AAAA,YACE,mCAAoB;AAAA,UAClB,KAAK,GAAG,QAAQ,GAAG,WAAW,QAAQ,SAAS;AAAA,UAC/C,OAAO,QAAQ;AAAA,QACjB,CAAC;AAAA,QACD,SAAS;AAAA,MACX;AAAA,MACA,EAAE,QAAQ,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO;AAAA,IACzD;AAAA,EACF;AACF;AAEA,eAAsB,UACpB,YAC6B;AAC7B,eAAa,cAAc,CAAC;AAC5B,QAAM,WAAW,MAAM,UAAU,UAAU;AAI3C,iBAAe,UAAU,UAAU;AAGnC,QAAM,YAAY,UAAU,WAAW,WAAW,CAAC,CAAC;AAEpD,QAAM,EAAE,SAAS,MAAM,SAAS,OAAO,IAAI;AAO3C,MAAI,QAAS,OAAM,SAAS,QAAQ,WAAW,OAAO;AACtD,MAAI,KAAM,OAAM,SAAS,QAAQ,QAAQ,IAAI;AAC7C,MAAI,QAAS,OAAM,SAAS,QAAQ,WAAW,OAAO;AACtD,MAAI,OAAQ,OAAM,SAAS,QAAQ,UAAU,MAAM;AAEnD,MAAI,SAAS,OAAO,IAAK,OAAM,SAAS,QAAQ,KAAK;AAMrD,MAAI,aAAqB,SAAS;AAElC,QAAM,UAAU,OAAO,OAAO,SAAS,OAAO;AAK9C,QAAM,gBAAgB,QAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,OAAO;AAEpE,MAAI,eAAe;AACjB,iBAAa,cAAc;AAAA,EAC7B,WAAW,QAAQ,SAAS,GAAG;AAE7B,iBAAa,QAAQ,CAAC,EAAE;AAAA,EAC1B;AAEA,SAAO;AAAA,IACL,WAAW;AAAA,IACX,KAAK;AAAA,EACP;AACF;","names":["collector","import_core","import_core","import_core","collector","collector","import_core","clone","import_core","import_core","import_core","collector","import_core","import_core","collector","collector","initTransformers","finished","result","collector","collector","require","collector","on","option","collector","queued","event","isInitialized","cacheMiss","batchState","destIdResolved","destStatus","outcome","import_core","collector","collector","collector","import_core","import_core","import_core","collector","prepareEvent","finished","import_core","collector","collector","import_core","import_core","collector","collector","finished","initStores","collector"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/code.ts","../src/constants.ts","../src/consent.ts","../src/collector-next.ts","../src/destination.ts","../src/observerEmit.ts","../src/state.ts","../src/cache.ts","../src/wrapEnv.ts","../src/sanitizeArgs.ts","../src/on.ts","../src/report-error.ts","../src/buffers.ts","../src/breaker.ts","../src/source.ts","../src/transformer.ts","../src/timeout.ts","../src/pending.ts","../src/handle.ts","../src/shutdown.ts","../src/flow.ts","../src/collector.ts","../src/push.ts","../src/command.ts","../src/elb.ts","../src/store.ts","../src/cache-store.ts","../src/store-cache-wrapper.ts"],"sourcesContent":["export * from './types';\n\nexport * from './constants';\n\nexport * from './consent';\nexport { runCollectorNext } from './collector-next';\nexport type { CollectorNextResult } from './collector-next';\nexport * from './flow';\nexport * from './push';\nexport * from './report-error';\nexport {\n isBreakerProbePermitted,\n resolveBreakerConfig,\n DEFAULT_BREAKER_THRESHOLD,\n DEFAULT_BREAKER_COOLDOWN_MS,\n} from './breaker';\nexport type { BreakerConfig, StepOutcome } from './breaker';\nexport {\n addDestination,\n createPushResult,\n destinationInit,\n destinationPush,\n initDestinations,\n mergeEnvironments,\n pushToDestinations,\n registerDestination,\n} from './destination';\nexport {\n commonHandleCommand,\n completeEvent,\n createEvent,\n enrichEvent,\n prepareEvent,\n runCollector,\n} from './handle';\nexport {\n callDestinationOn,\n enterCascade,\n fireCallbacks,\n isRequireSatisfied,\n isStateDelivery,\n isStatePresent,\n on,\n onApply,\n redeliverStateAtRun,\n setMark,\n shouldDeliver,\n} from './on';\nexport * from './source';\nexport {\n runTransformerChain,\n runTransformerBefore,\n transformerPush,\n transformerInit,\n} from './transformer';\nexport { wrapEnv } from './wrapEnv';\nexport { getCacheStore } from './cache';\n","import type { Destination, Mapping, On, WalkerOS } from '@walkeros/core';\n\nexport interface Settings {\n scripts?: string[];\n init?: string;\n on?: string;\n push?: string;\n pushBatch?: string;\n}\n\nexport interface CodeMapping extends Mapping.Rule<CodeMapping> {\n push?: string;\n pushBatch?: string;\n}\n\nexport type Types = Destination.Types<Settings, CodeMapping>;\nexport type Config = Destination.Config<Types>;\nexport type Context = Destination.Context<Types>;\nexport type PushContext = Destination.PushContext<Types>;\nexport type PushBatchContext = Destination.PushBatchContext<Types>;\n\nexport type InitFn = (context: Context) => void;\nexport type OnFn = (type: On.Types, context: Context) => void;\nexport type PushFn = (event: WalkerOS.Event, context: PushContext) => void;\nexport type PushBatchFn = (\n batch: Destination.Batch<CodeMapping>,\n context: PushBatchContext,\n) => WalkerOS.PromiseOrValue<void | Destination.BatchOutcome>;\n","import type { Collector } from '@walkeros/core';\nimport type { CommandTypes, StorageType } from './types/collector';\n\nexport const Commands: Record<CommandTypes, Collector.CommandType> = {\n Action: 'action',\n Actions: 'actions',\n Config: 'config',\n Consent: 'consent',\n Context: 'context',\n Custom: 'custom',\n Destination: 'destination',\n Elb: 'elb',\n Globals: 'globals',\n Hook: 'hook',\n Init: 'init',\n Link: 'link',\n On: 'on',\n Prefix: 'data-elb',\n Ready: 'ready',\n Run: 'run',\n Scoped: '_',\n Session: 'session',\n Shutdown: 'shutdown',\n User: 'user',\n Walker: 'walker',\n} as const;\n\nconst UtilsStorage: { [key: string]: StorageType } = {\n Cookie: 'cookie',\n Local: 'local',\n Session: 'session',\n} as const;\n\nconst Utils = {\n Storage: UtilsStorage,\n};\n\nexport const Const = {\n Commands,\n Utils,\n};\n\nexport default Const;\n","import type { Collector, WalkerOS } from '@walkeros/core';\nimport { assign } from '@walkeros/core';\n\n/**\n * Processes consent data: coerces to boolean, updates collector state.\n * Does NOT notify or process queues — caller handles that.\n */\nexport function processConsent(\n collector: Collector.Instance,\n data: WalkerOS.Consent,\n): { update: WalkerOS.Consent } {\n const update: WalkerOS.Consent = {};\n Object.entries(data).forEach(([name, granted]) => {\n update[name] = !!granted;\n });\n\n collector.consent = assign(collector.consent, update);\n\n return { update };\n}\n","import type {\n Collector,\n Ingest,\n RespondFn,\n Transformer,\n WalkerOS,\n} from '@walkeros/core';\nimport { createIngest } from '@walkeros/core';\nimport { completeEvent } from './handle';\nimport { emitCollectorDrop } from './observerEmit';\nimport { runTransformerChain } from './transformer';\n\n/** Chain path of the collector's own chain (`collector.config.next`). */\nexport const COLLECTOR_NEXT_PATH = 'collector.next';\n\n/** What `collector.next` hands to the destination fan-out. */\nexport interface CollectorNextResult {\n /**\n * Every finished copy, in order, with its own ingest; each event is\n * completed to a full event. One copy without a fork, one per surviving\n * fork after a `many` or a `Result[]` return, and none when the chain\n * dropped or halted the event.\n */\n copies: Transformer.ChainCopy<WalkerOS.Event>[];\n /** The respond in scope after the chain (a wrapped one if the chain set it). */\n respond?: RespondFn;\n /** Set when a route stop or a transformer ended every copy. */\n dropped?: true;\n}\n\n/**\n * Runs the collector's own chain (`collector.config.next`) for one completed\n * event, through the one chain runner. Called once per event by\n * `pushToDestinations`, before the event enters `collector.queue` and the\n * destination fan-out, so consent replay and late-destination backfill\n * deliver post-chain events and never run it again.\n *\n * A drop (route `stop` or a transformer returning `false`) on every copy\n * emits one `collector.push` `skip` / `dropped` record and counts the event\n * in; a `cache.stop` HIT halts delivery without a drop record, as at\n * `source.next`.\n */\nexport async function runCollectorNext(\n collector: Collector.Instance,\n event: WalkerOS.Event,\n meta: { id?: string; ingest?: Ingest; respond?: RespondFn } = {},\n): Promise<CollectorNextResult> {\n const ingest = meta.ingest ?? createIngest(meta.id || 'unknown');\n const next = collector.config.next;\n if (next === undefined) {\n return { copies: [{ event, ingest }], respond: meta.respond };\n }\n\n const result = await runTransformerChain(\n collector,\n collector.transformers || {},\n next,\n event,\n ingest,\n meta.respond,\n COLLECTOR_NEXT_PATH,\n );\n const respond = result.respond ?? meta.respond;\n\n if (result.copies.length === 0) {\n collector.logger.debug(\n `Event dropped by collector.next${\n result.droppedBy ? ` (${result.droppedBy})` : ''\n }`,\n );\n emitCollectorDrop(\n collector,\n event,\n ingest,\n result.droppedBy,\n COLLECTOR_NEXT_PATH,\n );\n return { copies: [], respond, dropped: true };\n }\n\n // A `cache.stop` HIT: the chain halted on purpose, nothing is delivered.\n if (result.stopped) return { copies: [], respond };\n\n // The runner owns identity (every copy keeps or derives its id). Only\n // missing fields are completed: the chain's edits to globals, user and\n // consent stand.\n return {\n copies: result.copies.map((copy) => ({\n event: completeEvent(collector, copy.event, copy.ingest),\n ingest: copy.ingest,\n })),\n respond,\n };\n}\n","import type {\n Cache,\n Collector,\n WalkerOS,\n Elb,\n Destination,\n Transformer,\n Ingest,\n RespondFn,\n Simulation,\n} from '@walkeros/core';\nimport {\n assign,\n createMappingRoot,\n clone,\n compileCache,\n checkCache,\n storeCache,\n createIngest,\n debounce,\n emitStep,\n getId,\n getGrantedConsent,\n isDefined,\n isFunction,\n isObject,\n OBSERVE_ENV_KEY,\n processEventMapping,\n stepId,\n tryCatchAsync,\n useHooks,\n} from '@walkeros/core';\nimport { journeyFields, stepError, stepState } from './observerEmit';\nimport { compileStepState, runStepState, warnStateOff } from './state';\nimport { wrapEnv } from './wrapEnv';\nimport { attachCalls } from './sanitizeArgs';\nimport {\n beginInitFlush,\n callDestinationOn,\n catchUpDestinationState,\n endInitFlush,\n enterCascade,\n getStateHold,\n isStateDelivery,\n isStateDeliveryInFlight,\n markStateLost,\n owesDestinationState,\n} from './on';\nimport type { DestinationDelivery } from './on';\nimport { resolveDestinationTimeout, withTimeout } from './timeout';\nimport { runTransformerChain, extractChainProperty } from './transformer';\nimport { getCacheStore } from './cache';\nimport {\n pushBounded,\n resetOverflowFlag,\n seededQueueMax,\n warnOverflowOnce,\n} from './buffers';\nimport {\n DEFAULT_DLQ_MAX,\n bumpDropped,\n ensureDestStatus,\n buildReportError,\n errorMeta,\n} from './report-error';\nimport { reconcilePending } from './pending';\nimport { runCollectorNext } from './collector-next';\nimport {\n isBreakerOpen,\n recordStepOutcome,\n releaseProbe,\n resolveBreakerConfig,\n} from './breaker';\n\nconst DEFAULT_QUEUE_MAX = 1_000;\n/** Default upper-bound on entries per batch. Caps unbounded growth under sustained load. */\nconst DEFAULT_BATCH_SIZE = 1_000;\n/** Default upper-bound on batch age in ms. Forces flush even if debounce keeps resetting. */\nconst DEFAULT_BATCH_AGE = 30_000;\n\n/**\n * Sentinel returned by {@link destinationPush} when an event was enqueued\n * into a batch (not delivered synchronously). The aggregation pass in\n * {@link pushToDestinations} reads this to skip the per-event `count`\n * increment; counters are bumped by the flush callback instead, after\n * `pushBatch` resolves. Per PROD-004 plan Q9: increment on successful\n * flush per entry, not on enqueue.\n */\nconst BATCHED_RESULT: { batched: true } = Object.freeze({ batched: true });\n\nfunction isBatchedResult(value: unknown): boolean {\n return value === BATCHED_RESULT;\n}\n\n/**\n * Narrows a `pushBatch` return value to a {@link Destination.BatchOutcome}.\n * A destination returning `void` (the historical contract) yields whole-batch\n * semantics and never enters the partial-failure path.\n */\nfunction isBatchOutcome(value: unknown): value is Destination.BatchOutcome {\n return (\n isObject(value) && Array.isArray((value as { failed?: unknown }).failed)\n );\n}\n\n/**\n * Reserved buffer key for the destination-wide default batch created by\n * `config.batch`. A produced mappingKey is `\"<entity> <action>\"` with both\n * segments guaranteed non-empty (getMappingEvent returns no key when either\n * is empty, packages/core/src/mapping.ts:24-25), so no event-derived key can\n * begin with a space. The leading space here therefore never collides with a\n * rule buffer or the `'* *'` fallback.\n */\nconst BATCH_ALL_KEY = ' batch-all';\n\n/**\n * Normalize a batch config value to the canonical `{ wait?, size?, age? }`\n * shape. A bare number is treated as `wait` (legacy form). `undefined`\n * normalizes to an empty object so callers can chain `??` lookups.\n */\nfunction normalizeBatchOptions(\n value: number | Destination.BatchOptions | undefined,\n): { wait?: number; size?: number; age?: number } {\n if (value === undefined) return {};\n if (typeof value === 'number') return { wait: value };\n return { wait: value.wait, size: value.size, age: value.age };\n}\n\n/**\n * Adds a new destination to the collector.\n *\n * @param collector - The walkerOS collector instance.\n * @param data - The destination's init data.\n * @returns The result of the push operation.\n */\nexport async function addDestination(\n collector: Collector.Instance,\n data: Destination.Init,\n): Promise<Elb.PushResult> {\n const {\n code,\n config: dataConfig = {},\n env = {},\n before,\n next,\n cache,\n state,\n } = data;\n\n // Validate that code has a push method\n if (!isFunction(code.push)) {\n return createPushResult({\n ok: false,\n failed: {\n invalid: {\n type: 'invalid',\n error: 'Destination code must have a push method',\n },\n },\n });\n }\n\n // Code defaults sit under the caller's config, the same merge\n // registerDestination applies, so a runtime destination keeps defaults such\n // as a code-level `batch` and the require check below sees them too.\n const baseConfig = { ...code.config, ...(dataConfig || { init: false }) };\n // Merge before, next, and cache into config if provided at root level\n let config = before ? { ...baseConfig, before } : { ...baseConfig };\n if (next) config = { ...config, next };\n if (cache) config = { ...config, cache };\n if (state !== undefined && config.state === undefined)\n config = { ...config, state };\n\n let id = config.id; // Use given id\n if (!id) {\n // Generate a new id if none was given (lowercase alpha only for readability)\n do {\n id = getId(5, 'abcdefghijklmnopqrstuvwxyz');\n } while (collector.destinations[id] || collector.pending.destinations[id]);\n }\n\n warnStateOff(collector, stepId('destination', id), config.state);\n\n // Honor `require`: a runtime destination with a require gate must wait for the\n // collector's current state to satisfy it, exactly like a startup destination\n // (initDestinations). Without this, addDestination registered + pushed\n // regardless of require. Route it through pending + reconcile: reconcile\n // activates it immediately if current state already satisfies it, otherwise it\n // stays pending until a later state change/run reconcile.\n if (config.require?.length) {\n // Store the raw Init def (before/next/cache/state at root) exactly as\n // initDestinations does; registerDestination folds the chain props on\n // activation. The map key carries the resolved id.\n collector.pending.destinations[id] = data;\n await reconcilePending(collector);\n const activated = collector.destinations[id];\n if (activated) {\n return pushToDestinations(collector, undefined, {}, { [id]: activated });\n }\n return createPushResult({ ok: true });\n }\n\n const destination: Destination.Instance = {\n ...code,\n config,\n env: mergeEnvironments(code.env, env),\n };\n\n // Add the destination\n collector.destinations[id] = destination;\n\n // Process previous events if not disabled\n if (destination.config.queue !== false)\n destination.queuePush = [...collector.queue];\n\n // A runtime destination catches up on state recorded before it existed, the\n // same way a pending destination does on activation, so its on() runs\n // before the replayed events are pushed.\n await catchUpDestinationState(collector, destination, id);\n\n return pushToDestinations(collector, undefined, {}, { [id]: destination });\n}\n\n/**\n * Mark the started destination deliveries whose destination is held right\n * now, just before a flush: that flush parks their events.\n */\nexport function markHeldForDrain(deliveries: DestinationDelivery[]): void {\n for (const delivery of deliveries)\n if (getStateHold(delivery.destination)) delivery.drain = true;\n}\n\n/**\n * Wait for started destination deliveries, each on its own: as soon as one\n * settles and its destination is no longer held, the events parked for it\n * during the flush are pushed to that destination alone. A slow delivery\n * delays only its own destination. A FatalError from a delivery propagates.\n * Returns the result of every such push.\n */\nexport async function settleDestinationDeliveries(\n collector: Collector.Instance,\n deliveries: DestinationDelivery[],\n): Promise<Elb.PushResult[]> {\n const drained = await Promise.all(\n deliveries.map(async ({ id, destination, done, drain }) => {\n await done;\n if (\n drain &&\n collector.allowed &&\n !getStateHold(destination) &&\n destination.queuePush?.length &&\n collector.destinations[id] === destination\n )\n return pushToDestinations(\n collector,\n undefined,\n {},\n { [id]: destination },\n );\n return undefined;\n }),\n );\n return drained.filter(isDefined);\n}\n\n/**\n * Fold the results of per-destination drains into a flush result, so a\n * command reports every destination its events reached. A destination queued\n * in the flush and done or failed after its drain is reported by its latest\n * outcome.\n */\nexport function mergePushResults(\n base: Elb.PushResult,\n drains: Elb.PushResult[],\n): Elb.PushResult {\n if (!drains.length) return base;\n const done = { ...(base.done ?? {}) };\n const queued = { ...(base.queued ?? {}) };\n const failed = { ...(base.failed ?? {}) };\n for (const drain of drains) {\n for (const [id, ref] of Object.entries(drain.done ?? {})) {\n done[id] = ref;\n delete queued[id];\n }\n for (const [id, ref] of Object.entries(drain.failed ?? {})) {\n failed[id] = ref;\n delete queued[id];\n }\n Object.assign(queued, drain.queued ?? {});\n }\n const merged: Elb.PushResult = {\n ...base,\n ok: base.ok && drains.every((drain) => drain.ok),\n };\n delete merged.done;\n delete merged.queued;\n delete merged.failed;\n if (Object.keys(done).length) merged.done = done;\n if (Object.keys(queued).length) merged.queued = queued;\n if (Object.keys(failed).length) merged.failed = failed;\n return merged;\n}\n\n/**\n * Pushes an event to all or a subset of destinations.\n *\n * A completed event first runs the collector's own chain\n * (`collector.config.next`), once, and every copy it hands back is delivered.\n * A flush call (no event) delivers what the destinations have queued and\n * never runs the chain: queued events are already post-chain.\n *\n * @param collector - The walkerOS collector instance.\n * @param event - The event to push.\n * @param meta - Optional metadata with id and ingest.\n * @param destinations - The destinations to push to.\n * @returns The result of the push operation.\n */\nexport async function pushToDestinations(\n collector: Collector.Instance,\n event?: WalkerOS.Event,\n meta: {\n id?: string;\n ingest?: Ingest;\n respond?: RespondFn;\n } = {},\n destinations?: Collector.Destinations,\n): Promise<Elb.PushResult> {\n // Check if collector is allowed to push\n if (!collector.allowed) return createPushResult({ ok: false });\n\n if (!event)\n return deliverToDestinations(collector, undefined, meta, destinations);\n\n const next = await runCollectorNext(collector, event, meta);\n if (next.copies.length === 0)\n return createPushResult({\n ok: true,\n ...(next.dropped ? { dropped: true } : {}),\n });\n\n // Each copy is delivered in order, as its own event with its own ingest.\n // The first delivery's result is reported, as for a source-level fan-out.\n const results: Elb.PushResult[] = [];\n for (const copy of next.copies) {\n results.push(\n await deliverToDestinations(\n collector,\n copy.event,\n { id: meta.id, ingest: copy.ingest, respond: next.respond },\n destinations,\n ),\n );\n }\n return results[0];\n}\n\n/**\n * Delivers one event (or, without one, the queued events only) to all or a\n * subset of destinations. Module-private: every caller goes through\n * `pushToDestinations`, so `collector.next` runs exactly once per event.\n */\nasync function deliverToDestinations(\n collector: Collector.Instance,\n event: WalkerOS.Event | undefined,\n meta: {\n id?: string;\n ingest?: Ingest;\n respond?: RespondFn;\n },\n destinations?: Collector.Destinations,\n): Promise<Elb.PushResult> {\n const { user } = collector;\n\n // Add event to the collector queue (bounded; FIFO drop-oldest on overflow)\n if (event) {\n const queueMax = seededQueueMax(collector.config.queueMax);\n const result = pushBounded(collector.queue, event, { max: queueMax });\n if (result.dropped > 0) {\n const droppedCount = bumpDropped(\n collector.status,\n stepId('collector'),\n 'queue',\n result.dropped,\n );\n warnOverflowOnce(\n collector.queue,\n collector.logger,\n 'collector.queue overflow; oldest events dropped',\n {\n buffer: 'queue',\n cap: queueMax,\n droppedCount,\n },\n );\n } else if (collector.queue.length < queueMax) {\n resetOverflowFlag(collector.queue);\n }\n collector.status.in++;\n }\n\n // Use given destinations or use internal destinations\n if (!destinations) destinations = collector.destinations;\n\n // Tests and partially initialized collectors may leave `transformers`\n // unset; routes then resolve against an empty set.\n const transformers: Transformer.Transformers = collector.transformers || {};\n\n const results = await Promise.all(\n // Process all destinations in parallel\n Object.entries(destinations || {}).map(async ([id, destination]) => {\n // Disabled destinations are completely skipped — no queuing, no init, no processing\n if (destination.config.disabled) {\n return { id, destination, skipped: true };\n }\n\n // Canonical id: the breaker gate, the failure/success accounting, and any\n // aggregation MUST all key on the SAME id. A destination whose runtime\n // `config.id` differs from its map key would otherwise touch two\n // different breaker entries (gate vs accounting), so failures never\n // accumulate against the entry the gate inspects and the breaker never\n // opens. Resolve once here and thread it through the result.\n const canonicalId = destination.config.id || id;\n const breakerKey = stepId('destination', canonicalId);\n const breakerConfig = resolveBreakerConfig(destination.config.breaker);\n\n // Circuit-breaker gate (same precedence as `config.disabled`): when the\n // breaker is open, skip the event (counted as skipped, never pushed).\n // Presence-gated: inert unless `config.breaker` is set.\n if (\n breakerConfig &&\n isBreakerOpen(\n collector.status.breakers,\n breakerKey,\n breakerConfig.cooldown,\n )\n ) {\n return { id, destination, skipped: true };\n }\n\n // Probe-settle helpers. When the gate above admitted a half-open probe,\n // EVERY post-gate path must settle it: either record an outcome (the\n // event reached the transport) or release the probe (it never did).\n // Otherwise `probing` stays true and the breaker deadlocks half-open.\n // Both are presence-gated and internally no-op unless half-open+probing.\n const recordProbe = (outcome: 'transport-failure' | 'success') => {\n if (breakerConfig) {\n recordStepOutcome(\n collector.status.breakers,\n breakerKey,\n outcome,\n breakerConfig.threshold,\n breakerConfig.cooldown,\n );\n }\n };\n const releaseProbeSlot = () => {\n if (breakerConfig) releaseProbe(collector.status.breakers, breakerKey);\n };\n\n // Return events to this destination's own queue. Bounded; FIFO\n // drop-oldest on overflow.\n const requeue = (events: WalkerOS.Events) => {\n if (!events.length) return;\n if (!destination.queuePush) destination.queuePush = [];\n const queuePush = destination.queuePush;\n const destId = destination.config.id || id;\n const bound = {\n max: destination.config.queueMax ?? DEFAULT_QUEUE_MAX,\n };\n let totalDropped = 0;\n for (const queued of events) {\n const r = pushBounded(queuePush, queued, bound);\n totalDropped += r.dropped;\n }\n if (totalDropped > 0) {\n // Ensure status entry exists for early-overflow paths.\n ensureDestStatus(collector, destId);\n const droppedCount = bumpDropped(\n collector.status,\n stepId('destination', destId),\n 'queue',\n totalDropped,\n );\n warnOverflowOnce(\n queuePush,\n collector.logger.scope(destination.type || 'unknown'),\n 'destination.queuePush overflow; oldest events dropped',\n {\n buffer: 'queuePush',\n destination: destId,\n cap: bound.max,\n droppedCount,\n },\n );\n } else if (queuePush.length < bound.max) {\n resetOverflowFlag(queuePush);\n }\n };\n\n // A held destination retries its owed state before its push, so a\n // handler that failed once and would settle now recovers without waiting\n // for another state command. Rate-limited by the hold's own age to one\n // attempt per timeout window, and never while a state delivery to it is\n // running: a permanently hung handler costs one bounded wait per window,\n // never one per event. The retry is inside this destination's own\n // closure, so siblings are untouched.\n // An initialized destination that is not held but owes state (a cell\n // merged at `walker run` before the run's re-delivery reached it)\n // receives that state before this push, the same way a held one\n // retries, but without waiting for a window.\n if (\n destination.on &&\n destination.config.init &&\n !getStateHold(destination) &&\n !isStateDeliveryInFlight(destination) &&\n owesDestinationState(collector, destination)\n )\n await catchUpDestinationState(collector, destination, id);\n\n const hold = getStateHold(destination);\n if (\n hold &&\n !isStateDeliveryInFlight(destination) &&\n Date.now() - hold.since >=\n resolveDestinationTimeout(destination.config.timeout)\n )\n await catchUpDestinationState(collector, destination, id);\n\n // State hold: a state delivery to this destination is running or did\n // not settle. Its events stay in its own queue, nothing is delivered,\n // and the queue is not drained. Held, not dropped.\n if (getStateHold(destination)) {\n releaseProbeSlot(); // probe admitted but the destination is held\n if (!event) return { id, destination, skipped: true };\n const held = [clone(event)];\n requeue(held);\n return { id, destination, queue: held };\n }\n\n // Queued events: refresh consent (full replace — stale consent must not persist).\n // User merge happens for all events below in allowedEvents.map.\n let currentQueue = (destination.queuePush || []).map((event) => ({\n ...event,\n consent: collector.consent,\n }));\n destination.queuePush = [];\n\n // Current event: added as-is (consent is already fresh from createEvent).\n if (event) currentQueue.push(clone(event));\n\n // Clone ingest for this destination (prevents cross-destination races in Promise.all)\n const destIngest: Ingest = meta.ingest\n ? {\n ...meta.ingest,\n _meta: { ...meta.ingest._meta, path: [...meta.ingest._meta.path] },\n }\n : createIngest('unknown');\n\n // If no events and no queued on events, skip this destination\n if (!currentQueue.length && !destination.queueOn?.length) {\n releaseProbeSlot(); // probe admitted but no event to push\n return { id, destination, skipped: true };\n }\n\n // If only on events queued (no push events), still init to flush queueOn.\n // Direct try/catch + logger.error here is intentional. Previously this\n // used tryCatchAsync(destinationInit) without an onError callback, which\n // silently returned undefined when init threw, hiding real failures on\n // the queueOn-only path. Mirrors the same pattern used below at the main\n // init call site so failures are never silent on either branch.\n if (!currentQueue.length && destination.queueOn?.length) {\n // Consent gate (sole-gate invariant): this branch would init the\n // destination purely to flush queued on() events, but there is no push\n // event whose individual consent could apply, so collector consent is\n // the complete basis. Never init a consent-gated destination while its\n // required consent is denied. Self-heals: handle.ts runs\n // pushToDestinations after every state command, so the grant command\n // re-enters here with consent satisfied and inits then.\n if (!getGrantedConsent(destination.config.consent, collector.consent)) {\n releaseProbeSlot(); // probe admitted but consent gate denies push\n return { id, destination, skipped: true };\n }\n let isInitialized = false;\n try {\n isInitialized = await destinationInit(\n collector,\n destination,\n id,\n true,\n );\n } catch (err) {\n collector.status.failed++;\n const destType = destination.type || 'unknown';\n collector.logger.scope(destType).error('destination init failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n // A probe whose init throws is a real transport failure: re-open.\n recordProbe('transport-failure');\n }\n // The flush held the destination: there are no events of this call\n // to requeue, and any parked by a concurrent push stay queued.\n if (getStateHold(destination)) {\n releaseProbeSlot();\n return { id, destination, skipped: true };\n }\n // Events parked by a concurrent push while the flush was running go\n // out with this call, through the consent gate below.\n if (isInitialized && destination.queuePush?.length) {\n currentQueue = destination.queuePush.map((queued) => ({\n ...queued,\n consent: collector.consent,\n }));\n destination.queuePush = [];\n } else {\n // queueOn-only flush exercises no push, so a successful/false-returning\n // init releases the probe (the transport-failure path already re-opened\n // it, where release is a no-op).\n releaseProbeSlot();\n return { id, destination, skipped: !isInitialized };\n }\n }\n\n // Per-event consent gate: granted events keep only their granted\n // states and are delivered, denied events emit a skip state so\n // observers see the gate decision, and stay queued. The collector state\n // is read at call time: this closure awaits, and a consent command can\n // run in between.\n const admit = (queue: WalkerOS.Events) => {\n const consent = collector.consent;\n const allowed: WalkerOS.Events = [];\n const skipped = queue.filter((queuedEvent) => {\n const grantedConsent = getGrantedConsent(\n destination.config.consent, // Required\n consent, // Current collector state\n queuedEvent.consent, // Individual event state\n );\n\n if (grantedConsent) {\n queuedEvent.consent = grantedConsent; // Save granted consent states only\n\n allowed.push(queuedEvent); // Add to allowed queue\n return false; // Remove from destination queue\n }\n\n const skipState = stepState(\n collector,\n stepId('destination', id),\n 'destination',\n 'skip',\n typeof queuedEvent.id === 'string' ? queuedEvent.id : '',\n Date.now(),\n journeyFields(queuedEvent, destIngest, collector),\n );\n skipState.skipReason = 'consent';\n if (consent) skipState.consent = { ...consent };\n if (destination.config.consent) {\n skipState.meta = { required: { ...destination.config.consent } };\n }\n emitStep(collector, skipState);\n\n return true; // Keep denied events in the queue\n });\n return { allowed, skipped };\n };\n\n const admittedWith = collector.consent;\n const { allowed: allowedEvents, skipped: skippedEvents } =\n admit(currentQueue);\n\n // Add skipped (consent-denied) events back to the queue.\n requeue(skippedEvents);\n\n // Execution shall not pass if no events are allowed\n if (!allowedEvents.length) {\n releaseProbeSlot(); // probe admitted but every event was re-queued\n return { id, destination, queue: currentQueue }; // Don't push if not allowed\n }\n\n // Events present in the queue before init: the consent-denied ones just\n // requeued. Anything else found there after init was parked by a\n // concurrent push while the init flush was running.\n const parked = new Set(destination.queuePush);\n\n // Initialize the destination if needed.\n // Direct try/catch + logger.error here is intentional. Previously this\n // used tryCatchAsync(destinationInit) without an onError callback, which\n // silently returned undefined when init threw, hiding real failures. The\n // destination itself may also log a more specific error before throwing;\n // this is the boundary safety net so failures are never silent.\n // Allowed: at least one event cleared the per-event consent gate above,\n // so initialization is authorized (true) for the chokepoint guard.\n let isInitialized = false;\n try {\n isInitialized = await destinationInit(collector, destination, id, true);\n } catch (err) {\n collector.status.failed++;\n const destType = destination.type || 'unknown';\n collector.logger.scope(destType).error('destination init failed', {\n error: err instanceof Error ? err.message : String(err),\n });\n // A probe whose init throws is a real transport failure (the down\n // destination is exactly the one whose init throws): re-open with a\n // fresh window so self-heal does not deadlock.\n recordProbe('transport-failure');\n }\n\n if (!isInitialized) {\n // Init returned false (no throw): the probe never pushed, so release it\n // (no-op if the throw path above already re-opened).\n releaseProbeSlot();\n return { id, destination, queue: currentQueue };\n }\n\n // The init flush held the destination: a state delivery did not settle.\n // The allowed events go back to its queue; the denied ones are there\n // already.\n if (getStateHold(destination)) {\n releaseProbeSlot();\n requeue(allowedEvents);\n return { id, destination, queue: allowedEvents };\n }\n\n // A consent command ran while init was awaited: the events admitted\n // before it pass the gate again with the consent that holds now.\n const deniedAfter: WalkerOS.Events = [];\n if (collector.consent !== admittedWith) {\n const regated = admit(\n allowedEvents.map((queued) => ({\n ...queued,\n consent: collector.consent,\n })),\n );\n allowedEvents.splice(0, allowedEvents.length, ...regated.allowed);\n deniedAfter.push(...regated.skipped);\n }\n\n // Events parked by a concurrent push while the init flush was running\n // pass the same consent gate, with the consent that holds now, and go\n // out with this call.\n const queuedAfter = destination.queuePush || [];\n const arrived = queuedAfter.filter((queued) => !parked.has(queued));\n if (arrived.length) {\n destination.queuePush = queuedAfter.filter((queued) =>\n parked.has(queued),\n );\n const late = admit(\n arrived.map((queued) => ({ ...queued, consent: collector.consent })),\n );\n allowedEvents.push(...late.allowed);\n deniedAfter.push(...late.skipped);\n }\n requeue(deniedAfter);\n\n if (!allowedEvents.length) {\n releaseProbeSlot(); // every event was denied after init\n return deniedAfter.length\n ? { id, destination, queue: deniedAfter }\n : { id, destination, skipped: true };\n }\n\n // Process the destinations event queue\n let error: unknown;\n let response: unknown;\n if (!destination.dlq) destination.dlq = [];\n\n // The before and next routes; each resolves per event, hop by hop,\n // with `{ ingest, event }` (the runner resolves nothing ahead).\n const before = destination.config.before;\n const nextConfig = destination.config.next;\n\n // Compile destination cache once per batch (not per-event).\n // Destination caches operate on events (HIT/MISS keyed by event fields),\n // so the rule shape is always EventCacheRule, not StoreCacheRule.\n const destCacheConfig = destination.config?.cache as\n | Cache.Cache<Cache.EventCacheRule>\n | undefined;\n const compiledDCache = destCacheConfig\n ? compileCache(destCacheConfig)\n : undefined;\n const dCacheStore = compiledDCache\n ? getCacheStore(compiledDCache, collector)\n : undefined;\n\n // Compile declarative state entries once per batch. `get` runs before\n // the mapping-to-payload push (so it can shape the pushed event); `set`\n // runs after a successful send.\n const dStateEntries = compileStepState(destination.config?.state);\n const dStateGet = dStateEntries?.filter((entry) => entry.mode === 'get');\n const dStateSet = dStateEntries?.filter((entry) => entry.mode === 'set');\n\n // Process allowed events and store failed ones in the dead letter queue (DLQ)\n let totalDuration = 0;\n // Count of events enqueued into a batch in this pass; the aggregation\n // below uses this to skip the synchronous `count++` for batched events\n // (counters move to the flush callback per PROD-004 plan Q9).\n let batchedCount = 0;\n // Events the destination actually received. A before-chain fan-out makes\n // this exceed allowedEvents.length, which counts what entered.\n let pushedCount = 0;\n await Promise.all(\n allowedEvents.map(async (event) => {\n // Merge collector user into event (collector as base, event overrides)\n event.user = assign(user, event.user);\n\n // Full cache check: before the before chain (skips everything on HIT)\n let cacheMiss: { key: string; ttl: number } | undefined;\n let cacheValue: unknown;\n if (compiledDCache?.stop && dCacheStore) {\n const cacheContext = createMappingRoot(destIngest, event);\n const cacheResult = await checkCache(\n compiledDCache,\n dCacheStore,\n cacheContext,\n );\n if (cacheResult?.status === 'HIT') {\n return event; // Skip before chain + push\n }\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\n }\n }\n\n // Run post-collector transformer chain if configured for this destination\n let children: Array<{ event: WalkerOS.Event; ingest: Ingest }> = [\n { event, ingest: destIngest },\n ];\n let destRespond = meta.respond;\n if (before !== undefined) {\n const chainPath = `destination.${id}.before`;\n const chainResult = await runTransformerChain(\n collector,\n transformers,\n before,\n event,\n destIngest,\n meta.respond,\n chainPath,\n );\n\n if (chainResult.copies.length === 0) {\n // Dropped or stopped: THIS destination skips the event; other\n // destinations are unaffected.\n const skipState = stepState(\n collector,\n stepId('destination', id),\n 'destination',\n 'skip',\n typeof event.id === 'string' ? event.id : '',\n Date.now(),\n journeyFields(event, destIngest, collector),\n );\n skipState.skipReason = 'dropped';\n skipState.meta = {\n by: chainResult.droppedBy ?? 'route',\n at: chainPath,\n };\n emitStep(collector, skipState);\n return event;\n }\n\n // Update respond if the chain produced a wrapped one\n if (chainResult.respond) destRespond = chainResult.respond;\n\n // A before chain may fan one event into several. Every child is\n // delivered, each with the ingest it finished with.\n children = chainResult.copies.map((copy) => ({\n event: copy.event as WalkerOS.Event,\n ingest: copy.ingest,\n }));\n }\n\n // Delivers one child of the before chain, from the step-level cache\n // check through the destination.next chain. Runs once per child, so\n // a fan-out reaches the destination in full. Returns whether the\n // child was actually delivered.\n const deliverOne = async (\n processedEvent: WalkerOS.Event | null,\n childIngest: Ingest,\n sharedMiss: { key: string; ttl: number } | undefined,\n ): Promise<boolean> => {\n // The pre-chain key is derived from the one event that entered, so\n // a fan-out shares it and one write covers every child. A\n // step-level key is derived from THIS child, so it is the child's\n // own and must be written here.\n let cacheMiss = sharedMiss;\n let ownKey = false;\n\n // Step-level cache check: after before chain, skip only push on HIT\n if (compiledDCache && !compiledDCache.stop && dCacheStore) {\n const cacheContext = createMappingRoot(\n childIngest,\n processedEvent ?? undefined,\n );\n const cacheResult = await checkCache(\n compiledDCache,\n dCacheStore,\n cacheContext,\n );\n if (cacheResult?.status === 'HIT') {\n return false; // Skip push, deduplicated\n }\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\n ownKey = true;\n }\n }\n\n // state[get]: enrich the event before the mapping-to-payload push.\n if (dStateGet && dStateGet.length > 0 && processedEvent) {\n processedEvent = await runStepState(\n collector,\n dStateGet,\n processedEvent,\n childIngest,\n );\n }\n\n const pushStart = Date.now();\n let pushFailed = false;\n const result = await tryCatchAsync(destinationPush, (err) => {\n // Log the error with destination scope\n const destType = destination.type || 'unknown';\n collector.logger.scope(destType).error('Push failed', {\n ...errorMeta(err),\n event: processedEvent!.name,\n });\n error = err; // oh no\n pushFailed = true;\n\n // Add failed event to destinations DLQ (bounded; FIFO drop-oldest)\n const dlq = destination.dlq!;\n const destId = destination.config.id || id;\n const dlqBound = {\n max: destination.config.dlqMax ?? DEFAULT_DLQ_MAX,\n };\n const dlqResult = pushBounded(\n dlq,\n [processedEvent!, err],\n dlqBound,\n );\n if (dlqResult.dropped > 0) {\n ensureDestStatus(collector, destId);\n const droppedCount = bumpDropped(\n collector.status,\n stepId('destination', destId),\n 'dlq',\n dlqResult.dropped,\n );\n warnOverflowOnce(\n dlq,\n collector.logger.scope(destination.type || 'unknown'),\n 'destination.dlq overflow; oldest entries dropped',\n {\n buffer: 'dlq',\n destination: destId,\n cap: dlqBound.max,\n droppedCount,\n },\n );\n } else if (dlq.length < dlqBound.max) {\n resetOverflowFlag(dlq);\n }\n\n return undefined;\n })(\n collector,\n destination,\n id,\n processedEvent!,\n childIngest,\n destRespond,\n );\n totalDuration += Date.now() - pushStart;\n\n // Destination cache MISS. A per-child key is written now; the\n // shared pre-chain key is recorded and written once after every\n // child settles. The stored value is a dedup marker, since neither\n // cache check reads it back.\n if (\n cacheMiss &&\n dCacheStore &&\n destination.config.mock === undefined\n ) {\n if (ownKey) {\n storeCache(\n dCacheStore,\n cacheMiss.key,\n result ?? true,\n cacheMiss.ttl,\n );\n } else if (cacheValue === undefined) {\n cacheValue = result ?? true;\n }\n }\n\n // state[set]: stash from the event after a successful send. A\n // batched-enqueue is not a real send (the sentinel is returned\n // before delivery), so set is deferred until flush. The flush-path\n // write is a documented follow-up, not handled here yet.\n if (\n !pushFailed &&\n !isBatchedResult(result) &&\n dStateSet &&\n dStateSet.length > 0 &&\n processedEvent\n ) {\n processedEvent = await runStepState(\n collector,\n dStateSet,\n processedEvent,\n childIngest,\n );\n }\n\n // Capture the last response (for single event pushes).\n // Batched-enqueue sentinel is NOT a real response; don't surface it.\n if (result !== undefined && !isBatchedResult(result)) {\n response = result;\n }\n if (isBatchedResult(result)) batchedCount++;\n\n // Run destination.next chain after successful push\n if (!pushFailed && nextConfig) {\n // Write push response to ingest for destination.next transformers\n if (result !== undefined) {\n childIngest._response = result;\n }\n\n // Delivery already happened: a stop only ends this chain.\n const nextResult = await runTransformerChain(\n collector,\n transformers,\n nextConfig,\n processedEvent!,\n childIngest,\n destRespond,\n `destination.${id}.next`,\n );\n if (nextResult.respond) destRespond = nextResult.respond;\n }\n\n return true;\n };\n\n for (const child of children) {\n // Each child gets its own step-level cache decision; the full-check\n // miss recorded before the chain is shared, since it was computed\n // from the one event that entered. Only a child that actually\n // reached the destination counts as delivered.\n if (await deliverOne(child.event, child.ingest, cacheMiss))\n pushedCount++;\n }\n\n // One write per request, after every child settled.\n if (\n cacheMiss &&\n dCacheStore &&\n cacheValue !== undefined &&\n destination.config.mock === undefined\n ) {\n storeCache(dCacheStore, cacheMiss.key, cacheValue, cacheMiss.ttl);\n }\n\n return event;\n }),\n );\n\n return {\n id,\n destination,\n error,\n response,\n totalDuration,\n batchedCount,\n allowedCount: allowedEvents.length,\n pushedCount,\n canonicalId,\n breakerConfig,\n };\n }),\n );\n\n // Build result objects\n const done: Record<string, Destination.Ref> = {};\n const queued: Record<string, Destination.Ref> = {};\n const failed: Record<string, Destination.Ref> = {};\n\n for (const result of results) {\n if (result.skipped) continue;\n\n const destination = result.destination;\n const ref: Destination.Ref = {\n type: destination.type || 'unknown',\n data: result.response, // Capture push() return value\n };\n\n // Ensure destination status entry exists\n ensureDestStatus(collector, result.id);\n const destStatus = collector.status.destinations[result.id];\n const now = Date.now();\n\n // Refresh point-in-time buffer sizes after the destination's push pass.\n destStatus.queuePushSize = destination.queuePush?.length ?? 0;\n destStatus.dlqSize = destination.dlq?.length ?? 0;\n\n // Circuit-breaker accounting keys on the canonical stepId so it matches the\n // gate exactly. Presence-gated: only when this destination has a breaker.\n const breakerConfig = result.breakerConfig;\n const breakerKey = result.canonicalId\n ? stepId('destination', result.canonicalId)\n : undefined;\n const recordBreaker = (outcome: 'transport-failure' | 'success') => {\n if (breakerConfig && breakerKey) {\n recordStepOutcome(\n collector.status.breakers,\n breakerKey,\n outcome,\n breakerConfig.threshold,\n breakerConfig.cooldown,\n );\n }\n };\n\n if (result.error) {\n ref.error = result.error;\n failed[result.id] = ref;\n destStatus.failed++;\n destStatus.lastAt = now;\n destStatus.duration += result.totalDuration || 0;\n collector.status.failed++;\n // A single-event push that threw/timed out is a transport failure.\n recordBreaker('transport-failure');\n } else if (result.queue && result.queue.length) {\n // Events already re-queued at destination.queuePush via skippedEvents push\n queued[result.id] = ref;\n } else {\n // If every allowed event was enqueued into a batch, success counters\n // belong to the flush callback (PROD-004 plan Q9): don't increment\n // here and don't mark `done`. The flush bumps `count` and `out` when\n // pushBatch resolves. If only some events were batched, count the\n // synchronously-delivered ones.\n const batchedCount = result.batchedCount ?? 0;\n const allowedCount = result.allowedCount ?? 0;\n // What the destination actually received. A before-chain fan-out makes\n // this exceed allowedCount, which counts what entered.\n const deliveredCount = result.pushedCount ?? allowedCount;\n const syncDelivered = Math.max(0, deliveredCount - batchedCount);\n if (syncDelivered > 0 || allowedCount === 0) {\n done[result.id] = ref;\n // For non-batched destinations preserve the historical semantics\n // (one bump per pushToDestinations call, regardless of allowed\n // events count, since the original code only bumped once).\n destStatus.count++;\n destStatus.lastAt = now;\n destStatus.duration += result.totalDuration || 0;\n collector.status.out++;\n // A synchronously-delivered single-event push is a success: reset and\n // close the breaker. (Fully-batched passes settle in the flush\n // callback instead, which records its own outcome.)\n recordBreaker('success');\n }\n }\n }\n\n return createPushResult({\n event,\n ...(Object.keys(done).length && { done }),\n ...(Object.keys(queued).length && { queued }),\n ...(Object.keys(failed).length && { failed }),\n });\n}\n\n/**\n * Initializes a destination.\n *\n * @template Destination\n * @param collector - The walkerOS collector instance.\n * @param destination - The destination to initialize.\n * @param destId - The destination ID.\n * @returns Whether the destination was initialized successfully.\n */\n/**\n * A destination declares a consent requirement when its config.consent has at\n * least one key. Such a destination must never be initialized without a cleared\n * consent gate (see destinationInit's `allowed` parameter).\n */\nfunction hasConsentRequirement(destination: Destination.Instance): boolean {\n const required = destination.config.consent;\n return !!required && Object.keys(required).length > 0;\n}\n\n/**\n * Run a destination's own `init()` and return the config to install, marked\n * initialized, or false when `init()` returned false. The caller installs it.\n */\nasync function runDestinationInit(\n collector: Collector.Instance,\n destination: Destination.Instance,\n init: NonNullable<Destination.Instance['init']>,\n destId: string,\n): Promise<false | Destination.Config> {\n // Create scoped logger for this destination: [type:id] or [unknown:id]\n const destType = destination.type || 'unknown';\n const destLogger = collector.logger.scope(destType);\n\n const context: Destination.Context = {\n collector,\n logger: destLogger,\n id: destId,\n config: destination.config,\n env: mergeEnvironments(destination.env, destination.config.env),\n reportError: buildReportError(\n collector,\n 'destination',\n destId,\n destLogger,\n destination,\n ),\n };\n\n destLogger.debug('init');\n\n const initStarted = Date.now();\n emitStep(\n collector,\n stepState(\n collector,\n stepId('destination', destId),\n 'destination',\n 'init',\n '',\n initStarted,\n ),\n );\n\n let configResult;\n try {\n configResult = await useHooks(\n init,\n 'DestinationInit',\n collector.hooks,\n collector.logger,\n )(context);\n } catch (err) {\n const initErrFinished = Date.now();\n const errState = stepState(\n collector,\n stepId('destination', destId),\n 'destination',\n 'error',\n '',\n initErrFinished,\n );\n errState.durationMs = initErrFinished - initStarted;\n errState.error = stepError(err);\n emitStep(collector, errState);\n throw err;\n }\n\n // Actively check for errors (when false)\n if (configResult === false) return false; // don't push if init is false\n\n // The config to install, marked initialized; the caller installs it.\n return {\n ...(configResult || destination.config),\n init: true, // Remember that the destination was initialized\n };\n}\n\n/**\n * Initialize a destination and flush its queued `on()` deliveries. Installing\n * the initialized config and opening the flush happen in one synchronous\n * step: no delivery can see the destination initialized while its older\n * queued entries are not yet flushing, so nothing overtakes them.\n */\nasync function initAndFlush(\n collector: Collector.Instance,\n destination: Destination.Instance,\n init: NonNullable<Destination.Instance['init']>,\n destId: string,\n): Promise<boolean> {\n const config = await runDestinationInit(collector, destination, init, destId);\n if (config === false) return false; // don't push if init is false\n destination.config = config;\n\n // Flush queued on() events now that destination is initialized. The\n // queue stays live while the flush runs: a delivery that arrives in the\n // meantime is appended behind the older entries (see\n // `deliverStateToDestination`), so deliveries to this destination reach\n // its handler strictly in order. `config.init` is already set, so a\n // concurrent push would go straight out: while the flush carries a state\n // entry the hold covers the whole flush and is released once at its end.\n if (destination.queueOn?.length) {\n // The flush runs inside a cascade (the command's own, when one is open):\n // a handler that re-emits state reaches the same bound as on the live\n // path instead of appending to this queue without end.\n const exitCascade = enterCascade(collector);\n beginInitFlush(destination);\n try {\n for (\n let current = destination.queueOn?.shift();\n current;\n current = destination.queueOn?.shift()\n ) {\n await callDestinationOn(\n collector,\n destination,\n destId,\n current.type,\n current.data,\n );\n }\n } catch (err) {\n // A FatalError stopped the flush. The state entries it never reached\n // were marked when queued; they did not reach the handler, so they\n // are lost and the destination stays held until they are delivered.\n for (const { type } of destination.queueOn || []) {\n if (isStateDelivery(type)) markStateLost(collector, destination, type);\n }\n destination.queueOn = [];\n throw err;\n } finally {\n endInitFlush(collector, destination);\n exitCascade();\n }\n }\n\n collector.logger.scope(destination.type || 'unknown').debug('init done');\n return true;\n}\n\n/**\n * Inits in progress (init plus flush), per destination: a second caller (a\n * runtime add and a state command overlapping) waits for the running one\n * instead of starting another `init()`.\n */\nconst initsRunning = new WeakMap<Destination.Instance, Promise<boolean>>();\n\nexport async function destinationInit<Destination extends Destination.Instance>(\n collector: Collector.Instance,\n destination: Destination,\n destId: string,\n // Fail-closed consent gate. Callers MUST pass an affirmative allow decision\n // (per-event on the push path, collector-consent on the queueOn path). The\n // default is false so any future call site that forgets fails closed: a\n // consent-gated destination is never initialized without a cleared gate.\n allowed = false,\n): Promise<boolean> {\n // Check if the destination was initialized properly or try to do so\n if (destination.init && !destination.config.init) {\n // Defense-in-depth: refuse to init a destination that declares a consent\n // requirement unless the gate was cleared. We do NOT re-derive consent from\n // collector state here, because the push path's decision may rest on an\n // event's individual consent this function cannot see; re-deriving would\n // wrongly block a legitimate event-level override.\n if (!allowed && hasConsentRequirement(destination)) {\n collector.logger\n .scope(destination.type || 'unknown')\n .debug('init blocked: consent gate not cleared');\n return false;\n }\n // One init per destination, init and its queue flush as one unit: a\n // concurrent caller waits until the destination is initialized and\n // flushed instead of starting another init().\n const running = initsRunning.get(destination);\n if (running) return running;\n const started = initAndFlush(\n collector,\n destination,\n destination.init,\n destId,\n );\n initsRunning.set(destination, started);\n try {\n return await started;\n } finally {\n initsRunning.delete(destination);\n }\n }\n\n return true; // Destination is ready to push\n}\n\n/**\n * Pushes an event to a single destination.\n * Handles mapping, batching, and consent checks.\n *\n * @template Destination\n * @param collector - The walkerOS collector instance.\n * @param destination - The destination to push to.\n * @param destId - The destination ID.\n * @param event - The event to push.\n * @param ingest - Mutable ingest context flowing through the pipeline.\n * @returns Whether the event was pushed successfully.\n */\nexport async function destinationPush<Destination extends Destination.Instance>(\n collector: Collector.Instance,\n destination: Destination,\n destId: string,\n event: WalkerOS.Event,\n ingest?: Ingest,\n respond?: import('@walkeros/core').RespondFn,\n): Promise<unknown> {\n const { config } = destination;\n\n const processed = await processEventMapping(event, config, collector);\n\n if (processed.ignore) return false;\n\n // Create scoped logger for this destination: [type] or [unknown]\n const destType = destination.type || 'unknown';\n const destLogger = collector.logger.scope(destType);\n\n const context: Destination.PushContext = {\n collector,\n logger: destLogger,\n id: destId,\n config,\n data: processed.data,\n rule: processed.mapping,\n ingest: ingest!,\n env: {\n ...mergeEnvironments(destination.env, config.env),\n ...(respond ? { respond } : {}),\n },\n reportError: buildReportError(\n collector,\n 'destination',\n destId,\n destLogger,\n destination,\n ),\n };\n\n // Mock interception — replaces the actual destination.push() call\n if (config.mock !== undefined) {\n destLogger.debug('mock', { event: processed.event.name });\n return config.mock;\n }\n\n const eventMapping = processed.mapping;\n // Presence, not truthiness: batch: 0 is a valid 0 ms wait, not \"disabled\".\n const ruleHasBatch = eventMapping?.batch !== undefined;\n const mappingKey = ruleHasBatch\n ? processed.mappingKey || '* *'\n : BATCH_ALL_KEY;\n\n if (\n (ruleHasBatch || config.batch !== undefined) &&\n destination.pushBatch &&\n config.mock === undefined\n ) {\n // Initialize batch registry on destination (not on shared mapping config)\n destination.batches = destination.batches || {};\n\n // Get or create batch state for this mapping key\n if (!destination.batches[mappingKey]) {\n const batched: Destination.Batch<unknown> = {\n key: mappingKey,\n entries: [],\n events: [],\n data: [],\n };\n\n // Resolve scheduling options: mapping-level overrides destination-level.\n // Mapping rule `batch` (number form = wait; object = wait/size/age).\n // Destination config `batch` (number = wait; object = wait/size/age).\n const ruleOpts = normalizeBatchOptions(eventMapping?.batch);\n const destOpts = normalizeBatchOptions(config.batch);\n const wait =\n ruleOpts.wait ??\n destOpts.wait ??\n // No wait at either layer means \"rely on size/age only\"; pick a\n // long debounce so wait is effectively never the trigger.\n DEFAULT_BATCH_AGE;\n const size = ruleOpts.size ?? destOpts.size ?? DEFAULT_BATCH_SIZE;\n const age = ruleOpts.age ?? destOpts.age ?? DEFAULT_BATCH_AGE;\n\n // Capture references the flush closure needs. ingest, respond, and\n // per-event eventMapping are read from `entries`, NOT from this scope,\n // so the closure does NOT leak the first event's context.\n const baseEnv = mergeEnvironments(destination.env, config.env);\n\n const flushBatch = async (): Promise<void> => {\n const batchState = destination.batches![mappingKey];\n const currentBatched = batchState.batched;\n if (currentBatched.entries.length === 0) return;\n\n const snapshot: Destination.Batch<unknown> = {\n key: currentBatched.key,\n entries: currentBatched.entries,\n events: currentBatched.events,\n data: currentBatched.data,\n };\n currentBatched.entries = [];\n currentBatched.events = [];\n currentBatched.data = [];\n\n const rep = snapshot.entries[0];\n const batchContext: Destination.PushBatchContext = {\n collector,\n logger: destLogger,\n id: destId,\n config,\n data: undefined,\n rule: batchState.isDefault ? undefined : rep.rule,\n ingest: rep.ingest!,\n env: {\n ...baseEnv,\n ...(rep.respond ? { respond: rep.respond } : {}),\n },\n reportError: buildReportError(\n collector,\n 'destination',\n destId,\n destLogger,\n destination,\n ),\n };\n\n destLogger.debug('push batch', { events: snapshot.entries.length });\n\n const destIdResolved = destination.config.id || destId;\n const destStatus = ensureDestStatus(collector, destIdResolved);\n\n // Circuit-breaker accounting for the batch path. Keys on the canonical\n // stepId so it matches the gate. Presence-gated. A whole-batch throw is\n // a transport failure; any delivered rows (full or partial success) are\n // a success. Partial-failure rows themselves are breaker-neutral.\n const flushBreakerConfig = resolveBreakerConfig(\n destination.config.breaker,\n );\n const flushBreakerKey = stepId('destination', destIdResolved);\n const recordFlushBreaker = (\n outcome: 'transport-failure' | 'success',\n ) => {\n if (flushBreakerConfig) {\n recordStepOutcome(\n collector.status.breakers,\n flushBreakerKey,\n outcome,\n flushBreakerConfig.threshold,\n flushBreakerConfig.cooldown,\n );\n }\n };\n\n const flushStarted = Date.now();\n\n // Rows the destination named as failed, index -> that row's error. A\n // whole-batch throw fails every row instead, tracked separately so a\n // thrown `undefined` still counts as a failure.\n const failedRows = new Map<number, unknown>();\n let batchThrew = false;\n let batchError: unknown;\n\n // Routes a set of [event, error] pairs to this destination's DLQ,\n // applying the bound and emitting the overflow warning once. Shared by\n // the whole-batch failure path (pushBatch threw) and the partial-row\n // failure path (pushBatch returned a BatchOutcome).\n const routeToDlq = (failures: Array<[WalkerOS.Event, unknown]>) => {\n const dlq = (destination.dlq = destination.dlq || []);\n const dlqBound = {\n max: destination.config.dlqMax ?? DEFAULT_DLQ_MAX,\n };\n let totalDropped = 0;\n for (const pair of failures) {\n const r = pushBounded(dlq, pair, dlqBound);\n totalDropped += r.dropped;\n }\n if (totalDropped > 0) {\n const droppedCount = bumpDropped(\n collector.status,\n stepId('destination', destIdResolved),\n 'dlq',\n totalDropped,\n );\n warnOverflowOnce(\n dlq,\n destLogger,\n 'destination.dlq overflow; oldest entries dropped',\n {\n buffer: 'dlq',\n destination: destIdResolved,\n cap: dlqBound.max,\n droppedCount,\n },\n );\n } else if (dlq.length < dlqBound.max) {\n resetOverflowFlag(dlq);\n }\n destStatus.failed += failures.length;\n destStatus.dlqSize = dlq.length;\n collector.status.failed += failures.length;\n };\n\n // Number of entries treated as delivered after the flush settles.\n // Whole-batch success (void) = all; whole-batch failure (throw) = 0;\n // partial outcome = total minus the entries reported failed.\n let succeededCount = snapshot.entries.length;\n\n const batchTimeoutMs = resolveDestinationTimeout(config.timeout);\n const outcome = await tryCatchAsync(\n (\n batchArg: Destination.Batch<unknown>,\n ctxArg: Destination.PushBatchContext,\n ) =>\n withTimeout(\n Promise.resolve(\n useHooks(\n destination.pushBatch!,\n 'DestinationPushBatch',\n collector.hooks,\n collector.logger,\n )(batchArg, ctxArg),\n ),\n batchTimeoutMs,\n `Destination \"${destId}\" batch delivery timed out after ${batchTimeoutMs}ms`,\n ),\n (err) => {\n succeededCount = 0;\n batchThrew = true;\n batchError = err;\n // Route the entire batch to DLQ on a thrown/whole-batch failure.\n routeToDlq(snapshot.entries.map((entry) => [entry.event, err]));\n // Whole-batch throw is a transport failure for the breaker.\n recordFlushBreaker('transport-failure');\n destLogger.error('Push batch failed', {\n error: err instanceof Error ? err.message : String(err),\n entries: snapshot.entries.length,\n });\n return undefined;\n },\n )(snapshot, batchContext);\n\n // Partial-failure path: pushBatch resolved a BatchOutcome listing the\n // entries that did not succeed. DLQ and fail-count only those; the rest\n // are delivered. Out-of-range indices are ignored defensively.\n if (isBatchOutcome(outcome) && outcome.failed.length > 0) {\n const failedPairs: Array<[WalkerOS.Event, unknown]> = [];\n for (const failure of outcome.failed) {\n const entry = snapshot.entries[failure.index];\n if (!entry || failedRows.has(failure.index)) continue;\n const rowError =\n failure.error ??\n new Error(\n `Push batch entry ${failure.index} failed (no per-row error provided)`,\n );\n failedRows.set(failure.index, rowError);\n failedPairs.push([entry.event, rowError]);\n }\n if (failedPairs.length > 0) {\n routeToDlq(failedPairs);\n succeededCount = Math.max(\n 0,\n snapshot.entries.length - failedPairs.length,\n );\n // One entry per failure cause: the error's `code`, else its\n // `name`, with a count and the first message as a sample.\n const causes = new Map<\n string,\n { code: string; count: number; message: string }\n >();\n for (const [, rowError] of failedPairs) {\n const code =\n rowError instanceof Error &&\n 'code' in rowError &&\n typeof rowError.code === 'string'\n ? rowError.code\n : rowError instanceof Error\n ? rowError.name\n : 'Error';\n const cause = causes.get(code);\n if (cause) cause.count++;\n else\n causes.set(code, {\n code,\n count: 1,\n message:\n rowError instanceof Error\n ? rowError.message\n : String(rowError),\n });\n }\n destLogger.error('Push batch partial failure', {\n failed: failedPairs.length,\n delivered: succeededCount,\n entries: snapshot.entries.length,\n causes: [...causes.values()],\n });\n }\n }\n\n // Batch outcomes fan out one frame per entry, emitted once the flush\n // has settled so each frame states that entry's real outcome. A single\n // batch-level frame covered N events and identified none, so a failure\n // marked no event errored and every entry kept reading as delivered.\n // Each entry gets exactly one frame: a flush frame only if the\n // destination delivered that row, an error frame if it failed it (a\n // throw fails every row, a BatchOutcome fails the rows it names). A\n // failed row therefore can never also carry a delivery confirmation,\n // and the partition matches the one the DLQ and counters used above.\n // An error frame here means the row was not delivered and will not be\n // retried: nothing drains `destination.dlq`, which is a bounded\n // in-memory buffer kept for inspection and evicted oldest-first.\n const settledAt = Date.now();\n snapshot.entries.forEach((entry, index) => {\n const failed = batchThrew || failedRows.has(index);\n const journey = journeyFields(entry.event, entry.ingest, collector);\n const state = stepState(\n collector,\n stepId('destination', destId),\n 'destination',\n failed ? 'error' : 'flush',\n typeof entry.event.id === 'string' ? entry.event.id : '',\n settledAt,\n journey,\n );\n state.batch = { size: snapshot.entries.length, index };\n // Every frame carries the transport latency, so a batched delivery\n // is as measurable as the non-batched `out` path.\n state.durationMs = settledAt - flushStarted;\n if (failed) {\n const err = batchThrew ? batchError : failedRows.get(index);\n state.error = stepError(err);\n }\n emitStep(collector, state);\n });\n\n destLogger.debug('push batch done');\n\n // Decrement in-flight regardless of outcome.\n destStatus.inFlightBatch = Math.max(\n 0,\n (destStatus.inFlightBatch ?? 0) - snapshot.entries.length,\n );\n\n if (succeededCount > 0) {\n destStatus.count += succeededCount;\n destStatus.lastAt = Date.now();\n collector.status.out += succeededCount;\n // Any delivered rows mean the transport worked: success closes the\n // breaker. Partial-failure rows are breaker-neutral (handled by the\n // absence of a transport-failure record for them above).\n recordFlushBreaker('success');\n }\n };\n\n const scheduler = debounce(flushBatch, {\n wait,\n size,\n age,\n });\n\n destination.batches[mappingKey] = {\n batched,\n isDefault: !ruleHasBatch, // created via config.batch, not a rule's own batch\n batchFn: () => {\n void scheduler();\n },\n flush: async () => {\n await scheduler.flush();\n },\n };\n }\n\n // Add per-event entry into the batch.\n const batchState = destination.batches[mappingKey];\n batchState.batched.entries.push({\n event: processed.event,\n ingest,\n respond,\n rule: eventMapping,\n data: processed.data,\n });\n batchState.batched.events.push(processed.event);\n if (isDefined(processed.data)) batchState.batched.data.push(processed.data);\n\n // Emit a per-event in/out pair at enqueue time so observers see every\n // event that entered the batch, not just the later flush frame. Enqueue is\n // synchronous, so there is no vendor call to time and no durationMs. The\n // terminal out record carries the batch coordinates the assembler reads to\n // confirm batched delivery: size is the queue length after this enqueue,\n // index is this entry's slot. The coordinates live on the out record only.\n const batchEventId =\n typeof processed.event.id === 'string' ? processed.event.id : '';\n const batchJourney = journeyFields(event, ingest, collector);\n const enqueuedAt = Date.now();\n const batchInState = stepState(\n collector,\n stepId('destination', destId),\n 'destination',\n 'in',\n batchEventId,\n enqueuedAt,\n batchJourney,\n );\n if (processed.mappingKey) batchInState.mappingKey = processed.mappingKey;\n if (processed.event.consent) {\n batchInState.consent = { ...processed.event.consent };\n }\n batchInState.inEvent = processed.event;\n emitStep(collector, batchInState);\n\n const batchOutState = stepState(\n collector,\n stepId('destination', destId),\n 'destination',\n 'out',\n batchEventId,\n enqueuedAt,\n batchJourney,\n );\n if (processed.mappingKey) batchOutState.mappingKey = processed.mappingKey;\n batchOutState.outEvent = processed.event;\n batchOutState.batch = {\n size: batchState.batched.entries.length,\n index: batchState.batched.entries.length - 1,\n };\n emitStep(collector, batchOutState);\n\n // In-flight bookkeeping for operational visibility.\n const destIdResolved = destination.config.id || destId;\n const destStatus = ensureDestStatus(collector, destIdResolved);\n destStatus.inFlightBatch = (destStatus.inFlightBatch ?? 0) + 1;\n\n // Trigger debounced batch (also handles size/age caps internally).\n batchState.batchFn();\n\n // Signal \"enqueued to batch, not delivered\" so the aggregation pass\n // in pushToDestinations skips the synchronous `count` increment.\n return BATCHED_RESULT;\n } else {\n destLogger.debug('push', { event: processed.event.name });\n\n // Trace-level vendor-call capture (presence-gated). Only when an\n // observeLevel supplier reports 'trace' AND this destination declares\n // observable callables do we wrap the merged env with recording proxies\n // for this push. wrapEnv deep-clones the env per push, so this must never\n // run on the default path; prod stays zero-cost beyond the guard check.\n // Build flag (see @walkeros/core build-flags): a lean bundle folds the\n // capture out, and `attachCalls` below with it.\n let recordedCalls: Simulation.Call[] | undefined;\n if (\n (typeof __WALKEROS_OBSERVE__ === 'undefined' || __WALKEROS_OBSERVE__) &&\n collector.observeLevel?.() === 'trace' &&\n Array.isArray(destination.calls) &&\n destination.calls.length > 0\n ) {\n const wrapped = wrapEnv({\n ...context.env,\n simulation: destination.calls,\n });\n context.env = wrapped.wrappedEnv;\n recordedCalls = wrapped.calls;\n\n // Paths wrapEnv could not resolve here (e.g. a live-web global not yet\n // installed) travel to the resolution-point wrapper (web-core getEnv) as\n // a typed recorder. Both channels push onto the SAME calls array, so the\n // out-record attach + sanitize below covers wrapped and recorded calls\n // alike. getEnv strips this key before the destination sees the env.\n if (wrapped.unresolved.length > 0) {\n wrapped.wrappedEnv[OBSERVE_ENV_KEY] = {\n paths: wrapped.unresolved,\n record: (fn, args) =>\n wrapped.calls.push({ fn, args, ts: Date.now() }),\n } satisfies Destination.EnvObserve;\n }\n }\n\n // Emit a per-event observer pair around the destination.push call so\n // observers see the work this destination did for this event.\n const eventIdValue =\n typeof processed.event.id === 'string' ? processed.event.id : '';\n const journey = journeyFields(event, ingest, collector);\n const pushStarted = Date.now();\n const inState = stepState(\n collector,\n stepId('destination', destId),\n 'destination',\n 'in',\n eventIdValue,\n pushStarted,\n journey,\n );\n if (processed.mappingKey) inState.mappingKey = processed.mappingKey;\n if (processed.event.consent) {\n inState.consent = { ...processed.event.consent };\n }\n inState.inEvent = processed.event;\n emitStep(collector, inState);\n\n try {\n // It's time to go to the destination's side now. Race the push against a\n // per-destination timeout so a hung delivery becomes a thrown failure\n // that flows into the SAME catch -> tryCatchAsync onError -> DLQ path a\n // real throw uses. The race is per call, so it never affects siblings.\n const timeoutMs = resolveDestinationTimeout(config.timeout);\n const response = await withTimeout(\n Promise.resolve(\n useHooks(\n destination.push,\n 'DestinationPush',\n collector.hooks,\n collector.logger,\n )(processed.event, context),\n ),\n timeoutMs,\n `Destination \"${destId}\" delivery timed out after ${timeoutMs}ms`,\n );\n\n const pushFinished = Date.now();\n const outState = stepState(\n collector,\n stepId('destination', destId),\n 'destination',\n 'out',\n eventIdValue,\n pushFinished,\n journey,\n );\n outState.durationMs = pushFinished - pushStarted;\n outState.outEvent = processed.event;\n // Attach the vendor calls recorded during this push.\n attachCalls(outState, recordedCalls);\n if (isDefined(response)) {\n outState.meta = { ...outState.meta, response };\n }\n if (processed.mappingKey) outState.mappingKey = processed.mappingKey;\n emitStep(collector, outState);\n\n destLogger.debug('push done');\n\n return response;\n } catch (err) {\n const pushFinished = Date.now();\n const errState = stepState(\n collector,\n stepId('destination', destId),\n 'destination',\n 'error',\n eventIdValue,\n pushFinished,\n journey,\n );\n errState.durationMs = pushFinished - pushStarted;\n errState.error = stepError(err);\n // Surface the vendor calls recorded before the failure, so a mid-push\n // error doesn't discard them.\n attachCalls(errState, recordedCalls);\n if (processed.mappingKey) errState.mappingKey = processed.mappingKey;\n emitStep(collector, errState);\n throw err;\n }\n }\n}\n\n/**\n * Creates a standardized result object for push operations.\n *\n * @param partialResult - A partial result to merge with the default result.\n * @returns The push result.\n */\nexport function createPushResult(\n partialResult?: Partial<Elb.PushResult>,\n): Elb.PushResult {\n return {\n ok: !partialResult?.failed,\n ...partialResult,\n };\n}\n\n/**\n * Register a single destination from its init definition.\n * Merges code config, user config, and chain config.\n * Used by initDestinations and activatePending.\n */\nexport function registerDestination(\n def: Destination.Init,\n): Destination.Instance {\n const { code, config = {}, env = {}, cache, state } = def;\n const { config: configWithBefore } = extractChainProperty(def, 'before');\n const { config: configWithChains } = extractChainProperty(\n { ...def, config: configWithBefore },\n 'next',\n );\n const mergedConfig = { ...code.config, ...config, ...configWithChains };\n // Merge definition-level cache into config for runtime access\n if (cache) mergedConfig.cache = cache;\n // Merge definition-level state into config; a config-level state wins.\n if (state !== undefined && mergedConfig.state === undefined)\n mergedConfig.state = state;\n const mergedEnv = mergeEnvironments(code.env, env);\n return { ...code, config: mergedConfig, env: mergedEnv };\n}\n\n/**\n * Initializes a map of destinations using ONLY the unified code/config/env pattern.\n * Does NOT call destination.init() - that happens later during push with proper consent checks.\n *\n * @param destinations - The destinations to initialize.\n * @param collector - The collector instance for destination init context.\n * @returns The initialized destinations.\n */\nexport async function initDestinations(\n collector: Collector.Instance,\n destinations: Destination.InitDestinations = {},\n): Promise<Collector.Destinations> {\n const result: Collector.Destinations = {};\n\n for (const [id, def] of Object.entries(destinations)) {\n warnStateOff(\n collector,\n stepId('destination', id),\n def.config?.state ?? def.code.config?.state ?? def.state,\n );\n if (def.config?.require?.length) {\n collector.pending.destinations[id] = def;\n continue;\n }\n result[id] = registerDestination(def);\n }\n\n return result;\n}\n\n/**\n * Merges destination environment with config environment\n * Config env takes precedence over destination env for overrides\n */\nexport function mergeEnvironments(\n destinationEnv?: Destination.Env,\n configEnv?: Destination.Env,\n): Destination.Env {\n // If neither environment exists, return empty object\n if (!destinationEnv && !configEnv) return {};\n\n // If only one exists, return it\n if (!configEnv) return destinationEnv!;\n if (!destinationEnv) return configEnv;\n\n // Both exist - merge objects with configEnv taking precedence\n if (isObject(destinationEnv) && isObject(configEnv)) {\n return { ...destinationEnv, ...configEnv };\n }\n\n // If they're not both objects, config env overrides destination env\n return configEnv;\n}\n","import type { Collector, FlowState, Ingest, WalkerOS } from '@walkeros/core';\nimport { emitStep } from '@walkeros/core';\n\n/** Journey-correlation trio shared by every FlowState-stamping site. */\nexport interface JourneyFields {\n traceId?: string;\n sourceId?: string;\n parentEventId?: string;\n}\n\n/**\n * Resolve the journey-correlation trio for a stamping site. Trace precedence:\n * a payload `event.source.trace` (origin identity) wins; a header-derived\n * `ingest._meta.trace` fills the gap; the run-scoped `collector.trace` is the\n * final fallback. `sourceId` and `parentEventId` come from the ingest context\n * threaded through the pipeline. The event accepts both a full event and a\n * DeepPartial incoming shape, since sites stamp at both pre- and\n * post-enrichment positions.\n */\nexport function journeyFields(\n event: WalkerOS.Event | WalkerOS.DeepPartialEvent,\n ingest: Ingest | undefined,\n collector: Collector.Instance,\n): JourneyFields {\n return {\n // Must match createEvent's trace precedence (handle.ts).\n traceId: event.source?.trace ?? ingest?._meta.trace ?? collector.trace,\n sourceId: ingest?._meta.path[0],\n parentEventId: ingest?._meta.parentEventId,\n };\n}\n\nexport interface BuildBaseStateArgs {\n stepId: string;\n stepType: FlowState['stepType'];\n phase: FlowState['phase'];\n eventId: string;\n now: number;\n /** W3C 32-hex trace id of the originating run (from event.source.trace). */\n traceId?: string;\n /** Originating source id (Ingest._meta.path[0]), when known. */\n sourceId?: string;\n /** Upstream runtime's event.id from an inbound $flow crossing. */\n parentEventId?: string;\n}\n\n/**\n * Build a `FlowState` carrying the always-populated fields. Callers fill in\n * additional fields (consent, batch, error, meta, inEvent, outEvent,\n * mappingKey, durationMs) as relevant for the step site.\n *\n * `flowId` is the collector's static flow `name`, falling back to `'default'`\n * when the flow is unnamed. The journey trio is stamped only when `journey`\n * carries a truthy value, so store and init records never carry it.\n */\nexport function stepState(\n collector: Collector.Instance,\n stepId: string,\n stepType: FlowState['stepType'],\n phase: FlowState['phase'],\n eventId: string,\n now = Date.now(),\n journey?: JourneyFields,\n): FlowState {\n const state: FlowState = {\n flowId: collector.name ?? 'default',\n stepId,\n stepType,\n phase,\n eventId,\n timestamp: new Date(now).toISOString(),\n elapsedMs: now - collector.status.startedAt,\n };\n // An undefined trace/source/parent must not appear as an explicit key.\n if (journey?.traceId) state.traceId = journey.traceId;\n if (journey?.sourceId) state.sourceId = journey.sourceId;\n if (journey?.parentEventId) state.parentEventId = journey.parentEventId;\n return state;\n}\n\n/** Object-argument form of `stepState`. */\nexport function buildBaseState(\n collector: Collector.Instance,\n args: BuildBaseStateArgs,\n): FlowState {\n return stepState(\n collector,\n args.stepId,\n args.stepType,\n args.phase,\n args.eventId,\n args.now,\n args,\n );\n}\n\n/**\n * The error a `FlowState` carries: name and message for an `Error`, the\n * message alone for anything else thrown.\n */\nexport function stepError(err: unknown): NonNullable<FlowState['error']> {\n return err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n}\n\n/**\n * Convenience wrapper: build the base state and fan out to observers in\n * one call. Returns no value; callers that need to add trailing fields\n * before observers see them should call `buildBaseState` + `emitStep`\n * directly instead.\n */\nexport function emit(\n collector: Collector.Instance,\n args: BuildBaseStateArgs,\n): void {\n emitStep(collector, buildBaseState(collector, args));\n}\n\n/**\n * A drop at a collector-owned chain position (`source.before`,\n * `source.next`, `collector.next`): the event never reaches the\n * destinations. Emits one `collector.push` `skip` with `skipReason:\n * 'dropped'` (the same hop as the wrap's in/out, which the skip outranks as\n * the terminal phase), naming what dropped it\n * (`by`: the transformer id, or `'route'` for a route `stop`) and where\n * (`at`: the chain path). The event counts as received (`status.in`), with\n * no `out` and no counter of its own.\n */\nexport function emitCollectorDrop(\n collector: Collector.Instance,\n event: WalkerOS.DeepPartialEvent,\n ingest: Ingest | undefined,\n by: string | undefined,\n at: string,\n): void {\n collector.status.in++;\n const state = stepState(\n collector,\n 'collector.push',\n 'collector',\n 'skip',\n typeof event.id === 'string' ? event.id : '',\n Date.now(),\n journeyFields(event, ingest, collector),\n );\n state.skipReason = 'dropped';\n state.meta = { by: by ?? 'route', at };\n emitStep(collector, state);\n}\n","import type { Collector, Ingest, State, WalkerOS } from '@walkeros/core';\nimport { applyState, compileState } from '@walkeros/core';\nimport { getStateStore } from './cache';\n\n/**\n * Declarative step `state` behind the `__WALKEROS_STATE__` build flag (see\n * @walkeros/core build-flags). Only these helpers read the flag, so a bundle\n * built with it defined false folds the state engine out of every step.\n */\n\n/** A step's state entries; undefined without any, or when the build has no state. */\nexport function compileStepState(\n state: State | State[] | undefined,\n): State[] | undefined {\n return (typeof __WALKEROS_STATE__ === 'undefined' || __WALKEROS_STATE__) &&\n state\n ? compileState(state)\n : undefined;\n}\n\n/** Apply compiled state entries to an event, reading stores off the collector. */\nexport function runStepState<E extends WalkerOS.DeepPartialEvent>(\n collector: Collector.Instance,\n entries: State[],\n event: E,\n ingest: Ingest | undefined,\n): Promise<E> {\n return typeof __WALKEROS_STATE__ === 'undefined' || __WALKEROS_STATE__\n ? applyState(\n entries,\n (id) => getStateStore(id, collector),\n event,\n collector,\n ingest,\n )\n : Promise.resolve(event);\n}\n\n/**\n * A build without state ignores a step's `state` (e.g. on a destination\n * added at runtime): warned, never silent. Stays in that lean bundle.\n */\nexport function warnStateOff(\n collector: Collector.Instance,\n step: string,\n state: unknown,\n): void {\n if (\n !(typeof __WALKEROS_STATE__ === 'undefined' || __WALKEROS_STATE__) &&\n state !== undefined\n )\n collector.logger.warn(`state: not in this build, ${step} state ignored`);\n}\n","import type { Collector, Store } from '@walkeros/core';\nimport type { CompiledCache } from '@walkeros/core';\n\n/**\n * Returns the store for a compiled cache config.\n * Uses the explicit store reference if provided, otherwise falls back to the\n * collector's default __cache store.\n */\nexport function getCacheStore(\n compiled: CompiledCache,\n collector: Collector.Instance,\n): Store.Instance | undefined {\n if (compiled.storeId && collector.stores[compiled.storeId]) {\n return collector.stores[compiled.storeId];\n }\n return collector.stores.__cache;\n}\n\n/**\n * Returns the store for a declarative `state` operation.\n * An explicit store id resolves to `collector.stores[id]` (or `undefined`\n * when that store is not declared). An omitted id falls back to the default\n * in-memory `__cache` store.\n */\nexport function getStateStore(\n storeId: string | undefined,\n collector: Pick<Collector.Instance, 'stores'>,\n): Store.Instance | undefined {\n if (storeId) return collector.stores[storeId];\n return collector.stores.__cache;\n}\n","import type { Simulation } from '@walkeros/core';\nimport { observeEnv } from '@walkeros/core';\n\ninterface WrapResult {\n /** Env view whose tracked paths record each call */\n wrappedEnv: Record<string, unknown>;\n /** Mutable array — calls are pushed here during step execution */\n calls: Simulation.Call[];\n /**\n * Well-formed declared paths whose object intermediates or leaf are absent\n * at wrap time, as the post-`call:` dot-path (what the recorder records as\n * `fn`). This list feeds `EnvObserve.paths` directly, so malformed paths\n * (`parseCallPath` returned `[]`) are skipped entirely. A path that\n * continues through a function (constructor, factory, method result)\n * resolves at call time and is not listed.\n */\n unresolved: string[];\n}\n\n/**\n * Structural-clone depth cap. Beyond this depth the ORIGINAL reference is\n * reused instead of cloned: the wrapped env is what the destination executes\n * against, so the fallback must stay functional (never a marker string).\n */\nconst CLONE_MAX_DEPTH = 8;\n\n/** Plain objects and arrays are data to copy; anything else is kept as is. */\nfunction isPlainData(value: object): boolean {\n if (Array.isArray(value)) return true;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Visit-once structural clone of plain objects and arrays, so writes a step\n * makes to its env stay in this push. The memo maps each source object to its\n * single clone, so cycles terminate and shared references stay shared.\n * Functions and class instances are kept by reference: an instance copied\n * into a plain object would lose its prototype and `#private` fields.\n */\nfunction deepClone(\n obj: unknown,\n memo: WeakMap<object, unknown>,\n depth: number,\n): unknown {\n if (obj === null || typeof obj !== 'object') return obj;\n if (depth >= CLONE_MAX_DEPTH || !isPlainData(obj)) return obj;\n const existing = memo.get(obj);\n if (existing !== undefined) return existing;\n if (Array.isArray(obj)) {\n const cloneArr: unknown[] = [];\n memo.set(obj, cloneArr);\n for (const item of obj) {\n cloneArr.push(deepClone(item, memo, depth + 1));\n }\n return cloneArr;\n }\n const clone: Record<string, unknown> = {};\n memo.set(obj, clone);\n for (const [key, value] of Object.entries(obj)) {\n clone[key] =\n typeof value === 'function' ? value : deepClone(value, memo, depth + 1);\n }\n return clone;\n}\n\n/**\n * Record calls on tracked paths of a destination env.\n *\n * The env object must include a `simulation: string[]` declaring which\n * dot-paths to intercept. Returns a view of a cloned env (without\n * `simulation`) where those paths record every call into the `calls` array.\n * Recording is the shared core recorder `observeEnv`, so constructors,\n * method results and Promises on a path work the same as in web-core `getEnv`.\n */\nexport function wrapEnv(\n env: Record<string, unknown> & { simulation: string[] },\n): WrapResult {\n const { simulation, ...rest } = env;\n const cloned: Record<string, unknown> = {};\n const memo = new WeakMap<object, unknown>();\n for (const [key, value] of Object.entries(rest)) {\n cloned[key] =\n typeof value === 'function' ? value : deepClone(value, memo, 1);\n }\n\n const observed = observeEnv(cloned, simulation);\n return {\n wrappedEnv: observed.env,\n calls: observed.calls,\n unresolved: observed.unresolved,\n };\n}\n","import type { FlowState, Simulation } from '@walkeros/core';\n\n/** Depth beyond which sanitizeArgs stops descending and emits a marker. */\nconst SANITIZE_MAX_DEPTH = 6;\n\n/**\n * True only for plain objects (prototype is Object.prototype or null). DOM\n * nodes, class instances, Dates, Errors, etc. are non-plain and get tagged\n * rather than deep-copied.\n */\nfunction isPlainObject(value: object): value is Record<string, unknown> {\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/**\n * Read one property without letting a hostile getter escape. Sanitization\n * runs inside the push try-block after a successful delivery, so a throwing\n * getter must degrade to a marker, never surface as a push failure.\n */\nfunction readProp(source: Record<string, unknown>, key: string): unknown {\n try {\n return source[key];\n } catch {\n return '[unreadable]';\n }\n}\n\n/**\n * Stable string tag for a non-plain object (DOM node, class instance, ...).\n * Falls back to a generic marker if the value's own String() throws.\n */\nfunction objectTag(value: object): string {\n try {\n return String(value);\n } catch {\n return '[object]';\n }\n}\n\n/**\n * Produce a JSON-safe deep copy of recorded vendor-call arguments. Vendor\n * calls can receive functions, DOM nodes, or cyclic structures that break or\n * silently vanish under the poster's JSON.stringify. Replace those leaves with\n * stable marker strings so the recorded calls always serialize:\n * functions -> '[function]', non-plain objects -> their String() tag, cyclic\n * refs -> '[circular]', anything past SANITIZE_MAX_DEPTH -> '[truncated]',\n * and values a throwing getter/hostile proxy makes unreadable -> '[unreadable]'.\n * Never throws: a sanitize failure must not alter push semantics.\n */\nexport function sanitizeArgs(args: unknown[]): unknown[] {\n const seen = new WeakSet<object>();\n\n const walk = (value: unknown, depth: number): unknown => {\n if (value === null) return null;\n if (typeof value === 'function') return '[function]';\n if (typeof value === 'string' || typeof value === 'boolean') return value;\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : null;\n }\n if (typeof value === 'bigint') return String(value);\n if (typeof value !== 'object') return undefined; // symbol/undefined: JSON-invisible\n\n const obj = value;\n if (seen.has(obj)) return '[circular]';\n if (depth >= SANITIZE_MAX_DEPTH) return '[truncated]';\n seen.add(obj);\n\n // Structurally hostile values (revoked proxies, throwing ownKeys traps)\n // must degrade to a marker: any throw here would surface inside the push\n // try-block and convert a successful delivery into a failure. Property\n // getters are additionally guarded per-value via readProp so one bad\n // getter only marks its own slot.\n let result: unknown;\n try {\n if (Array.isArray(obj)) {\n result = obj.map((item) => walk(item, depth + 1));\n } else if (isPlainObject(obj)) {\n const copy: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n copy[key] = walk(readProp(obj, key), depth + 1);\n }\n result = copy;\n } else {\n result = objectTag(obj);\n }\n } catch {\n result = '[unreadable]';\n }\n\n // Remove on exit so only ancestors (true cycles) count, not repeated\n // siblings referencing the same object.\n seen.delete(obj);\n return result;\n };\n\n return args.map((arg) => walk(arg, 0));\n}\n\n/**\n * Sanitize every recorded call's args into a JSON-safe projection. `fn` and\n * `ts` are already primitives; only `args` needs the deep pass.\n */\nexport function sanitizeCalls(calls: Simulation.Call[]): Simulation.Call[] {\n return calls.map((call) => ({\n fn: call.fn,\n args: sanitizeArgs(call.args),\n ts: call.ts,\n }));\n}\n\n/**\n * Attach the vendor calls recorded during a push to its out or error record,\n * sanitized. Only when trace capture ran and something was recorded. Build\n * flag (see @walkeros/core build-flags): a bundle without observe folds this\n * out.\n */\nexport function attachCalls(\n state: FlowState,\n calls: Simulation.Call[] | undefined,\n): void {\n if (\n (typeof __WALKEROS_OBSERVE__ === 'undefined' || __WALKEROS_OBSERVE__) &&\n calls &&\n calls.length > 0\n )\n state.calls = sanitizeCalls(calls);\n}\n","import type {\n Collector,\n On,\n WalkerOS,\n Destination,\n Source,\n Logger,\n} from '@walkeros/core';\nimport { isArray, FatalError } from '@walkeros/core';\nimport { Const } from './constants';\nimport { tryCatch, tryCatchAsync } from '@walkeros/core';\nimport { mergeEnvironments, pushToDestinations } from './destination';\nimport { buildReportError, errorMeta } from './report-error';\nimport { reconcilePending } from './pending';\nimport { flushSourceQueueOn, isSourceStarted } from './source';\nimport {\n DEFAULT_DESTINATION_TIMEOUT_MS,\n DestinationTimeoutError,\n resolveDestinationTimeout,\n withTimeout,\n} from './timeout';\n\n/**\n * Type guard: is `value` a genuine collector instance? A real collector ALWAYS\n * carries a `.logger` with a `.scope` function (see `collector.ts`, which\n * assigns `logger: createLogger(...)` unconditionally; `createLogger` never\n * returns undefined). So a value that fails this check can ONLY be a\n * foreign/non-collector caller; it can never be a real internal dispatch.\n * Cast-free: narrows via `typeof`/`in` only.\n */\nfunction isCollectorInstance(value: unknown): value is Collector.Instance {\n if (typeof value !== 'object' || value === null) return false;\n if (!('logger' in value)) return false;\n const logger = value.logger;\n if (typeof logger !== 'object' || logger === null) return false;\n return 'scope' in logger && typeof logger.scope === 'function';\n}\n\n/**\n * One-time, logger-less warning for a foreign dispatch. There is no collector\n * (hence no scoped logger) to use, so fall back to `console.warn`, guarded for\n * environments without a console, and fire at most once total to avoid spamming\n * a host page that may be calling a leaked global repeatedly.\n */\nlet warnedForeignDispatch = false;\nfunction warnForeignDispatch(): void {\n if (warnedForeignDispatch) return;\n warnedForeignDispatch = true;\n if (typeof console !== 'undefined' && typeof console.warn === 'function')\n console.warn(\n 'walkerOS: ignored an on-dispatch call with a non-collector argument',\n );\n}\n\ntype OnCallbackKind =\n | 'destination'\n | 'generic'\n | 'source'\n | 'consent'\n | 'ready'\n | 'run'\n | 'session';\n\n/**\n * Log a thrown error from a user-supplied `on` callback.\n *\n * Category B (user code): visibility via the scoped 'on' logger only.\n * `status.failed` is reserved for pipeline failures and stays untouched\n * here so it remains a clean health signal.\n *\n * Rethrows `FatalError` to let runtime supervisors fail fast on explicit\n * abort signals. Both `tryCatch` and `tryCatchAsync` propagate throws\n * raised inside onError, so this rethrow surfaces at the caller.\n */\nfunction logOnCallbackError(\n collector: Collector.Instance,\n kind: OnCallbackKind,\n error: unknown,\n extra?: Record<string, unknown>,\n): void {\n if (error instanceof FatalError) throw error;\n collector.logger.scope('on').error('on callback failed', {\n kind,\n ...extra,\n ...errorMeta(error),\n });\n}\n\n/**\n * The reactive state cells: the only commands that bump `collector.stateVersion`\n * and carry the per-subscriber exactly-once + `allowed` gate. Single source of\n * truth for \"which types are state cells\" — every list/membership check derives\n * from here, so adding a cell is a one-line change (no silently-missed site).\n */\nconst STATE_CELLS = ['consent', 'user', 'globals', 'custom'] as const;\n\ntype StateCell = (typeof STATE_CELLS)[number];\n\n/** Is `type` a state cell? Narrows it to a key of the collector's cells. */\nfunction isStateCell(type: On.Types): type is StateCell {\n const cells: readonly On.Types[] = STATE_CELLS;\n return cells.includes(type);\n}\n\n/**\n * State-delivery event types: the reactive-state commands that bump\n * `collector.stateVersion` (see handle.ts). These are the only deliveries\n * subject to the per-subscriber high-water-mark + `allowed` gate. Lifecycle\n * types (ready/run/session) and non-reactive config keep their own gating\n * (onReady/onRun check `allowed`, onSession checks `session`).\n */\nexport function isStateDelivery(type: On.Types): boolean {\n return isStateCell(type);\n}\n\n/**\n * Is a recorded state CELL present (non-empty)? The single source of truth for\n * \"cell X has a value\", shared by `isRequireSatisfied` (require gating) and\n * `redeliverStateAtRun` (run-barrier re-delivery) so the presence semantics\n * never drift between the two. PRESENCE, not grant: a denied consent\n * (`{marketing:false}`) counts as present. Non-cell types return `false` here;\n * their satisfaction (session/run/ready/arbitrary) is handled by the callers.\n *\n * Note: `globals` is seeded from `config.globalsStatic` at construction, so it\n * reads present whenever a static global exists, before any `command('globals')`\n * fires. That is intentional and presence-based.\n */\nexport function isStatePresent(\n collector: Collector.Instance,\n type: On.Types,\n): boolean {\n return isStateCell(type) && Object.keys(collector[type]).length > 0;\n}\n\n/**\n * Predicate: is a `require` entry satisfied by the collector's CURRENT recorded\n * state? This is the level-not-edge core of order-independent activation: a\n * step's gate is checked against the present state, not against whether the\n * required type fired before or after the step registered.\n *\n * Cell-backed types defer to `isStatePresent` (presence, not grant — the\n * destination send-gate `getGrantedConsent` remains a separate concern).\n * `run`/`ready` map to `allowed`. Any other type (including `session`) is\n * satisfied once it has been broadcast (recorded in `seenEvents`), which also\n * recovers a broadcast that fired before the requiring step registered.\n *\n * `session` deliberately uses the `seenEvents` path, not a cell check:\n * `collector.session` is vestigial (never written), so gating on it would park\n * a `require:[\"session\"]` step forever. The session source signals via\n * `command('session', …)`, which records `session` in `seenEvents`, so this\n * keeps `session` order-independent like every other type.\n */\nexport function isRequireSatisfied(\n collector: Collector.Instance,\n type: On.Types,\n): boolean {\n if (isStateCell(type)) return isStatePresent(collector, type);\n switch (type) {\n case Const.Commands.Run:\n case Const.Commands.Ready:\n return collector.allowed === true;\n default:\n return collector.seenEvents.has(String(type));\n }\n}\n\n/**\n * Read a subscriber's high-water mark FOR A CELL. A subscriber that has never\n * been delivered that cell has no entry; we read that as the sentinel -1\n * (\"-infinity\"). Since `stateVersion` starts at 0, the sentinel makes\n * registration catch-up fire (`stateVersion(0) > -1`) even when no version bump\n * has occurred yet.\n *\n * Marks are per `(subscriber, cell-type)`: a subscriber owed two distinct cells\n * at the same `stateVersion` must receive both, so each cell carries its own\n * mark. Subscriber identity keys are objects: a `ConsentRule` object (marked per\n * rule-OBJECT, coarser than per-key but sufficient for single-grant\n * exactly-once), a generic-fn, or a source instance.\n */\nfunction getMark(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): number {\n const marks = collector.delivery.get(subscriber);\n const mark = marks?.[String(type)];\n return mark === undefined ? -1 : mark;\n}\n\n/**\n * The version at which a CELL last changed. A single global `stateVersion`\n * cannot gate per-cell delivery: a later bump to cell B would make an\n * already-delivered cell A look stale. `cellVersion[type]` advances only when\n * that cell changes, so each cell's freshness is independent. A cell never\n * mutated via a command (e.g. `globalsStatic` seeded at construction) reads 0,\n * the construction baseline, so it still delivers once at the run barrier.\n */\nfunction cellVersionOf(collector: Collector.Instance, type: On.Types): number {\n // Read before every destination state delivery, including from callers\n // that hand in a partial collector without version state.\n return collector.cellVersion?.[String(type)] ?? 0;\n}\n\n/**\n * Advance a subscriber's mark for a cell to that cell's current version after\n * an invocation. Only the delivered cell's mark moves; other cells stay owed.\n */\nexport function setMark(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): void {\n // Marks never pass a cell's version, so advancing to the current version\n // is the same as setting it.\n advanceMark(collector, subscriber, type, cellVersionOf(collector, type));\n}\n\n/**\n * A subscriber is invoked for a state delivery iff that CELL has advanced past\n * its per-cell mark AND the collector is allowed. While `!allowed`, deliveries\n * are deferred (not fired, mark not advanced) so the subscriber stays \"owed\".\n */\nexport function shouldDeliver(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): boolean {\n return (\n collector.allowed &&\n cellVersionOf(collector, type) > getMark(collector, subscriber, type)\n );\n}\n\n/**\n * Bounded recursion guard. A state-delivery callback may emit a new state\n * command, re-entering the cascade. A cyclic cascade (A reacts to user by\n * emitting consent, B reacts to consent by emitting user, with ever-changing\n * values that keep bumping `stateVersion`) would recurse until stack overflow.\n *\n * This is a terminate-and-log bound, NOT a fixpoint: when a single\n * `(subscriber, cell-type)` pair would be delivered more than\n * `MAX_DELIVERY_REVISIONS` times within ONE top-level command's cascade, the\n * pair stops delivering and a single non-convergence error is logged. State is\n * left at its last recorded value (no rollback); the outer command finishes and\n * flushes once. Legitimate wide fan-out does not trip: only the SAME\n * `(subscriber, cell-type)` revisited past the bound bails.\n */\nconst MAX_DELIVERY_REVISIONS = 8;\n\n/**\n * Open the cascade-tracking structure for the OUTERMOST top-level state command\n * (or an init flush) and return a teardown. Nested commands emitted by\n * reacting callbacks find `collector.cascade` already set and join it, so the\n * counters are scoped to the originating command; the cascade is cleared when\n * its last holder leaves. Re-entrancy is detected by the presence of\n * `collector.cascade`.\n *\n * Assumes top-level state commands run serially on a given collector;\n * concurrent overlapping state commands on one shared collector are not\n * supported (web is serial; the server per-request path is event push, not\n * state commands).\n */\nexport function enterCascade(collector: Collector.Instance): () => void {\n const open = collector.cascade;\n // A cascade this function did not open is left to whoever set it.\n if (open && !cascadeHolders.has(open)) return () => undefined;\n\n const cascade = open || { counts: new WeakMap() };\n collector.cascade = cascade;\n cascadeHolders.set(cascade, (cascadeHolders.get(cascade) || 0) + 1);\n\n // Reference-counted: the cascade stays open until its last holder leaves,\n // so a command that opened it and finishes first does not end it under an\n // init flush or a nested command still running in it.\n let left = false;\n return () => {\n if (left) return;\n left = true;\n const holders = (cascadeHolders.get(cascade) || 1) - 1;\n if (holders > 0) {\n cascadeHolders.set(cascade, holders);\n return;\n }\n cascadeHolders.delete(cascade);\n if (collector.cascade === cascade) collector.cascade = undefined;\n };\n}\n\n/** Open holders per cascade opened by `enterCascade`. */\nconst cascadeHolders = new WeakMap<Collector.Cascade, number>();\n\n/**\n * Check-and-increment the per-`(subscriber, cell-type)` delivery count for the\n * current cascade. Returns `true` when the delivery is allowed, `false` when the\n * pair has exceeded `MAX_DELIVERY_REVISIONS` (the caller must then skip the\n * delivery). On the single bailing transition, logs the non-convergence error\n * once per pair. Outside a cascade (no `collector.cascade`) it always allows.\n *\n * `subscriber` is the identity object (an `on()` rule, generic-fn, or source\n * instance); `type` is the cell type (consent/user/globals/custom).\n */\nfunction cascadeAllow(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): boolean {\n const cascade = collector.cascade;\n if (!cascade) return true;\n\n let byType = cascade.counts.get(subscriber);\n if (!byType) {\n byType = {};\n cascade.counts.set(subscriber, byType);\n }\n\n const key = String(type);\n const next = (byType[key] || 0) + 1;\n byType[key] = next;\n\n if (next <= MAX_DELIVERY_REVISIONS) return true;\n\n // Past the bound: skip the delivery. Log exactly once per `(subscriber,\n // cell-type)`: the count crosses `MAX + 1` exactly once, so logging on that\n // single transition avoids spam without a separate bail flag.\n if (next === MAX_DELIVERY_REVISIONS + 1)\n collector.logger.error('state delivery did not converge', { type: key });\n\n return false;\n}\n\n/**\n * Build the unified On.Context passed to every subscription callback.\n * Mirrors the Mapping.Context posture: collector + scoped logger only.\n */\nfunction buildOnContext(\n collector: Collector.Instance,\n type: On.Types,\n): On.Context {\n return {\n collector,\n logger: collector.logger.scope('on').scope(String(type)),\n };\n}\n\n/**\n * Registers a callback for a specific event type.\n *\n * @param collector The walkerOS collector instance.\n * @param type The type of the event to listen for.\n * @param option The callback function or an array of callback functions.\n */\nexport async function on(\n collector: Collector.Instance,\n type: On.Types,\n option: WalkerOS.SingleOrArray<On.Subscription>,\n) {\n // Fail closed against a FOREIGN/non-collector caller (see fireCallbacks and\n // isCollectorInstance). `on` dereferences `collector.on` immediately, so it\n // would throw before reaching the dispatch; guard at the top, no state\n // mutated. A real collector always has `.logger`, so this only ever catches a\n // foreign caller.\n if (!isCollectorInstance(collector)) {\n warnForeignDispatch();\n return;\n }\n\n const on = collector.on;\n const onType: Array<On.Subscription> = on[type] || [];\n const options = isArray(option) ? option : [option];\n\n options.forEach((option) => {\n onType.push(option);\n });\n\n // Update collector on state\n (on[type] as typeof onType) = onType;\n\n // Execute the on function directly\n fireCallbacks(collector, type, options);\n}\n\n/**\n * Calls a destination's on() handler with proper context and waits for it to\n * settle. Used by onApply() for live deliveries and by destinationInit() for\n * flushing queued deliveries; both await it, so a handler's side effect (a\n * vendor consent update, an SDK opt-out) lands before the destination's next\n * push. The wait is bounded by the destination's `config.timeout`, the same\n * window as a push.\n *\n * Returns whether the handler settled. A state delivery holds the destination\n * while it runs, and keeps holding it when it does not settle:\n * `pushToDestinations` then keeps its events in `queuePush` rather than\n * sending them to a vendor whose consent state was not set. The hold clears\n * once no state delivery to the destination is in flight and every present\n * state cell has reached the handler.\n *\n * One state handler call runs per destination at a time, so the state the\n * vendor applies last is always the newest. A state delivery that arrives\n * while a call runs does not call the handler: its cell stays owed, and the\n * current cells are delivered right after the running call ends. A call that\n * timed out stays in flight until its handler settles; its late settle marks\n * nothing, and the current cells, then the held events, follow from there.\n * Deferring rather than waiting keeps a handler that issues a state command\n * itself from waiting on its own call.\n *\n * A state delivery carries the command's delta when the destination has\n * received every earlier change of that cell, and the whole cell otherwise\n * (after a failed delivery, or when its mark trails by more than one change),\n * so a settled delivery never marks content it did not carry.\n */\nexport async function callDestinationOn(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n type: On.Types,\n data: unknown,\n): Promise<boolean> {\n const handler = destination.on;\n if (!handler) return true;\n\n // Only a state cell (consent, user, globals, custom) has a push that depends\n // on it; a lifecycle delivery neither holds nor marks. The version is the\n // one this delivery carries, captured before anything can change the cell.\n const gated = isStateDelivery(type);\n\n // A handler call to this destination is still running: a second call\n // could settle first and be overwritten by the older state. The cell stays\n // owed instead. A call that settles in time delivers the current state\n // right after it; one that timed out does so when it finally settles.\n if (\n gated &&\n (overdueDeliveries.get(destination) || stateCalls.has(destination))\n ) {\n markStateLost(collector, destination, type);\n if (!overdueDeliveries.get(destination))\n deferredDuringCall.add(destination);\n return false;\n }\n\n const version = gated ? cellVersionOf(collector, type) : 0;\n const payload =\n gated && owesMoreThanDelta(collector, destination, type, version)\n ? resolveDeliveryData(collector, type)\n : data;\n\n const destType = destination.type || 'unknown';\n const destLogger = collector.logger.scope(destType).scope('on').scope(type);\n\n const context: Destination.Context = {\n collector,\n logger: destLogger,\n id: destId,\n config: destination.config,\n data: payload as Destination.Data,\n env: mergeEnvironments(destination.env, destination.config.env),\n reportError: buildReportError(\n collector,\n 'destination',\n destId,\n destLogger,\n destination,\n ),\n };\n\n // The hold goes up before the handler runs, so an event pushed by another\n // caller while the handler is still running is parked rather than\n // overtaking it: pushes are not serialized with state commands.\n if (gated) {\n openStateDelivery(destination, type);\n setInFlightVersion(destination, type, version);\n stateCalls.add(destination);\n }\n\n const timeoutMs = resolveDestinationTimeout(destination.config.timeout);\n // The handler's own promise, kept for a delivery that times out.\n let running: Promise<unknown> = Promise.resolve();\n let settled = true;\n let timedOut = false;\n let threw = true;\n try {\n await tryCatchAsync(\n () => {\n running = Promise.resolve(handler(type, context));\n return withTimeout(\n running,\n timeoutMs,\n `Destination \"${destId}\" on(${type}) did not settle within ${timeoutMs}ms`,\n );\n },\n (err) => {\n settled = false;\n if (err instanceof DestinationTimeoutError) timedOut = true;\n logOnCallbackError(collector, 'destination', err, { destId, type });\n },\n )();\n threw = false;\n } finally {\n // Also runs when a FatalError propagates: the delivery counts as failed\n // and the window closes, so a later settled delivery can release the hold.\n // No follow-up runs then, so nothing stays deferred.\n if (gated) {\n stateCalls.delete(destination);\n if (threw) deferredDuringCall.delete(destination);\n const lost = lostCells.get(destination);\n if (settled) {\n advanceMark(collector, destination, type, version);\n lost?.delete(String(type));\n } else {\n markStateLost(collector, destination, type);\n }\n if (timedOut) {\n awaitOverdueDelivery(\n collector,\n destination,\n destId,\n type,\n version,\n running,\n destLogger,\n );\n } else {\n clearInFlightVersion(destination, type, version);\n closeStateDelivery(collector, destination);\n }\n }\n }\n\n // State that arrived while the handler ran follows now, as current cells.\n if (gated && !timedOut && deferredDuringCall.delete(destination))\n await catchUpDestinationState(collector, destination, destId);\n\n return settled;\n}\n\n/**\n * Timed-out state deliveries to a destination whose handler has not settled\n * yet. While one runs, no other state delivery to the destination starts.\n */\nconst overdueDeliveries = new WeakMap<Destination.Instance, number>();\n\n/**\n * Destinations whose state handler call is running. Only one runs at a time:\n * a state delivery that arrives meanwhile is deferred.\n */\nconst stateCalls = new WeakSet<Destination.Instance>();\n\n/**\n * Destinations with a state delivery deferred behind a running call. When\n * that call ends in time, the destination catches up on the current state.\n */\nconst deferredDuringCall = new WeakSet<Destination.Instance>();\n\n/**\n * Keep a timed-out state delivery in flight until its handler settles, then\n * close its window. The cell was recorded as lost at the timeout and stays\n * owed, whatever the late outcome, so the hold is released only by a later\n * delivery that carries the current cell and settles in time. That delivery\n * starts from the settle itself, followed by the held events. A handler that\n * never settles keeps the destination held.\n */\nfunction awaitOverdueDelivery(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n type: On.Types,\n version: number,\n running: Promise<unknown>,\n logger: Logger.Instance,\n): void {\n overdueDeliveries.set(\n destination,\n (overdueDeliveries.get(destination) || 0) + 1,\n );\n const settle = () => {\n const count = (overdueDeliveries.get(destination) || 0) - 1;\n if (count > 0) overdueDeliveries.set(destination, count);\n else overdueDeliveries.delete(destination);\n addLostCell(destination, type);\n clearInFlightVersion(destination, type, version);\n closeStateDelivery(collector, destination);\n logger.debug('late settle after timeout');\n deferredDuringCall.delete(destination);\n if (collector.allowed && collector.destinations[destId] === destination)\n recoverDestinationState(collector, destination, destId, logger);\n };\n running.then(settle, settle);\n}\n\n/**\n * Deliver the state a destination still owes, then push the events held for\n * it, without waiting for its next push.\n */\nfunction recoverDestinationState(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n logger: Logger.Instance,\n): void {\n tryCatchAsync(\n async () => {\n await catchUpDestinationState(collector, destination, destId);\n if (!getStateHold(destination) && destination.queuePush?.length)\n await pushToDestinations(\n collector,\n undefined,\n {},\n {\n [destId]: destination,\n },\n );\n },\n (err) => {\n logger.error('state recovery failed', errorMeta(err));\n },\n )();\n}\n\n/**\n * A destination's state hold: set while a state delivery (consent, user,\n * globals, custom) to its `on` handler is running, and kept when it does not\n * settle. While it is set the collector delivers no events to it: they stay in\n * its `queuePush`. Cleared once every present state cell has reached the\n * handler. Collector-internal bookkeeping, keyed by the destination instance.\n */\nexport interface StateHold {\n type: On.Types;\n since: number;\n}\n\nconst stateHolds = new WeakMap<Destination.Instance, StateHold>();\n\n/** The destination's current state hold, if it is held. */\nexport function getStateHold(\n destination: Destination.Instance,\n): StateHold | undefined {\n return stateHolds.get(destination);\n}\n\n/**\n * State deliveries to a destination that have started and not yet ended. The\n * hold is never released while one is running.\n */\nconst stateInFlight = new WeakMap<Destination.Instance, number>();\n\n/**\n * Per destination and cell, the newest version a running delivery carries. A\n * second delivery of a version that is already on its way is not started.\n */\nconst inFlightVersions = new WeakMap<\n Destination.Instance,\n Record<string, number>\n>();\n\nfunction setInFlightVersion(\n destination: Destination.Instance,\n type: On.Types,\n version: number,\n): void {\n let versions = inFlightVersions.get(destination);\n if (!versions) {\n versions = {};\n inFlightVersions.set(destination, versions);\n }\n const key = String(type);\n const current = versions[key];\n if (current === undefined || current < version) versions[key] = version;\n}\n\nfunction clearInFlightVersion(\n destination: Destination.Instance,\n type: On.Types,\n version: number,\n): void {\n const versions = inFlightVersions.get(destination);\n if (versions && versions[String(type)] === version)\n delete versions[String(type)];\n}\n\n/**\n * Cells whose last delivery to a destination did not settle. The next\n * delivery of such a cell carries the whole cell, and the hold stays until it\n * settles.\n */\nconst lostCells = new WeakMap<Destination.Instance, Set<string>>();\n\nfunction addLostCell(destination: Destination.Instance, type: On.Types): void {\n const lost = lostCells.get(destination);\n if (lost) lost.add(String(type));\n else lostCells.set(destination, new Set([String(type)]));\n}\n\n/**\n * Destinations whose init flush is running. `held` records whether the flush\n * opened a state delivery window, closed once when the flush ends.\n */\nconst initFlushes = new WeakMap<Destination.Instance, { held: boolean }>();\n\n/**\n * Start a destination's init flush. While it runs, new deliveries to the\n * destination are queued behind the flush's entries. When the queue carries a\n * state entry the hold covers the whole flush, lifecycle entries before it\n * included, so no push slips in between two entries.\n */\nexport function beginInitFlush(destination: Destination.Instance): void {\n const first = destination.queueOn?.find(({ type }) => isStateDelivery(type));\n if (first) openStateDelivery(destination, first.type);\n initFlushes.set(destination, { held: !!first });\n}\n\n/** End a destination's init flush, releasing its window if it opened one. */\nexport function endInitFlush(\n collector: Collector.Instance,\n destination: Destination.Instance,\n): void {\n const flush = initFlushes.get(destination);\n initFlushes.delete(destination);\n if (flush?.held) closeStateDelivery(collector, destination);\n}\n\n/**\n * Record that a state cell did not reach a destination's handler: the mark is\n * taken back, the next delivery of the cell carries all of it, and the\n * destination is held, dated now, until that delivery settles. Used for a\n * delivery that failed, one the init flush never reached, and one the cascade\n * bound suppressed.\n */\nexport function markStateLost(\n collector: Collector.Instance,\n destination: Destination.Instance,\n type: On.Types,\n): void {\n clearMark(collector, destination, type);\n addLostCell(destination, type);\n stateHolds.set(destination, { type, since: Date.now() });\n}\n\n/**\n * Whether a destination is owed state: a cell whose delivery was lost, or a\n * present cell it has not received at its current version. False while the\n * collector is not allowed (nothing is deliverable yet).\n */\nexport function owesDestinationState(\n collector: Collector.Instance,\n destination: Destination.Instance,\n): boolean {\n if (lostCells.get(destination)?.size) return true;\n return STATE_CELLS.some(\n (cell) =>\n isStatePresent(collector, cell) &&\n shouldDeliver(collector, destination, cell),\n );\n}\n\n/**\n * Start a state delivery window on a destination: raise the hold and count\n * the window as in flight. Every call is paired with `closeStateDelivery`.\n * Used per delivery by `callDestinationOn`, and around the whole init flush by\n * `destinationInit`, so no push slips in between two queued entries.\n */\nexport function openStateDelivery(\n destination: Destination.Instance,\n type: On.Types,\n): void {\n stateInFlight.set(destination, (stateInFlight.get(destination) || 0) + 1);\n stateHolds.set(destination, { type, since: Date.now() });\n}\n\n/**\n * End a state delivery window, then release the hold if nothing else is in\n * flight and nothing is owed.\n */\nexport function closeStateDelivery(\n collector: Collector.Instance,\n destination: Destination.Instance,\n): void {\n const count = (stateInFlight.get(destination) || 0) - 1;\n if (count > 0) stateInFlight.set(destination, count);\n else stateInFlight.delete(destination);\n releaseHoldIfCurrent(collector, destination);\n}\n\n/**\n * Whether a delivery of `type` at `version` would leave a gap if it carried\n * only the command's delta: the cell's last delivery failed, the destination\n * has no mark for the cell (it never received it, so earlier content may be\n * missing), or its mark trails by more than one change. Every activation path\n * marks the present cells first, so in the init flush (entries marked when\n * queued) and on the live path the delta is what gets delivered.\n */\nfunction owesMoreThanDelta(\n collector: Collector.Instance,\n destination: Destination.Instance,\n type: On.Types,\n version: number,\n): boolean {\n if (lostCells.get(destination)?.has(String(type))) return true;\n const mark = collector.delivery?.get(destination)?.[String(type)];\n return mark === undefined || mark < version - 1;\n}\n\n/**\n * Advance a subscriber's mark for a cell to the version a delivery carried.\n * Marks only move forward: a slower delivery of an older version that settles\n * after a newer one does not take the mark back.\n */\nfunction advanceMark(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n version: number,\n): void {\n let marks = collector.delivery.get(subscriber);\n if (!marks) {\n marks = {};\n collector.delivery.set(subscriber, marks);\n }\n const key = String(type);\n const current = marks[key];\n if (current === undefined || current < version) marks[key] = version;\n}\n\n/**\n * Take a delivery mark back, so the cell reads as owed again. The mirror of\n * `setMark`: a delivery that was committed (called, or queued for the init\n * flush) but did not settle has not happened, and the subscriber must be\n * offered it again.\n */\nexport function clearMark(\n collector: Collector.Instance,\n subscriber: object,\n type: On.Types,\n): void {\n // Reached on every failed state delivery, including from callers that\n // hand in a partial collector without delivery marks.\n const marks = collector.delivery?.get(subscriber);\n if (marks) delete marks[String(type)];\n}\n\n/**\n * Clear a destination's hold only when no state delivery to it is in flight,\n * no delivery of a cell is outstanding after a failure, and every present\n * state cell has reached its `on` handler. A settled delivery of one cell\n * says nothing about another: a `user` delivery must not open the gate while\n * `consent` is still owed.\n */\nfunction releaseHoldIfCurrent(\n collector: Collector.Instance,\n destination: Destination.Instance,\n): void {\n if (!stateHolds.has(destination)) return;\n if (stateInFlight.get(destination)) return;\n if (!owesDestinationState(collector, destination)) {\n stateHolds.delete(destination);\n }\n}\n\n/**\n * Fire a set of registered `on` callbacks against current collector state.\n *\n * Used by both `on()` (when registering a new callback, to fire it against\n * current state) and `onApply()` (when dispatching a state-change command to\n * every registered callback of that type). Separating this from `onApply`\n * ensures `on()` does NOT trigger `onApply`'s source/destination broadcast,\n * which would cause infinite recursion if a source's `on` handler registers\n * another callback of the same type.\n */\nexport function fireCallbacks(\n collector: Collector.Instance,\n type: On.Types,\n options: Array<On.Subscription>,\n config?: unknown,\n): void {\n // Fail closed against a FOREIGN/non-collector caller. Threat: a minified\n // build can leak this helper onto a global that collides with another\n // library's API (e.g. a global named `ga`), which then invokes it with\n // foreign args like `(\"sent\",\"event\")`. The string \"sent\" would arrive here\n // as `collector` and crash on `\"sent\".logger.scope`. A genuine collector\n // ALWAYS has `.logger` (collector.ts assigns `logger: createLogger(...)`\n // unconditionally and createLogger never returns undefined), so this guard\n // can ONLY catch a foreign caller; it can never mask a real internal dispatch.\n if (!isCollectorInstance(collector)) {\n warnForeignDispatch();\n return;\n }\n\n // Calculate context data once for all sources and destinations.\n const contextData = resolveDeliveryData(collector, type, config);\n\n if (!options.length) return;\n\n switch (type) {\n case Const.Commands.Consent:\n onConsent(\n collector,\n options as Array<On.ConsentRule>,\n config as WalkerOS.Consent,\n );\n break;\n case Const.Commands.Ready:\n onReady(collector, options as Array<On.ReadyFn>);\n break;\n case Const.Commands.Run:\n onRun(collector, options as Array<On.RunFn>);\n break;\n case Const.Commands.Session:\n onSession(collector, options as Array<On.SessionFn>);\n break;\n default: {\n // Generic handler for user, custom, globals, config, and arbitrary events\n const ctx = buildOnContext(collector, type);\n const gated = isStateDelivery(type);\n options.forEach((func) => {\n if (typeof func !== 'function') return;\n // State-delivery generics (user/custom/globals) carry the per-subscriber\n // exactly-once + `allowed` gate. Non-reactive generics (config, arbitrary\n // events) keep their previous unconditional behavior.\n if (gated && !shouldDeliver(collector, func, type)) return;\n // Bounded recursion guard: a reacting generic that re-emits state could\n // cascade cyclically. Stop delivering this (func, cell-type) past the\n // bound (logs once); leave state at its last value.\n if (gated && !cascadeAllow(collector, func, type)) return;\n tryCatch(func as On.GenericFn, (err) =>\n logOnCallbackError(collector, 'generic', err, { type }),\n )(contextData, ctx);\n if (gated) setMark(collector, func, type);\n });\n break;\n }\n }\n}\n\n/**\n * Resolve the broadcast payload for a state/lifecycle delivery. An explicit\n * `config` (the command's update payload) wins; otherwise the current cell on\n * the collector is read. Shared by `onApply` and the run-barrier re-delivery so\n * both broadcast identical data.\n */\nfunction resolveDeliveryData(\n collector: Collector.Instance,\n type: On.Types,\n config?: unknown,\n): unknown {\n if (isStateCell(type)) return config || collector[type];\n switch (type) {\n case Const.Commands.Session:\n return collector.session;\n case Const.Commands.Config:\n return config || collector.config;\n default:\n return undefined;\n }\n}\n\n/**\n * Deliver a single state/lifecycle event to one started source's `on` handler,\n * carrying the per-subscriber exactly-once + `allowed` gate for state\n * deliveries. Returns `true` when the handler vetoed (returned `false`).\n *\n * Shared by the live `onApply` broadcast and the run-barrier re-delivery. It\n * does NOT touch `config.require` or `queueOn`: those belong to the live\n * command path's unstarted-source handling, not the barrier.\n */\nasync function deliverStateToSource(\n collector: Collector.Instance,\n source: Source.Instance,\n sourceId: string,\n type: On.Types,\n contextData: unknown,\n): Promise<boolean> {\n if (!source.on) return false;\n\n // State deliveries (consent/user/globals/custom) carry the per-subscriber\n // exactly-once + `allowed` gate keyed by the source instance. While !allowed\n // a state delivery is deferred (not invoked, mark not advanced). Lifecycle\n // deliveries (ready/run/session/config) are not gated here.\n if (isStateDelivery(type) && !shouldDeliver(collector, source, type))\n return false;\n\n // Bounded recursion guard: a source `on` handler that re-emits state could\n // cascade cyclically. Stop delivering this (source, cell-type) past the bound\n // (logs once); leave state at its last value.\n if (isStateDelivery(type) && !cascadeAllow(collector, source, type))\n return false;\n\n // One state handler call runs per source at a time, as for destinations: a\n // state delivery that arrives meanwhile leaves its cell owed, and the\n // current cells follow once the running call ends.\n const gated = isStateDelivery(type);\n if (gated && sourceStateCalls.has(source)) {\n deferredSourceCalls.add(source);\n return false;\n }\n const version = gated ? cellVersionOf(collector, type) : 0;\n if (gated) sourceStateCalls.add(source);\n\n // Sources carry no per-step timeout config and share the destination\n // default, so one hung source handler cannot stall the delivery pass.\n const handler = source.on;\n let running: Promise<unknown> = Promise.resolve();\n let timedOut = false;\n let result: unknown;\n try {\n result = await tryCatchAsync(\n () => {\n running = Promise.resolve(handler(type, contextData));\n return withTimeout(\n running,\n DEFAULT_DESTINATION_TIMEOUT_MS,\n `Source \"${sourceId}\" on(${type}) did not settle within ${DEFAULT_DESTINATION_TIMEOUT_MS}ms`,\n );\n },\n (err) => {\n if (err instanceof DestinationTimeoutError) timedOut = true;\n logOnCallbackError(collector, 'source', err, { sourceId, type });\n },\n )();\n } finally {\n // A timed-out call stays running until its handler settles.\n if (gated && !timedOut) sourceStateCalls.delete(source);\n }\n\n if (gated) {\n if (timedOut) {\n // A timed-out delivery has not happened: the mark stays, the cell stays\n // owed, and the current cells follow the late settle.\n const settle = () => {\n sourceStateCalls.delete(source);\n deferredSourceCalls.delete(source);\n if (collector.allowed && collector.sources[sourceId] === source)\n tryCatchAsync(\n () => catchUpSourceState(collector, source, sourceId),\n (err) => {\n collector.logger\n .scope('on')\n .error('state recovery failed', errorMeta(err));\n },\n )();\n };\n running.then(settle, settle);\n } else {\n advanceMark(collector, source, type, version);\n if (deferredSourceCalls.delete(source))\n await catchUpSourceState(collector, source, sourceId);\n }\n }\n\n return result === false;\n}\n\n/** Sources whose state handler call is running. */\nconst sourceStateCalls = new WeakSet<Source.Instance>();\n\n/** Sources with a state delivery deferred behind a running call. */\nconst deferredSourceCalls = new WeakSet<Source.Instance>();\n\n/** Deliver every state cell a started source still owes. */\nasync function catchUpSourceState(\n collector: Collector.Instance,\n source: Source.Instance,\n sourceId: string,\n): Promise<void> {\n // Opened or joined here, as for destinations, so the bound applies. Every\n // owed cell is delivered, one with no content included: a deferred update\n // reaches the source as it would have without the running call.\n const exitCascade = enterCascade(collector);\n try {\n for (const type of STATE_CELLS) {\n await deliverStateToSource(\n collector,\n source,\n sourceId,\n type,\n resolveDeliveryData(collector, type),\n );\n }\n } finally {\n exitCascade();\n }\n}\n\n/**\n * Deliver one state or lifecycle event to a registered destination's `on`\n * handler. State deliveries (consent/user/globals/custom) carry the same\n * per-subscriber exactly-once + `allowed` gate as sources and `on` rules,\n * keyed by the destination instance: while `!allowed` the delivery is deferred\n * (not queued, mark not advanced) and the run barrier delivers it; once\n * allowed, each cell change reaches the destination exactly once. Lifecycle\n * deliveries (ready/run/session/config/arbitrary) are unconditional.\n *\n * A delivery is committed either by calling `on()` now (initialized\n * destination, marked by `callDestinationOn` when it settles) or by appending\n * to `queueOn`, which `destinationInit` flushes before the destination's first\n * push. The queue branch marks the cell itself: a cell already waiting in\n * `queueOn` is not owed, so the run barrier, which fires on every navigation,\n * does not append it again. A queued entry whose flush fails takes its mark\n * back in `callDestinationOn`, and the next delivery carries the whole cell.\n */\nexport async function deliverStateToDestination(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n type: On.Types,\n data: unknown,\n): Promise<void> {\n if (!destination.on) return;\n\n const gated = isStateDelivery(type);\n if (gated && !shouldDeliver(collector, destination, type)) return;\n // The current version of the cell is already on its way to the handler.\n const inFlight = inFlightVersions.get(destination)?.[String(type)];\n if (\n gated &&\n inFlight !== undefined &&\n inFlight >= cellVersionOf(collector, type)\n )\n return;\n // Bounded recursion guard: a destination `on` handler that re-emits state\n // could cascade cyclically. Past the bound the delivery is skipped (logged\n // once). An initialized destination records the cell as lost, so it is held\n // until a later delivery of it settles. An uninitialized one runs no handler\n // here, so nothing can recurse: the whole cell is queued for its init flush\n // instead of this delta, replacing a trailing entry of the same cell.\n if (gated && !cascadeAllow(collector, destination, type)) {\n if (destination.config.init) {\n markStateLost(collector, destination, type);\n return;\n }\n const queue = (destination.queueOn = destination.queueOn || []);\n const entry = { type, data: resolveDeliveryData(collector, type) };\n const last = queue[queue.length - 1];\n if (last && last.type === type) queue[queue.length - 1] = entry;\n else queue.push(entry);\n setMark(collector, destination, type);\n lostCells.get(destination)?.delete(String(type));\n return;\n }\n\n // Uninitialized, or its init flush is still running: the delivery joins\n // the queue behind the older entries, so it never overtakes them.\n const flush = initFlushes.get(destination);\n if (!destination.config.init || flush) {\n destination.queueOn = destination.queueOn || [];\n destination.queueOn.push({ type, data });\n if (gated) {\n setMark(collector, destination, type);\n // A state entry joining a running flush holds the destination for the\n // rest of the flush.\n if (flush && !flush.held) {\n openStateDelivery(destination, type);\n flush.held = true;\n }\n }\n return;\n }\n\n await callDestinationOn(collector, destination, destId, type, data);\n}\n\n/**\n * Registration catch-up for a destination that just became active: a pending\n * `require` gate satisfied, or a runtime `walker destination`. Delivers every\n * present state cell as a snapshot through the same gate as a live broadcast,\n * so the destination's `on` handler sees the state that activated it before\n * its queued events are pushed, and holds a mark for every present cell\n * before any later delta reaches it. While `!allowed` this is inert and the\n * run barrier delivers instead. Also the retry of a held destination: only the\n * cells it still owes pass the gate.\n */\nexport async function catchUpDestinationState(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n): Promise<void> {\n if (!destination.on) return;\n // Opened or joined here, so a catch-up outside a command (a push's retry, a\n // late settle) still counts a handler that re-emits state against the bound.\n const exitCascade = enterCascade(collector);\n try {\n for (const type of STATE_CELLS) {\n // A cell with no content is not owed, unless its delivery was lost\n // (failed, or deferred behind a running call): that one still holds the\n // destination until it arrives.\n if (\n !isStatePresent(collector, type) &&\n !lostCells.get(destination)?.has(String(type))\n )\n continue;\n await deliverStateToDestination(\n collector,\n destination,\n destId,\n type,\n resolveDeliveryData(collector, type),\n );\n }\n } finally {\n exitCascade();\n }\n}\n\n/**\n * Whether a state delivery to the destination is running right now (a live\n * delivery or an init flush). A held destination is not retried while one is.\n */\nexport function isStateDeliveryInFlight(\n destination: Destination.Instance,\n): boolean {\n return (stateInFlight.get(destination) || 0) > 0;\n}\n\n/**\n * Run-barrier re-delivery. Called once from `runCollector` after the collector\n * becomes `allowed` and the RunState merge has bumped `stateVersion` for any\n * merged cells. Re-broadcasts each non-empty recorded state cell to its OWED\n * subscribers (mark < stateVersion) exactly once, so reactions deferred while\n * `!allowed` now emit into the open, consent-gated pipeline.\n *\n * Narrow path: it fires `collector.on` rules/fns via `fireCallbacks`, the\n * gated `source.on` handlers via `deliverStateToSource`, and the gated\n * destination `on` handlers via `deliverStateToDestination` (queued for an\n * uninitialized destination's init flush). It deliberately skips the\n * `require`-decrement and `queueOn`-flush machinery in `onApply` (those are\n * live-command concerns). Exactly-once is free from the `shouldDeliver` gate:\n * already-delivered subscribers (mark == stateVersion) are skipped.\n */\nexport async function redeliverStateAtRun(\n collector: Collector.Instance,\n): Promise<void> {\n const deliveries = await startRunRedelivery(collector);\n await Promise.all(deliveries.map(({ done }) => done));\n}\n\n/**\n * The run barrier without waiting for destinations. Rules and started sources\n * are re-delivered per cell and awaited (sources bounded); each destination\n * gets its own sequence of owed cells, started here and returned, so one slow\n * destination handler delays no other destination's run flush. A destination\n * is held from the start of its first delivery until nothing is owed.\n */\nexport async function startRunRedelivery(\n collector: Collector.Instance,\n): Promise<DestinationDelivery[]> {\n // Fail closed against a FOREIGN/non-collector caller (see fireCallbacks and\n // isCollectorInstance). This dereferences the collector's state cells, so\n // guard at the top, no state mutated, neutral result. A real collector\n // always has `.logger`, so this only ever catches a foreign caller.\n if (!isCollectorInstance(collector)) {\n warnForeignDispatch();\n return [];\n }\n\n // Each registered destination receives every owed cell, in cell order, as\n // a snapshot of the cell when its turn comes.\n const deliveries: DestinationDelivery[] = [];\n for (const [destId, destination] of Object.entries(collector.destinations)) {\n if (!destination.on) continue;\n const sequence = async () => {\n for (const type of STATE_CELLS) {\n if (!isStatePresent(collector, type)) continue;\n await deliverStateToDestination(\n collector,\n destination,\n destId,\n type,\n resolveDeliveryData(collector, type),\n );\n }\n };\n deliveries.push(startDelivery(destId, destination, sequence()));\n }\n\n for (const type of STATE_CELLS) {\n if (!isStatePresent(collector, type)) continue;\n\n const contextData = resolveDeliveryData(collector, type);\n\n // Re-deliver to registered collector.on rules/fns. fireCallbacks carries\n // the same per-subscriber gate, so owed rules fire once and advance.\n fireCallbacks(collector, type, collector.on[type] || []);\n\n // Re-deliver to started sources through the gated helper, concurrently:\n // one slow source handler does not cost the others their own timeout.\n await Promise.all(\n Object.entries(collector.sources)\n .filter(([, source]) => isSourceStarted(source))\n .map(([sourceId, source]) =>\n deliverStateToSource(collector, source, sourceId, type, contextData),\n ),\n );\n }\n\n return deliveries;\n}\n\n/**\n * Applies all registered callbacks for a specific event type.\n *\n * @param collector The walkerOS collector instance.\n * @param type The type of the event to apply the callbacks for.\n * @param options The options for the callbacks.\n * @param config The consent configuration.\n */\nexport async function onApply(\n collector: Collector.Instance,\n type: On.Types,\n options?: Array<On.Subscription>,\n config?: unknown,\n): Promise<boolean> {\n const { ok, deliveries } = await onApplyDeferred(\n collector,\n type,\n options,\n config,\n );\n await Promise.all(deliveries.map(({ done }) => done));\n return ok;\n}\n\n/**\n * A destination's `on()` delivery that a command started and did not wait\n * for. `drain` is set by the caller just before its flush when the\n * destination was held then: its events were parked, and once `done` settles\n * they are pushed for that destination alone.\n */\nexport interface DestinationDelivery {\n id: string;\n destination: Destination.Instance;\n done: Promise<void>;\n drain?: boolean;\n}\n\n/**\n * Start a destination delivery without waiting for it. A rejection (a\n * FatalError) stays on `done` for the caller that settles it; the handler\n * attached here only keeps it from surfacing as unhandled in between.\n */\nfunction startDelivery(\n id: string,\n destination: Destination.Instance,\n done: Promise<void>,\n): DestinationDelivery {\n done.catch(() => undefined);\n return { id, destination, done };\n}\n\n/**\n * `onApply` without waiting for destination deliveries. Sources are awaited\n * (bounded); every destination's `on()` delivery is started and returned, so\n * the caller can flush every destination at once: a destination whose\n * delivery is still running is held, its events wait for its own delivery,\n * and no other destination waits for it.\n */\nexport async function onApplyDeferred(\n collector: Collector.Instance,\n type: On.Types,\n options?: Array<On.Subscription>,\n config?: unknown,\n): Promise<{ ok: boolean; deliveries: DestinationDelivery[] }> {\n // Fail closed against a FOREIGN/non-collector caller (see fireCallbacks and\n // isCollectorInstance). `onApply` dereferences `collector.seenEvents`\n // immediately, so it would throw before reaching the dispatch; guard at the\n // top, no state mutated. Return the neutral not-vetoed result (`true`). A real\n // collector always has `.logger`, so this only ever catches a foreign caller.\n if (!isCollectorInstance(collector)) {\n warnForeignDispatch();\n return { ok: true, deliveries: [] };\n }\n\n // Record every broadcast type so a `require:[<arbitrary>]` gate stays\n // satisfiable from current state (incl. a broadcast that fired before the\n // requiring step registered). Cell-backed types are level-checked separately.\n collector.seenEvents.add(String(type));\n\n // Use the optionally provided options\n let onConfig = options || [];\n\n if (!options) {\n // Get the collector on events\n onConfig = collector.on[type] || [];\n }\n\n // Calculate context data once for source/destination broadcast.\n const contextData = resolveDeliveryData(collector, type, config);\n\n // Synchronous bookkeeping first, in subscriber order: the per-source require\n // decrement, queueOn buffering for unstarted sources and uninitialized\n // destinations, and the list of handlers that receive this delivery now.\n // Sources are not \"started\" until config.init === true AND config.require\n // is empty; their queued on() events are replayed once they start.\n const sourceDeliveries: Array<Promise<boolean>> = [];\n for (const [sourceId, source] of Object.entries(collector.sources)) {\n if (source.config.require?.length) {\n const idx = source.config.require.indexOf(type);\n if (idx !== -1) source.config.require.splice(idx, 1);\n }\n\n if (!source.on) continue;\n\n if (isSourceStarted(source)) {\n sourceDeliveries.push(\n deliverStateToSource(collector, source, sourceId, type, contextData),\n );\n } else {\n source.queueOn = source.queueOn || [];\n source.queueOn.push({ type, data: contextData });\n }\n }\n\n // Destinations: state deliveries are gated (exactly-once, deferred while\n // not allowed); an uninitialized destination's delivery is queued for its\n // init flush, synchronously, inside deliverStateToDestination.\n const deliveries: DestinationDelivery[] = [];\n for (const [destId, destination] of Object.entries(collector.destinations)) {\n if (!destination.on) continue;\n deliveries.push(\n startDelivery(\n destId,\n destination,\n deliverStateToDestination(\n collector,\n destination,\n destId,\n type,\n contextData,\n ),\n ),\n );\n }\n\n // Source handlers run concurrently, each bounded by the default timeout.\n // Destination deliveries are not awaited here: each is held while it runs\n // and the caller settles them after its flush. With no source handler to\n // wait for there is no await, which keeps the synchronous ordering the\n // bounded-recursion cascade relies on.\n let vetoed = false;\n if (sourceDeliveries.length) {\n const sourceVetoes = await Promise.all(sourceDeliveries);\n vetoed = sourceVetoes.some(Boolean);\n }\n\n // Sources whose require was just emptied AND init has run: flush their\n // queueOn now (the require-completing event was queued in the gated\n // branch above, so flushing here delivers it without losing ordering).\n for (const [sourceId, source] of Object.entries(collector.sources)) {\n if (isSourceStarted(source) && source.queueOn?.length) {\n await flushSourceQueueOn(collector, source, sourceId);\n }\n }\n\n // Activate any pending source/destination whose require is now satisfied by\n // current state. Level-based and additive: the per-source broadcast decrement\n // above still handles started-source delivery + queueOn buffering; reconcile\n // additionally activates steps satisfied by the recorded cell (or by an\n // arbitrary type already in `seenEvents`), so order does not matter.\n //\n // Gate the await on there being actual pending work: with nothing to\n // reconcile this is a no-op, and skipping the await preserves the\n // synchronous microtask ordering the bounded-recursion cascade relies on.\n const hasUnstartedSource = Object.values(collector.sources).some(\n (source) => !isSourceStarted(source) && source.config.require?.length,\n );\n if (\n Object.keys(collector.pending.destinations).length > 0 ||\n hasUnstartedSource\n ) {\n await reconcilePending(collector);\n }\n\n fireCallbacks(collector, type, onConfig, config);\n\n return { ok: !vetoed, deliveries };\n}\n\nfunction onConsent(\n collector: Collector.Instance,\n onConfig: Array<On.ConsentRule>,\n currentConsent?: WalkerOS.Consent,\n): void {\n const consentState = currentConsent || collector.consent;\n const ctx = buildOnContext(collector, Const.Commands.Consent);\n\n onConfig.forEach((rule) => {\n // Per-subscriber exactly-once gate, keyed by the rule OBJECT (coarser than\n // per-key, but sufficient for single-grant exactly-once). While !allowed\n // the delivery is deferred: don't invoke, don't advance the mark.\n if (!shouldDeliver(collector, rule, Const.Commands.Consent)) return;\n\n // Bounded recursion guard: a consent rule that re-emits state could cascade\n // cyclically. Stop delivering this (rule, consent) past the bound (logs\n // once); leave state at its last value.\n if (!cascadeAllow(collector, rule, Const.Commands.Consent)) return;\n\n // Execute every handler whose consent key is present in the current state.\n Object.keys(consentState)\n .filter((key) => key in rule)\n .forEach((key) => {\n tryCatch(rule[key], (err) =>\n logOnCallbackError(collector, 'consent', err, { key }),\n )(consentState, ctx);\n });\n\n // Advance the mark after an allowed invocation.\n setMark(collector, rule, Const.Commands.Consent);\n });\n}\n\nfunction onReady(\n collector: Collector.Instance,\n onConfig: Array<On.ReadyFn>,\n): void {\n if (!collector.allowed) return;\n const ctx = buildOnContext(collector, Const.Commands.Ready);\n onConfig.forEach((func) => {\n tryCatch(func, (err) => logOnCallbackError(collector, 'ready', err))(\n undefined,\n ctx,\n );\n });\n}\n\nfunction onRun(collector: Collector.Instance, onConfig: Array<On.RunFn>): void {\n if (!collector.allowed) return;\n const ctx = buildOnContext(collector, Const.Commands.Run);\n onConfig.forEach((func) => {\n tryCatch(func, (err) => logOnCallbackError(collector, 'run', err))(\n undefined,\n ctx,\n );\n });\n}\n\nfunction onSession(\n collector: Collector.Instance,\n onConfig: Array<On.SessionFn>,\n): void {\n if (!collector.session) return;\n const ctx = buildOnContext(collector, Const.Commands.Session);\n onConfig.forEach((func) => {\n tryCatch(func, (err) => logOnCallbackError(collector, 'session', err))(\n collector.session,\n ctx,\n );\n });\n}\n","import type {\n Collector,\n Context,\n Destination,\n Logger,\n StepKind,\n WalkerOS,\n} from '@walkeros/core';\nimport { stepId } from '@walkeros/core';\nimport { pushBounded, resetOverflowFlag, warnOverflowOnce } from './buffers';\nimport { recordStepOutcome, resolveBreakerConfig } from './breaker';\n\n/**\n * Maximum number of failed-push entries retained per destination DLQ before\n * FIFO drop-oldest. Mirrored by `Destination.Config.dlqMax`.\n */\nexport const DEFAULT_DLQ_MAX = 100;\n\n/**\n * Ensure a per-destination status entry exists and return it.\n */\nexport function ensureDestStatus(\n collector: Collector.Instance,\n destId: string,\n): Collector.DestinationStatus {\n if (!collector.status.destinations[destId]) {\n collector.status.destinations[destId] = {\n count: 0,\n failed: 0,\n duration: 0,\n queuePushSize: 0,\n dlqSize: 0,\n };\n }\n return collector.status.destinations[destId];\n}\n\n/**\n * Bump a drop counter under `status.dropped[stepId][buffer]`. Lazily\n * creates the per-step entry; returns the new counter value so callers\n * can pass it straight into the warn-once log payload.\n */\nexport function bumpDropped(\n status: Collector.Status,\n id: string,\n buffer: 'queue' | 'dlq',\n n: number,\n): number {\n if (!status.dropped[id]) status.dropped[id] = {};\n const entry = status.dropped[id];\n entry[buffer] = (entry[buffer] ?? 0) + n;\n return entry[buffer]!;\n}\n\n/**\n * Routes a single event/error pair to a destination's DLQ with the bounded\n * write, overflow-warn-once, and full failure accounting (`destStatus.failed`\n * + `collector.status.failed`). This mirrors the batch flush's `routeToDlq`\n * for the single-event case: write to the DLQ AND bump the failed counters in\n * one place. (The per-event in-band push path bumps `failed` later in the\n * aggregation pass instead, so it does NOT call this; this helper is for the\n * out-of-band `reportError(err, event)` seam that has no aggregation pass.)\n */\nfunction routeEventToDlq(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n event: WalkerOS.Event,\n err: unknown,\n logger: Logger.Instance,\n): void {\n const dlq = (destination.dlq = destination.dlq || []);\n const dlqBound = { max: destination.config.dlqMax ?? DEFAULT_DLQ_MAX };\n const dlqResult = pushBounded(dlq, [event, err], dlqBound);\n if (dlqResult.dropped > 0) {\n const droppedCount = bumpDropped(\n collector.status,\n stepId('destination', destId),\n 'dlq',\n dlqResult.dropped,\n );\n warnOverflowOnce(\n dlq,\n logger,\n 'destination.dlq overflow; oldest entries dropped',\n {\n buffer: 'dlq',\n destination: destId,\n cap: dlqBound.max,\n droppedCount,\n },\n );\n } else if (dlq.length < dlqBound.max) {\n resetOverflowFlag(dlq);\n }\n const destStatus = ensureDestStatus(collector, destId);\n destStatus.failed++;\n destStatus.dlqSize = dlq.length;\n collector.status.failed++;\n\n // A connection-level error that DLQs a specific event is a transport\n // failure: feed it to the circuit breaker so the gate picks it up.\n // Presence-gated and keyed on the canonical stepId (matching the push gate).\n const breakerConfig = resolveBreakerConfig(destination.config.breaker);\n if (breakerConfig) {\n const canonicalId = destination.config.id || destId;\n recordStepOutcome(\n collector.status.breakers,\n stepId('destination', canonicalId),\n 'transport-failure',\n breakerConfig.threshold,\n breakerConfig.cooldown,\n );\n }\n}\n\n/**\n * Extract loggable metadata from an unknown error: the message plus, when\n * present, the error's `name` (skipped for the default 'Error', which adds no\n * signal) and its transport `code` (gRPC status number or HTTP status). Keeps\n * connection-error lines diagnosable from logs alone (WHICH status killed a\n * stream), without serializing whole error objects into the log payload.\n */\nexport function errorMeta(err: unknown): {\n error: string;\n name?: string;\n code?: string | number;\n} {\n const meta: { error: string; name?: string; code?: string | number } = {\n error: err instanceof Error ? err.message : String(err),\n };\n if (err instanceof Error && err.name && err.name !== 'Error') {\n meta.name = err.name;\n }\n if (typeof err === 'object' && err !== null && 'code' in err) {\n const withCode: { code?: unknown } = err;\n if (\n typeof withCode.code === 'number' ||\n typeof withCode.code === 'string'\n ) {\n meta.code = withCode.code;\n }\n }\n return meta;\n}\n\n/**\n * Builds the step-general `reportError` callback for one step's context.\n *\n * This is the runtime behind `Context.Base.reportError`. It is captured ONCE\n * when a step's context is built and closes over `(collector, kind, id,\n * logger, destination)`, so a long-lived connection that holds the reference\n * keeps a valid callback for its whole lifetime — it is never rebuilt per\n * push. It runs on a detached emitter tick, so every path is internally\n * try/catch-guarded; a throw inside it would reintroduce the very\n * uncaughtException it exists to contain.\n *\n * - orphan (`reportError(err)`): bump `status.connectionErrors[stepId]` and\n * `logger.error`. Does NOT bump `failed` (no event lost at this instant;\n * counting it against `failed` would double-count the next push that hits\n * the broken writer and gets DLQ'd).\n * - event-bearing (`reportError(err, event)`): route the event through the\n * same DLQ + failure accounting an in-band push failure uses (for a\n * destination). A step kind without a DLQ (or a destination not passed)\n * still gets `failed`-counted and logged, never silently dropped.\n *\n * The with-event path deliberately funnels through the normal failure\n * accounting so that when circuit-breaker accounting is later attached to that\n * path, `reportError(err, event)` picks it up with no further wiring here.\n */\nexport function buildReportError(\n collector: Collector.Instance,\n kind: Exclude<StepKind, 'collector'>,\n id: string,\n logger: Logger.Instance,\n destination?: Destination.Instance,\n): NonNullable<Context.Base['reportError']> {\n const key = stepId(kind, id);\n return (err: unknown, event?: WalkerOS.Event): void => {\n try {\n if (event) {\n if (destination) {\n routeEventToDlq(collector, destination, id, event, err, logger);\n } else {\n // No DLQ buffer for this step kind: still account + surface the\n // lost event so it is never silent.\n collector.status.failed++;\n }\n logger.error('report error', {\n ...errorMeta(err),\n event: event.name,\n });\n return;\n }\n\n // Orphan / connection-level error: count it under connectionErrors,\n // not failed.\n collector.status.connectionErrors[key] =\n (collector.status.connectionErrors[key] ?? 0) + 1;\n logger.error('connection error', errorMeta(err));\n } catch {\n // Contained: reportError runs on a detached tick and must never throw.\n }\n };\n}\n","import type { Logger } from '@walkeros/core';\n\n/**\n * Bounded-append helpers for collector internal buffers.\n *\n * Three collector buffers are size-bounded:\n * - `collector.queue` (replay buffer for late-registered destinations)\n * - `destination.queuePush` (consent-denied buffer, per destination)\n * - `destination.dlq` (failed-push dead-letter queue, per destination)\n *\n * All three share the same FIFO ring-buffer eviction semantics, so the\n * append logic lives in one place. `pushBounded` performs the size check,\n * evicts oldest entries (or refuses the new one for `dropNewest`), and\n * reports drops back to the caller via the typed result + optional callback.\n *\n * Caller responsibility: increment the appropriate status counter\n * under `status.dropped[stepId]` (see `stepId()` in @walkeros/core)\n * and emit the warn-once-on-transition log. The helper stays pure: no logger\n * coupling, no collector reference.\n */\n\n/**\n * The collector queue bound. `collector()` seeds `config.queueMax`, so a\n * missing one is a wiring bug, never a user setting.\n */\nexport function seededQueueMax(max: number | undefined): number {\n if (max === undefined) {\n throw new Error(\n 'Collector.Config.queueMax is undefined; defaults must be seeded by collector()',\n );\n }\n return max;\n}\n\nexport type BufferOverflowPolicy = 'dropOldest' | 'dropNewest';\n\nexport interface BufferBound {\n max: number;\n onOverflow?: BufferOverflowPolicy;\n}\n\nexport interface PushBoundedResult {\n /** Whether the new item was appended to the buffer. */\n appended: boolean;\n /** Number of items dropped on this call (0 in the happy path). */\n dropped: number;\n}\n\n/**\n * Append `item` to `buffer`, respecting `bound.max`. On overflow, evict\n * per `bound.onOverflow` (defaults to `'dropOldest'`).\n *\n * @param buffer - In-place mutated array.\n * @param item - Item to append.\n * @param bound - Cap + overflow policy.\n * @param onDrop - Optional callback receiving the dropped items (oldest\n * evictions on `dropOldest`, or the rejected new item on `dropNewest`).\n * Called once per overflow event with all dropped items batched.\n * @returns `{ appended, dropped }`.\n */\nexport function pushBounded<T>(\n buffer: T[],\n item: T,\n bound: BufferBound,\n onDrop?: (dropped: T[]) => void,\n): PushBoundedResult {\n if (!Number.isFinite(bound.max) || bound.max <= 0) {\n throw new Error(`pushBounded: max must be > 0 (got ${bound.max})`);\n }\n\n const policy: BufferOverflowPolicy = bound.onOverflow ?? 'dropOldest';\n\n if (policy === 'dropNewest') {\n if (buffer.length >= bound.max) {\n if (onDrop) onDrop([item]);\n return { appended: false, dropped: 1 };\n }\n buffer.push(item);\n return { appended: true, dropped: 0 };\n }\n\n // dropOldest\n const dropped: T[] = [];\n while (buffer.length >= bound.max) {\n // Length-guarded shift; never undefined here (max > 0, length > 0).\n dropped.push(buffer.shift()!);\n }\n buffer.push(item);\n if (dropped.length > 0 && onDrop) onDrop(dropped);\n return { appended: true, dropped: dropped.length };\n}\n\n/**\n * Per-buffer overflow log state. Used to emit a single warn when a buffer\n * crosses from below-cap to at-cap, suppressing further warns until the\n * buffer drains below cap and overflows again (per Q13).\n */\nconst overflowState = new WeakMap<object, boolean>();\n\n/**\n * Emit a warn-once log on the transition into overflow. Subsequent drops\n * within the same overflow window stay silent until the buffer drains\n * (the caller signals \"below-cap again\" by calling `resetOverflow`).\n *\n * The cumulative drop counter is still incremented on every drop by the\n * caller, so operators retain rate signal via `collector.status.dropped[stepId]`.\n */\nexport function warnOverflowOnce(\n buffer: object,\n logger: Logger.Instance,\n message: string,\n context: Record<string, unknown>,\n): void {\n if (overflowState.get(buffer)) return;\n overflowState.set(buffer, true);\n logger.warn(message, context);\n}\n\n/**\n * Reset the overflow flag when a buffer drains below cap, so the next\n * overflow transition will warn again.\n */\nexport function resetOverflowFlag(buffer: object): void {\n overflowState.delete(buffer);\n}\n","import type { BreakerState, Destination } from '@walkeros/core';\n\n/**\n * Step-general circuit breaker.\n *\n * State lives in `collector.status.breakers`, keyed by `stepId()` so the\n * breaker is step-agnostic (destinations are the primary use today). All sites\n * — the skip gate, the per-event failure/success accounting, the batch flush —\n * drive their state changes through this one module so the gate and the\n * accounting can never disagree about a step's health.\n *\n * The breaker is presence-gated: a step with no `breaker` config never trips\n * (the caller skips this module entirely when {@link resolveBreakerConfig}\n * returns `undefined`).\n *\n * Time is read through an injectable `now()` so open→half-open transitions are\n * deterministic in tests without fake timers (mirrors `ErrorRing` in the cli).\n */\n\nexport const DEFAULT_BREAKER_THRESHOLD = 5;\nexport const DEFAULT_BREAKER_COOLDOWN_MS = 30_000;\n\n/** Resolved, presence-checked breaker tuning for one step. */\nexport interface BreakerConfig {\n threshold: number;\n cooldown: number;\n}\n\n/**\n * The kind of transport outcome a step site reports. `transport-failure`\n * counts toward opening; `success` resets and closes; `partial` is a\n * deliberate no-op (row-level batch failures must not trip a healthy\n * destination).\n */\nexport type StepOutcome = 'transport-failure' | 'success' | 'partial';\n\n/**\n * Injectable clock. Default reads wall time; tests swap it via\n * {@link __setBreakerNow} so open→half-open is deterministic.\n */\nlet nowFn: () => number = () => Date.now();\n\n/** Test-only: override the breaker clock. */\nexport function __setBreakerNow(fn: () => number): void {\n nowFn = fn;\n}\n\n/** Test-only: restore the real-time breaker clock. */\nexport function __resetBreakerNow(): void {\n nowFn = () => Date.now();\n}\n\n/** Current breaker time (injectable). */\nexport function breakerNow(): number {\n return nowFn();\n}\n\n/**\n * Resolve a destination's `breaker` config into tuned values, or `undefined`\n * when no breaker is configured (presence-gating: the breaker stays inert).\n * A bare number is the threshold.\n */\nexport function resolveBreakerConfig(\n breaker: Destination.Config['breaker'],\n): BreakerConfig | undefined {\n if (breaker === undefined) return undefined;\n if (typeof breaker === 'number') {\n return { threshold: breaker, cooldown: DEFAULT_BREAKER_COOLDOWN_MS };\n }\n return {\n threshold: breaker.threshold ?? DEFAULT_BREAKER_THRESHOLD,\n cooldown: breaker.cooldown ?? DEFAULT_BREAKER_COOLDOWN_MS,\n };\n}\n\n/** Lazily create and return the breaker state for a step. */\nexport function ensureBreakerState(\n breakers: Record<string, BreakerState>,\n key: string,\n): BreakerState {\n if (!breakers[key]) {\n breakers[key] = { state: 'closed', consecutiveFailures: 0 };\n }\n return breakers[key];\n}\n\n/**\n * The skip gate. Returns true when the step should be skipped (breaker open\n * and no probe slot available for this caller).\n *\n * On the open→half-open boundary the transition is atomic within this\n * synchronous call: the FIRST event at/after `openUntil` claims the probe\n * (sets `state='half-open'`, `probing=true`, re-arms `openUntil`) and is\n * admitted; every concurrent event then sees half-open with the probe taken\n * and skips. Single-threaded JS guarantees this mutate-before-return is not\n * interleaved with another gate call.\n */\nexport function isBreakerOpen(\n breakers: Record<string, BreakerState>,\n key: string,\n cooldown: number,\n): boolean {\n const breaker = breakers[key];\n if (!breaker || breaker.state === 'closed') return false;\n\n if (breaker.state === 'half-open') {\n // Probe slot already claimed by an earlier event in this window.\n return breaker.probing === true;\n }\n\n // state === 'open'\n const now = nowFn();\n if (breaker.openUntil !== undefined && now < breaker.openUntil) {\n return true; // still cooling down\n }\n\n // Cooldown elapsed: this caller becomes the single probe. Re-arm the window\n // and take the probe slot so concurrent callers still skip.\n breaker.state = 'half-open';\n breaker.probing = true;\n breaker.openUntil = now + cooldown;\n return false;\n}\n\n/**\n * Record a transport outcome for a step and apply the resulting state\n * transition. The single accounting authority for all sites.\n */\nexport function recordStepOutcome(\n breakers: Record<string, BreakerState>,\n key: string,\n outcome: StepOutcome,\n threshold: number,\n cooldown: number,\n): void {\n if (outcome === 'partial') return; // breaker-neutral\n\n const breaker = ensureBreakerState(breakers, key);\n\n if (outcome === 'success') {\n breaker.consecutiveFailures = 0;\n breaker.state = 'closed';\n breaker.probing = false;\n breaker.openUntil = undefined;\n return;\n }\n\n // transport-failure\n breaker.consecutiveFailures += 1;\n\n if (breaker.state === 'half-open') {\n // The probe failed: re-open with a fresh cooldown window.\n breaker.state = 'open';\n breaker.probing = false;\n breaker.openUntil = nowFn() + cooldown;\n return;\n }\n\n if (breaker.consecutiveFailures >= threshold) {\n breaker.state = 'open';\n breaker.probing = false;\n breaker.openUntil = nowFn() + cooldown;\n }\n}\n\n/**\n * Release a half-open probe slot WITHOUT recording an outcome. Called when an\n * admitted probe event settles on a path that never exercised the transport\n * (consent-denied, empty queue, queueOn-only, re-queued). The probe never\n * tested transport health, so it must not count as a failure or a success;\n * instead the breaker reverts half-open → open, keeping `consecutiveFailures`\n * intact, so the next event at/after the (already re-armed) `openUntil` can\n * probe again. Without this, an admitted probe that never pushes would leave\n * `probing=true` forever and the breaker would deadlock half-open.\n *\n * No-op unless the breaker is currently half-open with a probe in flight.\n */\nexport function releaseProbe(\n breakers: Record<string, BreakerState>,\n key: string,\n): void {\n const breaker = breakers[key];\n if (!breaker || breaker.state !== 'half-open' || breaker.probing !== true) {\n return;\n }\n breaker.state = 'open';\n breaker.probing = false;\n}\n\n/**\n * Predicate exposed for the BigQuery self-heal re-open (Task 4): true when a\n * probe would be permitted at `now` — the breaker is closed, half-open, or\n * open with its cooldown elapsed. Task 4 gates its re-open on this.\n */\nexport function isBreakerProbePermitted(\n breaker: BreakerState | undefined,\n now: number,\n): boolean {\n if (!breaker) return true;\n if (breaker.state === 'closed' || breaker.state === 'half-open') return true;\n return breaker.openUntil !== undefined && now >= breaker.openUntil;\n}\n","import type {\n Cache,\n Collector,\n Elb,\n Ingest,\n Source,\n Transformer,\n WalkerOS,\n} from '@walkeros/core';\nimport type { RespondFn, RespondOptions } from '@walkeros/core';\nimport {\n createIngest,\n FatalError,\n getMappingValue,\n getSpanId,\n parseTraceparent,\n isScope,\n tryCatchAsync,\n compileCache,\n checkCache,\n storeCache,\n applyUpdate,\n createMappingRoot,\n stepId,\n} from '@walkeros/core';\nimport { runTransformerChain } from './transformer';\nimport { compileStepState, runStepState, warnStateOff } from './state';\nimport { buildReportError, errorMeta } from './report-error';\nimport { isStateDelivery, shouldDeliver, setMark } from './on';\nimport { reconcilePending } from './pending';\nimport { createPushResult } from './destination';\nimport { emitCollectorDrop } from './observerEmit';\nimport { getCacheStore } from './cache';\nimport {\n DEFAULT_DESTINATION_TIMEOUT_MS,\n DestinationTimeoutError,\n withTimeout,\n} from './timeout';\n\n/**\n * Flush a source's queueOn buffer. Called when the source becomes \"started\"\n * (config.init === true AND config.require is empty/absent). Idempotent:\n * the buffer is cleared before iteration, so re-entry from within an `on`\n * handler does not re-fire the same items.\n *\n * A throw inside `source.on` is treated as a pipeline failure: log via the\n * scoped 'source' logger and increment `status.failed`. The flush itself\n * is walkerOS-orchestrated startup; the throw represents the source's\n * inability to consume a buffered state-change event. A handler that does\n * not settle within the default destination timeout is logged the same way\n * but not counted, matching the live delivery path.\n *\n * State-delivery entries (consent/user/globals/custom) are gated through the\n * same per-source high-water mark as the direct `onApply` broadcast: while\n * `!allowed` they defer (not invoked, mark not advanced — the source stays\n * \"owed\" for the run-barrier re-delivery), and an allowed delivery advances\n * the source mark so a later broadcast at the same version does not double\n * deliver. Lifecycle/arbitrary entries (ready/run/session/config) flush with\n * their unchanged behavior.\n */\nexport async function flushSourceQueueOn(\n collector: Collector.Instance,\n source: Source.Instance,\n sourceId?: string,\n): Promise<void> {\n if (!source.on || !source.queueOn?.length) return;\n const queue = source.queueOn;\n source.queueOn = [];\n const id = sourceId || source.config?.id || 'unknown';\n for (const { type, data } of queue) {\n // Defer state deliveries while !allowed: leave them owed (drop the queued\n // entry without firing or advancing the mark). The run-barrier re-delivery\n // (a later task) re-broadcasts owed state to behind-mark subscribers.\n if (isStateDelivery(type) && !shouldDeliver(collector, source, type))\n continue;\n\n // Bounded like a live delivery: sources carry no per-step timeout config\n // and share the destination default.\n const handler = source.on;\n let timedOut = false;\n await tryCatchAsync(\n () =>\n withTimeout(\n Promise.resolve(handler(type, data)),\n DEFAULT_DESTINATION_TIMEOUT_MS,\n `Source \"${id}\" on(${type}) did not settle within ${DEFAULT_DESTINATION_TIMEOUT_MS}ms`,\n ),\n (err: unknown): undefined => {\n if (err instanceof FatalError) throw err;\n // A handler that did not settle in time is logged, as on the live\n // delivery path, and is not a pipeline failure.\n if (err instanceof DestinationTimeoutError) timedOut = true;\n else collector.status.failed++;\n collector.logger.scope('source').error('source on flush failed', {\n sourceId: id,\n type,\n ...errorMeta(err),\n });\n return undefined;\n },\n )();\n\n // A timed-out delivery has not happened: the mark stays, the cell stays owed.\n if (isStateDelivery(type) && !timedOut) setMark(collector, source, type);\n }\n}\n\n/**\n * A source is \"started\" — eligible to receive on() events directly — when\n * its init has run and any require gate is satisfied.\n */\nexport function isSourceStarted(source: Source.Instance): boolean {\n return Boolean(source.config.init) && !source.config.require?.length;\n}\n\n/**\n * Initialize a single source. Extracted from the initSources loop body\n * so it can be reused by the pending-source activator.\n */\nexport async function initSource(\n collector: Collector.Instance,\n sourceId: string,\n sourceDefinition: Source.InitSource,\n): Promise<Source.Instance | undefined> {\n const {\n code,\n config = {},\n env = {},\n primary,\n next,\n before,\n cache,\n terminus,\n } = sourceDefinition;\n\n // Compile declarative state entries once. For a source, all state entries\n // run before handing the event to `collector.push` (get enriches the event\n // the collector receives, set stashes from it), so they execute together in\n // array order. A config-level `state` takes precedence over the\n // definition-level one.\n const sourceState = config.state ?? sourceDefinition.state;\n const stateEntries = compileStepState(sourceState);\n warnStateOff(collector, stepId('source', sourceId), sourceState);\n\n // Compile source cache config (if configured).\n // Source caches operate on events (request-scoped HIT/MISS keyed by event\n // fields), so the rule shape is always EventCacheRule, not StoreCacheRule.\n const sourceCacheConfig = cache as\n | Cache.Cache<Cache.EventCacheRule>\n | undefined;\n const compiledSourceCache = sourceCacheConfig\n ? compileCache({\n ...sourceCacheConfig,\n stop: sourceCacheConfig.stop ?? true,\n })\n : undefined;\n\n // The pipeline's end. `terminus` replaces the collector entirely; see the\n // field's doc on Source.InitSource for the full (total) semantics.\n const terminalPush: Collector.PushFn = terminus ?? collector.push;\n const hasTerminus = Boolean(terminus);\n\n /**\n * Execute the source pipeline for a single push call. Operates ONLY on\n * the per-call `scope` parameter — never reads source-factory closure\n * variables for ingest/respond. The scope is the unit of cross-request\n * isolation.\n *\n * The function may mutate `scope.respond` (cache MISS wraps it to\n * intercept the cached value before forwarding). That mutation is\n * scope-local: a concurrent call with its own scope is unaffected.\n */\n const executePush = async (\n rawEvent: WalkerOS.DeepPartialEvent,\n options: Collector.PushOptions,\n scope: { ingest: Ingest; respond: RespondFn | undefined },\n ): Promise<Elb.PushResult> => {\n // Total bypass: the terminus owns the pipeline and receives the raw event.\n // One early return instead of a per-stage conditional, so \"bypass\" cannot\n // drift into \"bypass some stages\".\n if (hasTerminus) return terminalPush(rawEvent);\n\n let pendingRespond: Promise<void> | undefined;\n\n // Mint the event's span id HERE when absent, so the source.before chain's\n // records carry the same id as the collector.push and destination records\n // of the same event; minting only at the collector wrap would leave every\n // before-chain record anonymous. The wrap then finds `id` set and keeps\n // it, as does `createEvent` (handle.ts): one span per event, end to end.\n const identified =\n typeof rawEvent.id === 'string' && rawEvent.id !== ''\n ? rawEvent\n : { ...rawEvent, id: getSpanId() };\n\n // The before chain may fan out (return an array of events). The cache\n // check and destination push must run once per event so fan-out is\n // preserved end-to-end. Cache logic is request-scoped (keyed by the\n // scope's ingest), so it lives outside the loop. The actual pipeline\n // (preChain + collector.push) runs inside the loop, once per event.\n let copies: Transformer.ChainCopy[] = [\n { event: identified, ingest: scope.ingest },\n ];\n\n // Run source.before chain (consent-exempt, pre-source preprocessing).\n // The route resolves hop by hop with `{ ingest, event }`, the event being\n // the source's raw output with its span id already minted.\n if (before !== undefined) {\n const chainPath = `source.${sourceId}.before`;\n const beforeResult = await runTransformerChain(\n collector,\n collector.transformers || {},\n before,\n identified,\n scope.ingest,\n scope.respond,\n chainPath,\n );\n if (beforeResult.copies.length === 0) {\n // Dropped or stopped: the event never reaches the collector.\n emitCollectorDrop(\n collector,\n identified,\n scope.ingest,\n beforeResult.droppedBy,\n chainPath,\n );\n return createPushResult({ ok: true, dropped: true });\n }\n // Pipeline-halt signal from a `cache.stop: true` HIT inside the\n // source.before chain. Do NOT invoke collector.push — drop the event\n // before it enters the collector pipeline.\n if (beforeResult.stopped) {\n if (beforeResult.respond) scope.respond = beforeResult.respond;\n return { ok: true } as Elb.PushResult;\n }\n if (beforeResult.respond) scope.respond = beforeResult.respond;\n\n // Every finished copy goes on with its own ingest and the id the\n // runner gave it (a single copy keeps the source-minted id).\n copies = beforeResult.copies;\n }\n\n // Source cache check (full=true by default for sources)\n if (compiledSourceCache) {\n const cacheStore = getCacheStore(compiledSourceCache, collector);\n if (cacheStore) {\n const cacheContext = createMappingRoot(scope.ingest);\n const cacheResult = await checkCache(\n compiledSourceCache,\n cacheStore,\n cacheContext,\n // no per-step prefix — cache keys honor user-provided namespace only\n );\n\n if (cacheResult) {\n if (cacheResult.status === 'HIT' && cacheResult.value !== undefined) {\n if (compiledSourceCache.stop) {\n // stop=true (default): respond with cached value, skip pipeline\n let respondValue: unknown = cacheResult.value;\n if (cacheResult.rule.update) {\n respondValue = await applyUpdate(\n respondValue,\n cacheResult.rule.update as Record<string, unknown>,\n { ...cacheContext, cache: { status: 'HIT' } },\n collector,\n );\n }\n scope.respond?.(respondValue as Record<string, unknown>);\n return { ok: true } as Elb.PushResult;\n }\n // stop=false: cached value unused — HIT signals \"seen before\", pipeline continues\n }\n\n if (\n cacheResult.status === 'MISS' &&\n compiledSourceCache.stop &&\n scope.respond\n ) {\n // stop=true MISS: wrap respond to intercept and cache the value.\n // Store original in cache, then apply update rules with MISS\n // status before responding (mirrors HIT path which applies\n // with HIT status).\n //\n // When `update` is configured the update step is async, so\n // the wrapper captures its promise in `pendingRespond`.\n // `executePush` awaits that promise before returning, so any\n // source fallback that runs after `await env.push(...)` (e.g.\n // the express source's transparent-GIF default) sees\n // `createRespond`'s first-call-wins flag already set and\n // correctly no-ops. Without this, the fallback would win\n // the race and the real response would be lost.\n const unwrappedRespond = scope.respond;\n const missUpdate = cacheResult.rule.update;\n const missContext = { ...cacheContext, cache: { status: 'MISS' } };\n const missKey = cacheResult.key;\n const missTtl = cacheResult.rule.ttl;\n\n const missRespond: RespondFn = (respondOptions) => {\n storeCache(cacheStore, missKey, respondOptions, missTtl);\n\n if (!missUpdate) {\n unwrappedRespond(respondOptions);\n return;\n }\n\n pendingRespond = (async () => {\n const updated = await applyUpdate(\n respondOptions,\n missUpdate as Record<string, unknown>,\n missContext,\n collector,\n );\n unwrappedRespond(updated as RespondOptions);\n })();\n };\n\n scope.respond = missRespond;\n }\n\n // stop=false MISS: store sentinel so subsequent requests get a HIT\n if (cacheResult.status === 'MISS' && !compiledSourceCache.stop) {\n storeCache(cacheStore, cacheResult.key, true, cacheResult.rule.ttl);\n }\n }\n }\n }\n\n // Apply declarative state per event before handing off to the collector.\n // Entries run sequentially in array order at this single pipeline point.\n if (stateEntries && stateEntries.length > 0) {\n copies = await Promise.all(\n copies.map(async (copy) => ({\n event: await runStepState(\n collector,\n stateEntries,\n copy.event,\n copy.ingest,\n ),\n ingest: copy.ingest,\n })),\n );\n }\n\n // Push each event independently through the post-before pipeline. The\n // source's `next` route travels as the pre-collector chain and resolves\n // per event, after the source's state, inside `collector.push`.\n let pushResult: Elb.PushResult = { ok: true } as Elb.PushResult;\n for (const copy of copies) {\n pushResult = await terminalPush(copy.event, {\n ...options,\n id: sourceId,\n ingest: copy.ingest,\n respond: scope.respond,\n mapping: config,\n preChain: next,\n });\n }\n\n // Wait for any deferred MISS update work to land on the source's\n // respond sender before returning control to the source. This\n // ensures source-level fallbacks (e.g. transparent GIFs) run after\n // the real response has been committed via first-call-wins.\n if (pendingRespond) await pendingRespond;\n\n return pushResult;\n };\n\n /**\n * Build a fresh per-scope `Ingest` from raw scope input by applying\n * `config.ingest` mapping if present. Always produces a typed Ingest\n * with valid `_meta`. Pure: returns a new object, never reads or\n * writes source-factory state.\n */\n const extractIngest = async (\n rawScope: Source.Scope | undefined,\n ): Promise<Ingest> => {\n const fresh = createIngest(sourceId);\n // Adopt an inbound W3C traceparent from the scope's header bag so every\n // server source gains trace continuity + parent-span linkage. The final\n // return reuses `fresh._meta` by reference, so stamping here holds for\n // both the mapped and unmapped paths. Sources can be user authored, so the\n // declared type is not assumed to hold at runtime; a miss resolves\n // nothing, which is the honest outcome.\n const traceparent = parseTraceparent(\n isScope(rawScope) ? rawScope?.headers?.traceparent : undefined,\n );\n if (traceparent) {\n fresh._meta.trace = traceparent.trace;\n fresh._meta.parentEventId = traceparent.parentSpan;\n }\n if (!config.ingest || rawScope === undefined) return fresh;\n const extracted = await getMappingValue(rawScope, config.ingest, {\n collector,\n });\n return {\n ...fresh,\n ...(extracted as Record<string, unknown>),\n _meta: fresh._meta, // protect _meta from being overwritten\n };\n };\n\n // Factory-default push: each call gets a fresh Ingest and no respond.\n // Sources with a single logical scope (browser, dataLayer) call this\n // directly via `env.push`. Server sources handling concurrent requests\n // call `context.withScope(...)` instead, which threads a per-scope\n // ingest/respond into the same pipeline.\n const wrappedPush: Collector.PushFn = async (\n rawEvent: WalkerOS.DeepPartialEvent,\n options: Collector.PushOptions = {},\n ) => {\n const scope = {\n ingest: createIngest(sourceId),\n respond: undefined as RespondFn | undefined,\n };\n return executePush(rawEvent, options, scope);\n };\n\n // Create initial logger scoped to sourceId (type will be added after init)\n const initialLogger = collector.logger.scope('source').scope(sourceId);\n\n // `env` is the source's dependency bag: the author owns it. The five\n // capabilities the collector provides are applied LAST so they always win,\n // uniformly. Writing one of them in `env` is therefore inert rather than\n // partially effective; to end the pipeline somewhere else, use\n // `InitSource.terminus`, which says so explicitly.\n const cleanEnv: Source.Env = {\n ...env,\n push: wrappedPush,\n command: collector.command,\n sources: collector.sources,\n elb: collector.elb,\n logger: initialLogger,\n };\n\n /**\n * Bind ingest and respond to a single scope of work. Each invocation\n * builds a fresh `Ingest`, captures the given `respond`, and runs the\n * caller's `body` with a per-scope env whose `push` carries both. The\n * scope is the unit of cross-call isolation — concurrent withScope\n * invocations never share ingest or respond.\n */\n const withScope: Source.Context['withScope'] = async (\n rawScope,\n respond,\n body,\n ) => {\n const scope: { ingest: Ingest; respond: RespondFn | undefined } = {\n ingest: await extractIngest(rawScope),\n respond,\n };\n const scopePush: Collector.PushFn = (rawEvent, options = {}) =>\n executePush(rawEvent, options, scope);\n const scopeEnv: Source.ScopeEnv = {\n ...cleanEnv,\n push: scopePush,\n ingest: scope.ingest,\n respond: scope.respond,\n };\n return body(scopeEnv);\n };\n\n const sourceContext: Source.Context = {\n collector,\n logger: initialLogger,\n id: sourceId,\n config,\n env: cleanEnv,\n withScope,\n reportError: buildReportError(collector, 'source', sourceId, initialLogger),\n };\n\n const sourceInstance = await tryCatchAsync(\n code,\n (err: unknown): undefined => {\n if (err instanceof FatalError) throw err;\n collector.status.failed++;\n collector.logger.scope('source').error('source factory failed', {\n sourceId,\n ...errorMeta(err),\n });\n return undefined;\n },\n )(sourceContext);\n if (!sourceInstance) return undefined;\n\n const sourceType = sourceInstance.type || 'unknown';\n const sourceLogger = collector.logger.scope(sourceType).scope(sourceId);\n cleanEnv.logger = sourceLogger;\n\n if (primary) {\n sourceInstance.config = { ...sourceInstance.config, primary };\n }\n\n return sourceInstance;\n}\n\n/**\n * Initialize sources. Every source whose factory succeeds is registered and\n * its init runs, `require` or not (a factory that throws is logged and the\n * source skipped); sources never go to collector.pending (that holds\n * destinations only). A source with `require` stays unstarted: its `on()`\n * deliveries wait in `queueOn` until every required event has occurred.\n */\nexport async function initSources(\n collector: Collector.Instance,\n sources: Source.InitSources = {},\n): Promise<Collector.Sources> {\n const result: Collector.Sources = {};\n\n // Pass 1: register every source via its factory.\n for (const [sourceId, sourceDefinition] of Object.entries(sources)) {\n const sourceInstance = await initSource(\n collector,\n sourceId,\n sourceDefinition,\n );\n if (!sourceInstance) continue;\n // Propagate orchestration fields from the user's source definition into\n // the registered instance config. The factory does not know about\n // `require` — it's an InitSource-level concern that the collector owns.\n // Clone the array so per-source decrement (in onApply) doesn't mutate\n // the caller's config.\n const userRequire = sourceDefinition.config?.require;\n sourceInstance.config = {\n ...sourceInstance.config,\n init: false,\n ...(userRequire ? { require: [...userRequire] } : {}),\n };\n result[sourceId] = sourceInstance;\n }\n\n // Merge into collector.sources BEFORE pass 2 so that any onApply\n // broadcast triggered during init can find every source.\n Object.assign(collector.sources, result);\n\n // Pass 2: init each source. Side effects allowed here.\n for (const sourceId of Object.keys(result)) {\n const instance = collector.sources[sourceId];\n let initFailed = false;\n if (instance.init) {\n await tryCatchAsync(instance.init.bind(instance), (err: unknown) => {\n if (err instanceof FatalError) throw err;\n initFailed = true;\n collector.status.failed++;\n collector.logger.scope('source').error('source init failed', {\n sourceId,\n ...errorMeta(err),\n });\n })();\n }\n // Control-flow fix: a throw inside `init()` previously left the source\n // marked `config.init = true` despite never having completed setup.\n // Operators reading `source.config.init` would see a healthy source\n // that was actually broken. Skip the rest of the loop on failure so\n // the source stays in `config.init = false` and is visibly stuck.\n if (initFailed) continue;\n instance.config.init = true;\n if (isSourceStarted(instance)) {\n await flushSourceQueueOn(collector, instance, sourceId);\n }\n }\n\n // Registration trigger: a source's factory or init (Pass 2) may have recorded\n // state that satisfies another source's/destination's `require`. The live\n // broadcast can miss a step that was not yet merged into collector.sources\n // when the state fired (a factory emit during Pass 1), so reconcile once over\n // the now-fully-registered set to activate any step satisfied by current\n // state. This is the load-bearing fix for order-independent activation.\n await reconcilePending(collector);\n\n return result;\n}\n","/**\n * @module transformer\n *\n * Transformer Chains\n * ==================\n *\n * The one chain runner of walkerOS. Every chain position (`source.before`,\n * `source.next`, `transformer.before`, `destination.before`,\n * `destination.next`) and the CLI simulation run through\n * `runTransformerChain`.\n *\n * A chain starts from a Route (or a continuation of one). The runner loops\n * `advanceChain` from `@walkeros/core`, which resolves the route hop by hop\n * with the root the previous step left (`{ ingest, event }`):\n *\n * - `run`: the member runs (cache, `before`, `state`, push); its own `next`\n * is inserted right after it, then the explicit array continues.\n * - `fork` (a `many`, or a transformer returning `Result[]`): each copy\n * finishes the whole rest of the path on its own, with its own span id\n * (`deriveSpanId`) and a cloned ingest. Copies never merge; every finished\n * copy is handed back as its own event.\n * - `stop`: the running copy ends (`copies: []`, `stopped: true`).\n *\n * Chain termination per member:\n * - returns false or throws: the copy is dropped (`droppedBy`)\n * - returns void: continue with the unchanged event\n * - returns `{ event }`: continue with the new event\n * - returns `{ next }`: that route runs right after the member, in place of\n * the member's own `next`, then the array continues\n */\nimport type {\n Cache,\n ChainContinuation,\n Collector,\n RespondFn,\n Transformer,\n WalkerOS,\n Ingest,\n} from '@walkeros/core';\nimport {\n advanceChain,\n clone,\n createIngest,\n deriveSpanId,\n emitStep,\n FatalError,\n isChainContinuation,\n isObject,\n startChain,\n stepId,\n tryCatchAsync,\n useHooks,\n compileCache,\n checkCache,\n storeCache,\n createMappingRoot,\n validateStepEntry,\n processEventMapping,\n} from '@walkeros/core';\nimport { journeyFields, stepError, stepState } from './observerEmit';\nimport { getCacheStore } from './cache';\nimport { buildReportError, errorMeta } from './report-error';\nimport { compileStepState, runStepState, warnStateOff } from './state';\n\n/**\n * Extracts chain property from definition and merges into config.\n * Provides unified handling for source.next, destination.before, and transformer.next.\n *\n * @param definition - Component definition with optional chain property\n * @param propertyName - Name of chain property ('next' or 'before')\n * @returns Object with merged config and extracted chain value\n */\nexport function extractChainProperty<\n T extends { config?: Record<string, unknown>; [key: string]: unknown },\n>(\n definition: T,\n propertyName: 'next' | 'before',\n): {\n config: Record<string, unknown>;\n chainValue: string | string[] | undefined;\n} {\n const config = (definition.config || {}) as Record<string, unknown>;\n const chainValue = definition[propertyName] as string | string[] | undefined;\n\n if (chainValue !== undefined) {\n return {\n config: { ...config, [propertyName]: chainValue },\n chainValue,\n };\n }\n\n return { config, chainValue: undefined };\n}\n\n/**\n * Initializes transformer instances from configuration.\n * Does NOT call transformer.init() - that happens lazily before first push.\n *\n * @param collector - The collector instance\n * @param initTransformers - Transformer initialization configurations\n * @returns Initialized transformer instances\n */\nexport async function initTransformers(\n collector: Collector.Instance,\n initTransformers: Transformer.InitTransformers = {},\n): Promise<Transformer.Transformers> {\n const result: Transformer.Transformers = {};\n\n for (const [transformerId, transformerDef] of Object.entries(\n initTransformers,\n )) {\n const { code, env = {} } = transformerDef;\n\n // Validate the entry via the shared predicate. A code-less entry must\n // declare at least one operative field (package, before, next, cache,\n // state, mapping). Unknown keys and code+package conflicts are also\n // rejected. Build flag (see @walkeros/core build-flags): CLI bundles\n // validate at build time and fold this out.\n if (typeof __WALKEROS_VALIDATE__ === 'undefined' || __WALKEROS_VALIDATE__) {\n const validation = validateStepEntry(\n transformerDef as Record<string, unknown>,\n 'Transformer',\n );\n if (!validation.ok) {\n collector.logger.warn(\n `Transformer ${transformerId} invalid (${validation.code}): ${validation.reason}. Skipping.`,\n );\n continue;\n }\n }\n\n // Use unified chain property extractor for both before and next\n const { config: configWithBefore } = extractChainProperty(\n transformerDef,\n 'before',\n );\n const { config: configWithChain } = extractChainProperty(\n { ...transformerDef, config: configWithBefore },\n 'next',\n );\n\n // Merge definition-level env into config so it's available during push.\n // transformerPush reads transformer.config.env to build the push context.\n const configWithEnv =\n Object.keys(env).length > 0\n ? { ...configWithChain, env: env as Transformer.Env }\n : configWithChain;\n\n // Merge definition-level cache into config for runtime access\n const { cache } = transformerDef;\n const configWithCache = cache ? { ...configWithEnv, cache } : configWithEnv;\n\n // Merge definition-level state into config for runtime access. A\n // config-level `state` (if present) takes precedence over def-level.\n const resolvedState = transformerDef.config?.state ?? transformerDef.state;\n warnStateOff(\n collector,\n stepId('transformer', transformerId),\n resolvedState,\n );\n const configWithState =\n resolvedState !== undefined && configWithCache.state === undefined\n ? { ...configWithCache, state: resolvedState }\n : configWithCache;\n\n // Build transformer context for init\n const transformerLogger = collector.logger\n .scope('transformer')\n .scope(transformerId);\n\n const context = {\n collector,\n logger: transformerLogger,\n id: transformerId,\n ingest: createIngest(transformerId),\n config: configWithState,\n env: env as Transformer.Env,\n reportError: buildReportError(\n collector,\n 'transformer',\n transformerId,\n transformerLogger,\n ),\n };\n\n // Synthesize a passthrough instance when `code` is absent.\n // This makes the entry a \"pass\" — a named, code-less hop. Two flavors:\n // 1. mapping-aware: when `mapping` is declared, the synthesized push\n // runs `processEventMapping` and forwards the transformed event\n // (or drops it when a rule has `ignore: true`).\n // 2. plain passthrough: when only `before` / `next` / `cache` are\n // declared, the push returns the event unchanged.\n const codeFn =\n code ??\n ((ctx: Transformer.Context) => {\n const stepMapping = transformerDef.mapping;\n if (stepMapping) {\n // Warn once per init if vendor-payload fields are present at the\n // transformer position. Only event-mutating fields apply here.\n // Note: `MappingConfig` has no top-level `silent` field — that\n // lives on `Rule` only, so the config-level check is `data` only.\n const meaninglessFields: string[] = [];\n if (stepMapping.data !== undefined) meaninglessFields.push('data');\n // Walk rules for per-rule data/silent\n if (stepMapping.mapping) {\n for (const [entity, actions] of Object.entries(\n stepMapping.mapping,\n )) {\n if (typeof actions !== 'object' || actions === null) continue;\n for (const [action, rule] of Object.entries(\n actions as Record<string, unknown>,\n )) {\n if (typeof rule !== 'object' || rule === null) continue;\n const r = rule as Record<string, unknown>;\n if (r.data !== undefined)\n meaninglessFields.push(`mapping[${entity}][${action}].data`);\n if (r.silent !== undefined)\n meaninglessFields.push(\n `mapping[${entity}][${action}].silent`,\n );\n }\n }\n }\n if (meaninglessFields.length > 0) {\n ctx.collector.logger.warn(\n `Transformer ${transformerId}: \\`${meaninglessFields.join(', ')}\\` ignored at transformer position (only event-mutating fields apply).`,\n );\n }\n\n return {\n type: 'pass',\n config: ctx.config,\n push: async (event: WalkerOS.DeepPartialEvent) => {\n const r = await processEventMapping(\n event,\n stepMapping,\n ctx.collector,\n );\n if (r.ignore) return false;\n return { event: r.event };\n },\n };\n }\n return {\n type: 'pass',\n config: ctx.config,\n push: (event: WalkerOS.DeepPartialEvent) => ({ event }),\n };\n });\n\n // Initialize the transformer instance with context\n const instance = await codeFn(context);\n\n // Bug 2 fix: propagate def-level before/next to instance.config when\n // not already set by the code function. The recursive chain walker\n // reads instance.config.before; for synthesized pass-throughs and\n // well-behaved user code that returns a fresh config object, the\n // def-level value needs to land on instance.config explicitly.\n // User-supplied code that sets its own config.before is preserved.\n if (\n transformerDef.before !== undefined &&\n instance.config?.before === undefined\n ) {\n instance.config = {\n ...(instance.config ?? {}),\n before: transformerDef.before,\n };\n }\n if (\n transformerDef.next !== undefined &&\n instance.config?.next === undefined\n ) {\n instance.config = {\n ...(instance.config ?? {}),\n next: transformerDef.next,\n };\n }\n // Propagate the precedence-resolved state (config-level wins over\n // def-level) onto instance.config when a custom factory dropped it.\n if (resolvedState !== undefined && instance.config?.state === undefined) {\n instance.config = {\n ...(instance.config ?? {}),\n state: resolvedState,\n };\n }\n\n result[transformerId] = instance;\n }\n\n return result;\n}\n\n/**\n * Initializes a transformer if it hasn't been initialized yet.\n * Called lazily before first push.\n *\n * @param collector - The collector instance\n * @param transformer - The transformer to initialize\n * @param transformerId - The transformer ID\n * @returns Whether initialization succeeded\n */\nexport async function transformerInit(\n collector: Collector.Instance,\n transformer: Transformer.Instance,\n transformerId: string,\n): Promise<boolean> {\n // Check if already initialized\n if (transformer.init && !transformer.config.init) {\n const transformerType = transformer.type || 'unknown';\n const transformerLogger = collector.logger.scope(\n `transformer:${transformerType}`,\n );\n\n const context: Transformer.Context = {\n collector,\n logger: transformerLogger,\n id: transformerId,\n ingest: createIngest(transformerId),\n config: transformer.config,\n env: mergeTransformerEnvironments(transformer.config.env),\n reportError: buildReportError(\n collector,\n 'transformer',\n transformerId,\n transformerLogger,\n ),\n };\n\n transformerLogger.debug('init');\n\n const configResult = await useHooks(\n transformer.init,\n 'TransformerInit',\n collector.hooks,\n collector.logger,\n )(context);\n\n // Check for initialization failure\n if (configResult === false) return false;\n\n // Update config if returned, preserving env from definition\n transformer.config = {\n ...(configResult || transformer.config),\n env:\n ((configResult as Record<string, unknown>)?.env as Transformer.Env) ||\n transformer.config.env,\n init: true,\n };\n\n transformerLogger.debug('init done');\n }\n\n return true;\n}\n\n/**\n * Pushes an event through a single transformer.\n *\n * @param collector - The collector instance\n * @param transformer - The transformer to push to\n * @param transformerId - The transformer ID\n * @param event - The event to process\n * @param ingest - Mutable ingest context flowing through the pipeline\n * @returns The processed event, void for passthrough, or false to stop chain\n */\nexport async function transformerPush(\n collector: Collector.Instance,\n transformer: Transformer.Instance,\n transformerId: string,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n respond?: import('@walkeros/core').RespondFn,\n): Promise<Transformer.Result | Transformer.Result[] | false | void> {\n const transformerType = transformer.type || 'unknown';\n const transformerLogger = collector.logger.scope(\n `transformer:${transformerType}`,\n );\n\n const context: Transformer.Context = {\n collector,\n logger: transformerLogger,\n id: transformerId,\n ingest: ingest!, // Mutable shared context\n config: transformer.config,\n env: {\n ...mergeTransformerEnvironments(transformer.config.env),\n ...(respond ? { respond } : {}),\n },\n reportError: buildReportError(\n collector,\n 'transformer',\n transformerId,\n transformerLogger,\n ),\n };\n\n transformerLogger.debug('push', { event: (event as { name?: string }).name });\n\n const eventId = typeof event.id === 'string' ? event.id : '';\n const journey = journeyFields(event, ingest, collector);\n const started = Date.now();\n const inState = stepState(\n collector,\n stepId('transformer', transformerId),\n 'transformer',\n 'in',\n eventId,\n started,\n journey,\n );\n inState.inEvent = event;\n emitStep(collector, inState);\n\n try {\n const result = await useHooks(\n transformer.push,\n 'TransformerPush',\n collector.hooks,\n collector.logger,\n )(event, context);\n\n const finished = Date.now();\n const outState = stepState(\n collector,\n stepId('transformer', transformerId),\n 'transformer',\n 'out',\n eventId,\n finished,\n journey,\n );\n outState.durationMs = finished - started;\n outState.outEvent = result;\n emitStep(collector, outState);\n\n transformerLogger.debug('push done');\n\n return result;\n } catch (err) {\n const finished = Date.now();\n const errState = stepState(\n collector,\n stepId('transformer', transformerId),\n 'transformer',\n 'error',\n eventId,\n finished,\n journey,\n );\n errState.durationMs = finished - started;\n errState.error = stepError(err);\n emitStep(collector, errState);\n throw err;\n }\n}\n\n/**\n * Clone an ingest for an independent copy (a fork). The top level and\n * `_meta` are shallow-copied and `_meta.path` is duplicated, so the path\n * budget and hop count of one copy never leak into a sibling.\n */\nexport function cloneIngest(ingest: Ingest): Ingest {\n return {\n ...ingest,\n _meta: { ...ingest._meta, path: [...ingest._meta.path] },\n };\n}\n\n/** Safety valve against unbounded path growth, per copy. */\nconst MAX_PATH_LENGTH = 256;\n\n/** What every copy of one chain run shares. */\ninterface ChainRun {\n collector: Collector.Instance;\n transformers: Transformer.Transformers;\n chainContext?: string;\n}\n\n/** A cache MISS of a member, written once the member settled. */\ninterface CacheMiss {\n key: string;\n ttl: number;\n}\n\n/** A member about to run, as `advanceChain` handed it out. */\ninterface Member {\n id: string;\n ancestry: readonly string[];\n /** The stack after the member; carries its own `next` on top if any. */\n rest: ChainContinuation;\n /** Whether `rest` carries the member's own `next` on top. */\n ownNext: boolean;\n}\n\n/**\n * A member that resumes after its `before` chain fanned out: each child\n * runs the member's own push (no second `before`, path and cache already\n * accounted for by the parent copy).\n */\ninterface Resume {\n member: Member;\n cacheMiss?: CacheMiss;\n}\n\n/** One independent copy of the event walking the chain. */\ninterface Copy {\n stack: ChainContinuation;\n event: WalkerOS.DeepPartialEvent;\n ingest: Ingest;\n respond: RespondFn | undefined;\n resume?: Resume;\n}\n\ntype MemberOutcome =\n | { kind: 'halt'; result: Transformer.ChainResult }\n | { kind: 'fork'; copies: Copy[] }\n | {\n kind: 'continue';\n event: WalkerOS.DeepPartialEvent;\n respond: RespondFn | undefined;\n stack: ChainContinuation;\n };\n\n/** The event's id, or '' when it has none. */\nfunction idOf(event: WalkerOS.DeepPartialEvent): string {\n return typeof event.id === 'string' ? event.id : '';\n}\n\n/**\n * Identity along one copy: an event a member handed on without an id (a\n * rebuilt event, a mock, a cached value) is still the event the member\n * received, so it keeps that id. The one identity rule for a single path;\n * forks derive theirs in `forkOf`.\n */\nfunction keepIdentity(\n received: WalkerOS.DeepPartialEvent,\n event: WalkerOS.DeepPartialEvent,\n): WalkerOS.DeepPartialEvent {\n const id = idOf(received);\n return id !== '' && idOf(event) === '' ? { ...event, id } : event;\n}\n\n/**\n * A fork child: a deep copy of the event (siblings run concurrently and\n * must never share nested objects), with its own cloned ingest. A child\n * still carrying the parent's id (or no id) gets a span id derived from the\n * parent id and its position, so forks never collapse on `event.id`; a\n * child with an id of its own keeps it. The ingest records the parent as\n * `parentEventId`, which links the fork into the parent's journey.\n */\nfunction forkOf(\n parent: WalkerOS.DeepPartialEvent,\n child: WalkerOS.DeepPartialEvent,\n ingest: Ingest,\n position: number,\n): { event: WalkerOS.DeepPartialEvent; ingest: Ingest } {\n const forkIngest = cloneIngest(ingest);\n const event = clone(child);\n const parentId = idOf(parent);\n if (parentId === '') return { event, ingest: forkIngest };\n forkIngest._meta.parentEventId = parentId;\n const childId = idOf(event);\n if (childId === '' || childId === parentId)\n event.id = deriveSpanId(parentId, position);\n return { event, ingest: forkIngest };\n}\n\n/** A finished result: every copy that continues, with its ingest. */\nfunction finished(\n copies: Transformer.ChainCopy[],\n respond: RespondFn | undefined,\n): Transformer.ChainResult {\n return { copies, respond };\n}\n\n/** The stack after a member, with a route pushed on its behalf. */\nfunction withMemberRoute(\n member: Member,\n route: Transformer.Route | undefined,\n): ChainContinuation {\n if (route === undefined) return member.rest;\n // A route the member returned replaces the member's own `next`.\n const below = member.ownNext ? member.rest.slice(1) : member.rest;\n return [{ route, ancestry: member.ancestry }, ...below];\n}\n\n/**\n * Runs every copy of a fork to its end, each isolated (a throw in one copy\n * never starves its siblings). Finished copies are handed back one by one;\n * a copy that was dropped or stopped contributes nothing. A copy started\n * without `respond` cannot hand a respond back (no respond across `many`).\n */\nasync function runForks(\n run: ChainRun,\n copies: Copy[],\n respond: RespondFn | undefined,\n): Promise<Transformer.ChainResult> {\n const results = await Promise.all(\n copies.map((copy, index) =>\n tryCatchAsync(runCopy, (err): Transformer.ChainResult => {\n run.collector.logger\n .scope('transformer:fork')\n .error(`fork ${index} failed`, errorMeta(err));\n return { copies: [] };\n })(run, copy),\n ),\n );\n\n const survivors: Transformer.ChainCopy[] = [];\n let lastRespond = respond;\n let allStopped = results.length > 0;\n let droppedBy: string | undefined;\n results.forEach((result, index) => {\n if (copies[index].respond !== undefined && result.respond)\n lastRespond = result.respond;\n if (!result.stopped) allStopped = false;\n // A dropped or stopped copy (route stop or cache.stop halt) ends here.\n if (result.stopped || result.copies.length === 0) {\n if (droppedBy === undefined) droppedBy = result.droppedBy;\n return;\n }\n survivors.push(...result.copies);\n });\n\n if (survivors.length === 0) {\n return {\n copies: survivors,\n respond: lastRespond,\n ...(allStopped ? { stopped: true as const } : {}),\n ...(droppedBy !== undefined ? { droppedBy } : {}),\n };\n }\n return finished(survivors, lastRespond);\n}\n\n/** Walks one copy to its end: loops `advanceChain`, runs each member. */\nasync function runCopy(\n run: ChainRun,\n copy: Copy,\n): Promise<Transformer.ChainResult> {\n const { ingest } = copy;\n let { stack, event, respond } = copy;\n let resume = copy.resume;\n\n for (;;) {\n let member: Member;\n let resumed: Resume | undefined;\n if (resume) {\n member = resume.member;\n resumed = resume;\n resume = undefined;\n } else {\n const step = advanceChain(\n stack,\n createMappingRoot(ingest, event),\n run.transformers,\n );\n if (step.kind === 'done') return finished([{ event, ingest }], respond);\n if (step.kind === 'stop') {\n return {\n copies: [],\n respond,\n stopped: true,\n ...(step.owner !== undefined ? { droppedBy: step.owner } : {}),\n };\n }\n if (step.kind === 'fork') {\n const parent = event;\n return runForks(\n run,\n step.branches.map((branch, position) => ({\n stack: branch,\n ...forkOf(parent, parent, ingest, position),\n respond: undefined,\n })),\n respond,\n );\n }\n const transformer = run.transformers[step.id];\n member = {\n id: step.id,\n ancestry: step.ancestry,\n rest: step.rest,\n ownNext: transformer ? transformer.config.next !== undefined : false,\n };\n }\n\n const outcome = await runMember(\n run,\n member,\n event,\n ingest,\n respond,\n resumed,\n );\n if (outcome.kind === 'halt') return outcome.result;\n if (outcome.kind === 'fork') return runForks(run, outcome.copies, respond);\n event = outcome.event;\n respond = outcome.respond;\n stack = outcome.stack;\n }\n}\n\n/**\n * Runs one member: path accounting, init, mocks, cache, its `before` chain,\n * `state`, the push, and the result handling. Returns how the copy goes on.\n */\nasync function runMember(\n run: ChainRun,\n member: Member,\n event: WalkerOS.DeepPartialEvent,\n ingest: Ingest,\n respond: RespondFn | undefined,\n resumed: Resume | undefined,\n): Promise<MemberOutcome> {\n const { collector, transformers, chainContext } = run;\n const transformerName = member.id;\n const transformer = transformers[transformerName];\n let processedEvent = event;\n let currentRespond = respond;\n const goOn = (stack: ChainContinuation = member.rest): MemberOutcome => ({\n kind: 'continue',\n event: keepIdentity(event, processedEvent),\n respond: currentRespond,\n stack,\n });\n // A dropped or route-stopped copy hands nothing on (`copies: []`); a\n // `cache.stop` halt hands its cached copy on, flagged `stopped`, for the\n // caller to decide.\n const halt = (result: Transformer.ChainResult): MemberOutcome => ({\n kind: 'halt',\n result,\n });\n\n if (!transformer) {\n collector.logger.warn(`Transformer not found: ${transformerName}`);\n return goOn();\n }\n\n // Compile transformer cache once (reused for HIT check and MISS store).\n // Transformer caches operate on events (step-level HIT/MISS keyed by event\n // fields), so the rule shape is always EventCacheRule, not StoreCacheRule.\n const tCacheConfig = transformer.config?.cache as\n | Cache.Cache<Cache.EventCacheRule>\n | undefined;\n const compiledTCache = tCacheConfig ? compileCache(tCacheConfig) : undefined;\n const tCacheStore = compiledTCache\n ? getCacheStore(compiledTCache, collector)\n : undefined;\n\n let cacheMiss: CacheMiss | undefined = resumed?.cacheMiss;\n\n if (!resumed) {\n // Safety valve: prevent unbounded path growth\n if (ingest._meta.path.length > MAX_PATH_LENGTH) {\n collector.logger.error(`Max path length exceeded at ${transformerName}`);\n return halt({ copies: [], respond: currentRespond });\n }\n\n // Track step in _meta (runtime-managed)\n ingest._meta.hops++;\n ingest._meta.path.push(transformerName);\n\n // Initialize transformer if needed. The wrap surfaces a thrown init\n // (misconfiguration, missing env, etc.) with full cause via the scoped\n // logger and counts it on `status.failed`. A non-throw `false` return\n // from transformerInit itself flows through the same early return below.\n const isInitialized = await tryCatchAsync(\n transformerInit,\n (err: unknown): boolean => {\n if (err instanceof FatalError) throw err;\n collector.status.failed++;\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .error('transformer init failed', {\n transformer: transformerName,\n ...errorMeta(err),\n });\n return false;\n },\n )(collector, transformer, transformerName);\n\n if (!isInitialized) return halt({ copies: [], respond: currentRespond });\n\n // Path-specific mock check (takes precedence)\n if (\n chainContext &&\n transformer.config?.chainMocks?.[chainContext] !== undefined\n ) {\n const chainMock = transformer.config.chainMocks[chainContext];\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .debug('chainMock', { chain: chainContext });\n processedEvent = chainMock as WalkerOS.DeepPartialEvent;\n return goOn();\n }\n\n // Global mock check\n if (transformer.config?.mock !== undefined) {\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .debug('mock');\n processedEvent = transformer.config.mock as WalkerOS.DeepPartialEvent;\n return goOn();\n }\n\n // Disabled check\n if (transformer.config?.disabled) return goOn();\n\n // Check transformer cache (step-level: skip push, continue chain)\n if (compiledTCache && tCacheStore) {\n const cacheResult = await checkCache(\n compiledTCache,\n tCacheStore,\n createMappingRoot(ingest, processedEvent),\n );\n\n if (cacheResult?.status === 'HIT' && cacheResult.value) {\n processedEvent = cacheResult.value as WalkerOS.DeepPartialEvent;\n // stop=true: stop the chain AND halt the pipeline at this position.\n // Callers branch on `stopped` to skip downstream stages.\n if (compiledTCache.stop) {\n const cached = keepIdentity(event, processedEvent);\n return halt({\n copies: [{ event: cached, ingest }],\n respond: currentRespond,\n stopped: true,\n });\n }\n return goOn(); // stop=false: next member\n }\n\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\n }\n }\n\n // The member's `before` chain (mandatory preparation).\n if (transformer.config.before !== undefined) {\n const before = await runTransformerBefore(\n collector,\n transformers,\n transformerName,\n processedEvent,\n ingest,\n currentRespond,\n chainContext,\n );\n const beforeRespond = before.respond ?? currentRespond;\n // Dropped, stopped, or a nested `cache.stop: true` HIT: the copy halts\n // with what the before chain handed back.\n if (before.copies.length === 0 || before.stopped) {\n return halt({ ...before, respond: beforeRespond });\n }\n currentRespond = beforeRespond;\n const [first] = before.copies;\n if (before.copies.length > 1 || first.ingest !== ingest) {\n // The before chain forked: every surviving copy runs this member and\n // the rest of the path as its own copy, with its own ingest and id\n // (both set by the fork inside the before chain).\n const resume: Resume = { member, cacheMiss };\n return {\n kind: 'fork',\n copies: before.copies.map((copy) => ({\n stack: member.rest,\n event: copy.event,\n ingest: copy.ingest,\n respond: undefined,\n resume,\n })),\n };\n }\n processedEvent = first.event;\n }\n }\n\n // Compile declarative state entries. `get` runs before the push (so the\n // mapping can read fetched values); `set` runs after the push settled the\n // event and before the member's route resolves.\n const stateEntries = compileStepState(transformer.config?.state);\n const stateGet = stateEntries?.filter((entry) => entry.mode === 'get');\n const stateSet = stateEntries?.filter((entry) => entry.mode === 'set');\n\n const applyStateSet = async (\n evt: WalkerOS.DeepPartialEvent,\n ): Promise<WalkerOS.DeepPartialEvent> => {\n if (!stateSet || stateSet.length === 0) return evt;\n return runStepState(collector, stateSet, evt, ingest);\n };\n\n if (stateGet && stateGet.length > 0) {\n processedEvent = await runStepState(\n collector,\n stateGet,\n processedEvent,\n ingest,\n );\n }\n\n // Run the transformer\n const result = await tryCatchAsync(transformerPush, (err) => {\n collector.status.failed++;\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .error('Push failed', errorMeta(err));\n return false as const; // Stop chain on error\n })(\n collector,\n transformer,\n transformerName,\n processedEvent,\n ingest,\n currentRespond,\n );\n\n // Returned false, or threw and was converted to false above.\n if (result === false) {\n return halt({\n copies: [],\n respond: currentRespond,\n droppedBy: transformerName,\n });\n }\n\n // `Result[]`: every result is a fork that finishes the rest of the path.\n if (Array.isArray(result) && result.length !== 1) {\n if (result.length === 0)\n return halt({ copies: [], respond: currentRespond });\n const parent = processedEvent;\n const copies: Copy[] = [];\n for (let position = 0; position < result.length; position++) {\n const forkResult = result[position];\n const settled = await applyStateSet(forkResult.event || parent);\n copies.push({\n stack: withMemberRoute(member, forkResult.next),\n ...forkOf(parent, settled, ingest, position),\n respond: currentRespond,\n });\n }\n return { kind: 'fork', copies };\n }\n\n // One result (a one-element `Result[]` continues in place, like a `many`\n // with one match).\n const single = Array.isArray(result) ? result[0] : result;\n let resultNext: Transformer.Route | undefined;\n if (single && typeof single === 'object') {\n if (single.respond) currentRespond = single.respond;\n if (single.event) processedEvent = single.event;\n resultNext = single.next;\n }\n\n processedEvent = await applyStateSet(processedEvent);\n\n // Cache MISS: store the processed event after push\n if (cacheMiss && tCacheStore) {\n storeCache(tCacheStore, cacheMiss.key, processedEvent, cacheMiss.ttl);\n }\n\n return goOn(withMemberRoute(member, resultNext));\n}\n\n/**\n * Runs an event through a chain: the one chain runner.\n *\n * @param collector - The collector instance with transformers\n * @param transformers - Map of transformer instances\n * @param start - The route to run (a chain field such as `source.next`), or\n * a continuation of one; `undefined` runs nothing\n * @param event - The event to process\n * @param ingest - Mutable ingest context flowing through the pipeline\n * @param respond - The respond function in scope\n * @param chainContext - Chain path (e.g. `destination.ga4.before`), recorded\n * as `ingest._meta.chainPath` and keying `chainMocks`\n * @returns Every finished copy with its own ingest (`copies`, empty when\n * dropped or stopped) and the respond in scope afterwards\n */\nexport async function runTransformerChain(\n collector: Collector.Instance,\n transformers: Transformer.Transformers,\n start: Transformer.Route | ChainContinuation | undefined,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n respond?: RespondFn,\n chainContext?: string,\n): Promise<Transformer.ChainResult> {\n // Ensure an ingest exists so the per-copy path budget engages regardless\n // of the caller.\n const chainIngest =\n ingest ?? createIngest(typeof start === 'string' ? start : 'chain');\n if (start === undefined)\n return finished([{ event, ingest: chainIngest }], respond);\n if (chainContext) chainIngest._meta.chainPath = chainContext;\n\n return runCopy(\n { collector, transformers, chainContext },\n {\n stack: isChainContinuation(start) ? start : startChain(start),\n event,\n ingest: chainIngest,\n respond,\n },\n );\n}\n\n/**\n * Runs a transformer's `before` chain: the one implementation, used by the\n * chain runner for every member and by the CLI simulation. A `stop` that\n * the before route itself resolved is attributed to the transformer.\n */\nexport async function runTransformerBefore(\n collector: Collector.Instance,\n transformers: Transformer.Transformers,\n transformerId: string,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n respond?: RespondFn,\n chainContext?: string,\n): Promise<Transformer.ChainResult> {\n const transformer = transformers[transformerId];\n const before = transformer ? transformer.config.before : undefined;\n const result = await runTransformerChain(\n collector,\n transformers,\n before,\n event,\n ingest,\n respond,\n chainContext,\n );\n if (result.stopped && result.copies.length === 0 && !result.droppedBy)\n return { ...result, droppedBy: transformerId };\n return result;\n}\n\n/**\n * Merges transformer environments.\n */\nfunction mergeTransformerEnvironments(\n configEnv?: Transformer.Env,\n): Transformer.Env {\n if (!configEnv) return {};\n if (isObject(configEnv)) return configEnv;\n return {};\n}\n","/**\n * Default per-destination delivery timeout in ms. Applied when a destination's\n * `config.timeout` is `0` or undefined. A hung delivery is converted into a\n * counted DLQ failure after this window so one slow destination never wedges\n * the collector push.\n */\nexport const DEFAULT_DESTINATION_TIMEOUT_MS = 10_000;\n\n/**\n * Resolve the effective delivery timeout for a destination. A positive number\n * wins; `0` or undefined falls back to {@link DEFAULT_DESTINATION_TIMEOUT_MS}.\n */\nexport function resolveDestinationTimeout(timeout?: number): number {\n return typeof timeout === 'number' && timeout > 0\n ? timeout\n : DEFAULT_DESTINATION_TIMEOUT_MS;\n}\n\n/**\n * Error thrown when a destination delivery does not settle within its timeout.\n * The dedicated `name` lets DLQ consumers discriminate a timeout from a\n * destination-thrown error without substring matching the message.\n */\nexport class DestinationTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DestinationTimeoutError';\n }\n}\n\n/**\n * Races a delivery promise against a per-destination timeout. If the work does\n * not settle within `ms`, the returned promise rejects with a\n * {@link DestinationTimeoutError}; the timer is always cleared on settle so no\n * dangling timer remains. The race is constructed per call site, so each\n * destination times out independently and one hang never affects another.\n */\nexport function withTimeout<T>(\n work: Promise<T>,\n ms: number,\n message: string,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new DestinationTimeoutError(message)), ms);\n });\n return Promise.race([work, timeout]).finally(() => {\n if (timer) clearTimeout(timer);\n });\n}\n","import type { Collector } from '@walkeros/core';\nimport { registerDestination } from './destination';\nimport { catchUpDestinationState, isRequireSatisfied } from './on';\nimport { flushSourceQueueOn, isSourceStarted } from './source';\n\n/**\n * Drive activation of every not-yet-active source or destination whose\n * `require` gate is now fully satisfied by the collector's CURRENT recorded\n * state. This is the load-bearing, order-independent safety net: a step\n * activates from the present state regardless of whether the required type\n * fired before or after the step registered (the level, not the broadcast\n * edge). Runs at four triggers (source registration, every state change, the\n * run barrier, dynamic destination add); each call is idempotent.\n *\n * Guards:\n * - Additive. A `require` entry is removed IFF `isRequireSatisfied` (a\n * cell-backed type is present, or an arbitrary type was recorded in\n * `seenEvents`). The broadcast-decrement path in `onApply` stays fully\n * intact, so non-state/arbitrary `require` remains broadcast-satisfiable.\n * - Monotonic + idempotent. A step transitions pending→active exactly once:\n * started sources and already-registered destinations are excluded from the\n * worklist, and `flushSourceQueueOn` clears the buffer it drains.\n * - Delivery-inert while `!allowed`. A source it starts flushes its queueOn,\n * but `flushSourceQueueOn` defers state deliveries (no `on` call, no\n * `setMark`) until allowed. An activated destination only seeds `queuePush`;\n * its `init()`/send stay behind the `!allowed` gate in `pushToDestinations`.\n * - An activated destination also catches up on the present state cells\n * through the gated delivery, so its `on` handler sees the state that\n * activated it before its queue drains; while `!allowed` that catch-up is\n * inert and the run barrier delivers instead.\n *\n * Worklist is scoped to not-yet-active steps only (`pending.destinations` plus\n * unstarted sources); the live `collector.destinations`/started sources are\n * never rescanned.\n */\nexport async function reconcilePending(\n collector: Collector.Instance,\n): Promise<void> {\n // Sources: drop satisfied require entries; flush any that transition to\n // started (init done AND require now empty).\n for (const [sourceId, source] of Object.entries(collector.sources)) {\n if (isSourceStarted(source)) continue;\n const require = source.config.require;\n if (!require?.length) continue;\n\n const remaining = require.filter((t) => !isRequireSatisfied(collector, t));\n if (remaining.length === require.length) continue; // nothing newly satisfied\n\n source.config.require = remaining;\n if (isSourceStarted(source)) {\n await flushSourceQueueOn(collector, source, sourceId);\n }\n }\n\n // Destinations: drop satisfied require entries; register + seed queuePush for\n // any whose require fully empties.\n for (const [id, def] of Object.entries(collector.pending.destinations)) {\n if (!collector.pending.destinations[id] || collector.destinations[id])\n continue;\n\n const require = def.config?.require;\n if (!require) continue;\n\n const remaining = require.filter((t) => !isRequireSatisfied(collector, t));\n if (def.config) def.config.require = remaining;\n if (remaining.length > 0) continue;\n\n delete collector.pending.destinations[id];\n const instance = registerDestination(def);\n if (instance.config.queue !== false) {\n instance.queuePush = [...collector.queue];\n }\n collector.destinations[id] = instance;\n await catchUpDestinationState(collector, instance, id);\n }\n}\n","import type {\n Collector,\n WalkerOS,\n Destination,\n Elb,\n Hooks,\n Ingest,\n On,\n} from '@walkeros/core';\nimport { Const } from './constants';\nimport {\n addDestination,\n markHeldForDrain,\n mergePushResults,\n pushToDestinations,\n settleDestinationDeliveries,\n createPushResult,\n} from './destination';\nimport {\n assign,\n getSpanId,\n getTraceId,\n InvalidEventError,\n isFunction,\n isString,\n} from '@walkeros/core';\nimport { isObject } from '@walkeros/core';\nimport { processConsent } from './consent';\nimport { on, onApplyDeferred, startRunRedelivery, enterCascade } from './on';\nimport type { DestinationDelivery } from './on';\nimport { reconcilePending } from './pending';\nimport { destroyAllSteps } from './shutdown';\nimport type { RunState } from './types/collector';\n\n// Replaced at build time by tsup's `define` (see packages/config/tsup).\ndeclare const __VERSION__: string;\n\n/**\n * Record a reactive-state mutation: bump the global `stateVersion` and stamp the\n * changed cell's own version. The per-cell stamp lets delivery dedup be per-cell\n * (a subscriber owed two cells at once receives both), while `stateVersion`\n * stays the monotonic tick used by the cascade guard.\n */\nfunction bumpCell(collector: Collector.Instance, type: string): void {\n collector.stateVersion++;\n collector.cellVersion[type] = collector.stateVersion;\n}\n\n/**\n * Handles common commands.\n *\n * @param collector The walkerOS collector instance.\n * @param action The action to handle.\n * @param data The data to handle.\n * @returns A promise that resolves with the push result or undefined.\n */\nexport async function commonHandleCommand(\n collector: Collector.Instance,\n action: string,\n data?: unknown,\n): Promise<Elb.PushResult> {\n let result: Elb.PushResult | undefined;\n let onData: unknown;\n let shouldNotify = false;\n // Destination `on()` deliveries this command started and did not wait for.\n const deliveries: DestinationDelivery[] = [];\n\n // Open the bounded-recursion cascade tracker for the OUTERMOST top-level\n // command. Nested commands emitted by reacting state callbacks find it\n // already open and reuse it; teardown is a no-op for them, so the\n // per-(subscriber, cell-type) counters are scoped to this top-level command\n // and reset when it returns.\n const exitCascade = enterCascade(collector);\n try {\n return await runHandleCommand();\n } finally {\n exitCascade();\n }\n\n async function runHandleCommand(): Promise<Elb.PushResult> {\n switch (action) {\n case Const.Commands.Config:\n if (isObject(data)) {\n // `merge: false`: a config array (the `next` route) is replaced,\n // never unioned with the previous one.\n assign(collector.config, data as Partial<Collector.Config>, {\n shallow: false,\n merge: false,\n });\n onData = data;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.Consent:\n if (isObject(data)) {\n const { update } = processConsent(\n collector,\n data as WalkerOS.Consent,\n );\n bumpCell(collector, Const.Commands.Consent);\n onData = update;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.Custom:\n if (isObject(data)) {\n collector.custom = assign(\n collector.custom,\n data as WalkerOS.Properties,\n );\n bumpCell(collector, Const.Commands.Custom);\n onData = data;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.Destination:\n if (\n isObject(data) &&\n 'code' in data &&\n isObject((data as Destination.Init).code)\n ) {\n result = await addDestination(collector, data as Destination.Init);\n }\n break;\n\n case Const.Commands.Globals:\n if (isObject(data)) {\n collector.globals = assign(\n collector.globals,\n data as WalkerOS.Properties,\n );\n bumpCell(collector, Const.Commands.Globals);\n onData = data;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.Hook:\n if (\n isObject(data) &&\n isString((data as { name?: unknown }).name) &&\n isFunction((data as { fn?: unknown }).fn)\n ) {\n const { name, fn } = data as {\n name: string;\n fn: WalkerOS.AnyFunction;\n };\n collector.hooks[name as keyof Hooks.Functions] = fn;\n onData = data;\n shouldNotify = true;\n }\n break;\n\n case Const.Commands.On:\n if (isObject(data) && isString((data as { type?: unknown }).type)) {\n const { type, rules } = data as {\n type: On.Types;\n rules: WalkerOS.SingleOrArray<On.Subscription>;\n };\n await on(collector, type, rules);\n }\n break;\n\n case Const.Commands.Ready:\n shouldNotify = true;\n break;\n\n case Const.Commands.Run:\n result = await runCollectorDeferred(\n collector,\n data as RunState,\n deliveries,\n );\n shouldNotify = true;\n break;\n\n case Const.Commands.Session:\n shouldNotify = true;\n break;\n\n case Const.Commands.Shutdown:\n // Idempotency guard: re-entrancy must not re-run destroyAllSteps and\n // double-close writers, destinations, or stores. The first shutdown\n // sets the flag and runs the full sequence; a second command no-ops.\n if (!collector.hasShutdown) {\n collector.hasShutdown = true;\n await destroyAllSteps(collector);\n }\n break;\n\n case Const.Commands.User:\n if (isObject(data)) {\n assign(collector.user, data as WalkerOS.User, { shallow: false });\n bumpCell(collector, Const.Commands.User);\n onData = data;\n shouldNotify = true;\n }\n break;\n\n default:\n collector.logger.warn('unknown command', { command: action });\n return createPushResult({ ok: false });\n }\n\n // Single notification + flush point for all state-mutation commands\n if (shouldNotify) {\n const applied = await onApplyDeferred(\n collector,\n action as On.Types,\n undefined,\n onData,\n );\n deliveries.push(...applied.deliveries);\n markHeldForDrain(applied.deliveries);\n // Every destination is flushed now. One whose delivery is still running\n // is held, so its events wait for that delivery alone; the settle below\n // pushes them as soon as it is done, without delaying any other\n // destination.\n const flushed = mergePushResults(\n await pushToDestinations(collector),\n await settleDestinationDeliveries(collector, deliveries),\n );\n // `run` is the only command that sets `result` before this point (from\n // runCollector). Overwriting it outright would discard that outcome, so a\n // pre-run event that failed on replay would be invisible: its original\n // caller already got `ok: true` at hold time and there is no other place\n // it can surface. Every other command leaves `result` undefined here, so\n // this merge is a no-op for them.\n if (result && result.ok === false) {\n const failed = { ...(flushed.failed ?? {}), ...(result.failed ?? {}) };\n result = {\n ...flushed,\n ok: false,\n ...(Object.keys(failed).length > 0 ? { failed } : {}),\n };\n } else {\n result = flushed;\n }\n }\n\n return result || createPushResult({ ok: true });\n }\n}\n\n/**\n * Builds the partial event handed to `createEvent`, injecting the default\n * `timing` (elapsed since the collector started) and the collector `source`\n * meta. Event-provided values override the defaults.\n *\n * @param collector The walkerOS collector instance.\n * @param event The incoming partial event.\n * @returns The partial event with defaults applied.\n */\nexport function prepareEvent(\n collector: Collector.Instance,\n event: WalkerOS.DeepPartialEvent,\n): WalkerOS.PartialEvent {\n return {\n timing: Math.round((Date.now() - collector.timing) / 10) / 100,\n source: { type: 'collector', schema: '4' },\n ...event,\n } as WalkerOS.PartialEvent;\n}\n\n/**\n * Collector state an event is floored with: its globals under the event's\n * own, its user and consent when the event has none.\n */\ninterface EventFloors {\n globals: WalkerOS.Properties;\n user: WalkerOS.User;\n consent: WalkerOS.Consent;\n}\n\n/**\n * Creates a full event from a partial event, floored with the collector's\n * current state (globals, user, consent).\n *\n * @param collector The walkerOS collector instance.\n * @param partialEvent The partial event to transform.\n * @returns The full event.\n */\nexport function createEvent(\n collector: Collector.Instance,\n partialEvent: WalkerOS.PartialEvent,\n ingest?: Ingest,\n): WalkerOS.Event {\n return buildEvent(collector, partialEvent, ingest, {\n globals: collector.globals,\n user: collector.user,\n consent: collector.consent,\n });\n}\n\n/**\n * Completes an event that was already created and then edited by a chain\n * (`collector.next`): fills only the fields that are missing, never floors\n * globals, user or consent again, so a step that removed one keeps it\n * removed.\n */\nexport function completeEvent(\n collector: Collector.Instance,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n): WalkerOS.Event {\n return buildEvent(collector, prepareEvent(collector, event), ingest, {\n globals: {},\n user: {},\n consent: {},\n });\n}\n\n/** Shape completion shared by `createEvent` and `completeEvent`. */\nfunction buildEvent(\n collector: Collector.Instance,\n partialEvent: WalkerOS.PartialEvent,\n ingest: Ingest | undefined,\n floors: EventFloors,\n): WalkerOS.Event {\n // The name arrives from client-controlled input, so its declared type is a\n // claim rather than a guarantee. A wrong-typed value must be rejected here:\n // reaching split() below throws a TypeError, which the push boundary reads as\n // a pipeline fault and answers with a 500 instead of a 400.\n const rawName = partialEvent.name;\n if (typeof rawName !== 'string')\n throw new InvalidEventError(\n rawName === undefined\n ? 'Event name is required'\n : 'Event name is invalid',\n );\n if (!rawName) throw new InvalidEventError('Event name is required');\n\n const [entityValue, actionValue] = rawName.split(' ');\n if (!entityValue || !actionValue)\n throw new InvalidEventError('Event name is invalid');\n\n const {\n timestamp = Date.now(),\n name = `${entityValue} ${actionValue}`,\n data = {},\n context = {},\n globals = {},\n custom = {},\n user = floors.user,\n nested = [],\n consent = floors.consent,\n // A supplied id is preserved: sources and the push wrap mint the span\n // early so pre-enrichment records can carry it.\n id = getSpanId(),\n trigger = '',\n entity = entityValue,\n action = actionValue,\n timing = 0,\n source = { type: 'collector', schema: '4' },\n } = partialEvent;\n\n // Stamp the per-run sequence and trace, but only when absent so forwarded\n // events (web -> api -> server) keep their origin identity. Trace precedence:\n // a payload trace wins; a header-derived ingest trace fills the gap; the\n // run-scoped collector trace is the final fallback.\n // A destructuring default fills `undefined` only, so an explicit null source\n // arrives as null and must be normalized before it is dereferenced.\n const sourceValue: WalkerOS.Source = source ?? {\n type: 'collector',\n schema: '4',\n };\n const count = sourceValue.count ?? (collector.count += 1);\n // Must match journeyFields' trace precedence (observerEmit.ts).\n const trace = sourceValue.trace ?? ingest?._meta.trace ?? collector.trace;\n const stampedSource: WalkerOS.Source = { ...sourceValue, count };\n if (trace !== undefined) stampedSource.trace = trace;\n\n // Spread the incoming map so entries from upstream flows survive the crossing\n // and the local flow's release is appended; release thus accumulates across a\n // full-event walkerOS→walkerOS crossing.\n const releaseKey = collector.name ?? sourceValue.platform ?? 'default';\n const releaseValue = collector.release ?? __VERSION__;\n stampedSource.release = {\n ...sourceValue.release,\n [releaseKey]: releaseValue,\n };\n\n // The collector's globals (config statics plus `walker globals`) are the\n // floor for every created event; values the event carries win per key.\n const mergedGlobals = assign(floors.globals, globals);\n\n return {\n name,\n data,\n context,\n globals: mergedGlobals,\n custom,\n user,\n nested,\n consent,\n id,\n trigger,\n entity,\n action,\n timestamp,\n timing,\n source: stampedSource,\n };\n}\n\n/**\n * Enriches a partial event into a full event by applying the collector defaults\n * (`prepareEvent`) and then building the complete event (`createEvent`). This is\n * the single enrichment entry point shared by the production push path and\n * simulation, so both produce identical events.\n *\n * @param collector The walkerOS collector instance.\n * @param event The incoming partial event.\n * @returns The full event.\n */\nexport function enrichEvent(\n collector: Collector.Instance,\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n): WalkerOS.Event {\n return createEvent(collector, prepareEvent(collector, event), ingest);\n}\n\n/**\n * Runs the collector by setting it to allowed state and processing queued events.\n *\n * @param collector The walkerOS collector instance.\n * @param state Optional state to merge with the collector (user, globals, consent, custom).\n * @returns A promise that resolves with the push result.\n */\nexport async function runCollector(\n collector: Collector.Instance,\n state?: RunState,\n): Promise<Elb.PushResult> {\n const deliveries: DestinationDelivery[] = [];\n const result = await runCollectorDeferred(collector, state, deliveries);\n return mergePushResults(\n result,\n await settleDestinationDeliveries(collector, deliveries),\n );\n}\n\n/**\n * `runCollector` without waiting for the destinations' run re-delivery: their\n * deliveries are appended to `deliveries` for the caller to settle after its\n * own flush, so one slow destination handler delays no other destination.\n */\nexport async function runCollectorDeferred(\n collector: Collector.Instance,\n state: RunState | undefined,\n deliveries: DestinationDelivery[],\n): Promise<Elb.PushResult> {\n // Set the collector to allowed state\n collector.allowed = true;\n\n // Update timing for this run\n collector.timing = Date.now();\n\n // Each run starts a new trace and resets the per-run emission counter.\n collector.trace = getTraceId();\n collector.count = 0;\n\n // Update collector state if provided\n if (state) {\n // Update consent if provided\n if (state.consent) {\n collector.consent = assign(collector.consent, state.consent);\n bumpCell(collector, Const.Commands.Consent);\n }\n\n // Update user if provided\n if (state.user) {\n collector.user = assign(collector.user, state.user);\n bumpCell(collector, Const.Commands.User);\n }\n\n // Update globals if provided\n if (state.globals) {\n collector.globals = assign(\n collector.config.globalsStatic || {},\n state.globals,\n );\n bumpCell(collector, Const.Commands.Globals);\n }\n\n // Update custom if provided\n if (state.custom) {\n collector.custom = assign(collector.custom, state.custom);\n bumpCell(collector, Const.Commands.Custom);\n }\n }\n\n // Reset destination queues\n Object.values(collector.destinations).forEach((destination) => {\n destination.queuePush = [];\n });\n\n // Reset collector queue for this run\n collector.queue = [];\n\n // Increase round counter\n collector.round++;\n\n // Run barrier — activate first, then re-deliver. The collector just became\n // `allowed` and any RunState cells were merged + bumped above, so a step\n // parked on `require` (e.g. a source gated on consent that only arrives via\n // the run state) can now activate. Reconcile BEFORE redeliver so the\n // freshly-started step is in `collector.sources` when redeliver re-broadcasts\n // owed state, and thus receives its consent/user/globals/custom delivery at\n // the barrier rather than missing it.\n await reconcilePending(collector);\n\n // Run barrier: the collector just became `allowed`. Re-deliver each non-empty\n // recorded state cell to subscribers owed a pre-run deferral (mark <\n // stateVersion) exactly once, so their reactions (e.g. a session source's\n // `session start` push) emit into the now-open, consent-gated pipeline. The\n // per-subscriber high-water mark guarantees exactly-once; this is the narrow\n // path (no require-decrement / queueOn flush). The subsequent `onApply(…,\n // 'run', …)` from commonHandleCommand is a lifecycle broadcast and does not\n // collide with these state re-deliveries.\n const redelivered = await startRunRedelivery(collector);\n\n // Replay events held while the collector was dormant (FIFO, wall-clock\n // order). Splice first so replayed pushes (now allowed) can never\n // re-enter the buffer, and a second run finds it empty.\n //\n // A replayed event's original caller already got `ok: true` (accepted-and-\n // held), so a later failure has no caller left to report to. The run result\n // is the only place it can surface, and it must: this run already reports\n // failures from the OTHER buffer it flushes below, so staying silent here\n // would make the same command inconsistent across its two buffers.\n let replayOk = true;\n const replayFailed: NonNullable<Elb.PushResult['failed']> = {};\n if (collector.preRunQueue.length) {\n const held = collector.preRunQueue.splice(0);\n collector.logger.debug('replaying pre-run events', { count: held.length });\n for (const { event, options } of held) {\n const replayResult = await collector.push(event, options);\n if (replayResult.ok === false) replayOk = false;\n // Carry per-destination detail when there is any. A push that threw\n // reports `ok: false` with no `failed` map (see push.ts's catch), so the\n // boolean is tracked separately rather than derived from the map.\n if (replayResult.failed) Object.assign(replayFailed, replayResult.failed);\n }\n }\n\n // Process any queued events now that the collector is allowed\n // Each destination's run re-delivery runs on its own: a destination still\n // receiving it is held and its events wait for it; the others go out now.\n markHeldForDrain(redelivered);\n const result = await pushToDestinations(collector);\n deliveries.push(...redelivered);\n\n if (replayOk) return result;\n\n const failed = { ...(result.failed ?? {}), ...replayFailed };\n return {\n ...result,\n ok: false,\n ...(Object.keys(failed).length > 0 ? { failed } : {}),\n };\n}\n","import type { Collector, Lifecycle, Logger } from '@walkeros/core';\n\nconst STEP_TIMEOUT = 5000;\n\n/**\n * Destroy all steps in pipeline order: sources → destinations → transformers.\n * Called by the collector's `shutdown` command handler.\n */\nexport async function destroyAllSteps(\n collector: Collector.Instance,\n): Promise<void> {\n const logger = collector.logger;\n\n // Phase 1: Sources (stop intake)\n await destroyStepGroup(collector.sources, 'source', logger);\n\n // Phase 2: Destinations, flush pending batches first, then close connections.\n await flushDestinationBatches(collector.destinations, logger);\n await destroyStepGroup(collector.destinations, 'destination', logger);\n\n // Phase 3: Transformers (release caches)\n await destroyStepGroup(collector.transformers, 'transformer', logger);\n\n // Phase 4: Stores (release storage — last, so transformers can flush during their destroy)\n await destroyStepGroup(collector.stores, 'store', logger);\n}\n\nasync function flushDestinationBatches(\n destinations: Collector.Instance['destinations'],\n rootLogger: Logger.Instance,\n): Promise<void> {\n const promises = Object.entries(destinations).flatMap(([id, dest]) => {\n const batches = dest.batches;\n if (!batches) return [];\n const logger = rootLogger.scope(dest.type || 'destination');\n return Object.values(batches).map(async (b) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n b.flush(),\n new Promise<void>((_, reject) => {\n timer = setTimeout(\n () =>\n reject(new Error(`destination '${id}' batch flush timed out`)),\n STEP_TIMEOUT,\n );\n }),\n ]);\n } catch (err) {\n logger.error(`destination '${id}' batch flush failed: ${err}`);\n } finally {\n if (timer) clearTimeout(timer);\n }\n });\n });\n await Promise.allSettled(promises);\n}\n\nasync function destroyStepGroup<\n T extends { config: unknown; env?: unknown; type?: string },\n>(\n steps: Record<string, T>,\n label: string,\n rootLogger: Logger.Instance,\n): Promise<void> {\n const promises = Object.entries(steps).map(async ([id, step]) => {\n // Access destroy via cast: its DestroyContext<C,E> generic is contravariant,\n // so concrete step types aren't assignable to a structural destroy signature.\n // Safe because we pass each step's own config/env back to its own destroy.\n const destroy = (\n step as {\n destroy?: (ctx: Lifecycle.DestroyContext) => void | Promise<void>;\n }\n ).destroy;\n if (!destroy) return;\n\n const stepType = step.type || 'unknown';\n const logger = rootLogger.scope(stepType);\n\n const context: Lifecycle.DestroyContext = {\n id,\n config: step.config,\n env: step.env ?? {},\n logger,\n };\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n destroy(context),\n new Promise<void>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`${label} '${id}' destroy timed out`)),\n STEP_TIMEOUT,\n );\n }),\n ]);\n } catch (err) {\n logger.error(`${label} '${id}' destroy failed: ${err}`);\n } finally {\n if (timer) clearTimeout(timer);\n }\n });\n\n await Promise.allSettled(promises);\n}\n","import type { Collector, Elb, EmitFn, ObserverFn } from '@walkeros/core';\nimport {\n OBSERVE_STORAGE_KEY,\n createBatchedPoster,\n createTelemetryObserver,\n parseObserveCredential,\n} from '@walkeros/core';\nimport type { StartFlow } from './types';\nimport { collector } from './collector';\nimport { initSources } from './source';\n\n// Structural slices of the browser globals the web-arm credential read\n// touches. The collector runs platform-neutral, so window/URLSearchParams\n// are read off globalThis behind guards -- the same pattern core's\n// preview.ts activator uses. On a server runtime both lookups resolve to\n// undefined and the web arm reads \"absent\" (zero work).\ninterface ObserveGlobals {\n window?: {\n location: { href: string; search: string };\n history: { replaceState(data: unknown, title: string, url: string): void };\n localStorage: {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n };\n };\n URLSearchParams?: new (init: string) => {\n getAll(name: string): string[];\n delete(name: string): void;\n toString(): string;\n };\n}\n\nconst G = globalThis as ObserveGlobals;\n\n/**\n * Last `elbObserve` URL param value, or null. The param name and the\n * storage slot share the `elbObserve` key by design (the preview activator\n * ferries the former into the latter). Never throws.\n */\nfunction readObserveParam(): string | null {\n const win = G.window;\n const USP = G.URLSearchParams;\n if (!win || !USP) return null;\n try {\n const search = new USP(win.location.search.replace(/^\\?/, ''));\n const values = search.getAll(OBSERVE_STORAGE_KEY);\n return values.length > 0 ? (values[values.length - 1] ?? null) : null;\n } catch {\n return null;\n }\n}\n\n/** Stored `elbObserve` slot, or null. Never throws (Safari private mode). */\nfunction readObserveSlot(): string | null {\n try {\n return G.window?.localStorage.getItem(OBSERVE_STORAGE_KEY) ?? null;\n } catch {\n return null;\n }\n}\n\nfunction writeObserveSlot(value: string): void {\n try {\n G.window?.localStorage.setItem(OBSERVE_STORAGE_KEY, value);\n } catch {\n // Slot persistence is best-effort; the session still attaches this page.\n }\n}\n\n/**\n * CAS-style slot clear: remove the slot only when it still holds exactly\n * `expected`, so a credential re-minted by another tab (or a later\n * activation) is never destroyed by a stale poster's self-heal.\n */\nfunction clearObserveSlotIf(expected: string): void {\n try {\n const win = G.window;\n if (!win) return;\n if (win.localStorage.getItem(OBSERVE_STORAGE_KEY) === expected) {\n win.localStorage.removeItem(OBSERVE_STORAGE_KEY);\n }\n } catch {\n // Storage unavailable: nothing to heal.\n }\n}\n\n/**\n * Remove the `elbObserve` param from the address bar after it has been\n * persisted to the slot, keeping every other param and the hash intact.\n * Same history.replaceState mechanics as core preview.ts's stripParam, but\n * scoped to the one param this wiring owns.\n */\nfunction stripObserveParam(): void {\n const win = G.window;\n const USP = G.URLSearchParams;\n if (!win || !USP) return;\n try {\n const href = win.location.href;\n const hashIdx = href.indexOf('#');\n const hash = hashIdx >= 0 ? href.slice(hashIdx) : '';\n const withoutHash = hashIdx >= 0 ? href.slice(0, hashIdx) : href;\n const qIdx = withoutHash.indexOf('?');\n const path = qIdx >= 0 ? withoutHash.slice(0, qIdx) : withoutHash;\n const params = new USP(qIdx >= 0 ? withoutHash.slice(qIdx + 1) : '');\n params.delete(OBSERVE_STORAGE_KEY);\n const query = params.toString();\n win.history.replaceState(\n {},\n '',\n `${path}${query ? `?${query}` : ''}${hash}`,\n );\n } catch {\n // A page that forbids history writes still attaches; the param stays.\n }\n}\n\n/**\n * Stamp the runtime's release provenance onto every posted record. Like\n * `flowId`, `release` is baked by the wiring layer so emitting sites never\n * see it. Identity when the runtime has no release id.\n */\nfunction withRelease(post: EmitFn, release: string | undefined): EmitFn {\n if (release === undefined) return post;\n return (state) => post({ ...state, release });\n}\n\n/**\n * Override the record's flowId on every posted record. The emit sites stamp\n * `collector.name`; a baked connect config (e.g. a preview artifact) may\n * carry the platform's flow id instead, so the posting layer rewrites it\n * without the emit sites ever knowing. Identity when no override is baked.\n */\nfunction withFlowId(post: EmitFn, flowId: string | undefined): EmitFn {\n if (flowId === undefined) return post;\n return (state) => post({ ...state, flowId });\n}\n\n/**\n * Install the advisory observation channel configured on `initConfig`: an\n * `observe` connect config attaches a telemetry poster for its arm. Runs\n * after the collector instance exists and before `command('run')`, so\n * run-phase records are captured. Everything installed here is advisory:\n * observers run inside `emitStep`'s try/catch and the poster swallows\n * transport errors, so nothing on this path can break event processing.\n */\nfunction installObserve(\n instance: Collector.Instance,\n initConfig: Collector.InitConfig,\n): void {\n const observe = initConfig.observe;\n if (!observe) return;\n\n const flowId = instance.name ?? 'default';\n\n if ('binding' in observe) {\n // Web arm: the credential arrives out-of-band via the elbObserve URL\n // param (or the storage slot the preview activator ferries it into).\n // Truly absent means zero work: no parse, no storage write, no observer.\n const param = readObserveParam();\n const raw = param ?? readObserveSlot();\n if (!raw) return;\n\n // A present-but-broken credential is warned, never silently dropped;\n // only the truly-absent case above is silent (zero-work contract).\n const credential = parseObserveCredential(raw);\n if (!credential) {\n if (param === null) {\n // Slot-sourced garbage: stored state clears on its own failure, so\n // self-heal instead of warning on every pageview.\n instance.logger.warn('observe: malformed stored credential cleared');\n clearObserveSlotIf(raw);\n } else {\n // URL-sourced garbage never touches stored state (anti-griefing).\n instance.logger.warn('observe: malformed credential ignored');\n }\n return;\n }\n if (credential.pb !== observe.binding) {\n instance.logger.warn(\n 'observe: credential binding mismatch, credential ignored',\n );\n return;\n }\n\n writeObserveSlot(raw);\n // The credential is persisted; a URL-borne copy is now redundant and,\n // being a bearer credential, must not linger in the address bar.\n if (param !== null) stripObserveParam();\n\n let observer: ObserverFn | undefined;\n const post = createBatchedPoster({\n url: `${observe.url}/ingest/${credential.ses}`,\n token: credential.secret,\n headers: { 'X-Walkeros-Binding': observe.binding },\n onStatus: (status) => {\n if (status !== 401) return;\n // The observer rejected this credential (session ended or token\n // revoked): self-heal the slot -- CAS, only while it still holds\n // exactly this credential -- and detach, so posting stops and the\n // next pageview is back on the silent zero-work path.\n clearObserveSlotIf(raw);\n if (observer) instance.observers.delete(observer);\n },\n });\n // Baked scoping: a wrap (e.g. a preview artifact) may carry a public\n // flowId/level/sample on the connect config. flowId overrides the local\n // config name on every posted record so they land under the platform's\n // flow id; a baked level also drives the collector-wide capture supplier\n // so destination call capture runs at trace.\n observer = createTelemetryObserver(\n withFlowId(withRelease(post, instance.release), observe.flowId),\n {\n flowId: observe.flowId ?? flowId,\n ...(observe.level !== undefined ? { level: observe.level } : {}),\n ...(observe.sample !== undefined ? { sample: observe.sample } : {}),\n },\n );\n instance.observers.add(observer);\n const bakedLevel = observe.level;\n if (bakedLevel !== undefined) {\n instance.observeLevel = () => bakedLevel;\n }\n return;\n }\n\n // Server arm: the config trio is the credential; attach directly.\n // 'off' opts out entirely (no observer, zero emit-path work).\n if (observe.level === 'off') return;\n // Mirror the web arm: a configured level also drives the collector-wide\n // capture supplier, so 'trace' enables destination call capture.\n const serverLevel = observe.level;\n if (serverLevel !== undefined) {\n instance.observeLevel = () => serverLevel;\n }\n instance.observers.add(\n createTelemetryObserver(\n withRelease(\n createBatchedPoster({\n url: `${observe.url}/ingest/${observe.sessionId}`,\n token: observe.token,\n }),\n instance.release,\n ),\n { flowId, level: observe.level, sample: observe.sample },\n ),\n );\n}\n\nexport async function startFlow<ElbPush extends Elb.Fn = Elb.Fn>(\n initConfig?: Collector.InitConfig,\n): Promise<StartFlow<ElbPush>> {\n initConfig = initConfig || {};\n const instance = await collector(initConfig);\n\n // Caller-supplied observers land in the advisory Set verbatim.\n if (initConfig.observers) {\n for (const observer of initConfig.observers) {\n instance.observers.add(observer);\n }\n }\n\n // Attach the advisory observation channel before source init and the run\n // command, so source-init and run-phase records are captured. Build flag\n // (see @walkeros/core build-flags): a lean bundle folds the poster out.\n if (typeof __WALKEROS_OBSERVE__ === 'undefined' || __WALKEROS_OBSERVE__) {\n installObserve(instance, initConfig);\n } else if (initConfig.observe) {\n instance.logger.warn('observe: not in this build, config ignored');\n }\n\n // Initialize sources; the collector's elb adapter is already available\n await initSources(instance, initConfig.sources || {});\n\n const { consent, user, globals, custom } = initConfig;\n\n // Route all four startup state cells through `command` so each bumps\n // `stateVersion`, broadcasts to subscribers, and triggers reconcile. A bare\n // `Object.assign` for globals/custom would silently skip those, leaving a\n // `require:[\"globals\"]` step un-reconciled and `on('globals')` subscribers\n // un-notified at startup.\n if (consent) await instance.command('consent', consent);\n if (user) await instance.command('user', user);\n if (globals) await instance.command('globals', globals);\n if (custom) await instance.command('custom', custom);\n\n if (instance.config.run) await instance.command('run');\n\n // Determine the primary elb:\n // 1. Use explicitly marked primary source\n // 2. Use first source if any exist\n // 3. Fallback to the collector's elb adapter\n let primaryElb: Elb.Fn = instance.elb;\n\n const sources = Object.values(instance.sources);\n\n // First, check for explicitly marked primary source. `initSources` mirrors a\n // top-level `InitSource.primary` onto the instance config, so both spellings\n // are visible here.\n const markedPrimary = sources.find((source) => source.config.primary);\n\n if (markedPrimary) {\n primaryElb = markedPrimary.push as Elb.Fn;\n } else if (sources.length > 0) {\n // Use first source as default\n primaryElb = sources[0].push as Elb.Fn;\n }\n\n return {\n collector: instance,\n elb: primaryElb as ElbPush,\n };\n}\n","import type { Collector, Elb, Logger, WalkerOS } from '@walkeros/core';\nimport { assign, createLogger } from '@walkeros/core';\nimport { commonHandleCommand, prepareEvent } from './handle';\nimport { initDestinations } from './destination';\nimport { initTransformers } from './transformer';\nimport { createPush } from './push';\nimport { createCommand } from './command';\nimport { createElb } from './elb';\nimport { initSources } from './source';\nimport { initStores, resolveStoreReferences } from './store';\nimport { createCacheStore } from './cache-store';\n\nexport async function collector(\n initConfig: Collector.InitConfig,\n): Promise<Collector.Instance> {\n const defaultConfig: Collector.Config = {\n globalsStatic: {},\n sessionStatic: {},\n run: true,\n queueMax: 1_000,\n };\n\n const config: Collector.Config = assign(defaultConfig, initConfig, {\n merge: false,\n extend: false,\n });\n\n // Create logger with config from initConfig\n const loggerConfig: Logger.Config = {\n level: initConfig.logger?.level,\n handler: initConfig.logger?.handler,\n };\n const logger = createLogger(loggerConfig);\n\n // Enhanced globals with static globals from config\n const finalGlobals = { ...config.globalsStatic, ...initConfig.globals };\n\n const collector: Collector.Instance = {\n allowed: false,\n config,\n consent: initConfig.consent || {},\n custom: initConfig.custom || {},\n destinations: {},\n transformers: {},\n stores: {},\n globals: finalGlobals,\n hooks: initConfig.hooks || {},\n observers: new Set(),\n logger,\n on: {},\n queue: [],\n preRunQueue: [],\n round: 0,\n count: 0,\n stateVersion: 0,\n cellVersion: {},\n delivery: new WeakMap(),\n session: undefined,\n status: {\n startedAt: Date.now(),\n in: 0,\n out: 0,\n failed: 0,\n sources: {},\n destinations: {},\n dropped: {},\n connectionErrors: {},\n breakers: {},\n },\n timing: Date.now(),\n user: initConfig.user || {},\n sources: {},\n pending: { destinations: {} },\n hasShutdown: false,\n seenEvents: new Set(),\n push: undefined as unknown as Collector.PushFn, // Placeholder, will be set below\n command: undefined as unknown as Collector.CommandFn, // Placeholder, will be set below\n elb: undefined as unknown as Elb.Fn, // Placeholder, will be set below\n };\n\n // Mirror static flow identity from initConfig onto the instance.\n // `assign(defaultConfig, initConfig, { extend: false })` copies a key only\n // if it already exists in defaultConfig, so name/release never reach\n // `collector.config`; read them from initConfig directly, once, at\n // construction (they are static, unlike the per-run `trace`).\n if (initConfig.name !== undefined) collector.name = initConfig.name;\n if (initConfig.release !== undefined) collector.release = initConfig.release;\n\n // `next` has no default, so the `extend: false` assign above drops it; seed\n // the collector chain explicitly.\n if (initConfig.next !== undefined) config.next = initConfig.next;\n\n // Set the push and command functions with the collector reference\n collector.push = createPush(collector, (event) =>\n prepareEvent(collector, event),\n );\n\n collector.command = createCommand(collector, commonHandleCommand);\n\n // Attach the elb adapter so it exists before any source init\n collector.elb = createElb(collector);\n\n // Initialize stores (first - other components may depend on them).\n // Build flag (see @walkeros/core build-flags): a lean bundle without\n // declared stores folds this out; the default `__cache` below always stays.\n const rawStores = initConfig.stores || {};\n if (typeof __WALKEROS_STORES__ === 'undefined' || __WALKEROS_STORES__) {\n collector.stores = await initStores(collector, rawStores);\n\n // Resolve store references in component env values.\n // The bundler emits `$store.gcs` as a direct reference to `stores.gcs`\n // (the raw {code, config} definition). After initialization, replace\n // these raw references with the actual Store.Instance objects.\n resolveStoreReferences(rawStores, collector.stores, initConfig);\n } else if (Object.keys(rawStores).length > 0) {\n logger.warn('stores: not in this build, config ignored');\n }\n\n // Create default cache store for steps that use cache without explicit store.\n // Uses LRU + entry cap + batched eviction + active TTL sweep. See\n // `cache-store.ts` for the full semantics.\n if (!collector.stores.__cache) {\n collector.stores.__cache = createCacheStore();\n }\n\n // Initialize destinations after collector is fully created\n // Sources are initialized in startFlow after ELB source is created\n collector.destinations = await initDestinations(\n collector,\n initConfig.destinations || {},\n );\n\n // Initialize transformers\n collector.transformers = await initTransformers(\n collector,\n initConfig.transformers || {},\n );\n\n return collector;\n}\n","import type { Collector, WalkerOS, Elb, Ingest } from '@walkeros/core';\nimport {\n createIngest,\n emitStep,\n FatalError,\n getGrantedConsent,\n getSpanId,\n InvalidEventError,\n processEventMapping,\n tryCatchAsync,\n useHooks,\n} from '@walkeros/core';\nimport {\n pushBounded,\n resetOverflowFlag,\n seededQueueMax,\n warnOverflowOnce,\n} from './buffers';\nimport { bumpDropped, errorMeta } from './report-error';\nimport { createEvent, enrichEvent } from './handle';\nimport { pushToDestinations, createPushResult } from './destination';\nimport {\n emitCollectorDrop,\n journeyFields,\n stepError,\n stepState,\n} from './observerEmit';\nimport { runTransformerChain } from './transformer';\n\nfunction filterDestinations(\n destinations: Collector.Destinations,\n include?: string[],\n exclude?: string[],\n): Collector.Destinations {\n let filtered = destinations;\n if (include) {\n filtered = Object.fromEntries(\n Object.entries(filtered).filter(([id]) => include.includes(id)),\n );\n }\n if (exclude) {\n filtered = Object.fromEntries(\n Object.entries(filtered).filter(([id]) => !exclude.includes(id)),\n );\n }\n return filtered;\n}\n\n/**\n * Creates the push function for the collector.\n * Handles source mapping, event creation, and routing to destinations.\n *\n * @param collector - The walkerOS collector instance\n * @param prepareEvent - Function to enrich partial events\n * @returns The push function\n */\nexport function createPush<T extends Collector.Instance>(\n collector: T,\n prepareEvent: (event: WalkerOS.DeepPartialEvent) => WalkerOS.PartialEvent,\n): Collector.PushFn {\n const innerPush = useHooks(\n async (\n event: WalkerOS.DeepPartialEvent,\n options: Collector.PushOptions = {},\n ): Promise<Elb.PushResult> => {\n return await tryCatchAsync(\n async (): Promise<Elb.PushResult> => {\n // Dormant hold: an event born before run is held raw and replayed\n // by runCollector, so the pipeline (mapping, chains, enrichment)\n // runs exactly once, with post-run state. See prerun-hold.test.ts.\n if (!collector.allowed) {\n const max = seededQueueMax(collector.config.queueMax);\n const held = pushBounded(\n collector.preRunQueue,\n { event, options },\n { max },\n );\n if (held.dropped > 0) {\n // Counted under its own step id, NOT `stepId('collector')`: that\n // one's `queue` counter is the post-run replay buffer, and\n // pre-run loss is a different problem with a different fix, so\n // the two stay separately diagnosable.\n const droppedCount = bumpDropped(\n collector.status,\n 'collector.preRun',\n 'queue',\n held.dropped,\n );\n warnOverflowOnce(\n collector.preRunQueue,\n collector.logger,\n 'collector.preRunQueue overflow; oldest events dropped',\n { buffer: 'queue', cap: max, droppedCount },\n );\n } else if (collector.preRunQueue.length < max) {\n resetOverflowFlag(collector.preRunQueue);\n }\n collector.logger.debug('event held until run', {\n name: event.name,\n dropped: held.dropped,\n });\n return createPushResult({ ok: true });\n }\n\n const pushStart = Date.now();\n const {\n id,\n ingest,\n respond: initialRespond,\n mapping,\n preChain,\n include,\n exclude,\n } = options;\n let respond = initialRespond;\n let partialEvent = event;\n\n // Build filtered destination set if include/exclude specified\n const filteredDests =\n include || exclude\n ? filterDestinations(collector.destinations, include, exclude)\n : undefined;\n\n // Create mutable Ingest — accumulates context through the pipeline\n let pipelineIngest: Ingest =\n (ingest as Ingest | undefined) ?? createIngest(id || 'unknown');\n\n // Apply source mapping if provided in options\n if (mapping) {\n const processed = await processEventMapping(\n partialEvent,\n mapping,\n collector,\n );\n\n // Check ignore flag\n if (processed.ignore) {\n return createPushResult({ ok: true });\n }\n\n // Check consent requirements\n if (mapping.consent) {\n const grantedConsent = getGrantedConsent(\n mapping.consent,\n collector.consent,\n processed.event.consent as WalkerOS.Consent | undefined,\n );\n\n if (!grantedConsent) {\n return createPushResult({ ok: true });\n }\n }\n\n partialEvent = processed.event;\n }\n\n // Run the pre-collector chain (the source's `next` route). It\n // resolves hop by hop with `{ ingest, event }`, after the source's\n // mapping and state.\n if (preChain !== undefined) {\n const chainPath = id ? `source.${id}.next` : undefined;\n const chainResult = await runTransformerChain(\n collector,\n collector.transformers || {},\n preChain,\n partialEvent,\n pipelineIngest,\n respond,\n chainPath,\n );\n\n // Dropped or stopped: the event never reaches the collector.\n if (chainResult.copies.length === 0) {\n collector.logger.debug(\n `Event dropped by transformer chain${\n chainResult.droppedBy ? ` (${chainResult.droppedBy})` : ''\n }`,\n );\n emitCollectorDrop(\n collector,\n partialEvent,\n pipelineIngest,\n chainResult.droppedBy,\n chainPath ?? 'collector.push.preChain',\n );\n return createPushResult({ ok: true, dropped: true });\n }\n\n // Pipeline-halt signal from a pre-collector `cache.stop: true`\n // HIT. The event is intentionally NOT forwarded to destinations;\n // duplicates are suppressed at the source.next boundary per the\n // documented \"downstream transformers and destinations are\n // skipped\" semantic in transformers/cache.mdx.\n if (chainResult.stopped) {\n if (chainResult.respond) respond = chainResult.respond;\n return createPushResult({ ok: true });\n }\n\n // Update respond if the chain produced a wrapped one\n if (chainResult.respond) respond = chainResult.respond;\n\n // Every finished copy goes on with its own ingest. The runner\n // owns identity: a single copy keeps the chain input's id, a fork\n // copy carries its derived id.\n if (chainResult.copies.length > 1) {\n // Process each forked copy through the rest of the pipeline\n const forkResults = await Promise.all(\n chainResult.copies.map(async (copy) => {\n const full = createEvent(\n collector,\n prepareEvent(copy.event),\n copy.ingest,\n );\n return pushToDestinations(\n collector,\n full,\n { id, ingest: copy.ingest, respond },\n filteredDests,\n );\n }),\n );\n\n // Update source status\n if (id) {\n if (!collector.status.sources[id]) {\n collector.status.sources[id] = {\n count: 0,\n duration: 0,\n };\n }\n const sourceStatus = collector.status.sources[id];\n sourceStatus.count += chainResult.copies.length;\n sourceStatus.lastAt = Date.now();\n sourceStatus.duration += Date.now() - pushStart;\n }\n\n return forkResults[0] ?? createPushResult({ ok: true });\n }\n\n partialEvent = chainResult.copies[0].event;\n pipelineIngest = chainResult.copies[0].ingest;\n }\n\n // Enrich into a full event (timing, source info, defaults)\n const fullEvent = enrichEvent(\n collector,\n partialEvent,\n pipelineIngest,\n );\n\n // Push to destinations with id and ingest\n const result = await pushToDestinations(\n collector,\n fullEvent,\n {\n id,\n ingest: pipelineIngest,\n respond,\n },\n filteredDests,\n );\n\n // Update source status\n if (id) {\n if (!collector.status.sources[id]) {\n collector.status.sources[id] = {\n count: 0,\n duration: 0,\n };\n }\n const sourceStatus = collector.status.sources[id];\n sourceStatus.count++;\n sourceStatus.lastAt = Date.now();\n sourceStatus.duration += Date.now() - pushStart;\n }\n\n return result;\n },\n (err: unknown) => {\n if (err instanceof FatalError) throw err;\n if (err instanceof InvalidEventError) {\n // Client input fault, not a pipeline failure: warn without a\n // stack, count it as a source rejection, and hand the caller a\n // discriminated result it can map to a 4xx response.\n // `id` is destructured inside the try body, which this sibling\n // callback does not see, so the source id comes from `options`.\n const sourceId = options.id;\n if (sourceId) {\n if (!collector.status.sources[sourceId]) {\n collector.status.sources[sourceId] = { count: 0, duration: 0 };\n }\n const sourceStatus = collector.status.sources[sourceId];\n sourceStatus.rejected = (sourceStatus.rejected ?? 0) + 1;\n }\n collector.logger.warn('invalid event rejected', {\n error: err.message,\n });\n return createPushResult({\n ok: false,\n invalid: true,\n error: err.message,\n });\n }\n collector.status.failed++;\n // Identify the event by NAME only. The log context is serialized\n // into stderr, the error ring and the managed-run jsonl sink, so it\n // stays primitive and low-cardinality: the full event (user,\n // consent, data) and the raw ingest payload would be a PII egress,\n // and per-event values would make every failure look distinct to\n // the ring's message dedup.\n collector.logger.error('push failed', {\n ...errorMeta(err),\n event: event.name,\n });\n return createPushResult({ ok: false });\n },\n )();\n },\n 'Push',\n collector.hooks,\n collector.logger,\n );\n\n const wrapped: Collector.PushFn = async (event, options) => {\n // Mint the event's span id HERE when absent, so every record of this\n // event carries it, the wrap's own in record included. This is the id the\n // identified event carries into `createEvent`, which preserves a supplied\n // id (handle.ts). The copy never mutates the caller's object.\n const identified =\n typeof event.id === 'string' && event.id !== ''\n ? event\n : { ...event, id: getSpanId() };\n const eventId = typeof identified.id === 'string' ? identified.id : '';\n // Journey correlation from what is in scope at the wrap boundary: the\n // incoming event's trace, then the header-derived ingest trace, then the\n // run trace, plus the source context threaded through `options.ingest`.\n // The processed full event is not visible here, so out/error reuse the\n // same incoming-event trace (identical value in the common case).\n const journey = journeyFields(identified, options?.ingest, collector);\n const started = Date.now();\n const inState = stepState(\n collector,\n 'collector.push',\n 'collector',\n 'in',\n eventId,\n started,\n journey,\n );\n inState.inEvent = identified;\n emitStep(collector, inState);\n\n try {\n const result = await innerPush(identified, options);\n const finished = Date.now();\n const outState = stepState(\n collector,\n 'collector.push',\n 'collector',\n 'out',\n // The same id as the in record. Reading it off the result instead\n // would split the wrap's own pair across two journeys whenever the\n // result reports a different event: a fan-out reporting its first\n // child, or a `prePush` hook that swapped the event.\n eventId,\n finished,\n journey,\n );\n outState.durationMs = finished - started;\n outState.outEvent = result;\n emitStep(collector, outState);\n return result;\n } catch (err) {\n const finished = Date.now();\n const errState = stepState(\n collector,\n 'collector.push',\n 'collector',\n 'error',\n eventId,\n finished,\n journey,\n );\n errState.durationMs = finished - started;\n errState.error = stepError(err);\n emitStep(collector, errState);\n throw err;\n }\n };\n\n return wrapped;\n}\n","import type { Collector, Elb } from '@walkeros/core';\nimport type { HandleCommandFn } from './types/collector';\nimport { FatalError, useHooks, tryCatchAsync } from '@walkeros/core';\nimport { createPushResult } from './destination';\nimport { errorMeta } from './report-error';\n\n/**\n * Creates the command function for the collector.\n * Handles walker commands (config, consent, destination, etc.)\n *\n * @param collector - The walkerOS collector instance\n * @param handleCommand - Command handler function\n * @returns The command function\n */\nexport function createCommand<T extends Collector.Instance>(\n collector: T,\n handleCommand: HandleCommandFn<T>,\n): Collector.CommandFn {\n return useHooks(\n async (\n command: string,\n data?: unknown,\n options?: unknown,\n ): Promise<Elb.PushResult> => {\n return await tryCatchAsync(\n async (): Promise<Elb.PushResult> => {\n return await handleCommand(collector, command, data, options);\n },\n (err: unknown) => {\n if (err instanceof FatalError) throw err;\n collector.status.failed++;\n // `command` is a low-cardinality identifier and stays; the\n // arbitrary `data` payload does not. Log context is serialized into\n // stderr, the error ring and the jsonl sink, where a command's\n // operand (consent state, user fields) would be a PII egress.\n collector.logger.error('command failed', {\n ...errorMeta(err),\n command,\n });\n return createPushResult({ ok: false });\n },\n )();\n },\n 'Command',\n collector.hooks,\n collector.logger,\n );\n}\n","import type { Collector, WalkerOS, Elb } from '@walkeros/core';\nimport { createPushResult } from './destination';\n\n/**\n * Creates the default ELB adapter.\n * Routes between collector.push and collector.command based on input.\n * Provides backward-compatible flexible argument interface.\n *\n * @param collector - The walkerOS collector instance\n * @returns ELB adapter function\n */\nexport function createElb(collector: Collector.Instance): Elb.Fn {\n return async (\n eventOrCommand?: unknown,\n data?: unknown,\n context?: unknown,\n nested?: WalkerOS.Entities,\n custom?: WalkerOS.Properties,\n ): Promise<Elb.PushResult> => {\n // Detect walker commands\n if (\n typeof eventOrCommand === 'string' &&\n eventOrCommand.startsWith('walker ')\n ) {\n const command = eventOrCommand.replace('walker ', '');\n return collector.command(command, data);\n }\n\n // Build event object\n let event: WalkerOS.DeepPartialEvent;\n\n if (typeof eventOrCommand === 'string') {\n // Convert string to object: elb('page view', { title: 'Home' })\n event = { name: eventOrCommand };\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n event.data = data as WalkerOS.Properties;\n }\n } else if (\n eventOrCommand &&\n typeof eventOrCommand === 'object' &&\n // Exclude arrays passed by untyped runtime callers; Elb.Fn already forbids them\n !Array.isArray(eventOrCommand)\n ) {\n // Use object directly: elb({ name: 'page view', data: {...} })\n // Shallow-clone so adapter writes never leak onto the caller's object\n event = { ...(eventOrCommand as WalkerOS.DeepPartialEvent) };\n // Merge additional data if provided\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n event.data = {\n ...(event.data || {}),\n ...(data as WalkerOS.Properties),\n };\n }\n } else {\n // Invalid input\n return createPushResult({ ok: false });\n }\n\n // Add optional properties if provided\n if (context && typeof context === 'object') {\n event.context = context as WalkerOS.OrderedProperties;\n }\n if (nested && Array.isArray(nested)) {\n event.nested = nested;\n }\n if (custom && typeof custom === 'object') {\n event.custom = custom as WalkerOS.Properties;\n }\n\n // Call collector.push with event object\n return collector.push(event);\n };\n}\n","import type { Cache, Collector, Store } from '@walkeros/core';\nimport { emitStep, useHooks } from '@walkeros/core';\nimport { createCacheStore } from './cache-store';\nimport { stepError, stepState } from './observerEmit';\nimport { wrapStoreWithCache } from './store-cache-wrapper';\nimport { buildReportError } from './report-error';\n\n/**\n * Narrowed view of a `Store.InitStore` entry that also carries the optional\n * `cache` configuration emitted by the bundler. The runtime `Store.InitStores`\n * map is loosely typed at the core level so it can carry pass-through fields\n * (`cache`, `variables`, etc.) without coupling the core `Store.InitStore`\n * shape to flow-level concerns. Phase 2 reads `cache` through this local view.\n */\ntype InitStoreWithCache = Store.InitStore & {\n cache?: Cache.Cache<Cache.StoreCacheRule>;\n};\n\n/**\n * Hook wrapping and observer emission for a single store instance.\n * Mutates `instance` in place.\n *\n * Called once per store, AFTER any cache wrapping in phase 2. Wrapping the\n * outer (wrapper) instance means observers see the consumer-facing\n * boundary: they fire on every `wrapped.get` regardless of cache HIT/MISS,\n * and only once per `wrapped.set` (not also for the wrapper's internal\n * write into `cacheStore`). If the store has no cache wrapper, the bare\n * backing is wrapped instead, preserving observability.\n *\n * Two responsibilities per op:\n * 1. Inner `useHooks(..., 'StoreGet', ...)` wrap keeps the generic\n * user-declared hook contract working (`preStoreGet`, `postStoreSet`,\n * etc.).\n * 2. Outer self-emit wrap pushes `FlowState` (`stepType: 'store'`) into\n * `collector.observers` directly, so per-store telemetry no longer\n * needs a separate hook bag.\n */\nfunction applyStoreHooks(\n collector: Collector.Instance,\n instance: Store.Instance,\n storeId: string,\n): void {\n const stepIdFor = `store.${storeId}`;\n\n const innerGet = useHooks(\n instance.get,\n 'StoreGet',\n collector.hooks,\n collector.logger,\n );\n const innerSet = useHooks(\n instance.set,\n 'StoreSet',\n collector.hooks,\n collector.logger,\n );\n const innerDelete = useHooks(\n instance.delete,\n 'StoreDelete',\n collector.hooks,\n collector.logger,\n );\n\n instance.get = async (key: string): Promise<Store.StoreValue | undefined> => {\n const started = Date.now();\n const inState = stepState(collector, stepIdFor, 'store', 'in', '', started);\n inState.meta = { op: 'get', key };\n emitStep(collector, inState);\n\n try {\n const result = await innerGet(key);\n const finished = Date.now();\n const outState = stepState(\n collector,\n stepIdFor,\n 'store',\n 'out',\n '',\n finished,\n );\n outState.durationMs = finished - started;\n outState.meta = { op: 'get', key };\n emitStep(collector, outState);\n return result;\n } catch (err) {\n const finished = Date.now();\n const errState = stepState(\n collector,\n stepIdFor,\n 'store',\n 'error',\n '',\n finished,\n );\n errState.durationMs = finished - started;\n errState.meta = { op: 'get', key };\n errState.error = stepError(err);\n emitStep(collector, errState);\n throw err;\n }\n };\n\n instance.set = async (\n key: string,\n value: Store.StoreValue,\n ttl?: number,\n ): Promise<void> => {\n const started = Date.now();\n const inState = stepState(collector, stepIdFor, 'store', 'in', '', started);\n // Store values can be secrets or PII: emit only the op + key, never the\n // raw value, on any phase (in/out/error). Observers see what happened,\n // not what was written.\n inState.meta = { op: 'set', key };\n emitStep(collector, inState);\n\n try {\n await innerSet(key, value, ttl);\n const finished = Date.now();\n const outState = stepState(\n collector,\n stepIdFor,\n 'store',\n 'out',\n '',\n finished,\n );\n outState.durationMs = finished - started;\n outState.meta = { op: 'set', key };\n emitStep(collector, outState);\n } catch (err) {\n const finished = Date.now();\n const errState = stepState(\n collector,\n stepIdFor,\n 'store',\n 'error',\n '',\n finished,\n );\n errState.durationMs = finished - started;\n errState.meta = { op: 'set', key };\n errState.error = stepError(err);\n emitStep(collector, errState);\n throw err;\n }\n };\n\n instance.delete = async (key: string): Promise<void> => {\n const started = Date.now();\n const inState = stepState(collector, stepIdFor, 'store', 'in', '', started);\n inState.meta = { op: 'delete', key };\n emitStep(collector, inState);\n\n try {\n await innerDelete(key);\n const finished = Date.now();\n const outState = stepState(\n collector,\n stepIdFor,\n 'store',\n 'out',\n '',\n finished,\n );\n outState.durationMs = finished - started;\n outState.meta = { op: 'delete', key };\n emitStep(collector, outState);\n } catch (err) {\n const finished = Date.now();\n const errState = stepState(\n collector,\n stepIdFor,\n 'store',\n 'error',\n '',\n finished,\n );\n errState.durationMs = finished - started;\n errState.meta = { op: 'delete', key };\n errState.error = stepError(err);\n emitStep(collector, errState);\n throw err;\n }\n };\n}\n\n/**\n * Walks the `cache.store` graph in topological order (terminals first) and\n * reports each store id together with its cache config. Detects cycles via\n * three-color DFS (WHITE → GRAY → BLACK) and rejects references to unknown\n * store ids. Throws on the first problem with a message naming the path.\n *\n * The returned order is suitable for wrapping: when a wrapper is built for\n * store X, its `cache.store` target (if any) has already been wrapped.\n */\nfunction topoOrderForCacheWrap(\n defs: Record<string, InitStoreWithCache>,\n): string[] {\n type Color = 'WHITE' | 'GRAY' | 'BLACK';\n const color: Record<string, Color> = {};\n for (const id of Object.keys(defs)) color[id] = 'WHITE';\n\n const order: string[] = [];\n const stack: string[] = [];\n\n function visit(id: string): void {\n const c = color[id];\n if (c === 'BLACK') return;\n if (c === 'GRAY') {\n const cycleStart = stack.indexOf(id);\n const cyclePath = stack\n .slice(cycleStart === -1 ? 0 : cycleStart)\n .concat(id)\n .join(' -> ');\n throw new Error(`Cycle in cache.store chain: ${cyclePath}`);\n }\n\n color[id] = 'GRAY';\n stack.push(id);\n\n const target = defs[id].cache?.store;\n if (target !== undefined) {\n if (!(target in defs)) {\n throw new Error(\n `Store \"${id}\" cache.store references \"${target}\", which is not declared in flow.stores`,\n );\n }\n visit(target);\n }\n\n stack.pop();\n color[id] = 'BLACK';\n order.push(id);\n }\n\n for (const id of Object.keys(defs)) {\n if (color[id] === 'WHITE') visit(id);\n }\n\n return order;\n}\n\n/**\n * Initialize store instances from configuration.\n *\n * Three-phase init:\n * Phase 1, instantiate: call `code(context)` for every declared store.\n * Order is not significant in this phase. Hooks are NOT installed yet —\n * they wrap the outer boundary in phase 3.\n * Phase 2, topologically wrap: walk the `cache.store` graph, detect cycles\n * and unknown targets, then visit terminals first so any cache wrapper\n * installed in Task 7+ can rely on its backing being already wrapped.\n * Phase 3, install hooks: wrap the final instance (wrapper if cache was\n * applied, otherwise the bare backing) so hooks fire at the consumer\n * boundary and observe cache HIT/MISS behavior.\n *\n * Phase 2 must run before `resolveStoreReferences` in `collector.ts` so that\n * env-reference replacement uses the wrapped instance (referential identity\n * matters for the resolver).\n */\nexport async function initStores(\n collector: Collector.Instance,\n initStores: Store.InitStores = {},\n): Promise<Store.Stores> {\n const result: Store.Stores = {};\n\n // Phase 1: instantiate every store. Hooks are deferred to phase 3 so they\n // can wrap the outer (cache-wrapped) instance and observe HIT/MISS at the\n // consumer-facing boundary.\n for (const [storeId, storeDef] of Object.entries(initStores)) {\n const { code, config = {}, env = {} } = storeDef;\n\n const storeLogger = collector.logger.scope('store').scope(storeId);\n\n const context = {\n collector,\n logger: storeLogger,\n id: storeId,\n config,\n env,\n reportError: buildReportError(collector, 'store', storeId, storeLogger),\n };\n\n const instance = await code(context);\n result[storeId] = instance;\n }\n\n // Phase 2: validate the cache.store graph and wrap in topological order.\n // Cycle and missing-target errors propagate out of `topoOrderForCacheWrap`.\n // Read-through wrapping is delegated to `wrapStoreWithCache`. The cache\n // layer is either a user-declared store (resolved against the in-progress\n // `result` map) or the default `__cache`, which is created lazily here so\n // it ends up assigned to `collector.stores` together with the rest.\n const defsWithCache = initStores as Record<string, InitStoreWithCache>;\n const order = topoOrderForCacheWrap(defsWithCache);\n for (const storeId of order) {\n const cacheConfig = defsWithCache[storeId].cache;\n if (!cacheConfig) continue;\n\n let cacheStore: Store.Instance;\n let cacheStoreId: string;\n if (cacheConfig.store !== undefined) {\n // Missing-target validation already ran in `topoOrderForCacheWrap`, so\n // this lookup is guaranteed to hit.\n cacheStore = result[cacheConfig.store];\n cacheStoreId = cacheConfig.store;\n } else {\n if (!result.__cache) {\n result.__cache = createCacheStore();\n }\n cacheStore = result.__cache;\n cacheStoreId = '__cache';\n }\n\n // Schema rejects `namespace: \"\"` for store caches, so the only way the\n // wrapper sees an absent namespace is when the user omitted it entirely.\n // In that case default to the host store id so multiple wrapped stores\n // sharing `__cache` cannot collide on raw keys.\n const resolvedNamespace = cacheConfig.namespace ?? storeId;\n\n // One startup log line per wrapped store. Operators inspecting the cache\n // layer see prefixed keys (e.g. `api:K`); surfacing the resolved namespace\n // and cache-store id here keeps that defaulting from feeling like hidden\n // magic. Scope mirrors the wrapper's own scope (Task 8) so all\n // cache-related output groups under `store-cache:<id>`.\n collector.logger\n .scope('store-cache')\n .scope(storeId)\n .info(\n `store \"${storeId}\" caches with namespace \"${resolvedNamespace}:\" via ${cacheStoreId}`,\n );\n\n result[storeId] = wrapStoreWithCache(result[storeId], {\n storeId,\n cacheConfig,\n cacheStore,\n namespace: resolvedNamespace,\n logger: collector.logger.scope('store-cache').scope(storeId),\n collector,\n });\n }\n\n // Phase 3: install hooks on the final instance for every user-declared\n // store. Wrapping the OUTER instance (wrapper if a cache was applied,\n // bare backing otherwise) means the hook fires at the consumer-facing\n // boundary and observes cache HIT/MISS. The auto-created default\n // `__cache` is skipped — it has no consumer-facing contract; users never\n // call `__cache.get` directly. Skipping it also prevents the wrapper's\n // internal writes into the default cache from double-firing\n // `preStoreSet` against the consumer-facing boundary.\n for (const [storeId, instance] of Object.entries(result)) {\n if (storeId === '__cache') continue;\n applyStoreHooks(collector, instance, storeId);\n }\n\n return result;\n}\n\n/**\n * Resolve store references in component env values.\n *\n * The bundler resolves `$store.gcs` to a direct JS reference to the raw\n * store definition object (`stores.gcs = { code, config }`). After stores\n * are initialized, this function walks transformer/destination/source env\n * objects and replaces any raw store definition reference with the\n * corresponding initialized Store.Instance.\n *\n * IMPORTANT: Uses referential identity (`===`) to match env values against\n * raw store definitions. This works because the bundler generates code where\n * env values are direct references to the same objects in the `stores` map.\n * Programmatic configs must use the same object reference — copies won't match.\n *\n * Only resolves top-level env keys. Nested store references are not supported.\n */\nexport function resolveStoreReferences(\n rawStores: Store.InitStores,\n initializedStores: Store.Stores,\n initConfig: Collector.InitConfig,\n): void {\n // Build a lookup: raw store def → initialized instance (O(1) per env value)\n const lookup = new Map<object, Store.Instance>();\n for (const [storeId, rawDef] of Object.entries(rawStores)) {\n if (initializedStores[storeId])\n lookup.set(rawDef, initializedStores[storeId]);\n }\n if (lookup.size === 0) return;\n\n function resolveEnv(env: Record<string, unknown> | undefined) {\n if (!env) return;\n for (const [key, value] of Object.entries(env)) {\n if (typeof value === 'object' && value !== null) {\n const instance = lookup.get(value);\n if (instance) env[key] = instance;\n }\n }\n }\n\n // Walk all component types that may have env values\n for (const defs of [\n initConfig.transformers,\n initConfig.destinations,\n initConfig.sources,\n ]) {\n if (!defs) continue;\n for (const def of Object.values(defs)) {\n resolveEnv((def as { env?: Record<string, unknown> }).env);\n }\n }\n}\n","import type { Store } from '@walkeros/core';\n\n/**\n * Options for the built-in collector cache store (`__cache`).\n *\n * The default cache is an entry-capped LRU with active TTL sweep. Byte-size\n * accounting is opt-in: when `maxSize` is `undefined`, no byte budget is\n * enforced.\n */\nexport interface CacheStoreOptions {\n /** Hard cap on entries. Defaults to 10000. */\n maxEntries?: number;\n /**\n * Optional byte budget for the cache. When set, byte-sized eviction is\n * enabled in addition to entry-count eviction. Defaults to `undefined`\n * (no byte budget).\n */\n maxSize?: number;\n /**\n * Active sweep interval (ms) for purging expired entries even when they\n * are never read. Defaults to 60_000 (60 seconds). Pass 0 to disable.\n */\n sweepIntervalMs?: number;\n /**\n * Fraction of `maxEntries` to keep after a batched eviction pass. Defaults\n * to 0.8. The cache trims to `maxEntries * lowWaterMark` in one pass on\n * overflow.\n */\n lowWaterMark?: number;\n}\n\n/**\n * Operational counters exposed by the cache store. All counters are\n * monotonic for the lifetime of the cache instance.\n */\nexport interface CacheStoreCounters {\n /** Successful `get` calls that returned a live cached value. */\n hits: number;\n /** `get` calls that found no entry (cold) or only an expired one. */\n misses: number;\n /** `set` calls that created a new key (first-time population). */\n populates: number;\n /** All `set` calls (populates + overwrites). */\n writes: number;\n /** All `delete` calls that removed an existing key. */\n deletes: number;\n /** Entries removed because the cache hit `maxEntries`. */\n evictions_entries: number;\n /** Entries removed because their TTL expired (sweep or lazy). */\n evictions_ttl: number;\n}\n\ninterface CacheEntry {\n value: Store.StoreValue;\n expires?: number;\n}\n\n/**\n * The upgraded `__cache` store. Backward-compatible with the existing\n * `Store.Instance` shape — callers see `get(key)`, `set(key, value, ttl?)`,\n * `delete(key)`. Adds an observability surface via `counters` and an active\n * TTL sweep that runs on a timer.\n *\n * Eviction model:\n * - Map iteration order is insertion order; oldest insertion is the FIFO head.\n * - `get` reorders the entry to most-recently-used (delete + re-insert).\n * - On insert overflow (size > maxEntries), evict in one pass down to\n * `lowWaterMark * maxEntries` (default 80%).\n *\n * Active TTL sweep: every `sweepIntervalMs` ms, walk the map and drop any\n * entries past `expires`. The interval is cleared in `destroy()`.\n */\nexport type CacheStore = Store.Instance & {\n readonly counters: CacheStoreCounters;\n destroy: () => void;\n};\n\nconst DEFAULT_MAX_ENTRIES = 10000;\nconst DEFAULT_SWEEP_INTERVAL_MS = 60_000;\nconst DEFAULT_LOW_WATER_MARK = 0.8;\n\nexport function createCacheStore(options: CacheStoreOptions = {}): CacheStore {\n const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;\n const lowWaterMark = options.lowWaterMark ?? DEFAULT_LOW_WATER_MARK;\n const sweepIntervalMs = options.sweepIntervalMs ?? DEFAULT_SWEEP_INTERVAL_MS;\n const targetSize = Math.floor(maxEntries * lowWaterMark);\n\n const entries = new Map<string, CacheEntry>();\n\n const counters: CacheStoreCounters = {\n hits: 0,\n misses: 0,\n populates: 0,\n writes: 0,\n deletes: 0,\n evictions_entries: 0,\n evictions_ttl: 0,\n };\n\n function evictOverflow(): void {\n if (entries.size <= maxEntries) return;\n // Trim in one pass down to targetSize using insertion-order iteration\n // (oldest first). LRU is preserved because `get` re-inserts on access.\n const toRemove = entries.size - targetSize;\n let removed = 0;\n for (const key of entries.keys()) {\n if (removed >= toRemove) break;\n entries.delete(key);\n removed++;\n }\n counters.evictions_entries += removed;\n }\n\n function sweep(): void {\n const now = Date.now();\n let removed = 0;\n for (const [key, entry] of entries) {\n if (entry.expires !== undefined && entry.expires <= now) {\n entries.delete(key);\n removed++;\n }\n }\n counters.evictions_ttl += removed;\n }\n\n let sweepTimer: ReturnType<typeof setInterval> | undefined;\n if (sweepIntervalMs > 0) {\n sweepTimer = setInterval(sweep, sweepIntervalMs);\n // Don't keep the Node.js event loop alive solely for the cache sweep.\n if (\n sweepTimer &&\n typeof (sweepTimer as { unref?: () => void }).unref === 'function'\n ) {\n (sweepTimer as { unref: () => void }).unref();\n }\n }\n\n const store: CacheStore = {\n type: 'memory',\n config: {},\n\n get(key: string): Store.StoreValue | undefined {\n const entry = entries.get(key);\n if (!entry) {\n counters.misses++;\n return undefined;\n }\n\n if (entry.expires !== undefined && entry.expires <= Date.now()) {\n entries.delete(key);\n counters.evictions_ttl++;\n counters.misses++;\n return undefined;\n }\n\n // LRU: move to most-recently-used position.\n entries.delete(key);\n entries.set(key, entry);\n counters.hits++;\n return entry.value;\n },\n\n set(key: string, value: Store.StoreValue, ttl?: number): void {\n const isNew = !entries.has(key);\n // Always delete first so re-insert puts the entry at the\n // most-recently-used position regardless of overwrite or new.\n if (!isNew) entries.delete(key);\n\n entries.set(key, {\n value,\n expires: ttl !== undefined ? Date.now() + ttl : undefined,\n });\n\n counters.writes++;\n if (isNew) counters.populates++;\n\n if (entries.size > maxEntries) evictOverflow();\n },\n\n delete(key: string): void {\n if (entries.delete(key)) counters.deletes++;\n },\n\n get counters() {\n // Return a snapshot so external callers can't mutate internal state.\n return { ...counters };\n },\n\n destroy(): void {\n if (sweepTimer !== undefined) {\n clearInterval(sweepTimer);\n sweepTimer = undefined;\n }\n entries.clear();\n },\n };\n\n return store;\n}\n","import type { Cache, Collector, Logger, Store } from '@walkeros/core';\nimport {\n compileMatcher,\n emitStep,\n readCacheEnvelope,\n wrapCacheEnvelope,\n} from '@walkeros/core';\nimport { stepState } from './observerEmit';\nimport { errorMeta } from './report-error';\n\n/**\n * Options passed to `wrapStoreWithCache`. Pre-resolved by `initStores` phase\n * 2 so the wrapper itself stays small and side-effect free at construction.\n *\n * - `cacheStore` is the store layer where cached values live. Defaults to\n * the collector's `__cache` instance, but may be any other initialized\n * store (e.g. a fs-backed cache for cross-process sharing).\n * - `namespace` is the prefix prepended to every key written to the cache\n * layer. Defaults to `storeId` when the user did not override\n * `cache.namespace`.\n * - `logger` is the collector's scoped logger, used for the best-effort\n * warnings emitted when a cache-side write or delete fails. Optional only\n * to keep test setups lightweight — production call sites pass\n * `collector.logger`.\n */\nexport interface WrappedStoreOptions {\n storeId: string;\n cacheConfig: Cache.Cache<Cache.StoreCacheRule>;\n cacheStore: Store.Instance;\n namespace: string;\n logger?: Logger.Instance;\n /**\n * Optional collector reference for cache-level observability. When\n * provided, the wrapper emits a `FlowState` (`stepType: 'store'`,\n * `meta.op: 'cache'`) on every wrapped `get`, carrying the resolved\n * cache status (`'hit'` or `'miss'`) and the key. Observers attached\n * to `collector.observers` see HIT/MISS without coupling to wrapper\n * internals. Optional only to keep unit-test setups lightweight;\n * production call sites pass it.\n */\n collector?: Collector.Instance;\n}\n\ninterface CompiledStoreCacheRule {\n match: (context: Record<string, unknown>) => boolean;\n ttl: number;\n}\n\n/**\n * Per-wrapped-store observability counters. The `evictions_*` counters live on\n * the underlying cache store (`createCacheStore` returns its own counters\n * surface for the global `__cache`), so they are deliberately absent here.\n *\n * Semantics:\n * - `hits` — `cacheStore.get` returned a defined value.\n * - `misses` — cache returned undefined AND no in-flight Promise was joined\n * (this caller is the one driving the backing fetch).\n * - `populates` — the wrapper wrote into the cache after a backing MISS that\n * returned a defined value AND matched a rule.\n * - `writes` — every call to `wrapper.set`, regardless of cache outcome.\n * - `deletes` — every call to `wrapper.delete`.\n * - `inflight_dedups` — a get found an in-flight Promise on the same key and\n * joined it instead of starting a new backing call.\n */\nexport interface WrappedStoreCounters {\n hits: number;\n misses: number;\n populates: number;\n writes: number;\n deletes: number;\n inflight_dedups: number;\n}\n\n/**\n * Public-facing extension of `Store.Instance` with the per-wrapper counter\n * surface. Consumers that need observability (operator UIs, debug endpoints)\n * cast to this type via `as WrappedStoreInstance`; everything else continues\n * to see the canonical `Store.Instance` shape and stays decoupled from the\n * wrapper's internals.\n */\nexport interface WrappedStoreInstance extends Store.Instance {\n /**\n * Snapshot accessor: returns a fresh copy of the counter map on every\n * access. Mutating the returned object never affects internal state, so\n * callers can serialize, diff, or send the snapshot freely. The returned\n * object always carries every counter key, zero-initialized.\n */\n readonly counters: WrappedStoreCounters;\n}\n\n/**\n * Wrap a backing `Store.Instance` with a read-through cache layer.\n *\n * Read semantics:\n * 1. Probe the cache at `namespace:key` and interpret the stored\n * `{value, exp}` envelope via `readCacheEnvelope`. A live envelope is a\n * HIT. An expired envelope is best-effort purged and treated as a MISS.\n * 2. On MISS, delegate to `backing.get(key)`.\n * 3. If the backing returned a defined value AND a rule matches the\n * `{ key, value }` context, populate the cache with the value wrapped in\n * a `{value, exp}` envelope (exp = now + `rule.ttl * 1000` ms) AND pass\n * the `ttl` arg so a TTL-native tier can proactively evict (dual-write).\n * The envelope `exp` is authoritative; the `ttl` arg is an eviction hint.\n * Negative caching (caching `undefined`) is intentionally not supported.\n *\n * Multi-tier: each wrapper wraps independently. When the cache tier is itself\n * a wrapped store, the value is enveloped once per tier (nested envelopes), and\n * each tier strips exactly its own outer envelope on read, so the read chain\n * unwraps as many layers as it wrapped. Nesting depth and payload grow with the\n * number of tiers (negligible for the typical 2-3 tier chain). Each tier owns\n * its own `exp` from its own rule, so the staleness bound is per tier.\n *\n * Write semantics (`set` / `delete`) follow the \"cache is advisory\" policy\n * documented in `docs/plans/2026-05-13-store-cache-design.md` (Write path and\n * error policy):\n * - Backing first. If `backing.set`/`backing.delete` throws, the wrapper\n * throws and the cache layer is never touched. The backing is the source\n * of truth and its failures must surface to the caller.\n * - Cache best-effort. After a successful backing write, attempt the cache\n * write. A throwing cache layer is logged via `logger.warn` and swallowed\n * so the wrapper still resolves successfully, the next read will MISS\n * and re-populate. Failed cache deletes leave a stale entry that serves\n * until TTL; the warning lets operators react.\n */\nexport function wrapStoreWithCache(\n backing: Store.Instance,\n opts: WrappedStoreOptions,\n): WrappedStoreInstance {\n const { cacheConfig, cacheStore, namespace, logger, storeId, collector } =\n opts;\n\n // Cache observability. Each wrapped `get` resolves to a HIT or MISS;\n // the wrapper emits a `FlowState` on the collector so observers can\n // record cache metadata without coupling to wrapper internals. When\n // `collector` is absent (unit-test path), reporting is skipped.\n const reportCacheStatus = (key: string, status: 'hit' | 'miss'): void => {\n if (!collector) return;\n const state = stepState(collector, `store.${storeId}`, 'store', 'in', '');\n state.meta = {\n op: 'cache',\n cached: status === 'hit',\n status,\n key,\n };\n emitStep(collector, state);\n };\n\n // Closure-scoped counters. Mutated directly at each path; the public\n // `counters` accessor on the returned instance returns a fresh shallow copy\n // so external consumers cannot mutate internal state.\n const counters: WrappedStoreCounters = {\n hits: 0,\n misses: 0,\n populates: 0,\n writes: 0,\n deletes: 0,\n inflight_dedups: 0,\n };\n\n // Pre-compile each rule's matcher once at wrap time. Rules without a `match`\n // clause are treated as always-matching, mirroring the EventCacheRule\n // helpers in `packages/core/src/cache.ts`.\n const compiledRules: CompiledStoreCacheRule[] = cacheConfig.rules.map(\n (rule) => ({\n match: rule.match ? compileMatcher(rule.match) : () => true,\n ttl: rule.ttl,\n }),\n );\n\n const prefixed = (key: string): string => `${namespace}:${key}`;\n\n function findMatchingRule(\n key: string,\n value: Store.StoreValue | undefined,\n ): CompiledStoreCacheRule | undefined {\n // Store-cache context shape is `{ key, value? }` — no `ingest`. The value\n // is omitted when the caller has not yet read from the backing (e.g.\n // future write-path callers).\n const ctx: Record<string, unknown> =\n value === undefined ? { key } : { key, value };\n return compiledRules.find((r) => r.match(ctx));\n }\n\n // Closure-scoped in-flight registry: N concurrent gets on the same cold key\n // share one backing call. Keyed by the namespaced cache key so distinct\n // backing keys never collide. The entry is removed in `finally` so a\n // settled (resolved or rejected) Promise never lingers — a subsequent get\n // either hits the now-populated cache or retries the backing.\n const inFlight = new Map<string, Promise<Store.StoreValue | undefined>>();\n\n return {\n type: backing.type,\n config: backing.config,\n setup: backing.setup,\n\n // Snapshot accessor. Returning a fresh shallow copy on every read keeps\n // the internal counter object un-aliased: consumers that store, diff, or\n // serialize the snapshot cannot inadvertently mutate state.\n get counters(): WrappedStoreCounters {\n return { ...counters };\n },\n\n async get(key: string): Promise<Store.StoreValue | undefined> {\n const ns = prefixed(key);\n const stored = await cacheStore.get(ns);\n const envelope = readCacheEnvelope(stored);\n if (envelope !== undefined) {\n if ('expired' in envelope) {\n // Expired entry: best-effort purge from the cache tier, then fall\n // through to the backing as a MISS. A throwing delete must not\n // surface to the caller; a stale entry serving until the next read\n // is acceptable.\n try {\n await cacheStore.delete(ns);\n } catch (error) {\n warnCacheFailure('delete', key, error);\n }\n } else {\n counters.hits++;\n reportCacheStatus(key, 'hit');\n return envelope.value;\n }\n }\n\n // Single-flight: if another caller is already fetching this key, join\n // their Promise rather than starting a second backing call.\n const existing = inFlight.get(ns);\n if (existing) {\n counters.inflight_dedups++;\n reportCacheStatus(key, 'hit');\n return existing;\n }\n\n // This caller drives the backing fetch — count the MISS once here so\n // joined callers above are not double-counted as misses too.\n counters.misses++;\n reportCacheStatus(key, 'miss');\n\n const promise = (async () => {\n try {\n const value = await backing.get(key);\n if (value === undefined) return undefined;\n\n const rule = findMatchingRule(key, value);\n if (rule) {\n // Best-effort cache populate. Mirrors the write-path\n // policy: backing has already returned, so a throwing cache layer\n // must not surface as an unhandled rejection on the shared\n // Promise that other concurrent callers are awaiting.\n try {\n // `cache.ttl` is documented in seconds; the envelope `exp` and\n // the TTL-native eviction hint both want ms. Multiply once at the\n // boundary to keep the rest of the pipeline consistent with\n // EventCache semantics. Dual-write: the `{value, exp}` envelope\n // is authoritative for expiry (every backing tier honors it),\n // and the `ttl` arg lets a TTL-native tier (`__cache`, Redis)\n // proactively evict.\n const ttlMs = rule.ttl * 1000;\n await cacheStore.set(ns, wrapCacheEnvelope(value, ttlMs), ttlMs);\n // Count the populate only after the cache write resolves so a\n // failed populate (logged below) does not inflate the counter.\n counters.populates++;\n } catch (error) {\n warnCacheFailure('set', key, error);\n }\n }\n return value;\n } finally {\n // Always release the slot — on resolve so the next read hits the\n // now-populated cache, on reject so a transient backing failure\n // doesn't freeze the key forever behind a dead Promise.\n inFlight.delete(ns);\n }\n })();\n inFlight.set(ns, promise);\n return promise;\n },\n\n async set(\n key: string,\n value: Store.StoreValue,\n ttl?: number,\n ): Promise<void> {\n // Count every set the moment the wrapper is entered, before any IO.\n // The counter reflects intent (how many writes the wrapper has been\n // asked to perform), independent of backing or cache success.\n counters.writes++;\n\n // Backing first. A throw here propagates: backing is the source of\n // truth, callers must see real write failures.\n await backing.set(key, value, ttl);\n\n const rule = findMatchingRule(key, value);\n if (!rule) return;\n\n // Best-effort cache populate. Wrap only the cache-side call: backing\n // errors above have already propagated, so this try/catch is scoped to\n // the advisory layer. Same dual-write as the read-path populate: store\n // the `{value, exp}` envelope and pass the `ttl` eviction hint.\n try {\n const ttlMs = rule.ttl * 1000;\n await cacheStore.set(\n prefixed(key),\n wrapCacheEnvelope(value, ttlMs),\n ttlMs,\n );\n } catch (error) {\n warnCacheFailure('set', key, error);\n }\n },\n\n async delete(key: string): Promise<void> {\n // Mirrors `writes`: count intent at entry, before backing or cache IO.\n counters.deletes++;\n\n // Backing first; same propagation rules as `set`.\n await backing.delete(key);\n\n try {\n await cacheStore.delete(prefixed(key));\n } catch (error) {\n warnCacheFailure('delete', key, error);\n }\n },\n };\n\n function warnCacheFailure(\n op: 'set' | 'delete',\n key: string,\n error: unknown,\n ): void {\n const message = `store-cache(${storeId}): cache ${op} failed for \"${key}\"; backing succeeded, continuing`;\n if (logger) {\n logger.warn(message, errorMeta(error));\n } else {\n // Defensive fallback so unit tests that do not thread a logger still\n // surface the failure rather than swallowing it silently. Production\n // call sites in `store.ts` always pass `collector.logger`.\n // eslint-disable-next-line no-console\n console.warn(message, error);\n }\n }\n}\n"],"mappings":"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","names":["collector","import_core","import_core","import_core","collector","stepId","collector","import_core","collector","collector","import_core","clone","import_core","import_core","import_core","collector","import_core","import_core","collector","initTransformers","finished","result","collector","collector","require","collector","on","option","collector","queued","event","isInitialized","cacheMiss","batchState","destIdResolved","destStatus","outcome","import_core","collector","collector","collector","import_core","import_core","import_core","collector","prepareEvent","finished","import_core","collector","collector","import_core","import_core","collector","collector","finished","initStores","collector"]}