import { LogContext } from '@rocicorp/logger'; import type { MaybePromise } from '../../shared/src/types.ts'; import { type Cookie } from './cookies.ts'; import { LazyStore } from './dag/lazy-store.ts'; import { type Store } from './dag/store.ts'; import { type Hash } from './hash.ts'; import { type PendingMutation } from './pending-mutations.ts'; import { type OnClientsDeleted } from './persist/clients.ts'; import type { Puller } from './puller.ts'; import { type Pusher } from './pusher.ts'; import type { ReplicacheOptions, ZeroOption } from './replicache-options.ts'; import { type SubscribeOptions, type SubscriptionsManager, type WatchCallbackForOptions, type WatchNoIndexCallback, type WatchOptions } from './subscriptions.ts'; import type { ClientID } from './sync/ids.ts'; import type { ReadTransaction } from './transactions.ts'; import type { BeginPullResult, MakeMutators, MutatorDefs, PokeInternal, QueryInternal, RequestOptions, UpdateNeededReason } from './types.ts'; /** @deprecated Not used any more */ export interface MakeSubscriptionsManager { (queryInternal: QueryInternal, lc: LogContext): SubscriptionsManager; } export interface ReplicacheImplOptions { /** * Defaults to true. */ enableMutationRecovery?: boolean | undefined; /** * Defaults to true. */ enableScheduledPersist?: boolean | undefined; /** * Defaults to true. */ enableScheduledRefresh?: boolean | undefined; /** * Defaults to true. */ enablePullAndPushInOpen?: boolean | undefined; /** * @deprecated Not used anymore. */ makeSubscriptionsManager?: unknown; /** * Default is `true`. If `false` if an exact match client group * is not found, a new client group is always made instead of forking * from an existing client group. */ enableClientGroupForking?: boolean | undefined; /** * Callback for when Replicache has deleted clients. */ onClientsDeleted?: OnClientsDeleted | undefined; /** * Internal option used by Zero. * Replicache will call this to and, if zero is enabled, will * invoke various hooks to allow Zero the keep IVM in sync with Replicache's b-trees. */ zero?: ZeroOption | undefined; } export declare class ReplicacheImpl { #private; /** The URL to use when doing a pull request. */ pullURL: string; /** The URL to use when doing a push request. */ pushURL: string; /** The name of the Replicache database. Populated by {@link ReplicacheOptions#name}. */ readonly name: string; /** * Client groups gets disabled when the server does not know about it. * A disabled client group prevents the client from pushing and pulling. */ isClientGroupDisabled: boolean; lastMutationID: number; /** * This is the name Replicache uses for the IndexedDB database where data is * stored. */ get idbName(): string; set auth(auth: string); get auth(): string; /** The schema version of the data understood by this application. */ readonly schemaVersion: string; /** * The mutators that was registered in the constructor. */ readonly mutate: MakeMutators; /** * The duration between each periodic {@link pull}. Setting this to `null` * disables periodic pull completely. Pull will still happen if you call * {@link pull} manually. */ pullInterval: number | null; /** * The delay between when a change is made to Replicache and when Replicache * attempts to push that change. */ pushDelay: number; /** * The function to use to pull data from the server. */ puller: Puller; /** * The function to use to push data to the server. */ pusher: Pusher; readonly memdag: LazyStore; readonly perdag: Store; /** * The options used to control the {@link pull} and push request behavior. This * object is live so changes to it will affect the next pull or push call. */ get requestOptions(): Required; /** * `onSync(true)` is called when Replicache transitions from no push or pull * happening to at least one happening. `onSync(false)` is called in the * opposite case: when Replicache transitions from at least one push or pull * happening to none happening. * * This can be used in a React like app by doing something like the following: * * ```js * const [syncing, setSyncing] = useState(false); * useEffect(() => { * rep.onSync = setSyncing; * }, [rep]); * ``` */ onSync: ((syncing: boolean) => void) | null; /** * `onClientStateNotFound` is called when the persistent client has been * garbage collected. This can happen if the client has no pending mutations * and has not been used for a while. * * The default behavior is to reload the page (using `location.reload()`). Set * this to `null` or provide your own function to prevent the page from * reloading automatically. */ onClientStateNotFound: (() => void) | null; /** * `onUpdateNeeded` is called when a code update is needed. * * A code update can be needed because: * - the server no longer supports the {@link pushVersion}, * {@link pullVersion} or {@link schemaVersion} of the current code. * - a new Replicache client has created a new client group, because its code * has different mutators, indexes, schema version and/or format version * from this Replicache client. This is likely due to the new client having * newer code. A code update is needed to be able to locally sync with this * new Replicache client (i.e. to sync while offline, the clients can still * sync with each other via the server). * * The default behavior is to reload the page (using `location.reload()`). Set * this to `null` or provide your own function to prevent the page from * reloading automatically. You may want to provide your own function to * display a toast to inform the end user there is a new version of your app * available and prompting them to refresh. */ onUpdateNeeded: ((reason: UpdateNeededReason) => void) | null; /** * This gets called when we get an HTTP unauthorized (401) response from the * push or pull endpoint. Set this to a function that will ask your user to * reauthenticate. */ getAuth: (() => MaybePromise) | null | undefined; onPushInvoked: () => undefined; onBeginPull: () => undefined; onRecoverMutations: (r: Promise) => Promise; constructor(options: ReplicacheOptions, implOptions?: ReplicacheImplOptions); /** * The browser profile ID for this browser profile. Every instance of Replicache * browser-profile-wide shares the same profile ID. */ get profileID(): Promise; /** * The client ID for this instance of Replicache. Each instance of Replicache * gets a unique client ID. */ get clientID(): string; /** * The client group ID for this instance of Replicache. Instances of * Replicache will have the same client group ID if and only if they have * the same name, mutators, indexes, schema version, format version, and * browser profile. */ get clientGroupID(): Promise; /** * `onOnlineChange` is called when the {@link online} property changes. See * {@link online} for more details. */ onOnlineChange: ((online: boolean) => void) | null; /** * A rough heuristic for whether the client is currently online. Note that * there is no way to know for certain whether a client is online - the next * request can always fail. This property returns true if the last sync attempt succeeded, * and false otherwise. */ get online(): boolean; /** * Whether the Replicache database has been closed. Once Replicache has been * closed it no longer syncs and you can no longer read or write data out of * it. After it has been closed it is pretty much useless and should not be * used any more. */ get closed(): boolean; /** * Closes this Replicache instance. * * When closed all subscriptions end and no more read or writes are allowed. */ close(): Promise; maybeEndPull(syncHead: Hash, requestID: string): Promise; /** * Push pushes pending changes to the {@link pushURL}. * * You do not usually need to manually call push. If {@link pushDelay} is * non-zero (which it is by default) pushes happen automatically shortly after * mutations. * * If the server endpoint fails push will be continuously retried with an * exponential backoff. * * @param [now=false] If true, push will happen immediately and ignore * {@link pushDelay}, {@link RequestOptions.minDelayMs} as well as the * exponential backoff in case of errors. * @returns A promise that resolves when the next push completes. In case of * errors the first error will reject the returned promise. Subsequent errors * will not be reflected in the promise. */ push({ now }?: { now?: boolean | undefined; }): Promise; /** * Pull pulls changes from the {@link pullURL}. If there are any changes local * changes will get replayed on top of the new server state. * * If the server endpoint fails pull will be continuously retried with an * exponential backoff. * * @param [now=false] If true, pull will happen immediately and ignore * {@link RequestOptions.minDelayMs} as well as the exponential backoff in * case of errors. * @returns A promise that resolves when the next pull completes. In case of * errors the first error will reject the returned promise. Subsequent errors * will not be reflected in the promise. */ pull({ now }?: { now?: boolean | undefined; }): Promise; /** * Applies an update from the server to Replicache. * Throws an error if cookie does not match. In that case the server thinks * this client has a different cookie than it does; the caller should disconnect * from the server and re-register, which transmits the cookie the client actually * has. * * @experimental This method is under development and its semantics will change. */ poke(poke: PokeInternal): Promise; beginPull(): Promise; persist(): Promise; refresh(): Promise; disableClientGroup(): Promise; /** * Subscribe to the result of a {@link query}. The `body` function is * evaluated once and its results are returned via `onData`. * * Thereafter, each time the the result of `body` changes, `onData` is fired * again with the new result. * * `subscribe()` goes to significant effort to avoid extraneous work * re-evaluating subscriptions: * * 1. subscribe tracks the keys that `body` accesses each time it runs. `body` * is only re-evaluated when those keys change. * 2. subscribe only re-fires `onData` in the case that a result changes by * way of the `isEqual` option which defaults to doing a deep JSON value * equality check. * * Because of (1), `body` must be a pure function of the data in Replicache. * `body` must not access anything other than the `tx` parameter passed to it. * * Although subscribe is as efficient as it can be, it is somewhat constrained * by the goal of returning an arbitrary computation of the cache. For even * better performance (but worse dx), see {@link experimentalWatch}. * * If an error occurs in the `body` the `onError` function is called if * present. Otherwise, the error is logged at log level 'error'. * * To cancel the subscription, call the returned function. * * @param body The function to evaluate to get the value to pass into * `onData`. * @param options Options is either a function or an object. If it is a * function it is equivalent to passing it as the `onData` property of an * object. */ subscribe(body: (tx: ReadTransaction) => Promise, options: SubscribeOptions | ((result: R) => void)): () => void; /** * Watches Replicache for changes. * * The `callback` gets called whenever the underlying data changes and the * `key` changes matches the `prefix` of {@link ExperimentalWatchIndexOptions} or * {@link ExperimentalWatchNoIndexOptions} if present. If a change * occurs to the data but the change does not impact the key space the * callback is not called. In other words, the callback is never called with * an empty diff. * * This gets called after commit (a mutation or a rebase). * * @experimental This method is under development and its semantics will * change. */ experimentalWatch(callback: WatchNoIndexCallback): () => void; experimentalWatch(callback: WatchCallbackForOptions, options?: Options): () => void; /** * Query is used for read transactions. It is recommended to use transactions * to ensure you get a consistent view across multiple calls to `get`, `has` * and `scan`. */ query(body: (tx: ReadTransaction) => Promise | R): Promise; /** * The DURABLE last-mutation-IDs of this client's client group, read from * the PERDAG — the companion to `cookie`, and required by any embedder * that supplies its own pokes. * * WHY THIS HAS TO EXIST. A poke's `lastMutationIDChanges` are merged * over the base snapshot's, so naming a client with a value BELOW what * is already durable silently rewrites that client's history in the * memdag. `persist` then refuses to adopt the snapshot — * `mutationIDsAreAtLeast` — because adopting one that under-reports a * SIBLING would let that sibling re-push mutations the authority has * already applied. Refusing is correct, but it is also terminal: the * client's own absorbed mutations are gone from the memdag chain while * the perdag has never seen them, so `rebase` throws `Inconsistent * mutation ID` on every attempt and the client persists nothing again, * forever, while continuing to look healthy. * * An embedder cannot avoid that with per-session bookkeeping: after a * reload its in-memory high-water marks start empty while the dag does * not, and it has no way to learn what a SIBLING tab made durable — * `refresh` is the mechanism for that, and it aborts whenever the * memdag's cookie is ahead, which for an app-driven poke source is * essentially always. So the floor has to be readable, and only the dag * can report it. * * Read the perdag rather than the memdag deliberately: the perdag is * what `persist` compares against, and it is where a sibling's progress * appears. */ get lastMutationIDs(): Promise>; get cookie(): Promise; recoverMutations(): Promise | void; /** * List of pending mutations. The order of this is from oldest to newest. * * Gives a list of local mutations that have `mutationID` > * `syncHead.mutationID` that exists on the main client group. * * @experimental This method is experimental and may change in the future. */ experimentalPendingMutations(): Promise; } //# sourceMappingURL=replicache-impl.d.ts.map