useWiredTools backs 20 consumers with a 618-line wide state + actions
surface; split it along the read/write seam so it's clear at the
import site whether a view is rendering Wired data or mutating it.
Because the actions need access to setters (setUserVariableAssignments,
setFurniVariableAssignments, ...), this isn't the same pure-action
shape as doorbell/friend-request. Used the useBetween singleton
indirection instead:
- useWiredToolsStore (internal) — the entire previous useWiredToolsState
body, untouched. State + listeners + effects + actions in one
closure.
- useWiredToolsState (public, read-only) — useBetween(useWiredToolsStore)
filtered to the 12 state fields (accountPreferences, roomSettings,
showInspect/Toolbar booleans, variable definitions+assignments,
areUserVariablesLoaded).
- useWiredToolsActions (public, imperative) — same singleton filtered
to the 13 actions (updateAccountPreferences, saveRoomSettings,
requestUserVariables, assignXxx/removeXxx/updateXxx variable
helpers, openMonitor / openInspectionForFurni / openInspectionForUser).
- useWiredTools (deprecated shim) — composes both, preserves the
full historical shape so the 20 existing consumers keep working.
useBetween ensures all four entry points hit the same instance, so the
state + dispatch loop stays a single source of truth. This is also the
shape that a future migration to a Zustand slice would inherit
cleanly — each public hook becomes a slice subscription.