/** * MT-side SharedValue bridge — publishes MT-thread mutations to BG. * * Diffs every registered SharedValue against its last-published snapshot * and dispatches one batched `Lynx.Sigx.AvPublish` event per flush boundary * with the changed `[wvid, value]` tuples. The BG side ingests these via * `@sigx/lynx-runtime/src/animated-bridge.ts` and writes them into the * mirror signal so any sigx `effect` reading `sv.value` re-runs. * * Bridge state (`bridgedAvWvids` / `bridgedAvLastValues`) lives in * `ops-apply.ts` because the BG→MT op handlers mutate it; this module * imports the references and reads them on every flush. * * Three flush hook points: * 1. `ops-apply.ts` calls `flushAvBridgePublishes()` at its tail (covers * every BG-driven ops batch). * 2. `installAvBridgeFlushHook()` wraps `globalThis.__FlushElementTree` * so spontaneous MT writes (e.g. a touchmove worklet that eventually * calls `setStyleProperties`) also trigger a publish on the same * tick the native tree flushes. Called once from `entry-main.ts` * after PAPI globals are present. * 3. `armAvAutoFlush()` (below) makes the SharedValue envelope itself * schedule a flush on every write, so a worklet that ONLY writes * `sv.current.value` — no style call, no manual flush — still repaints * the same frame. Installed per-wvid by the `OP.REGISTER_AV_BRIDGE` * handler. * * Coalescing: `===` per-wvid diff. Identical writes are filtered. N writes * within one flush window collapse to one BG event with N entries. */ /** * Diff registered AVs against their last-published snapshots; dispatch one * batched `Lynx.Sigx.AvPublish` event with all changed tuples. No-op when * the bridge set is empty or when nothing has changed since the last call. */ export declare function flushAvBridgePublishes(): void; /** * Register a binding (called from the OP.REGISTER_AV_STYLE_BINDING op * handler in `ops-apply.ts`). Initializes `lastValue` to a sentinel so the * first flush always applies the mapper, even when the AV is at its initial. */ export declare function registerAnimatedStyleBinding(bindingId: number, elementWvid: number, avWvid: number, mapperName: string, params: unknown): void; export declare function unregisterAnimatedStyleBinding(bindingId: number): void; export declare function resetAnimatedStyleBindings(): void; export declare function animatedStyleBindingCount(): number; /** Reset hook (tests) — re-arm the once-per-element dup-transform warning. */ export declare function resetDuplicateTransformWarnings(): void; /** * For each element with at least one *dirty* binding (AV value changed since * the last apply), re-run **all** of that element's bindings, merge their * mapper outputs, and apply the result with a single `setStyleProperties` * call. Called from the wrapped `__FlushElementTree` *before* the native * tree flush. * * Why "all bindings on a dirty element" rather than "only changed bindings": * - Multiple bindings on the same element can write the same style key * (e.g. `translateX` + `translateY` both produce `transform`). If we * applied only the changed ones, the unchanged-binding's contribution * would be lost and the element would visibly snap. By re-running every * binding on the dirty element and merging, all contributions land in * the same `setStyleProperties` call. * * Merge semantics: * - `transform` values from multiple bindings *concatenate* in registration * order (e.g. `translateX(50px)` + `translateY(20px)` -> * `translateX(50px) translateY(20px)`). * - All other keys merge by last-write-wins; a binding registered later on * the same element overwrites an earlier binding's same-key output. * * Skip cases (silent, by design): * - AV ref missing in `_workletRefMap` (race with unregister). * - Element ref's `current` is null (component not yet mounted, or * unmounted before the binding's UNREGISTER op landed). * - Mapper name not registered (typo or missing custom registration). */ export declare function flushAnimatedStyleBindings(): void; /** * Wrap `globalThis.__FlushElementTree` once so every flush also runs the AV * bridge publish step. Idempotent — safe to call across hot reloads. Test * setups that `vi.stubGlobal('__FlushElementTree', ...)` AFTER this hook * installs will replace our wrapper, which is the correct behavior for * unit tests that drive `flushAvBridgePublishes` directly. */ export declare function installAvBridgeFlushHook(): void; /** * Arm auto-flush on a registered SharedValue: convert the MT envelope's * `value` data property into a get/set pair whose setter schedules a * coalesced flush after storing the write. * * The accessor is defined on the EXISTING envelope object (identity * preserved) because worklet captures resolve `{_wvid}` to the same entry * via upstream's `getFromWorkletRefMap` — past and future captures all see * the setter. Safe against upstream: its worklet runtime only creates * ref-map entries if missing (`updateWorkletRefInitValueChanges`) and only * reassigns `.current` for element refs (`main-thread:ref` path), never for * SharedValue envelopes. * * Bails silently — preserving the old boundary-driven behavior — when the * envelope is missing (register raced release), isn't an object, `value` * is already an accessor (double-register), or `defineProperty` refuses. */ export declare function armAvAutoFlush(wvid: number): void;