/** * Browser-side interaction observation. D7. * * This is the collector, and it collects only what the hard constraints need to * be checkable. Notably it does **not** record what was typed, where a pointer * moved, or any field value: the impossible-idle-action constraint needs to know * *whether* interaction occurred, not what it contained. * * No platform API is used outside this directory, per D7: `src/core/` stays free * of DOM types so the same model runs on either side of the wire. */ /** Counters for one field, or for a form as a whole. */ export type InteractionCounts = { /** Pointer events: down, move within the element, up. */ readonly pointer: number; /** Key events. Count only, never which keys. */ readonly keyboard: number; /** Paste, drop, and autofill-shaped input with no preceding keystroke. */ readonly injected: number; /** Milliseconds from first interaction to submission, or `undefined`. */ readonly durationMs: number | undefined; /** Whether the field held a value at submission. */ readonly populated: boolean; }; export declare const EMPTY_COUNTS: InteractionCounts; /** * Minimal surface the collector needs, so it can be tested without a DOM and * without a headless browser. Any `HTMLElement` satisfies it structurally. */ export type Observable = { addEventListener(type: string, listener: (event: unknown) => void, options?: unknown): void; removeEventListener(type: string, listener: (event: unknown) => void, options?: unknown): void; }; export type ValueSource = { /** Whether the watched input currently holds a value. */ hasValue(): boolean; }; export type CollectorOptions = { /** Defaults to `Date.now`. Injected for the same reason as D11. */ readonly now?: () => number; }; /** * Watch one element and report interaction counts. * * `stop()` removes every listener. Call it on unmount: a collector that outlives * its element is a leak, and one that keeps counting after submission reports * numbers that describe the wrong interaction. */ export declare function watchInteraction(target: Observable, value: ValueSource, options?: CollectorOptions): { counts: () => InteractionCounts; reset(): void; stop(): void; }; /** * Reduce counts to the observation shape a declared invariant reads. D16. * * The collector produces counters; invariants consume a plain object. Keeping the * reduction here means the invariant never sees browser detail, and the core never * sees a DOM type. */ export declare function toObservation(counts: InteractionCounts): { readonly fieldPopulated: boolean; readonly interactions: number; readonly injected: number; readonly durationMs: number | undefined; }; //# sourceMappingURL=interaction.d.ts.map