import type { DocCipher, Json, SyncStore } from './types.js'; /** * Re-mints every pending (dirty, never-acked, live) row whose envelope the * given cipher cannot route to an epoch it knows -- the create-loss path for * an eager minter, run after adopting a published descriptor this client did * not install itself (`ensureWalletSpaceEpochs` returning an adopted * descriptor for a collection it had already minted against; the envelope, not * the `installed` flag, decides per row) and before the next push. * * Each such row is decrypted through `decryptStale` (the pre-adoption cipher, * or a plaintext-projection read keyed by the row id), re-encrypted with * `cipher` (built from the adopted descriptor, so under its current epoch), * and handed to {@link SyncStore.replacePending} -- which may re-key the row, * since the re-mint is a fresh encryption. Rows already readable under the * adopted descriptor, acked rows (`version > 0` -- they HAVE feed existence * and are never re-minted), and tombstones are left untouched. * * Two decrypt failures are told apart. An unknown epoch is the create-loss * shape this helper exists for, and the row is re-minted. An addressing * refusal (was-client's `IntegrityError`: the envelope is sealed for some * other resource id, the shape a row minted by a pre-addressed writer has) is * left where it is, logged once, and the pass moves to the next row -- the * row is not this helper's to settle, and aborting the pass over it would * strand every other pending row under the losing epoch and block the * adoption from ever completing. Any other decrypt failure still propagates. * * A replace the store SKIPS (`{ applied: false }` -- a local write bumped the * row's revision between the snapshot and the replace, so the row now holds a * body this pass never saw) is not counted as re-minted: the whole pass * re-snapshots and re-probes, settling the row under its fresh revision. Only * rows still unroutable are re-processed; the retry is bounded by * {@link MAX_REMINT_ATTEMPTS}, and a pass that exhausts the bound throws * rather than returning -- a row left sealed under the losing epoch MUST NOT * be pushed, since it would land on the feed as a permanently unroutable * entry. * * The store parameter is narrowed to one that implements `replacePending` * (optional on {@link SyncStore} itself, since a lazy-minting consumer never * re-mints): the requirement is a compile-time one, not a runtime throw. * * Idempotent: a re-run finds the re-minted rows readable and does nothing. * * @param options {object} * @param options.store {SyncStore} must implement `replacePending` * @param options.cipher {DocCipher} built from the adopted (published) * descriptor * @param options.decryptStale {function} opens envelopes minted before the * adoption; receives `{ id, envelope }` so a projection-backed caller can * look the plaintext up by row id instead of decrypting * @param [options.signal] {AbortSignal} checked between rows * @returns {Promise<{ pending: number; reminted: number }>} pending live * rows the first pass scanned, and how many rows were re-minted (applied * replaces only, across all passes) */ export declare function remintPendingEnvelopes({ store, cipher, decryptStale, signal }: { store: SyncStore & { replacePending: NonNullable; }; cipher: DocCipher; decryptStale: (options: { id: string; envelope: Json; }) => Promise; signal?: AbortSignal; }): Promise<{ pending: number; reminted: number; }>; //# sourceMappingURL=remint.d.ts.map