replicache
Version:
Realtime sync for any backend stack
410 lines (398 loc) • 19.2 kB
TypeScript
import { LogLevel, LogSink } from '@rocicorp/logger';
export { LogLevel, LogSink, consoleLogSink } from '@rocicorp/logger';
import { I as IterableUnion, P as Puller, S as StoreProvider, M as MutatorDefs, R as ReplicacheOptions, a as MakeMutators, b as Pusher, c as RequestOptions, U as UpdateNeededReason, d as MaybePromise, e as Poke, f as ReadTransaction, g as SubscribeOptions, W as WatchNoIndexCallback, h as WatchOptions, i as WatchCallbackForOptions, j as PendingMutation } from './chunk-C1TWiB5U.js';
export { $ as AsyncIterableIteratorToArray, ac as ClientGroupID, ad as ClientID, t as ClientStateNotFoundResponse, C as Cookie, am as CreateIndexDefinition, w as CreateKVStore, an as DeepReadonly, ao as DeepReadonlyObject, x as DropKVStore, D as ExperimentalDiff, n as ExperimentalDiffOperation, o as ExperimentalDiffOperationAdd, p as ExperimentalDiffOperationChange, q as ExperimentalDiffOperationDel, r as ExperimentalIndexDiff, N as ExperimentalNoIndexDiff, a9 as ExperimentalWatchIndexCallback, aa as ExperimentalWatchIndexOptions, ab as ExperimentalWatchNoIndexOptions, a0 as GetIndexScanIterator, a1 as GetScanIterator, H as HTTPRequestInfo, u as IndexDefinition, v as IndexDefinitions, s as IndexKey, J as JSONObject, k as JSONValue, y as KVRead, z as KVStore, A as KVWrite, a4 as KeyTypeForScanOptions, at as MakeMutator, ah as MutationV0, ai as MutationV1, au as MutatorReturn, B as PatchOperation, ae as PullRequest, af as PullRequestV0, ag as PullRequestV1, E as PullResponse, F as PullResponseOKV0, G as PullResponseOKV1, K as PullResponseV0, L as PullResponseV1, O as PullerResult, Q as PullerResultV0, T as PullerResultV1, X as PushError, aj as PushRequest, ak as PushRequestV0, al as PushRequestV1, Y as PushResponse, Z as PusherResult, l as ReadonlyJSONObject, m as ReadonlyJSONValue, a5 as ScanIndexOptions, a6 as ScanNoIndexOptions, a7 as ScanOptionIndexedStartKey, a8 as ScanOptions, a2 as ScanResult, ap as TransactionEnvironment, aq as TransactionLocation, ar as TransactionReason, V as VersionNotSupportedResponse, as as WriteTransaction, a3 as isScanIndexOptions, _ as makeScanResult } from './chunk-C1TWiB5U.js';
/**
* Filters an async iterable.
*
* This utility function is provided because it is useful when using
* {@link makeScanResult}. It can be used to filter out tombstones (delete entries)
* for example.
*/
declare function filterAsyncIterable<V>(iter: IterableUnion<V>, predicate: (v: V) => boolean): AsyncIterable<V>;
/**
* This creates a default puller which uses HTTP POST to send the pull request.
*/
declare function getDefaultPuller(rep: {
pullURL: string;
auth: string;
}): Puller;
/**
* This {@link Error} is thrown when we detect that the IndexedDB has been
* removed. This does not normally happen but can happen during development if
* the user has DevTools open and deletes the IndexedDB from there.
*/
declare class IDBNotFoundError extends Error {
name: string;
}
/**
* Merges an iterable on to another iterable.
*
* The two iterables need to be ordered and the `compare` function is used to
* compare two different elements.
*
* If two elements are equal (`compare` returns `0`) then the element from the
* second iterable is picked.
*
* This utility function is provided because it is useful when using
* {@link makeScanResult}. It can be used to merge an in memory pending async
* iterable on to a persistent async iterable for example.
*/
declare function mergeAsyncIterables<A, B>(iterableBase: IterableUnion<A>, iterableOverlay: IterableUnion<B>, compare: (a: A, b: B) => number): AsyncIterable<A | B>;
/**
* Options for `dropDatabase` and `dropAllDatabases`.
*/
type DropDatabaseOptions = {
/**
* Allows providing a custom implementation of the underlying storage layer.
* Default is `'idb'`.
*/
kvStore?: 'idb' | 'mem' | StoreProvider | undefined;
/**
* Determines how much logging to do. When this is set to `'debug'`,
* Replicache will also log `'info'` and `'error'` messages. When set to
* `'info'` we log `'info'` and `'error'` but not `'debug'`. When set to
* `'error'` we only log `'error'` messages.
* Default is `'info'`.
*/
logLevel?: LogLevel | undefined;
/**
* Enables custom handling of logs.
*
* By default logs are logged to the console. If you would like logs to be
* sent elsewhere (e.g. to a cloud logging service like DataDog) you can
* provide an array of {@link LogSink}s. Logs at or above
* {@link DropDatabaseOptions.logLevel} are sent to each of these {@link LogSink}s.
* If you would still like logs to go to the console, include
* `consoleLogSink` in the array.
*
* ```ts
* logSinks: [consoleLogSink, myCloudLogSink],
* ```
* Default is `[consoleLogSink]`.
*/
logSinks?: LogSink[] | undefined;
};
/**
* Deletes a single Replicache database.
* @param dbName
* @param createKVStore
*/
declare function dropDatabase(dbName: string, opts?: DropDatabaseOptions | undefined): Promise<void>;
/**
* Deletes all IndexedDB data associated with Replicache.
*
* Returns an object with the names of the successfully dropped databases
* and any errors encountered while dropping.
*/
declare function dropAllDatabases(opts?: DropDatabaseOptions | undefined): Promise<{
dropped: string[];
errors: unknown[];
}>;
/**
* Deletes all IndexedDB data associated with Replicache.
*
* Returns an object with the names of the successfully dropped databases
* and any errors encountered while dropping.
*
* @deprecated Use `dropAllDatabases` instead.
*/
declare function deleteAllReplicacheData(opts?: DropDatabaseOptions | undefined): Promise<{
dropped: string[];
errors: unknown[];
}>;
/**
* This error is thrown when you try to call methods on a closed transaction.
*/
declare class TransactionClosedError extends Error {
constructor();
}
/**
* Returns the name of the IDB database that will be used for a particular Replicache instance.
* @param name The name of the Replicache instance (i.e., the `name` field of `ReplicacheOptions`).
* @param schemaVersion The schema version of the database (i.e., the `schemaVersion` field of `ReplicacheOptions`).
* @returns
*/
declare function makeIDBName(name: string, schemaVersion?: string): string;
declare class Replicache<MD extends MutatorDefs = {}> {
#private;
constructor(options: ReplicacheOptions<MD>);
/** The URL to use when doing a pull request. */
get pullURL(): string;
set pullURL(value: string);
/** The URL to use when doing a push request. */
get pushURL(): string;
set pushURL(value: string);
/** The authorization token used when doing a push request. */
get auth(): string;
set auth(value: string);
/** The name of the Replicache database. Populated by {@link ReplicacheOptions#name}. */
get name(): string;
/**
* This is the name Replicache uses for the IndexedDB database where data is
* stored.
*/
get idbName(): string;
/** The schema version of the data understood by this application. */
get schemaVersion(): string;
/**
* The mutators that was registered in the constructor.
*/
get mutate(): MakeMutators<MD>;
/**
* 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.
*/
get pullInterval(): number | null;
set pullInterval(value: number | null);
/**
* The delay between when a change is made to Replicache and when Replicache
* attempts to push that change.
*/
get pushDelay(): number;
set pushDelay(value: number);
/**
* The function to use to pull data from the server.
*/
get puller(): Puller;
set puller(value: Puller);
/**
* The function to use to push data to the server.
*/
get pusher(): Pusher;
set pusher(value: Pusher);
/**
* 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<RequestOptions>;
/**
* `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]);
* ```
*/
get onSync(): ((syncing: boolean) => void) | null;
set onSync(value: ((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.
*/
get onClientStateNotFound(): (() => void) | null;
set onClientStateNotFound(value: (() => 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 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.
*/
get onUpdateNeeded(): ((reason: UpdateNeededReason) => void) | null;
set onUpdateNeeded(value: ((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.
*/
get getAuth(): (() => MaybePromise<string | null | undefined>) | null | undefined;
set getAuth(value: (() => MaybePromise<string | null | undefined>) | null | undefined);
/**
* The browser profile ID for this browser profile. Every instance of Replicache
* browser-profile-wide shares the same profile ID.
*/
get profileID(): Promise<string>;
/**
* 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<string>;
/**
* `onOnlineChange` is called when the {@link online} property changes. See
* {@link online} for more details.
*/
get onOnlineChange(): ((online: boolean) => void) | null;
set onOnlineChange(value: ((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<void>;
/**
* 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<void>;
/**
* 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<void>;
/**
* 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: Poke): Promise<void>;
/**
* 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<R>(body: (tx: ReadTransaction) => Promise<R>, options: SubscribeOptions<R> | ((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<Options extends WatchOptions>(callback: WatchCallbackForOptions<Options>, 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<R>(body: (tx: ReadTransaction) => Promise<R> | R): Promise<R>;
/**
* 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<readonly PendingMutation[]>;
}
/**
* This error is thrown when the puller fails for any reason.
*/
declare class PullError extends Error {
name: string;
causedBy?: Error | undefined;
constructor(causedBy?: Error);
}
/** @deprecated */
declare const TEST_LICENSE_KEY = "This key only good for automated testing";
/**
* The current version of Replicache.
*/
declare const version: string;
export { type DropDatabaseOptions, WatchCallbackForOptions as ExperimentalWatchCallbackForOptions, WatchNoIndexCallback as ExperimentalWatchNoIndexCallback, WatchOptions as ExperimentalWatchOptions, IDBNotFoundError, IterableUnion, StoreProvider as KVStoreProvider, MakeMutators, MaybePromise, MutatorDefs, PendingMutation, Poke, PullError, Puller, Pusher, ReadTransaction, Replicache, ReplicacheOptions, RequestOptions, SubscribeOptions, TEST_LICENSE_KEY, TransactionClosedError, UpdateNeededReason, deleteAllReplicacheData, dropAllDatabases, dropDatabase, filterAsyncIterable, getDefaultPuller, makeIDBName, mergeAsyncIterables, version };