export declare function clone(data: any): any; export declare function omit(data: any, keys: string[]): Record; /** * Structural comparison, deliberately narrow: it recurses into plain objects and * arrays and compares everything else by `Object.is`. * * That narrowness is the point. Anything with a prototype of its own — a `Date`, * a `Map`, a class instance, a DOM node — carries state that own enumerable keys * do not describe, and two distinct `Date`s would otherwise compare equal on an * empty key list. Reporting "not equivalent" for those is the safe answer: the * caller writes, which is what it did before this existed. * * `Object.is` is not an arbitrary choice either — it is exactly the predicate * Vue's `hasChanged` uses, so a value this reports as equivalent is a value Vue * would have refused to trigger on anyway. */ export declare function isEquivalent(a: any, b: any, seen?: WeakMap>): boolean; /** * Copies `state` onto `target`, and reports whether it wrote anything. * * The return value is what the syncs in `plugin-svelte` and the sandbox bridge * use to decide whether to expect an echo. Each holds a flag meaning "the next * firing is mine, ignore it", and that flag is only safe to set when a firing is * actually coming. See #95. * * `plugin-vue` no longer needs it: `createStateBaseline` recognises an echo by * it not being a change, so there is no flag left to keep honest. The two are * the same idea at different strengths, and the others can move across (#96). */ export declare function applyState(target: any, state: any, override?: boolean): boolean; /** * The subset of `next` that differs from `baseline`, shaped so `applyState` can * copy it faithfully: a key it will merge is narrowed to the nested keys that * moved, and everything else is carried whole. `null` when nothing changed. * * The narrowing is what lets two sides edit one object at once without either * clobbering the other — whatever is not sent cannot be overwritten — so it has * to line up with how `applyState` writes, exactly. Both ask `mergesNested`. * A key it refuses, `_h`-prefixed ones included, crosses whole, so concurrent * edits *inside* one of those still race; ordinary story state does not live * there. * * Only keys `next` has are considered. A key `baseline` has and `next` does not * is a removal, which `applyState` cannot express, so reporting it would produce * a write that changes nothing — and, worse, one the baseline would go on * reporting forever. Removals stay unmirrored, exactly as they were. */ export declare function diffState(baseline: any, next: any): Record | null; /** * Tracks the last state both sides of a sync agreed on. * * The syncs used to mirror whole state objects and coordinate with a boolean * meaning "the next firing is my own echo, ignore it". That has two costs. An * echo is only distinguishable from a genuine edit by counting firings, which * is what made the flag load-bearing and fragile (#95). And a side that mirrors * everything it holds also mirrors the keys it did *not* change, stale by one * edit if the far side changed them in the same tick — so the second firing * reverted the first side's edit and it was lost from both (#96). * * A baseline answers both. Ask it for what a side changed and it reports that * side's own edits, never the far side's; an echo diffs to nothing and needs no * flag to recognise, because it is not a change. */ export declare function createStateBaseline(): { /** * What `next` changed since both sides last agreed, or `null` for nothing. * The changes count as agreed from here, so ask once per firing and mirror * what you get. */ take(next: any): Record | null; /** * Take `changes` as agreed without reporting them. * * What a peer just sent is by definition something both sides now hold, and * it must not come back the other way. Two sides sharing one baseline — * `plugin-vue`, where both watchers run in one context — never need this, * because `take` on either side records for both. Two sides holding a * baseline each — the sandbox bridge, split across a `postMessage` — do: * the receiver has to record what arrived, or its own watcher will read the * applied write as a local edit and echo it straight back. */ record(changes: any): void; };