self-assert
Version:
A small TypeScript library for designing models with built-in validity.
157 lines • 5.6 kB
TypeScript
import type { LabelId, LabeledRule } from "../rule";
import type { ModelFromContainer, DraftViewer } from "../types";
/**
* Provides an assistant to guide the completion of a model.
*
* A `DraftAssistant` encapsulates the logic needed to:
*
* - track the current state of a form field or group of fields,
* - validate the model being built,
* - handle and route failed assertions,
* - notify observers (viewers) of changes or validation failures.
*
* Assistants can be nested and composed to build complex models.
*
* @typeParam Model The type of the model the assistant helps to create.
* @typeParam ContainerModel The type of the container model the assistant works on.
*
* @remarks
* Originally, this class was named `ModelCreator`. Later, it was renamed to `FormCompletionAssistant`,
* employing the metaphor of an assistant guiding form completion. This could have led to confusion,
* since the class has more use cases than just form completion.
*
* It can, for example, be used in a backend context to validate an object before persisting it.
*
* @category Draft assistants
*/
export declare abstract class DraftAssistant<Model = any, ContainerModel = any> {
protected labelIds: LabelId[];
protected modelFromContainer: ModelFromContainer<Model, ContainerModel>;
protected initialModel: Model;
/**
* See {@link https://github.com/microsoft/TypeScript/issues/3841 #3841} for
* more information.
* @hidden
*/
["constructor"]: typeof DraftAssistant;
/**
* This object is used as a **token** for an invalid model.
* @internal
*/
static INVALID_MODEL: Object;
/**
* @category Model creation
*/
static isInvalidModel(potentialModel: unknown): boolean;
/**
* @returns A default model getter from a container for the top-level assistant.
* Since there is no container to get the model from, it throws an error.
*/
static topLevelModelFromContainer<Model = any>(): ModelFromContainer<Model, unknown>;
protected model: Model;
protected brokenRules: LabeledRule[];
protected viewers: DraftViewer<Model>[];
protected constructor(labelIds: LabelId[], modelFromContainer: ModelFromContainer<Model, ContainerModel>, initialModel: Model);
/**
* Attempts to create a model. It fails if any of the assertions fail.
* @see {@link withCreatedModelDo}.
*
* @throws {@link RulesBroken} if the model is invalid
*
* @category Model creation
*/
abstract createModel(): Model;
/**
* Executes a closure depending on whether the model is valid or not after creating it.
*
* @template ReturnType - The type of the value returned by the closures.
* @param validModelClosure - A closure that will be called with the created model
* if it's valid.
* @param invalidModelClosure - A closure that will be called if the model is invalid.
* @returns The return value of the closure that was called.
*
* @category Model creation
*/
withCreatedModelDo<ReturnType>(validModelClosure: (model: Model) => ReturnType, invalidModelClosure: () => ReturnType): ReturnType;
/** @category Model creation */
getModel(): Model;
/** @category Model creation */
setModel(newModel: Model): void;
/**
* Resets the model to its initial value.
* @category Model creation
*/
resetModel(): void;
/**
* Sets the model from its container.
* @category Model creation
*/
setModelFrom(containerModel: ContainerModel): void;
/**
* Adds a viewer to the list of observers.
* @category Viewers
*/
accept(aViewer: DraftViewer<Model>): void;
/**
* Removes a viewer from the list of observers.
* @category Viewers
*/
removeViewer(aViewer: DraftViewer<never>): void;
/**
* @returns The number of viewers currently observing the assistant.
* @category Viewers
*/
numberOfViewers(): number;
/**
* Adds a rule to the list of broken rules.
* @category Rules
*/
addBrokenRule(aBrokenRuleLabel: LabeledRule): void;
/**
* Adds a list of rules to the list of broken rules.
* @category Rules
*/
addBrokenRules(brokenRules: LabeledRule[]): void;
/**
* @returns `true` if the list of broken rules is not empty
* @category Rules
*/
hasBrokenRules(): boolean;
/**
* Opposite of {@link hasBrokenRules}.
* @category Rules
*/
doesNotHaveBrokenRules(): boolean;
/**
* @returns The descriptions of the broken rules
* @category Rules
*/
brokenRulesDescriptions(): string[];
/**
* @returns `true` if this assistant handles the given `Assertion`.
* @category Rules
*/
handles(aRule: LabeledRule): boolean;
/**
* Adds an assertion id to the list of handled assertions.
* @category Rules
*/
addLabelId(aLabelId: LabelId): void;
/** @category Rules */
hasBrokenRule(aBrokenRuleLabel: LabeledRule): boolean;
/**
* @returns `true` if this assistant has only one failed assertion that
* is identified as the given `assertionId`.
*
* @remarks
* Used mostly for testing.
*
* @category Rules
*/
hasOnlyOneRuleBrokenIdentifiedAs(assertionId: LabelId): boolean;
/** @category Rules */
removeBrokenRules(): void;
protected forEachViewer(action: (viewer: DraftViewer<Model>) => void): void;
protected notifyViewersOnChange(aModel: Model): void;
}
//# sourceMappingURL=DraftAssistant.d.ts.map