import { UserKeyDefinition, UserKeyDefinitionOptions } from "../../../platform/state"; // eslint-disable-next-line -- `StateDefinition` used as an argument import { StateDefinition } from "../../../platform/state/state-definition"; /** A set of options for customizing the behavior of a {@link BufferedKeyDefinition} */ export type BufferedKeyDefinitionOptions = UserKeyDefinitionOptions & { /** Checks whether the input type can be converted to the output type. * @param input the data that is rolling over. * @returns `true` if the definition is valid, otherwise `false`. If this * function is not specified, any truthy input is valid. * * @remarks this is intended for cases where you're working with validated or * signed data. It should be used to prevent data from being "laundered" through * synchronized state. */ isValid?: (input: Input, dependency: Dependency) => Promise; /** Transforms the input data format to its output format. * @param input the data that is rolling over. * @returns the converted value. If this function is not specified, the value * is asserted as the output type. * * @remarks This is intended for converting between, say, a replication format * and a disk format or rotating encryption keys. */ map?: (input: Input, dependency: Dependency) => Promise; /** Checks whether an overwrite should occur * @param dependency the latest value from the dependency observable provided * to the buffered state. * @returns `true` if a overwrite should occur, otherwise `false`. If this * function is not specified, overwrites occur when the dependency is truthy. * * @remarks This is intended for waiting to overwrite until a dependency becomes * available (e.g. an encryption key or a user confirmation). */ shouldOverwrite?: (dependency: Dependency) => boolean; }; /** Storage and mapping settings for data stored by a `BufferedState`. */ export class BufferedKeyDefinition { /** * Defines a buffered state * @param stateDefinition The domain of the buffer * @param key Domain key that identifies the buffered value. This key must * not be reused in any capacity. * @param options Configures the operation of the buffered state. */ constructor( readonly stateDefinition: StateDefinition, readonly key: string, readonly options: BufferedKeyDefinitionOptions, ) {} /** Converts the buffered key definition to a state provider * key definition */ toKeyDefinition() { const bufferedKey = new UserKeyDefinition(this.stateDefinition, this.key, this.options); return bufferedKey; } /** Checks whether the dependency triggers an overwrite. */ shouldOverwrite(dependency: Dependency) { const shouldOverwrite = this.options?.shouldOverwrite; if (shouldOverwrite) { return shouldOverwrite(dependency); } return dependency ? true : false; } /** Converts the input data format to its output format. * @returns the converted value. */ map(input: Input, dependency: Dependency) { const map = this.options?.map; if (map) { return map(input, dependency); } return Promise.resolve(input as unknown as Output); } /** Checks whether the input type can be converted to the output type. * @returns `true` if the definition is defined and valid, otherwise `false`. */ isValid(input: Input, dependency: Dependency) { if (input === null) { return Promise.resolve(false); } const isValid = this.options?.isValid; if (isValid) { return isValid(input, dependency); } return Promise.resolve(input ? true : false); } }