import { default as Render } from './render'; import { default as Select } from './select'; import { default as Store, Optgroup, Option } from './store'; /** Where a change originated — affects batching and render behavior. */ export type ChangeSource = 'native' | 'ui' | 'api'; export interface SyncEvents { afterChange?: (newVal: Option[]) => void; error?: (err: Error) => void; } /** * A single unit of work in the sync queue. * Structure = replace option list; selection = change selected only; addOption = append one. */ export type SyncChange = { type: 'structure'; data: (Partial)[]; source: ChangeSource; /** Keep current selection when replacing data (async search results). */ preserveSelection?: boolean; /** API search results — do not update the catalog baseline. */ isSearchResult?: boolean; } | { type: 'selection'; values: string | string[]; source: ChangeSource; /** false when Vue/parent is pushing modelValue down (avoid emit loop). */ runAfterChange?: boolean; } | { type: 'addOption'; option: Partial)[]): boolean; /** * Resolve setSelected() arguments to option ids. * Accepts either ids or values for backward compatibility. */ export declare function resolveSelectedIds(store: Store, values: string | string[]): string[]; export default class SyncCoordinator { private deps; private queue; private flushScheduled; /** True while applyChange is running — prevents re-entrant flush loops. */ isSyncing: boolean; constructor(deps: SyncDeps); enqueue(change: SyncChange): void; /** Process everything in the queue. Callable from tests for deterministic native sync. */ flush(): void; /** * Collapse a batch into the minimum work needed. * Structure sync already includes selection from getData(), so drop redundant * selection changes in the same batch. When multiple structure updates arrive, * only the last one wins. */ private coalesceBatch; private applyChange; /** * Full sync: store → native to current selection (form truth). * When selected options are missing from the native DOM (e.g. picked from API * search results), rebuild from selected options only — never from search hits. */ private syncNativeSelection; /** * Lightweight selection sync: flip option.selected on native DOM only. * Avoids select.updateOptions() (innerHTML rebuild) for selection-only changes * when the options already exist on the native select. */ private applySelection; /** Append a single option then full-sync native + render (same as legacy addOption). */ private applyAddOption; }