@adobe/data - v0.10.30
    Preparing search index...

    Interface Database<C, R, A, F, S, AF, SV, CV, IX, PK>

    A service is an object that provides functionality to an application. Services are never dependent upon user interface components. Services come in several varieties:

    • Frontend Services
      • Only contain void actions and observe functions.
      • Async nature enforces unidirectional control flow and decouples the service from the UI.
    • Backend Services
      • Usually consumed by other services.
      • May also contain Promise or AsyncGenerator functions.

    A service's shape can be described by a Schema (an object schema whose property schemas describe each member). The schema is authored beside the service (e.g. MyService.schema) and validated with IsValidWithCompleteSchema; a factory may also expose it at runtime via the optional schema slot for introspection. It is Observe<Schema> — observable — because a service's discoverable interface can change at runtime (e.g. once an iframe-projected service loads and reveals a different surface). Both serviceName and schema are base-Service metadata, so they are excluded from AsyncDataService.IsValid (which is why schema need not be Data) and reserved as member names. See async-data-service/is-valid-with-*-schema.ts.

    interface Database<
        C extends Components = {},
        R extends ResourceComponents = {},
        A extends ArchetypeComponents<StringKeyof<C>> = {},
        F extends TransactionFunctions = {},
        S extends string = never,
        AF extends ActionFunctions = {},
        SV = {},
        CV = unknown,
        IX extends IndexDeclarations<C> = {},
        PK extends string = never,
    > {
        actions: AF & Service;
        apply: (envelope: TransactionEnvelope) => undefined | TransactionResult<C>;
        archetypes: {
            readonly [K in string]: ArchetypeOrRouter<
                HasPartitionKey<A[K][number], PK>,
                { [Col in string]: (C & OptionalComponents)[Col] },
                ReadonlyArchetype<{ [Col in string]: (C & OptionalComponents)[Col] }>,
                Extract<A[K][number], never>,
            >
        };
        cancel: (id: number, userId?: string | number) => void;
        componentSchemas: { readonly [K in string]: Schema.Schema };
        computed: CV;
        concurrency: ConcurrencyStrategy;
        indexes: { readonly [K in string | number | symbol]: Handle<C, IX[K]> };
        locate: (
            entity: number,
        ) => null | { archetype: ReadonlyArchetype; row: number };
        observe: {
            components: { readonly [K in string]: Observe<void> };
            envelopes: Observe<
                {
                    envelope: TransactionEnvelope;
                    intent: "cancel"
                    | "commit"
                    | "intermediate";
                    result: undefined | TransactionResult<C>;
                },
            >;
            resources: { readonly [K in string]: Observe<R[K]> };
            transactions: Observe<TransactionResult<C>>;
            archetype(id: number): Observe<void>;
            count<Include extends string, T extends string>(
                include: ReadonlySet<string> | readonly Include[],
                options?: EntitySelectOptions<C, Pick<C & RequiredComponents, T>>,
            ): Observe<number>;
            entity<T>(
                id: number,
                minArchetype?: ReadonlyArchetype<T> | Archetype<T, never>,
            ): Observe<null | Readonly<T> & EntityReadValues<C>>;
            entity(id: number): Observe<null | EntityReadValues<C>>;
            select<Include extends string, T extends string>(
                include: ReadonlySet<string> | readonly Include[],
                options?: EntitySelectOptions<C, Pick<C & RequiredComponents, T>>,
            ): Observe<readonly number[]>;
        };
        reset: () => void;
        resources: { readonly [K in string]: R[K] };
        schema?: Observe<Schema.Schema>;
        serviceName?: string;
        services: SV;
        system: {
            functions: { readonly [K in string]: null | SystemFunction };
            order: readonly (readonly string[])[];
        };
        transactions: F & Service;
        version: number;
        count<Include extends string>(
            include: ReadonlySet<string> | readonly Include[],
            options?: EntitySelectOptions<
                C & OptionalComponents,
                Pick<C & RequiredComponents & OptionalComponents, Include>,
            >,
        ): number;
        derive<T>(
            compute: (db: Read<Database<C, R, A, F, S, AF, SV, CV, IX, PK>>) => T,
        ): Observe<T>;
        derive<I extends Record<string, Observe<unknown>>, T>(
            inputs: I,
            compute: (
                db: Read<Database<C, R, A, F, S, AF, SV, CV, IX, PK>>,
                inputs: {
                    readonly [K in string | number | symbol]: I[K] extends Observe<U>
                        ? U
                        : never
                },
            ) => T,
        ): Observe<T>;
        ensureArchetype<const CC extends string>(
            components: ReadonlySet<CC> | readonly CC[],
        ): HasPartitionKey<CC, PK> extends true
            ? Router<
                { [K in string]: (C & OptionalComponents)[K] },
                Extract<CC, never>,
            >
            : ReadonlyArchetype<{ [K in string]: (C & OptionalComponents)[K] }>;
        ensureArchetype<const CC extends string>(
            components: ReadonlySet<CC> | readonly CC[],
            partitionValues: { readonly [K in string]: (C & OptionalComponents)[K] },
        ): ReadonlyArchetype<{ [K in string]: (C & OptionalComponents)[K] }>;
        extend<
            P extends Database.Plugin<any, any, any, any, any, any, any, any, any>,
        >(
            plugin: P,
        ): Database<
            C & FromSchemas<
                Simplify<
                    {
                        [K in string
                        | number
                        | symbol as string extends K
                            ? never
                            : number extends K ? never : symbol extends K ? never : K]: P["components"][K]
                    },
                >,
            >,
            R & FromSchemas<
                Simplify<
                    {
                        [K in string
                        | number
                        | symbol as string extends K
                            ? never
                            : number extends K ? never : symbol extends K ? never : K]: P["resources"][K]
                    },
                >,
            >,
            A & Simplify<
                {
                    [K in string
                    | number
                    | symbol as string extends K
                        ? never
                        : number extends K ? never : symbol extends K ? never : K]: P["archetypes"][K]
                },
            >,
            F & ToTransactionFunctions<
                Simplify<
                    {
                        [K in string
                        | number
                        | symbol as string extends K
                            ? never
                            : number extends K ? never : symbol extends K ? never : K]: P["transactions"][K]
                    },
                >,
            >,
            S
            | Extract<keyof P["systems"], string>,
            AF & ToActionFunctions<
                Simplify<
                    {
                        [K in string
                        | number
                        | symbol as string extends K
                            ? never
                            : number extends K ? never : symbol extends K ? never : K]: P["actions"][K]
                    },
                >,
            >,
            SV & FromServiceFactories<
                Simplify<
                    {
                        [K in string
                        | number
                        | symbol as string extends K
                            ? never
                            : number extends K ? never : symbol extends K ? never : K]: P["services"][K]
                    },
                >,
            >,
            CV & FromComputedFactories<
                Simplify<
                    {
                        [K in string
                        | number
                        | symbol as string extends K
                            ? never
                            : number extends K ? never : symbol extends K ? never : K]: P["computed"][K]
                    },
                >,
            >,
            IX & Simplify<
                {
                    [K in string
                    | number
                    | symbol as string extends K
                        ? never
                        : number extends K ? never : symbol extends K ? never : K]: P["indexes"][K]
                },
            >,
        >;
        fromData(data: unknown, scope?: PersistenceScope): Promise<FromDataResult>;
        get<K extends string>(entity: number, component: K): undefined | C[K];
        pruneToPluginSchema<
            P extends Database.Plugin<any, any, any, any, any, any, any, any, any>,
        >(
            plugin: P,
        ): FromPlugin<P>;
        queryArchetypes<Include extends string>(
            include: ReadonlySet<string> | readonly Include[],
            options?: ArchetypeQueryOptions<C, PK>,
        ): readonly ReadonlyArchetype<Pick<C & OptionalComponents, Include>>[];
        read<T>(
            entity: number,
            archetype: ReadonlyArchetype<T> | Archetype<T, never>,
        ): null | Readonly<T>;
        read<const K extends string | number | symbol>(
            entity: number,
            components: readonly K[],
        ): null | Readonly<Pick<EntityReadValues<C>, K>>;
        read(entity: number): null | EntityReadValues<C>;
        select<Include extends string>(
            include: ReadonlySet<string> | readonly Include[],
            options?: EntitySelectOptions<
                C & OptionalComponents,
                Pick<C & RequiredComponents & OptionalComponents, Include>,
            >,
        ): readonly number[];
        toData(options?: { scope?: PersistenceScope }): unknown;
    }

    Type Parameters

    Hierarchy (View Summary)

    Index

    Properties

    actions: AF & Service
    apply: (envelope: TransactionEnvelope) => undefined | TransactionResult<C>

    Apply a remotely-originated transaction envelope to the database. Used by sync services to feed in inbound commits and transients. Does not fire observe.envelopes.

    archetypes: {
        readonly [K in string]: ArchetypeOrRouter<
            HasPartitionKey<A[K][number], PK>,
            { [Col in string]: (C & OptionalComponents)[Col] },
            ReadonlyArchetype<{ [Col in string]: (C & OptionalComponents)[Col] }>,
            Extract<A[K][number], never>,
        >
    }
    cancel: (id: number, userId?: string | number) => void

    Cancel a previously-applied transient envelope by its compound (userId, id) key. Used by sync services to forward server-broadcast cancellations.

    componentSchemas: { readonly [K in string]: Schema.Schema }
    computed: CV
    concurrency: ConcurrencyStrategy

    The concurrency strategy the database was created with. Sync services read concurrency.userId to recover the peer identifier and check concurrency.deferredCommit to confirm the database is in the appropriate mode for multi-peer operation.

    indexes: { readonly [K in string | number | symbol]: Handle<C, IX[K]> }

    Lookup handles for the indexes declared by plugins on this database. Each key in IX becomes a Database.Index.Handle whose method shape is narrowed by the declared key tuple and unique flag.

    The handles are also the implementation path used by db.select / db.observe.select when a where / order matches a declared index — call sites do not need to be aware of which index served the query, but the same handle is what runs underneath.

    locate: (entity: number) => null | { archetype: ReadonlyArchetype; row: number }
    observe: {
        components: { readonly [K in string]: Observe<void> };
        envelopes: Observe<
            {
                envelope: TransactionEnvelope;
                intent: "cancel"
                | "commit"
                | "intermediate";
                result: undefined | TransactionResult<C>;
            },
        >;
        resources: { readonly [K in string]: Observe<R[K]> };
        transactions: Observe<TransactionResult<C>>;
        archetype(id: number): Observe<void>;
        count<Include extends string, T extends string>(
            include: ReadonlySet<string> | readonly Include[],
            options?: EntitySelectOptions<C, Pick<C & RequiredComponents, T>>,
        ): Observe<number>;
        entity<T>(
            id: number,
            minArchetype?: ReadonlyArchetype<T> | Archetype<T, never>,
        ): Observe<null | Readonly<T> & EntityReadValues<C>>;
        entity(id: number): Observe<null | EntityReadValues<C>>;
        select<Include extends string, T extends string>(
            include: ReadonlySet<string> | readonly Include[],
            options?: EntitySelectOptions<C, Pick<C & RequiredComponents, T>>,
        ): Observe<readonly number[]>;
    }

    Type declaration

    reset: () => void

    Wipes all entities and resets all resources to their plugin defaults, preserving database identity (observers, transaction wrappers, sync options stay intact). Equivalent in observable state to a freshly constructed Database with the same plugin.

    O(num_archetypes + num_resources) — does not walk individual entities. Clears any in-flight reconciler transient queue.

    resources: { readonly [K in string]: R[K] }

    Optional observable of the service's schema (its authored contract), which may change at runtime as the service's discoverable interface evolves.

    serviceName?: string
    services: SV
    system: {
        functions: { readonly [K in string]: null | SystemFunction };
        order: readonly (readonly string[])[];
    }

    Type declaration

    • Readonlyfunctions: { readonly [K in string]: null | SystemFunction }

      System create() return value, or null when create() returns void. Key is always present.

    • Readonlyorder: readonly (readonly string[])[]

      Tier order for execution. Looser type allows extended dbs to be assignable to base.

    transactions: F & Service
    version: number

    The current schema version — entries.length - 1 when a version upgrader is configured, else 0. Stamped into the save metadata of every toData (per persisted quadrant) and read back on load. Never an ECS component/resource.

    Methods

    • Reactive derivation. compute runs against a read-only projection of this database (Database.Read — value / index / resource reads only; no observers, writes, or table access). The derive records exactly the reads it performs and re-emits when any could have changed: the initial value on subscribe, then at most once per committed transaction (synchronously at the commit boundary), structurally deduplicated so an unchanged result never re-notifies.

      The callback receives Database.Read<this>, so an intersection database resolves to the merged read surface — consumers never need to cast.

      Type Parameters

      • T

      Parameters

      Returns Observe<T>

    • derive with a fixed record of external inputs — arbitrary Observe<T> values that do NOT live in the ECS (e.g. observables exposed by services). Their CURRENT values are injected as the second callback argument, keyed the same as inputs and unwrapped (Observe<U> → U); the first argument stays the read projection, so a body can fold external values and ECS reads into one synchronous expression.

      The inputs are subscribed once, at the root (not read dynamically inside the body), so the set is fixed for the life of the derive. The derive recomputes when any input emits OR an ECS read it recorded could have changed; like Observe.fromProperties, the first value is withheld until every input has produced one. Anything dynamic — an input set that depends on data, or an input whose arguments come from an ECS read — composes with Observe.withSwitch / Observe.fromKeys around the derive.

      Type Parameters

      • I extends Record<string, Observe<unknown>>
      • T

      Parameters

      • inputs: I
      • compute: (
            db: Read<Database<C, R, A, F, S, AF, SV, CV, IX, PK>>,
            inputs: {
                readonly [K in string | number | symbol]: I[K] extends Observe<U>
                    ? U
                    : never
            },
        ) => T

      Returns Observe<T>

    • Type Parameters

      • P extends Database.Plugin<any, any, any, any, any, any, any, any, any>

      Parameters

      • plugin: P

      Returns Database<
          C & FromSchemas<
              Simplify<
                  {
                      [K in string
                      | number
                      | symbol as string extends K
                          ? never
                          : number extends K ? never : symbol extends K ? never : K]: P["components"][K]
                  },
              >,
          >,
          R & FromSchemas<
              Simplify<
                  {
                      [K in string
                      | number
                      | symbol as string extends K
                          ? never
                          : number extends K ? never : symbol extends K ? never : K]: P["resources"][K]
                  },
              >,
          >,
          A & Simplify<
              {
                  [K in string
                  | number
                  | symbol as string extends K
                      ? never
                      : number extends K ? never : symbol extends K ? never : K]: P["archetypes"][K]
              },
          >,
          F & ToTransactionFunctions<
              Simplify<
                  {
                      [K in string
                      | number
                      | symbol as string extends K
                          ? never
                          : number extends K ? never : symbol extends K ? never : K]: P["transactions"][K]
                  },
              >,
          >,
          S
          | Extract<keyof P["systems"], string>,
          AF & ToActionFunctions<
              Simplify<
                  {
                      [K in string
                      | number
                      | symbol as string extends K
                          ? never
                          : number extends K ? never : symbol extends K ? never : K]: P["actions"][K]
                  },
              >,
          >,
          SV & FromServiceFactories<
              Simplify<
                  {
                      [K in string
                      | number
                      | symbol as string extends K
                          ? never
                          : number extends K ? never : symbol extends K ? never : K]: P["services"][K]
                  },
              >,
          >,
          CV & FromComputedFactories<
              Simplify<
                  {
                      [K in string
                      | number
                      | symbol as string extends K
                          ? never
                          : number extends K ? never : symbol extends K ? never : K]: P["computed"][K]
                  },
              >,
          >,
          IX & Simplify<
              {
                  [K in string
                  | number
                  | symbol as string extends K
                      ? never
                      : number extends K ? never : symbol extends K ? never : K]: P["indexes"][K]
              },
          >,
      >

    • Load a snapshot. Async because a configured version handler may be async (e.g. it lazy-import()s migration code); with no handler it still resolves after the synchronous load completes. toData stays synchronous — only the load path can await a handler.

      Resolves with a FromDataResult: { loaded: true } when the data was loaded (possibly migrated), or { loaded: false, currentVersion, schemaVersions } when a persisted quadrant was saved at a version newer than this app — the live database is left untouched. Rejection is data, not a throw, so a UI can branch on it (e.g. prompt "please update").

      Parameters

      Returns Promise<FromDataResult>

    • Conform the database's DATA to a target plugin's schema, dropping every component and resource the plugin does not declare (its imports/extends are already flattened in). An entity keeping at least one declared component migrates to its reduced archetype; an entity whose every component is foreign — including a foreign resource singleton — is removed.

      Prunes DATA only, in place: the emptied foreign archetypes and their unused schemas are left as inert residue and shed on the next fromData (which skips empty archetypes and adopts only schemas the restored data uses), so no snapshot round-trip carries them forever. Call when quiescent (no in-flight transient); any pending transient is cleared, as with reset.

      Returns the same database instance retyped to the target plugin's schema (Database.FromPlugin<P>), so a wider database narrows to the pruned schema at the type level. Foreign behavior (transactions/systems the original plugin declared) still exists at runtime but is no longer in the type.

      Type Parameters

      • P extends Database.Plugin<any, any, any, any, any, any, any, any, any>

      Parameters

      • plugin: P

      Returns FromPlugin<P>

    • Read exactly the components of archetype. A membership GATE: returns null unless the entity is a superset of archetype. The result is narrowed to the archetype's own row — reading a component outside archetype off the result is a compile error (use a wider archetype, the component-list overload, or read(entity)).

      Type Parameters

      • T

      Parameters

      Returns null | Readonly<T>

    • Read a chosen subset of an entity's components.

      A pure PROJECTION, not a membership gate: returns null only when the entity does not exist. A requested component the entity does not have comes back absent — the field stays optional in the result, exactly as from the full read(entity).

      Prefer this over read(entity) when only a few fields are needed: it names the exact components touched, so db.derive can scope its recompute to just those fields instead of the whole entity. id is not a readable component (you already hold it); the element type is inferred as a literal union.

      Type Parameters

      • const K extends string | number | symbol

      Parameters

      • entity: number
      • components: readonly K[]

      Returns null | Readonly<Pick<EntityReadValues<C>, K>>

    • Parameters

      • entity: number

      Returns null | EntityReadValues<C>

    • Serialize the store to a plain snapshot. When copy is true the snapshot is detached from the live store (column/entity buffers are copied) so it remains valid after subsequent mutations; otherwise it references live buffers and is only valid until the next mutation. See Database.toData() for the bug this copy flag addresses for transient-bearing strategies.

      options.scope selects which persistent quadrants to emit; omit for all.

      Parameters

      Returns unknown