/*! * Copyright (c) 2026 Interop Alliance. All rights reserved. */ /** * The wipe enumeration: the one list of durable local state this library leaves * on a browser, and the one executor that deletes it. Clearing data must leave * nothing behind, and the failure it exists to prevent is an ORPHANED database * -- one whose name is derived from an identity the clear itself destroyed, so * no later run can name it, let alone delete it. * * Three rules keep that from happening: * * - Snapshot first. Every target is derived from live state BEFORE anything is * deleted ({@link snapshotWipeTargets}), so the order of the deletions that * follow cannot lose a name. * - Delete by known name. Each replica's database name is computable from its * controller DID through `dbNameForController`, so it is deleted by that name * whether or not the engine can enumerate databases. * - Treat `indexedDB.databases()` as discovery and verification, never as the * deletion gate. An engine that does not implement it still gets every named * database deleted; what it cannot confirm is reported as `unverified` rather * than counted toward an outcome that reads clean. * * What the prefix sweep reaches beyond the snapshot: anonymous replicas that * earlier versions of this library already orphaned, and the replicas of other * wallet identities on this browser. Both are this app's own databases under * its own `dbName`, and removing them is what clearing data means. * * What no enumeration here reaches, stated plainly: data already synced to the * WAS server (this is a local clear, not an account deletion), forensic * recoverability of deleted IndexedDB data, and anything the app itself * persisted outside this library. */ import type { RxStorage } from 'rxdb/plugins/core'; /** * Every durable local target of a wipe, derived up front. */ export interface WipeTargets { /** * The RxDB replica database names, one per controller DID the snapshot could * reach (the connected identity, the anonymous one, or both). */ replicaDbNames: string[]; /** * The raw-IndexedDB seed stores: the session store (app-key seed, session * record, descriptor cache) and the anonymous seed store. */ seedStoreDbNames: string[]; /** * The name prefixes the sweep matches: the app's own base `dbName` (the seed * stores) and the RxDB/Dexie mangling of it (each replica collection is its * own IndexedDB database, named `rxdb-dexie------`). * Empty means no sweep: only the named targets and their Dexie sub-databases * are deleted and verified. */ idbNamePrefixes: string[]; /** * The localStorage prefix whose writer id is cleared, or `null` to leave it * in place (the logout grade: the user is expected to log back in on this * browser, and the id is only an attribution stamp). */ storageKeyPrefix: string | null; } /** * What a wipe deleted, and what it could not confirm. */ export interface LocalWipeReport { /** * The database names the executor issued a delete for and, where the engine * could confirm it, saw gone afterwards. */ removed: string[]; /** * Databases still present after the wipe, or whose delete threw. */ failed: string[]; /** * Deletions that were issued but could not be confirmed -- an engine without * `indexedDB.databases()`, or a delete another tab is blocking. Neither a * success nor a failure: a caller states the unconfirmed outcome rather than * claiming a clean wipe. */ unverified: string[]; } /** * Derives every wipe target from live state, before anything is deleted, at one * of the two grades the library ships: * * - `logout` (log out and erase): the CONNECTED replica and the session store. * The anonymous replica and the writer id deliberately survive -- a * local-first app keeps working logged out, and the user is expected to log * back in on this browser -- so this grade runs no prefix sweep, which would * reach the anonymous replica it is meant to spare. * - `clear` (clear data): everything this app ever wrote here -- both replicas, * both seed stores, the writer id -- plus a prefix sweep for whatever the * snapshot could not name. * * The anonymous controller DID must be resolved by the caller (re-derived from * the persisted anonymous seed) while that seed still exists: once it is * discarded, the database it names is unreachable. * * @param options {object} * @param options.dbName {string} the app's base database name * @param options.grade {'logout' | 'clear'} * @param [options.connectedControllerDid] {string | null} the wallet-derived * controller DID, when a connected replica is open * @param [options.anonControllerDid] {string | null} the anonymous controller * DID (`clear` only; ignored at the `logout` grade) * @param [options.storageKeyPrefix] {string} the localStorage prefix whose * writer id the `clear` grade removes * @returns {WipeTargets} */ export declare function snapshotWipeTargets({ dbName, grade, connectedControllerDid, anonControllerDid, storageKeyPrefix }: { dbName: string; grade: 'logout' | 'clear'; connectedControllerDid?: string | null; anonControllerDid?: string | null; storageKeyPrefix?: string; }): WipeTargets; /** * Executes a wipe over a snapshot: the replica databases (through RxDB, so each * one's internal metadata store goes with its collections), the seed stores, * then a prefix sweep for anything the snapshot could not name, then the writer * id. Every stage is best-effort and its failure is collected rather than * aborting the rest, because a stage that throws must not leave the later * stages' state behind. * * The live replica must already be torn down (an open database blocks its own * deletion), which is the caller's job. * * @param options {object} * @param options.targets {WipeTargets} * @param [options.storage] {RxStorage} the RxDB storage the * replicas were created with (defaults to Dexie/IndexedDB) * @param [options.idb] {IDBFactory} the IndexedDB factory (defaults to the * global one; inject a fake for tests) * @returns {Promise} */ export declare function executeLocalWipe({ targets, storage, idb }: { targets: WipeTargets; storage?: RxStorage; idb?: IDBFactory; }): Promise; //# sourceMappingURL=localWipe.d.ts.map