import { C as ComponentMountPayload, a as ComponentUnmountPayload, V as VariableRecord } from './lifecycle-DRSAPNpC.js'; /** * @eeko/sdk - Core Type Definitions * * These types define the public API contract for the Eeko SDK. * Both production (Pusher) and development (WebSocket) adapters implement this interface. * * Wire format: every event handler receives a `{type, context, payload}` * envelope — symmetric with the inbound TriggerCandidate that publishers * upstream consume. The canonical schemas live in @eeko/event-contracts; * the type definitions below are kept in lockstep with the OUTBOUND_EVENTS * registry there. When @eeko/event-contracts is published to npm, these * inline types should become a direct import: * * import type { OutboundEventMap } from '@eeko/event-contracts/outbound' * export type EekoEventMap = OutboundEventMap & { * // SDK-only iframe lifecycle events stay here * component_mount: ComponentMountPayload * component_unmount: ComponentUnmountPayload * } */ /** * All supported event types in the Eeko SDK. * * - component_trigger / component_update / component_dismiss / component_sync — * interactive component lifecycle events from the dispatcher. * - chat_message — unified chat / monetary / subscription / engagement event * from chat-relay (the discriminator is in `payload.type`). * - variable_updated — user variable mutation. * - component_mount / component_unmount — SDK-internal iframe lifecycle * events (NOT delivered over the Pusher wire). */ type EventType = 'component_trigger' | 'component_update' | 'component_dismiss' | 'component_sync' | 'component_mount' | 'component_unmount' | 'chat_message' | 'variable_updated'; /** * Event handler function signature */ type EventHandler = (data: T) => void; /** * SDK State object containing component and user information */ interface EekoSDKState { /** Current component ID */ componentId?: string; /** User ID of the overlay owner */ userId?: string; /** Global configuration applied to all triggers */ globalConfig: Record; /** Variant-specific configuration */ variantConfig: Record; /** Additional state properties */ [key: string]: unknown; } /** * Main SDK interface that widget developers interact with * * @example * ```typescript * window.eekoSDK.on('component_trigger', (envelope) => { * const { componentId } = envelope.context * const { data } = envelope.payload * console.log('Triggered', componentId, data) * }); * ``` */ interface IEekoSDK { on(event: E, handler: EventHandler): void; off(event: E, handler: EventHandler): void; getState(): EekoSDKState; isReady(): boolean; } interface BaseEnvelope { type: T; context: Context; payload: Payload; } interface ComponentEnvelopeContext { userId: string; componentId: string; instanceId?: string; } type ComponentTriggerEnvelope = BaseEnvelope<'component_trigger', ComponentEnvelopeContext, Record>; type ComponentUpdateEnvelope = BaseEnvelope<'component_update', ComponentEnvelopeContext, Record>; type ComponentDismissEnvelope = BaseEnvelope<'component_dismiss', Required, Record>; type ComponentSyncEnvelope = BaseEnvelope<'component_sync', ComponentEnvelopeContext, Record>; type ChatMessageEnvelope = BaseEnvelope<'chat_message', { userId: string; platform?: string; channelId?: string; }, { type: string; [key: string]: unknown; }>; type VariableUpdatedEnvelope = BaseEnvelope<'variable_updated', { userId: string; variableId?: string; source?: string; }, { variable: VariableRecord; }>; /** * Map of event types to the **handler argument shape** — what the runtime * actually passes to `sdk.on(event, handler)` callbacks. For every wire * event this is `envelope.payload` (the canonical developer-facing data); * the runtime bridge unwraps the wire envelope before dispatching to * handlers, so authors never see the `{type, context, payload}` wrapper. * * Iframe lifecycle events (`component_mount`, `component_unmount`) are * SDK-internal and not wire events; they keep their flat payload shape. * * The `*Envelope` types above remain exported for anyone needing the wire * shape (e.g. test fixtures, codec checks) — they're just not the * handler-facing shape. */ interface EekoEventMap { component_trigger: ComponentTriggerEnvelope['payload']; component_update: ComponentUpdateEnvelope['payload']; component_dismiss: ComponentDismissEnvelope['payload']; component_sync: ComponentSyncEnvelope['payload']; component_mount: ComponentMountPayload; component_unmount: ComponentUnmountPayload; chat_message: ChatMessageEnvelope['payload']; variable_updated: VariableUpdatedEnvelope['payload']; } /** * Type-safe window.eekoSDK declaration */ declare global { interface Window { eekoSDK?: IEekoSDK; } } /** * @eeko/sdk — Declarative Widget Interaction Model (`widget.json` `interactions`) * * A FINITE, non-Turing-complete vocabulary that lets a widget describe its * behaviour as DATA instead of hand-written `script.js`: which events it * reacts to, and an ordered list of enumerated actions per event (show/hide * with animation, bind an element to a data point, clone a row per chat * message, fill a progress bar, run a timer, play a sound, wait). * * The interpreter that executes this model ships INSIDE the SDK runtime * (`INTERACTION_RUNTIME_JS`, composed into `RUNTIME_BRIDGE_JS`) so BOTH the * production widget-host and the local `@eeko/cli` dev harness run identical * behaviour behind the one `window.eekoSDK` seam — never coupled to a single * transport. * * Design rules (enforced by the schema + the interpreter): * - No loops, no user-defined variables (only a fixed flat counter scope), * no inline expressions. Repetition only via a kit-managed timer that emits * the internal `timer_tick` event. The model is a finite reaction table, * not a programming language. * - Element targets are the SAME stable `data-eeko-el` ids the visual editor * stamps, so the editor authors interactions by selection and round-trips * them losslessly. * - Every value an action writes is an enumerated, sanitised kind — the * interpreter is a `switch`, never `eval`. Mirrored by a Zod schema in * nexus-api (the authoritative commit-time validator) and the editor * allowlist. * * Browser-safe: a type-only import of `EventType`; zero runtime deps. */ /** A target element, addressed by its stable `data-eeko-el` id (e.g. "el-3"). */ type ElTarget = string; /** * The manifest `behavior` keys a `{ fromBehavior }` binding may read * (runtime list for validation / docs). */ declare const BEHAVIOR_BINDING_KEYS: readonly ["displayDuration", "soundUrl", "soundVolume"]; type BehaviorBindingKey = (typeof BEHAVIOR_BINDING_KEYS)[number]; /** * Resolves to a value at runtime. * - `from` — a dotted path resolved against the merged data * `payload → variantConfig → globalConfig` (own-property walk only, no * bracket/prototype access), e.g. `username`, `user.displayName`. * - `fromVariable` — the latest value of a named user variable the kit tracks * from `variable_updated` events (goal bars / counters). * - `fromCounter` — a value in the kit's fixed flat counter scope. * - `literal` — a constant. * - `fromBehavior` — a reserved read of the manifest `behavior` block. */ type Binding = { from: string; } | { fromVariable: string; } | { fromCounter: string; } | { literal: string | number; } | { fromBehavior: BehaviorBindingKey; }; /** * Optional single-action guard. Skips ONLY the action it is attached to when * the test is false. Deliberately cannot express an else-branch or a chain — * it is structurally incapable of control flow. */ interface Guard { from: string; op: 'present' | 'truthy' | 'eq' | 'gt'; value?: string | number; } /** Numeric style properties an action may write (enumerated). */ type NumericStyleProp = 'width' | 'height' | 'opacity' | '--eeko-progress'; /** Style properties a ratio (numerator/denominator) may fill. */ type RatioStyleProp = 'width' | 'height' | '--eeko-progress'; /** Attributes `set-attr` may write (enumerated; never `style`/`on*`/`srcdoc`). */ type BindableAttr = 'src' | 'alt' | 'title'; /** A map applied to a freshly cloned row's descendants (chat / poll rows). */ type BindingMap = Record; /** * Entrance/exit animation preset names (runtime list for validation / docs). * These map to the `eeko-*` keyframes the widget-host shell already ships, so * editor preview and live overlay agree. Widget CSS must never (re)define them. */ declare const ANIMATION_PRESETS: readonly ["none", "fade", "slide-up", "slide-down", "zoom", "pulse"]; type AnimationPreset = (typeof ANIMATION_PRESETS)[number]; /** * The enumerated action vocabulary. Discriminated on `op`; targets are * `data-eeko-el` ids. ~18 ops, deliberately minimal-but-sufficient for the six * widget archetypes (alert, chat, goal/progress, countdown, poll, banner). */ type Action = { op: 'show'; target: ElTarget; animation?: AnimationPreset; durationMs?: number; onlyIf?: Guard; } | { op: 'hide'; target: ElTarget; animation?: AnimationPreset; durationMs?: number; onlyIf?: Guard; } | { op: 'add-class' | 'remove-class' | 'toggle-class'; target: ElTarget; class: string; onlyIf?: Guard; } | { op: 'set-text'; target: ElTarget; from: Binding; onlyIf?: Guard; } | { op: 'set-attr'; target: ElTarget; attr: BindableAttr; from: Binding; onlyIf?: Guard; } | { op: 'set-style-numeric'; target: ElTarget; prop: NumericStyleProp; from: Binding; unit?: 'px' | '%' | ''; min?: number; max?: number; multiplyBy?: number; onlyIf?: Guard; } | { op: 'set-style-ratio'; target: ElTarget; prop: RatioStyleProp; numerator: Binding; denominator: Binding; unit?: '%'; clamp?: boolean; onlyIf?: Guard; } | { op: 'clone-template'; templateRef: ElTarget; into: ElTarget; bindings: BindingMap; prepend?: boolean; onlyIf?: Guard; } | { op: 'trim-children'; target: ElTarget; max: number; from?: 'oldest' | 'newest'; } | { op: 'show-nth'; container: ElTarget; index: Binding; wrap?: boolean; } | { op: 'start-timer'; timerId: string; intervalMs: number; durationMs?: number; mode: 'interval' | 'countdown'; } | { op: 'stop-timer'; timerId: string; } | { op: 'increment-counter'; counterId: string; by?: number; from?: Binding; } | { op: 'set-counter'; counterId: string; from: Binding; } | { op: 'play-sound'; from?: Binding; url?: string; volume?: number; onlyIf?: Guard; } | { op: 'wait'; ms: number | { fromBehavior: 'displayDuration'; }; }; /** The `op` discriminator values (runtime list for validation / tests). */ declare const ACTION_OPS: readonly ["show", "hide", "add-class", "remove-class", "toggle-class", "set-text", "set-attr", "set-style-numeric", "set-style-ratio", "clone-template", "trim-children", "show-nth", "start-timer", "stop-timer", "increment-counter", "set-counter", "play-sound", "wait"]; type ActionOp = (typeof ACTION_OPS)[number]; /** An ordered, flat list of actions run when an event fires. */ type Sequence = Action[]; /** * The internal, kit-managed event a timer emits. NOT a public SDK event (kept * out of `EVENT_TYPES`) and never sent over any transport — dispatched only * within the interpreter. Its payload carries a kit-formatted `remaining` * string ("04:59") alongside the raw millis for countdown displays. */ declare const TIMER_TICK = "timer_tick"; interface TimerTickPayload { timerId: string; elapsedMs: number; remainingMs: number; /** Kit-formatted mm:ss (or h:mm:ss) string for direct display. */ remaining: string; } /** Events an interaction sequence may bind to: SDK events + the internal tick. */ type InteractionEvent = EventType | typeof TIMER_TICK; /** Queue policy values for rapid repeat events (runtime list for validation / docs). */ declare const QUEUE_POLICIES: readonly ["queue", "replace", "skip"]; /** Queue policy for rapid repeat events (default `queue`, or `behavior.queueBehavior`). */ type QueuePolicy = (typeof QUEUE_POLICIES)[number]; /** * The `interactions` block on `widget.json`. Optional and additive — a widget * with no `interactions` runs exactly as before (the interpreter no-ops). */ interface WidgetInteractions { /** Vocabulary version, for forward-compatible evolution. */ version: 1; /** Event → ordered action sequence. */ on: Partial>; /** Optional per-event queue policy. */ queue?: Partial>; } export { type ActionOp as A, type Binding as B, type EventType as E, type Guard as G, type IEekoSDK as I, type NumericStyleProp as N, type QueuePolicy as Q, type RatioStyleProp as R, type Sequence as S, type TimerTickPayload as T, type WidgetInteractions as W, type EventHandler as a, type EekoSDKState as b, type EekoEventMap as c, type ElTarget as d, type BehaviorBindingKey as e, type BindableAttr as f, type BindingMap as g, type AnimationPreset as h, type Action as i, type InteractionEvent as j, ACTION_OPS as k, ANIMATION_PRESETS as l, BEHAVIOR_BINDING_KEYS as m, QUEUE_POLICIES as n, TIMER_TICK as o };