{"version":3,"sources":["../src/form.ts","../src/field.ts","../src/binding.ts","../src/config.ts","../src/submission.ts"],"sourcesContent":["import { action, computed, makeObservable, observable } from \"mobx\";\nimport { v4 as uuidV4 } from \"uuid\";\nimport { Validator, Watcher, StandardNestedFetcher, KeyPath } from \"@mobx-sentinel/core\";\nimport { FormField } from \"./field\";\nimport { FormBinding, FormBindingConstructor, FormBindingFunc, getSafeBindingName } from \"./binding\";\nimport { FormConfig, globalConfig } from \"./config\";\nimport { Submission } from \"./submission\";\n\nconst registry = new WeakMap<object, Map<symbol, Form<any>>>();\nconst defaultFormKey = Symbol(\"form.defaultFormKey\");\nconst internalToken = Symbol(\"form.internalToken\");\n\n/**\n * Form manages submission, fields, and bindings.\n *\n * Key features:\n * - Manages form fields and their states\n * - Supports nested forms\n * - Manages form submission lifecycle\n * - Provides binding system for UI integration\n * - Integrates with Watcher for change detection\n * - Integrates with Validator for validation\n */\nexport class Form<T> {\n  readonly id = uuidV4();\n  readonly #formKey: symbol;\n  readonly watcher: Watcher;\n  readonly validator: Validator<T>;\n  readonly #nestedFetcher: StandardNestedFetcher<Form<any>>;\n  readonly #submission = new Submission();\n  readonly #fields = new Map<string, FormField>();\n  readonly #bindings = new Map<string, FormBinding>();\n  readonly #localConfig = observable.box<Partial<FormConfig>>({});\n\n  /** Extension fields for bindings */\n  [k: `bind${Capitalize<string>}`]: unknown;\n\n  /**\n   * Get a form instance for the subject.\n   *\n   * @remarks\n   * - Returns existing instance if one exists for the subject\n   * - Creates new instance if none exists\n   * - Instances are cached and garbage collected with their subjects\n   * - Multiple forms per subject supported via `formKey`\n   *\n   * @param subject The model object to create form for\n   * @param formKey Optional key for multiple forms per subject\n   *\n   * @throws `TypeError` if subject is not an object\n   */\n  static get<T extends object>(subject: T, formKey?: symbol): Form<T> {\n    const form = this.getSafe(subject, formKey);\n    if (!form) {\n      throw new TypeError(\"subject: Expected an object\");\n    }\n    return form;\n  }\n\n  /**\n   * Get a form instance for the subject.\n   *\n   * Same as {@link Form.get} but returns null instead of throwing an error.\n   */\n  static getSafe<T extends object>(subject: T, formKey?: symbol): Form<T> | null {\n    if (!subject || typeof subject !== \"object\") {\n      return null;\n    }\n\n    formKey ??= defaultFormKey;\n\n    let map = registry.get(subject);\n    if (!map) {\n      map = new Map();\n      registry.set(subject, map);\n    }\n\n    let instance = map.get(formKey);\n    if (!instance) {\n      instance = new this<T>(internalToken, {\n        subject,\n        formKey,\n      });\n      map.set(formKey, instance);\n    }\n    return instance;\n  }\n\n  /**\n   * Manually dispose the form instance for the subject.\n   *\n   * Use with caution.\\\n   * You don't usually need to use this method at all.\\\n   * It's only for advanced use cases, such as testing.\n   *\n   * @see {@link Form.get}\n   */\n  static dispose(subject: object, formKey?: symbol) {\n    const map = registry.get(subject);\n    if (!map) return;\n    if (formKey) {\n      map.delete(formKey);\n    } else {\n      map.clear();\n    }\n  }\n\n  private constructor(\n    token: symbol,\n    args: {\n      subject: T & object;\n      formKey: symbol;\n    }\n  ) {\n    if (token !== internalToken) {\n      throw new Error(\"private constructor\");\n    }\n\n    this.#formKey = args.formKey;\n    this.watcher = Watcher.get(args.subject);\n    this.validator = Validator.get(args.subject);\n    this.#nestedFetcher = new StandardNestedFetcher(args.subject, (entry) => Form.getSafe(entry.data, this.#formKey));\n\n    makeObservable(this);\n\n    this.#submission.addHandler(\"didSubmit\", (succeed) => {\n      if (succeed) {\n        this.reset();\n      }\n    });\n  }\n\n  /**\n   * The configuration of the form\n   *\n   * This is a computed value that combines the global configuration and the local configuration.\n   */\n  @computed.struct\n  get config(): Readonly<FormConfig> {\n    return {\n      ...globalConfig,\n      ...this.#localConfig.get(),\n    };\n  }\n\n  /** Configure the form locally */\n  @action.bound\n  configure: {\n    /** Override the global configuration locally */\n    (config: Partial<Readonly<FormConfig>>): void;\n    /** Reset to the global configuration */\n    (reset: true): void;\n  } = (arg0) => {\n    if (typeof arg0 === \"object\") {\n      Object.assign(this.#localConfig.get(), arg0);\n    } else {\n      this.#localConfig.set({});\n    }\n  };\n\n  /**\n   * Whether the form is dirty (including sub-forms)\n   *\n   * @remarks Alias for {@link Watcher.changed}.\n   */\n  get isDirty() {\n    return this.watcher.changed;\n  }\n\n  /**\n   * Whether the form is valid (including sub-forms)\n   *\n   * @remarks Alias for {@link Validator.isValid}.\n   */\n  get isValid() {\n    return this.validator.isValid;\n  }\n\n  /**\n   * The number of invalid fields\n   *\n   * @remarks Alias for {@link Validator.invalidKeyCount}.\n   */\n  get invalidFieldCount() {\n    return this.validator.invalidKeyCount;\n  }\n\n  /**\n   * The number of total invalid field paths (counts invalid fields in sub-forms)\n   *\n   * @remarks Alias for {@link Validator.invalidKeyPathCount}.\n   */\n  get invalidFieldPathCount() {\n    return this.validator.invalidKeyPathCount;\n  }\n\n  /**\n   * Whether the form is in validator state\n   *\n   * @remarks Alias for {@link Validator.isValidating}.\n   */\n  get isValidating() {\n    return this.validator.isValidating;\n  }\n\n  /** Whether the form is in submitting state */\n  get isSubmitting() {\n    return this.#submission.isRunning;\n  }\n\n  /** Whether the form is busy (submitting or validating) */\n  @computed\n  get isBusy() {\n    return this.isSubmitting || this.isValidating;\n  }\n\n  /**\n   * Whether the form can be submitted\n   *\n   * @remarks\n   * - Checks if the form is not busy\n   * - Checks if the form is valid or allows invalid submissions\n   * - Checks if the form is dirty or allows non-dirty submissions\n   */\n  @computed\n  get canSubmit() {\n    return (\n      !this.isBusy &&\n      (this.config.allowSubmitInvalid || this.isValid) &&\n      (this.config.allowSubmitNonDirty || this.isDirty)\n    );\n  }\n\n  /**\n   * Sub-forms within the form.\n   *\n   * Forms are collected via `@nested` annotation.\n   */\n  get subForms() {\n    return this.#nestedFetcher.dataMap;\n  }\n\n  /** Report error states on all fields and sub-forms */\n  @action\n  reportError() {\n    for (const field of this.#fields.values()) {\n      field.reportError();\n    }\n    for (const entry of this.#nestedFetcher) {\n      entry.data.reportError();\n    }\n  }\n\n  /**\n   * Reset the form's state\n   *\n   * @remarks\n   * - Resets the fields\n   * - Resets the sub-forms\n   * - Resets the watcher\n   * - Does not reset the validator\n   */\n  @action\n  reset() {\n    // NOTE: DO NOT reset the validator here.\n    this.watcher.reset();\n    for (const field of this.#fields.values()) {\n      field.reset();\n    }\n    for (const entry of this.#nestedFetcher) {\n      entry.data.reset();\n    }\n  }\n\n  /**\n   * Mark the form as dirty\n   *\n   * @remarks Alias for {@link Watcher.assumeChanged}.\n   */\n  markAsDirty() {\n    this.watcher.assumeChanged();\n  }\n\n  /**\n   * Submit the form.\n   *\n   * @remarks\n   * - Checks if {@link canSubmit} is `true`\n   * - Executes handlers in order\n   * - Aborts if any `submit` handler returns `false`\n   * - Handles exceptions in all phases\n   * - Resets the form after successful submission\n   *\n   * @param args.force Whether to force submission even if {@link canSubmit} is `false`.\n   *   It cancels any in-progress submission if any.\n   *\n   * @returns `true` if submission succeeded, `false` if failed or aborted\n   */\n  async submit(args?: { force?: boolean }) {\n    if (!args?.force && !this.canSubmit) return false;\n    return this.#submission.exec();\n  }\n\n  /**\n   * Add a submission handler\n   *\n   * @remarks\n   * Handlers are called in this order:\n   * 1. `willSubmit` - Called before submission starts\n   * 2. `submit` - Async handlers that perform the submission (serialized)\n   * 3. `didSubmit` - Called after submission completes\n   *\n   * @see {@link Form.Handlers}\n   *\n   * @returns Function to remove the handler\n   */\n  addHandler: {\n    (event: \"willSubmit\", handler: Submission.Handlers[\"willSubmit\"]): () => void;\n    (event: \"submit\", handler: Submission.Handlers[\"submit\"]): () => void;\n    (event: \"didSubmit\", handler: Submission.Handlers[\"didSubmit\"]): () => void;\n  } = (...args) => this.#submission.addHandler(...args);\n\n  /**\n   * Get a field by name\n   *\n   * @remarks Fields are cached and reused.\n   */\n  getField(fieldName: FormField.Name<T>) {\n    let field = this.#fields.get(fieldName);\n    if (!field) {\n      field = new FormField({\n        fieldName: String(fieldName),\n        validator: this.validator,\n        getFinalizationDelayMs: () => this.config.autoFinalizationDelayMs,\n      });\n      this.#fields.set(fieldName, field);\n    }\n    return field;\n  }\n\n  /** Define a binding by key */\n  #defineBinding(bindingKey: string, create: () => FormBinding) {\n    let binding = this.#bindings.get(bindingKey);\n    if (!binding) {\n      binding = create();\n      this.#bindings.set(bindingKey, binding);\n    }\n    return binding;\n  }\n\n  /** Create a binding to the form */\n  #bindToForm: FormBindingFunc.ForForm<T> = (\n    binding: FormBindingConstructor.ForForm,\n    config?: FormBindingFunc.Config\n  ) => {\n    const key = `${getSafeBindingName(binding)}:${config?.cacheKey}`;\n    const instance = this.#defineBinding(key, () => new binding(this, config));\n    instance.config = config; // Update on every call\n    return instance.props;\n  };\n\n  /** Create a binding to a field */\n  #bindToField: FormBindingFunc.ForField<T> = (\n    fieldName: FormField.Name<T>,\n    binding: FormBindingConstructor.ForField,\n    config?: FormBindingFunc.Config\n  ) => {\n    const key = `${fieldName}@${getSafeBindingName(binding)}:${config?.cacheKey}`;\n    const instance = this.#defineBinding(key, () => {\n      const field = this.getField(fieldName);\n      return new binding(field, config);\n    });\n    instance.config = config; // Update on every call\n    return instance.props;\n  };\n\n  /** Create a binding to multiple fields */\n  #bindToMultiField: FormBindingFunc.ForMultiField<T> = (\n    fieldNames: FormField.Name<T>[],\n    binding: FormBindingConstructor.ForMultiField,\n    config?: FormBindingFunc.Config\n  ) => {\n    const key = `${fieldNames.join(\",\")}@${getSafeBindingName(binding)}:${config?.cacheKey}`;\n    const instance = this.#defineBinding(key, () => {\n      const fields = fieldNames.map((name) => this.getField(name));\n      return new binding(fields, config);\n    });\n    instance.config = config; // Update on every call\n    return instance.props;\n  };\n\n  /**\n   * Create UI binding for form elements\n   *\n   * @remarks\n   * - Can bind to individual fields\n   * - Can bind to multiple fields\n   * - Can bind to the entire form\n   * - Bindings are cached and reused\n   * - Supports configuration via binding classes\n   */\n  bind: FormBindingFunc<T> = (...args: any[]) => {\n    if (typeof args[0] === \"string\") {\n      return this.#bindToField(args[0] as any, args[1], args[2]);\n    }\n    if (Array.isArray(args[0])) {\n      return this.#bindToMultiField(args[0], args[1], args[2]);\n    }\n    return this.#bindToForm(args[0], args[1]);\n  };\n\n  /**\n   * Get error messages for a field\n   *\n   * @param fieldName Field to get errors for\n   * @param includePreReported Whether to include errors not yet reported\n   *\n   * @returns Set of error messages\n   */\n  getErrors(fieldName: FormField.Name<T>, includePreReported = false): ReadonlySet<string> {\n    const field = this.getField(fieldName);\n\n    if (!includePreReported && !field.isErrorReported) {\n      return new Set();\n    }\n\n    // Reading errors from FormField#errors is computed,\n    // so notifications only trigger when the error of the specific field changes\n    return field.errors;\n  }\n\n  /**\n   * Get all error messages for the form\n   *\n   * @param fieldName Field to get errors for. If omitted, all errors are returned.\n   *\n   * @returns Set of error messages\n   */\n  getAllErrors(fieldName?: FormField.Name<T>) {\n    return this.validator.getErrorMessages(fieldName ? KeyPath.build(fieldName) : KeyPath.Self, true);\n  }\n\n  /**\n   * The first error message (including nested objects)\n   *\n   * @remarks Alias for {@link Validator.firstErrorMessage}.\n   */\n  @computed\n  get firstErrorMessage() {\n    return this.validator.firstErrorMessage;\n  }\n\n  /** @internal @ignore */\n  [internalToken]() {\n    return {\n      fields: this.#fields,\n      bindings: this.#bindings,\n      submission: this.#submission,\n    };\n  }\n}\n\nexport namespace Form {\n  /** @inline */\n  export type Handlers = Submission.Handlers;\n}\n\n/** @internal @ignore */\nexport function debugForm<T>(form: Form<T>) {\n  return form[internalToken]();\n}\n","import { action, comparer, computed, makeObservable, observable, reaction } from \"mobx\";\nimport { v4 as uuidV4 } from \"uuid\";\nimport { KeyPath, type Validator } from \"@mobx-sentinel/core\";\n\nconst internalToken = Symbol(\"formField.internal\");\n\n/**\n * Form field that tracks input state and validation errors\n *\n * Key features:\n * - Tracks touch state\n * - Handles intermediate (partial) input states\n * - Manages error reporting\n * - Supports auto-finalization of intermediate values\n */\nexport class FormField {\n  readonly id = uuidV4();\n  readonly fieldName: string;\n  readonly validator: Validator<any>;\n  readonly #getFinalizationDelayMs: () => number;\n  readonly #isTouched = observable.box(false);\n  readonly #changeType = observable.box<FormField.ChangeType | null>(null);\n  readonly #isReported = observable.box(false);\n  readonly #isReportedDelayed = observable.box(false);\n  #timerId: number | null = null;\n\n  /** @ignore */\n  constructor(args: { fieldName: string; validator: Validator<any>; getFinalizationDelayMs: () => number }) {\n    makeObservable(this);\n    this.fieldName = args.fieldName;\n    this.validator = args.validator;\n    this.#getFinalizationDelayMs = args.getFinalizationDelayMs;\n\n    // Delay the error reporting until the validation is up-to-date.\n    reaction(\n      () => [this.#isReported.get(), this.validator.isValidating] as const,\n      ([isReported, isValidating]) => {\n        if (!isValidating) {\n          this.#isReportedDelayed.set(isReported);\n        }\n      },\n      { equals: comparer.shallow }\n    );\n  }\n\n  /**\n   * Whether the field is touched.\n   *\n   * A field becomes touched when the user interacts with it.\n   */\n  get isTouched() {\n    return this.#isTouched.get();\n  }\n\n  /**\n   * Whether the field value is intermediate (partial input)\n   *\n   * @example\n   * - Typing \"user@\" in an email field\n   * - Typing a partial date \"2024-\"\n   *\n   * @remarks\n   * Intermediate values are automatically finalized after a delay\n   */\n  get isIntermediate() {\n    return this.#changeType.get() === \"intermediate\";\n  }\n\n  /**\n   * Whether the field value is changed\n   */\n  get isChanged() {\n    return !!this.#changeType.get();\n  }\n\n  /**\n   * Whether the error states has been reported.\n   *\n   * Check this value to determine if errors should be displayed to the user.\n   *\n   * @returns\n   * - `undefined` - Validity is undetermined (not yet reported)\n   * - `false` - Field is valid\n   * - `true` - Field is invalid\n   *\n   * @remarks\n   * - Error reporting is delayed until validation is complete.\n   * - It can be used directly with the `aria-invalid` attribute.\n   */\n  @computed\n  get isErrorReported() {\n    if (!this.#isReportedDelayed.get()) return undefined;\n    return this.hasErrors;\n  }\n\n  /**\n   * Error messages for the field\n   *\n   * Regardless of {@link isErrorReported}, this value is always up-to-date.\n   */\n  @computed.struct\n  get errors(): ReadonlySet<string> {\n    return this.validator.getErrorMessages(KeyPath.build(this.fieldName));\n  }\n\n  /**\n   * Whether the field has errors\n   *\n   * Regardless of {@link isErrorReported}, this value is always up-to-date.\n   */\n  @computed\n  get hasErrors() {\n    return this.validator.hasErrors(KeyPath.build(this.fieldName));\n  }\n\n  /**\n   * Reset the field state\n   *\n   * @remarks\n   * - Clears touched state\n   * - Clears change state\n   * - Clears error reporting\n   * - Cancels any pending auto-finalization\n   */\n  @action\n  reset() {\n    this.#changeType.set(null);\n    this.#isTouched.set(false);\n    this.#isReported.set(false);\n    this.#cancelFinalizeChangeWithDelay();\n  }\n\n  /**\n   * Mark the field as touched\n   *\n   * It's usually triggered by `onFocus`.\n   */\n  @action\n  markAsTouched() {\n    this.#isTouched.set(true);\n  }\n\n  /**\n   * Mark the field as changed\n   *\n   * It's usually triggered by `onChange`.\n   *\n   * @param type Default to \"final\"\n   *\n   * @remarks\n   * - \"final\" immediately reports errors\n   * - \"intermediate\" schedules auto-finalization after delay\n   */\n  @action\n  markAsChanged(type: FormField.ChangeType = \"final\") {\n    this.#changeType.set(type);\n\n    switch (type) {\n      case \"final\": {\n        this.#cancelFinalizeChangeWithDelay();\n        this.reportError();\n        break;\n      }\n      case \"intermediate\": {\n        this.#finalizeChangeWithDelay();\n        break;\n      }\n    }\n  }\n\n  /**\n   * Report the errors of the field.\n   *\n   * It will wait until the validation is up-to-date before reporting the errors.\n   */\n  @action\n  reportError() {\n    this.#isReported.set(true);\n  }\n\n  /** Finalize the intermediate change if needed (usually triggered by onBlur) */\n  finalizeChangeIfNeeded() {\n    this.#cancelFinalizeChangeWithDelay();\n    if (this.isIntermediate) {\n      this.markAsChanged(\"final\");\n    }\n  }\n\n  #finalizeChangeWithDelay() {\n    this.#cancelFinalizeChangeWithDelay();\n    this.#timerId = +setTimeout(() => {\n      this.finalizeChangeIfNeeded();\n    }, this.#getFinalizationDelayMs());\n  }\n\n  #cancelFinalizeChangeWithDelay() {\n    if (this.#timerId) {\n      clearTimeout(this.#timerId);\n      this.#timerId = null;\n    }\n  }\n\n  /** @internal @ignore */\n  [internalToken]() {\n    return {\n      isReported: this.#isReported,\n    };\n  }\n}\n\nexport namespace FormField {\n  /** Strict field name */\n  export type NameStrict<T> = keyof T & string;\n  /** Augmented field name with an arbitrary suffix */\n  export type NameAugmented<T> = `${NameStrict<T>}:${string}`;\n  /** Field name */\n  export type Name<T> = NameStrict<T> | NameAugmented<T>;\n\n  /**\n   * The type of change that has occurred in the field.\n   *\n   * - \"final\" - The input is complete and no further update is necessary to make it valid.\n   * - \"intermediate\" - The input is incomplete and does not yet conform to the expected format.\n   */\n  export type ChangeType = \"final\" | \"intermediate\";\n}\n\n/** @internal @ignore */\nexport function debugFormField(field: FormField) {\n  return field[internalToken]();\n}\n","import type { Form } from \"./form\";\nimport type { FormField } from \"./field\";\nimport { v4 as uuidV4 } from \"uuid\";\n\ntype ConfigOf<T> = T extends new (form: Form<any>, config: infer Config) => FormBinding\n  ? Config\n  : T extends new (field: FormField, config: infer Config) => FormBinding\n    ? Config\n    : T extends new (fields: FormField[], config: infer Config) => FormBinding\n      ? Config\n      : never;\n\n/** Interface for form binding classes */\nexport interface FormBinding {\n  /** Configuration of the binding */\n  config?: object;\n  /** Binding properties which passed to the view component */\n  readonly props: object;\n}\n\n/** Polymorphic constructor of binding classes */\nexport type FormBindingConstructor =\n  | FormBindingConstructor.ForField\n  | FormBindingConstructor.ForMultiField\n  | FormBindingConstructor.ForForm;\nexport namespace FormBindingConstructor {\n  /** Constructor for field binding classes */\n  export type ForField = new (field: FormField, config?: any) => FormBinding;\n  /** Constructor for multi-field binding classes */\n  export type ForMultiField = new (fields: FormField[], config?: any) => FormBinding;\n  /** Constructor for form binding classes */\n  export type ForForm = new (form: Form<any>, config?: any) => FormBinding;\n}\n\n/**\n * Get a safe name for the binding class\n *\n * Since Function.name is vulnerable to minification,\n * a UUID is appended to the name to ensure uniqueness.\n */\nexport function getSafeBindingName(constructor: FormBindingConstructor): string {\n  let name = safeBindingNameCache.get(constructor);\n  if (!name) {\n    name = `${constructor.name}--${uuidV4()}`;\n    safeBindingNameCache.set(constructor, name);\n  }\n  return name;\n}\nconst safeBindingNameCache = new WeakMap<FormBindingConstructor, string>();\n\n/** Polymorphic function of Form#bind */\nexport interface FormBindingFunc<T>\n  extends FormBindingFunc.ForField<T>,\n    FormBindingFunc.ForMultiField<T>,\n    FormBindingFunc.ForForm<T> {}\nexport namespace FormBindingFunc {\n  /** Bind configuration */\n  export type Config = {\n    /** Cache key for the binding */\n    cacheKey?: string;\n  };\n\n  /** Bind to a field */\n  export interface ForField<T> {\n    /** Create a binding for the field */\n    <Binding extends new (field: FormField) => FormBinding>(\n      fieldName: FormField.Name<T>,\n      binding: Binding,\n      config?: Config\n    ): InstanceType<Binding>[\"props\"];\n\n    /** Create a binding for the field with the config */\n    <Binding extends new (field: FormField, config: any) => FormBinding>(\n      fieldName: FormField.Name<T>,\n      binding: Binding,\n      config: NoInfer<ConfigOf<Binding>> & Config\n    ): InstanceType<Binding>[\"props\"];\n  }\n\n  /** Bind to multiple fields */\n  export interface ForMultiField<T> {\n    /** Create a binding for the multiple fields */\n    <Binding extends new (fields: FormField[]) => FormBinding>(\n      fieldNames: FormField.Name<T>[],\n      binding: Binding,\n      config?: Config\n    ): InstanceType<Binding>[\"props\"];\n\n    /** Create a binding for the multiple fields with the config */\n    <Binding extends new (fields: FormField[], config: any) => FormBinding>(\n      fieldNames: FormField.Name<T>[],\n      binding: Binding,\n      config: NoInfer<ConfigOf<Binding>> & Config\n    ): InstanceType<Binding>[\"props\"];\n  }\n\n  /** Bind to the form */\n  export interface ForForm<T> {\n    /** Create a binding for the form */\n    <Binding extends new (form: Form<T>) => FormBinding>(\n      binding: Binding,\n      config?: Config\n    ): InstanceType<Binding>[\"props\"];\n\n    /** Create a binding for the form with the config */\n    <Binding extends new (form: Form<T>, config: any) => FormBinding>(\n      binding: Binding,\n      config: NoInfer<ConfigOf<Binding>> & Config\n    ): InstanceType<Binding>[\"props\"];\n  }\n}\n\nexport namespace FormBindingFuncExtension {\n  /** Bind configuration */\n  export type Config = FormBindingFunc.Config;\n\n  /** Bind to a field */\n  export namespace ForField {\n    /** Create a binding for the field with an optional config */\n    export type OptionalConfig<T, Binding extends new (field: FormField, config?: any) => FormBinding> = (\n      fieldName: FormField.Name<T>,\n      config?: NoInfer<ConfigOf<Binding>> & Config\n    ) => InstanceType<Binding>[\"props\"];\n\n    /** Create a binding for the field with a required config */\n    export type RequiredConfig<T, Binding extends new (field: FormField, config: any) => FormBinding> = (\n      fieldName: FormField.Name<T>,\n      config: NoInfer<ConfigOf<Binding>> & Config\n    ) => InstanceType<Binding>[\"props\"];\n  }\n\n  /** Bind to multiple fields */\n  export namespace ForMultiField {\n    /** Create a binding for the multiple fields */\n    export type OptionalConfig<T, Binding extends new (fields: FormField[], config?: any) => FormBinding> = (\n      fieldNames: FormField.Name<T>[],\n      config?: NoInfer<ConfigOf<Binding>> & Config\n    ) => InstanceType<Binding>[\"props\"];\n\n    /** Create a binding for the multiple fields with the config */\n    export type RequiredConfig<T, Binding extends new (fields: FormField[], config: any) => FormBinding> = (\n      fieldNames: FormField.Name<T>[],\n      config: NoInfer<ConfigOf<Binding>> & Config\n    ) => InstanceType<Binding>[\"props\"];\n  }\n\n  /** Bind to the form */\n  export namespace ForForm {\n    /** Create a binding for the form */\n    export type OptionalConfig<T, Binding extends new (form: Form<T>, config: any) => FormBinding> = (\n      config?: NoInfer<ConfigOf<Binding>> & Config\n    ) => InstanceType<Binding>[\"props\"];\n\n    /** Create a binding for the form with the config */\n    export type RequiredConfig<T, Binding extends new (form: Form<T>, config: any) => FormBinding> = (\n      config: NoInfer<ConfigOf<Binding>> & Config\n    ) => InstanceType<Binding>[\"props\"];\n  }\n}\n","import { observable, runInAction } from \"mobx\";\n\n/** Form configuration */\nexport type FormConfig = {\n  /**\n   * Automatically finalize the form when the input is intermediate (partial input). [in milliseconds]\n   *\n   * @default 3000\n   */\n  autoFinalizationDelayMs: number;\n  /**\n   * Allow submission even if the form is not dirty.\n   *\n   * @default false\n   */\n  allowSubmitNonDirty: boolean;\n  /**\n   * Allow submission even if the form is invalid.\n   *\n   * @default false\n   */\n  allowSubmitInvalid: boolean;\n};\n\n/** Default configuration */\nexport const defaultConfig: Readonly<FormConfig> = Object.freeze({\n  autoFinalizationDelayMs: 3000,\n  allowSubmitNonDirty: false,\n  allowSubmitInvalid: false,\n});\n\n/** Global configuration */\nexport const globalConfig = observable.object(defaultConfig);\n\n/** Update the global configuration */\nexport function configureForm(config: Partial<Readonly<FormConfig>>): Readonly<FormConfig>;\n\n/** Reset the global configuration to the default */\nexport function configureForm(reset: true): Readonly<FormConfig>;\n\nexport function configureForm(config: true | Partial<Readonly<FormConfig>>): Readonly<FormConfig> {\n  runInAction(() => {\n    if (config === true) {\n      Object.assign(globalConfig, defaultConfig);\n    } else {\n      Object.assign(globalConfig, config);\n    }\n  });\n  return globalConfig;\n}\n","import { observable, runInAction } from \"mobx\";\n\n/**\n * Manages form submission lifecycle and handlers\n *\n * Key features:\n * - Handles submission lifecycle (`willSubmit` -> `submit` -> `didSubmit`)\n * - Executes handlers in registration order\n * - Supports cancellation of in-progress submissions\n * - Tracks submission state\n */\nexport class Submission {\n  readonly #isRunning = observable.box(false);\n  readonly #handlers: {\n    readonly [K in keyof Submission.Handlers]: Set<Submission.Handlers[K]>;\n  } = {\n    willSubmit: new Set(),\n    submit: new Set(),\n    didSubmit: new Set(),\n  };\n  #abortCtrl: AbortController | null = null;\n\n  /** Whether the submission is running */\n  get isRunning() {\n    return this.#isRunning.get();\n  }\n\n  /**\n   * Add a handler for submission events\n   *\n   * @returns Function to remove the handler\n   */\n  addHandler<K extends keyof Submission.Handlers>(event: K, handler: Submission.Handlers[K]) {\n    this.#handlers[event].add(handler);\n    return (): void => void this.#handlers[event].delete(handler);\n  }\n\n  /**\n   * Execute the submission process\n   *\n   * @remarks\n   * - Cancels any in-progress submission\n   * - Executes handlers in order\n   * - `submit` handlers are executed serially\n   * - Aborts if any `submit` handler returns false\n   * - Handles exceptions in all phases\n   *\n   * @returns `true` if submission succeeded, `false` if failed or aborted\n   */\n  async exec(): Promise<boolean> {\n    this.#abortCtrl?.abort();\n    const abortCtrl = new AbortController();\n    this.#abortCtrl = abortCtrl;\n\n    let succeed = true;\n\n    runInAction(() => {\n      this.#isRunning.set(true);\n    });\n\n    try {\n      for (const handler of this.#handlers.willSubmit) {\n        if (!(await handler(abortCtrl.signal))) {\n          succeed = false;\n          break;\n        }\n      }\n    } catch (e) {\n      succeed = false;\n      console.error(e);\n    }\n\n    if (succeed) {\n      try {\n        for (const handler of this.#handlers.submit) {\n          // Serialized\n          if (!(await handler(abortCtrl.signal))) {\n            succeed = false;\n            break;\n          }\n        }\n      } catch (e) {\n        succeed = false;\n        console.error(e);\n      }\n    }\n\n    this.#abortCtrl = null;\n    runInAction(() => {\n      this.#isRunning.set(false);\n\n      try {\n        for (const handler of this.#handlers.didSubmit) {\n          handler(succeed);\n        }\n      } catch (e) {\n        console.warn(e);\n      }\n    });\n\n    return succeed;\n  }\n}\n\nexport namespace Submission {\n  /** @inline */\n  export type Handlers = {\n    /**\n     * Called before submission starts\n     * @param abortSignal - Abort signal for the submission\n     * @returns `true` to continue submission, `false` to cancel submission\n     */\n    willSubmit: (abortSignal: AbortSignal) => Promise<boolean>;\n    /**\n     * Async handler that perform the submission (serialized)\n     *\n     * @param abortSignal - Abort signal for the submission\n     * @returns `true` if submission succeeded, `false` if failed or aborted\n     */\n    submit: (abortSignal: AbortSignal) => Promise<boolean>;\n    /**\n     * Called after submission completes\n     *\n     * @param succeed - `true` if submission succeeded, `false` if failed or aborted\n     */\n    didSubmit: (succeed: boolean) => void;\n  };\n}\n"],"mappings":"wMAAA,OAAS,UAAAA,EAAQ,YAAAC,EAAU,kBAAAC,EAAgB,cAAAC,MAAkB,OAC7D,OAAS,MAAMC,MAAc,OAC7B,OAAS,aAAAC,EAAW,WAAAC,EAAS,yBAAAC,EAAuB,WAAAC,MAAe,sBCFnE,OAAS,UAAAC,EAAQ,YAAAC,EAAU,YAAAC,EAAU,kBAAAC,EAAgB,cAAAC,EAAY,YAAAC,MAAgB,OACjF,OAAS,MAAMC,MAAc,OAC7B,OAAS,WAAAC,MAA+B,sBAExC,IAAMC,EAAgB,OAAO,oBAAoB,EAWpCC,EAAN,KAAgB,CACZ,GAAKC,EAAO,EACZ,UACA,UACAC,GACAC,GAAaC,EAAW,IAAI,EAAK,EACjCC,GAAcD,EAAW,IAAiC,IAAI,EAC9DE,GAAcF,EAAW,IAAI,EAAK,EAClCG,GAAqBH,EAAW,IAAI,EAAK,EAClDI,GAA0B,KAG1B,YAAYC,EAA8F,CACxGC,EAAe,IAAI,EACnB,KAAK,UAAYD,EAAK,UACtB,KAAK,UAAYA,EAAK,UACtB,KAAKP,GAA0BO,EAAK,uBAGpCE,EACE,IAAM,CAAC,KAAKL,GAAY,IAAI,EAAG,KAAK,UAAU,YAAY,EAC1D,CAAC,CAACM,EAAYC,CAAY,IAAM,CACzBA,GACH,KAAKN,GAAmB,IAAIK,CAAU,CAE1C,EACA,CAAE,OAAQE,EAAS,OAAQ,CAC7B,CACF,CAOA,IAAI,WAAY,CACd,OAAO,KAAKX,GAAW,IAAI,CAC7B,CAYA,IAAI,gBAAiB,CACnB,OAAO,KAAKE,GAAY,IAAI,IAAM,cACpC,CAKA,IAAI,WAAY,CACd,MAAO,CAAC,CAAC,KAAKA,GAAY,IAAI,CAChC,CAiBA,IAAI,iBAAkB,CACpB,GAAK,KAAKE,GAAmB,IAAI,EACjC,OAAO,KAAK,SACd,CAQA,IAAI,QAA8B,CAChC,OAAO,KAAK,UAAU,iBAAiBQ,EAAQ,MAAM,KAAK,SAAS,CAAC,CACtE,CAQA,IAAI,WAAY,CACd,OAAO,KAAK,UAAU,UAAUA,EAAQ,MAAM,KAAK,SAAS,CAAC,CAC/D,CAYA,OAAQ,CACN,KAAKV,GAAY,IAAI,IAAI,EACzB,KAAKF,GAAW,IAAI,EAAK,EACzB,KAAKG,GAAY,IAAI,EAAK,EAC1B,KAAKU,GAA+B,CACtC,CAQA,eAAgB,CACd,KAAKb,GAAW,IAAI,EAAI,CAC1B,CAcA,cAAcc,EAA6B,QAAS,CAGlD,OAFA,KAAKZ,GAAY,IAAIY,CAAI,EAEjBA,EAAM,CACZ,IAAK,QAAS,CACZ,KAAKD,GAA+B,EACpC,KAAK,YAAY,EACjB,KACF,CACA,IAAK,eAAgB,CACnB,KAAKE,GAAyB,EAC9B,KACF,CACF,CACF,CAQA,aAAc,CACZ,KAAKZ,GAAY,IAAI,EAAI,CAC3B,CAGA,wBAAyB,CACvB,KAAKU,GAA+B,EAChC,KAAK,gBACP,KAAK,cAAc,OAAO,CAE9B,CAEAE,IAA2B,CACzB,KAAKF,GAA+B,EACpC,KAAKR,GAAW,CAAC,WAAW,IAAM,CAChC,KAAK,uBAAuB,CAC9B,EAAG,KAAKN,GAAwB,CAAC,CACnC,CAEAc,IAAiC,CAC3B,KAAKR,KACP,aAAa,KAAKA,EAAQ,EAC1B,KAAKA,GAAW,KAEpB,CAGA,CAACT,CAAa,GAAI,CAChB,MAAO,CACL,WAAY,KAAKO,EACnB,CACF,CACF,EAtHMa,EAAA,CADHC,GA1EUpB,EA2EP,+BAWAmB,EAAA,CADHC,EAAS,QArFCpB,EAsFP,sBAUAmB,EAAA,CADHC,GA/FUpB,EAgGP,yBAcJmB,EAAA,CADCE,GA7GUrB,EA8GX,qBAaAmB,EAAA,CADCE,GA1HUrB,EA2HX,6BAgBAmB,EAAA,CADCE,GA1IUrB,EA2IX,6BAsBAmB,EAAA,CADCE,GAhKUrB,EAiKX,2BC9KF,OAAS,MAAMsB,MAAc,OAsCtB,SAASC,EAAmBC,EAA6C,CAC9E,IAAIC,EAAOC,EAAqB,IAAIF,CAAW,EAC/C,OAAKC,IACHA,EAAO,GAAGD,EAAY,IAAI,KAAKF,EAAO,CAAC,GACvCI,EAAqB,IAAIF,EAAaC,CAAI,GAErCA,CACT,CACA,IAAMC,EAAuB,IAAI,QChDjC,OAAS,cAAAC,EAAY,eAAAC,MAAmB,OAyBjC,IAAMC,EAAsC,OAAO,OAAO,CAC/D,wBAAyB,IACzB,oBAAqB,GACrB,mBAAoB,EACtB,CAAC,EAGYC,EAAeH,EAAW,OAAOE,CAAa,EAQpD,SAASE,EAAcC,EAAoE,CAChG,OAAAJ,EAAY,IAAM,CACZI,IAAW,GACb,OAAO,OAAOF,EAAcD,CAAa,EAEzC,OAAO,OAAOC,EAAcE,CAAM,CAEtC,CAAC,EACMF,CACT,CCjDA,OAAS,cAAAG,EAAY,eAAAC,MAAmB,OAWjC,IAAMC,EAAN,KAAiB,CACbC,GAAaH,EAAW,IAAI,EAAK,EACjCI,GAEL,CACF,WAAY,IAAI,IAChB,OAAQ,IAAI,IACZ,UAAW,IAAI,GACjB,EACAC,GAAqC,KAGrC,IAAI,WAAY,CACd,OAAO,KAAKF,GAAW,IAAI,CAC7B,CAOA,WAAgDG,EAAUC,EAAiC,CACzF,YAAKH,GAAUE,CAAK,EAAE,IAAIC,CAAO,EAC1B,IAAY,KAAK,KAAKH,GAAUE,CAAK,EAAE,OAAOC,CAAO,CAC9D,CAcA,MAAM,MAAyB,CAC7B,KAAKF,IAAY,MAAM,EACvB,IAAMG,EAAY,IAAI,gBACtB,KAAKH,GAAaG,EAElB,IAAIC,EAAU,GAEdR,EAAY,IAAM,CAChB,KAAKE,GAAW,IAAI,EAAI,CAC1B,CAAC,EAED,GAAI,CACF,QAAWI,KAAW,KAAKH,GAAU,WACnC,GAAI,CAAE,MAAMG,EAAQC,EAAU,MAAM,EAAI,CACtCC,EAAU,GACV,KACF,CAEJ,OAASC,EAAG,CACVD,EAAU,GACV,QAAQ,MAAMC,CAAC,CACjB,CAEA,GAAID,EACF,GAAI,CACF,QAAWF,KAAW,KAAKH,GAAU,OAEnC,GAAI,CAAE,MAAMG,EAAQC,EAAU,MAAM,EAAI,CACtCC,EAAU,GACV,KACF,CAEJ,OAASC,EAAG,CACVD,EAAU,GACV,QAAQ,MAAMC,CAAC,CACjB,CAGF,YAAKL,GAAa,KAClBJ,EAAY,IAAM,CAChB,KAAKE,GAAW,IAAI,EAAK,EAEzB,GAAI,CACF,QAAWI,KAAW,KAAKH,GAAU,UACnCG,EAAQE,CAAO,CAEnB,OAASC,EAAG,CACV,QAAQ,KAAKA,CAAC,CAChB,CACF,CAAC,EAEMD,CACT,CACF,EJ9FA,IAAME,EAAW,IAAI,QACfC,EAAiB,OAAO,qBAAqB,EAC7CC,EAAgB,OAAO,oBAAoB,EAapCC,EAAN,MAAMA,CAAQ,CACV,GAAKC,EAAO,EACZC,GACA,QACA,UACAC,GACAC,GAAc,IAAIC,EAClBC,GAAU,IAAI,IACdC,GAAY,IAAI,IAChBC,GAAeC,EAAW,IAAyB,CAAC,CAAC,EAmB9D,OAAO,IAAsBC,EAAYC,EAA2B,CAClE,IAAMC,EAAO,KAAK,QAAQF,EAASC,CAAO,EAC1C,GAAI,CAACC,EACH,MAAM,IAAI,UAAU,6BAA6B,EAEnD,OAAOA,CACT,CAOA,OAAO,QAA0BF,EAAYC,EAAkC,CAC7E,GAAI,CAACD,GAAW,OAAOA,GAAY,SACjC,OAAO,KAGTC,IAAYb,EAEZ,IAAIe,EAAMhB,EAAS,IAAIa,CAAO,EACzBG,IACHA,EAAM,IAAI,IACVhB,EAAS,IAAIa,EAASG,CAAG,GAG3B,IAAIC,EAAWD,EAAI,IAAIF,CAAO,EAC9B,OAAKG,IACHA,EAAW,IAAI,KAAQf,EAAe,CACpC,QAAAW,EACA,QAAAC,CACF,CAAC,EACDE,EAAI,IAAIF,EAASG,CAAQ,GAEpBA,CACT,CAWA,OAAO,QAAQJ,EAAiBC,EAAkB,CAChD,IAAME,EAAMhB,EAAS,IAAIa,CAAO,EAC3BG,IACDF,EACFE,EAAI,OAAOF,CAAO,EAElBE,EAAI,MAAM,EAEd,CAEQ,YACNE,EACAC,EAIA,CACA,GAAID,IAAUhB,EACZ,MAAM,IAAI,MAAM,qBAAqB,EAGvC,KAAKG,GAAWc,EAAK,QACrB,KAAK,QAAUC,EAAQ,IAAID,EAAK,OAAO,EACvC,KAAK,UAAYE,EAAU,IAAIF,EAAK,OAAO,EAC3C,KAAKb,GAAiB,IAAIgB,EAAsBH,EAAK,QAAUI,GAAUpB,EAAK,QAAQoB,EAAM,KAAM,KAAKlB,EAAQ,CAAC,EAEhHmB,EAAe,IAAI,EAEnB,KAAKjB,GAAY,WAAW,YAAckB,GAAY,CAChDA,GACF,KAAK,MAAM,CAEf,CAAC,CACH,CAQA,IAAI,QAA+B,CACjC,MAAO,CACL,GAAGC,EACH,GAAG,KAAKf,GAAa,IAAI,CAC3B,CACF,CAIA,UAKKgB,GAAS,CACR,OAAOA,GAAS,SAClB,OAAO,OAAO,KAAKhB,GAAa,IAAI,EAAGgB,CAAI,EAE3C,KAAKhB,GAAa,IAAI,CAAC,CAAC,CAE5B,EAOA,IAAI,SAAU,CACZ,OAAO,KAAK,QAAQ,OACtB,CAOA,IAAI,SAAU,CACZ,OAAO,KAAK,UAAU,OACxB,CAOA,IAAI,mBAAoB,CACtB,OAAO,KAAK,UAAU,eACxB,CAOA,IAAI,uBAAwB,CAC1B,OAAO,KAAK,UAAU,mBACxB,CAOA,IAAI,cAAe,CACjB,OAAO,KAAK,UAAU,YACxB,CAGA,IAAI,cAAe,CACjB,OAAO,KAAKJ,GAAY,SAC1B,CAIA,IAAI,QAAS,CACX,OAAO,KAAK,cAAgB,KAAK,YACnC,CAWA,IAAI,WAAY,CACd,MACE,CAAC,KAAK,SACL,KAAK,OAAO,oBAAsB,KAAK,WACvC,KAAK,OAAO,qBAAuB,KAAK,QAE7C,CAOA,IAAI,UAAW,CACb,OAAO,KAAKD,GAAe,OAC7B,CAIA,aAAc,CACZ,QAAWsB,KAAS,KAAKnB,GAAQ,OAAO,EACtCmB,EAAM,YAAY,EAEpB,QAAWL,KAAS,KAAKjB,GACvBiB,EAAM,KAAK,YAAY,CAE3B,CAYA,OAAQ,CAEN,KAAK,QAAQ,MAAM,EACnB,QAAWK,KAAS,KAAKnB,GAAQ,OAAO,EACtCmB,EAAM,MAAM,EAEd,QAAWL,KAAS,KAAKjB,GACvBiB,EAAM,KAAK,MAAM,CAErB,CAOA,aAAc,CACZ,KAAK,QAAQ,cAAc,CAC7B,CAiBA,MAAM,OAAOJ,EAA4B,CACvC,MAAI,CAACA,GAAM,OAAS,CAAC,KAAK,UAAkB,GACrC,KAAKZ,GAAY,KAAK,CAC/B,CAeA,WAII,IAAIY,IAAS,KAAKZ,GAAY,WAAW,GAAGY,CAAI,EAOpD,SAASU,EAA8B,CACrC,IAAID,EAAQ,KAAKnB,GAAQ,IAAIoB,CAAS,EACtC,OAAKD,IACHA,EAAQ,IAAIE,EAAU,CACpB,UAAW,OAAOD,CAAS,EAC3B,UAAW,KAAK,UAChB,uBAAwB,IAAM,KAAK,OAAO,uBAC5C,CAAC,EACD,KAAKpB,GAAQ,IAAIoB,EAAWD,CAAK,GAE5BA,CACT,CAGAG,GAAeC,EAAoBC,EAA2B,CAC5D,IAAIC,EAAU,KAAKxB,GAAU,IAAIsB,CAAU,EAC3C,OAAKE,IACHA,EAAUD,EAAO,EACjB,KAAKvB,GAAU,IAAIsB,EAAYE,CAAO,GAEjCA,CACT,CAGAC,GAA0C,CACxCD,EACAE,IACG,CACH,IAAMC,EAAM,GAAGC,EAAmBJ,CAAO,CAAC,IAAIE,GAAQ,QAAQ,GACxDnB,EAAW,KAAKc,GAAeM,EAAK,IAAM,IAAIH,EAAQ,KAAME,CAAM,CAAC,EACzE,OAAAnB,EAAS,OAASmB,EACXnB,EAAS,KAClB,EAGAsB,GAA4C,CAC1CV,EACAK,EACAE,IACG,CACH,IAAMC,EAAM,GAAGR,CAAS,IAAIS,EAAmBJ,CAAO,CAAC,IAAIE,GAAQ,QAAQ,GACrEnB,EAAW,KAAKc,GAAeM,EAAK,IAAM,CAC9C,IAAMT,EAAQ,KAAK,SAASC,CAAS,EACrC,OAAO,IAAIK,EAAQN,EAAOQ,CAAM,CAClC,CAAC,EACD,OAAAnB,EAAS,OAASmB,EACXnB,EAAS,KAClB,EAGAuB,GAAsD,CACpDC,EACAP,EACAE,IACG,CACH,IAAMC,EAAM,GAAGI,EAAW,KAAK,GAAG,CAAC,IAAIH,EAAmBJ,CAAO,CAAC,IAAIE,GAAQ,QAAQ,GAChFnB,EAAW,KAAKc,GAAeM,EAAK,IAAM,CAC9C,IAAMK,EAASD,EAAW,IAAKE,GAAS,KAAK,SAASA,CAAI,CAAC,EAC3D,OAAO,IAAIT,EAAQQ,EAAQN,CAAM,CACnC,CAAC,EACD,OAAAnB,EAAS,OAASmB,EACXnB,EAAS,KAClB,EAYA,KAA2B,IAAIE,IACzB,OAAOA,EAAK,CAAC,GAAM,SACd,KAAKoB,GAAapB,EAAK,CAAC,EAAUA,EAAK,CAAC,EAAGA,EAAK,CAAC,CAAC,EAEvD,MAAM,QAAQA,EAAK,CAAC,CAAC,EAChB,KAAKqB,GAAkBrB,EAAK,CAAC,EAAGA,EAAK,CAAC,EAAGA,EAAK,CAAC,CAAC,EAElD,KAAKgB,GAAYhB,EAAK,CAAC,EAAGA,EAAK,CAAC,CAAC,EAW1C,UAAUU,EAA8Be,EAAqB,GAA4B,CACvF,IAAMhB,EAAQ,KAAK,SAASC,CAAS,EAErC,MAAI,CAACe,GAAsB,CAAChB,EAAM,gBACzB,IAAI,IAKNA,EAAM,MACf,CASA,aAAaC,EAA+B,CAC1C,OAAO,KAAK,UAAU,iBAAiBA,EAAYgB,EAAQ,MAAMhB,CAAS,EAAIgB,EAAQ,KAAM,EAAI,CAClG,CAQA,IAAI,mBAAoB,CACtB,OAAO,KAAK,UAAU,iBACxB,CAGA,CAAC3C,CAAa,GAAI,CAChB,MAAO,CACL,OAAQ,KAAKO,GACb,SAAU,KAAKC,GACf,WAAY,KAAKH,EACnB,CACF,CACF,EAlUMuC,EAAA,CADHC,EAAS,QAlHC5C,EAmHP,sBASJ2C,EAAA,CADCE,EAAO,OA3HG7C,EA4HX,yBAiEI2C,EAAA,CADHC,GA5LU5C,EA6LP,sBAaA2C,EAAA,CADHC,GAzMU5C,EA0MP,yBAmBJ2C,EAAA,CADCE,GA5NU7C,EA6NX,2BAmBA2C,EAAA,CADCE,GA/OU7C,EAgPX,qBAyLI2C,EAAA,CADHC,GAxaU5C,EAyaP,iCAzaC,IAAM8C,EAAN9C","names":["action","computed","makeObservable","observable","uuidV4","Validator","Watcher","StandardNestedFetcher","KeyPath","action","comparer","computed","makeObservable","observable","reaction","uuidV4","KeyPath","internalToken","FormField","uuidV4","#getFinalizationDelayMs","#isTouched","observable","#changeType","#isReported","#isReportedDelayed","#timerId","args","makeObservable","reaction","isReported","isValidating","comparer","KeyPath","#cancelFinalizeChangeWithDelay","type","#finalizeChangeWithDelay","__decorateClass","computed","action","uuidV4","getSafeBindingName","constructor","name","safeBindingNameCache","observable","runInAction","defaultConfig","globalConfig","configureForm","config","observable","runInAction","Submission","#isRunning","#handlers","#abortCtrl","event","handler","abortCtrl","succeed","e","registry","defaultFormKey","internalToken","_Form","uuidV4","#formKey","#nestedFetcher","#submission","Submission","#fields","#bindings","#localConfig","observable","subject","formKey","form","map","instance","token","args","Watcher","Validator","StandardNestedFetcher","entry","makeObservable","succeed","globalConfig","arg0","field","fieldName","FormField","#defineBinding","bindingKey","create","binding","#bindToForm","config","key","getSafeBindingName","#bindToField","#bindToMultiField","fieldNames","fields","name","includePreReported","KeyPath","__decorateClass","computed","action","Form"]}