/*! * Copyright (c) 2026 Interop Alliance. All rights reserved. */ /** * Shared WAS replication bootstrap: given a parsed grant set and the invoking * ZcapClient, builds the delegated {@link WasRemoteStore}, best-effort marks * each private collection encrypted and declares each collection's equality * indexes -- in the collection description for a public one, in the * collection's encrypted metadata (as blinded-index attributes) for a private * one -- and starts the supplied {@link SyncController} with * reactive store patching. The caller injects the opened localStore, the * controller, and the per-doc `onRemoteChange` patcher (typically wired to the * rehydrate mechanism over the app's store registry) rather than this module * reaching for app-side globals. * * SHARED collections are handled apart from all of that. They belong to the * wallet, so they never enter replication, never get a local replica, and are * excluded from the best-effort description PUTs (a read-only grant would draw * nothing but a pointless 403). Instead one {@link SharedCollectionReader} is * opened per configured shared collection the grant set actually covers; a * shared collection with no covering grant, or one this app turns out not to be * a recipient of, is skipped with a warning rather than failing the session. */ import type { ZcapClient } from '@interop/ezcap'; import type { RxChangeEvent } from 'rxdb/plugins/core'; import type { CollectionEncryption } from '@interop/was-client'; import type { IKeyAgreementKey, IKeyResolver } from '@interop/data-integrity-core'; import { type SyncedDoc } from '../sync/index.js'; import { type SharedCollectionConfig, type WasCollectionConfig } from '../config.js'; import type { ParsedGrants } from '../grants.js'; import { WasRemoteStore } from './wasRemoteStore.js'; import { SharedCollectionReader } from './sharedCollectionReader.js'; import type { LocalStore } from './localStore.js'; import type { SyncController } from './syncController.js'; /** * What the sync bootstrap hands back: the delegated remote store, plus a * read-only {@link SharedCollectionReader} per configured shared collection the * grant set covers and this app is a recipient of, keyed by the config `key`. */ export interface WasSyncBootstrap { remoteStore: WasRemoteStore; sharedCollections: Record; } /** * One live encryption-descriptor read per granted private collection, invoked * with the grants' delegated zcaps and keyed by WAS collection id. Only * epoch-bearing descriptors are returned (a rosterless one cannot build a * cipher). Used at login time, BEFORE any replication exists: the connected * replica must open epoch-aware -- epoch-from-birth leaves no single-key * fallback, and the adoption merge writes into it before sync starts. The * sync bootstrap reuses these reads (its `knownDescriptors` input) rather * than re-issuing them. * * @param options {object} * @param options.parsed {ParsedGrants} * @param options.zcapClient {ZcapClient} invocation signer = grants' controller * @param options.collections {WasCollectionConfig[]} the collections to read * descriptors for (public ones are skipped) * @returns {Promise>} */ export declare function readRemoteDescriptors({ parsed, zcapClient, collections }: { parsed: ParsedGrants; zcapClient: ZcapClient; collections: WasCollectionConfig[]; }): Promise>; /** * Builds the remote store, opens the shared-collection readers, and starts * background replication. * * @param options {object} * @param options.parsed {ParsedGrants} * @param options.zcapClient {ZcapClient} invocation signer = grants' controller * @param options.collections {WasCollectionConfig[]} the collection registry; * public (plaintext) collections are never marked encrypted * @param options.localStore {LocalStore} the opened local encrypted replica * @param options.syncController {SyncController} a fresh per-session controller * @param options.onRemoteChange {(collectionKey, event) => void} per-doc * reactive patcher for pulled/conflict-resolved remote changes * @param [options.sharedCollections] {SharedCollectionConfig[]} the shared * (read-only, wallet-owned) registry; never replicated, never written to * @param [options.identityKeys] {object} this app's IDENTITY key-agreement key * and its resolver, the recipient identity a wallet writes into a shared * collection's epoch roster. Required to open any shared-collection reader, * and to run the codec-driven blinded-index verbs on a private collection * @param [options.identityKeys.keyAgreementKey] {IKeyAgreementKey} * @param [options.identityKeys.keyResolver] {IKeyResolver} * @param [options.onAuthError] {() => void} fired when replication hits a * 401/403 (expired/revoked access) -- wired to the reconnect banner * @param [options.onDescriptorsFetched] {(descriptors) => void | Promise} given * the freshly fetched per-collection encryption descriptors (by WAS collection * id), to refresh the offline descriptor cache * @param [options.knownDescriptors] {Record} * descriptors the caller ALREADY read live in this same bring-up (the * login-time {@link readRemoteDescriptors} pass); the bootstrap reuses them * instead of re-issuing the same GET seconds later. A hot restore passes * none -- there the bootstrap read IS the freshness refresh over the * offline cache * @returns {Promise} */ export declare function startWasSync({ parsed, zcapClient, collections, localStore, syncController, onRemoteChange, sharedCollections, identityKeys, onAuthError, onDescriptorsFetched, knownDescriptors }: { parsed: ParsedGrants; zcapClient: ZcapClient; collections: WasCollectionConfig[]; localStore: LocalStore; syncController: SyncController; onRemoteChange: (collectionKey: string, event: RxChangeEvent) => void; sharedCollections?: SharedCollectionConfig[]; identityKeys?: { keyAgreementKey: IKeyAgreementKey; keyResolver: IKeyResolver; }; onAuthError?: () => void; onDescriptorsFetched?: (descriptors: Record) => void | Promise; knownDescriptors?: Record; }): Promise; //# sourceMappingURL=wasSync.d.ts.map