@dittolive/ditto
Version:
Ditto is a cross-platform SDK that allows apps to sync with and even without internet connectivity.
1,383 lines (1,358 loc) • 216 kB
TypeScript
/** @internal */
declare class KeepAlive {
/** @internal */
get isActive(): boolean;
/** @internal */
constructor();
/** @internal */
retain(id: string): void;
/** @internal */
release(id: string): void;
/** @internal */
currentIDs(): string[];
/** @internal */
countForID(id: string): number | null;
private static finalizationRegistry;
private intervalID;
private countsByID;
}
/** @internal */
type ObserverToken = string;
/** @internal */
type ObserverManagerConstructorOptions = {
keepAlive?: KeepAlive;
register?: (callback: (...args: any[]) => void) => void;
unregister?: () => void;
process?: (...args: any[]) => any[];
};
/** @internal */
declare class ObserverManager {
/** @internal */
readonly id: string;
/** @internal */
readonly keepAlive: KeepAlive | null;
/** @internal */
constructor(id: string, options?: ObserverManagerConstructorOptions);
/** @internal */
addObserver(callback: any): ObserverToken;
/** @internal */
removeObserver(token: ObserverToken): void;
hasObserver(token: ObserverToken): boolean;
/** @internal */
notify(...args: any[]): void;
/** @internal */
close(): void;
/**
* Can be injected and replaced via constructor options.
*
* @abstract
*/
protected register(callback: (...args: any[]) => void): void;
/**
* Can be injected and replaced via constructor options.
*
* @abstract
*/
protected unregister(): void;
/**
* Can be injected and replaced via constructor options.
*
* @abstract
*/
protected process(...args: any[]): any[];
private isClosed;
private isRegistered;
private callbacksByToken;
private constructorOptions;
private hasObservers;
private registerIfNeeded;
private unregisterIfNeeded;
}
/** @internal */
interface ObserverManaging {
hasObserver(token: ObserverToken): boolean;
removeObserver(token: ObserverToken): void;
}
/** @internal */
type ObserverOptions = {
stopsWhenFinalized?: boolean;
};
/**
* Generic observer handle returned by various observation APIs. The observation
* remains active until the {@link stop | stop()} method is called explicitly or
* the observer instance is garbage collected. Therefore, to keep the observation
* alive, you have to keep a reference to the corresponding observer.
*/
declare class Observer {
/** @internal */
readonly observerManager: ObserverManaging;
/** @internal */
get token(): ObserverToken | undefined;
/** @internal */
readonly options?: ObserverOptions;
/** @internal */
constructor(observerManager: ObserverManaging, token: any, options?: ObserverOptions);
/**
* Returns `true` if the observer has been explicitly stopped via the `stop()`
* method. Otherwise returns `false`.
*/
get isStopped(): boolean;
/**
* Stops the observation. Calling this method multiple times has no effect.
*/
stop(): void;
private static finalizationRegistry;
private _token?;
private static finalize;
}
/**
* Error codes for FFI result.
*
* This should include all variants of `FfiError` in `ffi/src/result/error.rs`.
*
* @internal
*/
type FFIResultErrorCode = 'ActivationLicenseTokenExpired' | 'ActivationLicenseTokenInvalid' | 'ActivationLicenseUnsupportedFutureVersion' | 'ActivationNotActivated' | 'ActivationUnnecessary' | 'Base64Invalid' | 'CborInvalid' | 'CborUnsupported' | 'Crdt' | 'DifferIdentityKeyPathInvalid' | 'DqlEvaluationError' | 'DqlInvalidQueryArgs' | 'DqlQueryCompilation' | 'DqlUnsupported' | 'IoAlreadyExists' | 'IoNotFound' | 'IoOperationFailed' | 'IoPermissionDenied' | 'JsFloatingStoreOperation' | 'LockedDittoWorkingDirectory' | 'EncryptionExtraneousPassphraseGiven' | 'ParameterQuery' | 'StoreDatabase' | 'StoreDocumentId' | 'StoreDocumentNotFound' | 'StoreTransactionReadOnly' | 'StoreQuery' | 'Transport' | 'Unknown' | 'Unsupported' | 'ValidationDepthLimitExceeded' | 'ValidationInvalidCbor' | 'ValidationInvalidJson' | 'ValidationNotAMap' | 'ValidationInvalidTransportConfig' | 'ValidationSizeLimitExceeded';
/**
* Represents an exception that occurred during a call into the Ditto FFI.
*
* Use the {@link throwOnErrorStatus | throwOnErrorStatus()} helper to
* automatically throw this error when an FFI call returns with a non-zero
* return value.
*
* @internal
*/
declare class DittoFFIError extends Error {
/**
* The code identifying this error.
*
* May be a numerical status code returned by an FFI call or an
* {@link FFIResultErrorCode} for errors returned on FFI result objects.
*
* @see {@link throwOnErrorStatus | throwOnErrorStatus()}
*/
readonly code: number | FFIResultErrorCode;
/**
* Only call this constructor after having called `FFI.ensureInitialized()`
* and `FFI.trace()`.
*
* @param code numerical status code returned by an FFI call or an
* {@link FFIResultErrorCode} for errors returned on FFI result objects
* @param messageOverride overrides the thread-local error message set in
* Ditto core
* @param messageFallback fallback message to use if the thread-local error
* message is empty
*/
constructor(code: number | FFIResultErrorCode, messageOverride?: string, messageFallback?: string);
}
/** @internal */
type Pointer<Type> = {
type: Type;
addr: string;
};
/** @internal */
declare const DittoCRDTTypeKey = "_ditto_internal_type_jkb12973t4b";
/** @internal */
type FFIAuthenticationStatus = 'dittoffi_authentication_status_t';
/** @internal */
type FFIQueryResultItem = 'dittoffi_query_result_item_t';
/** @internal */
type FFIQueryResult = 'dittoffi_query_result_t';
/** @internal */
type FFIDiffer = 'dittoffi_differ_t';
/** @internal */
type FFIWriteTransaction = 'CWriteTransaction_t';
/** @internal */
type FFIDitto = 'CDitto_t';
/** @internal */
type OrderBy = {
query: string;
direction: 'Ascending' | 'Descending';
};
/** @internal */
type PathAccessorType = 'String' | 'Number' | 'Int' | 'UInt' | 'Float' | 'Double' | 'Bool' | 'Null' | 'Object' | 'Array' | 'Any' | 'Counter' | 'Register' | 'Attachment' | 'Rga' | 'RWMap';
/** @internal */
declare enum DittoCRDTType {
counter = 0,
register = 1,
attachment = 2,
rga = 3,
rwMap = 4
}
/** Various options to pass the web assembly module to Ditto. */
type WebAssemblyModule = RequestInfo | URL | Response | BufferSource | WebAssembly.Module | string | null;
/** @internal */
type UntypedAttachmentToken = {
id: string;
len: number | BigInt;
metadata: AttachmentMetadata;
};
/** @internal */
type TypedAttachmentToken = {
[DittoCRDTTypeKey]?: DittoCRDTType.attachment;
_id: Uint8Array;
_len: number | BigInt;
_meta: AttachmentMetadata;
};
/**
* Serves as a token for a specific attachment that you can pass to a call to
* {@link Store.fetchAttachment | ditto.store.fetchAttachment()}.
*/
declare class AttachmentToken {
/** The attachment's ID. */
readonly id: string;
/** The attachment's size given as number of bytes. */
readonly len: number | BigInt;
/** The attachment's metadata. */
readonly metadata: AttachmentMetadata;
/** @internal */
constructor(jsObj: UntypedAttachmentToken | TypedAttachmentToken);
/** @internal */
readonly idBytes: Uint8Array;
/**
* Validate an input value that has a field `[FFI.DittoCRDTTypeKey]` and
* return its contents.
*
* @throws {Error} If the input is invalid.
* @returns {object} binary id, len and metadata of the attachment token
*/
private static validateTypedInput;
/**
* Validate an untyped input value and return its contents.
*
* Converts _unpadded_ base64-encoded ID in input to _padded_ base64-encoded
* ID before returning it as `Uint8Array`.
*
* @throws {@link DittoError} `store/attachment-token-invalid` If the input id
* is not a valid base64 string.
* @returns {object} binary id, len and metadata of the attachment token
*/
private static validateUntypedInput;
}
/**
* The types of attachment fetch events that can be delivered to an attachment
* fetcher's `callback`.
*/
type AttachmentFetchEventType = 'Completed' | 'Progress' | 'Deleted';
/**
* An attachment fetch event used when the attachment's download has completed.
*/
type AttachmentFetchEventCompleted = {
type: 'Completed';
attachment: Attachment;
};
/**
* An attachment fetch event used when the attachment's download progressed but
* is not yet complete.
*/
type AttachmentFetchEventProgress = {
type: 'Progress';
totalBytes: number | BigInt;
downloadedBytes: number | BigInt;
};
/**
* An attachment fetch event used when the attachment is deleted.
*/
type AttachmentFetchEventDeleted = {
type: 'Deleted';
};
/**
* A representation of the events that can occur in relation to an attachment
* fetch.
*
* There are three different attachment fetch events: `Completed`, `Progress`,
* or `Deleted`.
*
* There will be at most one `Completed` or `Deleted` event per attachment
* fetch. There can be many `Progress` events delivered for each attachment
* fetch.
*
* Updates relating to an attachment fetch are delivered by registering an
* {@link AttachmentFetcher} through a call to
* {@link Store["fetchAttachment"] | ditto.store.fetchAttachment()}.
*/
type AttachmentFetchEvent = AttachmentFetchEventCompleted | AttachmentFetchEventProgress | AttachmentFetchEventDeleted;
/**
* Manages attachment fetchers to make sure we free all resources when the
* fetcher is garbage collected and to allow us to wait for freeing of
* ressources to be finished before the ditto instance is closed.
*
* @internal
*/
declare class AttachmentFetcherManager {
readonly ditto: Ditto;
/** @internal */
constructor(ditto: Ditto);
/**
* Start an attachment fetcher.
*
* @internal */
startAttachmentFetcher(token: AttachmentToken, eventHandler?: (attachmentFetchEvent: AttachmentFetchEvent) => void): AttachmentFetcher;
/**
* Stop an attachment fetcher and wait for it to be stopped.
*
* @internal */
stopAttachmentFetcher(attachmentFetcher: AttachmentFetcher): Promise<void>;
/**
* Closing the manager will cancel all attachment fetchers.
*
* @internal
*/
close(): void;
private contextInfoByID;
private finalizationRegistry;
/**
* Stop the attachment fetcher without unregistering it from the finalization
* registry.
*/
private stopWithContextInfo;
}
/**
* These objects are returned by calls to
* {@link Store.fetchAttachment | ditto.store.fetchAttachment()}
* and allow you to stop an in-flight attachment fetch.
*/
declare class AttachmentFetcher implements PromiseLike<Attachment | null> {
/**
* Returns a promise for the attachment that you can `await`.
*
* The promise is rejected if an error occurs during the fetch. Note that the
* `AttachmentFetcher` itself implements `PromiseLike`, so you can `await` it
* directly.
*
* If this attachment fetcher has been initiated through {@link
* Collection.fetchAttachment | `Collection.fetchAttachment()`}, the promise
* resolves to `null` if the attachment could not be found instead of being
* rejected.
*/
readonly attachment: Promise<Attachment | null>;
/**
* Stops fetching the associated attachment and cleans up any associated
* resources.
*
* Note that you are not required to call `stop()` once your attachment fetch
* operation has finished. The method primarily exists to allow you to cancel
* an attachment fetch request while it is ongoing if you no longer wish for
* the attachment to be made available locally to the device.
*/
stop(): void;
/** @internal */
readonly cancelTokenPromise: Promise<number | BigInt | null> | null;
/** @internal */
readonly ditto: Ditto;
/** @internal */
readonly id: string;
/**
* Defined when the fetcher was started from `Collection.fetchAttachment()`.
* Otherwise, the fetcher was started from `Store.fetchAttachment()`.
*
* @internal
*/
readonly manager?: AttachmentFetcherManager;
/** @internal */
readonly token: AttachmentToken;
/** @internal */
then<TResult1 = any, TResult2 = never>(onfulfilled?: ((value: any) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): PromiseLike<TResult1 | TResult2>;
/** @internal */
constructor(ditto: Ditto, token: AttachmentToken, manager?: AttachmentFetcherManager, eventHandler?: (attachmentFetchEvent: AttachmentFetchEvent) => void);
/**
* `true` if the fetcher has completed or was stopped.
*
* @internal
*/
get isStopped(): boolean;
/**
* This function is defined while a fetch is in progress and is used to reject
* the promise `this.attachment` when the fetch is canceled.
*
* @internal
*/
private rejectPendingFetch;
}
/** Represents a unique identifier for a {@link Document}. */
type DocumentIDValue = any;
/** Represents a unique identifier for a {@link Document}. */
declare class DocumentID {
/**
* Returns the value of the receiver, lazily decoded from its CBOR
* representation if needed.
*/
get value(): any;
/**
* Returns `false` if validation has been skipped at construction time,
* otherwise returns `true`. This is mostly for internal use only, you
* shouldn't need this in client code.
*/
readonly isValidated: boolean;
/**
* Creates a new `DocumentID`.
*
* A document ID can be created from any of the following:
*
* - `string`
* - `number` (integer)
* - `boolean`
* - `null`
* - raw data in the form of a JS [Typed Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays)
* - `Array` (containing any of the items in this list)
* - Map (a raw JS `object`, where the keys must be strings and the values
* can be made up of any of the items in this list)
*
* Note that you cannot use floats or other custom types to create a document
* ID.
*
* Document IDs are also limited in size, based on their serialized
* representation, to 256 bytes. You will receive an error if you try to
* create a document ID that exceeds the size limit.
*
* @param value The value that represents the document identifier.
* @param skipCBOREncoding If `true, skips CBOR encoding and assumes
* the passed in `value` is already CBOR encoded. You shouldn't need to ever
* pass this parameter, it's only used internally for certain edge cases.
* @param skipValidation If `true, skips validation of the passed in value or
* CBOR. You shouldn't need to ever pass this parameter, it's only used
* internally for certain edge cases.
*/
constructor(value: any, skipCBOREncoding?: boolean, skipValidation?: boolean);
/**
* Returns `true` if passed in `documentID` is equal to the receiver,
* otherwise returns `false`.
*/
equals(documentID: DocumentID): boolean;
/**
* Returns a string representation of the receiver.
*
* If you need a string representation to be used directly in a query,
* please use `toQueryCompatibleString()` instead.
*/
toString(): string;
/**
* Returns the base64-encoded CBOR representation of this document ID.
*
* @deprecated
*/
toBase64String(): string;
/**
* Returns a query compatible string representation of the receiver.
*
* The returned string can be used directly in queries that you use with other
* Ditto functions. For example you could create a query that was like this:
*
* ``` TypeScript
* collection.find(`_id == ${documentID.toQueryCompatibleString()}`)
* ```
*
* @deprecated use document IDs in queries by embedding them in the query
* arguments parameter.
*/
toQueryCompatibleString(): string;
/** @internal */
toCBOR(): Uint8Array;
}
/** @internal */
declare function validateDocumentIDValue(id: DocumentIDValue): DocumentIDValue;
/** @internal */
declare function validateDocumentIDCBOR(idCBOR: Uint8Array): Uint8Array;
/** @internal */
type SubscriptionContextInfo = {
id: string;
collectionName: string;
query: string;
queryArgsCBOR: Uint8Array | null;
orderBys: OrderBy[];
limit: number;
offset: number;
};
/**
* Tracks `Subscription` instances in order to remove them when Ditto is
* closed.
*
* @internal
*/
declare class SubscriptionManager {
/** @internal */
constructor(ditto: Ditto);
/**
* Begin tracking a subscription instance and start it.
*
* @internal
*/
add(subscription: Subscription): void;
/**
* Stop tracking a subscription instance and cancel it.
*
* @internal
*/
remove(subscription: Subscription): void;
/**
* Stop tracking all subscriptions and cancel them.
*
* @internal
*/
close(): void;
private ditto;
private subscriptions;
private finalizationRegistry;
/**
* Remove tracked subscription without unregistering from finalization
* registry.
*
* @internal
*/
private removeWithContextInfo;
}
/**
* Used to subscribe to receive updates from remote peers about matching
* documents.
*
* While {@link Subscription} objects remain in scope they ensure that
* documents in the collection specified and that match the query provided will
* try to be kept up-to-date with the latest changes from remote peers.
*
* This class is used by Ditto's query builder APIs.
* @see {@link SyncSubscription} for the DQL equivalent.
*
* Not available in React Native environments.
*/
declare class Subscription {
/**
* The query that the subscription is based on.
*/
readonly query: string;
/**
* Returns `true` if subscription has been explicitly cancelled, `false`
* otherwise.
*/
get isCancelled(): boolean;
/**
* The name of the collection that the subscription is based on.
*/
get collectionName(): string;
/**
* Cancels a subscription and releases all associated resources.
*/
cancel(): void;
/** @internal */
constructor(collection: Collection, query: string, queryArgsCBOR: Uint8Array | null, orderBys: OrderBy[], limit: number, offset: number);
/**
* The collection this subscription belongs to.
* @internal Because not exposed in any of the other SDKs (yet?).
*/
readonly collection: Collection;
/**
* The corresponding named arguments for {@link query}, if any.
* @internal Because not exposed in any of the other SDKs (yet?).
*/
readonly queryArgsCBOR: Uint8Array | null;
/** @internal */
readonly contextInfo: SubscriptionContextInfo;
private readonly manager;
private _isCancelled;
}
/** @internal */
declare class LiveQueryManager {
readonly ditto: Ditto;
readonly keepAlive: KeepAlive;
/** @internal */
constructor(ditto: Ditto, keepAlive: KeepAlive);
/** @internal */
startLiveQuery(liveQuery: LiveQuery): void;
/** @internal */
stopLiveQuery(liveQuery: LiveQuery): void;
/** @internal */
close(): void;
private liveQueriesByID;
private finalizationRegistry;
private stopLiveQueryWithID;
private finalize;
}
/**
* The type that is returned when calling
* {@link PendingCursorOperation.observeLocal | observeLocal()} on a
* {@link PendingCursorOperation} object. It handles the logic for calling the
* event handler that is provided to `observeLocal()` calls.
*
* Ditto will prevent the process from exiting as long as there are active live
* queries (not relevant when running in the browser).
*
* `LiveQuery` objects must be kept in scope for as long as you wish to have
* your event handler be called when there is an update to a document matching
* the query you provide. When you no longer want to receive updates about
* documents matching a query then you must call {@link stop | stop()}.
*
* Not available in React Native environments.
*/
declare class LiveQuery {
/** The query that the live query is based on. */
readonly query: string;
/** The arguments belonging to {@link query}. */
readonly queryArgs: QueryArguments | null;
/** The name of the collection that the live query is based on. */
get collectionName(): string;
/** Returns true if the receiver has been stopped. */
get isStopped(): boolean;
/**
* Stop the live query from delivering updates.
*
* @throws {Error} when called in a React Native environment.
*/
stop(): void;
/** @internal */
orderBys: OrderBy[];
/** @internal */
queryArgsCBOR: Uint8Array | null;
/** @internal */
readonly limit: number;
/** @internal */
readonly offset: number;
/** @internal */
readonly collection: Collection;
/** @internal */
readonly handler: QueryObservationHandler;
/**
* This field is only populated while a live query is active and set to null
* when the live query is stopped.
*
* @internal
*/
liveQueryManager: LiveQueryManager | null;
get liveQueryID(): number;
/** @internal */
constructor(query: string, queryArgs: QueryArguments | null, queryArgsCBOR: Uint8Array | null, orderBys: OrderBy[], limit: number, offset: number, collection: Collection, handler: QueryObservationHandler);
private _liveQueryID;
}
/**
* Represents a CRDT counter that can be upserted as part of a document or
* assigned to a property during an update of a document.
*
* Not available in React Native environments.
*/
declare class Counter {
/** The value of the counter. */
get value(): number;
/**
* Creates a new counter that can be used as part of a document's content.
*/
constructor();
/** @internal */
static '@ditto.create'(mutDoc: any, path: any, value: any): any;
protected mutDoc: any;
protected path: any;
protected _value: number;
}
/**
* Represents a mutable CRDT counter that can be incremented by a specific
* amount while updating a document.
*
* This class can't be instantiated directly, it's returned automatically for
* any counter property within an update block via {@link MutableDocumentPath.counter}.
*/
declare class MutableCounter extends Counter {
/**
* Increments the counter by `amount`, which can be any valid number.
*
* Only valid within the `update` closure of
* {@link PendingCursorOperation.update | PendingCursorOperation.update()} and
* {@link PendingIDSpecificOperation.update | PendingIDSpecificOperation.update()},
* otherwise an exception is thrown.
*
* @throws {Error} when called in a React Native environment.
*/
increment(amount: number): void;
/** @internal */
protected constructor();
}
/**
* Represents a CRDT register that can be upserted as part of a document or
* assigned to a property during an update of a document.
*
* Not available in React Native environments.
*/
declare class Register {
/** Returns the value of the register. */
get value(): any;
/**
* Creates a new Register that can be used as part of a document's content.
*/
constructor(value: any);
/** @internal */
static '@ditto.create'(mutableDocument: any, path: any, value: any): any;
/** @internal */
protected '@ditto.mutableDocument': any;
/** @internal */
protected '@ditto.path': any;
/** @internal */
protected '@ditto.value': any;
}
/**
* Represents a mutable CRDT register that can be set to a specific value when
* updating a document.
*
* This class can't be instantiated directly, it's returned automatically for
* any register property of a document within an update block via
* {@link MutableDocumentPath.register}.
*
* Not available in React Native environments.
*/
declare class MutableRegister extends Register {
/**
* Returns the value of the register.
*
* Not available in React Native environments.
*/
get value(): any;
/**
* Convenience setter, equivalent to {@link set | set()}.
*
* Not available in React Native environments.
*/
set value(value: any);
/**
* Sets the register to the provided value.
*
* Only valid within the `update` closure of
* {@link PendingCursorOperation.update | PendingCursorOperation.update()} and
* {@link PendingIDSpecificOperation.update | PendingIDSpecificOperation.update()},
* otherwise an exception is thrown.
*
* Not available in React Native environments.
*/
set(value: any): void;
/** @internal */
constructor(value: any);
}
/**
* Represents a portion of the document at a specific key-path.
*
* Provides an interface to specify a path to a key in a document that you can
* then call a function on to get the value at the specified key as a specific
* type. You don't create a `DocumentPath` directly but obtain one via the
* {@link Document.path | path} property or the {@link Document.at | at()}
* method of {@link Document}.
*
* Not available in React Native environments.
*/
declare class DocumentPath {
/** The document this path belongs to. */
readonly document: Document;
/** The full document path so far. */
readonly path: string;
/**
* Returns a new document path instance with the passed in key-path or
* index appended.
*
* A key-path can be a single property name or multiple property names
* separated by a dot. Indexes can also be specified as part of the key
* path using the square bracket syntax. The empty string returns a document
* path representing the same portion of the document as the receiver. If a
* key-path starts with a property name and is prefixed by a dot, the dot is
* ignored.
*
* Examples:
*
* - `documentPath.at('mileage')`
* - `documentPath.at('driver.name')`
* - `documentPath.at('passengers[2]')`
* - `documentPath.at('passengers[2].belongings[1].kind')`
* - `documentPath.at('.mileage')`
*
* @throws {Error} when called in a React Native environment.
*/
at(keyPathOrIndex: string | number): DocumentPath;
/**
* Traverses the document with the key-path represented by the receiver and
* returns the corresponding object or value.
*
* @throws {Error} when called in a React Native environment.
*/
get value(): any | undefined;
/**
* Returns the value at the previously specified key in the document as a
* {@link Counter} if possible, otherwise returns `null`.
*
* @throws {Error} when called in a React Native environment.
*/
get counter(): Counter | null;
/**
* Returns the value at the previously specified key in the document as a
* {@link Register} if possible, otherwise returns `null`.
*
* @throws {Error} when called in a React Native environment.
*/
get register(): Register | null;
/**
* Returns the value at the previously specified key in the document as an
* {@link AttachmentToken} if possible, otherwise returns `null`.
*
* @throws {Error} when called in a React Native environment.
*/
get attachmentToken(): AttachmentToken | null;
/** @internal */
constructor(document: Document, path: string, validate: boolean);
/** @internal */
underlyingValueForPathType(pathType: PathAccessorType): any | undefined;
}
/**
* Mutable version of {@link DocumentPath} allowing you to mutate a document at
* a specific key-path. You don't create a `MutableDocumentPath` directly but
* obtain one via the {@link MutableDocument.path | path} property or the
* {@link MutableDocument.at | at()} method of {@link MutableDocument}.
*
* Not available in React Native environments.
*/
declare class MutableDocumentPath {
/** The (mutable) document this path belongs to. */
readonly mutableDocument: MutableDocument;
/** The full document path so far. */
readonly path: string;
/**
* Returns a new mutable document path instance with the passed in key-path or
* index appended.
*
* A key-path can be a single property name or multiple property names
* separated by a dot. Indexes can also be specified as part of the key
* path using square brackets syntax. The empty string returns a document path
* representing the same portion of the document as the receiver. If a key
* path starts with a property name and is prefixed by a dot, the dot is
* ignored.
*
* Examples:
*
* - `mutableDocumentPath.at('mileage')`
* - `mutableDocumentPath.at('driver.name')`
* - `mutableDocumentPath.at('passengers[2]')`
* - `mutableDocumentPath.at('passengers[2].belongings[1].kind')`
* - `mutableDocumentPath.at('.mileage')`
*
* @throws {Error} when called in a React Native environment.
*/
at(keyPathOrIndex: string | number): MutableDocumentPath;
/**
* Traverses the document with the key-path represented by the receiver and
* returns the corresponding object or value.
*
* @throws {Error} when called in a React Native environment.
*/
get value(): any | undefined;
/**
* Returns the value at the previously specified key in the document as a
* {@link MutableCounter} if possible, otherwise returns `null`.
*
* @throws {Error} when called in a React Native environment.
*/
get counter(): MutableCounter | null;
/**
* Returns the value at the previously specified key in the document as a
* {@link MutableRegister} if possible, otherwise returns `null`.
*
* @throws {Error} when called in a React Native environment.
*/
get register(): MutableRegister | null;
/**
* Returns the value at the previously specified key in the document as a
* {@link AttachmentToken} if possible, otherwise returns `null`.
*
* @throws {Error} when called in a React Native environment.
*/
get attachmentToken(): AttachmentToken | null;
/**
* Sets a value at the document's key-path defined by the receiver.
*
* @param isDefault Represents whether or not the value should be set as a
* default value. Set this to `true` if you want to set a default value that
* you expect to be overwritten by other devices in the network. The default
* value is `false`.
*
* @throws {Error} when called in a React Native environment.
*/
set(value: any, isDefault?: boolean): void;
/**
* Removes a value at the document's key-path defined by the receiver.
*
* @throws {Error} when called in a React Native environment.
*/
remove(): void;
/** @internal */
constructor(mutableDocument: MutableDocument, path: string, validate: boolean);
/** @internal */
underlyingValueForPathType(pathType: PathAccessorType): any | null;
/** @internal */
'@ditto.increment'(amount: number): void;
/** @internal */
'@ditto.set'(value: any, isDefault?: boolean): void;
/** @internal */
'@ditto.remove'(): void;
/** @private */
private updateInMemory;
/** @private */
private recordUpdateResult;
}
/**
* The types of an {@link UpdateResult}.
*/
type UpdateResultType = 'set' | 'incremented' | 'removed';
/**
* Provides information about a successful update operation on a document.
*
* The update result can be one of the following types:
* - `set`
* - `removed`
* - `incremented`
*
* Not available in React Native environments.
*/
declare class UpdateResult {
/** The update result's type. */
readonly type: UpdateResultType;
/** The ID of the document that was updated. */
readonly docID: DocumentID;
/** The path to the key in the document that was updated. */
readonly path: string;
/**
* The associated value for `set` operations. The value will be the new value
* at the key path.
*
* All other types of update results do not have this property set.
*/
readonly value?: any;
/** The associated amount, only set if {@link type} is `incremented`. */
readonly amount?: number;
/** @internal */
static set(docID: DocumentID, path: string, value?: any): UpdateResult;
/** @internal */
static incremented(docID: DocumentID, path: string, amount: number): UpdateResult;
/** @internal */
static removed(docID: DocumentID, path: string): UpdateResult;
/** @internal */
private constructor();
}
declare const CUSTOM_INSPECT_SYMBOL$1: unique symbol;
/**
* A document value is a JavaScript object containing values for keys that can
* be serialized via CBOR.
*
* This value must not contain any non-finite numbers (`NaN`, `Infinity`,
* `-Infinity`).
*/
type DocumentValue = Record<string, any>;
/**
* A document belonging to a {@link Collection} with an inner value.
*
* Not available in React Native environments.
*/
declare class Document {
/**
* Returns a hash that represents the passed in document(s).
*
* @throws {Error} when called in a React Native environment.
*/
static hash(documentOrMany: Document | Document[]): BigInt;
/**
* Returns a pattern of words that together create a mnemonic, which
* represents the passed in document(s).
*
* @throws {Error} when called in a React Native environment.
*/
static hashMnemonic(documentOrMany: Document | Document[]): string;
/**
* Returns the document ID.
*
* @throws {Error} when called in a React Native environment.
*/
get id(): DocumentID;
/**
* Returns the document path at the root of the document.
*
* @throws {Error} when called in a React Native environment.
*/
get path(): DocumentPath;
/**
* Convenience property, same as calling `path.value`. The value is cached on
* first access and returned on subsequent calls without calling `path.value`
* again.
*
* @throws {Error} when called in a React Native environment.
*/
get value(): DocumentValue;
/**
* Convenience method, same as calling `path.at()`.
*
* @throws {Error} when called in a React Native environment.
*/
at(keyPathOrIndex: string | number): DocumentPath;
/** @internal */
constructor();
/** @internal */
static idCBOR(document: Document): Uint8Array;
/** @internal */
static canonicalizedIDCBOR(idCBOR: Uint8Array): Uint8Array;
/** @internal */
static isIDCBORCanonical(idCBOR: Uint8Array): boolean;
/** @internal */
toString(): string;
/**
* Defines a custom inspect function for Node.js that will be used when the
* object is inspected with console.log() or util.inspect().
*
* @internal
*/
[CUSTOM_INSPECT_SYMBOL$1](_depth: number, _inspectOptions: any, inspect: any): string;
}
/**
* A representation of a {@link Document} that can be mutated via
* {@link MutableDocumentPath}. You don't create or interact with a
* `MutableDocument` directly but rather through the `update()` methods of
* {@link PendingCursorOperation.update | PendingCursorOperation} and
* {@link PendingIDSpecificOperation.update | PendingIDSpecificOperation}.
*
* Not available in React Native environments.
*/
declare class MutableDocument {
/**
* Returns the ID of the document.
*
* @throws {Error} when called in a React Native environment.
*/
get id(): DocumentID;
/**
* Returns the document path at the root of the document.
*
* @throws {Error} when called in a React Native environment.
*/
get path(): MutableDocumentPath;
/**
* Convenience property, same as `path.value`.
*
* @throws {Error} when called in a React Native environment.
*/
get value(): DocumentValue;
/**
* Convenience method, same as calling `path.at()`.
*
* @throws {Error} when called in a React Native environment.
*/
at(keyPathOrIndex: string | number): MutableDocumentPath;
/** @internal */
constructor();
/** @internal */
readonly '@ditto.updateResults': UpdateResult[];
/** @internal */
static idCBOR(mutableDocument: MutableDocument): Uint8Array;
/** @internal */
static canonicalizedIDCBOR: typeof Document.canonicalizedIDCBOR;
/** @internal */
static isIDCBORCanonical: typeof Document.isIDCBORCanonical;
/** @internal */
toString(): string;
/**
* Defines a custom inspect function for Node.js that will be used when
* the object is inspected with console.log() or util.inspect().
*
* @internal */
[CUSTOM_INSPECT_SYMBOL$1](_depth: number, _inspectOptions: any, inspect: any): string;
}
/**
* Maps a {@link DocumentID} to an array of
* {@link UpdateResult | update results}. This is the data structure you get
* when {@link PendingCursorOperation.update | updating} a set of documents
* with detailed info about the performed updates.
*
* Not available in React Native environments.
*/
declare class UpdateResultsMap {
/**
* Returns an array of {@link UpdateResult | update results} associated with
* the `documentID` or undefined if not found.
*/
get(documentIDOrValue: DocumentID | DocumentIDValue): UpdateResult[] | undefined;
/**
* Returns all contained keys, i.e. {@link DocumentID | document IDs}
* contained in this map.
*/
keys(): DocumentID[];
/** @internal */
constructor(documentIDs: DocumentID[], updateResultsByDocumentIDString: object);
private documentIDs;
private updateResultsByDocumentIDString;
}
/**
* These objects are returned when using `find`-like functionality on
* {@link Collection}.
*
* They allow chaining of further query-related functions to do things like add
* a limit to the number of documents you want returned or specify how you want
* the documents to be sorted and ordered.
*
* You can call {@link exec | exec()} on the cursor to get an array of
* {@link Document | documents} or you can use methods for updating, removing
* or evicting any matching documents.
*
* Live queries and subscriptions are only available outside of transactions.
*
* Not available in React Native environments.
*/
declare class WriteTransactionPendingCursorOperation extends BasePendingCursorOperation {
sort(propertyPath: string, direction?: SortDirection): WriteTransactionPendingCursorOperation;
offset(offset: number): WriteTransactionPendingCursorOperation;
limit(limit: number): WriteTransactionPendingCursorOperation;
remove(): Promise<DocumentID[]>;
evict(): Promise<DocumentID[]>;
update(closure: (documents: MutableDocument[]) => void): Promise<UpdateResultsMap>;
/** @internal */
constructor(query: string, queryArgs: QueryArguments | null, collection: WriteTransactionCollection);
}
declare class WriteTransactionPendingIDSpecificOperation extends BasePendingIDSpecificOperation {
remove(): Promise<boolean>;
evict(): Promise<boolean>;
update(closure: (document: MutableDocument) => void): Promise<UpdateResult[]>;
updateV2(closure: (document?: MutableDocument) => void): Promise<UpdateResult[]>;
exec(): Promise<Document | undefined>;
/** @internal */
constructor(documentID: DocumentID, collection: WriteTransactionCollection);
}
/**
* Represents a collection of a Ditto store that is used in the context of a
* write transaction.
*
* Supports most of a regular {@link Collection | collection}'s functionality
* but cannot be subscribed or live queried and can not be used to create
* attachments.
*
* Create a `WriteTransactionCollection` by starting a {@link WriteTransaction}
* and using its `scoped` method.
*
* Not available in React Native environments.
*/
declare class WriteTransactionCollection implements CollectionInterface {
/** The name of the collection. */
readonly name: string;
/**
* The store this collection belongs to.
* @internal
*/
readonly store: Store;
/**
* The write transaction within which this collection instance is used.
* @internal
*/
readonly writeTransaction: WriteTransaction;
/**
* Search for documents in this collection using the provided query string.
*
* The returned cursor operation can be used to chain operations on the
* resulting document set.
*
* @param query The query to run against the collection.
* @param queryArgs These arguments replace placeholders in the provided
* query.
* @throws {Error} when called in a React Native environment.
*/
find(query: string, queryArgs?: QueryArguments | undefined): WriteTransactionPendingCursorOperation;
/**
* Convenience method, equivalent to calling {@link find | find()} and passing
* the query `"true"`.
*
* @throws {Error} when called in a React Native environment.
*/
findAll(): WriteTransactionPendingCursorOperation;
/**
* Generates a {@link WriteTransactionPendingIDSpecificOperation} with the
* provided document ID.
*
* The returned object can be used to find and return the document. It can also be used to update, remove or evict the document.
*
* @param id The ID of the document to find.
* @throws {Error} when called in a React Native environment.
*/
findByID(id: any): WriteTransactionPendingIDSpecificOperation;
upsert(value: DocumentValue, options?: UpsertOptions): Promise<DocumentID>;
/**
* See comment in {@link CollectionInterface.findByIDCBOR()}
*
* @internal */
findByIDCBOR(idCBOR: Uint8Array): WriteTransactionPendingIDSpecificOperation;
/**
* This constructor is marked internal because write transaction collections
* should be created from a {@link WriteTransaction} instance.
*
* @internal */
constructor(name: string, store: Store, writeTransaction: WriteTransaction);
}
/**
* Provides information about the result of an operation on a document that was
* part of a write transaction.
*
* The write transaction result can be one of the following types:
*
* - `inserted`
* - `removed`
* - `evicted`
* - `updated`
*
* Please note that an `upsert` operation always results in the result type
* `inserted`, regardless of whether it resulted in an update or insert.
*
* Not available in React Native environments.
*/
interface WriteTransactionResult {
type: 'inserted' | 'removed' | 'evicted' | 'updated';
docID: DocumentID;
collectionName: string;
}
/**
* Perform writes in a transaction.
*
* Create a write transaction using {@link Store.write | ditto.store.write}.
*/
declare class WriteTransaction {
readonly results: WriteTransactionResult[];
/**
* Creates a transaction-specific
* {@link WriteTransactionCollection | collection} object that will ensure
* that operations called on it are all in the context of the collection name
* provided to this function. You can create many
* {@link WriteTransactionCollection | collection} objects per
* {@link WriteTransaction} object.
*
* @throws {Error} when called in a React Native environment.
* */
scoped(toCollectionNamed: string): WriteTransactionCollection;
/** @internal */
readonly writeTransactionPointer: Pointer<FFIWriteTransaction>;
/** @internal */
readonly ditto: Ditto;
/** @internal */
constructor(ditto: Ditto, cTransaction: Pointer<FFIWriteTransaction>);
/**
* Initialise a write transaction given a Ditto instance.
*
* This is not implemented as a constructor in order to be able to use FFI
* async functions. Users start transactions through {@link Store.write}.
*
* @param ditto an instance of Ditto
* @internal
*/
static init(ditto: Ditto): Promise<WriteTransaction>;
/** @internal */
commit(): Promise<void>;
/** @internal */
rollback(): Promise<void>;
/**
* Adds an entry to the list of results that is returned at the end of a
* transaction.
*
* @internal
*/
addResult(type: WriteTransactionResult['type'], docID: DocumentID, collectionName: string): void;
}
/**
* These objects are returned when using
* {@link Collection.findByID | findByID()} functionality on
* {@link Collection | collections}.
*
* You can either call {@link exec | exec()} on the object to get an immediate
* return value, or chain calls to update, evict or remove the document.
*
* Live queries and subscriptions are only available outside of a transaction.
*
* Not available in React Native environments.
*/
declare abstract class BasePendingIDSpecificOperation implements PromiseLike<Document | undefined> {
/**
* Removes the document with the matching ID.
*
* @throws {Error} when called in a React Native environment.
* @returns `true` promise if the document was found and removed. `false`
* promise if the document wasn't found and therefore wasn't removed.
*/
abstract remove(): Promise<boolean>;
/**
* Evicts the document with the matching ID.
*
* @throws {Error} when called in a React Native environment.
* @returns `true` promise if the document was found and evicted. `false`
* promise if the document wasn't found and therefore wasn't evicted.
*/
abstract evict(): Promise<boolean>;
/**
* Updates the document with the matching ID.
*
* Document values must not be set to any non-finite numbers (`NaN`,
* `Infinity`, `-Infinity`).
*
* @param closure A closure that gets called with the document matching the
* ID. If found, the document is a {@link MutableDocument}, so you can call
* update-related functions on it. The closure is not called if the document
* is not found.
*
* @throws `Error` if the document is not found.
*
* @return An array promise of {@link UpdateResult | update results} that
* describe the updates that were performed on the document.
*
* @deprecated This method throws and does not call the closure if the
* document is not found. Use {@link updateV2 | updateV2() } instead.
*/
abstract update(closure: (document: MutableDocument) => void): Promise<UpdateResult[]>;
/**
* Updates the document with the matching ID.
*
* Document values must not be set to any non-finite numbers (`NaN`,
* `Infinity`, `-Infinity`).
*
* @param closure A closure that gets called with the document matching the
* ID. If found, the document is a {@link MutableDocument}, so you can call
* update-related functions on it. If the document is not found then the value
* provided to the closure will be `undefined`.
*
* @throws {Error} when called in a React Native environment.
* @return An array promise of {@link UpdateResult | update results} that
* describe the updates that were performed on the document.
*/
abstract updateV2(closure: (document?: MutableDocument) => void): Promise<UpdateResult[]>;
/** The ID of the document this operation operates on. */
readonly documentID: DocumentID;
/** The collection the receiver is operating on. */
readonly collection: CollectionInterface;
/**
* Executes the find operation to return the document with the matching ID.
*
* @throws {Error} when called in a React Native environment.
* @returns The {@link Document} promise with the ID provided in the
* {@link Collection.findByID | findByID()} call or `undefined` if the document was
* not found.
*/
exec(): Promise<Document | undefined>;
/** @internal */
constructor(documentID: DocumentID, collection: CollectionInterface);
/** @internal */
then<TResult1 = any, TResult2 = never>(onfulfilled?: ((value: any) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): PromiseLike<TResult1 | TResult2>;
/** @internal */
get query(): string;
protected documentIDCBOR: Uint8Array;
/**
* Commit changes made by the given closure to the current document.
*
* @param closure
* @param throwOnAsyncClosure if true, throw an error when passed an async
* closure, otherwise log a warning
* @param throwOnDocumentNotFound if true, throw an error if the document is
* not found, otherwise call the closure with `undefined` and return an
* empty array
* @param publicAPIName the name of the public API that was called, used in
* error messages and warnings
* @param transaction the transaction to use, if not provided a new one will
* be created and committed
* @internal
*/
protected updateWithClosure(closure: (document?: MutableDocument) => void, throwOnAsyncClosure: boolean, throwOnDocumentNotFound: boolean, publicAPIName: string, transaction?: WriteTransaction): Promise<UpdateResult[]>;
}
type UpsertOptions = {
/**
* Specifies the desired strategy for inserting a document. The default
* strategy is `merge`. See {@link WriteStrategy} for more information.
*/
writeStrategy?: WriteStrategy;
};
interface CollectionInterface {
/** The