selfstore 1.6.5 → 1.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.d.ts +47 -6
- package/dist/advanced.js +28 -2
- package/dist/advanced.js.map +1 -1
- package/dist/backups.d.ts +1 -1
- package/dist/{chunk-5L7JC2SH.js → chunk-PBWDDWWN.js} +4 -2
- package/dist/chunk-PBWDDWWN.js.map +1 -0
- package/dist/{drive-CO_mNEgi.d.ts → drive-Cf_ulDfn.d.ts} +1 -1
- package/dist/{flows-DMy_Hbf-.d.ts → flows-BIWaqRUz.d.ts} +2 -2
- package/dist/flows.d.ts +3 -3
- package/dist/households.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/{local-hr_BimjH.d.ts → local-BowlLFZc.d.ts} +2 -2
- package/dist/{store-BQhcwSbe.d.ts → store-CSxHlrov.d.ts} +1 -1
- package/dist/widgets.d.ts +3 -3
- package/package.json +1 -1
- package/dist/chunk-5L7JC2SH.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/persistence/target.ts","../src/persistence/status.ts","../src/persistence/store.ts","../src/persistence/cache.ts","../src/persistence/targets/drive-auth-gis.ts"],"names":["opts","key"],"mappings":"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","file":"chunk-PBWDDWWN.js","sourcesContent":["// The contract every durable destination implements: disk file, Google Drive,\n// WebDAV, or anything custom. A target is something the store can save() to\n// silently, with no user gesture.\n//\n// Error protocol: throw AuthExpiredError for a genuine loss of access (session\n// gone, permission withdrawn) - that raises the blocking reconnect gate. Any\n// other throw reads as transient (offline, cold start, 5xx): the edit stays in\n// the local cache and the next save or sync retries, no gate.\n\nexport type BuiltinTargetKind = 'file' | 'drive' | 'webdav';\n\n/**\n * The two kinds the store keeps for itself: 'device' (cache-only) and\n * 'file-manual' (degraded download-on-demand). attachTarget refuses a target\n * claiming either - they name the absence of a target.\n */\nexport const RESERVED_STORE_MODES = ['device', 'file-manual'] as const;\n\n/** Single source of truth for \"is this kind a store mode, not a durable target\". */\nexport function isReservedStoreMode(kind: string): boolean {\n\treturn (RESERVED_STORE_MODES as readonly string[]).includes(kind);\n}\n\n/**\n * The read-only subset of BackupTarget a peer must provide. Any BackupTarget\n * satisfies it structurally; its save() is simply never called. Peer failures\n * follow the same protocol but are recorded per peer and never gate the store.\n */\nexport interface PeerSource {\n\t/** The peer's published copy, or null when none exists yet. */\n\tload(): Promise<Blob | null>;\n\t/** Cheap remote change marker, so unchanged copies can be skipped. Absent means \"cannot tell\". */\n\tstat?(): Promise<string | null>;\n\t/** Display name (defaults to the peer id). */\n\treadonly label?: string;\n}\n\nexport interface BackupTarget {\n\t/** Stable discriminator, persisted and handed back to restoreTarget(kind)\n\t * next session. Custom targets pick any string outside the built-ins and\n\t * RESERVED_STORE_MODES. */\n\treadonly kind: string;\n\t/** Human label for the connected destination (file name, \"Google Drive\"). */\n\treadonly label: string;\n\n\t/** Push the backup blob. May resolve to the remote's new version marker\n\t * when the write reports it atomically (else the store calls stat()). */\n\tsave(blob: Blob): Promise<string | null>;\n\t/** Latest backup blob, or null if none exists / unavailable. */\n\tload(): Promise<Blob | null>;\n\t/** Cheap remote change marker (Drive version, file mtime): lets the store\n\t * spot another replica's writes without downloading. */\n\tstat?(): Promise<string | null>;\n\t/** Writable right now, without a user gesture? False for a transient blip\n\t * (retried later); AuthExpiredError for a genuine loss of access. */\n\tisReady(): Promise<boolean>;\n\t/** Re-acquire access (needs a user gesture); resolves to whether it worked. */\n\treconnect(): Promise<boolean>;\n\t/** Forget the target locally. Never deletes the remote data. */\n\tdisconnect(): Promise<void>;\n\t/** Cut any in-flight network request NOW (best-effort). The store calls it\n\t * when the user detaches the target, so a suspended request cannot make\n\t * the detach wait behind its network deadline. Optional: without it,\n\t * in-flight calls simply run to their own deadlines first. */\n\tabortInFlight?(): void;\n}\n","// Headless status derivation: raw store flags in, semantic descriptor out\n// (state, severity, action, labelKey). No colours, no copy - the app owns both.\n\nexport type Severity = 'ok' | 'info' | 'warn' | 'danger';\n\nexport type StorageState =\n\t'ephemeral' | 'cache-only' | 'saving' | 'saved' | 'pending-download' | 'needs-attention';\n\n/** A suggested action the UI can wire to a button. */\nexport type StatusAction = 'choose-destination' | 'download' | 'reconnect' | 'unlock';\n\n/** The headless descriptor the UI renders. */\nexport interface StatusDescriptor {\n\tstate: StorageState;\n\tseverity: Severity;\n\tactionable: boolean;\n\taction?: StatusAction;\n\t/** Stable i18n key; the app owns the actual copy. */\n\tlabelKey: string;\n}\n\nexport interface StatusInput {\n\t/** False means ephemeral (the local cache is off). */\n\tpersistent: boolean;\n\t/** Any BackupTarget kind, or a reserved store mode ('device', 'file-manual'). */\n\ttargetKind: string;\n\tsaving: boolean;\n\t/** The durable home needs a user gesture (token expired, permission lapsed, locked). */\n\tneedsAttention: boolean;\n\t/** The attention is a lock (password not in memory): the gesture is unlock, not reconnect. */\n\tlocked: boolean;\n\t/** Degraded file mode has changes awaiting a manual download. */\n\tpendingDownload: boolean;\n}\n\nimport { isReservedStoreMode } from './target';\n\n/** A kind that names a real durable target (anything but the store modes). */\nconst isDurableKind = (kind: string): boolean => !isReservedStoreMode(kind);\n\n/** Map the store's raw flags to a single, ranked status; the most important wins. */\nexport function deriveStatus(input: StatusInput): StatusDescriptor {\n\tif (!input.persistent) {\n\t\treturn {\n\t\t\tstate: 'ephemeral',\n\t\t\tseverity: 'warn',\n\t\t\tactionable: true,\n\t\t\taction: 'choose-destination',\n\t\t\tlabelKey: 'status.ephemeral'\n\t\t};\n\t}\n\n\tif (isDurableKind(input.targetKind) && input.needsAttention) {\n\t\treturn {\n\t\t\tstate: 'needs-attention',\n\t\t\tseverity: 'danger',\n\t\t\tactionable: true,\n\t\t\taction: input.locked ? 'unlock' : 'reconnect',\n\t\t\tlabelKey: input.locked ? 'status.locked' : 'status.needsAttention'\n\t\t};\n\t}\n\n\tif (input.saving) {\n\t\treturn { state: 'saving', severity: 'info', actionable: false, labelKey: 'status.saving' };\n\t}\n\n\tif (input.targetKind === 'file-manual' && input.pendingDownload) {\n\t\treturn {\n\t\t\tstate: 'pending-download',\n\t\t\tseverity: 'info',\n\t\t\tactionable: true,\n\t\t\taction: 'download',\n\t\t\tlabelKey: 'status.pendingDownload'\n\t\t};\n\t}\n\n\tif (input.targetKind === 'device') {\n\t\treturn {\n\t\t\tstate: 'cache-only',\n\t\t\tseverity: 'warn',\n\t\t\tactionable: true,\n\t\t\taction: 'choose-destination',\n\t\t\tlabelKey: 'status.cacheOnly'\n\t\t};\n\t}\n\n\treturn { state: 'saved', severity: 'ok', actionable: false, labelKey: 'status.saved' };\n}\n","// createLocalStore: the front door. Composes the backup format, the merge\n// engine and a LocalCache into one lifecycle - debounced saves, flush on tab\n// hide, logical clocks, replica merges, memory/cache/durable-home juggling all\n// live here so the app never has to. Framework-agnostic (plain state plus\n// subscribe) and headless (semantic status, never colours or copy). The app\n// brings what is app-specific: gather, apply, a schema version, migrate.\n\nimport {\n\tinspect,\n\tisSelfstoreError,\n\tisAuthExpired,\n\terrorLabelKey,\n\tSelfstoreError,\n\tcheckPasswordPolicy,\n\ttype Snapshot,\n\ttype SelfstoreErrorCode,\n\ttype PasswordSlot,\n\ttype ExternalSlot,\n\ttype PasswordPolicy\n} from '../selfstore';\nimport {\n\twriteBox,\n\treadBoxWithSync,\n\tasBytes,\n\tBACKUP_MIME,\n\ttype GroupReadOptions,\n\ttype BoxEnvelope\n} from '../selfstore/box';\nimport { mintSlot, openSlot, mintExternalSlot, MAX_KEY_SLOTS } from '../selfstore/crypto';\nimport {\n\tGROUP_KEYING,\n\topenManifest,\n\ttype GroupIdentity,\n\ttype GroupManifest,\n\ttype SignedManifest\n} from '../selfstore/group';\nimport {\n\tstamp,\n\tmerge,\n\tdetectConflicts,\n\tcreateMeta,\n\tcreateNode,\n\tchanges,\n\tgcTombstones,\n\tunsyncableCounts,\n\tidPathFor,\n\ttype SyncMeta,\n\ttype SyncConfig,\n\ttype CollectionChanges,\n\ttype Conflict\n} from '../sync';\nimport { deriveStatus, type StatusDescriptor } from './status';\nimport { isReservedStoreMode, type BackupTarget, type PeerSource } from './target';\nimport type { LocalCache, CachedFile } from './cache';\n\nexport type Mode = 'persistent' | 'ephemeral';\n/** Any BackupTarget kind, or a reserved store mode ('device', 'file-manual').\n * Deliberately open: a custom target's kind flows through here. */\nexport type TargetKind = 'device' | 'file-manual' | (string & {});\n\n/** What triggered a converge with the remote (for the sync journal). */\nexport type SyncSource = 'boot' | 'focus' | 'online' | 'interval' | 'manual' | 'push' | 'connect';\n\n/** One journal line: a converge that actually changed local data. */\nexport interface SyncJournalEntry {\n\tat: number;\n\tsource: SyncSource;\n\tchanges: Record<string, CollectionChanges>;\n\t/** Concurrent same-record edits, auto-resolved latest-wins. Both values are\n\t * carried so the app can show or restore the overwritten one. */\n\tconflicts?: Conflict[];\n}\n\n/** The last problem the store hit, as a stable code the app maps to its own wording. */\nexport interface StoreError {\n\tcode: SelfstoreErrorCode;\n\t/** Stable i18n key for `code` (errorLabelKey). Show this, mapped to your copy. */\n\tlabelKey: string;\n\t/** Developer detail for logs - English, may carry an HTTP status. Never display it. */\n\tmessage: string;\n}\n\n// labelKey derived from code here, so no reporting site can forget it.\nconst storeError = (code: SelfstoreErrorCode, message: string): StoreError => ({\n\tcode,\n\tlabelKey: errorLabelKey(code),\n\tmessage\n});\n\n/**\n * Group mode: this member's identity, the admin key pinned at join time\n * (TOFU, from the invite), and the manifest as it travels. The store verifies\n * the manifest itself - signature, member-key shapes, group binding - so\n * group security never depends on the app remembering to call openManifest.\n */\nexport interface StoreGroupConfig {\n\tidentity: GroupIdentity;\n\t/** The admin's Ed25519 public key (base64 raw), pinned from the invite. */\n\tadmin: string;\n\t/** The admin-signed manifest exactly as distributed (signManifest output). */\n\tmanifest: SignedManifest;\n}\n\ninterface ActiveGroup {\n\tidentity: GroupIdentity;\n\tadmin: string;\n\tmanifest: GroupManifest;\n}\n\n/** One attached peer (another member's read-only copy - see attachPeer). */\nexport interface PeerState {\n\tid: string;\n\tlabel: string;\n\t/** Last successful fold-in (ms epoch), or null. */\n\tlastSyncAt: number | null;\n\t/** Group mode: the manifest member whose signature the last folded copy carried. */\n\tauthor: string | null;\n\t/** Per-peer on purpose: a broken peer never gates the store itself. */\n\tlastError: StoreError | null;\n}\n\n/** One write-only published copy of this store (see attachMirror). */\nexport interface MirrorState {\n\tid: string;\n\tlabel: string;\n\t/** Last successful publish (ms epoch), or null. */\n\tlastPublishAt: number | null;\n\t/** Per-mirror on purpose: a broken mirror never gates the store itself. */\n\tlastError: StoreError | null;\n}\n\n/** One secondary synced copy of this store (see attachReplica). */\nexport interface ReplicaState {\n\tid: string;\n\tlabel: string;\n\t/** Last successful publish (ms epoch), or null. */\n\tlastPublishAt: number | null;\n\t/** Per-replica on purpose: a broken replica never gates the store itself. */\n\tlastError: StoreError | null;\n}\n\n/** The read-only snapshot of the store the UI renders. */\nexport interface LocalStoreState {\n\tready: boolean;\n\tmode: Mode;\n\ttargetKind: TargetKind;\n\tlabel: string | null;\n\tencrypted: boolean;\n\tlocked: boolean;\n\tsaving: boolean;\n\tlastSavedAt: number | null;\n\tstatus: StatusDescriptor;\n\t/** The last durable-target problem (upload/refresh), or null. */\n\tlastError: StoreError | null;\n\t/** Recent converges that changed local data, newest first (device-local). */\n\tjournal: SyncJournalEntry[];\n\t/** The last live converge that changed data (drives the \"synced\" toast). */\n\tlastSync: SyncJournalEntry | null;\n\t/** Attached peers, in attach order. */\n\tpeers: PeerState[];\n\t/** Attached mirrors, in attach order. */\n\tmirrors: MirrorState[];\n\t/** Attached replicas (secondary synced copies), in attach order. */\n\treplicas: ReplicaState[];\n}\n\nexport interface LocalStoreOptions {\n\t/** App id; names the backup and scopes the default cache database. */\n\tapp: string;\n\t/** Data schema version; bump when gather's shape changes. Stamped into every\n\t * backup, drives migrate() and the SCHEMA_TOO_NEW gate. */\n\tschemaVersion: number;\n\t/** Release version (\"1.4.2\"), stamped informationally into the header. */\n\tappVersion?: string;\n\t/** Branded README shipped inside encrypted backups. */\n\treadme?: string;\n\t/** Refuse to ever write or export a plaintext backup. attachTarget without a\n\t * password or group is rejected, setEncryption(null) is rejected, and\n\t * exportBlob refuses a cleartext copy - the backup that leaves the device is\n\t * always ciphertext. Scope is deliberately the travelling copy: the\n\t * on-device working cache stays governed by the browser profile, as ever.\n\t * Off by default. */\n\trequireEncryption?: boolean;\n\t/** Reject a backup password that fails this strength policy (length and\n\t * character classes): setEncryption, addEncryptionKey and a password given\n\t * to attachTarget throw WEAK_PASSWORD before touching anything. The app can\n\t * preview the same rules with checkPasswordPolicy so its UI blocks a weak\n\t * password before it is ever submitted. Omit for no policy. */\n\tpasswordPolicy?: PasswordPolicy;\n\t/** Gather the app's live state into a portable snapshot. */\n\tgather: () => Promise<Snapshot> | Snapshot;\n\t/** Apply a snapshot into the app (replaces current state). */\n\tapply: (snap: Snapshot) => void;\n\t/** Upgrade a snapshot written by an older version to the current shape. */\n\tmigrate?: (fromVersion: number, snap: Snapshot) => Snapshot;\n\t/** Per-collection merge strategies. Omit for everything lww-set. */\n\tsync?: SyncConfig;\n\t/** Derived collections whose merges are routine noise (recomputed data, not\n\t * user edits): converges touching only these skip the sync journal. */\n\tjournalSilent?: string[];\n\t/** Prune delete-tombstones older than this many ms on each save. Safe only\n\t * when it comfortably exceeds the longest a device stays offline: a device\n\t * that never saw a delete resurrects the record once the tombstone is gone\n\t * everywhere. Omit to keep every tombstone; weeks is a reasonable value. */\n\ttombstoneHorizonMs?: number;\n\t/** Coordinate several tabs of the same app (default: on in browser\n\t * windows). Every save first folds what other tabs persisted, writes\n\t * serialize through a cross-tab Web Lock where available, and a\n\t * BroadcastChannel refreshes the other tabs after each write. Data and\n\t * bookkeeping only: a target's connection stays per tab (restoreTarget at\n\t * boot), and mode/target switches reach other tabs on reload. */\n\tmultiTab?: boolean;\n\t/** The working store under the app. */\n\tcache: LocalCache;\n\t/** Rebuild a durable target connected in a past session. Receives the kind\n\t * persisted at attach time - built-in or custom. */\n\trestoreTarget?: (kind: string) => Promise<BackupTarget | null>;\n\t/** Debounce window for auto-save (ms). Default 800. */\n\tdebounceMs?: number;\n\t/** Diagnostics sink, developer-facing (defaults to the console). */\n\tlogger?: { warn(...args: unknown[]): void; error(...args: unknown[]): void };\n}\n\nexport interface LocalStore {\n\treadonly state: LocalStoreState;\n\tsubscribe(fn: () => void): () => void;\n\n\t/** Hydrate from the cache, restore a saved durable target, converge with it. */\n\tinit(): Promise<void>;\n\t/** Schedule a debounced save (call after each mutation). */\n\tschedule(): void;\n\t/** Save now, cancelling the debounce (use on tab hide). */\n\tflush(): Promise<void>;\n\n\t/** Converge with the remote only if it changed since the last sync (a cheap\n\t * stat, throttled). Call on tab focus, network return and a slow interval. */\n\tsyncIfStale(source: SyncSource): Promise<void>;\n\t/** Converge with the remote now (user gesture). Resolves to what changed\n\t * locally, or null when already up to date. */\n\tsyncNow(): Promise<SyncJournalEntry | null>;\n\n\t/** Inspect a target for an existing backup, without changing any state. */\n\tinspectTarget(\n\t\ttarget: BackupTarget\n\t): Promise<{ hasBackup: boolean; date: string | null; encrypted: boolean }>;\n\t/** Attach a durable home. `strategy` reconciles with what is already on the\n\t * target: 'merge' (default, multi-device), 'replace-local' (load the\n\t * target into the app) or 'replace-remote' (overwrite the target).\n\t * `keepSession` leaves the departing target's credentials untouched (a\n\t * backup switch behind one account). `wipe` starts the new home blank -\n\t * empty data, fresh sync meta, never seeded from the departing one. */\n\tattachTarget(\n\t\ttarget: BackupTarget,\n\t\topts?: {\n\t\t\tpassword?: string | null;\n\t\t\t/** Group mode: publish signed copies enveloped for every manifest\n\t\t\t * member, trust only member-signed copies back. The manifest is\n\t\t\t * verified here, against the pinned admin key, before anything\n\t\t\t * about the store changes. Mutually exclusive with `password`.\n\t\t\t * Not persisted: re-attach with the group config at boot. */\n\t\t\tgroup?: StoreGroupConfig;\n\t\t\tstrategy?: 'merge' | 'replace-local' | 'replace-remote';\n\t\t\tkeepSession?: boolean;\n\t\t\twipe?: boolean;\n\t\t}\n\t): Promise<void>;\n\t/** Apply a newer membership manifest. Verified against the admin key and\n\t * group id pinned at attach (a swapped admin or foreign group never\n\t * lands), with seq monotonicity across sessions (MANIFEST_ROLLBACK on an\n\t * older one). The next publish re-envelopes for the new member list -\n\t * which is how removal takes effect: a removed member stops being a\n\t * recipient of anything published from now on. */\n\tsetGroup(manifest: SignedManifest): Promise<void>;\n\t/** Attach another member's published copy as a read-only peer. Every\n\t * converge pulls each peer's copy and merges it as one more replica, then\n\t * publishes the merged state to this store's own target - crossed\n\t * read-only links are how read-write sharing emerges. A peer copy opens\n\t * with its own `password` when given, else the session password. Peer\n\t * problems land on `state.peers` and never gate the store. Not persisted:\n\t * re-attach at boot. Resolves to the peer id (pass `id` to pin it). */\n\tattachPeer(source: PeerSource, opts?: { id?: string; password?: string }): string;\n\t/** Detach a peer locally (never touches the member's copy). Unknown id: no-op. */\n\tdetachPeer(id: string): void;\n\t/** Publish a write-only mirror: after every save or converge that moved\n\t * data, the current state is re-encoded under the mirror's own password\n\t * and saved to the mirror target. The store's own file is never re-keyed -\n\t * that is the point: your file stays yours, the copy others read travels\n\t * under the share key. The envelope is minted once (no KDF per publish);\n\t * mirror problems land on `state.mirrors` and never gate the store. Not\n\t * persisted: re-attach at boot. Resolves to the mirror id. */\n\tattachMirror(target: BackupTarget, opts: { password: string; id?: string }): string;\n\t/** Detach a mirror locally (the published copy stays where it is). */\n\tdetachMirror(id: string): void;\n\t/** Attach a secondary synced copy: after every save or converge that moved\n\t * data, the CURRENT backup - same bytes, same key as the primary home - is\n\t * also written to this target. A resilience mirror of your own file (Drive\n\t * plus an S3 bucket, say), not a share: any device can later attach it as\n\t * its primary with the same password. Publishing reuses the primary's\n\t * envelope, so it costs no extra KDF; replica problems land on\n\t * `state.replicas` and never gate the store. Not persisted: re-attach at\n\t * boot. Resolves to the replica id (pass `id` to pin it). */\n\tattachReplica(target: BackupTarget, opts?: { id?: string }): string;\n\t/** Detach a replica locally (the copy already written stays where it is). */\n\tdetachReplica(id: string): void;\n\t/** Switch to degraded download-on-demand mode (non-Chromium file). */\n\tsetManualFile(): Promise<void>;\n\t/** Unlock an encrypted target: the password is held in memory only, then a\n\t * converge runs. False on a wrong password (the gate re-raises) or when\n\t * the target is not locked (use `reconnect`). */\n\tunlock(password: string): Promise<boolean>;\n\t/** Re-acquire access after a genuine loss: run the target's reconnect\n\t * gesture, then converge. False when locked (use `unlock`) or absent. */\n\treconnect(): Promise<boolean>;\n\t/** Re-lock now: drop the in-memory password (encrypted target). */\n\tlock(): void;\n\t/** Detach the durable home (does not delete it); back to cache-only.\n\t * `keepSession` skips the target's disconnect so its credentials survive -\n\t * for a caller that still needs the destination right after (deleting the\n\t * detached file, attaching another one on the same account). */\n\tdetachTarget(opts?: { keepSession?: boolean }): Promise<void>;\n\n\t/** Build the portable .selfstore blob (for a manual download or dated copy). */\n\texportBlob(): Promise<Blob>;\n\t/** Mark the file-manual pending download as resolved. */\n\tmarkDownloaded(): void;\n\n\t/** Stop persisting (shared computer). */\n\tsetEphemeral(): void;\n\t/** Resume persisting to the cache. */\n\tleaveEphemeral(): Promise<void>;\n\t/** Wipe all app data. With a destination connected, keep the connection and\n\t * empty its backup too; with none, forget locally and return to the\n\t * cache-only default. The UI empties immediately, no reload. */\n\tforget(): Promise<void>;\n\n\t/** Add, change or remove the backup password - reversible. A non-empty\n\t * string (re)encrypts; null decrypts. Needs a connected, unlocked target;\n\t * rewrites cache and remote. Setting a password rotates the data key\n\t * (fresh key, single slot), so every previously authorized password\n\t * stops opening the file. */\n\tsetEncryption(password: string | null): Promise<void>;\n\n\t/** Add another password that opens this backup: the data key gains one\n\t * slot, nothing is re-encrypted, existing passwords keep working - how\n\t * sharing adds its key without clobbering the owner's. Verified against\n\t * the built bytes before the write lands. Resolves to the slot id. */\n\taddEncryptionKey(password: string, id?: string): Promise<string>;\n\n\t/** Remove one password slot by id. Refuses the last slot (that is\n\t * setEncryption(null)) and refuses to lock the current session out.\n\t * Bearer reality: whoever held that password may hold old bytes - only a\n\t * rotation makes new writes unreadable to them. */\n\tremoveEncryptionKey(id: string): Promise<void>;\n\n\t/** Encrypt under an external key (passkey PRF, hardware token) instead of\n\t * a typed password: fresh data key, one external slot. `keyRef` is stored\n\t * verbatim so the app can re-derive the secret. Rotates like\n\t * setEncryption; the app owns the WebAuthn exchange and hands in the\n\t * 32-byte secret. */\n\tsetExternalEncryption(secret: Uint8Array, keyRef: string): Promise<void>;\n\n\t/** Add an external-key slot to an already-encrypted backup - a passkey\n\t * alongside a recovery password, or the reverse. Needs an unlocked\n\t * session; verified against the built bytes before the write lands. */\n\taddExternalKey(secret: Uint8Array, keyRef: string, id?: string): Promise<string>;\n\n\t/** unlock(), but trying the external slots with `secret`. */\n\tunlockWithExternal(secret: Uint8Array): Promise<boolean>;\n\n\t/** The current slot table (id + kind, so a passkey slot can be labelled).\n\t * Empty when unknown: plaintext, locked, or not read yet this session. */\n\tlistEncryptionKeys(): { id: string; kind: 'password' | 'external' }[];\n\n\t/** Cancel timers, close the cross-tab channel, drop subscribers - nothing\n\t * fires into a dead app after unmount. Persisted data is untouched; the\n\t * store is not usable afterwards. */\n\tdispose(): void;\n}\n\n// Reserved collection name: `__`-prefixed collections belong to the library\n// and are stripped from decoded snapshots before they reach the app.\nconst RESERVED = '__store';\n\n// Carried in a backup's sync.json sidecar: the schema version the data was\n// written under plus the merge metadata (HLC clocks, tombstones).\ninterface Bookkeeping {\n\tschemaVersion: number;\n\tmeta: SyncMeta;\n}\n\n// Named kv keys, so a typo cannot silently lose state.\nconst KEY = {\n\tmode: 'mode',\n\tversion: 'version',\n\tsyncMeta: 'syncMeta',\n\tlastSavedAt: 'lastSavedAt',\n\tenc: 'enc',\n\ttargetKind: 'targetKind',\n\tremoteVersion: 'remoteVersion',\n\tsyncJournal: 'syncJournal',\n\tbaseMeta: 'baseMeta',\n\t// Bumped on every cache write: one cheap kv read tells a tab whether\n\t// someone else wrote since it last looked (multi-tab fold).\n\tepoch: 'writeEpoch',\n\t// SHA-256 of the content last pushed. Identical content skips the save (no\n\t// \"saving\" flash, no redundant upload); an unpushed local edit hashes\n\t// differently and still saves.\n\tsavedHash: 'savedHash',\n\t// The KV has no key enumeration, so forget() needs this index to preserve\n\t// every group's anti-replay counter.\n\tgroupSeqIds: 'groupSeqIds'\n} as const;\n\nconst JOURNAL_MAX = 20;\n\n/** Ceiling on each network wait of init(): a radio waking from sleep can\n * suspend a fetch without ever erroring, and one such stall used to hang the\n * whole boot behind \"connecting...\" until the user reconnected by hand. The\n * work keeps running in the background; only the BOOT stops waiting for it,\n * falls back to the cached copy, and the next save/sync retries. */\nconst BOOT_NET_MS = 25_000;\n\n/** Marks a boot wait that hit BOOT_NET_MS (a stall, not an auth verdict). */\nclass BootTimeout extends Error {\n\tconstructor(what: string) {\n\t\tsuper(`${what} timed out at boot`);\n\t\tthis.name = 'BootTimeout';\n\t}\n}\n\n/** Reject with BootTimeout after `ms` unless `work` settles first. The timer is\n * cleared on settle so tests and short-lived workers never linger. */\nfunction bootDeadline<T>(work: Promise<T>, what: string, ms = BOOT_NET_MS): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tconst timer = setTimeout(() => reject(new BootTimeout(what)), ms);\n\t\twork.then(\n\t\t\t(v) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(v);\n\t\t\t},\n\t\t\t(e) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\treject(e instanceof Error ? e : new Error(String(e)));\n\t\t\t}\n\t\t);\n\t});\n}\n\n// Focus events can burst; skip repeat staleness checks inside this window.\nconst STALE_CHECK_MS = 20_000;\n\nexport function createLocalStore(opts: LocalStoreOptions): LocalStore {\n\tconst {\n\t\tapp,\n\t\tschemaVersion: version,\n\t\tappVersion,\n\t\tgather,\n\t\tapply,\n\t\tcache,\n\t\treadme,\n\t\tdebounceMs = 800\n\t} = opts;\n\tconst logger = opts.logger ?? console;\n\t// Hard no-plaintext policy: a store told to require encryption refuses every\n\t// path that could emit a cleartext travelling copy (see requireEncryption).\n\tconst requireEncryption = opts.requireEncryption ?? false;\n\tconst passwordPolicy = opts.passwordPolicy;\n\n\t/** Throw WEAK_PASSWORD when a policy is set and this password fails it. The\n\t * unmet requirement codes ride in the message for logs; the app previews the\n\t * same rules with checkPasswordPolicy for its live UI hint. */\n\tfunction assertPasswordPolicy(pw: string): void {\n\t\tif (!passwordPolicy) return;\n\t\tconst { ok, unmet } = checkPasswordPolicy(pw, passwordPolicy);\n\t\tif (!ok) {\n\t\t\tthrow new SelfstoreError(\n\t\t\t\t'WEAK_PASSWORD',\n\t\t\t\t`Password does not meet the policy: ${unmet.join(', ')}.`\n\t\t\t);\n\t\t}\n\t}\n\t// Derived collections whose merges are routine noise, not user edits - they\n\t// do not make a converge worth a journal entry.\n\tconst journalSilent = new Set(opts.journalSilent ?? []);\n\tconst sync: SyncConfig = opts.sync ?? {};\n\tconst kv = cache.kv;\n\n\t// Multi-tab coordination (see the multiTab option). The channel and the Web\n\t// Lock are the LIVENESS half and are gated; the fold-on-save correctness rule\n\t// below (foldTabWrites) is always on - it costs one kv read per save and\n\t// only ever triggers when something else actually wrote the shared cache.\n\tconst multiTab =\n\t\topts.multiTab ?? (typeof window !== 'undefined' && typeof BroadcastChannel !== 'undefined');\n\tconst tabId = createNode();\n\tconst channel =\n\t\tmultiTab && typeof BroadcastChannel !== 'undefined'\n\t\t\t? new BroadcastChannel(`selfstore:${app}`)\n\t\t\t: null;\n\tconst locks: LockManager | null =\n\t\tmultiTab && typeof navigator !== 'undefined' && navigator.locks ? navigator.locks : null;\n\tconst lockName = `selfstore:${app}`;\n\n\tlet mode: Mode = 'persistent';\n\tlet targetKind: TargetKind = 'device';\n\tlet durable: BackupTarget | null = null;\n\tlet label: string | null = null;\n\tlet encrypted = false;\n\tlet needsAttention = false;\n\tlet lastError: StoreError | null = null;\n\tlet pendingDownload = false;\n\tlet lastSavedAt: number | null = null;\n\tlet ready = false;\n\tlet saving = false;\n\t// SHA-256 of the content last persisted to the remote (seeded from kv on\n\t// boot). doSave() skips a write whose content hashes identically - a reactive\n\t// touch (a share link created, a derived recompute) must never re-upload an\n\t// unchanged backup or flash \"saving\". Set only after a push truly succeeds, so\n\t// a deferred/failed push always retries.\n\tlet lastSavedContentHash: string | null = null;\n\tlet pass: string | null = null;\n\t// Transiently held only across an unlockWithExternal converge (a user-gesture\n\t// passkey unlock): while set, a decode that hits an external slot resolves its\n\t// secret from here. Never persisted, cleared the moment the unlock pull returns.\n\tlet pendingExternalSecret: Uint8Array | null = null;\n\t// The own file's password envelope, captured at read time: the raw data key\n\t// plus the slot table verbatim. Memory only (see setPass), refreshed on\n\t// every successful own-copy read, carried into every encrypted rewrite.\n\tlet envelope: BoxEnvelope | null = null;\n\t// Passwordless group mode (see StoreGroupConfig). In-memory only, like the\n\t// password: the app re-attaches with { group } at boot.\n\tlet group: ActiveGroup | null = null;\n\tlet meta: SyncMeta = createMeta();\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet idleTimer: ReturnType<typeof setTimeout> | undefined;\n\t// The remote's last seen/written version marker (per target stat()). Lets us\n\t// skip pulls when nothing moved, and converge before a push would overwrite\n\t// another replica's write.\n\tlet remoteVersion: string | null = null;\n\tlet journal: SyncJournalEntry[] = [];\n\tlet lastSync: SyncJournalEntry | null = null;\n\t// The meta as of the last converge: lets detectConflicts tell a concurrent\n\t// same-record edit (both sides moved since here) from a one-sided change.\n\tlet baseMeta: SyncMeta | null = null;\n\tlet lastStaleCheck = 0;\n\t// Collections already flagged for records without a string id, so the\n\t// data-loss warning fires once each, not on every save.\n\tconst warnedNoId = new Set<string>();\n\t// The cache write epoch this tab has already absorbed (multi-tab fold).\n\tlet seenEpoch: string | undefined;\n\t// An edit was schedule()d and not yet saved: a cross-tab refresh must SAVE it\n\t// (folding the other tab's write in) rather than adopt that tab's state over it.\n\tlet pendingEdit = false;\n\t// Bumped by every schedule(). doSave clears pendingEdit only when this is\n\t// unchanged across its persist: an edit landing during the gather/write is not\n\t// in the persisted snapshot, so its flag must survive (else a cross-tab refresh\n\t// would adopt over it and lose it).\n\tlet editSeq = 0;\n\t// Coalesces bursts of cross-tab messages into one queued refresh ('forget' wins).\n\tlet queuedKind: 'change' | 'forget' | null = null;\n\n\t// The blob inspectTarget last downloaded, offered to the attach that usually\n\t// follows in the same connect journey so the backup is fetched once, not\n\t// twice. One-shot and reused only when the remote provably has not moved since\n\t// (see takeFreshPrefetch), so a stale blob can never clobber a concurrent write.\n\tlet prefetched: { target: BackupTarget; blob: Blob; marker: string | null; at: number } | null =\n\t\tnull;\n\t// A prefetched blob past this age is dropped: the connect journey (pick a\n\t// resolution, maybe type a password) is seconds, not minutes.\n\tconst PREFETCH_TTL_MS = 60_000;\n\n\t// Peers: other members' published copies of this store, attached read-only\n\t// (see attachPeer). Distinct from the multi-tab machinery above, which\n\t// coordinates tabs of this member around one shared cache.\n\tinterface PeerEntry {\n\t\tid: string;\n\t\tsource: PeerSource;\n\t\t/** This copy's own decryption password (a share key); falls back to the\n\t\t * session password when absent. */\n\t\tpassword?: string;\n\t\tlabel: string;\n\t\tlastSyncAt: number | null;\n\t\t/** Group mode: manifest member id of the last verified author. */\n\t\tauthor: string | null;\n\t\tlastError: StoreError | null;\n\t\t/** Last change marker seen from stat(), to skip unchanged copies. */\n\t\tlastSeen: string | null;\n\t\t/** The envelope data key captured on the last successful read of this peer's\n\t\t * copy (share-key model), so the NEXT fold reuses it and skips the Argon2 KDF\n\t\t * (~1-2s) - the heaviest recurring cost of a shared session. A rotation on\n\t\t * the peer's side makes the cached key fail and the read falls back to the\n\t\t * password (see readEnvelopeBox). Memory only, like the own-file envelope. */\n\t\tenvelope: BoxEnvelope | null;\n\t}\n\tconst peerList: PeerEntry[] = [];\n\n\t// Mirrors: write-only published copies of this store, re-encoded under the\n\t// mirror's own password (see LocalStore.attachMirror). The envelope (data\n\t// key + single slot for the mirror password) is minted once at first\n\t// publish and reused, so publishing costs no KDF pass.\n\tinterface MirrorEntry {\n\t\tid: string;\n\t\ttarget: BackupTarget;\n\t\tpassword: string;\n\t\tenvelope: BoxEnvelope | null;\n\t\tlabel: string;\n\t\tlastPublishAt: number | null;\n\t\tlastError: StoreError | null;\n\t}\n\tconst mirrorList: MirrorEntry[] = [];\n\n\t// Replicas: secondary synced copies of this store under its OWN key (see\n\t// LocalStore.attachReplica). Unlike a mirror, a replica carries no password of\n\t// its own - it receives the same buildBlob() bytes as the primary home, so it\n\t// is a resilience copy of your file rather than a re-keyed share.\n\tinterface ReplicaEntry {\n\t\tid: string;\n\t\ttarget: BackupTarget;\n\t\tlabel: string;\n\t\tlastPublishAt: number | null;\n\t\tlastError: StoreError | null;\n\t}\n\tconst replicaList: ReplicaEntry[] = [];\n\n\t// Serialize the mutating flows (save / pull / forget): a focus-pull racing the\n\t// debounced save must not interleave gather/restore. With multiTab the same\n\t// chain also holds a cross-tab Web Lock, so several tabs' writes never\n\t// interleave on the shared cache either. Serialized functions never await\n\t// another serialized one (that would self-deadlock the chain and the lock).\n\tlet chain: Promise<unknown> = Promise.resolve();\n\tfunction serialize<T>(fn: () => Promise<T>): Promise<T> {\n\t\tconst exec = locks ? (): Promise<T> => locks.request(lockName, fn) as Promise<T> : fn;\n\t\tconst run = chain.then(exec, exec);\n\t\tchain = run.catch(() => undefined);\n\t\treturn run;\n\t}\n\n\t// Auto-lock: drop the in-memory password after inactivity, so an unattended\n\t// (e.g. shared) machine does not keep an encrypted backup unlocked\n\t// indefinitely. Reset on each save (user activity).\n\tconst IDLE_LOCK_MS = 30 * 60 * 1000;\n\n\t// A kind naming a real durable target (anything but the store modes).\n\tconst durableKind = (): boolean => !isReservedStoreMode(targetKind);\n\n\tconst subs = new Set<() => void>();\n\t// The state snapshot is rebuilt on notify and handed out by reference, so a\n\t// framework adapter (useSyncExternalStore etc.) sees a stable object between\n\t// changes instead of a fresh literal per read.\n\tlet stateSnapshot: LocalStoreState;\n\tconst notify = (): void => {\n\t\tstateSnapshot = buildState();\n\t\tsubs.forEach((f) => f());\n\t};\n\t// Group mode never locks: there is no password to forget (the identity is\n\t// the app's to persist), so the unlock gate is a password-mode concept only.\n\t// Locked = encrypted with no way in: neither a password nor a held envelope\n\t// (the data key). An external-key unlock (a passkey) holds the envelope without\n\t// a password, so it reads as unlocked; a password lock clears both (setPass(null)\n\t// drops the envelope), so it reads as locked. Group mode is never \"locked\" here.\n\tconst locked = (): boolean => durableKind() && encrypted && !pass && !envelope && !group;\n\n\t/** The group read options for the own target: only copies signed by this\n\t * member's key are ours (each member's copy is single-writer; a foreign\n\t * signature in our own storage is a swap, not a copy of ours). */\n\tconst ownGroupRead = (): GroupReadOptions | undefined =>\n\t\tgroup ? { identity: group.identity, authors: [group.identity.sigPub] } : undefined;\n\n\t/** The group read options for PEERS: any current manifest member may sign. */\n\tconst peerGroupRead = (): GroupReadOptions | undefined =>\n\t\tgroup\n\t\t\t? { identity: group.identity, authors: group.manifest.members.map((m) => m.sig) }\n\t\t\t: undefined;\n\n\t/** Manifest seq high-water mark key (rollback protection across sessions). */\n\tconst groupSeqKey = (id: string): string => `groupSeq:${id}`;\n\n\t/** Persist a group's seq high-water mark and record its id in the index, so\n\t * forget() can preserve every group's mark across the cache wipe (the KV has\n\t * no key enumeration). Dropping a mark would let a replayed older manifest\n\t * re-add a removed member after a forget + re-join. */\n\tasync function persistGroupSeq(id: string, seq: number): Promise<void> {\n\t\tawait kv.set(groupSeqKey(id), seq);\n\t\tconst ids = (await kv.get<string[]>(KEY.groupSeqIds)) ?? [];\n\t\tif (!ids.includes(id)) await kv.set(KEY.groupSeqIds, [...ids, id]);\n\t}\n\n\t/** Raise the blocking gate with its reason and notify; the app renders from\n\t * the code. Notifying here (not at each call site) keeps the \"every mutation\n\t * ends in notify\" invariant that the cached state snapshot depends on. */\n\tfunction raiseGate(code: SelfstoreErrorCode, message: string): void {\n\t\tneedsAttention = true;\n\t\tlastError = storeError(code, message);\n\t\tnotify();\n\t}\n\n\t/** A transient, self-healing problem: reported, never gated. */\n\tconst transient = (message: string): StoreError => storeError('TARGET_UNAVAILABLE', message);\n\n\t/** Fire-and-forget kv write with the failure logged instead of unhandled. */\n\tfunction kvSetSafe(key: string, value: unknown, what: string): void {\n\t\tkv.set(key, value).catch((e) => logger.error(`[selfstore] ${what} write failed`, e));\n\t}\n\n\tfunction armIdleLock(): void {\n\t\tclearTimeout(idleTimer);\n\t\t// Arm whenever a secret sits in memory: a typed password, or the data key of\n\t\t// an envelope (password- or external-keyed). An external-keyed store holds no\n\t\t// password, so gate on the envelope too, or its data key would never expire.\n\t\tif (encrypted && (pass || envelope)) idleTimer = setTimeout(() => lockNow(), IDLE_LOCK_MS);\n\t}\n\tfunction lockNow(): void {\n\t\tclearTimeout(idleTimer);\n\t\tif (!pass && !envelope) return; // nothing sensitive in hand to drop\n\t\tsetPass(null); // drops the password and the envelope's data key (see setPass)\n\t\tneedsAttention = true; // re-lock: the gate asks to unlock again\n\t\tnotify();\n\t}\n\n\t// The password lives in memory only, never web storage: a reload boots the\n\t// target locked and re-prompts, which keeps the secret out of reach of any\n\t// script that could read localStorage/sessionStorage (XSS defence in depth).\n\t// The password envelope (raw data key + slot table, captured at read time)\n\t// follows the same rule: locking or forgetting the password drops it too -\n\t// a locked store must not keep a key that silently decrypts.\n\tfunction setPass(p: string | null): void {\n\t\tpass = p;\n\t\tif (p === null) envelope = null;\n\t\tarmIdleLock();\n\t}\n\n\tconst toCachedFiles = (snap: Snapshot): CachedFile[] =>\n\t\tsnap.files.map((f) => ({\n\t\t\tid: f.id,\n\t\t\tname: f.name,\n\t\t\tmime: f.mime,\n\t\t\tblob: new Blob([f.bytes as BlobPart], { type: f.mime })\n\t\t}));\n\n\t/** The inverse: rebuild a Snapshot from the cache's stored form. */\n\tasync function cachedToSnapshot(local: {\n\t\tcollections: Record<string, unknown[]>;\n\t\tfiles: CachedFile[];\n\t}): Promise<Snapshot> {\n\t\treturn {\n\t\t\tcollections: local.collections,\n\t\t\tfiles: await Promise.all(\n\t\t\t\tlocal.files.map(async (f) => ({\n\t\t\t\t\tid: f.id,\n\t\t\t\t\tname: f.name,\n\t\t\t\t\tmime: f.mime,\n\t\t\t\t\tbytes: new Uint8Array(await f.blob.arrayBuffer())\n\t\t\t\t}))\n\t\t\t)\n\t\t};\n\t}\n\n\tasync function buildBlob(pre?: Snapshot): Promise<Blob> {\n\t\t// Backstop the attach/setEncryption guards: even a direct exportBlob() never\n\t\t// hands back cleartext once the store is set to require encryption.\n\t\tif (requireEncryption && !encrypted && !group) {\n\t\t\tthrow new SelfstoreError(\n\t\t\t\t'ENCRYPTION_REQUIRED',\n\t\t\t\t'requireEncryption is set: refusing to build a plaintext backup.'\n\t\t\t);\n\t\t}\n\t\t// Reuse a snapshot the caller already gathered (pushDurable hashes it first),\n\t\t// so a save does not gather twice for the same bytes. No caller mutates state\n\t\t// between its gather and this call.\n\t\tconst snap = pre ?? (await gather());\n\t\t// Encrypted writes carry the password envelope: the held data key plus\n\t\t// every slot from the last read, so a session that knows only one of the\n\t\t// backup's passwords never drops the others. A file read before the\n\t\t// envelope era (or a fresh setting) mints its single-slot envelope here -\n\t\t// the write upgrades the container in place, same password.\n\t\tlet env: BoxEnvelope | undefined;\n\t\tif (encrypted && !group) {\n\t\t\tif (!envelope && pass) {\n\t\t\t\tconst dataKey = crypto.getRandomValues(new Uint8Array(32));\n\t\t\t\tenvelope = { dataKey, slots: [await mintSlot(pass, dataKey)] };\n\t\t\t}\n\t\t\tenv = envelope ?? undefined;\n\t\t\t// Locked mid-build (a lock() or the idle auto-lock dropped both pass and\n\t\t\t// envelope while this write was awaiting the network): refuse rather than\n\t\t\t// fall through to a plaintext write of an encrypted backup. The caller's\n\t\t\t// push lands in its transient path and retries after unlock; exportBlob\n\t\t\t// surfaces the error instead of handing back cleartext.\n\t\t\tif (!env) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'PASSWORD_REQUIRED',\n\t\t\t\t\t'Cannot write the encrypted backup while locked - unlock first.'\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\t// The store's bookkeeping rides its own sync.json sidecar (encrypted with\n\t\t// the data when a password is set), so the app's collections travel\n\t\t// untouched - no reserved collection injected into user data.\n\t\t// Never stamp below the schema ceiling ever seen (same rule persistLocal uses\n\t\t// for the kv version): a downgraded app must not write its lower number over\n\t\t// newer-shape data it hydrated, or other devices would skip the migration.\n\t\tconst stampV = Math.max(version, schemaCeiling);\n\t\tconst sidecar: Bookkeeping = { schemaVersion: stampV, meta };\n\t\t// Group mode: envelope for every current member - plus ourselves even if\n\t\t// the manifest dropped us (we must always reopen our own copy), and sign.\n\t\tconst groupOpts = group\n\t\t\t? {\n\t\t\t\t\trecipients: [\n\t\t\t\t\t\t...new Set([...group.manifest.members.map((m) => m.enc), group.identity.encPub])\n\t\t\t\t\t],\n\t\t\t\t\tsign: { pub: group.identity.sigPub, priv: group.identity.sigPriv }\n\t\t\t\t}\n\t\t\t: undefined;\n\t\tconst bytes = await writeBox(\n\t\t\t{ collections: snap.collections, files: snap.files },\n\t\t\t{ app, appVersion, schemaVersion: stampV, envelope: env, group: groupOpts, readme },\n\t\t\tsidecar\n\t\t);\n\t\treturn new Blob([bytes as BlobPart], { type: BACKUP_MIME });\n\t}\n\n\t/** Publish every attached mirror: the current state (collections + files +\n\t * sync sidecar, so a reader can merge it as a replica), re-encoded under\n\t * each mirror's own password. Failures land on that mirror's state and\n\t * never gate the store or the surrounding save/converge. */\n\tasync function publishMirrors(): Promise<void> {\n\t\tif (mirrorList.length === 0 || locked() || needsAttention) return;\n\t\t// One snapshot for the whole round: every mirror publishes the same current\n\t\t// state, so re-gathering per mirror was pure repeat work.\n\t\tconst snap = await gather();\n\t\tfor (const m of mirrorList) {\n\t\t\ttry {\n\t\t\t\tif (!m.envelope) {\n\t\t\t\t\tconst dataKey = crypto.getRandomValues(new Uint8Array(32));\n\t\t\t\t\tm.envelope = { dataKey, slots: [await mintSlot(m.password, dataKey)] };\n\t\t\t\t}\n\t\t\t\tconst sidecar: Bookkeeping = { schemaVersion: version, meta };\n\t\t\t\tconst bytes = await writeBox(\n\t\t\t\t\t{ collections: snap.collections, files: snap.files },\n\t\t\t\t\t{ app, appVersion, schemaVersion: version, envelope: m.envelope, readme },\n\t\t\t\t\tsidecar\n\t\t\t\t);\n\t\t\t\tawait m.target.save(new Blob([bytes as BlobPart], { type: BACKUP_MIME }));\n\t\t\t\tm.lastPublishAt = Date.now();\n\t\t\t\tm.lastError = null;\n\t\t\t} catch (e) {\n\t\t\t\tm.lastError = isAuthExpired(e)\n\t\t\t\t\t? storeError('AUTH_EXPIRED', 'Write access to the mirror expired or was revoked.')\n\t\t\t\t\t: isSelfstoreError(e)\n\t\t\t\t\t\t? storeError(e.code, e.message)\n\t\t\t\t\t\t: transient('Mirror momentarily unreachable.');\n\t\t\t\tlogger.warn(`[selfstore] mirror \"${m.id}\" publish failed`, e);\n\t\t\t}\n\t\t}\n\t\tnotify();\n\t}\n\n\t/** Write the current backup to every replica: the SAME bytes as the primary\n\t * home (buildBlob under the store's own key), built once for the round. Best\n\t * effort - a broken replica lands on its own state and never gates the store\n\t * or the surrounding save/converge. Skipped while locked (buildBlob would\n\t * refuse) or gated. */\n\tasync function publishReplicas(): Promise<void> {\n\t\tif (replicaList.length === 0 || locked() || needsAttention) return;\n\t\tlet blob: Blob;\n\t\ttry {\n\t\t\tblob = await buildBlob();\n\t\t} catch (e) {\n\t\t\t// buildBlob refuses to write an encrypted backup while locked: skip this\n\t\t\t// round rather than emit a plaintext replica; the next save retries.\n\t\t\tlogger.warn('[selfstore] replica publish skipped (cannot build backup)', e);\n\t\t\treturn;\n\t\t}\n\t\tfor (const r of replicaList) {\n\t\t\ttry {\n\t\t\t\tawait r.target.save(blob);\n\t\t\t\tr.lastPublishAt = Date.now();\n\t\t\t\tr.lastError = null;\n\t\t\t} catch (e) {\n\t\t\t\tr.lastError = isAuthExpired(e)\n\t\t\t\t\t? storeError('AUTH_EXPIRED', 'Write access to the replica expired or was revoked.')\n\t\t\t\t\t: isSelfstoreError(e)\n\t\t\t\t\t\t? storeError(e.code, e.message)\n\t\t\t\t\t\t: transient('Replica momentarily unreachable.');\n\t\t\t\tlogger.warn(`[selfstore] replica \"${r.id}\" publish failed`, e);\n\t\t\t}\n\t\t}\n\t\tnotify();\n\t}\n\n\t/** The store's bookkeeping for a decoded remote: the schema version its data\n\t * was written under and its merge metadata, from the sync.json sidecar. A\n\t * reserved `__`-prefixed collection is never data - strip it from the app's\n\t * view rather than hand it to apply(). */\n\tfunction readBookkeeping(\n\t\tsnap: Snapshot,\n\t\tsidecar: unknown\n\t): { fromVersion: number; sync: SyncMeta | null } {\n\t\tif (RESERVED in snap.collections) delete snap.collections[RESERVED];\n\t\tconst s = sidecar as Partial<Bookkeeping> | null;\n\t\treturn { fromVersion: s?.schemaVersion ?? 0, sync: s?.meta ?? null };\n\t}\n\n\tconst migrated = (snap: Snapshot, fromV: number): Snapshot =>\n\t\topts.migrate && fromV < version ? opts.migrate(fromV, snap) : snap;\n\n\t/** Union files by id (immutable per id, so prefer local). Orphans from deleted\n\t * records self-heal: the next gather omits them and the cache reconciles. */\n\tfunction mergeFiles(local: Snapshot['files'], remote: Snapshot['files']): Snapshot['files'] {\n\t\tconst byId = new Map<string, Snapshot['files'][number]>();\n\t\tfor (const f of remote) byId.set(f.id, f);\n\t\tfor (const f of local) byId.set(f.id, f);\n\t\treturn [...byId.values()];\n\t}\n\n\t/** Persist the in-memory state to L2 and stamp which records moved. The\n\t * version stamp never goes below the schema ceiling: a downgraded app must\n\t * not erase the newer-schema marker, or its next boot would drop the\n\t * SCHEMA_TOO_NEW gate and let it clobber the newer backup. */\n\t/** Warn (once per collection) about records the sync engine cannot track\n\t * because they have no string id at the configured path: they silently never\n\t * replicate. The message states the fix, so a dev - or an LLM reading the\n\t * console - can correct it without digging. */\n\tfunction warnUnsyncable(collections: Record<string, unknown[]>): void {\n\t\tconst counts = unsyncableCounts(collections, sync);\n\t\tfor (const [name, n] of Object.entries(counts)) {\n\t\t\tif (warnedNoId.has(name)) continue;\n\t\t\twarnedNoId.add(name);\n\t\t\tconst path = idPathFor(sync, name);\n\t\t\tlogger.warn(\n\t\t\t\t`[selfstore] ${n} record(s) in collection \"${name}\" have no string id at \"${path}\" ` +\n\t\t\t\t\t`and will NOT sync or persist reliably. selfstore identifies records by a string id. ` +\n\t\t\t\t\t`Give each record a string id, or map this collection's id field with ` +\n\t\t\t\t\t`createLocalStore({ sync: { ids: { ${JSON.stringify(name)}: 'yourIdField' } } }).`\n\t\t\t);\n\t\t}\n\t}\n\n\tasync function persistLocal(): Promise<void> {\n\t\t// Absorb what other tabs persisted first, so this write is a superset of\n\t\t// theirs instead of an overwrite (multi-tab safety). When the fold finds a\n\t\t// newer-schema cache it gates and returns false: this stale tab must not\n\t\t// write its old-shape data over the newer one (it would stamp the newer\n\t\t// version number onto old-shape records - cross-device corruption), the same\n\t\t// never-clobber rule convergeRemote and adoptTabState follow.\n\t\tif (!(await foldTabWrites())) return;\n\t\tconst snap = await gather();\n\t\twarnUnsyncable(snap.collections);\n\t\t// Trim old delete-tombstones before stamping, so the sync metadata does not\n\t\t// grow without bound (opt-in; see tombstoneHorizonMs for the safety window).\n\t\tif (opts.tombstoneHorizonMs) meta = gcTombstones(meta, Date.now() - opts.tombstoneHorizonMs);\n\t\tmeta = stamp(meta, snap.collections, sync);\n\t\tawait cache.saveCollections(snap.collections);\n\t\tawait cache.saveFiles(toCachedFiles(snap));\n\t\tawait kv.set(KEY.syncMeta, meta);\n\t\tawait kv.set(KEY.version, Math.max(version, schemaCeiling));\n\t\tlastSavedAt = Date.now();\n\t\tawait kv.set(KEY.lastSavedAt, lastSavedAt);\n\t\tawait publishWrite('change');\n\t}\n\n\t/** Stamp the cache with a fresh write epoch and tell the other tabs. The\n\t * message carries no user data (a tab id and a kind); the state itself\n\t * travels through the shared cache. */\n\tasync function publishWrite(kind: 'change' | 'forget'): Promise<void> {\n\t\tseenEpoch = createNode();\n\t\tawait kv.set(KEY.epoch, seenEpoch);\n\t\tchannel?.postMessage({ tab: tabId, kind });\n\t}\n\n\t/** Fold in whatever OTHER tabs persisted since this tab last touched the\n\t * cache. Runs at the start of every persist: the shared cache is treated as\n\t * one more replica and merged with the app's live state - in-flight edits are\n\t * stamped first, so they keep their (latest) clocks - which is what makes a\n\t * save from one tab unable to erase another tab's records or resurrect its\n\t * deletes. One kv read when nothing changed. */\n\tasync function foldTabWrites(): Promise<boolean> {\n\t\tconst current = await kv.get<string>(KEY.epoch);\n\t\tif (current === undefined || current === seenEpoch) return true;\n\t\tconst local = await cache.load();\n\t\tif (!local) {\n\t\t\tseenEpoch = current;\n\t\t\treturn true;\n\t\t}\n\t\tconst storedV = (await kv.get<number>(KEY.version)) ?? version;\n\t\tif (isNewerSchema(storedV)) {\n\t\t\t// A newer-schema tab wrote the cache: this stale tab gates instead of\n\t\t\t// merging shapes it cannot migrate. Reloading the tab resumes. Return\n\t\t\t// false so persistLocal ABORTS its write - never clobber the newer cache.\n\t\t\tgateNewerSchema(storedV);\n\t\t\tseenEpoch = current;\n\t\t\treturn false;\n\t\t}\n\t\tconst tabMeta = await kv.get<SyncMeta>(KEY.syncMeta);\n\t\tif (!tabMeta) {\n\t\t\tseenEpoch = current;\n\t\t\treturn true;\n\t\t}\n\t\tconst snap = migrated(await cachedToSnapshot(local), storedV);\n\t\tconst live = await gather();\n\t\tmeta = stamp(meta, live.collections, sync); // in-flight edits win over older tab clocks\n\t\tconst merged = merge(\n\t\t\t{ collections: live.collections, meta },\n\t\t\t{ collections: snap.collections, meta: tabMeta },\n\t\t\tsync\n\t\t);\n\t\tmeta = merged.meta;\n\t\tapply({ collections: merged.collections, files: mergeFiles(live.files, snap.files) });\n\t\tseenEpoch = current; // only after the fold landed, so a failure retries\n\t\treturn true;\n\t}\n\n\t/** Replace this tab's state with what another tab persisted (only called with\n\t * no local edit in flight). Data + sync bookkeeping; the journal keeps this\n\t * tab's own in-memory conflict values, and a durable target's connection\n\t * stays per-tab. */\n\tasync function adoptTabState(): Promise<void> {\n\t\tconst current = await kv.get<string>(KEY.epoch);\n\t\tif (current === seenEpoch) return;\n\t\tconst local = await cache.load();\n\t\tconst storedV = (await kv.get<number>(KEY.version)) ?? version;\n\t\t// Same rule as boot: newer-schema data still hydrates (it is the user's),\n\t\t// but the gate blocks pushes from this stale tab.\n\t\tif (isNewerSchema(storedV)) gateNewerSchema(storedV);\n\t\tif (local) apply(migrated(await cachedToSnapshot(local), storedV));\n\t\telse apply({ collections: {}, files: [] });\n\t\tmeta = (await kv.get<SyncMeta>(KEY.syncMeta)) ?? createMeta();\n\t\tbaseMeta = (await kv.get<SyncMeta>(KEY.baseMeta)) ?? null;\n\t\tlastSavedAt = (await kv.get<number>(KEY.lastSavedAt)) ?? null;\n\t\tremoteVersion = (await kv.get<string>(KEY.remoteVersion)) ?? null;\n\t\t// Adopt the other tab's remote fingerprint too (it pushed, or forgot and\n\t\t// cleared it): keeping our own stale hash would wrongly skip a needed push.\n\t\tlastSavedContentHash = (await kv.get<string>(KEY.savedHash)) ?? null;\n\t\tif (durable) {\n\t\t\t// Another tab may have added or removed the backup password: refresh the\n\t\t\t// flag so this tab re-locks (and asks) instead of pushing the wrong setting.\n\t\t\tencrypted = (await kv.get(KEY.enc)) === true;\n\t\t\tneedsAttention = needsAttention || locked();\n\t\t}\n\t\tseenEpoch = current;\n\t\tnotify();\n\t}\n\n\t/** Coalesced cross-tab refresh: an idle tab adopts the other tab's state, a\n\t * tab holding an unsaved edit saves it instead (the save folds the other\n\t * write, so both survive), and a forget() elsewhere drops local state. */\n\tfunction onTabMessage(kind: 'change' | 'forget'): void {\n\t\tif (!ready || mode !== 'persistent') return;\n\t\tif (queuedKind) {\n\t\t\tif (kind === 'forget') queuedKind = 'forget';\n\t\t\treturn;\n\t\t}\n\t\tqueuedKind = kind;\n\t\tserialize(async () => {\n\t\t\tconst k = queuedKind;\n\t\t\tqueuedKind = null;\n\t\t\tif (k === 'forget') {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tpendingEdit = false; // the other tab wiped on purpose: the edit dies with the data\n\t\t\t\tmode = (await kv.get(KEY.mode)) === 'ephemeral' ? 'ephemeral' : 'persistent';\n\t\t\t\tconst savedKind = (await kv.get<TargetKind>(KEY.targetKind)) ?? 'device';\n\t\t\t\tif (durable) {\n\t\t\t\t\tawait dropDurable({ keepSession: true }); // that tab owns the disconnect side-effects\n\t\t\t\t}\n\t\t\t\t// Adopt the wiped kind even in a tab with no durable (file-manual): else\n\t\t\t\t// it kept 'file-manual', and its next save re-armed a download of the\n\t\t\t\t// now-empty backup while kv already said 'device'.\n\t\t\t\ttargetKind = savedKind;\n\t\t\t\tpendingDownload = false;\n\t\t\t\tseenEpoch = undefined; // that tab cleared and rewrote: adopt unconditionally\n\t\t\t\tawait adoptTabState();\n\t\t\t} else if (pendingEdit) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tawait doSave(); // folds the other tab's write and persists our edit with it\n\t\t\t} else {\n\t\t\t\tawait adoptTabState();\n\t\t\t}\n\t\t}).catch((e) => logger.error('[selfstore] cross-tab refresh failed', e));\n\t}\n\n\tif (channel) {\n\t\tchannel.onmessage = (ev: MessageEvent): void => {\n\t\t\tconst msg = ev.data as { tab?: string; kind?: 'change' | 'forget' } | null;\n\t\t\tif (msg && msg.tab !== tabId && (msg.kind === 'change' || msg.kind === 'forget')) {\n\t\t\t\tonTabMessage(msg.kind);\n\t\t\t}\n\t\t};\n\t}\n\n\t/** The blob inspectTarget stashed for `t`, but only when it is still safe to\n\t * reuse instead of downloading again: same target, fresh entry, and - the\n\t * safety gate - the remote's change marker is unchanged since the inspect, so\n\t * the blob still is the remote. A moved remote (or a target that cannot report\n\t * a marker) returns null, and the caller does a live load. One-shot: the entry\n\t * is consumed whatever the outcome. */\n\tasync function takeFreshPrefetch(t: BackupTarget): Promise<Blob | null> {\n\t\tconst p = prefetched;\n\t\tprefetched = null; // one-shot, whatever we decide below\n\t\tif (!p || p.target !== t || p.marker === null) return null;\n\t\tif (Date.now() - p.at > PREFETCH_TTL_MS) return null;\n\t\tlet now: string | null;\n\t\ttry {\n\t\t\tnow = t.stat ? await t.stat() : null;\n\t\t} catch {\n\t\t\treturn null; // cannot confirm it did not move: load live\n\t\t}\n\t\treturn now !== null && now === p.marker ? p.blob : null;\n\t}\n\n\t/** The remote's current change marker, or null when the target cannot tell. */\n\tasync function statRemote(): Promise<string | null> {\n\t\tif (!durable?.stat) return null;\n\t\ttry {\n\t\t\treturn await durable.stat();\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/** Readiness check for the encryption-management flows (setEncryption and the\n\t * key-slot methods), which call isReady() OUTSIDE the store's normal push\n\t * path. isReady() now THROWS AuthExpired on a genuine loss: raise the gate\n\t * before it propagates, so the store reads needs-attention instead of a false\n\t * \"saved\", then rethrow so the caller knows the op did not run. Throws\n\t * TARGET_WRITE_FAILED for a transient not-ready. */\n\tasync function requireReady(where: string): Promise<void> {\n\t\tlet ok: boolean;\n\t\ttry {\n\t\t\tok = await durable!.isReady();\n\t\t} catch (e) {\n\t\t\tif (isAuthExpired(e)) {\n\t\t\t\traiseGate('AUTH_EXPIRED', 'Access to the destination expired or was revoked.');\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t\tif (!ok) {\n\t\t\tthrow new SelfstoreError(\n\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t`${where}(): the destination is unreachable; try again online.`\n\t\t\t);\n\t\t}\n\t}\n\n\tasync function setRemoteVersion(v: string | null): Promise<void> {\n\t\tremoteVersion = v;\n\t\tif (v === null) await kv.del(KEY.remoteVersion);\n\t\telse await kv.set(KEY.remoteVersion, v);\n\t}\n\n\t/** The persisted form of a journal entry: conflict VALUES are redacted. The\n\t * kv bookkeeping is not encrypted at rest (only the collections snapshot and\n\t * files are sealed), so full user records must never travel there - the live\n\t * in-memory journal keeps the values for the session's resolution UI. */\n\tfunction redactForStorage(entries: SyncJournalEntry[]): SyncJournalEntry[] {\n\t\treturn entries.map((e) =>\n\t\t\te.conflicts\n\t\t\t\t? {\n\t\t\t\t\t\t...e,\n\t\t\t\t\t\tconflicts: e.conflicts.map(({ collection, id, kept }) => ({ collection, id, kept }))\n\t\t\t\t\t}\n\t\t\t\t: e\n\t\t);\n\t}\n\n\t/** Append a converge to the journal - only when it changed something the user\n\t * can see (derived collections are silent). Returns the entry, or null. */\n\tfunction recordJournal(\n\t\tdelta: Record<string, CollectionChanges>,\n\t\tsource: SyncSource,\n\t\tconflicts: Conflict[] = []\n\t): SyncJournalEntry | null {\n\t\tconst visible = Object.fromEntries(\n\t\t\tObject.entries(delta).filter(([name]) => !journalSilent.has(name))\n\t\t);\n\t\tif (Object.keys(visible).length === 0) return null;\n\t\tconst entry: SyncJournalEntry = { at: Date.now(), source, changes: visible };\n\t\tif (conflicts.length > 0) entry.conflicts = conflicts;\n\t\tjournal = [entry, ...journal].slice(0, JOURNAL_MAX);\n\t\tlastSync = entry;\n\t\tkvSetSafe(KEY.syncJournal, redactForStorage(journal), 'journal');\n\t\treturn entry;\n\t}\n\n\tasync function pushDurable(source: SyncSource = 'push'): Promise<boolean> {\n\t\tif (!durable || locked() || needsAttention) return false;\n\t\ttry {\n\t\t\t// isReady() rethrows a genuine auth loss and returns false only for a\n\t\t\t// transient hiccup, so a cold-start never masquerades as \"not ready\".\n\t\t\tif (!(await durable.isReady())) {\n\t\t\t\t// Momentarily unreachable: the edit is safe in the local cache. Leave the\n\t\t\t\t// connection attached and let the next scheduled save / focus-sync retry.\n\t\t\t\t// Never raise the blocking reconnect gate over a still-valid session.\n\t\t\t\tlastError = transient('Save deferred: destination momentarily unreachable.');\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Converge first when another replica wrote since our last sync: a blind\n\t\t\t// push would hide its changes from every replica until its next pull.\n\t\t\tconst seen = await statRemote();\n\t\t\tif (seen !== null && remoteVersion !== null && seen !== remoteVersion) {\n\t\t\t\tawait pullRemoteIntoLocal(source, seen);\n\t\t\t\tif (locked() || needsAttention) return false; // the pull hit a lock: never clobber\n\t\t\t}\n\t\t\t// Skip the upload when the remote already holds this exact content: a\n\t\t\t// converge that only adopted the remote, or a reactive re-save, would\n\t\t\t// otherwise re-encrypt and re-upload byte-identical data - the commonest\n\t\t\t// recurring waste of a synced session, and the \"enregistrements inutiles\"\n\t\t\t// a user sees. One gather() here feeds both the fingerprint and the blob.\n\t\t\tconst snap = await gather();\n\t\t\tconst digest = await contentDigest(snap);\n\t\t\tif (digest === lastSavedContentHash) {\n\t\t\t\tlastError = null;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tconst written = await durable.save(await buildBlob(snap));\n\t\t\tawait setRemoteVersion(typeof written === 'string' ? written : await statRemote());\n\t\t\t// Remember what reached the remote, so the next passive save (or a converge\n\t\t\t// that changed nothing) skips a byte-identical upload.\n\t\t\tlastSavedContentHash = digest;\n\t\t\tkvSetSafe(KEY.savedHash, digest, 'savedHash');\n\t\t\tlastError = null;\n\t\t\treturn true;\n\t\t} catch (e) {\n\t\t\tif (isAuthExpired(e)) {\n\t\t\t\t// The session is genuinely gone: only a user gesture (reconnect) fixes it.\n\t\t\t\traiseGate('AUTH_EXPIRED', 'Access to the destination expired or was revoked.');\n\t\t\t} else if (isSelfstoreError(e) && e.code === 'TARGET_GONE') {\n\t\t\t\t// The bound destination is permanently unwritable (the file was deleted\n\t\t\t\t// or moved, access was withdrawn, storage is full): retrying writes the\n\t\t\t\t// same doomed request forever - the silent \"momentarily unreachable\"\n\t\t\t\t// trap - so gate and let the user reconnect to a fresh file or free\n\t\t\t\t// space. This is a false \"saved\" otherwise: persistLocal already bumped\n\t\t\t\t// lastSavedAt, so a swallowed push would read as safely saved.\n\t\t\t\traiseGate('TARGET_GONE', e.message);\n\t\t\t} else {\n\t\t\t\t// Transient (offline, cold-start 5xx, network reset): keep the connection,\n\t\t\t\t// the edit waits in the local cache, the next save/sync retries. Raising\n\t\t\t\t// the reconnect gate here is exactly the spurious popin we must avoid.\n\t\t\t\tlastError = transient('Save deferred: destination momentarily unreachable.');\n\t\t\t}\n\t\t\tlogger.error('[selfstore] push to durable failed', e);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/** SHA-256 of the snapshot's user content (collections + files) - the bytes a\n\t * save would write, minus the encryption envelope and sync sidecar. Two saves\n\t * with the same digest push byte-identical user data, so the second is a\n\t * no-op. Stable across gathers of unchanged data (files sorted by id). */\n\tasync function contentDigest(snap: Snapshot): Promise<string> {\n\t\tconst enc = new TextEncoder();\n\t\tconst parts: Uint8Array[] = [enc.encode(JSON.stringify(snap.collections))];\n\t\tfor (const f of [...snap.files].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))) {\n\t\t\tparts.push(enc.encode(`\\u001f${f.id}\\u001f${f.mime}\\u001f`), f.bytes);\n\t\t}\n\t\tlet len = 0;\n\t\tfor (const p of parts) len += p.length;\n\t\tconst buf = new Uint8Array(len);\n\t\tlet off = 0;\n\t\tfor (const p of parts) {\n\t\t\tbuf.set(p, off);\n\t\t\toff += p.length;\n\t\t}\n\t\tconst digest = await crypto.subtle.digest('SHA-256', buf);\n\t\treturn [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, '0')).join('');\n\t}\n\n\tasync function doSave(): Promise<void> {\n\t\tif (mode !== 'persistent') return;\n\t\t// Snapshot the edit counter: an edit that lands while this save is gathering\n\t\t// or writing bumps it, and its flag must not be cleared below (that edit is\n\t\t// not in what we persist). See editSeq.\n\t\tconst seq = editSeq;\n\t\t// Skip a save whose content is byte-identical to the last one pushed: a\n\t\t// reactive touch (a share link created, a derived store recomputed) must\n\t\t// not flash \"saving\" or re-upload an unchanged backup. A genuine edit - or\n\t\t// an edit not yet pushed to the remote - hashes differently and still\n\t\t// saves, so this only ever drops redundant work, never a real change.\n\t\tconst digest = await contentDigest(await gather());\n\t\tif (digest === lastSavedContentHash) {\n\t\t\tif (editSeq === seq) pendingEdit = false;\n\t\t\treturn;\n\t\t}\n\t\tsaving = true;\n\t\tnotify();\n\t\ttry {\n\t\t\tawait persistLocal();\n\t\t\tif (editSeq === seq) pendingEdit = false; // an edit that arrived mid-persist stays in flight\n\t\t\tif (targetKind === 'file-manual') {\n\t\t\t\t// No remote to reach: the downloaded file is the copy. Remember the\n\t\t\t\t// content so a passive re-save does not re-arm the download for nothing.\n\t\t\t\tlastSavedContentHash = digest;\n\t\t\t\tkvSetSafe(KEY.savedHash, digest, 'savedHash');\n\t\t\t\tpendingDownload = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// pushDurable owns the remote fingerprint now: it records lastSavedContentHash\n\t\t\t// only on a real push (a deferred/failed/permanent-gone push leaves it\n\t\t\t// untouched, so the next save retries), and skips a byte-identical upload.\n\t\t\tawait pushDurable();\n\t\t\t// The published copies follow every local edit (best-effort, per-mirror\n\t\t\t// errors only - see publishMirrors).\n\t\t\tawait publishMirrors();\n\t\t\tawait publishReplicas();\n\t\t} finally {\n\t\t\tsaving = false;\n\t\t\tnotify();\n\t\t}\n\t}\n\n\tconst save = (): Promise<void> => serialize(doSave);\n\n\t/** PURE check for a silent downgrade/substitution: we expect an encrypted\n\t * backup but the loaded file's header says it is unencrypted. An attacker\n\t * with write access to the destination could otherwise swap in a crafted\n\t * plaintext backup that loads with no password prompt. In group mode the\n\t * bar is higher still: anything that is not a group copy (plaintext or\n\t * password mode) is a substitution. The caller decides what to do (gate). */\n\tasync function isDowngraded(remote: Blob): Promise<boolean> {\n\t\tif (!encrypted) return false;\n\t\ttry {\n\t\t\tconst h = await inspect(remote);\n\t\t\tif (group) return h.keying !== GROUP_KEYING;\n\t\t\treturn h.encryption === 'none';\n\t\t} catch {\n\t\t\treturn false; // unreadable header: let the normal import path handle it\n\t\t}\n\t}\n\n\t/** A decoded remote: the app snapshot plus its opaque sync.json sidecar. */\n\ttype Decoded = { snapshot: Snapshot; sidecar: unknown };\n\n\t/** Decode a remote backup with the shared safety rails: the downgrade guard,\n\t * and the password/lock (or group trust) protocol. Resolves to the decoded\n\t * snapshot + sidecar, or 'locked' when the caller must not touch either side\n\t * (gate raised, reason in lastError). Any other decode failure PROPAGATES -\n\t * a genuine bug must never read as \"nothing changed\". */\n\tasync function importLocked(remote: Blob): Promise<Decoded | 'locked'> {\n\t\tif (await isDowngraded(remote)) {\n\t\t\traiseGate(\n\t\t\t\t'UNEXPECTEDLY_UNENCRYPTED',\n\t\t\t\tgroup\n\t\t\t\t\t? 'Expected a signed group copy - found something else. Refused for safety.'\n\t\t\t\t\t: 'Unexpected unencrypted backup - refused for safety.'\n\t\t\t);\n\t\t\treturn 'locked';\n\t\t}\n\t\ttry {\n\t\t\tconst r = await readBoxWithSync(\n\t\t\t\tawait asBytes(remote),\n\t\t\t\tpass ?? undefined,\n\t\t\t\townGroupRead(),\n\t\t\t\tenvelope?.dataKey,\n\t\t\t\t// Only during a passkey unlock (a user gesture) is a secret in hand for\n\t\t\t\t// an external slot; a background converge has none and reads via the held\n\t\t\t\t// data key or gates for the user to unlock.\n\t\t\t\tpendingExternalSecret ? async () => pendingExternalSecret : undefined\n\t\t\t);\n\t\t\t// Capture (or refresh) the envelope: another device may have added or\n\t\t\t// removed a slot since our last read. A plain (never encrypted) copy\n\t\t\t// reads with none - the next password write mints it (buildBlob).\n\t\t\tif (!group) envelope = r.envelope ?? null;\n\t\t\treturn r;\n\t\t} catch (e) {\n\t\t\tif (isSelfstoreError(e) && (e.code === 'PASSWORD_REQUIRED' || e.code === 'DECRYPT_FAILED')) {\n\t\t\t\t// The remote is genuinely encrypted (a key is missing or wrong). Reconcile\n\t\t\t\t// the local flag to that truth: a device that attached without a key - an\n\t\t\t\t// external-keyed backup has no attach-time secret to offer, unlike a\n\t\t\t\t// password - would otherwise carry encrypted=false and never read as\n\t\t\t\t// locked(), so neither unlock() nor unlockWithExternal() (both of which\n\t\t\t\t// require locked()) could ever clear the gate.\n\t\t\t\tif (!encrypted) {\n\t\t\t\t\tencrypted = true;\n\t\t\t\t\tkvSetSafe(KEY.enc, true, 'enc');\n\t\t\t\t}\n\t\t\t\tsetPass(null);\n\t\t\t\traiseGate(e.code, e.message);\n\t\t\t\treturn 'locked'; // wrong/missing key: re-lock and ask, never clobber\n\t\t\t}\n\t\t\tif (\n\t\t\t\tisSelfstoreError(e) &&\n\t\t\t\t(e.code === 'IDENTITY_REQUIRED' ||\n\t\t\t\t\te.code === 'SIGNATURE_INVALID' ||\n\t\t\t\t\te.code === 'NOT_A_RECIPIENT')\n\t\t\t) {\n\t\t\t\t// Group trust failed on our own copy (foreign signature, missing\n\t\t\t\t// identity, no envelope): gate, never clobber either side.\n\t\t\t\traiseGate(e.code, e.message);\n\t\t\t\treturn 'locked';\n\t\t\t}\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// The highest schema version ever SEEN on this device's data (cache or\n\t// remote). While it exceeds our own, the gate stays up - and persistLocal\n\t// must never stamp a LOWER version over it, or a downgraded app would clear\n\t// the gate on its next boot and clobber the newer backup.\n\tlet schemaCeiling = version;\n\n\t/** PURE: is this data written by a newer app schema than ours? */\n\tconst isNewerSchema = (fromVersion: number): boolean => fromVersion > version;\n\n\t/** Command: record the newer schema and raise the blocking gate. An older app\n\t * must neither apply a shape it cannot migrate nor push its older shape over\n\t * it; only updating the app resolves this. */\n\tfunction gateNewerSchema(fromVersion: number): void {\n\t\tschemaCeiling = Math.max(schemaCeiling, fromVersion);\n\t\traiseGate(\n\t\t\t'SCHEMA_TOO_NEW',\n\t\t\t`Backup written by schema v${fromVersion}; this app reads v${version}. Update the app.`\n\t\t);\n\t}\n\n\t/** Three-way converge the local state with a decoded remote snapshot: merge\n\t * when it carries sync metadata, else adopt the foreign copy if this device\n\t * is fresh. Resolves to the journal entry when the merge changed local data. */\n\tasync function convergeRemote(\n\t\tsnap: Snapshot,\n\t\tsidecar: unknown,\n\t\tsource: SyncSource\n\t): Promise<SyncJournalEntry | null> {\n\t\tconst { fromVersion, sync: remoteMeta } = readBookkeeping(snap, sidecar);\n\t\tif (isNewerSchema(fromVersion)) {\n\t\t\tgateNewerSchema(fromVersion);\n\t\t\treturn null;\n\t\t}\n\t\tconst snapM = migrated(snap, fromVersion);\n\t\tif (!remoteMeta) {\n\t\t\tawait adoptForeign(snapM);\n\t\t\treturn null;\n\t\t}\n\t\tconst local = await gather();\n\t\t// Stamp before merging: an edit still inside the debounce window carries no\n\t\t// clock yet and would lose to any newer remote clock. Stamping now gives it\n\t\t// its rightful (latest) clock, so an in-flight edit survives the converge.\n\t\tmeta = stamp(meta, local.collections, sync);\n\t\tconst localState = { collections: local.collections, meta };\n\t\tconst remoteState = { collections: snapM.collections, meta: remoteMeta };\n\t\tconst result = merge(localState, remoteState, sync);\n\t\t// Informational: same-record edits both sides made since the last converge.\n\t\t// merge() already picked the latest; this reports what was overwritten, with\n\t\t// both values, so the app can surface (or restore) the losing side.\n\t\tconst conflicts = detectConflicts(localState, remoteState, sync, baseMeta ?? undefined);\n\t\tconst delta = changes(local.collections, result.collections, sync);\n\t\tmeta = result.meta;\n\t\tbaseMeta = meta;\n\t\tkvSetSafe(KEY.baseMeta, meta, 'baseMeta');\n\t\tapply({ collections: result.collections, files: mergeFiles(local.files, snapM.files) });\n\t\t// Record what the remote CURRENTLY holds (its decoded content, in our\n\t\t// migrated form). The push-back that follows this converge fingerprints the\n\t\t// merged local state and compares: equal when our merge added nothing (the\n\t\t// remote already has it - no ping-pong re-upload), different when we\n\t\t// contributed a newer value (so the needed push still happens). Without this\n\t\t// the fingerprint kept describing our last push, causing either a wasteful\n\t\t// full re-upload every passive sync, or - worse - skipping a push whose\n\t\t// merged content happened to match that stale fingerprint.\n\t\tlastSavedContentHash = await contentDigest({\n\t\t\tcollections: snapM.collections,\n\t\t\tfiles: snapM.files\n\t\t});\n\t\tkvSetSafe(KEY.savedHash, lastSavedContentHash, 'savedHash');\n\t\tawait persistLocal();\n\t\tif (conflicts.length) {\n\t\t\tlogger.warn(\n\t\t\t\t'[selfstore] concurrent edits auto-resolved (latest kept): ' +\n\t\t\t\t\tconflicts.map((c) => `${c.collection}/${c.id}`).join(', ')\n\t\t\t);\n\t\t}\n\t\treturn recordJournal(delta, source, conflicts);\n\t}\n\n\t/** Load + decode + converge only (no push back). `seen` is the remote marker\n\t * stat'ed before the load: a write landing mid-load still reads as stale on\n\t * the next check instead of being marked seen-but-unmerged. Resolves to the\n\t * journal entry, 'locked' (missing/wrong password, a refused plaintext swap,\n\t * or a newer-schema remote - the caller must not push), or null when nothing\n\t * changed. */\n\tasync function pullRemoteIntoLocal(\n\t\tsource: SyncSource,\n\t\tseen?: string | null\n\t): Promise<SyncJournalEntry | 'locked' | null> {\n\t\tif (!durable) return null;\n\t\tconst marker = seen === undefined ? await statRemote() : seen;\n\t\tlet remote: Blob | null = null;\n\t\ttry {\n\t\t\t// Reuse the blob inspectTarget just downloaded when the remote has not\n\t\t\t// moved since (the connect journey), else load live. `marker` above was\n\t\t\t// stat'ed the same way the reuse is gated on, so it stays consistent.\n\t\t\tremote = (await takeFreshPrefetch(durable)) ?? (await durable.load());\n\t\t} catch {\n\t\t\t/* offline or transient: keep local, push later */\n\t\t}\n\t\tif (!remote) return null;\n\t\tconst decoded = await importLocked(remote);\n\t\tif (decoded === 'locked') return 'locked';\n\t\tconst entry = await convergeRemote(decoded.snapshot, decoded.sidecar, source);\n\t\tif (needsAttention) return 'locked'; // newer schema: never mark seen, never push\n\t\tawait setRemoteVersion(marker);\n\t\treturn entry;\n\t}\n\n\t/** Fold every attached peer's published copy into local state: pull each copy\n\t * (a cheap stat() skips unchanged ones), decode it with the same rails as the\n\t * own target, and merge it as one more replica - exactly the multi-device\n\t * merge, sourced from a read-only link. Per-peer failures are recorded on\n\t * that peer's state and never gate the store or block the surrounding\n\t * converge: only the own target raises blocking gates. Resolves to the last\n\t * journal entry a fold produced, or null when nothing changed. */\n\tasync function foldPeers(source: SyncSource): Promise<SyncJournalEntry | null> {\n\t\tif (peerList.length === 0 || locked() || needsAttention) return null;\n\t\tlet entry: SyncJournalEntry | null = null;\n\t\tlet folded = false;\n\t\tfor (const p of peerList) {\n\t\t\ttry {\n\t\t\t\tlet marker: string | null = null;\n\t\t\t\tif (p.source.stat) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tmarker = await p.source.stat();\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tif (isAuthExpired(e)) throw e; // a genuine read-access loss: record it below\n\t\t\t\t\t\tmarker = null; // cannot tell: fall through to a full load\n\t\t\t\t\t}\n\t\t\t\t\tif (marker !== null && marker === p.lastSeen) {\n\t\t\t\t\t\tp.lastError = null;\n\t\t\t\t\t\tcontinue; // unchanged since the last fold\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst remote = await p.source.load();\n\t\t\t\tif (!remote) {\n\t\t\t\t\t// The member has not published a copy yet: nothing to fold.\n\t\t\t\t\tp.lastError = null;\n\t\t\t\t\tp.lastSyncAt = Date.now();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (p.password !== undefined) {\n\t\t\t\t\t// This copy travels under its own key: a plaintext blob in its\n\t\t\t\t\t// place is a substitution, refused per-peer - even when the own\n\t\t\t\t\t// own file is unencrypted (the mirror model's normal shape).\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif ((await inspect(remote)).encryption === 'none') {\n\t\t\t\t\t\t\tp.lastError = storeError(\n\t\t\t\t\t\t\t\t'UNEXPECTEDLY_UNENCRYPTED',\n\t\t\t\t\t\t\t\t'Peer copy unexpectedly unencrypted - refused for safety.'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Unreadable header: the read below reports the real problem.\n\t\t\t\t\t}\n\t\t\t\t} else if (await isDowngraded(remote)) {\n\t\t\t\t\t// Same swap guard as the own target - we expect encrypted (or signed\n\t\t\t\t\t// group) copies and this is not one - scoped to this peer, no gate.\n\t\t\t\t\tp.lastError = storeError(\n\t\t\t\t\t\t'UNEXPECTEDLY_UNENCRYPTED',\n\t\t\t\t\t\tgroup\n\t\t\t\t\t\t\t? 'Peer copy is not a signed group copy - refused for safety.'\n\t\t\t\t\t\t\t: 'Peer copy unexpectedly unencrypted - refused for safety.'\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst {\n\t\t\t\t\tsnapshot,\n\t\t\t\t\tsidecar,\n\t\t\t\t\tauthor,\n\t\t\t\t\tenvelope: peerEnv\n\t\t\t\t} = await readBoxWithSync(\n\t\t\t\t\tawait asBytes(remote),\n\t\t\t\t\tp.password ?? pass ?? undefined,\n\t\t\t\t\tpeerGroupRead(),\n\t\t\t\t\tp.envelope?.dataKey // reuse the data key: skip the Argon2 KDF unless rotated\n\t\t\t\t);\n\t\t\t\t// Cache the (possibly refreshed) data key for the next fold. A rotation\n\t\t\t\t// makes the reused key fail above, so readBoxWithSync fell back to the\n\t\t\t\t// password and returns the new envelope here.\n\t\t\t\tif (peerEnv) p.envelope = peerEnv;\n\t\t\t\tconst { fromVersion, sync: peerMeta } = readBookkeeping(snapshot, sidecar);\n\t\t\t\tif (isNewerSchema(fromVersion)) {\n\t\t\t\t\t// That member runs a newer app. Skip their copy (we cannot read that\n\t\t\t\t\t// shape safely) without gating: we never write their copy, so there is\n\t\t\t\t\t// nothing we could clobber - unlike the own-target case.\n\t\t\t\t\tp.lastError = storeError(\n\t\t\t\t\t\t'SCHEMA_TOO_NEW',\n\t\t\t\t\t\t`Peer copy written by schema v${fromVersion}; this app reads v${version}.`\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!peerMeta) {\n\t\t\t\t\t// A copy with no sync metadata cannot merge (a pre-sync backup, not a\n\t\t\t\t\t// published copy): flag the link rather than guess at clobbering.\n\t\t\t\t\tp.lastError = storeError(\n\t\t\t\t\t\t'BAD_FORMAT',\n\t\t\t\t\t\t'Peer copy carries no sync metadata; not a published copy.'\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst snapM = migrated(snapshot, fromVersion);\n\t\t\t\tconst local = await gather();\n\t\t\t\t// Stamp first, as everywhere: an in-flight edit keeps its (latest) clock.\n\t\t\t\tmeta = stamp(meta, local.collections, sync);\n\t\t\t\tconst localState = { collections: local.collections, meta };\n\t\t\t\tconst remoteState = { collections: snapM.collections, meta: peerMeta };\n\t\t\t\tconst result = merge(localState, remoteState, sync);\n\t\t\t\tconst conflicts = detectConflicts(localState, remoteState, sync, baseMeta ?? undefined);\n\t\t\t\tconst delta = changes(local.collections, result.collections, sync);\n\t\t\t\tmeta = result.meta;\n\t\t\t\tbaseMeta = meta;\n\t\t\t\tkvSetSafe(KEY.baseMeta, meta, 'baseMeta');\n\t\t\t\tapply({ collections: result.collections, files: mergeFiles(local.files, snapM.files) });\n\t\t\t\tfolded = true;\n\t\t\t\tentry = recordJournal(delta, source, conflicts) ?? entry;\n\t\t\t\tp.lastError = null;\n\t\t\t\tp.lastSyncAt = Date.now();\n\t\t\t\tp.lastSeen = marker;\n\t\t\t\t// Group mode: surface WHO published this copy (verified, not claimed).\n\t\t\t\tp.author = author\n\t\t\t\t\t? (group?.manifest.members.find((m) => m.sig === author)?.id ?? null)\n\t\t\t\t\t: null;\n\t\t\t} catch (e) {\n\t\t\t\tp.lastError = isAuthExpired(e)\n\t\t\t\t\t? storeError('AUTH_EXPIRED', 'Read access to the peer copy expired or was revoked.')\n\t\t\t\t\t: isSelfstoreError(e)\n\t\t\t\t\t\t? storeError(e.code, e.message)\n\t\t\t\t\t\t: transient('Peer momentarily unreachable.');\n\t\t\t\tlogger.warn(`[selfstore] peer \"${p.id}\" fold failed`, e);\n\t\t\t}\n\t\t}\n\t\t// One persist for the whole round (each fold already applied in memory).\n\t\tif (folded) await persistLocal();\n\t\treturn entry;\n\t}\n\n\t/** Cheap staleness check across peers: true when any copy looks changed or\n\t * cannot tell cheaply. Never throws - a failing stat reads as \"go check\",\n\t * and the fold records the real error. */\n\tasync function anyPeerMoved(): Promise<boolean> {\n\t\tfor (const p of peerList) {\n\t\t\tif (!p.source.stat) return true;\n\t\t\ttry {\n\t\t\t\tconst marker = await p.source.stat();\n\t\t\t\tif (marker === null || marker !== p.lastSeen) return true;\n\t\t\t} catch {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/** Pull the durable copy and converge it with local (or adopt a foreign one),\n\t * fold the attached peers in, then push the result back so the remote\n\t * carries the merged state too (which is what lets peers gossip through us). */\n\tasync function doPull(source: SyncSource): Promise<SyncJournalEntry | null> {\n\t\tif (!durable && peerList.length === 0 && mirrorList.length === 0) return null;\n\t\tlet entry: SyncJournalEntry | null = null;\n\t\tif (durable) {\n\t\t\tconst r = await pullRemoteIntoLocal(source);\n\t\t\tif (r === 'locked') return null; // locked: skip peers and the push too, never clobber\n\t\t\tentry = r;\n\t\t}\n\t\tentry = (await foldPeers(source)) ?? entry;\n\t\tif (durable) await pushDurable(source);\n\t\t// Refresh the published copies when this converge moved data (a fold\n\t\t// from a peer must reach the mirror readers too), and on the connect\n\t\t// round so a freshly attached mirror exists right away.\n\t\tif (entry !== null || source === 'connect') {\n\t\t\tawait publishMirrors();\n\t\t\tawait publishReplicas();\n\t\t}\n\t\tnotify();\n\t\treturn entry;\n\t}\n\n\tconst pull = (source: SyncSource): Promise<SyncJournalEntry | null> =>\n\t\tserialize(() => doPull(source));\n\n\t/** Replace local data with the target's backup, then make the target match. */\n\tasync function loadFromRemote(): Promise<void> {\n\t\tif (!durable) return;\n\t\tconst remote = (await takeFreshPrefetch(durable)) ?? (await durable.load());\n\t\tif (remote) {\n\t\t\tconst decoded = await importLocked(remote);\n\t\t\tif (decoded === 'locked') return; // gate raised: never clobber either side\n\t\t\tconst { fromVersion } = readBookkeeping(decoded.snapshot, decoded.sidecar);\n\t\t\tif (isNewerSchema(fromVersion)) {\n\t\t\t\tgateNewerSchema(fromVersion);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tapply(migrated(decoded.snapshot, fromVersion));\n\t\t\tawait persistLocal();\n\t\t}\n\t\tawait pushDurable();\n\t}\n\n\t/** A backup with no sync metadata: valid per the spec (hand-authored or\n\t * written by another tool), but there is nothing to merge with. Adopt it on\n\t * a fresh device; when this device already holds data, keep local - the next\n\t * push overwrites the remote with a merge-capable copy. */\n\tasync function adoptForeign(snap: Snapshot): Promise<void> {\n\t\tconst local = await cache.load();\n\t\tif (local) return;\n\t\tapply(snap);\n\t\tawait persistLocal();\n\t}\n\n\tasync function becomePersistent(): Promise<void> {\n\t\tif (mode !== 'persistent') {\n\t\t\tmode = 'persistent';\n\t\t\tawait kv.set(KEY.mode, 'persistent');\n\t\t}\n\t\tawait cache.requestPersistent?.();\n\t}\n\n\t/** keepSession: drop the target object but leave its credentials/session\n\t * intact (a same-account backup switch must not kill the shared auth). */\n\tasync function dropDurable({\n\t\tkeepSession = false\n\t}: { keepSession?: boolean } = {}): Promise<void> {\n\t\tif (durable && !keepSession) await durable.disconnect();\n\t\tdurable = null;\n\t\tlabel = null;\n\t\tencrypted = false;\n\t\tneedsAttention = false;\n\t\tpendingDownload = false;\n\t\tsetPass(null);\n\t\tgroup = null; // the group config belongs to the departed target's attach\n\t\tawait kv.del(KEY.enc);\n\t\tawait setRemoteVersion(null); // the marker belongs to the departed target\n\t\t// The content fingerprint describes what reached the DEPARTED remote. Carried\n\t\t// into a new (or no) target it would wrongly skip the seed push to the new\n\t\t// destination - leaving it unwritten while the status reads \"saved\", then\n\t\t// resurrecting the old backup on the next converge - or suppress a local\n\t\t// persist of an edit-then-revert. Clear it with the marker, same reasoning.\n\t\tlastSavedContentHash = null;\n\t\tawait kv.del(KEY.savedHash);\n\t}\n\n\tasync function doForget(): Promise<void> {\n\t\t// Empty the in-memory state first, so the UI clears immediately (no reload)\n\t\t// and the snapshot we are about to persist/push is the empty one.\n\t\tapply({ collections: {}, files: [] });\n\n\t\tif (durable && !locked() && !needsAttention) {\n\t\t\t// A destination is connected: keep it attached and overwrite its backup\n\t\t\t// with the empty snapshot, so the data is gone here and on the target\n\t\t\t// while the connection (and its encryption/passphrase) is preserved.\n\t\t\t// Keep the existing meta (do not reset it): stamping the now-empty state\n\t\t\t// against it tombstones every record, so other devices drop them on the\n\t\t\t// next sync instead of re-propagating their copies back.\n\t\t\tawait persistLocal(); // stamp(meta, {}) -> tombstones; stamps lastSavedAt\n\t\t\tawait pushDurable(); // pushes empty data + the deletions to the target\n\t\t} else {\n\t\t\t// No destination (or it is locked/unreachable): nothing to propagate.\n\t\t\t// Forget everything on this device and reset to the cache-only default.\n\t\t\t// The group rollback high-water marks are SAFETY counters, not user data:\n\t\t\t// preserve every group's mark (not just the current one) across the wipe,\n\t\t\t// so a later re-join of any previously-seen group cannot be handed a\n\t\t\t// replayed older manifest (re-adding a removed member).\n\t\t\tconst seqIds = (await kv.get<string[]>(KEY.groupSeqIds)) ?? [];\n\t\t\tconst savedSeqs: [string, number][] = [];\n\t\t\tfor (const id of seqIds) {\n\t\t\t\tconst v = await kv.get<number>(groupSeqKey(id));\n\t\t\t\tif (v !== undefined) savedSeqs.push([id, v]);\n\t\t\t}\n\t\t\tmeta = createMeta();\n\t\t\tawait cache.clear();\n\t\t\tawait dropDurable();\n\t\t\tfor (const [id, v] of savedSeqs) await persistGroupSeq(id, v);\n\t\t\tmode = 'persistent';\n\t\t\ttargetKind = 'device';\n\t\t\tlastSavedAt = null;\n\t\t\tawait kv.set(KEY.mode, 'persistent');\n\t\t\tawait kv.set(KEY.targetKind, 'device');\n\t\t\tawait kv.set(KEY.syncMeta, meta);\n\t\t\tawait kv.del(KEY.lastSavedAt);\n\t\t\t// The wipe reset the merge history (no tombstones): other tabs must DROP\n\t\t\t// their in-memory copies rather than fold them back in.\n\t\t\tawait publishWrite('forget');\n\t\t}\n\t\tnotify();\n\t}\n\n\tfunction buildState(): LocalStoreState {\n\t\treturn {\n\t\t\tready,\n\t\t\tmode,\n\t\t\ttargetKind,\n\t\t\tlabel,\n\t\t\tencrypted,\n\t\t\tlocked: locked(),\n\t\t\tsaving,\n\t\t\tlastSavedAt,\n\t\t\tstatus: deriveStatus({\n\t\t\t\tpersistent: mode === 'persistent',\n\t\t\t\ttargetKind,\n\t\t\t\tsaving,\n\t\t\t\tneedsAttention,\n\t\t\t\tlocked: locked(),\n\t\t\t\tpendingDownload\n\t\t\t}),\n\t\t\tlastError,\n\t\t\tjournal,\n\t\t\tlastSync,\n\t\t\tpeers: peerList.map(({ id, label: l, lastSyncAt, author, lastError: err }) => ({\n\t\t\t\tid,\n\t\t\t\tlabel: l,\n\t\t\t\tlastSyncAt,\n\t\t\t\tauthor,\n\t\t\t\tlastError: err\n\t\t\t})),\n\t\t\tmirrors: mirrorList.map(({ id, label: l, lastPublishAt, lastError: err }) => ({\n\t\t\t\tid,\n\t\t\t\tlabel: l,\n\t\t\t\tlastPublishAt,\n\t\t\t\tlastError: err\n\t\t\t})),\n\t\t\treplicas: replicaList.map(({ id, label: l, lastPublishAt, lastError: err }) => ({\n\t\t\t\tid,\n\t\t\t\tlabel: l,\n\t\t\t\tlastPublishAt,\n\t\t\t\tlastError: err\n\t\t\t}))\n\t\t};\n\t}\n\tstateSnapshot = buildState();\n\n\treturn {\n\t\tget state(): LocalStoreState {\n\t\t\treturn stateSnapshot;\n\t\t},\n\n\t\tsubscribe(fn) {\n\t\t\tsubs.add(fn);\n\t\t\treturn () => subs.delete(fn);\n\t\t},\n\n\t\tasync init() {\n\t\t\tmode = (await kv.get(KEY.mode)) === 'ephemeral' ? 'ephemeral' : 'persistent';\n\t\t\tif (mode === 'ephemeral') {\n\t\t\t\tready = true;\n\t\t\t\tnotify();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Persistent from the start: ask the browser not to evict the cache even\n\t\t\t// before any durable home is attached (best-effort, never blocks boot).\n\t\t\tvoid Promise.resolve(cache.requestPersistent?.()).catch(() => undefined);\n\n\t\t\tconst local = await cache.load();\n\t\t\tif (local) {\n\t\t\t\tconst snap = await cachedToSnapshot(local);\n\t\t\t\tconst storedV = (await kv.get<number>(KEY.version)) ?? version;\n\t\t\t\t// A cache written by a newer schema (the app was downgraded) still\n\t\t\t\t// hydrates - the data is the user's - but the gate blocks pushes so the\n\t\t\t\t// older app can never clobber the newer shape elsewhere.\n\t\t\t\tif (isNewerSchema(storedV)) gateNewerSchema(storedV);\n\t\t\t\tapply(migrated(snap, storedV));\n\t\t\t}\n\n\t\t\tlastSavedAt = (await kv.get<number>(KEY.lastSavedAt)) ?? null;\n\t\t\t// The fingerprint of what we last pushed: a passive save that matches it\n\t\t\t// (a reactive touch after boot, no real edit) is a no-op, but a local\n\t\t\t// edit that never reached the remote hashes differently and still saves.\n\t\t\tlastSavedContentHash = (await kv.get<string>(KEY.savedHash)) ?? null;\n\t\t\tmeta = (await kv.get<SyncMeta>(KEY.syncMeta)) ?? createMeta();\n\t\t\tawait kv.set(KEY.syncMeta, meta);\n\t\t\tbaseMeta = (await kv.get<SyncMeta>(KEY.baseMeta)) ?? null;\n\t\t\tremoteVersion = (await kv.get<string>(KEY.remoteVersion)) ?? null;\n\t\t\tjournal = (await kv.get<SyncJournalEntry[]>(KEY.syncJournal)) ?? [];\n\t\t\t// Everything above reflects the cache as of now: later folds only need to\n\t\t\t// absorb writes that land after this point.\n\t\t\tseenEpoch = await kv.get<string>(KEY.epoch);\n\n\t\t\tconst savedKind = (await kv.get<TargetKind>(KEY.targetKind)) ?? 'device';\n\t\t\tif (!isReservedStoreMode(savedKind)) {\n\t\t\t\tencrypted = (await kv.get(KEY.enc)) === true;\n\t\t\t\t// Show the destination we are RESTORING right away: during the (often\n\t\t\t\t// slow) reconnect handshake the profile reads \"Google Drive\"\n\t\t\t\t// (connecting), not \"this device\". A failed restore resets it to\n\t\t\t\t// 'device' in the else-branch below; durable stays null until it lands,\n\t\t\t\t// and schedule() is inert until ready, so no save fires meanwhile.\n\t\t\t\ttargetKind = savedKind;\n\t\t\t\tnotify();\n\t\t\t\t// restoreTarget is app code (rebuilding a Drive/WebDAV session): a\n\t\t\t\t// transient throw must not brick boot. On throw, keep the saved kind so\n\t\t\t\t// a later reconnect retries - never demote to 'device' the way a\n\t\t\t\t// deliberate null return (no session to restore) does.\n\t\t\t\tlet t: BackupTarget | null = null;\n\t\t\t\tlet restoreThrew = false;\n\t\t\t\ttry {\n\t\t\t\t\tt = opts.restoreTarget\n\t\t\t\t\t\t? await bootDeadline(\n\t\t\t\t\t\t\t\tPromise.resolve(opts.restoreTarget(savedKind)),\n\t\t\t\t\t\t\t\t'destination restore'\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: null;\n\t\t\t\t} catch (e) {\n\t\t\t\t\trestoreThrew = true;\n\t\t\t\t\tlastError = transient('Could not restore the destination; will retry.');\n\t\t\t\t\tlogger.error('[selfstore] restoreTarget failed', e);\n\t\t\t\t}\n\t\t\t\tif (t) {\n\t\t\t\t\tdurable = t;\n\t\t\t\t\ttargetKind = savedKind;\n\t\t\t\t\tlabel = t.label;\n\t\t\t\t\t// isReady() rethrows a genuine auth loss (open the gate) and returns\n\t\t\t\t\t// false only for a transient hiccup (stay connected, retry later) - so\n\t\t\t\t\t// booting during a broker cold-start no longer pops a spurious\n\t\t\t\t\t// reconnect. A BOOT TIMEOUT is a stall, not an auth verdict: stay\n\t\t\t\t\t// connected, skip the boot pull, let the next sync retry.\n\t\t\t\t\tlet ok = false;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tok = await bootDeadline(t.isReady(), 'destination check');\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tif (e instanceof BootTimeout) {\n\t\t\t\t\t\t\tlastError = transient('Destination is slow to answer; will retry.');\n\t\t\t\t\t\t\tlogger.error('[selfstore] boot destination check stalled', e);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\traiseGate('AUTH_EXPIRED', 'Access to the destination expired or was revoked.');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tneedsAttention = needsAttention || locked();\n\t\t\t\t\tif (ok && !locked()) {\n\t\t\t\t\t\t// Boot must never crash OR HANG the app on a bad remote: log, gate\n\t\t\t\t\t\t// nothing, keep the local copy and let a later sync retry.\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait bootDeadline(pull('boot'), 'boot sync');\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\tlastError = transient('Boot sync failed; will retry.');\n\t\t\t\t\t\t\tlogger.error('[selfstore] boot sync failed', e);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (!restoreThrew) {\n\t\t\t\t\t// A deliberate null (no session to restore): fall back to cache-only.\n\t\t\t\t\ttargetKind = 'device';\n\t\t\t\t\tawait kv.set(KEY.targetKind, 'device');\n\t\t\t\t}\n\t\t\t\t// else: restore threw transiently - keep savedKind + durable null, so\n\t\t\t\t// the profile still reads the destination and a reconnect can retry.\n\t\t\t} else if (savedKind === 'file-manual') {\n\t\t\t\ttargetKind = 'file-manual';\n\t\t\t\tpendingDownload = false;\n\t\t\t}\n\t\t\t// Peers attached before init() with no durable home (a read-only\n\t\t\t// follower): fold them now - with a durable target the boot pull above\n\t\t\t// already did. Same crash rule as boot: log, never block, never hang.\n\t\t\tif (!durable && peerList.length > 0) {\n\t\t\t\ttry {\n\t\t\t\t\tawait bootDeadline(pull('boot'), 'boot sync');\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlastError = transient('Boot sync failed; will retry.');\n\t\t\t\t\tlogger.error('[selfstore] boot sync failed', e);\n\t\t\t\t}\n\t\t\t}\n\t\t\tready = true;\n\t\t\tnotify();\n\t\t},\n\n\t\tschedule() {\n\t\t\t// Passive auto-save is armed only once init() hydrated the app: before\n\t\t\t// that, gather() would snapshot emptiness over the cache (e.g. a stray\n\t\t\t// track on a viewer page that never initializes persistence).\n\t\t\tif (!ready) return;\n\t\t\tpendingEdit = true; // a cross-tab refresh must save this, not adopt over it\n\t\t\teditSeq++; // an edit landing mid-persist must keep pendingEdit (see doSave)\n\t\t\tclearTimeout(timer);\n\t\t\t// A background save failure (quota, cache write) must never surface as an\n\t\t\t// unhandled rejection from a debounce timer: log it and let the next\n\t\t\t// scheduled save retry.\n\t\t\ttimer = setTimeout(\n\t\t\t\t() => save().catch((e) => logger.error('[selfstore] scheduled save failed', e)),\n\t\t\t\tdebounceMs\n\t\t\t);\n\t\t\tarmIdleLock(); // user activity resets the auto-lock countdown\n\t\t},\n\n\t\tlock: lockNow,\n\n\t\tasync flush() {\n\t\t\tif (!ready) return; // same pre-init guard as schedule()\n\t\t\tclearTimeout(timer);\n\t\t\tif (mode === 'persistent') await save();\n\t\t},\n\n\t\tsyncIfStale(source) {\n\t\t\treturn serialize(async () => {\n\t\t\t\tif (locked() || needsAttention || mode !== 'persistent') return;\n\t\t\t\tif (!durable?.stat && peerList.length === 0) return;\n\t\t\t\tconst nowMs = Date.now();\n\t\t\t\tif (nowMs - lastStaleCheck < STALE_CHECK_MS) return;\n\t\t\t\tlastStaleCheck = nowMs;\n\t\t\t\tlet moved = false;\n\t\t\t\tif (durable?.stat) {\n\t\t\t\t\tconst seen = await statRemote();\n\t\t\t\t\tmoved = seen !== null && seen !== remoteVersion;\n\t\t\t\t}\n\t\t\t\tif (!moved) moved = await anyPeerMoved();\n\t\t\t\tif (!moved) return;\n\t\t\t\t// A background staleness check must never surface as an unhandled\n\t\t\t\t// rejection on a focus event: log and let the next check retry.\n\t\t\t\ttry {\n\t\t\t\t\tawait doPull(source);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tlastError = transient('Background sync failed; will retry.');\n\t\t\t\t\tlogger.error('[selfstore] background sync failed', e);\n\t\t\t\t\tnotify();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tsyncNow() {\n\t\t\treturn serialize(() => {\n\t\t\t\tlastStaleCheck = Date.now();\n\t\t\t\treturn doPull('manual');\n\t\t\t});\n\t\t},\n\n\t\tattachTarget(target, attachOpts) {\n\t\t\tif (isReservedStoreMode(target.kind)) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`attachTarget(): kind \"${target.kind}\" is a reserved store mode, not a target kind - pick any other string`\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst cfg = attachOpts?.group ?? null;\n\t\t\tif (cfg && attachOpts?.password) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'attachTarget(): `group` and `password` are mutually exclusive - a group is keyed by member identities.'\n\t\t\t\t);\n\t\t\t}\n\t\t\t// A require-encryption store has no plaintext home: reject the attach up\n\t\t\t// front rather than let a passwordless target through to a cleartext save.\n\t\t\tif (requireEncryption && !attachOpts?.password && !cfg) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'ENCRYPTION_REQUIRED',\n\t\t\t\t\t'attachTarget(): this store requires encryption - attach with a password or a group.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (attachOpts?.password) assertPasswordPolicy(attachOpts.password);\n\t\t\t// Serialized with the save/pull chain: an in-flight converge of the\n\t\t\t// departing target finishes first, so it can neither resurrect that\n\t\t\t// backup's data over a wipe nor leak it into the new home.\n\t\t\treturn serialize(async () => {\n\t\t\t\t// Verify the signed manifest first, against the admin key the app\n\t\t\t\t// pinned at join: the store is the verification gate, so a forged\n\t\t\t\t// membership rejects (SIGNATURE_INVALID) before anything changes.\n\t\t\t\tconst g: ActiveGroup | null = cfg\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tidentity: cfg.identity,\n\t\t\t\t\t\t\tadmin: cfg.admin,\n\t\t\t\t\t\t\tmanifest: await openManifest(cfg.manifest, cfg.admin)\n\t\t\t\t\t\t}\n\t\t\t\t\t: null;\n\t\t\t\tif (g && !g.manifest.members.some((m) => m.sig === g.identity.sigPub)) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t'attachTarget(): this identity is not a member of the manifest - the admin must add it first.'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tawait becomePersistent();\n\t\t\t\tconst strategy = attachOpts?.strategy ?? 'merge';\n\t\t\t\t// Flush pending edits to the departing target before we let go of it, but\n\t\t\t\t// only when the incoming strategy REPLACES local (switching isolated silos\n\t\t\t\t// via loadBackup): local is about to be overwritten, so an unsynced edit on\n\t\t\t\t// the file we leave would be lost unless we save it there first. 'merge'\n\t\t\t\t// keeps local (nothing stranded) and 'replace-remote' carries local into\n\t\t\t\t// the new home, so neither needs this - and a blind flush on 'merge' could\n\t\t\t\t// even resurrect a record another replica deleted. Best-effort: offline\n\t\t\t\t// keeps the edit in the local cache.\n\t\t\t\tif (strategy === 'replace-local' && durable && !locked() && !needsAttention) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait persistLocal();\n\t\t\t\t\t\tawait pushDurable('push');\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* offline or unreachable: the local cache keeps the edit */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Manifest seq must never move backwards, even across sessions: a\n\t\t\t\t// replayed old manifest would silently re-add a removed member.\n\t\t\t\tif (g) {\n\t\t\t\t\tconst stored = await kv.get<number>(groupSeqKey(g.manifest.group));\n\t\t\t\t\tif (stored !== undefined && g.manifest.seq < stored) {\n\t\t\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t\t\t'MANIFEST_ROLLBACK',\n\t\t\t\t\t\t\t`Manifest seq ${g.manifest.seq} is older than the last applied (${stored}).`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tawait persistGroupSeq(g.manifest.group, Math.max(stored ?? 0, g.manifest.seq));\n\t\t\t\t}\n\t\t\t\tawait dropDurable({ keepSession: attachOpts?.keepSession });\n\t\t\t\tif (attachOpts?.wipe) {\n\t\t\t\t\t// A brand-new home starts blank: empty data and fresh sync meta (no\n\t\t\t\t\t// clocks or tombstones carried over from the previous backup).\n\t\t\t\t\tapply({ collections: {}, files: [] });\n\t\t\t\t\tmeta = createMeta();\n\t\t\t\t\tbaseMeta = null;\n\t\t\t\t\tawait kv.set(KEY.syncMeta, meta);\n\t\t\t\t\tawait kv.del(KEY.baseMeta);\n\t\t\t\t}\n\t\t\t\tdurable = target;\n\t\t\t\ttargetKind = target.kind;\n\t\t\t\tlabel = target.label;\n\t\t\t\tconst next = attachOpts?.password ?? null;\n\t\t\t\tgroup = g;\n\t\t\t\tencrypted = !!next || !!g;\n\t\t\t\tsetPass(next);\n\t\t\t\t// A new home means new key material: never carry the previous file's\n\t\t\t\t// envelope over (the legs below recapture it from the real file).\n\t\t\t\tenvelope = null;\n\t\t\t\tawait kv.set(KEY.enc, encrypted);\n\t\t\t\tawait kv.set(KEY.targetKind, target.kind);\n\t\t\t\tneedsAttention = false;\n\t\t\t\tnotify();\n\t\t\t\tif (strategy === 'replace-local') await loadFromRemote();\n\t\t\t\telse if (strategy === 'replace-remote') await doSave();\n\t\t\t\telse await doPull('connect');\n\t\t\t\tnotify();\n\t\t\t});\n\t\t},\n\n\t\tasync inspectTarget(target) {\n\t\t\t// A read that fails is not a destination that is empty. Swallowing the\n\t\t\t// difference let a transient failure (offline, a cold start, an expired\n\t\t\t// token) read as \"no backup\", and the connect that followed could\n\t\t\t// overwrite a perfectly good one. Failures and unreadable files\n\t\t\t// propagate, typed, for the caller to surface; only a genuine\n\t\t\t// \"nothing there\" (a null blob) reads as empty.\n\t\t\tconst blob = await target.load();\n\t\t\t// A missing file and an empty file both read as \"nothing there\": a\n\t\t\t// just-created destination file has zero bytes (Drive's create writes\n\t\t\t// metadata + empty content), and zero bytes cannot be data anyone\n\t\t\t// could lose. Only a NON-empty file that fails to parse propagates -\n\t\t\t// that one may be someone's backup.\n\t\t\tif (!blob || blob.size === 0) return { hasBackup: false, date: null, encrypted: false };\n\t\t\t// Remember this download (with the remote's current marker) so the attach\n\t\t\t// that typically follows reuses it instead of fetching the same file again.\n\t\t\t// A Blob is re-readable, so inspecting it here does not spend it.\n\t\t\tlet marker: string | null;\n\t\t\ttry {\n\t\t\t\tmarker = target.stat ? await target.stat() : null;\n\t\t\t} catch {\n\t\t\t\tmarker = null;\n\t\t\t}\n\t\t\tprefetched = { target, blob, marker, at: Date.now() };\n\t\t\tconst header = await inspect(blob);\n\t\t\treturn {\n\t\t\t\thasBackup: true,\n\t\t\t\tdate: header.createdAt ?? null,\n\t\t\t\tencrypted: header.encryption !== 'none'\n\t\t\t};\n\t\t},\n\n\t\tsetManualFile() {\n\t\t\t// Serialized with the save/pull chain: dropping the durable target and\n\t\t\t// re-persisting must not interleave with an in-flight debounced save or a\n\t\t\t// focus-pull (which could push to, or converge from, the target we are\n\t\t\t// detaching mid-operation).\n\t\t\treturn serialize(async () => {\n\t\t\t\tawait becomePersistent();\n\t\t\t\tawait dropDurable();\n\t\t\t\ttargetKind = 'file-manual';\n\t\t\t\tpendingDownload = false;\n\t\t\t\tawait kv.set(KEY.targetKind, 'file-manual');\n\t\t\t\tawait persistLocal();\n\t\t\t\tnotify();\n\t\t\t});\n\t\t},\n\n\t\tasync unlock(password) {\n\t\t\tif (!locked() || !password) return false;\n\t\t\tsetPass(password);\n\t\t\t// Clear only the LOCK, not a SCHEMA_TOO_NEW ceiling gate we do not own: a\n\t\t\t// downgraded app that hydrated newer-shape data must stay gated, or its\n\t\t\t// pull-then-push would upload old-shaped records stamped with the newer\n\t\t\t// version and corrupt other devices.\n\t\t\tneedsAttention = schemaCeiling > version;\n\t\t\tawait pull('manual'); // doPull notifies; a wrong password re-raises the gate\n\t\t\treturn !needsAttention;\n\t\t},\n\n\t\tasync reconnect() {\n\t\t\tif (locked() || !durable) return false; // a lock needs unlock(), not reconnect()\n\t\t\tif (await durable.reconnect()) {\n\t\t\t\tneedsAttention = schemaCeiling > version; // keep the schema ceiling gate (see unlock)\n\t\t\t\tif (!needsAttention) lastError = null;\n\t\t\t\tawait pull('manual');\n\t\t\t\treturn !needsAttention;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\n\t\tdetachTarget(opts) {\n\t\t\t// The user is walking away NOW: cut the target's in-flight requests\n\t\t\t// first, or a suspended pull/save (a waking mobile radio at boot) would\n\t\t\t// hold the serialize chain - and this very detach - hostage until its\n\t\t\t// network deadline. The cut rejects those requests as transient; the\n\t\t\t// chain then reaches the drop below immediately.\n\t\t\tdurable?.abortInFlight?.();\n\t\t\t// Serialized like setManualFile: a concurrent save/pull must not run\n\t\t\t// against a target that is being dropped out from under it.\n\t\t\treturn serialize(async () => {\n\t\t\t\tawait dropDurable({ keepSession: opts?.keepSession });\n\t\t\t\ttargetKind = 'device';\n\t\t\t\tawait kv.set(KEY.targetKind, 'device');\n\t\t\t\tnotify();\n\t\t\t});\n\t\t},\n\n\t\tsetGroup(next) {\n\t\t\tif (!group) {\n\t\t\t\tthrow new TypeError('setGroup(): no group attached - attachTarget with { group } first.');\n\t\t\t}\n\t\t\treturn serialize(async () => {\n\t\t\t\t// Verified against the admin key and group id pinned at attach: a\n\t\t\t\t// swapped admin (rotation is not a plain setGroup) or a foreign\n\t\t\t\t// group's manifest fails right here, whoever signed it. The store\n\t\t\t\t// is the verification gate, not the app.\n\t\t\t\tconst manifest = await openManifest(next, group!.admin, group!.manifest.group);\n\t\t\t\tconst key = groupSeqKey(manifest.group);\n\t\t\t\tconst stored = (await kv.get<number>(key)) ?? 0;\n\t\t\t\tconst floor = Math.max(stored, group!.manifest.seq);\n\t\t\t\tif (manifest.seq < floor) {\n\t\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t\t'MANIFEST_ROLLBACK',\n\t\t\t\t\t\t`Manifest seq ${manifest.seq} is older than the last applied (${floor}).`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// Monotonic write: never lower the persisted high-water mark, even if a\n\t\t\t\t// concurrent (Web-Lock-less) tab read an older value first.\n\t\t\t\tawait persistGroupSeq(manifest.group, Math.max(stored, manifest.seq));\n\t\t\t\tgroup = { ...group!, manifest };\n\t\t\t\tnotify();\n\t\t\t\t// Republish under the new member list NOW: this is the moment a\n\t\t\t\t// removal stops enveloping the removed member. The membership change\n\t\t\t\t// alters the output bytes (recipients/envelopes) but not the content\n\t\t\t\t// digest, so the idempotent-save guard would wrongly skip it - drop\n\t\t\t\t// the fingerprint to force a real re-encode and upload.\n\t\t\t\tlastSavedContentHash = null;\n\t\t\t\tawait doSave();\n\t\t\t});\n\t\t},\n\n\t\tattachPeer(source, peerOpts) {\n\t\t\tconst id = peerOpts?.id ?? createNode();\n\t\t\tif (peerList.some((p) => p.id === id)) {\n\t\t\t\tthrow new TypeError(`attachPeer(): a peer with id \"${id}\" is already attached`);\n\t\t\t}\n\t\t\tpeerList.push({\n\t\t\t\tid,\n\t\t\t\tsource,\n\t\t\t\tpassword: peerOpts?.password,\n\t\t\t\tlabel: source.label ?? id,\n\t\t\t\tlastSyncAt: null,\n\t\t\t\tauthor: null,\n\t\t\t\tlastError: null,\n\t\t\t\tlastSeen: null,\n\t\t\t\tenvelope: null\n\t\t\t});\n\t\t\tnotify();\n\t\t\t// Fold the new peer promptly (serialized with saves and pulls). Before\n\t\t\t// init() this just registers - the boot converge picks the peer up.\n\t\t\tif (ready) {\n\t\t\t\tvoid serialize(() => doPull('connect')).catch((e) =>\n\t\t\t\t\tlogger.error('[selfstore] peer converge failed', e)\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn id;\n\t\t},\n\n\t\tdetachPeer(id) {\n\t\t\tconst i = peerList.findIndex((p) => p.id === id);\n\t\t\tif (i >= 0) {\n\t\t\t\tpeerList.splice(i, 1);\n\t\t\t\tnotify();\n\t\t\t}\n\t\t},\n\n\t\tattachMirror(target, mirrorOpts) {\n\t\t\tconst id = mirrorOpts.id ?? createNode();\n\t\t\tif (mirrorList.some((m) => m.id === id)) {\n\t\t\t\tthrow new TypeError(`attachMirror(): a mirror with id \"${id}\" is already attached`);\n\t\t\t}\n\t\t\tmirrorList.push({\n\t\t\t\tid,\n\t\t\t\ttarget,\n\t\t\t\tpassword: mirrorOpts.password,\n\t\t\t\tenvelope: null,\n\t\t\t\tlabel: target.label ?? id,\n\t\t\t\tlastPublishAt: null,\n\t\t\t\tlastError: null\n\t\t\t});\n\t\t\tnotify();\n\t\t\t// Publish promptly so the copy exists as soon as the mirror is wired\n\t\t\t// (serialized with saves and pulls). Before init() this just registers.\n\t\t\tif (ready) {\n\t\t\t\tvoid serialize(publishMirrors).catch((e) =>\n\t\t\t\t\tlogger.error('[selfstore] mirror publish failed', e)\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn id;\n\t\t},\n\n\t\tdetachMirror(id) {\n\t\t\tconst i = mirrorList.findIndex((m) => m.id === id);\n\t\t\tif (i >= 0) {\n\t\t\t\tmirrorList.splice(i, 1);\n\t\t\t\tnotify();\n\t\t\t}\n\t\t},\n\n\t\tattachReplica(target, replicaOpts) {\n\t\t\tconst id = replicaOpts?.id ?? createNode();\n\t\t\tif (replicaList.some((r) => r.id === id)) {\n\t\t\t\tthrow new TypeError(`attachReplica(): a replica with id \"${id}\" is already attached`);\n\t\t\t}\n\t\t\treplicaList.push({\n\t\t\t\tid,\n\t\t\t\ttarget,\n\t\t\t\tlabel: target.label ?? id,\n\t\t\t\tlastPublishAt: null,\n\t\t\t\tlastError: null\n\t\t\t});\n\t\t\tnotify();\n\t\t\t// Publish promptly so the copy exists as soon as the replica is wired\n\t\t\t// (serialized with saves and pulls). Before init() this just registers.\n\t\t\tif (ready) {\n\t\t\t\tvoid serialize(publishReplicas).catch((e) =>\n\t\t\t\t\tlogger.error('[selfstore] replica publish failed', e)\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn id;\n\t\t},\n\n\t\tdetachReplica(id) {\n\t\t\tconst i = replicaList.findIndex((r) => r.id === id);\n\t\t\tif (i >= 0) {\n\t\t\t\treplicaList.splice(i, 1);\n\t\t\t\tnotify();\n\t\t\t}\n\t\t},\n\n\t\texportBlob() {\n\t\t\treturn buildBlob();\n\t\t},\n\n\t\tmarkDownloaded() {\n\t\t\tpendingDownload = false;\n\t\t\t// A download IS the save on a browser that cannot hold a file: recording\n\t\t\t// when it happened is what lets a host say \"saved 2 hours ago\" instead of\n\t\t\t// a bare state word. Without it, every host had to keep its own memo of\n\t\t\t// the last export - and one of them found out the hard way that a memo\n\t\t\t// living in memory tells the practitioner, the next morning, that he has\n\t\t\t// never saved anything.\n\t\t\tlastSavedAt = Date.now();\n\t\t\tvoid kv.set(KEY.lastSavedAt, lastSavedAt).catch(() => undefined);\n\t\t\tnotify();\n\t\t},\n\n\t\tsetEphemeral() {\n\t\t\tmode = 'ephemeral';\n\t\t\tkvSetSafe(KEY.mode, 'ephemeral', 'mode');\n\t\t\tnotify();\n\t\t},\n\n\t\tasync leaveEphemeral() {\n\t\t\tawait becomePersistent();\n\t\t\tawait save();\n\t\t},\n\n\t\tforget() {\n\t\t\treturn serialize(doForget);\n\t\t},\n\n\t\tasync setEncryption(password) {\n\t\t\t// Reversible: add/change a password (non-empty string) or remove it (null),\n\t\t\t// after connecting. Rewrites the local cache and the remote backup with the\n\t\t\t// new setting - and COMMITS the flag only once the remote rewrite has\n\t\t\t// verifiably landed. The old order (flag first, best-effort save after)\n\t\t\t// let a deferred or failed write pass for success: the store then\n\t\t\t// expected one setting while the file kept the other, which surfaced as\n\t\t\t// \"asks a password that never works\" or an unresolvable reconnect gate.\n\t\t\t// The same reasoning turns the silent preconditions into loud errors: a\n\t\t\t// caller must never mistake a no-op for a rewrite.\n\t\t\tif (group) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'setEncryption(): the store is in group mode - encryption is keyed by the membership manifest (setGroup), not a password.'\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Removing the password would leave a plaintext backup, which this store\n\t\t\t// forbids; changing it (non-empty) is still allowed.\n\t\t\tif (requireEncryption && !password) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'ENCRYPTION_REQUIRED',\n\t\t\t\t\t'setEncryption(): this store requires encryption - the password cannot be removed.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (password) assertPasswordPolicy(password);\n\t\t\tif (!durable) {\n\t\t\t\tthrow new SelfstoreError('NOT_CONNECTED', 'setEncryption(): no destination is connected.');\n\t\t\t}\n\t\t\tif (locked() || needsAttention) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t'setEncryption(): the store needs attention; resolve it before changing encryption.'\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn serialize(async () => {\n\t\t\t\t// Converge first, under the current setting: another replica may have\n\t\t\t\t// written since our last sync, and its blob opens with the old key. A\n\t\t\t\t// blind re-encrypting push would clobber that write.\n\t\t\t\tawait requireReady('setEncryption');\n\t\t\t\tconst seen = await statRemote();\n\t\t\t\tif (seen !== null && remoteVersion !== null && seen !== remoteVersion) {\n\t\t\t\t\tawait pullRemoteIntoLocal('push', seen);\n\t\t\t\t\tif (locked() || needsAttention) {\n\t\t\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t\t\t'setEncryption(): the pre-rewrite converge needs attention; resolve it first.'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst prevEncrypted = encrypted;\n\t\t\t\tconst prevPass = pass;\n\t\t\t\tconst prevEnvelope = envelope;\n\t\t\t\tencrypted = !!password;\n\t\t\t\tsetPass(password || null);\n\t\t\t\t// Setting a password is a data-key ROTATION: drop the old envelope so\n\t\t\t\t// buildBlob mints a fresh key with a single slot. Every previously\n\t\t\t\t// authorized password (a share key, an old password) stops opening\n\t\t\t\t// the new bytes - that is the point.\n\t\t\t\tenvelope = null;\n\t\t\t\ttry {\n\t\t\t\t\tawait persistLocal();\n\t\t\t\t\tpendingEdit = false;\n\t\t\t\t\tconst written = await durable!.save(await buildBlob());\n\t\t\t\t\tawait setRemoteVersion(typeof written === 'string' ? written : await statRemote());\n\t\t\t\t\tlastError = null;\n\t\t\t\t\tawait kv.set(KEY.enc, encrypted); // the flag follows the write, never precedes it\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// Roll the setting back everywhere the write did not reach: the\n\t\t\t\t\t// caller gets the failure, and the store still matches the file.\n\t\t\t\t\tencrypted = prevEncrypted;\n\t\t\t\t\tsetPass(prevPass);\n\t\t\t\t\tenvelope = prevEnvelope;\n\t\t\t\t\tawait persistLocal().catch(() => undefined);\n\t\t\t\t\tif (isAuthExpired(e)) {\n\t\t\t\t\t\traiseGate('AUTH_EXPIRED', 'Access to the destination expired or was revoked.');\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t} finally {\n\t\t\t\t\tnotify();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tasync addEncryptionKey(password, id) {\n\t\t\tif (group) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'addEncryptionKey(): the store is in group mode - keys come from the membership manifest (setGroup), not passwords.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!password) {\n\t\t\t\tthrow new TypeError('addEncryptionKey(): a non-empty password is required.');\n\t\t\t}\n\t\t\tassertPasswordPolicy(password);\n\t\t\tif (!durable) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'NOT_CONNECTED',\n\t\t\t\t\t'addEncryptionKey(): no destination is connected.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (locked() || needsAttention) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t'addEncryptionKey(): the store needs attention; resolve it before changing keys.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!encrypted || !pass) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'addEncryptionKey(): the backup has no password yet - setEncryption(password) first.'\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn serialize(async () => {\n\t\t\t\tawait requireReady('addEncryptionKey');\n\t\t\t\tconst seen = await statRemote();\n\t\t\t\tif (seen !== null && remoteVersion !== null && seen !== remoteVersion) {\n\t\t\t\t\tawait pullRemoteIntoLocal('push', seen);\n\t\t\t\t\tif (locked() || needsAttention) {\n\t\t\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t\t\t'addEncryptionKey(): the pre-rewrite converge needs attention; resolve it first.'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// A pre-envelope file mints its own-password slot now; the new slot\n\t\t\t\t// joins it. Same data key: nothing is re-encrypted, every existing\n\t\t\t\t// password keeps opening the file - that is the whole point.\n\t\t\t\tif (!envelope) {\n\t\t\t\t\tconst dataKey = crypto.getRandomValues(new Uint8Array(32));\n\t\t\t\t\tenvelope = { dataKey, slots: [await mintSlot(pass!, dataKey)] };\n\t\t\t\t}\n\t\t\t\tif (envelope.slots.length >= MAX_KEY_SLOTS) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`addEncryptionKey(): this backup already has ${MAX_KEY_SLOTS} key slots.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (id && envelope.slots.some((s) => s.id === id)) {\n\t\t\t\t\tthrow new TypeError(`addEncryptionKey(): a key slot named \"${id}\" already exists.`);\n\t\t\t\t}\n\t\t\t\tconst prevEnvelope = envelope;\n\t\t\t\tconst slot = await mintSlot(password, envelope.dataKey, id);\n\t\t\t\tenvelope = { dataKey: envelope.dataKey, slots: [...envelope.slots, slot] };\n\t\t\t\ttry {\n\t\t\t\t\tconst blob = await buildBlob();\n\t\t\t\t\t// Write-verified the strong way: the new password must open the very\n\t\t\t\t\t// bytes about to land, before they land.\n\t\t\t\t\tawait readBoxWithSync(await asBytes(blob), password);\n\t\t\t\t\tconst written = await durable!.save(blob);\n\t\t\t\t\tawait setRemoteVersion(typeof written === 'string' ? written : await statRemote());\n\t\t\t\t\tlastError = null;\n\t\t\t\t\treturn slot.id;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tenvelope = prevEnvelope;\n\t\t\t\t\tif (isAuthExpired(e)) {\n\t\t\t\t\t\traiseGate('AUTH_EXPIRED', 'Access to the destination expired or was revoked.');\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t} finally {\n\t\t\t\t\tnotify();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tasync removeEncryptionKey(id) {\n\t\t\tif (group) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'removeEncryptionKey(): the store is in group mode - keys come from the membership manifest (setGroup), not passwords.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!durable) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'NOT_CONNECTED',\n\t\t\t\t\t'removeEncryptionKey(): no destination is connected.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (locked() || needsAttention) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t'removeEncryptionKey(): the store needs attention; resolve it before changing keys.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!encrypted || !pass) {\n\t\t\t\tthrow new TypeError('removeEncryptionKey(): the backup has no password.');\n\t\t\t}\n\t\t\treturn serialize(async () => {\n\t\t\t\tawait requireReady('removeEncryptionKey');\n\t\t\t\tconst seen = await statRemote();\n\t\t\t\tif (seen !== null && remoteVersion !== null && seen !== remoteVersion) {\n\t\t\t\t\tawait pullRemoteIntoLocal('push', seen);\n\t\t\t\t\tif (locked() || needsAttention) {\n\t\t\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t\t\t'removeEncryptionKey(): the pre-rewrite converge needs attention; resolve it first.'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!envelope) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t'removeEncryptionKey(): no key slots known - the file predates the envelope or has not been read yet.'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst remaining = envelope.slots.filter((s) => s.id !== id);\n\t\t\t\tif (remaining.length === envelope.slots.length) {\n\t\t\t\t\tthrow new TypeError(`removeEncryptionKey(): no key slot named \"${id}\".`);\n\t\t\t\t}\n\t\t\t\tif (remaining.length === 0) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t'removeEncryptionKey(): cannot remove the last key - setEncryption(null) decrypts instead.'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// Lock-out guard: after the removal at least one remaining slot must\n\t\t\t\t// still open, or the very next reload would be unrecoverable. An\n\t\t\t\t// external-key slot (a passkey) counts - the app owns that key, so it\n\t\t\t\t// keeps a way in; otherwise this session's own password must open a\n\t\t\t\t// remaining PASSWORD slot.\n\t\t\t\tlet stillOpens = remaining.some((s) => (s as ExternalSlot).kind === 'external');\n\t\t\t\tfor (const s of remaining) {\n\t\t\t\t\tif (stillOpens) break;\n\t\t\t\t\tif ((s as ExternalSlot).kind === 'external') continue;\n\t\t\t\t\tif (await openSlot(s as PasswordSlot, pass!)) {\n\t\t\t\t\t\tstillOpens = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!stillOpens) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t'removeEncryptionKey(): removing this slot would lock this session out - rotate with setEncryption(password) instead.'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst prevEnvelope = envelope;\n\t\t\t\tenvelope = { dataKey: envelope.dataKey, slots: remaining };\n\t\t\t\ttry {\n\t\t\t\t\tconst blob = await buildBlob();\n\t\t\t\t\tawait readBoxWithSync(await asBytes(blob), pass!); // our password still opens\n\t\t\t\t\tconst written = await durable!.save(blob);\n\t\t\t\t\tawait setRemoteVersion(typeof written === 'string' ? written : await statRemote());\n\t\t\t\t\tlastError = null;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tenvelope = prevEnvelope;\n\t\t\t\t\tif (isAuthExpired(e)) {\n\t\t\t\t\t\traiseGate('AUTH_EXPIRED', 'Access to the destination expired or was revoked.');\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t} finally {\n\t\t\t\t\tnotify();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tasync setExternalEncryption(secret, keyRef) {\n\t\t\tif (group) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'setExternalEncryption(): the store is in group mode - keys come from the membership manifest (setGroup), not an external key.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!durable) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'NOT_CONNECTED',\n\t\t\t\t\t'setExternalEncryption(): no destination is connected.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (locked() || needsAttention) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t'setExternalEncryption(): the store needs attention; resolve it before changing encryption.'\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn serialize(async () => {\n\t\t\t\tawait requireReady('setExternalEncryption');\n\t\t\t\tconst seen = await statRemote();\n\t\t\t\tif (seen !== null && remoteVersion !== null && seen !== remoteVersion) {\n\t\t\t\t\tawait pullRemoteIntoLocal('push', seen);\n\t\t\t\t\tif (locked() || needsAttention) {\n\t\t\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t\t\t'setExternalEncryption(): the pre-rewrite converge needs attention; resolve it first.'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst prevEncrypted = encrypted;\n\t\t\t\tconst prevPass = pass;\n\t\t\t\tconst prevEnvelope = envelope;\n\t\t\t\t// Rotation: a fresh data key sealed under one external slot, so every\n\t\t\t\t// prior key (password or external) stops opening the new bytes.\n\t\t\t\tconst dataKey = crypto.getRandomValues(new Uint8Array(32));\n\t\t\t\tconst slot = await mintExternalSlot(secret, keyRef, dataKey);\n\t\t\t\tencrypted = true;\n\t\t\t\tpass = null; // external-keyed: no password (do not setPass - it drops the envelope)\n\t\t\t\tenvelope = { dataKey, slots: [slot] };\n\t\t\t\tarmIdleLock();\n\t\t\t\ttry {\n\t\t\t\t\tawait persistLocal();\n\t\t\t\t\tpendingEdit = false;\n\t\t\t\t\tconst blob = await buildBlob();\n\t\t\t\t\t// Write-verified: the secret must open the very bytes about to land.\n\t\t\t\t\tawait readBoxWithSync(\n\t\t\t\t\t\tawait asBytes(blob),\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tasync () => secret\n\t\t\t\t\t);\n\t\t\t\t\tconst written = await durable!.save(blob);\n\t\t\t\t\tawait setRemoteVersion(typeof written === 'string' ? written : await statRemote());\n\t\t\t\t\tlastError = null;\n\t\t\t\t\tawait kv.set(KEY.enc, true);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tencrypted = prevEncrypted;\n\t\t\t\t\tpass = prevPass;\n\t\t\t\t\tenvelope = prevEnvelope;\n\t\t\t\t\tarmIdleLock();\n\t\t\t\t\tawait persistLocal().catch(() => undefined);\n\t\t\t\t\tif (isAuthExpired(e)) {\n\t\t\t\t\t\traiseGate('AUTH_EXPIRED', 'Access to the destination expired or was revoked.');\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t} finally {\n\t\t\t\t\tnotify();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tasync addExternalKey(secret, keyRef, id) {\n\t\t\tif (group) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'addExternalKey(): the store is in group mode - keys come from the membership manifest (setGroup).'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!durable) {\n\t\t\t\tthrow new SelfstoreError('NOT_CONNECTED', 'addExternalKey(): no destination is connected.');\n\t\t\t}\n\t\t\tif (locked() || needsAttention) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t'addExternalKey(): the store needs attention; resolve it before changing keys.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!encrypted) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'addExternalKey(): the backup is not encrypted yet - setEncryption(password) or setExternalEncryption(secret, ref) first.'\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn serialize(async () => {\n\t\t\t\tawait requireReady('addExternalKey');\n\t\t\t\tconst seen = await statRemote();\n\t\t\t\tif (seen !== null && remoteVersion !== null && seen !== remoteVersion) {\n\t\t\t\t\tawait pullRemoteIntoLocal('push', seen);\n\t\t\t\t\tif (locked() || needsAttention) {\n\t\t\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t\t\t'TARGET_WRITE_FAILED',\n\t\t\t\t\t\t\t'addExternalKey(): the pre-rewrite converge needs attention; resolve it first.'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// A password-unlocked session with no envelope yet mints its own slot\n\t\t\t\t// first (same data key), so the external slot joins it - nothing is\n\t\t\t\t// re-encrypted and the existing password keeps opening the file.\n\t\t\t\tif (!envelope && pass) {\n\t\t\t\t\tconst dataKey = crypto.getRandomValues(new Uint8Array(32));\n\t\t\t\t\tenvelope = { dataKey, slots: [await mintSlot(pass, dataKey)] };\n\t\t\t\t}\n\t\t\t\tif (!envelope) {\n\t\t\t\t\tthrow new TypeError('addExternalKey(): no data key in hand - unlock the backup first.');\n\t\t\t\t}\n\t\t\t\tif (envelope.slots.length >= MAX_KEY_SLOTS) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`addExternalKey(): this backup already has ${MAX_KEY_SLOTS} key slots.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (id && envelope.slots.some((s) => s.id === id)) {\n\t\t\t\t\tthrow new TypeError(`addExternalKey(): a key slot named \"${id}\" already exists.`);\n\t\t\t\t}\n\t\t\t\tconst prevEnvelope = envelope;\n\t\t\t\tconst slot = await mintExternalSlot(secret, keyRef, envelope.dataKey, id);\n\t\t\t\tenvelope = { dataKey: envelope.dataKey, slots: [...envelope.slots, slot] };\n\t\t\t\ttry {\n\t\t\t\t\tconst blob = await buildBlob();\n\t\t\t\t\t// Write-verified: the new secret must open the bytes about to land.\n\t\t\t\t\tawait readBoxWithSync(\n\t\t\t\t\t\tawait asBytes(blob),\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t\tasync () => secret\n\t\t\t\t\t);\n\t\t\t\t\tconst written = await durable!.save(blob);\n\t\t\t\t\tawait setRemoteVersion(typeof written === 'string' ? written : await statRemote());\n\t\t\t\t\tlastError = null;\n\t\t\t\t\treturn slot.id;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tenvelope = prevEnvelope;\n\t\t\t\t\tif (isAuthExpired(e)) {\n\t\t\t\t\t\traiseGate('AUTH_EXPIRED', 'Access to the destination expired or was revoked.');\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t} finally {\n\t\t\t\t\tnotify();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tasync unlockWithExternal(secret) {\n\t\t\tif (!locked() || !durable) return false;\n\t\t\t// Hold the secret only across this converge: importLocked resolves the\n\t\t\t// external slot from it, adopts the envelope (data key) on success, and\n\t\t\t// every later read uses the held data key - the secret is needed once.\n\t\t\tpendingExternalSecret = secret;\n\t\t\tneedsAttention = schemaCeiling > version; // clear only the LOCK, not a schema ceiling gate\n\t\t\ttry {\n\t\t\t\tawait pull('manual'); // doPull notifies; a wrong secret re-raises the gate\n\t\t\t} finally {\n\t\t\t\tpendingExternalSecret = null;\n\t\t\t}\n\t\t\treturn !locked() && !needsAttention;\n\t\t},\n\n\t\tlistEncryptionKeys() {\n\t\t\treturn (envelope?.slots ?? []).map((s) => ({\n\t\t\t\tid: s.id,\n\t\t\t\tkind:\n\t\t\t\t\t(s as ExternalSlot).kind === 'external' ? ('external' as const) : ('password' as const)\n\t\t\t}));\n\t\t},\n\n\t\tdispose() {\n\t\t\tclearTimeout(timer);\n\t\t\tclearTimeout(idleTimer);\n\t\t\tchannel?.close();\n\t\t\tsubs.clear();\n\t\t}\n\t};\n}\n","// The working store behind createLocalStore: the app's data always lives here\n// so a refresh never loses it. Swappable interface - indexedDbCache(name) in\n// the browser, memoryCache() in tests and SSR.\n//\n// Collections and file blobs are encrypted at rest under a non-extractable\n// device key kept in the same database (cache-crypto.ts). The small kv\n// bookkeeping (sync metadata, journal) stays in the clear - it is not the\n// sensitive payload.\n\nimport { openDB, type IDBPDatabase } from 'idb';\nimport { seal, unseal, isEnvelope, newDeviceKey, type EncEnvelope } from './cache-crypto';\nimport { SelfstoreError } from '../selfstore/errors';\nimport type { CacheKdf } from './cache-lock';\n\n/** A binary attachment kept as a real Blob. */\nexport interface CachedFile {\n\tid: string;\n\tname: string;\n\tmime: string;\n\tblob: Blob;\n}\n\n/** A tiny async key/value space for the store's bookkeeping. */\nexport interface KV {\n\tget<T = unknown>(key: string): Promise<T | undefined>;\n\tset(key: string, value: unknown): Promise<void>;\n\tdel(key: string): Promise<void>;\n}\n\nexport interface LocalCache {\n\treadonly kv: KV;\n\t/** Load the persisted collections + files, or null if nothing was ever saved. */\n\tload(): Promise<{ collections: Record<string, unknown[]>; files: CachedFile[] } | null>;\n\t/** Overwrite the collections snapshot (small; written on every change). */\n\tsaveCollections(collections: Record<string, unknown[]>): Promise<void>;\n\t/** Reconcile the file store: add new blobs, drop removed ones (immutable by id). */\n\tsaveFiles(files: CachedFile[]): Promise<void>;\n\t/** Wipe every locally-stored byte (the \"forget me on this device\" action). */\n\tclear(): Promise<void>;\n\t/** Ask the platform to make storage persistent (not evicted). Best-effort;\n\t * optional because only browser-backed caches have the concept. */\n\trequestPersistent?(): Promise<boolean>;\n}\n\n/** A cache whose payload seal key is not on disk but supplied per session from\n * a secret held in memory (a password, or an app-provided key such as a passkey\n * PRF). Until unlock() succeeds each session, load()/save*() reject with\n * PASSWORD_REQUIRED. Defeats a full-profile copy, which a device key cannot -\n * see indexedDbCache(name, { lock: true }). */\nexport interface LockableCache extends LocalCache {\n\t/** Supply the session secret. A string is Argon2id-derived (the salt is\n\t * persisted in the clear); a CryptoKey is used as-is. Returns false when it\n\t * does not open existing data - the cache stays locked. The first secret on\n\t * an empty cache sets the lock. */\n\tunlock(secret: string | CryptoKey): Promise<boolean>;\n\t/**\n\t * Change the secret that seals this cache, in place: re-derive the key (a\n\t * fresh salt for a password) and rewrite every sealed record under it.\n\t *\n\t * Without this, \"change my password\" has no honest implementation for a\n\t * locked cache - the app has to wipe and rebuild, which also throws away\n\t * the durable destination's session, and a half-finished wipe leaves data\n\t * no key can open. Requires the cache to be unlocked: what cannot be read\n\t * cannot be re-sealed.\n\t */\n\treseal(secret: string | CryptoKey): Promise<void>;\n\t/** Drop the in-memory key: reads and writes lock until unlock() is called. */\n\tlockNow(): void;\n\t/** Whether no seal key is currently held. */\n\treadonly locked: boolean;\n}\n\n/** Narrow a cache to its lockable shape (created with { lock: true }). */\nexport function isLockableCache(cache: LocalCache): cache is LockableCache {\n\treturn typeof (cache as Partial<LockableCache>).unlock === 'function';\n}\n\n/** In-memory LocalCache for tests and SSR paths where IndexedDB does not\n * exist. Not encrypted - nothing is at rest. */\nexport function memoryCache(): LocalCache {\n\tconst kvMap = new Map<string, unknown>();\n\tlet collections: Record<string, unknown[]> | undefined;\n\tconst files = new Map<string, CachedFile>();\n\treturn {\n\t\tkv: {\n\t\t\tasync get<T = unknown>(key: string): Promise<T | undefined> {\n\t\t\t\treturn kvMap.get(key) as T | undefined;\n\t\t\t},\n\t\t\tasync set(key: string, value: unknown): Promise<void> {\n\t\t\t\tkvMap.set(key, value);\n\t\t\t},\n\t\t\tasync del(key: string): Promise<void> {\n\t\t\t\tkvMap.delete(key);\n\t\t\t}\n\t\t},\n\t\tasync load() {\n\t\t\tif (collections === undefined) return null;\n\t\t\t// Clone both ways: a returned reference must never alias internal state.\n\t\t\treturn { collections: structuredClone(collections), files: [...files.values()] };\n\t\t},\n\t\tasync saveCollections(c) {\n\t\t\tcollections = structuredClone(c);\n\t\t},\n\t\tasync saveFiles(fs) {\n\t\t\tfiles.clear();\n\t\t\tfor (const f of fs) files.set(f.id, f);\n\t\t},\n\t\tasync clear() {\n\t\t\tkvMap.clear();\n\t\t\tcollections = undefined;\n\t\t\tfiles.clear();\n\t\t}\n\t};\n}\n\n/** A file record decoded for the caller: metadata plus the live blob. */\ninterface StoredFile {\n\tname: string;\n\tmime: string;\n\tblob: Blob;\n}\n/** A file record as stored: metadata in the clear, bytes sealed. */\ntype EncFile = { name: string; mime: string } & EncEnvelope;\n\nconst COLLECTIONS_KEY = '__collections';\nconst DEVICE_KEY = '__deviceKey';\nconst CACHE_KDF = '__cacheKdf';\n\n/** The default browser cache. `name` scopes the database to one app, so two\n * apps on the same origin never collide. */\nexport function indexedDbCache(name: string, opts: { lock: true }): LockableCache;\nexport function indexedDbCache(name: string, opts?: { lock?: boolean }): LocalCache;\nexport function indexedDbCache(name: string, opts?: { lock?: boolean }): LocalCache {\n\tlet _db: Promise<IDBPDatabase> | null = null;\n\tconst db = (): Promise<IDBPDatabase> =>\n\t\t(_db ??= openDB(name, 1, {\n\t\t\tupgrade(d) {\n\t\t\t\td.createObjectStore('kv');\n\t\t\t\td.createObjectStore('files');\n\t\t\t}\n\t\t}));\n\n\t// Lock mode: the seal key is supplied per session (unlock) and kept in RAM\n\t// only; no device key is ever written, so a copy of the profile carries no\n\t// usable key. Locked reads/writes reject with PASSWORD_REQUIRED.\n\tconst lockMode = opts?.lock === true;\n\tlet sealKey: CryptoKey | null = null;\n\n\t// The device key lives in this same database, so it and the data it protects\n\t// are cleared together (clear() wipes both) - no orphaned ciphertext.\n\tlet _key: Promise<CryptoKey> | null = null;\n\tfunction key(): Promise<CryptoKey> {\n\t\tif (lockMode) {\n\t\t\treturn sealKey\n\t\t\t\t? Promise.resolve(sealKey)\n\t\t\t\t: Promise.reject(\n\t\t\t\t\t\tnew SelfstoreError(\n\t\t\t\t\t\t\t'PASSWORD_REQUIRED',\n\t\t\t\t\t\t\t'The local cache is locked - unlock() it first.'\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t}\n\t\treturn (_key ??= loadOrCreateKey());\n\t}\n\tasync function loadOrCreateKey(): Promise<CryptoKey> {\n\t\tconst d = await db();\n\t\tconst existing = (await d.get('kv', DEVICE_KEY)) as CryptoKey | undefined;\n\t\tif (existing) return existing;\n\t\t// Generate outside the write tx (a non-IDB await would auto-close it), then\n\t\t// store only if still absent so a racing tab cannot clobber the key.\n\t\tconst fresh = await newDeviceKey();\n\t\tconst tx = d.transaction('kv', 'readwrite');\n\t\tif (!(await tx.store.get(DEVICE_KEY))) await tx.store.put(fresh, DEVICE_KEY);\n\t\tawait tx.done;\n\t\treturn (await d.get('kv', DEVICE_KEY)) as CryptoKey;\n\t}\n\n\tasync function decodeFile(v: EncFile): Promise<StoredFile> {\n\t\tif (!isEnvelope(v)) {\n\t\t\tthrow new SelfstoreError('BAD_FORMAT', 'Unrecognized cache record (not a sealed envelope).');\n\t\t}\n\t\tconst bytes = await unseal(await key(), v);\n\t\treturn { name: v.name, mime: v.mime, blob: new Blob([bytes as BlobPart], { type: v.mime }) };\n\t}\n\n\tconst kv: KV = {\n\t\tasync get<T = unknown>(key: string): Promise<T | undefined> {\n\t\t\treturn (await (await db()).get('kv', `m:${key}`)) as T | undefined;\n\t\t},\n\t\tasync set(key: string, value: unknown): Promise<void> {\n\t\t\tawait (await db()).put('kv', value, `m:${key}`);\n\t\t},\n\t\tasync del(key: string): Promise<void> {\n\t\t\tawait (await db()).delete('kv', `m:${key}`);\n\t\t}\n\t};\n\n\tconst base: LocalCache = {\n\t\tkv,\n\n\t\tasync load() {\n\t\t\tconst d = await db();\n\t\t\tconst rawCollections = await d.get('kv', COLLECTIONS_KEY);\n\t\t\tif (rawCollections === undefined) return null;\n\t\t\t// A decrypt (or shape) failure throws, never returns null: init then\n\t\t\t// leaves the store not-ready, so auto-save cannot overwrite the bytes.\n\t\t\tif (!isEnvelope(rawCollections)) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'BAD_FORMAT',\n\t\t\t\t\t'Unrecognized cache record (not a sealed envelope).'\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst collections = JSON.parse(\n\t\t\t\tnew TextDecoder().decode(await unseal(await key(), rawCollections))\n\t\t\t) as Record<string, unknown[]>;\n\t\t\tconst files: CachedFile[] = [];\n\t\t\tfor (const fileKey of await d.getAllKeys('files')) {\n\t\t\t\tconst v = (await d.get('files', fileKey)) as EncFile | undefined;\n\t\t\t\tif (v) files.push({ id: String(fileKey), ...(await decodeFile(v)) });\n\t\t\t}\n\t\t\treturn { collections, files };\n\t\t},\n\n\t\tasync saveCollections(collections) {\n\t\t\tconst bytes = new TextEncoder().encode(JSON.stringify(collections));\n\t\t\tconst env = await seal(await key(), bytes);\n\t\t\tawait (await db()).put('kv', env, COLLECTIONS_KEY);\n\t\t},\n\n\t\tasync saveFiles(files) {\n\t\t\tconst d = await db();\n\t\t\tconst have = new Set((await d.getAllKeys('files')).map(String));\n\t\t\tconst want = new Set(files.map((f) => f.id));\n\t\t\t// Seal new blobs before opening the write tx: crypto is a non-IDB await and\n\t\t\t// would otherwise auto-close the transaction.\n\t\t\tconst k = await key();\n\t\t\tconst fresh = await Promise.all(\n\t\t\t\tfiles\n\t\t\t\t\t.filter((f) => !have.has(f.id))\n\t\t\t\t\t.map(async (f) => {\n\t\t\t\t\t\tconst env = await seal(k, new Uint8Array(await f.blob.arrayBuffer()));\n\t\t\t\t\t\treturn { id: f.id, rec: { name: f.name, mime: f.mime, ...env } satisfies EncFile };\n\t\t\t\t\t})\n\t\t\t);\n\t\t\tconst tx = d.transaction('files', 'readwrite');\n\t\t\tfor (const { id, rec } of fresh) tx.store.put(rec, id);\n\t\t\tfor (const id of have) if (!want.has(id)) tx.store.delete(id);\n\t\t\tawait tx.done;\n\t\t},\n\n\t\tasync clear() {\n\t\t\tconst d = await db();\n\t\t\tawait d.clear('kv');\n\t\t\tawait d.clear('files');\n\t\t\t_key = null; // next save mints a fresh device key\n\t\t\tsealKey = null; // lock mode: forget the session key (its kdf lived in kv, now gone)\n\t\t},\n\n\t\tasync requestPersistent() {\n\t\t\tif (typeof navigator === 'undefined' || !navigator.storage?.persist) return false;\n\t\t\ttry {\n\t\t\t\tif (await navigator.storage.persisted()) return true;\n\t\t\t\treturn await navigator.storage.persist();\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t};\n\n\tif (!lockMode) return base;\n\n\tconst lockable: LockableCache = {\n\t\t...base,\n\t\tget locked() {\n\t\t\treturn sealKey === null;\n\t\t},\n\t\tlockNow() {\n\t\t\tsealKey = null;\n\t\t},\n\t\tasync reseal(secret: string | CryptoKey): Promise<void> {\n\t\t\tconst { keyFromPassword, freshCacheKdf } = await import('./cache-lock');\n\t\t\tconst previous = sealKey;\n\t\t\tif (previous === null) {\n\t\t\t\tthrow new SelfstoreError(\n\t\t\t\t\t'PASSWORD_REQUIRED',\n\t\t\t\t\t'reseal(): the local cache is locked - unlock() it first.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst d = await db();\n\t\t\t// A password gets a fresh salt: reusing the old one would let a stolen\n\t\t\t// derivation survive the change the user just made.\n\t\t\tconst kdf = typeof secret === 'string' ? freshCacheKdf() : null;\n\t\t\tconst next = kdf ? await keyFromPassword(secret as string, kdf) : (secret as CryptoKey);\n\n\t\t\t// Re-encrypt everything BEFORE touching the database. Writing the new\n\t\t\t// salt first and the payload after would, on a crash or a closed tab in\n\t\t\t// between, leave records that no key opens - the cache would be lost\n\t\t\t// with the very gesture meant to keep it.\n\t\t\tconst rawCollections = await d.get('kv', COLLECTIONS_KEY);\n\t\t\tconst collections = isEnvelope(rawCollections)\n\t\t\t\t? await seal(next, await unseal(previous, rawCollections))\n\t\t\t\t: null;\n\t\t\tconst files: { id: IDBValidKey; rec: EncFile }[] = [];\n\t\t\tfor (const fileKey of await d.getAllKeys('files')) {\n\t\t\t\tconst v = (await d.get('files', fileKey)) as EncFile | undefined;\n\t\t\t\tif (!v) continue;\n\t\t\t\tconst bytes = await unseal(previous, v);\n\t\t\t\tfiles.push({\n\t\t\t\t\tid: fileKey,\n\t\t\t\t\trec: { name: v.name, mime: v.mime, ...(await seal(next, bytes)) }\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// One transaction, so the salt and every record it governs land together.\n\t\t\tconst tx = d.transaction(['kv', 'files'], 'readwrite');\n\t\t\tconst store = tx.objectStore('kv');\n\t\t\tif (kdf) store.put(kdf, CACHE_KDF);\n\t\t\telse store.delete(CACHE_KDF); // an app-supplied key needs no salt\n\t\t\tif (collections) store.put(collections, COLLECTIONS_KEY);\n\t\t\tconst fileStore = tx.objectStore('files');\n\t\t\tfor (const { id, rec } of files) fileStore.put(rec, id);\n\t\t\tawait tx.done;\n\t\t\tsealKey = next;\n\t\t},\n\t\tasync unlock(secret: string | CryptoKey): Promise<boolean> {\n\t\t\t// cache-lock (and its Argon2id dependency) load only when lock mode is\n\t\t\t// actually used, so the default cache path stays free of the KDF.\n\t\t\tconst { keyFromPassword, freshCacheKdf, opens } = await import('./cache-lock');\n\t\t\tconst d = await db();\n\t\t\tlet candidate: CryptoKey;\n\t\t\tif (typeof secret === 'string') {\n\t\t\t\tlet kdf = (await d.get('kv', CACHE_KDF)) as CacheKdf | undefined;\n\t\t\t\tif (!kdf) {\n\t\t\t\t\t// Mint the salt once, race-safe against a second tab (same guard as\n\t\t\t\t\t// the device key): store only if still absent.\n\t\t\t\t\tconst fresh = freshCacheKdf();\n\t\t\t\t\tconst tx = d.transaction('kv', 'readwrite');\n\t\t\t\t\tif (!(await tx.store.get(CACHE_KDF))) await tx.store.put(fresh, CACHE_KDF);\n\t\t\t\t\tawait tx.done;\n\t\t\t\t\tkdf = (await d.get('kv', CACHE_KDF)) as CacheKdf;\n\t\t\t\t}\n\t\t\t\tcandidate = await keyFromPassword(secret, kdf);\n\t\t\t} else {\n\t\t\t\tcandidate = secret;\n\t\t\t}\n\t\t\t// Trust the secret only once it opens existing data; an empty cache\n\t\t\t// accepts the first secret, which sets the lock.\n\t\t\tconst raw = await d.get('kv', COLLECTIONS_KEY);\n\t\t\tif (isEnvelope(raw) && !(await opens(candidate, raw))) return false;\n\t\t\tsealKey = candidate;\n\t\t\treturn true;\n\t\t}\n\t};\n\treturn lockable;\n}\n","/**\n * A client-only DriveAuth: the Google Identity Services token flow, no backend.\n * The access token is cached in sessionStorage so a reload reuses it, and a\n * silent re-acquisition is attempted when it lapses; if that fails (the Google\n * session expired, or third-party cookies are blocked) the Drive target reports\n * needs-attention and the user reconnects in one click. For a connection that\n * never re-prompts, back the Drive target with a server that holds a refresh\n * token instead (a broker implementing the same DriveAuth interface).\n */\n\nimport type { DriveAuth } from './drive';\n\nconst DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive.file';\n/** How long a token request may hang before it reads as failed. */\nconst TOKEN_TIMEOUT_MS = 120_000;\n/** Refresh margin: a token this close to expiry counts as stale. */\nconst EXPIRY_MARGIN_MS = 60_000;\n/** Google's default access-token lifetime, when the response omits expires_in. */\nconst DEFAULT_TOKEN_TTL_S = 3600;\n\nlet gisLoading: Promise<void> | null = null;\nfunction loadGIS(): Promise<void> {\n\tif (typeof globalThis.window === 'undefined') return Promise.resolve();\n\tif (globalThis.window.google?.accounts) return Promise.resolve();\n\tgisLoading ??= new Promise<void>((resolve, reject) => {\n\t\tconst s = document.createElement('script');\n\t\ts.src = 'https://accounts.google.com/gsi/client';\n\t\ts.async = true;\n\t\ts.onload = () => resolve();\n\t\ts.onerror = () => reject(new Error('GIS failed to load'));\n\t\tdocument.head.appendChild(s);\n\t});\n\treturn gisLoading;\n}\n\n// prompt '' = silent (no UI, fails if the session lapsed); 'consent' = popup.\n// Module-level (not nested in gisDriveAuth) to keep the callback nesting shallow.\nfunction requestToken(\n\tclientId: string,\n\tscope: string,\n\tprompt: string,\n\tonToken: (token: string, expiry: number) => void\n): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst finish = (fn: () => void): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timer);\n\t\t\tfn();\n\t\t};\n\t\tconst timer = setTimeout(() => finish(() => reject(new Error('timeout'))), TOKEN_TIMEOUT_MS);\n\t\tconst client = globalThis.window.google!.accounts.oauth2.initTokenClient({\n\t\t\tclient_id: clientId,\n\t\t\tscope,\n\t\t\tcallback(resp) {\n\t\t\t\tif (resp.error || !resp.access_token) {\n\t\t\t\t\tfinish(() => reject(new Error(resp.error ?? 'token_failed')));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tonToken(resp.access_token, Date.now() + (resp.expires_in ?? DEFAULT_TOKEN_TTL_S) * 1000);\n\t\t\t\tfinish(() => resolve(resp.access_token!));\n\t\t\t},\n\t\t\terror_callback(err) {\n\t\t\t\tfinish(() => reject(new Error(err?.type ?? 'gis_error')));\n\t\t\t}\n\t\t});\n\t\tclient.requestAccessToken({ prompt });\n\t});\n}\n\n/** Build a client-only DriveAuth for the given OAuth client id (no backend). */\nexport function gisDriveAuth(opts: { clientId: string; scope?: string }): DriveAuth {\n\tconst scope = opts.scope ?? DRIVE_SCOPE;\n\n\t// The access token is kept in MEMORY only (never sessionStorage/localStorage),\n\t// so an XSS payload in the same origin cannot lift it from web storage. A\n\t// reload simply re-acquires it silently (prompt '') or, if the Google session\n\t// lapsed, surfaces a one-click reconnect. This trades a little re-prompting for\n\t// not persisting a Drive-scoped credential.\n\tlet token: string | null = null;\n\tlet expiry = 0;\n\tconst fresh = (): boolean => !!token && Date.now() < expiry - EXPIRY_MARGIN_MS;\n\n\tfunction cache(t: string, exp: number): void {\n\t\ttoken = t;\n\t\texpiry = exp;\n\t}\n\tfunction clear(): void {\n\t\ttoken = null;\n\t\texpiry = 0;\n\t}\n\n\treturn {\n\t\tasync token(tokenOpts?: { forceRefresh?: boolean }): Promise<string> {\n\t\t\t// forceRefresh: the target saw a 401 on this cached token, so re-acquire\n\t\t\t// even though our own clock still thinks it is fresh (Google can reject a\n\t\t\t// token before its nominal expiry).\n\t\t\tif (!tokenOpts?.forceRefresh && fresh()) return token!;\n\t\t\tawait loadGIS();\n\t\t\treturn requestToken(opts.clientId, scope, '', cache); // silent\n\t\t},\n\t\tasync reconnect(): Promise<boolean> {\n\t\t\tawait loadGIS();\n\t\t\ttry {\n\t\t\t\tawait requestToken(opts.clientId, scope, 'consent', cache);\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tasync forget(): Promise<void> {\n\t\t\tclear();\n\t\t}\n\t};\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as StoreError, B as BackupTarget, L as LocalStore, k as ReplicaState } from './store-
|
|
1
|
+
import { t as StoreError, B as BackupTarget, L as LocalStore, k as ReplicaState } from './store-CSxHlrov.js';
|
|
2
2
|
import { K as KV } from './cache-ilsK3Tki.js';
|
|
3
|
-
import { W as WebdavConfig, S as S3Config, D as DriveAuth } from './drive-
|
|
3
|
+
import { W as WebdavConfig, S as S3Config, D as DriveAuth } from './drive-Cf_ulDfn.js';
|
|
4
4
|
import { F as FlowStore } from './machine-ALMkT3mk.js';
|
|
5
5
|
|
|
6
6
|
type ConnectKind = 'drive' | 'file' | 'webdav' | 's3';
|
package/dist/flows.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { c as ConnectFlow, a as ConnectFlowOptions, h as ConnectFlowOutcome, b as ConnectKind, i as ConnectResolution, j as ConnectSnapshot, k as ConnectStep, C as ConnectTargets, l as Connector, F as FlowHost, J as JoinEngine, g as JoinFlow, m as JoinOutcome, n as JoinPreview, o as JoinSnapshot, p as JoinStep, q as REPLICA_ID, R as ReplicaFlow, r as ReplicaFlowOptions, s as ReplicaSnapshot, t as ReplicaStep, u as ShareBusy, d as ShareEngine, f as ShareFlow, e as ShareLevel, v as ShareLinkInfo, w as ShareMemberInfo, x as ShareSnapshot, y as connectFlow, z as joinFlow, A as replicaFlow, B as shareFlow } from './flows-
|
|
1
|
+
export { c as ConnectFlow, a as ConnectFlowOptions, h as ConnectFlowOutcome, b as ConnectKind, i as ConnectResolution, j as ConnectSnapshot, k as ConnectStep, C as ConnectTargets, l as Connector, F as FlowHost, J as JoinEngine, g as JoinFlow, m as JoinOutcome, n as JoinPreview, o as JoinSnapshot, p as JoinStep, q as REPLICA_ID, R as ReplicaFlow, r as ReplicaFlowOptions, s as ReplicaSnapshot, t as ReplicaStep, u as ShareBusy, d as ShareEngine, f as ShareFlow, e as ShareLevel, v as ShareLinkInfo, w as ShareMemberInfo, x as ShareSnapshot, y as connectFlow, z as joinFlow, A as replicaFlow, B as shareFlow } from './flows-BIWaqRUz.js';
|
|
2
2
|
export { F as FlowStore, w as withDeadline } from './machine-ALMkT3mk.js';
|
|
3
|
-
import './store-
|
|
3
|
+
import './store-CSxHlrov.js';
|
|
4
4
|
import './cache-ilsK3Tki.js';
|
|
5
5
|
import './sync.js';
|
|
6
|
-
import './drive-
|
|
6
|
+
import './drive-Cf_ulDfn.js';
|
package/dist/households.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { n as Snapshot, E as EncodeOptions, H as Header,
|
|
2
|
-
export { d as Mode,
|
|
1
|
+
import { n as Snapshot, E as EncodeOptions, H as Header, f as PasswordPolicy, B as BackupTarget, q as StatusDescriptor, t as StoreError, c as LocalStoreState, L as LocalStore } from './store-CSxHlrov.js';
|
|
2
|
+
export { d as Mode, e as PasswordCheck, g as PasswordRequirement, S as SelfstoreError, l as SelfstoreErrorCode, m as Severity, o as SnapshotFile, p as StatusAction, s as StorageState, T as TargetKind, x as checkPasswordPolicy, C as errorLabelKey, G as isSelfstoreError } from './store-CSxHlrov.js';
|
|
3
3
|
import { L as LocalCache, K as KV } from './cache-ilsK3Tki.js';
|
|
4
4
|
import { SyncConfig } from './sync.js';
|
|
5
|
-
import { D as DriveAuth, W as WebdavConfig, S as S3Config } from './drive-
|
|
6
|
-
export { c as changePassword, g as gisDriveAuth, p as pickFromDisk, s as saveToDisk } from './local-
|
|
5
|
+
import { D as DriveAuth, W as WebdavConfig, S as S3Config } from './drive-Cf_ulDfn.js';
|
|
6
|
+
export { c as changePassword, g as gisDriveAuth, p as pickFromDisk, s as saveToDisk } from './local-BowlLFZc.js';
|
|
7
7
|
|
|
8
8
|
declare const BACKUP_EXTENSION = ".zip";
|
|
9
9
|
declare const BACKUP_MIME = "application/zip";
|