/**
* @license
* Copyright 2022-2026 Matter.js Authors
* SPDX-License-Identifier: Apache-2.0
*/
import { GeneratedClass } from "@matter/general";
import { Val } from "@matter/protocol";
/**
* State is a plain JS object.
*
* Any constructor invokable with no arguments may define a state structure.
*/
export interface StateType {
new (): {};
}
/**
* This is used as state in base classes.
*/
export const EmptyState = function () {
return {};
} as unknown as new () => {};
/**
* DerivedState is a programmatic extension of state.
*/
export interface DerivedState {
new (): InstanceType & Extension;
}
/**
* Extend state with additional values.
*/
export function DerivedState({
base,
values,
name,
}: DerivedState.Options) {
if (base === EmptyState) {
base = undefined;
}
const oldDefaults = (base ? new base() : {}) as Val.Struct;
let newDefaults: undefined | Val.Struct;
for (const key in values) {
const value = (values as Val.Struct)[key];
if (!Object.prototype.hasOwnProperty.call(oldDefaults, key) || oldDefaults[key] !== value) {
if (!newDefaults) {
newDefaults = {};
}
newDefaults[key] = value;
}
}
if (!newDefaults) {
return (base ?? EmptyState) as DerivedState;
}
return GeneratedClass({
name: name ?? base?.name ?? "State",
base: base,
instanceProperties: newDefaults,
}) as DerivedState;
}
export namespace DerivedState {
export interface Options {
values: Values;
base?: Base;
name?: string;
}
}