ConstRegister (or replace) an offline sync handler under a stable id (e.g. "poi").
Registers a step to run BEFORE each outbox drain; null removes it.
🛑 A different registry from Sync.registerHandler, and the distinction is
the point: a handler DRIVES a replay (its processSyncQueue calls the drain), a
step must FINISH before one. Iterating handlers inside the drain would be
re-entrance by construction.
The step is awaited under the drain's own lock, so a drain triggered while it runs cannot overtake it. ⚠️ Its failure is logged and the drain proceeds — a photo that cannot be uploaded is a photo still waiting, not a reason to hold every other capture hostage.
Stable identifier, e.g. "editor:images".
The step, or null to unregister — which a plugin's destroy owes.
Registers the reader of the write session, which Storage.preflight() reports; null
removes it.
The core authenticates nothing, so it cannot know whether captures made off-network will
reach the server: the one holding the token tells it. The connector registers its own
when it manages the session (auth.endpoint); a host that hands its own token over
(getToken) is the only one who knows its expiry, and registers here to say it.
One slot: the last registration wins. The reader must not renew the session — a check
made before leaving writes nothing. It is bounded in time: a reader that throws, or does
not answer within two seconds, leaves session at null without holding up the check.
Answers { state, expiresAt }, or null when it cannot say; synchronously
or with a promise. null unregisters.
Public façade — mounted on
GeoLeaf.Sync; all state lives in the seams it delegates to (SyncHandlerContract,DrainHooksContract,SessionReaderContract).