@walkeros/core 4.1.1-next-1779485810490 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @walkeros/core
2
2
 
3
- ## 4.1.1-next-1779485810490
3
+ ## 4.1.1
4
4
 
5
5
  ### Patch Changes
6
6
 
@@ -11,6 +11,13 @@
11
11
  partial rule onto a package-shipped default (a `null` value clears an
12
12
  inherited field); `remove` strips fields from the produced payload. Rules
13
13
  without either keyword keep the existing replace behavior.
14
+ - 0b7f494: The collector exposes `observers: Set<ObserverFn>` so any subscriber
15
+ can watch every step of the pipeline. Each source, transformer, destination,
16
+ and store call emits a `FlowState` record with timings, mapping match, consent
17
+ state, and skip reasons. `createTelemetryObserver` from `@walkeros/core`
18
+ batches emissions to an HTTP endpoint, and the CLI runtime picks up the
19
+ `traceUntil` flag from its heartbeat so trace mode toggles take effect without
20
+ a redeploy.
14
21
 
15
22
  ## 4.1.0
16
23
 
package/dist/dev.d.mts CHANGED
@@ -6868,6 +6868,74 @@ interface Ingest {
6868
6868
  _meta: IngestMeta;
6869
6869
  }
6870
6870
 
6871
+ /**
6872
+ * FlowState is the canonical observation record emitted at each hop in a
6873
+ * walkerOS pipeline. Telemetry helpers populate one of these per (step,
6874
+ * phase) tuple and pass it to a user-supplied emit callback. The shape is
6875
+ * stable across step kinds (source, transformer, collector, destination,
6876
+ * store) so a single observer can correlate work across the pipeline.
6877
+ *
6878
+ * Optional fields are populated only when meaningful for the (step, phase)
6879
+ * pair, or when the telemetry options explicitly opt in (e.g. trace level
6880
+ * for inEvent/outEvent).
6881
+ */
6882
+ type FlowStatePhase = 'init' | 'in' | 'out' | 'error' | 'skip' | 'flush';
6883
+ type FlowStepType = 'source' | 'transformer' | 'collector' | 'destination' | 'store';
6884
+ interface FlowStateBatch {
6885
+ size: number;
6886
+ index: number;
6887
+ }
6888
+ interface FlowState {
6889
+ /** The flow this state belongs to. */
6890
+ flowId: string;
6891
+ /** Step identifier, e.g. 'destination.gtag', 'transformer.consent', 'collector.push'. */
6892
+ stepId: string;
6893
+ stepType: FlowStepType;
6894
+ phase: FlowStatePhase;
6895
+ /** W3C span-id of the originating WalkerOS.Event. Sourced from event.id; never synthesized. */
6896
+ eventId: string;
6897
+ /** ISO 8601 timestamp. */
6898
+ timestamp: string;
6899
+ /** Milliseconds since the runtime's startedAt origin. Monotonic. */
6900
+ elapsedMs: number;
6901
+ /** Wall-clock duration of this step, if measured (typically only on 'out'). */
6902
+ durationMs?: number;
6903
+ /** Inbound walker event for this hop. Only populated when level === 'trace' or includeIn === true. */
6904
+ inEvent?: unknown;
6905
+ /** Outbound walker event/payload for this hop. Only populated when level === 'trace' or includeOut === true. */
6906
+ outEvent?: unknown;
6907
+ /** Error info when phase === 'error'. */
6908
+ error?: {
6909
+ name?: string;
6910
+ message: string;
6911
+ };
6912
+ /** The mapping rule that matched, when one matched. */
6913
+ mappingKey?: string;
6914
+ /** Contract rule that matched, if any. */
6915
+ contractRule?: string;
6916
+ /** Consent gate snapshot at hop time. */
6917
+ consent?: Record<string, boolean>;
6918
+ /** Consent state actually applied (after policy resolution). */
6919
+ consentApplied?: Record<string, boolean>;
6920
+ /** W3C 16-hex span-id of the child branch for `many` fan-out. */
6921
+ branchId?: string;
6922
+ /** For phase === 'flush', the batch size + entry index. */
6923
+ batch?: FlowStateBatch;
6924
+ /** Discriminator when phase === 'skip'. */
6925
+ skipReason?: 'consent' | 'cache_hit' | 'sampled_out' | 'disabled' | 'unknown';
6926
+ /** Free-form metadata: store key/value, cached: true, etc. */
6927
+ meta?: Record<string, unknown>;
6928
+ }
6929
+
6930
+ /**
6931
+ * Pipeline observation channel. Observers receive a FlowState record per
6932
+ * step phase (init, in, out, error, skip, flush) and run synchronously in
6933
+ * the collector's emit loop. They must not throw; emitStep swallows
6934
+ * thrown values defensively so a slow or buggy observer cannot crash the
6935
+ * pipeline. Observers must not perform synchronous IO.
6936
+ */
6937
+ type ObserverFn = (state: FlowState) => void;
6938
+
6871
6939
  /**
6872
6940
  * Drop counters at a single step. Each buffer is optional: a step kind
6873
6941
  * may have only `queue` (collector), only `dlq`, both (destinations
@@ -7038,6 +7106,15 @@ interface Instance$5 {
7038
7106
  stores: Stores;
7039
7107
  globals: Properties;
7040
7108
  hooks: Functions;
7109
+ /**
7110
+ * First-class observation channel. The runtime self-emits FlowState
7111
+ * records at canonical step sites (collector.push, destination.push,
7112
+ * destination.init, destination.pushBatch, destination consent skip,
7113
+ * transformer.push, store.get/set/delete, store cache HIT/MISS).
7114
+ * Observers run synchronously inside emitStep; thrown values are
7115
+ * swallowed. Subscribers add/remove via the standard Set API.
7116
+ */
7117
+ observers: Set<ObserverFn>;
7041
7118
  logger: Instance$3;
7042
7119
  on: OnConfig;
7043
7120
  queue: Events;
@@ -8248,6 +8325,29 @@ declare namespace Flow {
8248
8325
  * Consumed by the CLI bundler at build time.
8249
8326
  */
8250
8327
  bundle?: Bundle;
8328
+ /**
8329
+ * Observability configuration. Controls whether the runtime emits
8330
+ * FlowState records to a remote observer, and at what verbosity.
8331
+ *
8332
+ * When omitted, the runtime defaults to `{ level: 'standard' }` for
8333
+ * managed deployments. When `level: 'off'`, the bundle ships no
8334
+ * telemetry plumbing at all.
8335
+ */
8336
+ observe?: Observe;
8337
+ }
8338
+ /**
8339
+ * Observability configuration block.
8340
+ *
8341
+ * - `off` disables telemetry entirely (no hooks installed, no fetch).
8342
+ * - `standard` emits structural FlowState records (no inEvent/outEvent).
8343
+ * - `trace` emits full payloads on every hop. Use only for short debug
8344
+ * windows; the operator can also flip the deployment's `trace_until`
8345
+ * timestamp at runtime to enable trace without a redeploy.
8346
+ */
8347
+ interface Observe {
8348
+ level?: 'off' | 'standard' | 'trace';
8349
+ /** Deterministic sample fraction in [0, 1]. Defaults to 1. */
8350
+ sample?: number;
8251
8351
  }
8252
8352
  /**
8253
8353
  * Reusable values referenced via `$var.name` (with optional deep paths).
package/dist/dev.d.ts CHANGED
@@ -6868,6 +6868,74 @@ interface Ingest {
6868
6868
  _meta: IngestMeta;
6869
6869
  }
6870
6870
 
6871
+ /**
6872
+ * FlowState is the canonical observation record emitted at each hop in a
6873
+ * walkerOS pipeline. Telemetry helpers populate one of these per (step,
6874
+ * phase) tuple and pass it to a user-supplied emit callback. The shape is
6875
+ * stable across step kinds (source, transformer, collector, destination,
6876
+ * store) so a single observer can correlate work across the pipeline.
6877
+ *
6878
+ * Optional fields are populated only when meaningful for the (step, phase)
6879
+ * pair, or when the telemetry options explicitly opt in (e.g. trace level
6880
+ * for inEvent/outEvent).
6881
+ */
6882
+ type FlowStatePhase = 'init' | 'in' | 'out' | 'error' | 'skip' | 'flush';
6883
+ type FlowStepType = 'source' | 'transformer' | 'collector' | 'destination' | 'store';
6884
+ interface FlowStateBatch {
6885
+ size: number;
6886
+ index: number;
6887
+ }
6888
+ interface FlowState {
6889
+ /** The flow this state belongs to. */
6890
+ flowId: string;
6891
+ /** Step identifier, e.g. 'destination.gtag', 'transformer.consent', 'collector.push'. */
6892
+ stepId: string;
6893
+ stepType: FlowStepType;
6894
+ phase: FlowStatePhase;
6895
+ /** W3C span-id of the originating WalkerOS.Event. Sourced from event.id; never synthesized. */
6896
+ eventId: string;
6897
+ /** ISO 8601 timestamp. */
6898
+ timestamp: string;
6899
+ /** Milliseconds since the runtime's startedAt origin. Monotonic. */
6900
+ elapsedMs: number;
6901
+ /** Wall-clock duration of this step, if measured (typically only on 'out'). */
6902
+ durationMs?: number;
6903
+ /** Inbound walker event for this hop. Only populated when level === 'trace' or includeIn === true. */
6904
+ inEvent?: unknown;
6905
+ /** Outbound walker event/payload for this hop. Only populated when level === 'trace' or includeOut === true. */
6906
+ outEvent?: unknown;
6907
+ /** Error info when phase === 'error'. */
6908
+ error?: {
6909
+ name?: string;
6910
+ message: string;
6911
+ };
6912
+ /** The mapping rule that matched, when one matched. */
6913
+ mappingKey?: string;
6914
+ /** Contract rule that matched, if any. */
6915
+ contractRule?: string;
6916
+ /** Consent gate snapshot at hop time. */
6917
+ consent?: Record<string, boolean>;
6918
+ /** Consent state actually applied (after policy resolution). */
6919
+ consentApplied?: Record<string, boolean>;
6920
+ /** W3C 16-hex span-id of the child branch for `many` fan-out. */
6921
+ branchId?: string;
6922
+ /** For phase === 'flush', the batch size + entry index. */
6923
+ batch?: FlowStateBatch;
6924
+ /** Discriminator when phase === 'skip'. */
6925
+ skipReason?: 'consent' | 'cache_hit' | 'sampled_out' | 'disabled' | 'unknown';
6926
+ /** Free-form metadata: store key/value, cached: true, etc. */
6927
+ meta?: Record<string, unknown>;
6928
+ }
6929
+
6930
+ /**
6931
+ * Pipeline observation channel. Observers receive a FlowState record per
6932
+ * step phase (init, in, out, error, skip, flush) and run synchronously in
6933
+ * the collector's emit loop. They must not throw; emitStep swallows
6934
+ * thrown values defensively so a slow or buggy observer cannot crash the
6935
+ * pipeline. Observers must not perform synchronous IO.
6936
+ */
6937
+ type ObserverFn = (state: FlowState) => void;
6938
+
6871
6939
  /**
6872
6940
  * Drop counters at a single step. Each buffer is optional: a step kind
6873
6941
  * may have only `queue` (collector), only `dlq`, both (destinations
@@ -7038,6 +7106,15 @@ interface Instance$5 {
7038
7106
  stores: Stores;
7039
7107
  globals: Properties;
7040
7108
  hooks: Functions;
7109
+ /**
7110
+ * First-class observation channel. The runtime self-emits FlowState
7111
+ * records at canonical step sites (collector.push, destination.push,
7112
+ * destination.init, destination.pushBatch, destination consent skip,
7113
+ * transformer.push, store.get/set/delete, store cache HIT/MISS).
7114
+ * Observers run synchronously inside emitStep; thrown values are
7115
+ * swallowed. Subscribers add/remove via the standard Set API.
7116
+ */
7117
+ observers: Set<ObserverFn>;
7041
7118
  logger: Instance$3;
7042
7119
  on: OnConfig;
7043
7120
  queue: Events;
@@ -8248,6 +8325,29 @@ declare namespace Flow {
8248
8325
  * Consumed by the CLI bundler at build time.
8249
8326
  */
8250
8327
  bundle?: Bundle;
8328
+ /**
8329
+ * Observability configuration. Controls whether the runtime emits
8330
+ * FlowState records to a remote observer, and at what verbosity.
8331
+ *
8332
+ * When omitted, the runtime defaults to `{ level: 'standard' }` for
8333
+ * managed deployments. When `level: 'off'`, the bundle ships no
8334
+ * telemetry plumbing at all.
8335
+ */
8336
+ observe?: Observe;
8337
+ }
8338
+ /**
8339
+ * Observability configuration block.
8340
+ *
8341
+ * - `off` disables telemetry entirely (no hooks installed, no fetch).
8342
+ * - `standard` emits structural FlowState records (no inEvent/outEvent).
8343
+ * - `trace` emits full payloads on every hop. Use only for short debug
8344
+ * windows; the operator can also flip the deployment's `trace_until`
8345
+ * timestamp at runtime to enable trace without a redeploy.
8346
+ */
8347
+ interface Observe {
8348
+ level?: 'off' | 'standard' | 'trace';
8349
+ /** Deterministic sample fraction in [0, 1]. Defaults to 1. */
8350
+ sample?: number;
8251
8351
  }
8252
8352
  /**
8253
8353
  * Reusable values referenced via `$var.name` (with optional deep paths).
package/dist/index.d.mts CHANGED
@@ -220,6 +220,74 @@ interface Ingest {
220
220
  /** Create a fresh Ingest for a new pipeline invocation. */
221
221
  declare function createIngest(sourceId: string): Ingest;
222
222
 
223
+ /**
224
+ * FlowState is the canonical observation record emitted at each hop in a
225
+ * walkerOS pipeline. Telemetry helpers populate one of these per (step,
226
+ * phase) tuple and pass it to a user-supplied emit callback. The shape is
227
+ * stable across step kinds (source, transformer, collector, destination,
228
+ * store) so a single observer can correlate work across the pipeline.
229
+ *
230
+ * Optional fields are populated only when meaningful for the (step, phase)
231
+ * pair, or when the telemetry options explicitly opt in (e.g. trace level
232
+ * for inEvent/outEvent).
233
+ */
234
+ type FlowStatePhase = 'init' | 'in' | 'out' | 'error' | 'skip' | 'flush';
235
+ type FlowStepType = 'source' | 'transformer' | 'collector' | 'destination' | 'store';
236
+ interface FlowStateBatch {
237
+ size: number;
238
+ index: number;
239
+ }
240
+ interface FlowState {
241
+ /** The flow this state belongs to. */
242
+ flowId: string;
243
+ /** Step identifier, e.g. 'destination.gtag', 'transformer.consent', 'collector.push'. */
244
+ stepId: string;
245
+ stepType: FlowStepType;
246
+ phase: FlowStatePhase;
247
+ /** W3C span-id of the originating WalkerOS.Event. Sourced from event.id; never synthesized. */
248
+ eventId: string;
249
+ /** ISO 8601 timestamp. */
250
+ timestamp: string;
251
+ /** Milliseconds since the runtime's startedAt origin. Monotonic. */
252
+ elapsedMs: number;
253
+ /** Wall-clock duration of this step, if measured (typically only on 'out'). */
254
+ durationMs?: number;
255
+ /** Inbound walker event for this hop. Only populated when level === 'trace' or includeIn === true. */
256
+ inEvent?: unknown;
257
+ /** Outbound walker event/payload for this hop. Only populated when level === 'trace' or includeOut === true. */
258
+ outEvent?: unknown;
259
+ /** Error info when phase === 'error'. */
260
+ error?: {
261
+ name?: string;
262
+ message: string;
263
+ };
264
+ /** The mapping rule that matched, when one matched. */
265
+ mappingKey?: string;
266
+ /** Contract rule that matched, if any. */
267
+ contractRule?: string;
268
+ /** Consent gate snapshot at hop time. */
269
+ consent?: Record<string, boolean>;
270
+ /** Consent state actually applied (after policy resolution). */
271
+ consentApplied?: Record<string, boolean>;
272
+ /** W3C 16-hex span-id of the child branch for `many` fan-out. */
273
+ branchId?: string;
274
+ /** For phase === 'flush', the batch size + entry index. */
275
+ batch?: FlowStateBatch;
276
+ /** Discriminator when phase === 'skip'. */
277
+ skipReason?: 'consent' | 'cache_hit' | 'sampled_out' | 'disabled' | 'unknown';
278
+ /** Free-form metadata: store key/value, cached: true, etc. */
279
+ meta?: Record<string, unknown>;
280
+ }
281
+
282
+ /**
283
+ * Pipeline observation channel. Observers receive a FlowState record per
284
+ * step phase (init, in, out, error, skip, flush) and run synchronously in
285
+ * the collector's emit loop. They must not throw; emitStep swallows
286
+ * thrown values defensively so a slow or buggy observer cannot crash the
287
+ * pipeline. Observers must not perform synchronous IO.
288
+ */
289
+ type ObserverFn = (state: FlowState) => void;
290
+
223
291
  /** Identifies which kind of step a stepId belongs to. */
224
292
  type StepKind = 'collector' | 'source' | 'transformer' | 'destination';
225
293
  /**
@@ -404,6 +472,15 @@ interface Instance$6 {
404
472
  stores: Stores$1;
405
473
  globals: Properties;
406
474
  hooks: Functions;
475
+ /**
476
+ * First-class observation channel. The runtime self-emits FlowState
477
+ * records at canonical step sites (collector.push, destination.push,
478
+ * destination.init, destination.pushBatch, destination consent skip,
479
+ * transformer.push, store.get/set/delete, store cache HIT/MISS).
480
+ * Observers run synchronously inside emitStep; thrown values are
481
+ * swallowed. Subscribers add/remove via the standard Set API.
482
+ */
483
+ observers: Set<ObserverFn>;
407
484
  logger: Instance$3;
408
485
  on: OnConfig;
409
486
  queue: Events;
@@ -1290,6 +1367,29 @@ declare namespace Flow {
1290
1367
  * Consumed by the CLI bundler at build time.
1291
1368
  */
1292
1369
  bundle?: Bundle;
1370
+ /**
1371
+ * Observability configuration. Controls whether the runtime emits
1372
+ * FlowState records to a remote observer, and at what verbosity.
1373
+ *
1374
+ * When omitted, the runtime defaults to `{ level: 'standard' }` for
1375
+ * managed deployments. When `level: 'off'`, the bundle ships no
1376
+ * telemetry plumbing at all.
1377
+ */
1378
+ observe?: Observe;
1379
+ }
1380
+ /**
1381
+ * Observability configuration block.
1382
+ *
1383
+ * - `off` disables telemetry entirely (no hooks installed, no fetch).
1384
+ * - `standard` emits structural FlowState records (no inEvent/outEvent).
1385
+ * - `trace` emits full payloads on every hop. Use only for short debug
1386
+ * windows; the operator can also flip the deployment's `trace_until`
1387
+ * timestamp at runtime to enable trace without a redeploy.
1388
+ */
1389
+ interface Observe {
1390
+ level?: 'off' | 'standard' | 'trace';
1391
+ /** Deterministic sample fraction in [0, 1]. Defaults to 1. */
1392
+ sample?: number;
1293
1393
  }
1294
1394
  /**
1295
1395
  * Reusable values referenced via `$var.name` (with optional deep paths).
@@ -3406,18 +3506,193 @@ declare class FatalError extends Error {
3406
3506
  * A utility function that wraps a function with hooks.
3407
3507
  *
3408
3508
  * Pre/post hooks are user-supplied and may throw. A throwing hook must not
3409
- * crash the surrounding pipeline on failure, fall back to calling the
3509
+ * crash the surrounding pipeline. On failure, fall back to calling the
3410
3510
  * original function (pre-hook) or keep the original result (post-hook).
3411
3511
  *
3412
- * @template P, R
3512
+ * The generic `F` preserves the exact call shape of `fn`, including named
3513
+ * parameters and overloaded interfaces, so call sites can assign the result
3514
+ * to the same interface slot without a cast.
3515
+ *
3516
+ * @template F The exact function type being wrapped.
3413
3517
  * @param fn The function to wrap.
3414
3518
  * @param name The name of the function.
3415
3519
  * @param hooks The hooks to use.
3416
3520
  * @param logger Optional logger for hook failure warnings. Falls back to
3417
3521
  * `console.warn` when not provided.
3418
- * @returns The wrapped function.
3522
+ * @returns The wrapped function with the same call shape as `fn`.
3523
+ */
3524
+ declare function useHooks<F extends AnyFunction$1>(fn: F, name: string, hooks: Functions, logger?: Instance$3): F;
3525
+
3526
+ /**
3527
+ * Telemetry level. Off disables emission entirely. Standard projects
3528
+ * structural state without inEvent or outEvent payloads (unless explicitly
3529
+ * opted in). Trace emits full payloads on every hop.
3530
+ */
3531
+ type TelemetryLevel = 'off' | 'standard' | 'trace';
3532
+ /**
3533
+ * Options that shape the telemetry projection strategy. Defaults are chosen
3534
+ * so a caller can pass `{ flowId }` and get sensible behavior.
3535
+ */
3536
+ interface TelemetryOptions {
3537
+ /** Required flow identifier; observers may use this for cross-flow correlation. */
3538
+ flowId: string;
3539
+ /** Verbosity. Defaults to 'standard'. */
3540
+ level?: TelemetryLevel;
3541
+ /** Force-include the inbound event regardless of level. */
3542
+ includeIn?: boolean;
3543
+ /** Force-include the outbound event regardless of level. */
3544
+ includeOut?: boolean;
3545
+ /** Force-include the matched mapping key (only meaningful for transformers/destinations). */
3546
+ includeMappingKey?: boolean;
3547
+ /**
3548
+ * Fraction of events to emit, between 0 and 1. Deterministic by eventId:
3549
+ * the same eventId always falls on the same side of the threshold so
3550
+ * paired in/out states either both emit or both drop.
3551
+ */
3552
+ sample?: number;
3553
+ }
3554
+ type EmitFn = (state: FlowState) => void;
3555
+ /**
3556
+ * Optional supplier form. When passed instead of static `TelemetryOptions`,
3557
+ * the observer evaluates the supplier on every emit so toggle-style runtime
3558
+ * overrides (e.g. `WALKEROS_TRACE_UNTIL`) reach the projection without
3559
+ * rebuilding the observer.
3560
+ */
3561
+ type TelemetryOptionsSupplier = () => TelemetryOptions | null;
3562
+ /**
3563
+ * Build a telemetry observer that projects FlowState records according to
3564
+ * level/sample/include flags and forwards them to `emit`. The observer is
3565
+ * synchronous, never throws (a throwing emit is swallowed), and does no
3566
+ * IO of its own. Designed to be added to `collector.observers` so the
3567
+ * runtime self-emission loop drives it.
3568
+ *
3569
+ * Accepts either a static `TelemetryOptions` value or a supplier
3570
+ * `() => TelemetryOptions | null`. With a supplier, every emit reads the
3571
+ * current opts so toggles such as `WALKEROS_TRACE_UNTIL` reach the
3572
+ * projection without rebuilding the observer. A supplier returning `null`
3573
+ * suppresses the emit (telemetry off).
3574
+ */
3575
+ declare function createTelemetryObserver(emit: EmitFn, optsOrSupplier: TelemetryOptions | TelemetryOptionsSupplier): ObserverFn;
3576
+ /**
3577
+ * Convenience export: the internal sampling predicate so callers (and
3578
+ * tests) can verify the deterministic bucketing without importing the
3579
+ * private FNV-1a helper.
3580
+ */
3581
+ declare function isSampled(eventId: string, sample: number): boolean;
3582
+
3583
+ /**
3584
+ * Runtime telemetry resolver.
3585
+ *
3586
+ * Converts a flow-side `Flow.Config.observe` block plus a runtime override
3587
+ * (the `WALKEROS_TRACE_UNTIL` env var) into a concrete `TelemetryOptions`
3588
+ * the collector hooks installer can consume.
3589
+ *
3590
+ * Resolution order (highest priority first):
3591
+ * 1. `WALKEROS_TRACE_UNTIL` env var, if present and parses to a future ISO
3592
+ * timestamp -> force level=trace, sample=1, include in/out payloads.
3593
+ * 2. The `observe` block from `flow.config?.observe`.
3594
+ * 3. A tier default of `{ level: 'standard' }`.
3595
+ *
3596
+ * The full poll-and-update plumbing that lets an operator flip
3597
+ * `WALKEROS_TRACE_UNTIL` without redeploying the container is intentionally
3598
+ * stubbed at the env-var seam: the deployment record's `trace_until` is
3599
+ * written by the app, but a sidecar/heartbeat that propagates it into the
3600
+ * container is out of scope for this phase. For now an operator sets the
3601
+ * env var directly, or the next deploy picks it up at boot.
3602
+ */
3603
+
3604
+ interface ResolveTelemetryInput {
3605
+ flowId: string;
3606
+ /** From `flow.config?.observe`. May be undefined. */
3607
+ observe?: {
3608
+ level?: 'off' | 'standard' | 'trace';
3609
+ sample?: number;
3610
+ };
3611
+ /** Snapshot of `process.env` (or any equivalent). Test seam. */
3612
+ env?: Record<string, string | undefined>;
3613
+ /** Clock seam for tests. Defaults to `Date.now()`. */
3614
+ now?: () => number;
3615
+ }
3616
+ /**
3617
+ * Returns `TelemetryOptions` ready to pass to `createTelemetryObserver`,
3618
+ * or `null` if telemetry is disabled (`level === 'off'` with no trace
3619
+ * override). Callers should skip observer installation when this returns
3620
+ * null.
3621
+ */
3622
+ declare function resolveTelemetryOptions(input: ResolveTelemetryInput): TelemetryOptions | null;
3623
+
3624
+ /**
3625
+ * Synchronously fans out a FlowState record to every registered observer
3626
+ * on the collector. Each call is wrapped in try/catch so a misbehaving
3627
+ * observer cannot crash the runtime; observers are advisory and must not
3628
+ * affect pipeline outcomes.
3629
+ *
3630
+ * Iterates a snapshot of the observer set so an observer adding or removing
3631
+ * another observer during the emit does not re-enter or skip in the same
3632
+ * pass. The early return on an empty set keeps the zero-observer hot path
3633
+ * allocation-free.
3634
+ */
3635
+ declare function emitStep(collector: Instance$6, state: FlowState): void;
3636
+
3637
+ /**
3638
+ * Batched FlowState poster.
3639
+ *
3640
+ * Buffers FlowState records and flushes them to an HTTP endpoint either when
3641
+ * `batchMs` elapses since the first queued record, or when `batchSize` is
3642
+ * reached. Returns the emit callback that `createTelemetryObserver` consumes.
3643
+ *
3644
+ * Errors from the underlying fetch are swallowed (or routed through the
3645
+ * optional `onError` callback) so a transient observer outage cannot crash
3646
+ * the runtime.
3647
+ *
3648
+ * Uses the global `fetch` so the same primitive works in Node 18+, browsers,
3649
+ * and Edge runtimes. Tests may inject a stub via `opts.fetch`.
3650
+ */
3651
+
3652
+ /**
3653
+ * Minimum HTTP response surface the poster touches. Anything that exposes
3654
+ * `ok` and `status` works. Decoupling from the DOM `Response` type lets the
3655
+ * helper run in Edge, browser, and Node-only test environments without
3656
+ * requiring `lib: dom` or a polyfill.
3657
+ */
3658
+ interface PosterResponse {
3659
+ ok: boolean;
3660
+ status: number;
3661
+ }
3662
+ /**
3663
+ * Minimum fetch surface the poster needs. A subset of `typeof fetch` that
3664
+ * lets test harnesses pass a plain async function without dragging in the
3665
+ * Response/Request DOM types.
3666
+ */
3667
+ type PosterFetch = (url: string, init: {
3668
+ method: string;
3669
+ headers: Record<string, string>;
3670
+ body: string;
3671
+ }) => Promise<PosterResponse>;
3672
+ interface BatchedPosterOptions {
3673
+ /** Absolute HTTP endpoint URL. POST with JSON array body. */
3674
+ url: string;
3675
+ /** Bearer token sent in the `Authorization` header. */
3676
+ token: string;
3677
+ /** Max time to wait before flushing the current batch. Default 50 ms. */
3678
+ batchMs?: number;
3679
+ /** Max records per batch. When reached, flushes immediately. Default 50. */
3680
+ batchSize?: number;
3681
+ /** Test seam. Defaults to the global `fetch`. */
3682
+ fetch?: PosterFetch;
3683
+ /** Called when the underlying POST rejects. Defaults to swallowing. */
3684
+ onError?: (err: unknown) => void;
3685
+ }
3686
+ /**
3687
+ * Build a batched emit callback. The returned function is synchronous, never
3688
+ * throws, and schedules an async flush in the background.
3689
+ *
3690
+ * Concurrency model: a single in-memory buffer plus a single pending timer.
3691
+ * When the timer fires (or `batchSize` is hit) the buffer is moved into a
3692
+ * local variable and reset, then POSTed. New records arriving during the in-
3693
+ * flight POST land in the next batch.
3419
3694
  */
3420
- declare function useHooks<P extends unknown[], R>(fn: (...args: P) => R, name: string, hooks: Functions, logger?: Instance$3): (...args: P) => R;
3695
+ declare function createBatchedPoster(opts: BatchedPosterOptions): (state: FlowState) => void;
3421
3696
 
3422
3697
  /**
3423
3698
  * Parses a user agent string to extract browser, OS, and device information.
@@ -3714,4 +3989,4 @@ declare const REF_STORE: RegExp;
3714
3989
  declare const REF_SECRET: RegExp;
3715
3990
  declare const REF_CODE_PREFIX = "$code:";
3716
3991
 
3717
- export { cache as Cache, type CacheResult, type ClickIdEntry, collector as Collector, type CompiledCache, Const, context as Context, type Debounced, destination as Destination, type DestroyContext, type DestroyFn, type DroppedCounters, ENV_MARKER_PREFIX, elb as Elb, type ExampleSummary, FatalError, Flow, type FlowConfigResolver, hint as Hint, hooks as Hooks, type Ingest, type IngestMeta, type JsonSchema, Level, lifecycle as Lifecycle, type LifecycleContext, logger as Logger, mapping as Mapping, type MarketingParameters, matcher as Matcher, type MockLogger, on as On, REF_CODE_PREFIX, REF_CONTRACT, REF_ENV, REF_FLOW, REF_SECRET, REF_STORE, REF_VAR_FULL, REF_VAR_INLINE, request as Request, type ResolveOptions, type RespondFn, type RespondOptions, STEP_OPERATIVE_FIELDS, type ScheduleOptions, type SendDataValue, type SendHeaders, type SendResponse, type SetupFn, simulation as Simulation, source as Source, type StepEntryErrorCode, type StepEntryValidation, type StepKind, type StorageType, store as Store, transformer as Transformer, trigger as Trigger, type Validate, type ValidateEvents, walkeros as WalkerOS, type WalkerOSPackage, type WalkerOSPackageInfo, type WalkerOSPackageMeta, anonymizeIP, applyUpdate, assign, branch, buildCacheContext, castToProperty, castValue, checkCache, clone, compileCache, compileMatcher, createDestination, createEvent, createIngest, createLogger, createMockContext, createMockLogger, createRespond, debounce, deepMerge, defaultClickIds, deleteByPath, fetchPackage, fetchPackageSchema, filterValues, flattenIncludeSections, formatOut, getBrowser, getBrowserVersion, getByPath, getDeviceType, getEvent, getFlowSettings, getGrantedConsent, getHeaders, getId, getMappingEvent, getMappingValue, getMarketingParameters, getNextSteps, getOS, getOSVersion, getPlatform, getSpanId, isArguments, isArray, isBoolean, isCommand, isDefined, isElementOrDocument, isFunction, isNumber, isObject, isPathStepEntry, isPropertyType, isSameType, isString, mcpError, mcpResult, mergeContractSchemas, mergeMappingRule, mockEnv, packageNameToVariable, parseUserAgent, processEventMapping, requestToData, requestToParameter, resolveContracts, resolveSetup, setByPath, stepId, storeCache, throttle, throwError, transformData, traverseEnv, trim, tryCatch, tryCatchAsync, useHooks, validateStepEntry, walkPath, wrapCondition, wrapFn, wrapValidate };
3992
+ export { type BatchedPosterOptions, cache as Cache, type CacheResult, type ClickIdEntry, collector as Collector, type CompiledCache, Const, context as Context, type Debounced, destination as Destination, type DestroyContext, type DestroyFn, type DroppedCounters, ENV_MARKER_PREFIX, elb as Elb, type EmitFn, type ExampleSummary, FatalError, Flow, type FlowConfigResolver, type FlowState, type FlowStateBatch, type FlowStatePhase, type FlowStepType, hint as Hint, hooks as Hooks, type Ingest, type IngestMeta, type JsonSchema, Level, lifecycle as Lifecycle, type LifecycleContext, logger as Logger, mapping as Mapping, type MarketingParameters, matcher as Matcher, type MockLogger, type ObserverFn, on as On, type PosterFetch, type PosterResponse, REF_CODE_PREFIX, REF_CONTRACT, REF_ENV, REF_FLOW, REF_SECRET, REF_STORE, REF_VAR_FULL, REF_VAR_INLINE, request as Request, type ResolveOptions, type RespondFn, type RespondOptions, STEP_OPERATIVE_FIELDS, type ScheduleOptions, type SendDataValue, type SendHeaders, type SendResponse, type SetupFn, simulation as Simulation, source as Source, type StepEntryErrorCode, type StepEntryValidation, type StepKind, type StorageType, store as Store, type TelemetryLevel, type TelemetryOptions, type TelemetryOptionsSupplier, transformer as Transformer, trigger as Trigger, type Validate, type ValidateEvents, walkeros as WalkerOS, type WalkerOSPackage, type WalkerOSPackageInfo, type WalkerOSPackageMeta, anonymizeIP, applyUpdate, assign, branch, buildCacheContext, castToProperty, castValue, checkCache, clone, compileCache, compileMatcher, createBatchedPoster, createDestination, createEvent, createIngest, createLogger, createMockContext, createMockLogger, createRespond, createTelemetryObserver, debounce, deepMerge, defaultClickIds, deleteByPath, emitStep, fetchPackage, fetchPackageSchema, filterValues, flattenIncludeSections, formatOut, getBrowser, getBrowserVersion, getByPath, getDeviceType, getEvent, getFlowSettings, getGrantedConsent, getHeaders, getId, getMappingEvent, getMappingValue, getMarketingParameters, getNextSteps, getOS, getOSVersion, getPlatform, getSpanId, isArguments, isArray, isBoolean, isCommand, isDefined, isElementOrDocument, isFunction, isNumber, isObject, isPathStepEntry, isPropertyType, isSameType, isSampled, isString, mcpError, mcpResult, mergeContractSchemas, mergeMappingRule, mockEnv, packageNameToVariable, parseUserAgent, processEventMapping, requestToData, requestToParameter, resolveContracts, resolveSetup, resolveTelemetryOptions, setByPath, stepId, storeCache, throttle, throwError, transformData, traverseEnv, trim, tryCatch, tryCatchAsync, useHooks, validateStepEntry, walkPath, wrapCondition, wrapFn, wrapValidate };