/** * Canonical event writer. Validates with Zod, writes to Cloudflare Analytics * Engine. No-ops gracefully when `env.EVENTS` is missing — local dev or bots * that don't ship telemetry don't need to wire up an AE binding. * * Generic over the event schema so consumers (e.g. a multi-tenant SaaS with * its own event union) can plug in their schema + numeric-field extractor + * id-field selector while reusing the validation, stamping, blob-shape, and * AE-write infrastructure. The default form uses `FrameworkEventSchema` and * is what `Agent` wires internally. * * AE convention (blobs / doubles / indexes): * blobs[0] = event type * blobs[1] = tenantId (empty string if none) * blobs[2] = idField(event) — defaults to ev.whatsapp ?? '' * blobs[3] = traceId * blobs[4] = full JSON of the validated event * indexes[0] = tenantId (for sample-by-tenant in AE queries) * doubles[] = numeric fields auto-extracted from the payload */ import type { z } from 'zod'; import { type FrameworkEvent, type FrameworkEventInput } from './schemas.js'; export type Emit = (input: TInput) => Promise; export interface EventsBindings { EVENTS?: AnalyticsEngineDataset; } export interface EmitOptions { env: EventsBindings; tenantId?: string; /** Defaults to `FrameworkEventSchema`. Consumers pass their own discriminated union. */ schema?: z.ZodType; /** Defaults to extracting `latencyMs`/`planId`/`day` from `FrameworkEvent`. */ extractDoubles?: (ev: TEvent) => number[]; /** What goes in `blobs[2]`. Defaults to `ev.whatsapp ?? ''`. */ idField?: (ev: TEvent) => string; } /** Minimum shape every event must have after `stampBase` runs. */ interface StampedEvent { v: 1; ts: string; traceId: string; type: string; tenantId?: string; } /** * Build an `emit` callable bound to a specific env + tenant + schema. Returned * function is what gets passed to stores (`emit?: Emit`). */ export declare function makeEmit(opts: EmitOptions): Emit; export {}; //# sourceMappingURL=emit.d.ts.map