Conflict resolution UI
Every handshake-replay store can produce a conflict on reconnect. Rather than building a resolution UI per store, Flux funnels all of them through one callback and one array — this page covers wiring that up, what each button actually calls, and the one place a shallow-merge default isn't enough.
- At least one store registered with replayStrategy: 'handshake' — see core_concepts/conflict_resolution
- @tsworldtech/flux_react or @tsworldtech/flux_next installed, if using the built-in FluxConflictPanel
- Familiarity with api/get_active_conflicts and api/resolve_unified_conflict
Why one panel instead of one per store
The full wiring
useFlux()'s activeConflicts already mirrors the engine's live register — no manual subscription or state management needed.What actually produces a conflict
replayStrategy: 'handshake' stores can ever reach this panel — fire_and_forget stores have no server-state comparison to conflict against in the first place.What each button actually calls
resolveUnifiedConflict().The Merge view's shallow-spread limit
QueueConfig.mergeHandler only applies to dedupeStrategy: 'replace' — merging two queued entries before either is sent. It has no role in resolving a conflict against server state. For nested-object conflicts, build custom merge logic inside queueConfig.onConflict instead.
Discard vs. resolve — two different calls
Quick path — import it as-is
Why this one is worth copying instead
Full source — copy this into your project
Everything driven by onResolve/onAbandon stays identical once copied — only the visual layer is meant to change.
A licensing note
Because the conflict register aggregates frames across stores into a single immutable array, you can mount FluxConflictPanel globally at your application root. It automatically unmounts when all conflicting records are resolved or abandoned.
For the two-pass handshake mechanics behind every conflict shown here, see core_concepts/conflict_resolution. For the register's internal lifecycle, see api/get_active_conflicts and api/resolve_unified_conflict. For the offline upload pattern, which uses a similar copy-vs-import tradeoff, see offline/upload_pattern.