/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import { Entropy, MaybePromise, Observable, Transaction } from "@matter/general"; import { AccessControl, Val } from "@matter/protocol"; import { RootSupervisor } from "../../supervision/RootSupervisor.js"; import { ValueSupervisor } from "../../supervision/ValueSupervisor.js"; import { StateType } from "../StateType.js"; import type { ValReference } from "./ValReference.js"; /** * Datasource manages the canonical root of a state tree. The "state" property of a Behavior is a reference to a * Datasource. * * Datasources maintain a version number and triggers change events. If modified in a transaction they compute changes * and persist values as necessary. */ export interface Datasource extends Transaction.Resource { /** * Create a managed version of the source data. */ reference(session: ValueSupervisor.Session): InstanceType; /** * The data's version. */ readonly version: number; /** * Advance {@link version}, which Matter requires to move with the data a report carries. * * Does nothing where the version belongs to someone else: a client node's version is whatever the peer reported, * so it advances only when a data report says so. */ advanceVersion(): void; /** * Advance {@link version} only where one of these properties is served from an accessor, as declared by * {@link Val.Dynamic}. Use this where a stored property's own commit already advanced the version, so advancing * again would count one change twice. */ advanceVersionFor(props: string[]): void; /** * Validate values against the schema. */ validate(session: ValueSupervisor.Session, values?: Val.Struct): void; /** * Release resources. */ close(): void; /** * Obtain a read-only view of values. */ readonly view: InstanceType; /** * Path used in diagnostic messages. */ location: AccessControl.Location; /** * Events registered for this Datasource */ events: Datasource.Events; } /** * Create a new datasource. */ export declare function Datasource(options: Datasource.Options): Datasource; export declare namespace Datasource { /** * Datasource events. */ type Events = { interactionBegin?: Observable<[context?: ValueSupervisor.Session], MaybePromise>; interactionEnd?: Observable<[context?: ValueSupervisor.Session], MaybePromise>; stateChanged?: Observable<[context?: ValueSupervisor.Session], MaybePromise>; } & { [K in `${string}$Changing` | `${string}$Changed`]: Observable, MaybePromise>; }; /** * Datasource configuration options. */ interface Options { /** * The JS class for the root value. */ type: T; /** * The manager used to manage and validate values. */ supervisor: RootSupervisor; /** * Data model location, used for access control and diagnostics. */ location: AccessControl.Location; /** * Used to generate initial version numbers. */ entropy: Entropy; /** * Events triggered automatically. * * Events named "fieldName$Changing", if present, emit before changes commit. Events named "fieldName$Changed", * if present, emit after field changes commit. */ events?: Events; /** * Default values. These defaults override default properties in the state class but not values persisted in * the store. */ defaults?: Val.Struct; /** * Optional storage for non-volatile values. */ store?: Store | ExternallyMutableStore; /** * Adjusts persisted values in an outdated format, see {@link Behavior.migrate}. Does not apply to values that * mirror a remote node. */ migrate?: (values: Val.Struct) => void; /** * The object that owns the datasource. This is passed as the "owner" parameter to {@link Val.Dynamic}. */ owner?: any; /** * The internal key used for storage of attributes and struct properties. Defaults to name. If set to ID but * the schema has no ID, uses name instead. * * For structs we also support the other key (id or name) for input, but always write using the preferred key. */ primaryKey?: ValReference.PrimaryKey; /** * Optional callback, invoked when properties change. */ onChange?: (attrs: string[]) => MaybePromise; } /** * The interface {@link Datasource} uses to read and write non-volatile values. */ interface Store { /** * Initial values must be loaded beforehand. That allows the behavior to initialize synchronously. */ initialValues?: Val.Struct; /** * Updates the values. * * This is a patch operation. Only properties present are modified. Properties that are present but set to * undefined are deleted. */ set(transaction: Transaction, values: Val.Struct): Promise; } /** * An extended {@link Store} that represents cached values that may mutate independently from the datasource. */ interface ExternallyMutableStore extends Store { /** * Apply values the peer reported. * * Uses the same patch semantics as {@link set}, but the values are the peer's own and take effect at once. On a * mirror, {@link set} instead proposes values to the peer and leaves the local values unchanged until the peer * accepts them, so never route a report through {@link set}. Resolves once the values are applied, also when * storing them locally failed; the result then carries that failure for the caller to report. Their change * notifications may follow later, when notifications of an earlier change are still held; do not await them. */ externalSet(values: Val.StructMap): Promise; /** * The datasource consuming this store's data. Installed by the datasource when it binds to the store. */ consumer?: ExternallyMutableStore.Consumer; /** * Current values, preferring the live consumer over {@link Store.initialValues}. Reflects up-to-date * data while a consumer is attached, where {@link Store.initialValues} may be absent. */ currentValues?: Val.Struct; /** * The current version of the data. */ version: number; /** * Forget the version so the next read requests the full data instead of only changes since that version. */ invalidateVersion?(): void; /** * Forget the version in memory and in storage. Resolves once storage holds the unknown version. */ forgetVersion(): Promise; /** * Reclaim values from the datasource so a rebuilt datasource re-seeds from live data rather than defaults. */ reclaimValues?(): void; /** * Discard the store's values, including any persisted copy. */ erase?(): MaybePromise; } namespace ExternallyMutableStore { /** * The result of {@link ExternallyMutableStore.externalSet}. */ interface Applied { /** * The error that kept the values from being stored locally, if any. A failure thrown as `undefined` is * not reported. */ persistFailure?: unknown; } function is(store?: Store | ExternallyMutableStore): store is ExternallyMutableStore; /** * Interface the datasource exposes to its external store for change integration and value access. */ interface Consumer { /** * Apply externally-sourced values to the datasource's managed state now. * * Returns the function that announces the changes, or undefined if nothing changed. It logs a failing * {@link Datasource.Options.onChange} or event emit and goes on; it never throws. */ integrate(values: Val.StructMap): undefined | (() => MaybePromise); /** * Read current values for the specified keys. */ readValues(keys: Set): Val.Struct; /** * Read a non-destructive copy of all current values. */ snapshot(): Val.Struct; /** * Release all values from the datasource, transferring ownership back to the store. */ releaseValues(): Val.Struct; } } /** * The version we report until we've recorded a version. */ const UNKNOWN_VERSION = -1; interface ValueObserver { (value: Val, oldValue: Val, context?: ValueSupervisor.Session): void; } } //# sourceMappingURL=Datasource.d.ts.map