import type { AppDispatch } from "../../store/types"; import type { PushDeviceIdentifier } from "../../interfaces/PushTokenAdapter"; import { type GetSublayState } from "./mintAccountAccessToken"; export interface PushReconcileContext { dispatch: AppDispatch; getState: GetSublayState; projectId: string; } /** * Structural equality for two device identifiers. * * Web subscriptions are objects, so `===` is wrong for them; comparing the * endpoint alone is not enough either, because a browser can re-issue the same * endpoint with fresh keys. */ export declare function pushIdentifiersEqual(a: PushDeviceIdentifier | null | undefined, b: PushDeviceIdentifier | null | undefined): boolean; /** * Binds or unbinds ONE account against this device's stored identifier. * * Takes `enabled` explicitly rather than reading the flag, because the toggle * must apply the new binding BEFORE the flag is written — the SDK may never * report an account as push-enabled while nothing is bound. * * A no-op when no device identifier is stored: the device has never registered, * so there is nothing to bind and nothing to unbind. * * Goes out over the bare public axios instance with an explicit Authorization * header. `baseApi`/`axiosPrivate` would inject the ACTIVE account's token, * which is the wrong identity for every non-active account. */ export declare function applyAccountPushBinding(ctx: PushReconcileContext, userId: string, enabled: boolean): Promise; /** * Makes ONE account's server binding match its stored intent, and clears its * re-bind marker once it has. * * Path (a) and path (b) in the header. Unknown accounts are a no-op. * * **An account that has never expressed a preference is left completely * alone** — not bound, not unbound. Absent is "never asked", and the activation * path is reached on every sign-in, so reading absent as consent here is what * bound a fresh account on a shared device to an identifier the previous user * left behind. It is also the rule `markPushBindingsForRebind` applies, so the * two cannot disagree about which accounts are in play. * * The marker is cleared only after `applyAccountPushBinding` RESOLVES: a * throw leaves it standing, so the next activation tries again. It is cleared * on the silenced path too — an account whose binding has been removed to * match its intent has nothing left to repair. */ export declare function reconcileAccountPushBinding(ctx: PushReconcileContext, userId: string): Promise; /** * Path (c): records that every opted-in BACKGROUND account needs re-binding, * and re-binds the active one on the spot. * * ⚠ Only two callers may ever reach this — a successful `register()` and a * device-token change. They are the only two moments the device identifier can * be new. * * **Nothing here exchanges a credential.** That is the whole difference from * the bulk loop this replaces: a background account is marked, not spent. The * active account is bound immediately because it costs nothing to — its * session is already live, so `resolveAccessToken` takes the live-token branch * and never reaches the mint. * * Marks are raised before the active account's request goes out, so an * identifier change that is interrupted mid-flight still leaves the record of * what needs repairing. The single persist at the end covers both. * * The active account is marked TOO when its own re-bind fails — it is the one * account with no self-healing loop of its own, so without a mark it went * quiet with nothing on screen to say so. The mark comes off again as soon as * a later reconcile binds it. */ export declare function markPushBindingsForRebind(ctx: PushReconcileContext, options?: { /** * Restrict marking to these background accounts. Omit to mark every * opted-in background account, which is what a genuine identifier change * calls for. * * The narrow form exists for the other reason an account can need a * binding it does not have: a repeat `register()` on an UNCHANGED * identifier, which flips accounts that had never expressed a preference * to enabled. Those have no binding and nothing else would ever create * one, while every already-bound account is exactly as valid as it was and * must not be told its notifications are paused. */ accountIds?: readonly string[]; }): Promise;