/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import { Datasource } from "#behavior/state/managed/Datasource.js"; import type { EndpointStore } from "#storage/EndpointStore.js"; import { MaybePromise, Transaction } from "@matter/general"; import { Val } from "@matter/protocol"; import type { ServerEndpointStore } from "./ServerEndpointStore.js"; interface StorageParticipant extends Transaction.Participant { mutations?: Record; } /** * Factory function for the default implementation of {@link Datasource.Store}. * * Performs read & write for non-volatile values for a single behavior via the {@link ServerEndpointStore} interface. */ export function DatasourceStore( endpointStore: EndpointStore, behaviorId: string, initialValues: Val.Struct | undefined, ): Datasource.Store { return { initialValues, async set(transaction: Transaction, values: Val.Struct) { if (behaviorId === "__proto__") { return; } const participant = participantFor(transaction, endpointStore); if (!participant.mutations) { participant.mutations = {}; } const behaviorMutations = participant.mutations[behaviorId]; if (behaviorMutations) { for (const key in values) { behaviorMutations[key] = values[key]; } } else { participant.mutations[behaviorId] = { ...values }; } }, }; } /** * We create a single participant per storage/transaction pair. This function handles setup and retrieval of this * participant. */ function participantFor(transaction: Transaction, endpointStore: EndpointStore) { let participant = transaction.getParticipant(endpointStore) as StorageParticipant | undefined; if (participant) { return participant; } participant = { role: endpointStore, mutations: undefined, toString() { return endpointStore.toString(); }, commit1(): MaybePromise { // Persistence serves phase one commit; values are added directly to the journal so nothing necessary here }, async commit2() { if (this.mutations) { await endpointStore.set(this.mutations); } }, rollback(): MaybePromise { delete this.mutations; }, }; transaction.addParticipants(participant); return participant; }