import * as Context from 'effect/Context'; import * as Effect from 'effect/Effect'; import * as Layer from 'effect/Layer'; import * as Schema from 'effect/Schema'; import { type SpaceId, type URI } from '@dxos/keys'; import type * as Entity from './Entity'; import * as Err from './Err'; import type * as Filter from './Filter'; import type * as Hypergraph from './Hypergraph'; import { type AnyProperties, EntityKind, KindId } from './internal/common/types'; import type { Ref } from './internal/Ref/ref'; import type * as Obj from './Obj'; import type * as Query from './Query'; import type * as QueryResult from './QueryResult'; import type * as Registry from './Registry'; import type * as Type from './Type'; /** * `query` API function declaration. */ export interface QueryFn { (query: Q): QueryResult.QueryResult>; (filter: F): QueryResult.QueryResult>; } /** * Common interface for Database, Feed, and Hypergraph. */ export interface Queryable { query: QueryFn; } export type GetObjectByIdOptions = { deleted?: boolean; }; export type ObjectPlacement = 'root-doc' | 'linked-doc'; export type AddOptions = { /** * Where to place the object in the Automerge document tree. * Root document is always loaded with the space. * Linked documents are loaded lazily. * Placing large number of objects in the root document may slow down the initial load. * * @default 'linked-doc' */ placeIn?: ObjectPlacement; }; /** * Rejects Type entities from {@link Database.add} at compile time via their `[KindId]` brand. Used * as `T & RejectTypeEntity` to preserve inference of `T`. Bounding `add` on * `Obj.Unknown | Relation.Unknown` instead would reject broadly-typed instance adds (e.g. * `Entity.Any`, `Obj.OfShape`), forcing casts repo-wide. */ export type RejectTypeEntity = T extends { readonly [KindId]: EntityKind.Type; } ? { __error: 'Type entities must be persisted via db.addType(), not db.add().'; } : T; export type FlushOptions = { /** * Write any pending changes to disk. * @default true */ disk?: boolean; /** * Wait for pending index updates. * @default true */ indexes?: boolean; /** * Flush pending updates to objects and queries. * @default false */ updates?: boolean; }; /** * Identifier denoting an ECHO Database. */ export declare const TypeId: unique symbol; export type TypeId = typeof TypeId; /** * ECHO Database interface. */ export interface Database extends Queryable { readonly [TypeId]: TypeId; get spaceId(): SpaceId; get graph(): Hypergraph.Hypergraph; /** * Registry for this database. Delegates type lookups to the shared hypergraph registry. * To persist a schema so it replicates to other clients, add the type entity with * {@link addType} (e.g. `await db.addType(Type.makeObjectFromJsonSchema(...))`). */ readonly registry: Registry.Registry; toJSON(): object; /** * Return object by local ID. * @deprecated Use `db.query(Filter.id(id)).runSync()[0]` for a working-set lookup, or resolve via a {@link Ref}. */ getObjectById>(id: string, opts?: GetObjectByIdOptions): T | undefined; /** * Query objects. */ query: QueryFn; /** * Creates a reference to an existing object in the database. * * NOTE: The reference may be dangling if the object is not present in the database. * NOTE: Difference from `Ref.fromURI` * `Ref.fromURI(dxn)` returns an unhydrated reference. The `.load` and `.target` APIs will not work. * `db.makeRef(dxn)` is preferable in cases with access to the database. */ makeRef(uri: URI.URI): Ref; /** * Adds an object or relation to the database. * * Only Object and Relation entities are accepted. To persist a Type definition use * {@link addType} — passing a Type entity is rejected at compile time (and at runtime). */ add(obj: T & RejectTypeEntity, opts?: AddOptions): T; /** * Persists a Type definition (clones/forks the entity) so it replicates to other peers. * * Runs a conflict query first: if a type with the same typename + version already exists in * this space, the existing persisted entity is returned and no duplicate is created. This is * the only supported way to add Type entities — {@link add} rejects them. */ addType(type: T): Promise; /** * Removes object from the database. */ remove(obj: Entity.Unknown): void; /** * Wait for all pending changes to be saved to disk. * Optionaly waits for changes to be propagated to indexes and event handlers. */ flush(opts?: FlushOptions): Promise; } export declare const isDatabase: (obj: unknown) => obj is Database; export declare const Database: Schema.Schema; declare const Service_base: Context.TagClass; /** * Effect service tag for Database dependency injection. */ export declare class Service extends Service_base { } /** * Layer that provides a Database service that throws when accessed. * Useful as a default layer when no database is available. */ export declare const notAvailable: Layer.Layer; /** * Creates a Database service instance from a Database. */ export declare const makeService: (db: Database) => Context.Tag.Service; /** * Creates a Layer that provides the Database service. */ export declare const layer: (db: Database) => Layer.Layer; /** * Returns the space ID of the database. */ export declare const spaceId: Effect.Effect; /** * Resolves an object by its DXN. */ export declare const resolve: { (ref: URI.URI | Ref): Effect.Effect; (ref: URI.URI | Ref, schema: S): Effect.Effect, Err.EntityNotFoundError, Service>; }; /** * Loads an object reference. * * Catching not found error: * * ```ts * yield* load(ref).pipe(Effect.catchTag('EntityNotFoundError', () => Effect.succeed(undefined))); * ``` * */ export declare const load: (ref: Ref) => Effect.Effect; /** * Adds an object or relation to the database. * @see {@link Database.add} */ export declare const add: (obj: T & RejectTypeEntity) => Effect.Effect; /** * Persists a Type definition to the database. * @see {@link Database.addType} */ export declare const addType: (type: T) => Effect.Effect; /** * Removes an object from the database. * @see {@link Database.remove} */ export declare const remove: (obj: T) => Effect.Effect; /** * Flushes pending changes to disk. * @see {@link Database.flush} */ export declare const flush: (opts?: FlushOptions) => Effect.Effect; /** * Creates a `QueryResult` object that can be subscribed to. */ export declare const query: { (query: Q): QueryResult.QueryResultEffect, never, Service>; (filter: F): QueryResult.QueryResultEffect, never, Service>; }; export {}; //# sourceMappingURL=Database.d.ts.map