UNPKG

@player-ui/player

Version:

151 lines 7.33 kB
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