@walkeros/collector 4.3.0-next-1784055686454 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/code.ts","../src/constants.ts","../src/consent.ts","../src/collector.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/pending.ts","../src/handle.ts","../src/shutdown.ts","../src/push.ts","../src/command.ts","../src/elb.ts","../src/store.ts","../src/cache-store.ts","../src/store-cache-wrapper.ts","../src/flow.ts"],"sourcesContent":["export * from './types';\n\nexport * from './constants';\n\nexport * from './consent';\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 * from './destination';\nexport * from './handle';\nexport * from './on';\nexport * from './source';\nexport {\n runTransformerChain,\n transformerPush,\n transformerInit,\n walkChain,\n extractTransformerNextMap,\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 { 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 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 // 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 {\n Cache,\n Collector,\n WalkerOS,\n Elb,\n Destination,\n Transformer,\n Ingest,\n Simulation,\n} from '@walkeros/core';\nimport {\n assign,\n buildCacheContext,\n clone,\n compileCache,\n checkCache,\n storeCache,\n createIngest,\n debounce,\n emitStep,\n getId,\n getGrantedConsent,\n getNextSteps,\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 { callDestinationOn } from './on';\nimport {\n runTransformerChain,\n walkChain,\n extractTransformerNextMap,\n extractChainProperty,\n} 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} from './report-error';\nimport { reconcilePending } from './pending';\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 * 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 */\nconst 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 */\nfunction 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 */\nclass 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 */\nfunction 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\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 * Resolves transformer chain for a destination.\n *\n * `getNextSteps` returns the immediate next-step ids for the given Route in\n * the supplied context. `walkChain` then follows static `.next` links from\n * each entry to produce the full ordered chain. The WeakMap inside\n * `getNextSteps` caches the compiled form, so we don't re-compile per event.\n *\n * post-collector destination.before disallows `many` (enforced at the schema\n * layer via `RouteWithoutManySchema`), so we never see more than one id here\n * unless a user passes an explicit string[] chain — in which case we want to\n * treat it as the explicit chain (no further walking).\n *\n * `transformerNextMap` is computed once per `pushToDestinations` call (it depends\n * only on `collector.transformers`) and passed in to avoid rebuilding it for\n * every destination's before and next chain resolution.\n */\nfunction resolveDestinationChain(\n before: Transformer.Route | undefined,\n transformerNextMap: ReturnType<typeof extractTransformerNextMap>,\n ingest?: Ingest,\n): string[] {\n if (!before) return [];\n // Static string[] chains pass through unchanged — they are explicit and\n // suppress `.next` walking. Static single-string starts are walked.\n if (\n Array.isArray(before) &&\n before.every((entry) => typeof entry === 'string')\n ) {\n return walkChain(before, transformerNextMap);\n }\n if (typeof before === 'string') {\n return walkChain(before, transformerNextMap);\n }\n // Conditional shape — resolve per-event, walk single-id result.\n const ids = getNextSteps(before, buildCacheContext(ingest));\n if (ids.length === 0) return [];\n if (ids.length === 1) return walkChain(ids[0], transformerNextMap);\n // Multiple ids from a conditional shape: treat as explicit chain.\n // (destination.before disallows `many`; this path is reached only if a\n // RouteConfig.next resolves to a string[], which is then the user's\n // declared chain.)\n return walkChain(ids, transformerNextMap);\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 const baseConfig = 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 return pushToDestinations(collector, undefined, {}, { [id]: destination });\n}\n\n/**\n * Pushes an event to all or a subset of destinations.\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?: import('@walkeros/core').RespondFn;\n } = {},\n destinations?: Collector.Destinations,\n): Promise<Elb.PushResult> {\n const { allowed, consent, globals, user } = collector;\n\n // Check if collector is allowed to push\n if (!allowed) return createPushResult({ ok: false });\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 // Precompute the transformer next map once per push (shared across all\n // destinations in this batch, used for both before and next chain resolution).\n // Guarded because tests and partially-initialized collectors may pass\n // `transformers` as undefined.\n const transformerNextMap = collector.transformers\n ? extractTransformerNextMap(collector.transformers)\n : {};\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 // Queued events: refresh consent (full replace — stale consent must not persist).\n // User/globals merge happens for all events below in allowedEvents.map.\n let currentQueue = (destination.queuePush || []).map((event) => ({\n ...event,\n 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, 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 // 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 const allowedEvents: WalkerOS.Events = [];\n const skippedEvents = currentQueue.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 allowedEvents.push(queuedEvent); // Add to allowed queue\n return false; // Remove from destination queue\n }\n\n // Emit a skip state for the consent-denied event so observers can\n // see the gate decision per-event.\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\n // Add skipped (consent-denied) events back to the queue.\n // Bounded; FIFO drop-oldest on overflow.\n if (skippedEvents.length > 0) {\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 skipped of skippedEvents) {\n const r = pushBounded(queuePush, skipped, 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 // 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 // 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 // Process the destinations event queue\n let error: unknown;\n let response: unknown;\n if (!destination.dlq) destination.dlq = [];\n\n // Resolve the before chain once per destination batch (the per-event\n // resolution inside getNextSteps is WeakMap-cached, so this is cheap).\n const before = destination.config.before;\n const postChain = resolveDestinationChain(\n before,\n transformerNextMap,\n destIngest,\n );\n\n // Capture the next chain config; resolution happens per-event below.\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 await Promise.all(\n allowedEvents.map(async (event) => {\n // Merge collector state into event (collector as base, event overrides)\n event.globals = assign(globals, event.globals);\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 if (compiledDCache?.stop && dCacheStore) {\n const cacheContext = buildCacheContext(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 processedEvent: WalkerOS.Event | null = event;\n let destRespond = meta.respond;\n if (\n postChain.length > 0 &&\n collector.transformers &&\n Object.keys(collector.transformers).length > 0\n ) {\n const chainResult = await runTransformerChain(\n collector,\n collector.transformers,\n postChain,\n event,\n destIngest,\n meta.respond,\n `destination.${id}.before`,\n );\n\n if (chainResult.event === null) {\n // Chain stopped - skip this event for this destination\n return event;\n }\n\n // Update respond if the chain produced a wrapped one\n if (chainResult.respond) destRespond = chainResult.respond;\n\n // Use the processed event (cast back to full Event type)\n // Before chains use first result if fan-out occurred\n processedEvent = (\n Array.isArray(chainResult.event)\n ? chainResult.event[0]\n : chainResult.event\n ) as WalkerOS.Event;\n }\n\n // Step-level cache check: after before chain, skip only push on HIT\n if (compiledDCache && !compiledDCache.stop && dCacheStore) {\n const cacheContext = buildCacheContext(destIngest, processedEvent);\n const cacheResult = await checkCache(\n compiledDCache,\n dCacheStore,\n cacheContext,\n );\n if (cacheResult?.status === 'HIT') {\n return event; // Skip push — deduplicated\n }\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\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 );\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 error: 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 destIngest,\n destRespond,\n );\n totalDuration += Date.now() - pushStart;\n\n // Destination cache MISS: store the push result after attempt\n if (\n cacheMiss &&\n dCacheStore &&\n destination.config.mock === undefined\n ) {\n storeCache(\n dCacheStore,\n cacheMiss.key,\n result ?? true,\n cacheMiss.ttl,\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 );\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 destIngest._response = result;\n }\n\n const nextChain = resolveDestinationChain(\n nextConfig,\n transformerNextMap,\n destIngest,\n );\n\n if (\n nextChain.length > 0 &&\n collector.transformers &&\n Object.keys(collector.transformers).length > 0\n ) {\n const nextResult = await runTransformerChain(\n collector,\n collector.transformers,\n nextChain,\n processedEvent!,\n destIngest,\n destRespond,\n `destination.${id}.next`,\n );\n if (nextResult.respond) destRespond = nextResult.respond;\n }\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 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 const syncDelivered = Math.max(0, allowedCount - 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\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 // 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 destination.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 configResult; // don't push if init is false\n\n // Update the destination config if it was returned\n destination.config = {\n ...(configResult || destination.config),\n init: true, // Remember that the destination was initialized\n };\n\n // Flush queued on() events now that destination is initialized\n if (destination.queueOn?.length) {\n const queueOn = destination.queueOn;\n destination.queueOn = [];\n\n for (const { type, data } of queueOn) {\n callDestinationOn(collector, destination, destId, type, data);\n }\n }\n\n destLogger.debug('init done');\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 // Representative journey correlation for the batch record. A forwarded\n // batch may aggregate events from distinct upstream traces, so\n // first-entry stamping on the flush/error records is best-effort; the\n // per-event in/out records carry each event's exact trace.\n const {\n traceId: batchTraceId,\n sourceId: batchSourceId,\n parentEventId: batchParentEventId,\n } = journeyFields(rep.event, rep.ingest, collector);\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 const flushState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'flush',\n eventId: '',\n now: flushStarted,\n traceId: batchTraceId,\n sourceId: batchSourceId,\n parentEventId: batchParentEventId,\n });\n flushState.batch = { size: snapshot.entries.length, index: 0 };\n emitStep(collector, flushState);\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 const errFinished = Date.now();\n const batchErrState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'error',\n eventId: '',\n now: errFinished,\n traceId: batchTraceId,\n sourceId: batchSourceId,\n parentEventId: batchParentEventId,\n });\n batchErrState.durationMs = errFinished - flushStarted;\n batchErrState.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n batchErrState.batch = {\n size: snapshot.entries.length,\n index: 0,\n };\n emitStep(collector, batchErrState);\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 const seen = new Set<number>();\n for (const failure of outcome.failed) {\n const entry = snapshot.entries[failure.index];\n if (!entry || seen.has(failure.index)) continue;\n seen.add(failure.index);\n failedPairs.push([\n entry.event,\n failure.error ??\n new Error(\n `Push batch entry ${failure.index} failed (no per-row error provided)`,\n ),\n ]);\n }\n if (failedPairs.length > 0) {\n routeToDlq(failedPairs);\n succeededCount = Math.max(\n 0,\n snapshot.entries.length - failedPairs.length,\n );\n destLogger.error('Push batch partial failure', {\n failed: failedPairs.length,\n delivered: succeededCount,\n entries: snapshot.entries.length,\n });\n }\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","import type { Simulation } from '@walkeros/core';\nimport { parseCallPath } from '@walkeros/core';\n\n/**\n * True for any non-null object, arrays included, narrowing to an index-readable\n * record. Arrays must count: `window.dataLayer.push` navigates through an array\n * to reach its method. (`isObject` from core rejects arrays, so it can't gate\n * intermediate navigation here.)\n */\nfunction isNavigable(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\ninterface WrapResult {\n /** Env with tracked paths wrapped by recording functions */\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 this env could not wrap: a missing or\n * non-object root/intermediate, an absent/non-function leaf, or a parent\n * beyond the clone cap (wrapping there would mutate the caller's env). Each\n * entry is the post-`call:` stripped dot-path (what the recorder records as\n * `fn`) — this list feeds `EnvObserve.paths` directly, so malformed paths\n * (`parseCallPath` returned `[]`) are skipped entirely: the shared grammar\n * makes them unresolvable for the fallback wrapper too. A path that\n * navigates part-way then stops belongs here, never wrapped at a wrong level.\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 * Tracked simulation dot-paths must resolve within this depth so recorders\n * are installed on cloned parents and never mutate the caller's env.\n */\nconst CLONE_MAX_DEPTH = 8;\n\n/**\n * Visit-once structural clone. The memo maps each source object to its single\n * clone, so cycles terminate and shared references stay shared (the clone\n * preserves the object graph's shape). Functions are kept by reference.\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) 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 as Record<string, unknown>)) {\n clone[key] =\n typeof value === 'function' ? value : deepClone(value, memo, depth + 1);\n }\n return clone;\n}\n\n/**\n * Wrap tracked paths in a destination env with recording wrappers.\n *\n * The env object must include a `simulation: string[]` declaring which\n * dot-paths to intercept. Returns a cloned env (without `simulation`)\n * where those paths record every call into the `calls` array.\n */\nexport function wrapEnv(\n env: Record<string, unknown> & { simulation: string[] },\n): WrapResult {\n const calls: Simulation.Call[] = [];\n const unresolved: string[] = [];\n const { simulation, ...rest } = env;\n\n // Deep clone the env to avoid mutating the original (preserves functions)\n const wrappedEnv = deepClone(\n rest,\n new WeakMap<object, unknown>(),\n 0,\n ) as Record<string, unknown>;\n\n for (const rawPath of simulation) {\n // `parseCallPath` owns the split grammar (shared with getEnv): strips a\n // single `call:` prefix, splits on `.`, rejects empty segments as `[]`.\n const segments = parseCallPath(rawPath);\n if (segments.length === 0) {\n // Malformed: the fallback wrapper shares this grammar, so the path can\n // never resolve anywhere — skip it, keeping `unresolved` well-formed.\n continue;\n }\n\n // Post-`call:` display form derived from the shared segments, so no local\n // strip literal can drift from `parseCallPath`.\n const path = segments.join('.');\n\n // A parent at or beyond the clone cap is an ORIGINAL reference (see\n // deepClone); installing a wrapper there would permanently mutate the\n // caller's env. The recorder fallback handles such paths instead.\n if (segments.length - 1 >= CLONE_MAX_DEPTH) {\n unresolved.push(path);\n continue;\n }\n\n // Navigate to the parent. Every intermediate must resolve to an object;\n // stopping short sends the whole path to `unresolved` rather than wrapping\n // a same-named leaf at the wrong level.\n let target: Record<string, unknown> = wrappedEnv;\n let resolved = true;\n for (let i = 0; i < segments.length - 1; i++) {\n const next = target[segments[i]];\n if (!isNavigable(next)) {\n resolved = false;\n break;\n }\n target = next;\n }\n\n const leaf = segments[segments.length - 1];\n if (!resolved || !(leaf in target)) {\n unresolved.push(path);\n continue;\n }\n\n const original = target[leaf];\n if (typeof original !== 'function') {\n unresolved.push(path);\n continue;\n }\n\n target[leaf] = function (this: unknown, ...args: unknown[]) {\n calls.push({ fn: path, args, ts: Date.now() });\n return original.apply(this, args);\n };\n }\n\n return { wrappedEnv, calls, unresolved };\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} from '@walkeros/core';\nimport { isArray, FatalError } from '@walkeros/core';\nimport { Const } from './constants';\nimport { tryCatch, tryCatchAsync } from '@walkeros/core';\nimport { mergeEnvironments } from './destination';\nimport { buildReportError } from './report-error';\nimport { reconcilePending } from './pending';\nimport { flushSourceQueueOn, isSourceStarted } from './source';\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 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 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 * and return a teardown that clears it. Nested commands emitted by reacting\n * callbacks find `collector.cascade` already set and reuse it (teardown is a\n * no-op for them), so the counters are scoped to the originating command and\n * reset when it returns. 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 if (collector.cascade) return () => undefined;\n collector.cascade = { counts: new WeakMap() };\n return () => {\n collector.cascade = undefined;\n };\n}\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.\n * Used by both onApply() for immediate calls and destinationInit() for flushing queued events.\n */\nexport function callDestinationOn(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n type: On.Types,\n data: unknown,\n) {\n if (!destination.on) return;\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: data 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 tryCatch(destination.on, (err) =>\n logOnCallbackError(collector, 'destination', err, { destId, type }),\n )(type, context);\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 const result = await tryCatchAsync(source.on, (err) =>\n logOnCallbackError(collector, 'source', err, { sourceId, type }),\n )(type, contextData);\n\n if (isStateDelivery(type)) setMark(collector, source, type);\n\n return result === false;\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` and the\n * gated `source.on` loop via `deliverStateToSource`. 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 // 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 void return. 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 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' on handlers via the gated helper.\n for (const [sourceId, source] of Object.entries(collector.sources)) {\n if (!isSourceStarted(source)) continue;\n await deliverStateToSource(\n collector,\n source,\n sourceId,\n type,\n contextData,\n );\n }\n }\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 // 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 true;\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 let vetoed = false;\n // Per-source require decrement + gated on() delivery.\n // Sources are not \"started\" until config.init === true AND config.require is empty.\n // Unstarted sources have their on() events queued in instance.queueOn\n // and replayed once they start.\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 const sourceVetoed = await deliverStateToSource(\n collector,\n source,\n sourceId,\n type,\n contextData,\n );\n if (sourceVetoed) vetoed = true;\n } else {\n source.queueOn = source.queueOn || [];\n source.queueOn.push({ type, data: contextData });\n }\n }\n\n Object.entries(collector.destinations).forEach(([destId, destination]) => {\n if (destination.on) {\n // Queue if destination not yet initialized\n if (!destination.config.init) {\n destination.queueOn = destination.queueOn || [];\n destination.queueOn.push({ type, data: contextData });\n return;\n }\n callDestinationOn(collector, destination, destId, type, contextData);\n }\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 !vetoed;\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 * 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 error: err instanceof Error ? err.message : String(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', {\n error: err instanceof Error ? err.message : String(err),\n });\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 WalkerOS,\n} from '@walkeros/core';\nimport type { RespondFn, RespondOptions } from '@walkeros/core';\nimport {\n createIngest,\n FatalError,\n getMappingValue,\n parseTraceparent,\n tryCatchAsync,\n getNextSteps,\n compileCache,\n checkCache,\n storeCache,\n applyUpdate,\n buildCacheContext,\n compileState,\n applyState,\n} from '@walkeros/core';\nimport {\n walkChain,\n extractTransformerNextMap,\n runTransformerChain,\n cloneIngest,\n} from './transformer';\nimport { buildReportError } from './report-error';\nimport { isStateDelivery, shouldDeliver, setMark } from './on';\nimport { reconcilePending } from './pending';\n\n/**\n * A Route is \"static\" when it's a transformer-ID string or an array of\n * transformer-ID strings. Static routes can be resolved once at init and\n * walked synchronously; conditional shapes (RouteConfig, mixed arrays)\n * depend on per-event context and resolve via getNextSteps at dispatch.\n */\nfunction isStaticRoute(\n route: import('@walkeros/core').Transformer.Route | undefined,\n): route is string | string[] {\n if (typeof route === 'string') return true;\n if (\n Array.isArray(route) &&\n route.every((entry) => typeof entry === 'string')\n ) {\n return true;\n }\n return false;\n}\nimport { getCacheStore, getStateStore } from './cache';\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.\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 await tryCatchAsync(source.on, (err: unknown): undefined => {\n if (err instanceof FatalError) throw err;\n collector.status.failed++;\n collector.logger.scope('source').error('source on flush failed', {\n sourceId: id,\n type,\n error: err,\n });\n return undefined;\n })(type, data);\n\n if (isStateDelivery(type)) 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// Intentionally looser than core's isObject, which rejects non-plain objects\n// like Fetch Headers instances ('[object Headers]') that must pass here.\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction hasHeaderGetter(\n headers: Record<string, unknown>,\n): headers is { get: (name: string) => unknown } {\n return 'get' in headers && typeof headers.get === 'function';\n}\n\n/**\n * Read a `traceparent` header value from a raw source scope input, if any.\n * Supports a Fetch `Headers` instance (via its `.get` accessor) and a plain\n * object header bag (direct `traceparent` key first, then a case-insensitive\n * fallback since raw Node/GCP requests may not lowercase header keys). Any\n * other shape yields undefined. Never throws on exotic inputs.\n */\nfunction readTraceparentHeader(rawScope: unknown): unknown {\n if (!isRecord(rawScope)) return undefined;\n const headers = rawScope.headers;\n if (!isRecord(headers)) return undefined;\n\n if (hasHeaderGetter(headers)) return headers.get('traceparent') ?? undefined;\n\n if ('traceparent' in headers) return headers.traceparent;\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === 'traceparent') return headers[key];\n }\n return undefined;\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 } = 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 // Resolve transformer chain for this source.\n // Static (string / string[]) chains pre-walk at init (optimization).\n // Conditional shapes (case / gate) require per-request context — see wrappedPush.\n const staticPreChain = isStaticRoute(next)\n ? walkChain(next, extractTransformerNextMap(collector.transformers))\n : undefined;\n\n // Resolve before chain for this source (consent-exempt, pre-source preprocessing).\n const staticBeforeChain = isStaticRoute(before)\n ? walkChain(before, extractTransformerNextMap(collector.transformers))\n : undefined;\n\n // Terminal push: where the source pipeline ends. Defaults to\n // `collector.push`. Tests (and rare advanced consumers) may override by\n // passing `push` in the source's `env`; in that case the override\n // replaces the collector and receives the raw event with no pipeline\n // options. Per-scope ingest/respond is invisible to overriders by\n // design: overriders are responsible for their own pipeline shape.\n const userTerminalPush = (env as { push?: Collector.PushFn }).push;\n const terminalPush: Collector.PushFn = userTerminalPush ?? collector.push;\n const hasUserTerminalPush = Boolean(userTerminalPush);\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 let pendingRespond: Promise<void> | undefined;\n\n // Resolve before chain (static or conditional).\n // Single-id results walk static `.next` links; multi-id results are\n // explicit chains (fan-out from `many` is handled by the engine).\n const beforeChain =\n staticBeforeChain ??\n (before !== undefined\n ? (() => {\n const ids = getNextSteps(before, buildCacheContext(scope.ingest));\n if (ids.length === 0) return [];\n const start = ids.length === 1 ? ids[0] : ids;\n return walkChain(\n start,\n extractTransformerNextMap(collector.transformers),\n );\n })()\n : []);\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 events: WalkerOS.DeepPartialEvent[] = [rawEvent];\n\n // Run source.before chain (consent-exempt, pre-source preprocessing)\n if (\n beforeChain.length > 0 &&\n collector.transformers &&\n Object.keys(collector.transformers).length > 0\n ) {\n const beforeResult = await runTransformerChain(\n collector,\n collector.transformers,\n beforeChain,\n rawEvent,\n scope.ingest,\n scope.respond,\n `source.${sourceId}.before`,\n );\n if (beforeResult.event === null) {\n return { ok: true } as Elb.PushResult;\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 events = Array.isArray(beforeResult.event)\n ? beforeResult.event\n : [beforeResult.event];\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 = buildCacheContext(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 // Resolve chain: static (pre-computed) or conditional (per-event).\n // Three dispatch shapes from `getNextSteps`:\n // - [] → no route matched; passthrough to collector with no\n // pre-chain.\n // - ['x'] → walk static `.next` links from x and run as a single\n // sequential subchain inside `collector.push`.\n // - ['a','b',…] → `many` fan-out. Each id is an INDEPENDENT terminal\n // subchain dispatched via its own `collector.push` call\n // with a per-branch cloned ingest and `respond` cleared\n // (no-respond-across-many doctrine). Error isolation\n // per branch via tryCatchAsync.\n //\n // Note: a plain `next: ['a','b','c']` is `isStaticRoute` → pre-walked\n // by `staticPreChain` as the legacy explicit sequential chain. Only\n // `{ many: [...] }` reaches the multi-id branch here.\n type Dispatch =\n | { kind: 'single'; preChain: string[] }\n | { kind: 'many'; branches: string[][] };\n\n const dispatch: Dispatch = staticPreChain\n ? { kind: 'single', preChain: staticPreChain }\n : next !== undefined\n ? (() => {\n const ids = getNextSteps(next, buildCacheContext(scope.ingest));\n if (ids.length === 0)\n return { kind: 'single', preChain: [] } as Dispatch;\n if (ids.length === 1)\n return {\n kind: 'single',\n preChain: walkChain(\n ids[0],\n extractTransformerNextMap(collector.transformers),\n ),\n } as Dispatch;\n return {\n kind: 'many',\n branches: ids.map((id) =>\n walkChain(\n id,\n extractTransformerNextMap(collector.transformers),\n ),\n ),\n } as Dispatch;\n })()\n : ({ kind: 'single', preChain: [] } as Dispatch);\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 // A user `env.push` override receives the raw event with no pipeline\n // (see the terminal-push contract above), so state is skipped for it.\n if (!hasUserTerminalPush && stateEntries && stateEntries.length > 0) {\n events = await Promise.all(\n events.map((event) =>\n applyState(\n stateEntries,\n (id) => getStateStore(id, collector),\n event,\n collector,\n ),\n ),\n );\n }\n\n // Push each event independently through the post-before pipeline.\n // For non-fan-out (single event) this is a one-iteration loop and\n // behaves exactly like the previous implementation.\n let pushResult: Elb.PushResult = { ok: true } as Elb.PushResult;\n for (const event of events) {\n if (dispatch.kind === 'many') {\n // `many` fan-out: each branch is an independent terminal flow.\n // Per-branch ingest clone, no respond propagation, error isolation\n // via tryCatchAsync. Branch results are awaited and discarded;\n // scope.respond is NOT updated from any branch.\n await Promise.all(\n dispatch.branches.map((branchChain, idx) =>\n tryCatchAsync(\n async () =>\n hasUserTerminalPush\n ? terminalPush(event)\n : terminalPush(event, {\n ...options,\n id: sourceId,\n ingest: cloneIngest(scope.ingest, `${sourceId}.${idx}`),\n respond: undefined,\n mapping: config,\n preChain: branchChain,\n }),\n (err) => {\n collector.logger\n .scope('source:many')\n .error(`many branch ${idx} failed`, { error: err });\n return { ok: true } as Elb.PushResult;\n },\n )(),\n ),\n );\n // `many` is fan-out, not enrichment — surface a generic OK.\n pushResult = { ok: true } as Elb.PushResult;\n } else if (hasUserTerminalPush) {\n // User override: bypass the pipeline, deliver raw events. This\n // preserves the `env.push: mockPush` test spy pattern.\n pushResult = await terminalPush(event);\n } else {\n pushResult = await terminalPush(event, {\n ...options,\n id: sourceId,\n ingest: scope.ingest,\n respond: scope.respond,\n mapping: config,\n preChain: dispatch.preChain,\n });\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 (rawScope: unknown): Promise<Ingest> => {\n const fresh = createIngest(sourceId);\n // Adopt an inbound W3C traceparent from the raw scope's header bag so\n // every server source gains trace continuity + parent-span linkage. The\n // final return reuses `fresh._meta` by reference, so stamping here holds\n // for both the mapped and unmapped paths.\n const traceparent = parseTraceparent(readTraceparentHeader(rawScope));\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 // Build cleanEnv. User-supplied env can override every field; we\n // immediately overwrite `push` with the source-pipeline `wrappedPush`.\n // Any user-supplied `env.push` was captured above as `terminalPush`\n // (the pipeline's terminus, not the source's outward-facing push).\n const cleanEnv: Source.Env = {\n command: collector.command,\n sources: collector.sources,\n elb: collector.elb,\n logger: initialLogger,\n ...env,\n push: wrappedPush,\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 error: 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 error: 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 Chain Utilities\n * ==========================\n *\n * This module provides the unified implementation for transformer chains in walkerOS.\n * Chains are used at two points in the data flow:\n *\n * 1. Pre-collector chains (source.next):\n * Source → [Transformer Chain] → Collector\n * Events are processed before the collector sees them.\n *\n * 2. Post-collector chains (destination.before):\n * Collector → [Transformer Chain] → Destination\n * Events are processed before reaching specific destinations.\n *\n * Key Functions:\n * - extractTransformerNextMap(): Extracts next links from transformer instances\n * - extractChainProperty(): Unified extraction of chain properties from definitions\n * - walkChain(): Resolves chain IDs from starting point\n * - runTransformerChain(): Executes a chain of transformers on an event\n *\n * Chain Resolution:\n * - String start: Walk transformer.next links until chain ends\n * - Array start: Use array directly (explicit chain, ignores transformer.next)\n *\n * Chain Termination:\n * - Transformer returns false → chain stops, event is dropped\n * - Transformer throws error → chain stops, event is dropped\n * - Transformer returns void → continue with unchanged event\n * - Transformer returns event → continue with modified event\n */\nimport type {\n Cache,\n Collector,\n Transformer,\n WalkerOS,\n Ingest,\n} from '@walkeros/core';\nimport {\n createIngest,\n emitStep,\n FatalError,\n isObject,\n stepId,\n tryCatchAsync,\n useHooks,\n getNextSteps,\n compileCache,\n checkCache,\n storeCache,\n buildCacheContext,\n validateStepEntry,\n processEventMapping,\n compileState,\n applyState,\n} from '@walkeros/core';\nimport { buildBaseState, journeyFields } from './observerEmit';\nimport { getCacheStore, getStateStore } from './cache';\nimport { buildReportError } from './report-error';\n\n/**\n * Extracts transformer next configuration for chain walking.\n * Maps transformer instances to their config.next values.\n *\n * This is the single source of truth for extracting chain links.\n * Used by both source.ts (pre-collector chains) and destination.ts (post-collector chains).\n *\n * @param transformers - Map of transformer instances\n * @returns Map of transformer IDs to their next configuration\n */\nexport function extractTransformerNextMap(\n transformers: Transformer.Transformers,\n): Record<string, { next?: string | string[] }> {\n const result: Record<string, { next?: string | string[] }> = {};\n for (const [id, transformer] of Object.entries(transformers)) {\n const next = transformer.config?.next;\n // Static shapes are recorded for synchronous chain walking.\n // Conditional shapes (RouteConfig, mixed arrays) resolve per-event via\n // getNextSteps at dispatch time; they get an empty entry here so the\n // chain walker stops at this hop rather than following a stale link.\n if (typeof next === 'string') {\n result[id] = { next };\n } else if (\n Array.isArray(next) &&\n next.every((entry) => typeof entry === 'string')\n ) {\n result[id] = { next: next as string[] };\n } else {\n result[id] = {};\n }\n }\n return result;\n}\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 * Walks a transformer chain starting from a given transformer ID.\n * Returns ordered array of transformer IDs in the chain.\n *\n * Used for on-demand chain resolution:\n * - Called from destination.ts with destination.config.before\n * - Called from source.ts with source.config.next\n *\n * @param startId - First transformer in chain, or explicit array of transformer IDs\n * @param transformers - Available transformer configs with optional `next` field\n * @returns Ordered array of transformer IDs to execute\n *\n * @example\n * // Single transformer\n * walkChain('redact', { redact: {} }) // ['redact']\n *\n * @example\n * // Chain via next\n * walkChain('a', { a: { next: 'b' }, b: { next: 'c' }, c: {} }) // ['a', 'b', 'c']\n *\n * @example\n * // Explicit array\n * walkChain(['x', 'y'], {}) // ['x', 'y']\n */\nexport function walkChain(\n startId: string | string[] | undefined,\n transformers: Record<string, { next?: string | string[] }> = {},\n): string[] {\n if (!startId) return [];\n\n // If array provided, use it directly (explicit chain)\n if (Array.isArray(startId)) {\n return startId;\n }\n\n // Walk the chain via transformer.next links\n const chain: string[] = [];\n const visited = new Set<string>();\n let current: string | undefined = startId;\n\n while (current && transformers[current]) {\n if (visited.has(current)) {\n // Circular reference detected - stop walking\n break;\n }\n visited.add(current);\n chain.push(current);\n\n const next: string | string[] | undefined = transformers[current].next;\n\n // If transformer has array next, append it and stop walking\n if (Array.isArray(next)) {\n chain.push(...next);\n break;\n }\n\n current = next;\n }\n\n return chain;\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 branch (e.g. a `many` fan-out branch).\n *\n * Each branch needs its own `_meta.path` so cycle protection and the\n * MAX_PATH_LENGTH safety valve operate per-branch rather than colliding\n * across sibling forks. The top-level object and `_meta` are shallow-copied;\n * `_meta.path` is duplicated so appends in one branch do not leak into others.\n *\n * `branchId` is reserved for future per-branch labelling (Task 4.1) and is\n * not currently written into `_meta`; it is accepted now so callers don't\n * need to change their call sites when error-isolation lands.\n */\nexport function cloneIngest(\n ingest: Ingest | undefined,\n branchId: string,\n): Ingest {\n if (!ingest) return createIngest(branchId);\n return {\n ...ingest,\n _meta: { ...ingest._meta, path: [...ingest._meta.path] },\n };\n}\n\n/**\n * Runs an event through a chain of transformers.\n *\n * @param collector - The collector instance with transformers\n * @param transformers - Map of transformer instances\n * @param chain - Ordered array of transformer IDs to execute\n * @param event - The event to process\n * @param ingest - Mutable ingest context flowing through the pipeline\n * @returns The processed event or null if chain was stopped\n */\nexport async function runTransformerChain(\n collector: Collector.Instance,\n transformers: Transformer.Transformers,\n chain: string[],\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n respond?: import('@walkeros/core').RespondFn,\n chainContext?: string,\n): Promise<Transformer.ChainResult> {\n const MAX_PATH_LENGTH = 256;\n\n // Ensure an ingest exists so the per-branch path budget engages\n // regardless of caller. Production callers (source/push/destination)\n // always pass one; this guards direct test invocations and any future\n // entrypoint that omits it. Without an ingest, the safety valve below\n // can never trip — leaving cyclic `many` graphs unbounded.\n if (!ingest) {\n ingest = createIngest(chain[0] ?? 'chain');\n }\n\n if (chainContext && ingest._meta) {\n ingest._meta.chainPath = chainContext;\n }\n\n let processedEvent = event;\n let currentRespond = respond;\n\n for (const transformerName of chain) {\n const transformer = transformers[transformerName];\n if (!transformer) {\n collector.logger.warn(`Transformer not found: ${transformerName}`);\n continue;\n }\n\n // Safety valve: prevent unbounded path growth\n if (ingest && ingest._meta && ingest._meta.path.length > MAX_PATH_LENGTH) {\n collector.logger.error(`Max path length exceeded at ${transformerName}`);\n return { event: null, respond: currentRespond };\n }\n\n // Track step in _meta (runtime-managed)\n if (ingest && ingest._meta) {\n ingest._meta.hops++;\n ingest._meta.path.push(transformerName);\n }\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 // (handled by the destination's own log; counter remains untouched on\n // the deliberate-false path).\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 error: err,\n });\n return false;\n },\n )(collector, transformer, transformerName);\n\n if (!isInitialized) {\n // Stop chain on init failure. Thrown cases were already logged with\n // full cause via the onError above; deliberate-false returns leave\n // the chain stop signal intact without extra noise.\n return { event: null, respond: currentRespond };\n }\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 continue;\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 continue;\n }\n\n // Disabled check\n if (transformer.config?.disabled) {\n continue;\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\n ? compileCache(tCacheConfig)\n : undefined;\n const tCacheStore = compiledTCache\n ? getCacheStore(compiledTCache, collector)\n : undefined;\n\n // Compile declarative state entries once. `get` runs before the step's\n // mapping (so the mapping can read fetched values); `set` runs after the\n // mapping settles `processedEvent` and before the `next` dispatch.\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 // Apply `state[set]` to a settled event right before it is routed. Called\n // once per emitted event on every emitting path (straight-through,\n // runtime `{ next }` single/many, conditional `config.next`, and per fork\n // of a `Result[]` fan-out). Not called on halted paths (push returned\n // `false`, a `cache.stop` HIT, a stopped before-chain, init failure).\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 );\n };\n\n // Check transformer cache (step-level: skip push, continue chain)\n let cacheMiss: { key: string; ttl: number } | undefined;\n if (compiledTCache && tCacheStore) {\n const cacheContext = buildCacheContext(ingest, processedEvent);\n const cacheResult = await checkCache(\n compiledTCache,\n tCacheStore,\n cacheContext,\n );\n\n if (cacheResult?.status === 'HIT' && cacheResult.value) {\n processedEvent = cacheResult.value as WalkerOS.DeepPartialEvent;\n if (compiledTCache.stop)\n // stop=true → stop chain AND halt pipeline at this position.\n // Caller branches on `stopped` to skip downstream stages\n // (collector.push, destinations); see push.ts and source.ts.\n return {\n event: processedEvent,\n respond: currentRespond,\n stopped: true,\n };\n continue; // stop=false → next transformer\n }\n\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\n }\n }\n\n // Run transformer.before chain if configured.\n //\n // Dispatch uses `getNextSteps`:\n // - [] → no route matched; skip the before chain (passthrough).\n // - ['x'] → sequential continuation; walk static .next links from x\n // and run as a single subchain. Preserves cache.stop and\n // null/respond propagation from the nested chain.\n // - ['a','b',...] → `many` fan-out. Each branch is an independent\n // terminal subchain with a cloned ingest (per-branch\n // cycle protection). No merge: many is fan-out, not\n // enrichment, so parent processedEvent is unchanged.\n // Per-branch error isolation lands in Task 4.1;\n // respond suppression lands in Task 4.2.\n const transformerBefore = transformer.config.before;\n if (transformerBefore) {\n const beforeIds = getNextSteps(\n transformerBefore,\n buildCacheContext(ingest, processedEvent),\n );\n if (beforeIds.length === 1) {\n const beforeChainIds = walkChain(\n beforeIds[0],\n extractTransformerNextMap(transformers),\n );\n if (beforeChainIds.length > 0) {\n const beforeResult = await runTransformerChain(\n collector,\n transformers,\n beforeChainIds,\n processedEvent,\n ingest,\n currentRespond,\n chainContext,\n );\n if (beforeResult.event === null)\n return {\n event: null,\n respond: beforeResult.respond ?? currentRespond,\n }; // Before chain stopped\n // Propagate pipeline-halt from a nested `cache.stop: true` HIT in\n // the before chain. The outer caller (push.ts / source.ts) drops\n // the event before destinations see it.\n if (beforeResult.stopped) {\n return {\n event: Array.isArray(beforeResult.event)\n ? beforeResult.event[0]\n : beforeResult.event,\n respond: beforeResult.respond ?? currentRespond,\n stopped: true,\n };\n }\n if (beforeResult.respond) currentRespond = beforeResult.respond;\n // Before chains use first result if fan-out occurred\n processedEvent = Array.isArray(beforeResult.event)\n ? beforeResult.event[0]\n : beforeResult.event;\n }\n } else if (beforeIds.length > 1) {\n // many: independent terminal subchains. Each branch walks to its own\n // exit with a per-branch ingest clone. Per-branch error isolation\n // (Task 4.1): wrap each branch dispatch in `tryCatchAsync` so a\n // throw in one branch (init failure, unforeseen runtime error) does\n // not reject the surrounding `Promise.all` and starve siblings.\n // No-respond-across-many: respond ownership cannot be unambiguously\n // assigned when one inbound request fans out to N terminal flows.\n // Branch dispatch passes `undefined` instead of `currentRespond`, and\n // branch results are awaited and discarded — currentRespond is NOT\n // updated from any branch's wrapped respond.\n await Promise.all(\n beforeIds.map((id) =>\n tryCatchAsync(runTransformerChain, (err) => {\n collector.logger\n .scope('transformer:many')\n .error(`many branch ${id} failed`, { error: err });\n return { event: null, respond: undefined };\n })(\n collector,\n transformers,\n walkChain(id, extractTransformerNextMap(transformers)),\n processedEvent,\n cloneIngest(ingest, id),\n undefined,\n chainContext,\n ),\n ),\n );\n // No merge: many is fan-out, not enrichment. Parent processedEvent\n // unchanged.\n }\n }\n\n // state[get]: read from the store and write fetched values onto the event\n // before the transformer's mapping runs.\n if (stateGet && stateGet.length > 0) {\n processedEvent = await applyState(\n stateGet,\n (id) => getStateStore(id, collector),\n processedEvent,\n collector,\n );\n }\n\n // Run the transformer\n const result = await tryCatchAsync(transformerPush, (err) => {\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .error('Push failed', { error: 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 // Handle result\n if (result === false) {\n // Transformer explicitly stopped the chain\n return { event: null, respond: currentRespond };\n }\n\n // Handle Result array (fan-out) — MUST be before typeof === 'object'\n if (Array.isArray(result)) {\n const remainingChain = chain.slice(chain.indexOf(transformerName) + 1);\n\n const forkResults = await Promise.all(\n result.map(async (forkResult) => {\n const forkEvent = await applyStateSet(\n forkResult.event || processedEvent,\n );\n // Clone ingest per fork to prevent cross-fork contamination\n const forkIngest = cloneIngest(ingest, 'unknown');\n\n if (forkResult.next) {\n // Fork has explicit routing. Dispatch uses `getNextSteps`:\n // - [] → no route matched; passthrough this fork's\n // event without entering any subchain (fork\n // has explicit routing, so we do NOT fall\n // through to remainingChain).\n // - ['x'] → walk static .next from x and run that as a\n // single subchain. Preserves the existing\n // \"fork has explicit routing terminates the\n // main chain at this branch\" semantic — the\n // subchain's ChainResult is this fork's\n // result.\n // - ['a','b',...] → `many` fan-out. Each id dispatches as its\n // own terminal subchain with a per-branch\n // cloned ingest. Returns an array of\n // ChainResults; the outer `.flat()` in the\n // aggregation loop folds them into the\n // surrounding flatEvents collection.\n const forkIds = getNextSteps(\n forkResult.next,\n buildCacheContext(forkIngest, forkEvent),\n );\n if (forkIds.length === 0) {\n return { event: forkEvent, respond: currentRespond };\n }\n if (forkIds.length === 1) {\n const branchedChain = walkChain(\n forkIds[0],\n extractTransformerNextMap(transformers),\n );\n if (branchedChain.length > 0) {\n return runTransformerChain(\n collector,\n transformers,\n branchedChain,\n forkEvent,\n forkIngest,\n currentRespond,\n chainContext,\n );\n }\n return { event: forkEvent, respond: currentRespond };\n }\n // Terminal fan-out. Each branch walks to its own exit with a\n // per-branch ingest clone. Per-branch error isolation\n // (Task 4.1): wrap each branch dispatch in `tryCatchAsync` so a\n // throw in one branch does not reject the surrounding\n // `Promise.all` and starve siblings.\n // No-respond-across-many: respond ownership cannot be unambiguously\n // assigned when one inbound request fans out to N terminal flows.\n // Branches are dispatched with `respond: undefined`, and the\n // ChainResults returned to the outer aggregation are stripped of\n // any branch-internal respond so the outer fork's combined result\n // never propagates a branch's wrapped respond back to the caller.\n const branchResults = await Promise.all(\n forkIds.map((id) =>\n tryCatchAsync(runTransformerChain, (err) => {\n collector.logger\n .scope('transformer:many')\n .error(`many branch ${id} failed`, { error: err });\n return { event: null, respond: undefined };\n })(\n collector,\n transformers,\n walkChain(id, extractTransformerNextMap(transformers)),\n forkEvent,\n cloneIngest(forkIngest, id),\n undefined,\n chainContext,\n ),\n ),\n );\n // Strip per-branch side-channels (respond, stopped) at the many\n // boundary. The outer aggregation only learns about events from\n // branch ChainResults; respond and stopped are branch-internal\n // concerns and must not leak back to the surrounding fork's\n // combined result.\n return branchResults.map(\n (br): Transformer.ChainResult => ({\n event: br.event,\n respond: undefined,\n }),\n );\n }\n\n // Fork continues through remaining chain\n if (remainingChain.length > 0) {\n return runTransformerChain(\n collector,\n transformers,\n remainingChain,\n forkEvent,\n forkIngest,\n currentRespond,\n chainContext,\n );\n }\n return { event: forkEvent, respond: currentRespond };\n }),\n );\n\n // Collect events from ChainResult objects and track last respond\n let lastForkRespond = currentRespond;\n const flatEvents: WalkerOS.DeepPartialEvent[] = [];\n for (const fr of forkResults.flat()) {\n if (fr === null) continue;\n if (fr && typeof fr === 'object' && 'event' in fr) {\n const cr = fr as Transformer.ChainResult;\n if (cr.respond) lastForkRespond = cr.respond;\n if (cr.event === null) continue;\n if (Array.isArray(cr.event)) flatEvents.push(...cr.event);\n else flatEvents.push(cr.event);\n } else {\n flatEvents.push(fr as WalkerOS.DeepPartialEvent);\n }\n }\n if (flatEvents.length === 0)\n return { event: null, respond: lastForkRespond };\n if (flatEvents.length === 1)\n return { event: flatEvents[0], respond: lastForkRespond };\n return { event: flatEvents, respond: lastForkRespond };\n }\n\n if (result && typeof result === 'object') {\n // Unified TransformerResult handling\n const { event: resultEvent, respond: resultRespond, next } = result;\n\n // Update respond if transformer provided a wrapper\n if (resultRespond) {\n currentRespond = resultRespond;\n }\n\n // Handle chain branching.\n //\n // Dispatch uses `getNextSteps`:\n // - [] → no route matched; passthrough (continue main chain\n // with resultEvent if provided).\n // - ['x'] → walk static .next from x and run that as a single\n // subchain. The branched subchain's ChainResult\n // becomes this transformer's final result; the main\n // chain terminates here (explicit routing wins).\n // - ['a','b',...] → `many` fan-out. Terminal: each branch dispatches\n // as its own subchain with a per-branch ingest\n // clone. Main chain terminates here. Per-branch\n // error isolation arrives in Task 4.1; respond\n // suppression in 4.2.\n if (next !== undefined) {\n // Apply `state[set]` to the settled event before this step's `next`\n // dispatch, once for every branch that emits it.\n const settledEvent = await applyStateSet(resultEvent || processedEvent);\n const nextIds = getNextSteps(\n next,\n buildCacheContext(ingest, settledEvent),\n );\n if (nextIds.length === 0) {\n // No route matched → passthrough (continue chain)\n processedEvent = settledEvent;\n continue;\n }\n if (nextIds.length === 1) {\n const branchedChain = walkChain(\n nextIds[0],\n extractTransformerNextMap(transformers),\n );\n if (branchedChain.length > 0) {\n return runTransformerChain(\n collector,\n transformers,\n branchedChain,\n settledEvent,\n ingest,\n currentRespond,\n chainContext,\n );\n }\n // Branch target not found — drop event (fail-safe).\n collector.logger.warn(\n `Branch target not found: ${JSON.stringify(next)}`,\n );\n return { event: null, respond: currentRespond };\n }\n // many: terminal fan-out. Main chain terminates here. Per-branch\n // error isolation (Task 4.1): wrap each branch dispatch in\n // `tryCatchAsync` so a throw in one branch does not reject the\n // surrounding `Promise.all` and starve siblings.\n // No-respond-across-many: respond ownership cannot be unambiguously\n // assigned when one inbound request fans out to N terminal flows.\n // Branches are dispatched with `respond: undefined`, branch results\n // are awaited and discarded, and the outer return has\n // `respond: undefined` so the parent caller (source) sees no\n // wrapped respond.\n // No-stopped-across-many (Task 4.2 / regression-guarded by Task 4.3):\n // branch results — including any `stopped: true` from a nested\n // `cache.stop` HIT inside one branch — are discarded here. The outer\n // return omits `stopped`, so a cache.stop HIT in one branch does NOT\n // halt sibling branches. See the regression test\n // `transformer.test.ts > many: cache.stop in one branch does not\n // halt sibling branches`.\n await Promise.all(\n nextIds.map((id) =>\n tryCatchAsync(runTransformerChain, (err) => {\n collector.logger\n .scope('transformer:many')\n .error(`many branch ${id} failed`, { error: err });\n return { event: null, respond: undefined };\n })(\n collector,\n transformers,\n walkChain(id, extractTransformerNextMap(transformers)),\n settledEvent,\n cloneIngest(ingest, id),\n undefined,\n chainContext,\n ),\n ),\n );\n return { event: null, respond: undefined };\n }\n\n // Update event if provided\n if (resultEvent) {\n processedEvent = resultEvent;\n }\n }\n // If result is undefined (void), continue with current event unchanged\n\n // state[set]: write to the store from the settled event, after the\n // mapping and before the `next` dispatch.\n if (stateSet && stateSet.length > 0) {\n processedEvent = await applyState(\n stateSet,\n (id) => getStateStore(id, collector),\n processedEvent,\n collector,\n );\n }\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 // If transformer didn't return { next } but has a conditional\n // config.next (one / gate / sequence / many), resolve it per-request\n // via `getNextSteps`. Static (string / string[]) chains are wired\n // statically via the next-map and pre-baked into `chain` by the\n // caller (or by `walkChain` when an explicit chain array is passed);\n // re-dispatching them here would override an explicit caller chain.\n //\n // Dispatch (conditional variants only):\n // - [] → no match; chain ends here (passthrough).\n // - ['x'] → continue main chain via static walk from x.\n // - ['a','b',...] → `many` fan-out. Terminal: each branch dispatches\n // as its own subchain with a per-branch ingest\n // clone. Main chain terminates here.\n const configNext = transformer.config.next;\n const isStaticConfigNext =\n typeof configNext === 'string' ||\n (Array.isArray(configNext) &&\n configNext.every((entry) => typeof entry === 'string'));\n const isConditionalConfigNext =\n configNext !== undefined && !isStaticConfigNext;\n if (\n (!result || (typeof result === 'object' && !result.next)) &&\n isConditionalConfigNext\n ) {\n const configNextIds = getNextSteps(\n transformer.config.next,\n buildCacheContext(ingest, processedEvent),\n );\n if (configNextIds.length === 1) {\n const continuationChain = walkChain(\n configNextIds[0],\n extractTransformerNextMap(transformers),\n );\n if (continuationChain.length > 0) {\n return runTransformerChain(\n collector,\n transformers,\n continuationChain,\n processedEvent,\n ingest,\n currentRespond,\n chainContext,\n );\n }\n // Target not found → chain ends here (passthrough)\n return { event: processedEvent, respond: currentRespond };\n }\n if (configNextIds.length > 1) {\n // many: terminal fan-out. Main chain terminates here. Per-branch\n // error isolation (Task 4.1): wrap each branch dispatch in\n // `tryCatchAsync` so a throw in one branch does not reject the\n // surrounding `Promise.all` and starve siblings.\n // No-respond-across-many: respond ownership cannot be unambiguously\n // assigned when one inbound request fans out to N terminal flows.\n // Branches are dispatched with `respond: undefined`, branch results\n // are awaited and discarded, and the outer return has\n // `respond: undefined` so the parent caller (source) sees no\n // wrapped respond.\n await Promise.all(\n configNextIds.map((id) =>\n tryCatchAsync(runTransformerChain, (err) => {\n collector.logger\n .scope('transformer:many')\n .error(`many branch ${id} failed`, { error: err });\n return { event: null, respond: undefined };\n })(\n collector,\n transformers,\n walkChain(id, extractTransformerNextMap(transformers)),\n processedEvent,\n cloneIngest(ingest, id),\n undefined,\n chainContext,\n ),\n ),\n );\n return { event: null, respond: undefined };\n }\n // configNextIds.length === 0: no match → chain ends here\n return { event: processedEvent, respond: currentRespond };\n }\n }\n\n return { event: processedEvent, respond: currentRespond };\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","import type { Collector } from '@walkeros/core';\nimport { registerDestination } from './destination';\nimport { 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 *\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 }\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 pushToDestinations,\n createPushResult,\n} from './destination';\nimport {\n assign,\n getSpanId,\n getTraceId,\n isFunction,\n isString,\n} from '@walkeros/core';\nimport { isObject } from '@walkeros/core';\nimport { processConsent } from './consent';\nimport { on, onApply, redeliverStateAtRun, enterCascade } 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\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 assign(collector.config, data as Partial<Collector.Config>, {\n shallow: 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 runCollector(collector, data as RunState);\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 await onApply(collector, action as On.Types, undefined, onData);\n result = await pushToDestinations(collector);\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 * Creates a full event from a partial event.\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 if (!partialEvent.name) throw new Error('Event name is required');\n\n const [entityValue, actionValue] = partialEvent.name.split(' ');\n if (!entityValue || !actionValue) throw new Error('Event name is invalid');\n\n const {\n timestamp = Date.now(),\n name = `${entityValue} ${actionValue}`,\n data = {},\n context = {},\n globals = collector.globals,\n custom = {},\n user = collector.user,\n nested = [],\n consent = collector.consent,\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 const count = source.count ?? (collector.count += 1);\n // Must match journeyFields' trace precedence (observerEmit.ts).\n const trace = source.trace ?? ingest?._meta.trace ?? collector.trace;\n const stampedSource: WalkerOS.Source = { ...source, 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 ?? source.platform ?? 'default';\n const releaseValue = collector.release ?? __VERSION__;\n stampedSource.release = { ...source.release, [releaseKey]: releaseValue };\n\n return {\n name,\n data,\n context,\n globals,\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 // 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 await redeliverStateAtRun(collector);\n\n // Process any queued events now that the collector is allowed\n const result = await pushToDestinations(collector);\n\n return result;\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, WalkerOS, Elb, Ingest } from '@walkeros/core';\nimport {\n createIngest,\n emitStep,\n FatalError,\n getGrantedConsent,\n processEventMapping,\n tryCatchAsync,\n useHooks,\n} from '@walkeros/core';\nimport { createEvent, enrichEvent } from './handle';\nimport { pushToDestinations, createPushResult } from './destination';\nimport { buildBaseState, journeyFields } 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 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 const 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 pre-collector transformer chain if provided in options\n if (\n preChain?.length &&\n collector.transformers &&\n Object.keys(collector.transformers).length > 0\n ) {\n const chainResult = await runTransformerChain(\n collector,\n collector.transformers,\n preChain,\n partialEvent,\n pipelineIngest,\n respond,\n id ? `source.${id}.next` : undefined,\n );\n\n // Chain was stopped - event dropped\n if (chainResult.event === null) {\n return createPushResult({ ok: 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 // Handle fan-out: array means multiple events from a single input\n if (Array.isArray(chainResult.event)) {\n // Process each forked event through the rest of the pipeline\n const forkResults = await Promise.all(\n chainResult.event.map(async (forkEvent) => {\n const enriched = prepareEvent(forkEvent);\n const full = createEvent(collector, enriched, pipelineIngest);\n return pushToDestinations(\n collector,\n full,\n {\n id,\n ingest: pipelineIngest,\n respond,\n },\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.event.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.event;\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 collector.status.failed++;\n collector.logger.error('push failed', {\n event,\n ingest: options.ingest,\n error: err,\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 const eventId = typeof event.id === 'string' ? event.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 event,\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 = event;\n emitStep(collector, inState);\n\n try {\n const result = await innerPush(event, options);\n const finished = Date.now();\n const outState = buildBaseState(collector, {\n stepId: 'collector.push',\n stepType: 'collector',\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 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';\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 collector.logger.error('command failed', {\n command,\n data,\n error: err,\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';\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, { 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","import type { Collector, Elb } from '@walkeros/core';\nimport type { StartFlow } from './types';\nimport { collector } from './collector';\nimport { initSources } from './source';\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 // 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\n const markedPrimary = sources.find(\n (source) => (source.config as { primary?: boolean }).primary,\n );\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"],"mappings":"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","names":["collector","import_core","import_core","import_core","collector","import_core","clone","import_core","import_core","import_core","collector","import_core","import_core","collector","collector","initTransformers","collector","collector","require","collector","on","option","collector","event","isInitialized","batchState","destIdResolved","destStatus","outcome","import_core","collector","collector","import_core","collector","prepareEvent","import_core","collector","collector","import_core","import_core","collector","collector","initStores","collector"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/code.ts","../src/constants.ts","../src/consent.ts","../src/collector.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/pending.ts","../src/handle.ts","../src/shutdown.ts","../src/push.ts","../src/command.ts","../src/elb.ts","../src/store.ts","../src/cache-store.ts","../src/store-cache-wrapper.ts","../src/flow.ts"],"sourcesContent":["export * from './types';\n\nexport * from './constants';\n\nexport * from './consent';\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 * from './destination';\nexport * from './handle';\nexport * from './on';\nexport * from './source';\nexport {\n runTransformerChain,\n transformerPush,\n transformerInit,\n walkChain,\n extractTransformerNextMap,\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 { 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 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 // 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 {\n Cache,\n Collector,\n WalkerOS,\n Elb,\n Destination,\n Transformer,\n Ingest,\n Simulation,\n} from '@walkeros/core';\nimport {\n assign,\n buildCacheContext,\n clone,\n compileCache,\n checkCache,\n storeCache,\n createIngest,\n debounce,\n emitStep,\n getId,\n getGrantedConsent,\n getNextSteps,\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 { callDestinationOn } from './on';\nimport {\n runTransformerChain,\n walkChain,\n extractTransformerNextMap,\n extractChainProperty,\n} 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} from './report-error';\nimport { reconcilePending } from './pending';\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 * 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 */\nconst 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 */\nfunction 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 */\nclass 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 */\nfunction 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\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 * Resolves transformer chain for a destination.\n *\n * `getNextSteps` returns the immediate next-step ids for the given Route in\n * the supplied context. `walkChain` then follows static `.next` links from\n * each entry to produce the full ordered chain. The WeakMap inside\n * `getNextSteps` caches the compiled form, so we don't re-compile per event.\n *\n * post-collector destination.before disallows `many` (enforced at the schema\n * layer via `RouteWithoutManySchema`), so we never see more than one id here\n * unless a user passes an explicit string[] chain — in which case we want to\n * treat it as the explicit chain (no further walking).\n *\n * `transformerNextMap` is computed once per `pushToDestinations` call (it depends\n * only on `collector.transformers`) and passed in to avoid rebuilding it for\n * every destination's before and next chain resolution.\n */\nfunction resolveDestinationChain(\n before: Transformer.Route | undefined,\n transformerNextMap: ReturnType<typeof extractTransformerNextMap>,\n ingest?: Ingest,\n): string[] {\n if (!before) return [];\n // Static string[] chains pass through unchanged — they are explicit and\n // suppress `.next` walking. Static single-string starts are walked.\n if (\n Array.isArray(before) &&\n before.every((entry) => typeof entry === 'string')\n ) {\n return walkChain(before, transformerNextMap);\n }\n if (typeof before === 'string') {\n return walkChain(before, transformerNextMap);\n }\n // Conditional shape — resolve per-event, walk single-id result.\n const ids = getNextSteps(before, buildCacheContext(ingest));\n if (ids.length === 0) return [];\n if (ids.length === 1) return walkChain(ids[0], transformerNextMap);\n // Multiple ids from a conditional shape: treat as explicit chain.\n // (destination.before disallows `many`; this path is reached only if a\n // RouteConfig.next resolves to a string[], which is then the user's\n // declared chain.)\n return walkChain(ids, transformerNextMap);\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 const baseConfig = 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 return pushToDestinations(collector, undefined, {}, { [id]: destination });\n}\n\n/**\n * Pushes an event to all or a subset of destinations.\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?: import('@walkeros/core').RespondFn;\n } = {},\n destinations?: Collector.Destinations,\n): Promise<Elb.PushResult> {\n const { allowed, consent, globals, user } = collector;\n\n // Check if collector is allowed to push\n if (!allowed) return createPushResult({ ok: false });\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 // Precompute the transformer next map once per push (shared across all\n // destinations in this batch, used for both before and next chain resolution).\n // Guarded because tests and partially-initialized collectors may pass\n // `transformers` as undefined.\n const transformerNextMap = collector.transformers\n ? extractTransformerNextMap(collector.transformers)\n : {};\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 // Queued events: refresh consent (full replace — stale consent must not persist).\n // User/globals merge happens for all events below in allowedEvents.map.\n let currentQueue = (destination.queuePush || []).map((event) => ({\n ...event,\n 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, 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 // 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 const allowedEvents: WalkerOS.Events = [];\n const skippedEvents = currentQueue.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 allowedEvents.push(queuedEvent); // Add to allowed queue\n return false; // Remove from destination queue\n }\n\n // Emit a skip state for the consent-denied event so observers can\n // see the gate decision per-event.\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\n // Add skipped (consent-denied) events back to the queue.\n // Bounded; FIFO drop-oldest on overflow.\n if (skippedEvents.length > 0) {\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 skipped of skippedEvents) {\n const r = pushBounded(queuePush, skipped, 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 // 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 // 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 // Process the destinations event queue\n let error: unknown;\n let response: unknown;\n if (!destination.dlq) destination.dlq = [];\n\n // Resolve the before chain once per destination batch (the per-event\n // resolution inside getNextSteps is WeakMap-cached, so this is cheap).\n const before = destination.config.before;\n const postChain = resolveDestinationChain(\n before,\n transformerNextMap,\n destIngest,\n );\n\n // Capture the next chain config; resolution happens per-event below.\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 await Promise.all(\n allowedEvents.map(async (event) => {\n // Merge collector state into event (collector as base, event overrides)\n event.globals = assign(globals, event.globals);\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 if (compiledDCache?.stop && dCacheStore) {\n const cacheContext = buildCacheContext(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 processedEvent: WalkerOS.Event | null = event;\n let destRespond = meta.respond;\n if (\n postChain.length > 0 &&\n collector.transformers &&\n Object.keys(collector.transformers).length > 0\n ) {\n const chainResult = await runTransformerChain(\n collector,\n collector.transformers,\n postChain,\n event,\n destIngest,\n meta.respond,\n `destination.${id}.before`,\n );\n\n if (chainResult.event === null) {\n // Chain stopped - skip this event for this destination\n return event;\n }\n\n // Update respond if the chain produced a wrapped one\n if (chainResult.respond) destRespond = chainResult.respond;\n\n // Use the processed event (cast back to full Event type)\n // Before chains use first result if fan-out occurred\n processedEvent = (\n Array.isArray(chainResult.event)\n ? chainResult.event[0]\n : chainResult.event\n ) as WalkerOS.Event;\n }\n\n // Step-level cache check: after before chain, skip only push on HIT\n if (compiledDCache && !compiledDCache.stop && dCacheStore) {\n const cacheContext = buildCacheContext(destIngest, processedEvent);\n const cacheResult = await checkCache(\n compiledDCache,\n dCacheStore,\n cacheContext,\n );\n if (cacheResult?.status === 'HIT') {\n return event; // Skip push — deduplicated\n }\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\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 );\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 error: 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 destIngest,\n destRespond,\n );\n totalDuration += Date.now() - pushStart;\n\n // Destination cache MISS: store the push result after attempt\n if (\n cacheMiss &&\n dCacheStore &&\n destination.config.mock === undefined\n ) {\n storeCache(\n dCacheStore,\n cacheMiss.key,\n result ?? true,\n cacheMiss.ttl,\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 );\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 destIngest._response = result;\n }\n\n const nextChain = resolveDestinationChain(\n nextConfig,\n transformerNextMap,\n destIngest,\n );\n\n if (\n nextChain.length > 0 &&\n collector.transformers &&\n Object.keys(collector.transformers).length > 0\n ) {\n const nextResult = await runTransformerChain(\n collector,\n collector.transformers,\n nextChain,\n processedEvent!,\n destIngest,\n destRespond,\n `destination.${id}.next`,\n );\n if (nextResult.respond) destRespond = nextResult.respond;\n }\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 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 const syncDelivered = Math.max(0, allowedCount - 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\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 // 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 destination.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 configResult; // don't push if init is false\n\n // Update the destination config if it was returned\n destination.config = {\n ...(configResult || destination.config),\n init: true, // Remember that the destination was initialized\n };\n\n // Flush queued on() events now that destination is initialized\n if (destination.queueOn?.length) {\n const queueOn = destination.queueOn;\n destination.queueOn = [];\n\n for (const { type, data } of queueOn) {\n callDestinationOn(collector, destination, destId, type, data);\n }\n }\n\n destLogger.debug('init done');\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 // Representative journey correlation for the batch record. A forwarded\n // batch may aggregate events from distinct upstream traces, so\n // first-entry stamping on the flush/error records is best-effort; the\n // per-event in/out records carry each event's exact trace.\n const {\n traceId: batchTraceId,\n sourceId: batchSourceId,\n parentEventId: batchParentEventId,\n } = journeyFields(rep.event, rep.ingest, collector);\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 const flushState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'flush',\n eventId: '',\n now: flushStarted,\n traceId: batchTraceId,\n sourceId: batchSourceId,\n parentEventId: batchParentEventId,\n });\n flushState.batch = { size: snapshot.entries.length, index: 0 };\n emitStep(collector, flushState);\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 const errFinished = Date.now();\n const batchErrState = buildBaseState(collector, {\n stepId: stepId('destination', destId),\n stepType: 'destination',\n phase: 'error',\n eventId: '',\n now: errFinished,\n traceId: batchTraceId,\n sourceId: batchSourceId,\n parentEventId: batchParentEventId,\n });\n batchErrState.durationMs = errFinished - flushStarted;\n batchErrState.error =\n err instanceof Error\n ? { name: err.name, message: err.message }\n : { message: String(err) };\n batchErrState.batch = {\n size: snapshot.entries.length,\n index: 0,\n };\n emitStep(collector, batchErrState);\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 const seen = new Set<number>();\n for (const failure of outcome.failed) {\n const entry = snapshot.entries[failure.index];\n if (!entry || seen.has(failure.index)) continue;\n seen.add(failure.index);\n failedPairs.push([\n entry.event,\n failure.error ??\n new Error(\n `Push batch entry ${failure.index} failed (no per-row error provided)`,\n ),\n ]);\n }\n if (failedPairs.length > 0) {\n routeToDlq(failedPairs);\n succeededCount = Math.max(\n 0,\n snapshot.entries.length - failedPairs.length,\n );\n destLogger.error('Push batch partial failure', {\n failed: failedPairs.length,\n delivered: succeededCount,\n entries: snapshot.entries.length,\n });\n }\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","import type { Simulation } from '@walkeros/core';\nimport { parseCallPath } from '@walkeros/core';\n\n/**\n * True for any non-null object, arrays included, narrowing to an index-readable\n * record. Arrays must count: `window.dataLayer.push` navigates through an array\n * to reach its method. (`isObject` from core rejects arrays, so it can't gate\n * intermediate navigation here.)\n */\nfunction isNavigable(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\ninterface WrapResult {\n /** Env with tracked paths wrapped by recording functions */\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 this env could not wrap: a missing or\n * non-object root/intermediate, an absent/non-function leaf, or a parent\n * beyond the clone cap (wrapping there would mutate the caller's env). Each\n * entry is the post-`call:` stripped dot-path (what the recorder records as\n * `fn`) — this list feeds `EnvObserve.paths` directly, so malformed paths\n * (`parseCallPath` returned `[]`) are skipped entirely: the shared grammar\n * makes them unresolvable for the fallback wrapper too. A path that\n * navigates part-way then stops belongs here, never wrapped at a wrong level.\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 * Tracked simulation dot-paths must resolve within this depth so recorders\n * are installed on cloned parents and never mutate the caller's env.\n */\nconst CLONE_MAX_DEPTH = 8;\n\n/**\n * Visit-once structural clone. The memo maps each source object to its single\n * clone, so cycles terminate and shared references stay shared (the clone\n * preserves the object graph's shape). Functions are kept by reference.\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) 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 as Record<string, unknown>)) {\n clone[key] =\n typeof value === 'function' ? value : deepClone(value, memo, depth + 1);\n }\n return clone;\n}\n\n/**\n * Wrap tracked paths in a destination env with recording wrappers.\n *\n * The env object must include a `simulation: string[]` declaring which\n * dot-paths to intercept. Returns a cloned env (without `simulation`)\n * where those paths record every call into the `calls` array.\n */\nexport function wrapEnv(\n env: Record<string, unknown> & { simulation: string[] },\n): WrapResult {\n const calls: Simulation.Call[] = [];\n const unresolved: string[] = [];\n const { simulation, ...rest } = env;\n\n // Deep clone the env to avoid mutating the original (preserves functions)\n const wrappedEnv = deepClone(\n rest,\n new WeakMap<object, unknown>(),\n 0,\n ) as Record<string, unknown>;\n\n for (const rawPath of simulation) {\n // `parseCallPath` owns the split grammar (shared with getEnv): strips a\n // single `call:` prefix, splits on `.`, rejects empty segments as `[]`.\n const segments = parseCallPath(rawPath);\n if (segments.length === 0) {\n // Malformed: the fallback wrapper shares this grammar, so the path can\n // never resolve anywhere — skip it, keeping `unresolved` well-formed.\n continue;\n }\n\n // Post-`call:` display form derived from the shared segments, so no local\n // strip literal can drift from `parseCallPath`.\n const path = segments.join('.');\n\n // A parent at or beyond the clone cap is an ORIGINAL reference (see\n // deepClone); installing a wrapper there would permanently mutate the\n // caller's env. The recorder fallback handles such paths instead.\n if (segments.length - 1 >= CLONE_MAX_DEPTH) {\n unresolved.push(path);\n continue;\n }\n\n // Navigate to the parent. Every intermediate must resolve to an object;\n // stopping short sends the whole path to `unresolved` rather than wrapping\n // a same-named leaf at the wrong level.\n let target: Record<string, unknown> = wrappedEnv;\n let resolved = true;\n for (let i = 0; i < segments.length - 1; i++) {\n const next = target[segments[i]];\n if (!isNavigable(next)) {\n resolved = false;\n break;\n }\n target = next;\n }\n\n const leaf = segments[segments.length - 1];\n if (!resolved || !(leaf in target)) {\n unresolved.push(path);\n continue;\n }\n\n const original = target[leaf];\n if (typeof original !== 'function') {\n unresolved.push(path);\n continue;\n }\n\n target[leaf] = function (this: unknown, ...args: unknown[]) {\n calls.push({ fn: path, args, ts: Date.now() });\n return original.apply(this, args);\n };\n }\n\n return { wrappedEnv, calls, unresolved };\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} from '@walkeros/core';\nimport { isArray, FatalError } from '@walkeros/core';\nimport { Const } from './constants';\nimport { tryCatch, tryCatchAsync } from '@walkeros/core';\nimport { mergeEnvironments } from './destination';\nimport { buildReportError } from './report-error';\nimport { reconcilePending } from './pending';\nimport { flushSourceQueueOn, isSourceStarted } from './source';\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 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 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 * and return a teardown that clears it. Nested commands emitted by reacting\n * callbacks find `collector.cascade` already set and reuse it (teardown is a\n * no-op for them), so the counters are scoped to the originating command and\n * reset when it returns. 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 if (collector.cascade) return () => undefined;\n collector.cascade = { counts: new WeakMap() };\n return () => {\n collector.cascade = undefined;\n };\n}\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.\n * Used by both onApply() for immediate calls and destinationInit() for flushing queued events.\n */\nexport function callDestinationOn(\n collector: Collector.Instance,\n destination: Destination.Instance,\n destId: string,\n type: On.Types,\n data: unknown,\n) {\n if (!destination.on) return;\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: data 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 tryCatch(destination.on, (err) =>\n logOnCallbackError(collector, 'destination', err, { destId, type }),\n )(type, context);\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 const result = await tryCatchAsync(source.on, (err) =>\n logOnCallbackError(collector, 'source', err, { sourceId, type }),\n )(type, contextData);\n\n if (isStateDelivery(type)) setMark(collector, source, type);\n\n return result === false;\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` and the\n * gated `source.on` loop via `deliverStateToSource`. 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 // 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 void return. 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 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' on handlers via the gated helper.\n for (const [sourceId, source] of Object.entries(collector.sources)) {\n if (!isSourceStarted(source)) continue;\n await deliverStateToSource(\n collector,\n source,\n sourceId,\n type,\n contextData,\n );\n }\n }\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 // 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 true;\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 let vetoed = false;\n // Per-source require decrement + gated on() delivery.\n // Sources are not \"started\" until config.init === true AND config.require is empty.\n // Unstarted sources have their on() events queued in instance.queueOn\n // and replayed once they start.\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 const sourceVetoed = await deliverStateToSource(\n collector,\n source,\n sourceId,\n type,\n contextData,\n );\n if (sourceVetoed) vetoed = true;\n } else {\n source.queueOn = source.queueOn || [];\n source.queueOn.push({ type, data: contextData });\n }\n }\n\n Object.entries(collector.destinations).forEach(([destId, destination]) => {\n if (destination.on) {\n // Queue if destination not yet initialized\n if (!destination.config.init) {\n destination.queueOn = destination.queueOn || [];\n destination.queueOn.push({ type, data: contextData });\n return;\n }\n callDestinationOn(collector, destination, destId, type, contextData);\n }\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 !vetoed;\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 * 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 error: err instanceof Error ? err.message : String(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', {\n error: err instanceof Error ? err.message : String(err),\n });\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 WalkerOS,\n} from '@walkeros/core';\nimport type { RespondFn, RespondOptions } from '@walkeros/core';\nimport {\n createIngest,\n FatalError,\n getMappingValue,\n parseTraceparent,\n tryCatchAsync,\n getNextSteps,\n compileCache,\n checkCache,\n storeCache,\n applyUpdate,\n buildCacheContext,\n compileState,\n applyState,\n} from '@walkeros/core';\nimport {\n walkChain,\n extractTransformerNextMap,\n runTransformerChain,\n cloneIngest,\n} from './transformer';\nimport { buildReportError } from './report-error';\nimport { isStateDelivery, shouldDeliver, setMark } from './on';\nimport { reconcilePending } from './pending';\n\n/**\n * A Route is \"static\" when it's a transformer-ID string or an array of\n * transformer-ID strings. Static routes can be resolved once at init and\n * walked synchronously; conditional shapes (RouteConfig, mixed arrays)\n * depend on per-event context and resolve via getNextSteps at dispatch.\n */\nfunction isStaticRoute(\n route: import('@walkeros/core').Transformer.Route | undefined,\n): route is string | string[] {\n if (typeof route === 'string') return true;\n if (\n Array.isArray(route) &&\n route.every((entry) => typeof entry === 'string')\n ) {\n return true;\n }\n return false;\n}\nimport { getCacheStore, getStateStore } from './cache';\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.\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 await tryCatchAsync(source.on, (err: unknown): undefined => {\n if (err instanceof FatalError) throw err;\n collector.status.failed++;\n collector.logger.scope('source').error('source on flush failed', {\n sourceId: id,\n type,\n error: err,\n });\n return undefined;\n })(type, data);\n\n if (isStateDelivery(type)) 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// Intentionally looser than core's isObject, which rejects non-plain objects\n// like Fetch Headers instances ('[object Headers]') that must pass here.\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction hasHeaderGetter(\n headers: Record<string, unknown>,\n): headers is { get: (name: string) => unknown } {\n return 'get' in headers && typeof headers.get === 'function';\n}\n\n/**\n * Read a `traceparent` header value from a raw source scope input, if any.\n * Supports a Fetch `Headers` instance (via its `.get` accessor) and a plain\n * object header bag (direct `traceparent` key first, then a case-insensitive\n * fallback since raw Node/GCP requests may not lowercase header keys). Any\n * other shape yields undefined. Never throws on exotic inputs.\n */\nfunction readTraceparentHeader(rawScope: unknown): unknown {\n if (!isRecord(rawScope)) return undefined;\n const headers = rawScope.headers;\n if (!isRecord(headers)) return undefined;\n\n if (hasHeaderGetter(headers)) return headers.get('traceparent') ?? undefined;\n\n if ('traceparent' in headers) return headers.traceparent;\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === 'traceparent') return headers[key];\n }\n return undefined;\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 } = 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 // Resolve transformer chain for this source.\n // Static (string / string[]) chains pre-walk at init (optimization).\n // Conditional shapes (case / gate) require per-request context — see wrappedPush.\n const staticPreChain = isStaticRoute(next)\n ? walkChain(next, extractTransformerNextMap(collector.transformers))\n : undefined;\n\n // Resolve before chain for this source (consent-exempt, pre-source preprocessing).\n const staticBeforeChain = isStaticRoute(before)\n ? walkChain(before, extractTransformerNextMap(collector.transformers))\n : undefined;\n\n // Terminal push: where the source pipeline ends. Defaults to\n // `collector.push`. Tests (and rare advanced consumers) may override by\n // passing `push` in the source's `env`; in that case the override\n // replaces the collector and receives the raw event with no pipeline\n // options. Per-scope ingest/respond is invisible to overriders by\n // design: overriders are responsible for their own pipeline shape.\n const userTerminalPush = (env as { push?: Collector.PushFn }).push;\n const terminalPush: Collector.PushFn = userTerminalPush ?? collector.push;\n const hasUserTerminalPush = Boolean(userTerminalPush);\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 let pendingRespond: Promise<void> | undefined;\n\n // Resolve before chain (static or conditional).\n // Single-id results walk static `.next` links; multi-id results are\n // explicit chains (fan-out from `many` is handled by the engine).\n const beforeChain =\n staticBeforeChain ??\n (before !== undefined\n ? (() => {\n const ids = getNextSteps(before, buildCacheContext(scope.ingest));\n if (ids.length === 0) return [];\n const start = ids.length === 1 ? ids[0] : ids;\n return walkChain(\n start,\n extractTransformerNextMap(collector.transformers),\n );\n })()\n : []);\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 events: WalkerOS.DeepPartialEvent[] = [rawEvent];\n\n // Run source.before chain (consent-exempt, pre-source preprocessing)\n if (\n beforeChain.length > 0 &&\n collector.transformers &&\n Object.keys(collector.transformers).length > 0\n ) {\n const beforeResult = await runTransformerChain(\n collector,\n collector.transformers,\n beforeChain,\n rawEvent,\n scope.ingest,\n scope.respond,\n `source.${sourceId}.before`,\n );\n if (beforeResult.event === null) {\n return { ok: true } as Elb.PushResult;\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 events = Array.isArray(beforeResult.event)\n ? beforeResult.event\n : [beforeResult.event];\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 = buildCacheContext(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 // Resolve chain: static (pre-computed) or conditional (per-event).\n // Three dispatch shapes from `getNextSteps`:\n // - [] → no route matched; passthrough to collector with no\n // pre-chain.\n // - ['x'] → walk static `.next` links from x and run as a single\n // sequential subchain inside `collector.push`.\n // - ['a','b',…] → `many` fan-out. Each id is an INDEPENDENT terminal\n // subchain dispatched via its own `collector.push` call\n // with a per-branch cloned ingest and `respond` cleared\n // (no-respond-across-many doctrine). Error isolation\n // per branch via tryCatchAsync.\n //\n // Note: a plain `next: ['a','b','c']` is `isStaticRoute` → pre-walked\n // by `staticPreChain` as the legacy explicit sequential chain. Only\n // `{ many: [...] }` reaches the multi-id branch here.\n type Dispatch =\n | { kind: 'single'; preChain: string[] }\n | { kind: 'many'; branches: string[][] };\n\n const dispatch: Dispatch = staticPreChain\n ? { kind: 'single', preChain: staticPreChain }\n : next !== undefined\n ? (() => {\n const ids = getNextSteps(next, buildCacheContext(scope.ingest));\n if (ids.length === 0)\n return { kind: 'single', preChain: [] } as Dispatch;\n if (ids.length === 1)\n return {\n kind: 'single',\n preChain: walkChain(\n ids[0],\n extractTransformerNextMap(collector.transformers),\n ),\n } as Dispatch;\n return {\n kind: 'many',\n branches: ids.map((id) =>\n walkChain(\n id,\n extractTransformerNextMap(collector.transformers),\n ),\n ),\n } as Dispatch;\n })()\n : ({ kind: 'single', preChain: [] } as Dispatch);\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 // A user `env.push` override receives the raw event with no pipeline\n // (see the terminal-push contract above), so state is skipped for it.\n if (!hasUserTerminalPush && stateEntries && stateEntries.length > 0) {\n events = await Promise.all(\n events.map((event) =>\n applyState(\n stateEntries,\n (id) => getStateStore(id, collector),\n event,\n collector,\n ),\n ),\n );\n }\n\n // Push each event independently through the post-before pipeline.\n // For non-fan-out (single event) this is a one-iteration loop and\n // behaves exactly like the previous implementation.\n let pushResult: Elb.PushResult = { ok: true } as Elb.PushResult;\n for (const event of events) {\n if (dispatch.kind === 'many') {\n // `many` fan-out: each branch is an independent terminal flow.\n // Per-branch ingest clone, no respond propagation, error isolation\n // via tryCatchAsync. Branch results are awaited and discarded;\n // scope.respond is NOT updated from any branch.\n await Promise.all(\n dispatch.branches.map((branchChain, idx) =>\n tryCatchAsync(\n async () =>\n hasUserTerminalPush\n ? terminalPush(event)\n : terminalPush(event, {\n ...options,\n id: sourceId,\n ingest: cloneIngest(scope.ingest, `${sourceId}.${idx}`),\n respond: undefined,\n mapping: config,\n preChain: branchChain,\n }),\n (err) => {\n collector.logger\n .scope('source:many')\n .error(`many branch ${idx} failed`, { error: err });\n return { ok: true } as Elb.PushResult;\n },\n )(),\n ),\n );\n // `many` is fan-out, not enrichment — surface a generic OK.\n pushResult = { ok: true } as Elb.PushResult;\n } else if (hasUserTerminalPush) {\n // User override: bypass the pipeline, deliver raw events. This\n // preserves the `env.push: mockPush` test spy pattern.\n pushResult = await terminalPush(event);\n } else {\n pushResult = await terminalPush(event, {\n ...options,\n id: sourceId,\n ingest: scope.ingest,\n respond: scope.respond,\n mapping: config,\n preChain: dispatch.preChain,\n });\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 (rawScope: unknown): Promise<Ingest> => {\n const fresh = createIngest(sourceId);\n // Adopt an inbound W3C traceparent from the raw scope's header bag so\n // every server source gains trace continuity + parent-span linkage. The\n // final return reuses `fresh._meta` by reference, so stamping here holds\n // for both the mapped and unmapped paths.\n const traceparent = parseTraceparent(readTraceparentHeader(rawScope));\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 // Build cleanEnv. User-supplied env can override every field; we\n // immediately overwrite `push` with the source-pipeline `wrappedPush`.\n // Any user-supplied `env.push` was captured above as `terminalPush`\n // (the pipeline's terminus, not the source's outward-facing push).\n const cleanEnv: Source.Env = {\n command: collector.command,\n sources: collector.sources,\n elb: collector.elb,\n logger: initialLogger,\n ...env,\n push: wrappedPush,\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 error: 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 error: 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 Chain Utilities\n * ==========================\n *\n * This module provides the unified implementation for transformer chains in walkerOS.\n * Chains are used at two points in the data flow:\n *\n * 1. Pre-collector chains (source.next):\n * Source → [Transformer Chain] → Collector\n * Events are processed before the collector sees them.\n *\n * 2. Post-collector chains (destination.before):\n * Collector → [Transformer Chain] → Destination\n * Events are processed before reaching specific destinations.\n *\n * Key Functions:\n * - extractTransformerNextMap(): Extracts next links from transformer instances\n * - extractChainProperty(): Unified extraction of chain properties from definitions\n * - walkChain(): Resolves chain IDs from starting point\n * - runTransformerChain(): Executes a chain of transformers on an event\n *\n * Chain Resolution:\n * - String start: Walk transformer.next links until chain ends\n * - Array start: Use array directly (explicit chain, ignores transformer.next)\n *\n * Chain Termination:\n * - Transformer returns false → chain stops, event is dropped\n * - Transformer throws error → chain stops, event is dropped\n * - Transformer returns void → continue with unchanged event\n * - Transformer returns event → continue with modified event\n */\nimport type {\n Cache,\n Collector,\n Transformer,\n WalkerOS,\n Ingest,\n} from '@walkeros/core';\nimport {\n createIngest,\n emitStep,\n FatalError,\n isObject,\n stepId,\n tryCatchAsync,\n useHooks,\n getNextSteps,\n compileCache,\n checkCache,\n storeCache,\n buildCacheContext,\n validateStepEntry,\n processEventMapping,\n compileState,\n applyState,\n} from '@walkeros/core';\nimport { buildBaseState, journeyFields } from './observerEmit';\nimport { getCacheStore, getStateStore } from './cache';\nimport { buildReportError } from './report-error';\n\n/**\n * Extracts transformer next configuration for chain walking.\n * Maps transformer instances to their config.next values.\n *\n * This is the single source of truth for extracting chain links.\n * Used by both source.ts (pre-collector chains) and destination.ts (post-collector chains).\n *\n * @param transformers - Map of transformer instances\n * @returns Map of transformer IDs to their next configuration\n */\nexport function extractTransformerNextMap(\n transformers: Transformer.Transformers,\n): Record<string, { next?: string | string[] }> {\n const result: Record<string, { next?: string | string[] }> = {};\n for (const [id, transformer] of Object.entries(transformers)) {\n const next = transformer.config?.next;\n // Static shapes are recorded for synchronous chain walking.\n // Conditional shapes (RouteConfig, mixed arrays) resolve per-event via\n // getNextSteps at dispatch time; they get an empty entry here so the\n // chain walker stops at this hop rather than following a stale link.\n if (typeof next === 'string') {\n result[id] = { next };\n } else if (\n Array.isArray(next) &&\n next.every((entry) => typeof entry === 'string')\n ) {\n result[id] = { next: next as string[] };\n } else {\n result[id] = {};\n }\n }\n return result;\n}\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 * Walks a transformer chain starting from a given transformer ID.\n * Returns ordered array of transformer IDs in the chain.\n *\n * Used for on-demand chain resolution:\n * - Called from destination.ts with destination.config.before\n * - Called from source.ts with source.config.next\n *\n * @param startId - First transformer in chain, or explicit array of transformer IDs\n * @param transformers - Available transformer configs with optional `next` field\n * @returns Ordered array of transformer IDs to execute\n *\n * @example\n * // Single transformer\n * walkChain('redact', { redact: {} }) // ['redact']\n *\n * @example\n * // Chain via next\n * walkChain('a', { a: { next: 'b' }, b: { next: 'c' }, c: {} }) // ['a', 'b', 'c']\n *\n * @example\n * // Explicit array\n * walkChain(['x', 'y'], {}) // ['x', 'y']\n */\nexport function walkChain(\n startId: string | string[] | undefined,\n transformers: Record<string, { next?: string | string[] }> = {},\n): string[] {\n if (!startId) return [];\n\n // If array provided, use it directly (explicit chain)\n if (Array.isArray(startId)) {\n return startId;\n }\n\n // Walk the chain via transformer.next links\n const chain: string[] = [];\n const visited = new Set<string>();\n let current: string | undefined = startId;\n\n while (current && transformers[current]) {\n if (visited.has(current)) {\n // Circular reference detected - stop walking\n break;\n }\n visited.add(current);\n chain.push(current);\n\n const next: string | string[] | undefined = transformers[current].next;\n\n // If transformer has array next, append it and stop walking\n if (Array.isArray(next)) {\n chain.push(...next);\n break;\n }\n\n current = next;\n }\n\n return chain;\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 branch (e.g. a `many` fan-out branch).\n *\n * Each branch needs its own `_meta.path` so cycle protection and the\n * MAX_PATH_LENGTH safety valve operate per-branch rather than colliding\n * across sibling forks. The top-level object and `_meta` are shallow-copied;\n * `_meta.path` is duplicated so appends in one branch do not leak into others.\n *\n * `branchId` is reserved for future per-branch labelling (Task 4.1) and is\n * not currently written into `_meta`; it is accepted now so callers don't\n * need to change their call sites when error-isolation lands.\n */\nexport function cloneIngest(\n ingest: Ingest | undefined,\n branchId: string,\n): Ingest {\n if (!ingest) return createIngest(branchId);\n return {\n ...ingest,\n _meta: { ...ingest._meta, path: [...ingest._meta.path] },\n };\n}\n\n/**\n * Runs an event through a chain of transformers.\n *\n * @param collector - The collector instance with transformers\n * @param transformers - Map of transformer instances\n * @param chain - Ordered array of transformer IDs to execute\n * @param event - The event to process\n * @param ingest - Mutable ingest context flowing through the pipeline\n * @returns The processed event or null if chain was stopped\n */\nexport async function runTransformerChain(\n collector: Collector.Instance,\n transformers: Transformer.Transformers,\n chain: string[],\n event: WalkerOS.DeepPartialEvent,\n ingest?: Ingest,\n respond?: import('@walkeros/core').RespondFn,\n chainContext?: string,\n): Promise<Transformer.ChainResult> {\n const MAX_PATH_LENGTH = 256;\n\n // Ensure an ingest exists so the per-branch path budget engages\n // regardless of caller. Production callers (source/push/destination)\n // always pass one; this guards direct test invocations and any future\n // entrypoint that omits it. Without an ingest, the safety valve below\n // can never trip — leaving cyclic `many` graphs unbounded.\n if (!ingest) {\n ingest = createIngest(chain[0] ?? 'chain');\n }\n\n if (chainContext && ingest._meta) {\n ingest._meta.chainPath = chainContext;\n }\n\n let processedEvent = event;\n let currentRespond = respond;\n\n for (const transformerName of chain) {\n const transformer = transformers[transformerName];\n if (!transformer) {\n collector.logger.warn(`Transformer not found: ${transformerName}`);\n continue;\n }\n\n // Safety valve: prevent unbounded path growth\n if (ingest && ingest._meta && ingest._meta.path.length > MAX_PATH_LENGTH) {\n collector.logger.error(`Max path length exceeded at ${transformerName}`);\n return { event: null, respond: currentRespond };\n }\n\n // Track step in _meta (runtime-managed)\n if (ingest && ingest._meta) {\n ingest._meta.hops++;\n ingest._meta.path.push(transformerName);\n }\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 // (handled by the destination's own log; counter remains untouched on\n // the deliberate-false path).\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 error: err,\n });\n return false;\n },\n )(collector, transformer, transformerName);\n\n if (!isInitialized) {\n // Stop chain on init failure. Thrown cases were already logged with\n // full cause via the onError above; deliberate-false returns leave\n // the chain stop signal intact without extra noise.\n return { event: null, respond: currentRespond };\n }\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 continue;\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 continue;\n }\n\n // Disabled check\n if (transformer.config?.disabled) {\n continue;\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\n ? compileCache(tCacheConfig)\n : undefined;\n const tCacheStore = compiledTCache\n ? getCacheStore(compiledTCache, collector)\n : undefined;\n\n // Compile declarative state entries once. `get` runs before the step's\n // mapping (so the mapping can read fetched values); `set` runs after the\n // mapping settles `processedEvent` and before the `next` dispatch.\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 // Apply `state[set]` to a settled event right before it is routed. Called\n // once per emitted event on every emitting path (straight-through,\n // runtime `{ next }` single/many, conditional `config.next`, and per fork\n // of a `Result[]` fan-out). Not called on halted paths (push returned\n // `false`, a `cache.stop` HIT, a stopped before-chain, init failure).\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 );\n };\n\n // Check transformer cache (step-level: skip push, continue chain)\n let cacheMiss: { key: string; ttl: number } | undefined;\n if (compiledTCache && tCacheStore) {\n const cacheContext = buildCacheContext(ingest, processedEvent);\n const cacheResult = await checkCache(\n compiledTCache,\n tCacheStore,\n cacheContext,\n );\n\n if (cacheResult?.status === 'HIT' && cacheResult.value) {\n processedEvent = cacheResult.value as WalkerOS.DeepPartialEvent;\n if (compiledTCache.stop)\n // stop=true → stop chain AND halt pipeline at this position.\n // Caller branches on `stopped` to skip downstream stages\n // (collector.push, destinations); see push.ts and source.ts.\n return {\n event: processedEvent,\n respond: currentRespond,\n stopped: true,\n };\n continue; // stop=false → next transformer\n }\n\n if (cacheResult?.status === 'MISS') {\n cacheMiss = { key: cacheResult.key, ttl: cacheResult.rule.ttl };\n }\n }\n\n // Run transformer.before chain if configured.\n //\n // Dispatch uses `getNextSteps`:\n // - [] → no route matched; skip the before chain (passthrough).\n // - ['x'] → sequential continuation; walk static .next links from x\n // and run as a single subchain. Preserves cache.stop and\n // null/respond propagation from the nested chain.\n // - ['a','b',...] → `many` fan-out. Each branch is an independent\n // terminal subchain with a cloned ingest (per-branch\n // cycle protection). No merge: many is fan-out, not\n // enrichment, so parent processedEvent is unchanged.\n // Per-branch error isolation lands in Task 4.1;\n // respond suppression lands in Task 4.2.\n const transformerBefore = transformer.config.before;\n if (transformerBefore) {\n const beforeIds = getNextSteps(\n transformerBefore,\n buildCacheContext(ingest, processedEvent),\n );\n if (beforeIds.length === 1) {\n const beforeChainIds = walkChain(\n beforeIds[0],\n extractTransformerNextMap(transformers),\n );\n if (beforeChainIds.length > 0) {\n const beforeResult = await runTransformerChain(\n collector,\n transformers,\n beforeChainIds,\n processedEvent,\n ingest,\n currentRespond,\n chainContext,\n );\n if (beforeResult.event === null)\n return {\n event: null,\n respond: beforeResult.respond ?? currentRespond,\n }; // Before chain stopped\n // Propagate pipeline-halt from a nested `cache.stop: true` HIT in\n // the before chain. The outer caller (push.ts / source.ts) drops\n // the event before destinations see it.\n if (beforeResult.stopped) {\n return {\n event: Array.isArray(beforeResult.event)\n ? beforeResult.event[0]\n : beforeResult.event,\n respond: beforeResult.respond ?? currentRespond,\n stopped: true,\n };\n }\n if (beforeResult.respond) currentRespond = beforeResult.respond;\n // Before chains use first result if fan-out occurred\n processedEvent = Array.isArray(beforeResult.event)\n ? beforeResult.event[0]\n : beforeResult.event;\n }\n } else if (beforeIds.length > 1) {\n // many: independent terminal subchains. Each branch walks to its own\n // exit with a per-branch ingest clone. Per-branch error isolation\n // (Task 4.1): wrap each branch dispatch in `tryCatchAsync` so a\n // throw in one branch (init failure, unforeseen runtime error) does\n // not reject the surrounding `Promise.all` and starve siblings.\n // No-respond-across-many: respond ownership cannot be unambiguously\n // assigned when one inbound request fans out to N terminal flows.\n // Branch dispatch passes `undefined` instead of `currentRespond`, and\n // branch results are awaited and discarded — currentRespond is NOT\n // updated from any branch's wrapped respond.\n await Promise.all(\n beforeIds.map((id) =>\n tryCatchAsync(runTransformerChain, (err) => {\n collector.logger\n .scope('transformer:many')\n .error(`many branch ${id} failed`, { error: err });\n return { event: null, respond: undefined };\n })(\n collector,\n transformers,\n walkChain(id, extractTransformerNextMap(transformers)),\n processedEvent,\n cloneIngest(ingest, id),\n undefined,\n chainContext,\n ),\n ),\n );\n // No merge: many is fan-out, not enrichment. Parent processedEvent\n // unchanged.\n }\n }\n\n // state[get]: read from the store and write fetched values onto the event\n // before the transformer's mapping runs.\n if (stateGet && stateGet.length > 0) {\n processedEvent = await applyState(\n stateGet,\n (id) => getStateStore(id, collector),\n processedEvent,\n collector,\n );\n }\n\n // Run the transformer\n const result = await tryCatchAsync(transformerPush, (err) => {\n collector.logger\n .scope(`transformer:${transformer.type || 'unknown'}`)\n .error('Push failed', { error: 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 // Handle result\n if (result === false) {\n // Transformer explicitly stopped the chain (returned false, or threw\n // and was converted to false by the error handler above).\n return {\n event: null,\n respond: currentRespond,\n droppedBy: transformerName,\n };\n }\n\n // Handle Result array (fan-out) — MUST be before typeof === 'object'\n if (Array.isArray(result)) {\n const remainingChain = chain.slice(chain.indexOf(transformerName) + 1);\n\n const forkResults = await Promise.all(\n result.map(async (forkResult) => {\n const forkEvent = await applyStateSet(\n forkResult.event || processedEvent,\n );\n // Clone ingest per fork to prevent cross-fork contamination\n const forkIngest = cloneIngest(ingest, 'unknown');\n\n if (forkResult.next) {\n // Fork has explicit routing. Dispatch uses `getNextSteps`:\n // - [] → no route matched; passthrough this fork's\n // event without entering any subchain (fork\n // has explicit routing, so we do NOT fall\n // through to remainingChain).\n // - ['x'] → walk static .next from x and run that as a\n // single subchain. Preserves the existing\n // \"fork has explicit routing terminates the\n // main chain at this branch\" semantic — the\n // subchain's ChainResult is this fork's\n // result.\n // - ['a','b',...] → `many` fan-out. Each id dispatches as its\n // own terminal subchain with a per-branch\n // cloned ingest. Returns an array of\n // ChainResults; the outer `.flat()` in the\n // aggregation loop folds them into the\n // surrounding flatEvents collection.\n const forkIds = getNextSteps(\n forkResult.next,\n buildCacheContext(forkIngest, forkEvent),\n );\n if (forkIds.length === 0) {\n return { event: forkEvent, respond: currentRespond };\n }\n if (forkIds.length === 1) {\n const branchedChain = walkChain(\n forkIds[0],\n extractTransformerNextMap(transformers),\n );\n if (branchedChain.length > 0) {\n return runTransformerChain(\n collector,\n transformers,\n branchedChain,\n forkEvent,\n forkIngest,\n currentRespond,\n chainContext,\n );\n }\n return { event: forkEvent, respond: currentRespond };\n }\n // Terminal fan-out. Each branch walks to its own exit with a\n // per-branch ingest clone. Per-branch error isolation\n // (Task 4.1): wrap each branch dispatch in `tryCatchAsync` so a\n // throw in one branch does not reject the surrounding\n // `Promise.all` and starve siblings.\n // No-respond-across-many: respond ownership cannot be unambiguously\n // assigned when one inbound request fans out to N terminal flows.\n // Branches are dispatched with `respond: undefined`, and the\n // ChainResults returned to the outer aggregation are stripped of\n // any branch-internal respond so the outer fork's combined result\n // never propagates a branch's wrapped respond back to the caller.\n const branchResults = await Promise.all(\n forkIds.map((id) =>\n tryCatchAsync(runTransformerChain, (err) => {\n collector.logger\n .scope('transformer:many')\n .error(`many branch ${id} failed`, { error: err });\n return { event: null, respond: undefined };\n })(\n collector,\n transformers,\n walkChain(id, extractTransformerNextMap(transformers)),\n forkEvent,\n cloneIngest(forkIngest, id),\n undefined,\n chainContext,\n ),\n ),\n );\n // Strip per-branch side-channels (respond, stopped) at the many\n // boundary. The outer aggregation only learns about events from\n // branch ChainResults; respond and stopped are branch-internal\n // concerns and must not leak back to the surrounding fork's\n // combined result.\n return branchResults.map(\n (br): Transformer.ChainResult => ({\n event: br.event,\n respond: undefined,\n }),\n );\n }\n\n // Fork continues through remaining chain\n if (remainingChain.length > 0) {\n return runTransformerChain(\n collector,\n transformers,\n remainingChain,\n forkEvent,\n forkIngest,\n currentRespond,\n chainContext,\n );\n }\n return { event: forkEvent, respond: currentRespond };\n }),\n );\n\n // Collect events from ChainResult objects and track last respond\n let lastForkRespond = currentRespond;\n const flatEvents: WalkerOS.DeepPartialEvent[] = [];\n for (const fr of forkResults.flat()) {\n if (fr === null) continue;\n if (fr && typeof fr === 'object' && 'event' in fr) {\n const cr = fr as Transformer.ChainResult;\n if (cr.respond) lastForkRespond = cr.respond;\n if (cr.event === null) continue;\n if (Array.isArray(cr.event)) flatEvents.push(...cr.event);\n else flatEvents.push(cr.event);\n } else {\n flatEvents.push(fr as WalkerOS.DeepPartialEvent);\n }\n }\n if (flatEvents.length === 0)\n return { event: null, respond: lastForkRespond };\n if (flatEvents.length === 1)\n return { event: flatEvents[0], respond: lastForkRespond };\n return { event: flatEvents, respond: lastForkRespond };\n }\n\n if (result && typeof result === 'object') {\n // Unified TransformerResult handling\n const { event: resultEvent, respond: resultRespond, next } = result;\n\n // Update respond if transformer provided a wrapper\n if (resultRespond) {\n currentRespond = resultRespond;\n }\n\n // Handle chain branching.\n //\n // Dispatch uses `getNextSteps`:\n // - [] → no route matched; passthrough (continue main chain\n // with resultEvent if provided).\n // - ['x'] → walk static .next from x and run that as a single\n // subchain. The branched subchain's ChainResult\n // becomes this transformer's final result; the main\n // chain terminates here (explicit routing wins).\n // - ['a','b',...] → `many` fan-out. Terminal: each branch dispatches\n // as its own subchain with a per-branch ingest\n // clone. Main chain terminates here. Per-branch\n // error isolation arrives in Task 4.1; respond\n // suppression in 4.2.\n if (next !== undefined) {\n // Apply `state[set]` to the settled event before this step's `next`\n // dispatch, once for every branch that emits it.\n const settledEvent = await applyStateSet(resultEvent || processedEvent);\n const nextIds = getNextSteps(\n next,\n buildCacheContext(ingest, settledEvent),\n );\n if (nextIds.length === 0) {\n // No route matched → passthrough (continue chain)\n processedEvent = settledEvent;\n continue;\n }\n if (nextIds.length === 1) {\n const branchedChain = walkChain(\n nextIds[0],\n extractTransformerNextMap(transformers),\n );\n if (branchedChain.length > 0) {\n return runTransformerChain(\n collector,\n transformers,\n branchedChain,\n settledEvent,\n ingest,\n currentRespond,\n chainContext,\n );\n }\n // Branch target not found — drop event (fail-safe).\n collector.logger.warn(\n `Branch target not found: ${JSON.stringify(next)}`,\n );\n return { event: null, respond: currentRespond };\n }\n // many: terminal fan-out. Main chain terminates here. Per-branch\n // error isolation (Task 4.1): wrap each branch dispatch in\n // `tryCatchAsync` so a throw in one branch does not reject the\n // surrounding `Promise.all` and starve siblings.\n // No-respond-across-many: respond ownership cannot be unambiguously\n // assigned when one inbound request fans out to N terminal flows.\n // Branches are dispatched with `respond: undefined`, branch results\n // are awaited and discarded, and the outer return has\n // `respond: undefined` so the parent caller (source) sees no\n // wrapped respond.\n // No-stopped-across-many (Task 4.2 / regression-guarded by Task 4.3):\n // branch results — including any `stopped: true` from a nested\n // `cache.stop` HIT inside one branch — are discarded here. The outer\n // return omits `stopped`, so a cache.stop HIT in one branch does NOT\n // halt sibling branches. See the regression test\n // `transformer.test.ts > many: cache.stop in one branch does not\n // halt sibling branches`.\n await Promise.all(\n nextIds.map((id) =>\n tryCatchAsync(runTransformerChain, (err) => {\n collector.logger\n .scope('transformer:many')\n .error(`many branch ${id} failed`, { error: err });\n return { event: null, respond: undefined };\n })(\n collector,\n transformers,\n walkChain(id, extractTransformerNextMap(transformers)),\n settledEvent,\n cloneIngest(ingest, id),\n undefined,\n chainContext,\n ),\n ),\n );\n return { event: null, respond: undefined };\n }\n\n // Update event if provided\n if (resultEvent) {\n processedEvent = resultEvent;\n }\n }\n // If result is undefined (void), continue with current event unchanged\n\n // state[set]: write to the store from the settled event, after the\n // mapping and before the `next` dispatch.\n if (stateSet && stateSet.length > 0) {\n processedEvent = await applyState(\n stateSet,\n (id) => getStateStore(id, collector),\n processedEvent,\n collector,\n );\n }\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 // If transformer didn't return { next } but has a conditional\n // config.next (one / gate / sequence / many), resolve it per-request\n // via `getNextSteps`. Static (string / string[]) chains are wired\n // statically via the next-map and pre-baked into `chain` by the\n // caller (or by `walkChain` when an explicit chain array is passed);\n // re-dispatching them here would override an explicit caller chain.\n //\n // Dispatch (conditional variants only):\n // - [] → no match; chain ends here (passthrough).\n // - ['x'] → continue main chain via static walk from x.\n // - ['a','b',...] → `many` fan-out. Terminal: each branch dispatches\n // as its own subchain with a per-branch ingest\n // clone. Main chain terminates here.\n const configNext = transformer.config.next;\n const isStaticConfigNext =\n typeof configNext === 'string' ||\n (Array.isArray(configNext) &&\n configNext.every((entry) => typeof entry === 'string'));\n const isConditionalConfigNext =\n configNext !== undefined && !isStaticConfigNext;\n if (\n (!result || (typeof result === 'object' && !result.next)) &&\n isConditionalConfigNext\n ) {\n const configNextIds = getNextSteps(\n transformer.config.next,\n buildCacheContext(ingest, processedEvent),\n );\n if (configNextIds.length === 1) {\n const continuationChain = walkChain(\n configNextIds[0],\n extractTransformerNextMap(transformers),\n );\n if (continuationChain.length > 0) {\n return runTransformerChain(\n collector,\n transformers,\n continuationChain,\n processedEvent,\n ingest,\n currentRespond,\n chainContext,\n );\n }\n // Target not found → chain ends here (passthrough)\n return { event: processedEvent, respond: currentRespond };\n }\n if (configNextIds.length > 1) {\n // many: terminal fan-out. Main chain terminates here. Per-branch\n // error isolation (Task 4.1): wrap each branch dispatch in\n // `tryCatchAsync` so a throw in one branch does not reject the\n // surrounding `Promise.all` and starve siblings.\n // No-respond-across-many: respond ownership cannot be unambiguously\n // assigned when one inbound request fans out to N terminal flows.\n // Branches are dispatched with `respond: undefined`, branch results\n // are awaited and discarded, and the outer return has\n // `respond: undefined` so the parent caller (source) sees no\n // wrapped respond.\n await Promise.all(\n configNextIds.map((id) =>\n tryCatchAsync(runTransformerChain, (err) => {\n collector.logger\n .scope('transformer:many')\n .error(`many branch ${id} failed`, { error: err });\n return { event: null, respond: undefined };\n })(\n collector,\n transformers,\n walkChain(id, extractTransformerNextMap(transformers)),\n processedEvent,\n cloneIngest(ingest, id),\n undefined,\n chainContext,\n ),\n ),\n );\n return { event: null, respond: undefined };\n }\n // configNextIds.length === 0: no match → chain ends here\n return { event: processedEvent, respond: currentRespond };\n }\n }\n\n return { event: processedEvent, respond: currentRespond };\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","import type { Collector } from '@walkeros/core';\nimport { registerDestination } from './destination';\nimport { 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 *\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 }\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 pushToDestinations,\n createPushResult,\n} from './destination';\nimport {\n assign,\n getSpanId,\n getTraceId,\n isFunction,\n isString,\n} from '@walkeros/core';\nimport { isObject } from '@walkeros/core';\nimport { processConsent } from './consent';\nimport { on, onApply, redeliverStateAtRun, enterCascade } 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\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 assign(collector.config, data as Partial<Collector.Config>, {\n shallow: 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 runCollector(collector, data as RunState);\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 await onApply(collector, action as On.Types, undefined, onData);\n result = await pushToDestinations(collector);\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 * Creates a full event from a partial event.\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 if (!partialEvent.name) throw new Error('Event name is required');\n\n const [entityValue, actionValue] = partialEvent.name.split(' ');\n if (!entityValue || !actionValue) throw new Error('Event name is invalid');\n\n const {\n timestamp = Date.now(),\n name = `${entityValue} ${actionValue}`,\n data = {},\n context = {},\n globals = collector.globals,\n custom = {},\n user = collector.user,\n nested = [],\n consent = collector.consent,\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 const count = source.count ?? (collector.count += 1);\n // Must match journeyFields' trace precedence (observerEmit.ts).\n const trace = source.trace ?? ingest?._meta.trace ?? collector.trace;\n const stampedSource: WalkerOS.Source = { ...source, 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 ?? source.platform ?? 'default';\n const releaseValue = collector.release ?? __VERSION__;\n stampedSource.release = { ...source.release, [releaseKey]: releaseValue };\n\n return {\n name,\n data,\n context,\n globals,\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 // 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 await redeliverStateAtRun(collector);\n\n // Process any queued events now that the collector is allowed\n const result = await pushToDestinations(collector);\n\n return result;\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, WalkerOS, Elb, Ingest } from '@walkeros/core';\nimport {\n createIngest,\n emitStep,\n FatalError,\n getGrantedConsent,\n processEventMapping,\n tryCatchAsync,\n useHooks,\n} from '@walkeros/core';\nimport { createEvent, enrichEvent } from './handle';\nimport { pushToDestinations, createPushResult } from './destination';\nimport { buildBaseState, journeyFields } 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 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 const 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 pre-collector transformer chain if provided in options\n if (\n preChain?.length &&\n collector.transformers &&\n Object.keys(collector.transformers).length > 0\n ) {\n const chainResult = await runTransformerChain(\n collector,\n collector.transformers,\n preChain,\n partialEvent,\n pipelineIngest,\n respond,\n id ? `source.${id}.next` : undefined,\n );\n\n // Chain was stopped - event dropped\n if (chainResult.event === null) {\n collector.logger.debug(\n `Event dropped by transformer chain${\n chainResult.droppedBy ? ` (${chainResult.droppedBy})` : ''\n }`,\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 // Handle fan-out: array means multiple events from a single input\n if (Array.isArray(chainResult.event)) {\n // Process each forked event through the rest of the pipeline\n const forkResults = await Promise.all(\n chainResult.event.map(async (forkEvent) => {\n const enriched = prepareEvent(forkEvent);\n const full = createEvent(collector, enriched, pipelineIngest);\n return pushToDestinations(\n collector,\n full,\n {\n id,\n ingest: pipelineIngest,\n respond,\n },\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.event.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.event;\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 collector.status.failed++;\n collector.logger.error('push failed', {\n event,\n ingest: options.ingest,\n error: err,\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 const eventId = typeof event.id === 'string' ? event.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 event,\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 = event;\n emitStep(collector, inState);\n\n try {\n const result = await innerPush(event, options);\n const finished = Date.now();\n const outState = buildBaseState(collector, {\n stepId: 'collector.push',\n stepType: 'collector',\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 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';\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 collector.logger.error('command failed', {\n command,\n data,\n error: err,\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';\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, { 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","import type { Collector, Elb } from '@walkeros/core';\nimport type { StartFlow } from './types';\nimport { collector } from './collector';\nimport { initSources } from './source';\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 // 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\n const markedPrimary = sources.find(\n (source) => (source.config as { primary?: boolean }).primary,\n );\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"],"mappings":"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","names":["collector","import_core","import_core","import_core","collector","import_core","clone","import_core","import_core","import_core","collector","import_core","import_core","collector","collector","initTransformers","collector","collector","require","collector","on","option","collector","event","isInitialized","batchState","destIdResolved","destStatus","outcome","import_core","collector","collector","import_core","collector","prepareEvent","import_core","collector","collector","import_core","import_core","collector","collector","initStores","collector"]}