import { type Scope } from "../types.ts"; import type { DeepSignalSet } from "@ng-org/alien-deepsignals"; import type { ShapeType, BaseType } from "@ng-org/shex-orm"; /** * Class for managing RDF-based ORM subscriptions with the engine. * * You have two options on how to interact with the ORM: * - Use a hook for your favorite framework under `@ng-org/orm/react|vue|svelte` * - Call {@link OrmSubscription.getOrCreate} to create a subscription manually * * For more information about RDF-based ORM subscriptions, * see the README and follow the tutorial. */ export declare class OrmSubscription { /** Global store of all subscriptions. We use that for pooling. */ private static idToEntry; /** The shape type that is subscribed to. */ readonly shapeType: ShapeType; /** The {@link Scope} of the subscription. */ readonly scope: Scope; /** * The signalObject containing all data matching the shape and scope * (once subscription is established). * The object is of type {@link DeepSignalSet} which * to the outside behaves like a regular set but has a couple of * additional features: * - Modifications are immediately propagated back to the database. * - Database changes are immediately reflected in the object. * - `.getBy(graphIri, subjectIri)` utility for quicker access to objects in set. * - `.first()` utility to get the first element added to the set. * - the iterator utilities, e.g. `.map()`, `.filter()`, ... * - Watch for object changes using {@link watchDeepSignal}. */ readonly signalObject: DeepSignalSet; private stopSignalListening; /** The subscription ID kept as an identifier for communicating with the verifier. */ private subscriptionId; /** The number of OrmSubscriptions with the same shape and scope (for pooling). */ private refCount; /** Identifier as a combination of shape type and scope. Prevents duplications. */ private identifier; /** When true, modifications from the signalObject are not processed. */ private suspendDeepWatcher; /** True, if a transaction is running. */ private inTransaction_; /** Aggregation of patches to be sent when in transaction. @ignore */ private pendingPatches; /** **Await to ensure that the subscription is established and the data arrived.** */ private readyPromise_; private closeOrmSubscription; /** Function to call once initial data has been applied. */ private resolveReady; private static cleanupSignalRegistry; private constructor(); /** * Returns an OrmSubscription which subscribes to the given * {@link ShapeType} and {@link Scope} in a 2-way binding. * * You **find the data** and objects matching the shape and scope * in the **`signalObject`** once {@link readyPromise} resolves. This is a {@link DeepSignalSet} which * to the outside behaves like a regular set but has a couple of * additional features: * - Modifications are propagated back to the database. * Note that multiple immediate modifications in the same task, * e.g. `obj[0] = "foo"; obj[1] = "bar"` are batched together * and sent in a subsequent microtask. * - Database changes are immediately reflected in the object. * - `.getBy(graphIri, subjectIri)` utility for quicker access to objects in set. * - `.first()` utility to get the first element added to the set. * - the iterator utilities, e.g. `.map()`, `.filter()`, ... * - Watch for object changes using {@link watchDeepSignal}. * * You can use **transactions**, to prevent excessive calls to the database * with {@link beginTransaction} and {@link commitTransaction}. * * In many cases, you are advised to use a hook for your * favorite framework under `@ng-org/orm/react|vue|svelte` * instead of calling `getOrCreate` directly. * * Call {@link close}, to close the subscription. * * Note: If another call to `getOrCreate` was previously made * and `close` was not called on it (or only shortly after), * it will return the same OrmSubscription. * * @param shapeType The {@link ShapeType} * @param scope The {@link Scope}. If no scope is given, the whole store is considered. * * @example * ```typescript * // We assume you have created a graph document already, as below. * // const documentId = await ng.doc_create( * // session_id, * // "Graph", * // "data:graph", * // "store", * // undefined * // ); * const subscription = OrmSubscription.getOrCreate(ExpenseShapeType, {graphs: [graphIri]}); * // Wait for data. * await subscription.readyPromise; * * const expense = subscription.signalObject.first() * expense.name = "updated name"; * expense.description = "updated description"; * * // Await promise to run the below code in a new task. * // That will push the changes to the database. * await Promise.resolve(); * * // Here, the expense modifications have been have been committed * // (unless you had previously called subscription.beginTransaction()). * // The data is available in subscriptions running on a different device too. * * subscription.close(); * // If you create a new subscription with the same document within a couple of 100ms, * // The subscription hasn't been closed and the old one is returned so that the data * // is available instantly. This is especially useful in the context of frontend frameworks. * const subscription2 = OrmSubscription.getOrCreate(ExpenseShapeType, {graphs: [graphIri]}); * * subscription2.signalObject.add({ * "@graph": graphIri, * "@id": "", // Leave empty to auto-assign one. * name": "A new expense", * description: "A new description" * }); * * subscription2.close() * ``` */ static getOrCreate: (shapeType: ShapeType, scope: Scope) => OrmSubscription; /** True, if a transaction is running. */ get inTransaction(): boolean; /** **Await to ensure that the subscription is established and the data arrived.** */ get readyPromise(): Promise; /** * Stop the subscription. * * **If there is more than one subscription with the same shape type and scope * the orm subscription will persist.** * * Additionally, the closing of the subscription is delayed by a couple hundred milliseconds * so that when frontend frameworks unmount and soon mount a component again with the same * shape type and scope, we reuse the same orm subscription. */ close: () => void; /** Handle updates (patches) coming from signal object modifications. */ private onSignalObjectUpdate; /** Handle messages coming from the engine (initial data or patches). */ private onBackendMessage; private handleInitialResponse; /** Handle incoming patches from the engine */ private onBackendUpdate; /** Function to create random subject NURIs for newly created nested objects. */ private signalObjectPropGenerator; /** * Begins a transaction that batches changes to be committed to the database. * This is useful for performance reasons. * * Note that this does not disable reactivity of the `signalObject`. * Modifications keep being rendered. */ beginTransaction: () => void; /** * Commits a transactions sending all modifications made during the transaction * (started with `beginTransaction`) to the database. */ commitTransaction: () => Promise; } //# sourceMappingURL=GraphOrmSubscription.d.ts.map