@player-ui/player
Version:
151 lines • 7.33 kB
TypeScript
import type { Validation } from "@player-ui/types";
import { SyncHook, SyncWaterfallHook } from "tapable-ts";
import type { BindingInstance, BindingFactory } from "../../binding";
import type { DataModelMiddleware } from "../../data";
import type { SchemaController } from "../../schema";
import type { ErrorValidationResponse, ValidationObjectWithHandler, ValidatorContext, ValidationProvider, ValidationResponse, WarningValidationResponse } from "../../validator";
import { ValidatorRegistry } from "../../validator";
import type { Logger } from "../../logger";
import type { Resolve, ViewInstance } from "../../view";
import type { BindingTracker } from "./binding-tracker";
export declare const SCHEMA_VALIDATION_PROVIDER_NAME = "schema";
export declare const VIEW_VALIDATION_PROVIDER_NAME = "view";
export declare const VALIDATION_PROVIDER_NAME_SYMBOL: unique symbol;
export type ValidationObjectWithSource = ValidationObjectWithHandler & {
/** The name of the validation */
[VALIDATION_PROVIDER_NAME_SYMBOL]: string;
};
type SimpleValidatorContext = Omit<ValidatorContext, "validation" | "schemaType">;
interface BaseActiveValidation<T> {
/** The validation is being actively shown */
state: "active";
/** The validation response */
response: T;
}
type ActiveWarning = BaseActiveValidation<WarningValidationResponse> & {
/** Warnings track if they can be dismissed automatically (by navigating) */
dismissable: boolean;
};
type ActiveError = BaseActiveValidation<ErrorValidationResponse>;
/**
* warnings that keep track of their active state
*/
type StatefulWarning = {
/** A common key to differentiate between errors and warnings */
type: "warning";
/** The underlying validation this tracks */
value: ValidationObjectWithSource;
/** If this is currently preventing navigation from continuing */
isBlockingNavigation: boolean;
} & ({
/** warnings start with no state, but can active or dismissed */
state: "none" | "dismissed";
} | ActiveWarning);
/** Errors that keep track of their state */
type StatefulError = {
/** A common key to differentiate between errors and warnings */
type: "error";
/** The underlying validation this tracks */
value: ValidationObjectWithSource;
/** If this is currently preventing navigation from continuing */
isBlockingNavigation: boolean;
} & ({
/** Errors start with no state an can be activated */
state: "none";
} | ActiveError);
export type StatefulValidationObject = StatefulWarning | StatefulError;
type ValidationRunner = (obj: ValidationObjectWithHandler) => {
/** A validation message */
message: string;
} | undefined;
/** A class that manages validating bindings across phases */
declare class ValidatedBinding {
currentPhase?: Validation.Trigger;
private applicableValidations;
private validationsByState;
get allValidations(): Array<StatefulValidationObject>;
weakBindings: Set<BindingInstance>;
private onDismiss?;
constructor(possibleValidations: Array<ValidationObjectWithSource>, onDismiss?: () => void, log?: Logger, weakBindings?: Set<BindingInstance>);
private checkIfBlocking;
getAll(): Array<ValidationResponse>;
get(): ValidationResponse | undefined;
private runApplicableValidations;
update(phase: Validation.Trigger, canDismiss: boolean, runner: ValidationRunner): void;
}
/**
* A controller for orchestrating validation within a running player
*
* The current validation flow is as follows:
*
* - When a binding is first seen, gather all of the possible validations for it from the providers
* - Schema and Crossfield (view) are both providers of possible validations
* - Run all of the applicable validations for that binding for the `load` trigger
*
* - When a change occurs, set the phase of the binding to `change`.
* - Run all of the `change` triggered validations for that binding.
*
* - When a navigation event occurs, set the phase of the binding to `navigate`.
* - Run all `change` and `navigate` validations for each tracked binding.
* - For any warnings, also keep a state of `shown` or `dismissed`.
* - Set all non-dismissed warnings to `shown`.
* - Set all `shown` warnings to `dismissed`.
* - Allow navigation forward if there are no non-dismissed warnings and no valid errors.
*/
export declare class ValidationController implements BindingTracker {
readonly hooks: {
/** A hook called to tap into the validator registry for adding more validators */
createValidatorRegistry: SyncHook<[ValidatorRegistry], Record<string, any>>;
/** A callback/event when a new validation is added to the view */
onAddValidation: SyncWaterfallHook<[ValidationResponse, BindingInstance], Record<string, any>>;
/** The inverse of onAddValidation, this is called when a validation is removed from the list */
onRemoveValidation: SyncWaterfallHook<[ValidationResponse, BindingInstance], Record<string, any>>;
resolveValidationProviders: SyncWaterfallHook<[{
/** The name of the provider */
source: string;
/** The provider itself */
provider: ValidationProvider;
}[]], {
/** The view this is triggered for */
view?: ViewInstance;
}>;
/** A hook called when a binding is added to the tracker */
onTrackBinding: SyncHook<[BindingInstance], Record<string, any>>;
};
private tracker;
private validations;
private validatorRegistry?;
private schema;
private providers;
private viewValidationProvider?;
private options?;
private weakBindingTracker;
constructor(schema: SchemaController, options?: SimpleValidatorContext);
setOptions(options: SimpleValidatorContext): void;
/** Return the middleware for the data-model to stop propagation of invalid data */
getDataMiddleware(): Array<DataModelMiddleware>;
private getValidationProviders;
reset(): void;
onView(view: ViewInstance): void;
updateValidationsForBinding(binding: BindingInstance, trigger: Validation.Trigger, validationContext?: SimpleValidatorContext, onDismiss?: () => void): void;
validationRunner(validationObj: ValidationObjectWithHandler, binding: BindingInstance, context?: SimpleValidatorContext | undefined): {
message: string;
} | undefined;
private updateValidationsForView;
private get activeBindings();
getValidator(type: string): import("../../validator").ValidatorFunction | undefined;
getBindings(): Set<BindingInstance>;
trackBinding(binding: BindingInstance): void;
/** Executes all known validations for the tracked bindings using the given model */
validateView(trigger?: Validation.Trigger): {
/** Indicating if the view can proceed without error */
canTransition: boolean;
/** the validations that are preventing the view from continuing */
validations?: Map<BindingInstance, ValidationResponse>;
};
/** Get the current tracked validation for the given binding */
getValidationForBinding(binding: BindingInstance): ValidatedBinding | undefined;
forView(parser: BindingFactory): Resolve.Validation;
}
export {};
//# sourceMappingURL=controller.d.ts.map