/**
 * @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";
/**
 * 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<T extends StateType = StateType> extends Transaction.Resource {
    /**
     * Create a managed version of the source data.
     */
    reference(session: ValueSupervisor.Session): InstanceType<T>;
    /**
     * The data's version.
     */
    readonly version: number;
    /**
     * 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<T>;
    /**
     * Path used in diagnostic messages.
     */
    location: AccessControl.Location;
    /**
     * Events registered for this Datasource
     */
    events: Datasource.Events;
}
/**
 * Create a new datasource.
 */
export declare function Datasource<const T extends StateType = StateType>(options: Datasource.Options<T>): Datasource<T>;
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<Parameters<ValueObserver>, MaybePromise>;
    };
    /**
     * Datasource configuration options.
     */
    interface Options<T extends StateType = StateType> {
        /**
         * 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;
        /**
         * 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?: "name" | "id";
        /**
         * Optional callback, invoked when properties change.
         */
        onChange?: (attrs: string[]) => MaybePromise<void>;
    }
    /**
     * 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<void>;
    }
    /**
     * An extended {@link Store} that represents cached values that may mutate independently from the datasource.
     */
    interface ExternallyMutableStore extends Store {
        /**
         * Apply changes from an external source.
         *
         * Uses the same semantics as {@link set}.
         */
        externalSet(values: Val.StructMap): Promise<void>;
        /**
         * The datasource consuming this store's data.  Installed by the datasource when it binds to the store.
         */
        consumer?: ExternallyMutableStore.Consumer;
        /**
         * The current version of the data.
         */
        version: number;
    }
    namespace ExternallyMutableStore {
        /**
         * Interface the datasource exposes to its external store for change integration and value access.
         */
        interface Consumer {
            /**
             * Integrate externally-sourced changes into the datasource's managed state.
             */
            integrateExternalChange(values: Val.StructMap): Promise<void>;
            /**
             * Read current values for the specified keys.
             */
            readValues(keys: Set<string>): 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