{"version":3,"file":"kform-react.cjs","sources":["../../src/contexts/FormContext.ts","../../src/utils/errors.ts","../../src/hooks/useFormContext.ts","../../src/hooks/useResolvedPath.ts","../../src/components/CurrentPath.tsx","../../src/utils/ignorePromiseCancellationException.ts","../../src/utils/useLatestValues.ts","../../src/utils/iterableUtils.ts","../../src/utils/promiseUtils.ts","../../src/utils/useConstant.ts","../../src/utils/useEqualityFn.ts","../../src/hooks/useFormManager.ts","../../src/hooks/useController.ts","../../src/utils/equals.ts","../../src/utils/usePrevious.ts","../../src/hooks/useNewFormManager.ts","../../src/hooks/useForm.ts","../../src/components/Form.tsx","../../src/hooks/useFormatter.ts","../../src/components/FormattedValue.tsx","../../src/hooks/useInput.ts","../../src/components/Input.tsx","../../src/hooks/useCurrentPath.ts","../../src/utils/fileUtils.ts","../../src/hooks/useFileInput.ts","../../src/hooks/useFormattedValue.ts","../../src/hooks/useFormController.ts","../../src/utils/binarySearch.ts","../../src/hooks/useIssuesTracker.ts","../../src/utils/listableUtils.ts","../../src/hooks/useListableInput.ts","../../src/utils/numericUtils.ts","../../src/hooks/useNumericInput.ts","../../src/hooks/useSubmitting.ts","../../src/hooks/useSubscription.ts","../../src/utils/temporalUtils.ts","../../src/hooks/useTemporalInput.ts","../../src/utils/setKFormLogLevel.ts"],"sourcesContent":["import { type AbsolutePath, FormManager } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { type FormController } from \"../hooks/useForm\";\n\n/**\n * Value of the form context.\n */\nexport interface FormContextValue<T = unknown> {\n  /**\n   * Form manager in scope.\n   */\n  formManager: FormManager;\n  /**\n   * Current path in context.\n   *\n   * Paths provided to e.g. `useController` are relative to this path.\n   */\n  currentPath: AbsolutePath;\n  /**\n   * Controller of the form in scope.\n   */\n  controller?: FormController<T>;\n}\n\n/**\n * Context of a form.\n */\nexport const FormContext = React.createContext<FormContextValue<any> | null>(\n  null,\n);\n","import { AbsolutePath } from \"@kform/core\";\n\n/**\n * Error thrown when attempting to access the context of a form when no form is\n * in context.\n */\nexport class NoFormContextError extends Error {\n  constructor() {\n    super(\"No form context found\");\n    this.name = this.constructor.name;\n  }\n}\n\n/**\n * Error thrown when attempting to access a form value but no form is in context\n * and no form manager was provided via an option.\n */\nexport class NoFormManagerError extends Error {\n  constructor() {\n    super(\"No form manager found\");\n    this.name = this.constructor.name;\n  }\n}\n\n/**\n * Error thrown when attempting to access the controller of a form but no form\n * controller is in context.\n */\nexport class NoFormControllerError extends Error {\n  constructor() {\n    super(\"No form controller found\");\n    this.name = this.constructor.name;\n  }\n}\n\n/**\n * Error occurring at a certain path.\n */\nexport class PathError extends Error {\n  constructor(path: AbsolutePath, message: string) {\n    super(`At '${path.toString()}': ${message}`);\n    this.name = this.constructor.name;\n  }\n}\n","import * as React from \"react\";\n\nimport { FormContext, FormContextValue } from \"../contexts/FormContext\";\nimport { NoFormContextError } from \"../utils/errors\";\n\n/**\n * Hook providing access to the current context within a form.\n * @throws {NoFormContextError} When no form is in context.\n * @returns The current context within a form.\n */\nexport function useFormContext<T = unknown>(): FormContextValue<T> {\n  const formContext = React.useContext(FormContext);\n  if (!formContext) {\n    throw new NoFormContextError();\n  }\n  return formContext;\n}\n","import { AbsolutePath, Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { FormContext } from \"../contexts/FormContext\";\nimport { NoFormContextError } from \"../utils/errors\";\n\n/**\n * Resolves a given path against the current form path or against\n * {@link currentPath} when provided. The returned absolute path has a stable\n * identity.\n * @param path Path to resolve against the current path.\n * @param currentPath Optional current path argument. When provided, this path\n * is used instead of the form context's current path.\n * @returns Resolved absolute path with a stable identity.\n */\nexport function useResolvedPath(\n  path: Path | string = Path.CURRENT,\n  currentPath?: AbsolutePath,\n): AbsolutePath {\n  const formContext = React.useContext(FormContext);\n  currentPath ??= formContext?.currentPath;\n  if (currentPath == null) {\n    throw new NoFormContextError();\n  }\n\n  const stableAbsolutePathRef = React.useRef<AbsolutePath>();\n  const absolutePath = React.useMemo(\n    () => currentPath.resolve(path),\n    [currentPath, path],\n  );\n  if (!absolutePath.equals(stableAbsolutePathRef.current)) {\n    stableAbsolutePathRef.current = absolutePath;\n  }\n  return stableAbsolutePathRef.current!;\n}\n","import { Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { FormContext, FormContextValue } from \"../contexts/FormContext\";\nimport { useFormContext } from \"../hooks/useFormContext\";\nimport { useResolvedPath } from \"../hooks/useResolvedPath\";\n\n/**\n * Properties of the current path component.\n */\nexport interface CurrentPathProps {\n  /**\n   * Path to set as the new current path for all children of this component.\n   *\n   * This path will be resolved against the current path.\n   * @default Path.CURRENT\n   */\n  path?: Path | string;\n  children?: React.ReactNode;\n}\n\n/**\n * Component used to specify a new current path for its children.\n *\n * This component must be rendered within a form context. The provided path will\n * be resolved against the current path in context.\n */\nexport function CurrentPath({\n  path = Path.CURRENT,\n  children,\n}: CurrentPathProps) {\n  const formContext = useFormContext();\n  const resolvedPath = useResolvedPath(path);\n\n  const newFormContext = React.useMemo<FormContextValue>(\n    () => ({\n      formManager: formContext.formManager,\n      currentPath: resolvedPath,\n      controller: formContext.controller,\n    }),\n    [formContext.controller, formContext.formManager, resolvedPath],\n  );\n\n  return (\n    <FormContext.Provider value={newFormContext}>\n      {children}\n    </FormContext.Provider>\n  );\n}\n","import { PromiseCancellationException } from \"@kform/core\";\n\n/**\n * Function that re-throws the provided {@link caughtError} argument, unless it\n * is an instance of {@link PromiseCancellationException}.\n *\n * This is useful in scenarios where cancellations are expected and, as such,\n * shouldn't be regarded as errors.\n * @param caughtError Caught error.\n * @throws {caughtError} When not an instance of\n * {@link PromiseCancellationException}.\n */\nexport function ignorePromiseCancellationException(caughtError: unknown) {\n  if (!(caughtError instanceof PromiseCancellationException)) {\n    throw caughtError;\n  }\n}\n","import * as React from \"react\";\n\n/**\n * Hook providing a stable identity object containing the latest values. These\n * values should **not** be accessed during render time.\n * @param values Object containing all values.\n * @returns Stable identity object containing said values.\n */\nexport function useLatestValues<T extends Record<keyof T, unknown>>(\n  values: T,\n): T {\n  const valuesRef = React.useRef<T>({} as T);\n  Object.assign(valuesRef.current, values);\n  return valuesRef.current;\n}\n","/**\n * Simple `Array.fromAsync` implementation.\n * @param iterable Iterable to transform into an array.\n * @returns Promise containing an array with all the elements in the iterable.\n */\nexport async function arrayFromAsync<T>(\n  iterable: Iterable<T> | AsyncIterable<T>,\n): Promise<T[]> {\n  const array = [];\n  for await (const el of iterable) {\n    array.push(el);\n  }\n  return array;\n}\n","/**\n * Whether a given value is [promise-like]{@link PromiseLike}.\n * @param value Value to check if it is promise-like.\n * @returns Whether the provided value is like a promise.\n */\nexport function isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n  return typeof (value as any)?.then === \"function\";\n}\n","import * as React from \"react\";\n\n/**\n * Hook for creating a value exactly once.\n * @param fn Function which created the value to return.\n * @returns Value created on the first render of the hook.\n */\nexport function useConstant<T>(fn: () => T): T {\n  const ref = React.useRef<{ value: T }>();\n  if (!ref.current) {\n    ref.current = { value: fn() };\n  }\n  return ref.current.value;\n}\n","import * as React from \"react\";\n\nconst INITIAL = Symbol();\n\nexport function useEqualityFn<TState, TResult>(\n  selector: (state: TState) => TResult,\n  equalityFn: (v1: TResult, v2: TResult) => boolean = Object.is,\n): (state: TState) => TResult {\n  const latest = React.useRef<TResult | typeof INITIAL>(INITIAL);\n  return (state) => {\n    const next = selector(state);\n    return latest.current !== INITIAL && equalityFn(latest.current, next)\n      ? latest.current\n      : (latest.current = next);\n  };\n}\n","import { type FormManager } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { FormContext } from \"../contexts/FormContext\";\nimport { NoFormManagerError } from \"../utils/errors\";\n\n/**\n * Hook providing access to the form manager within the context of a form. If a\n * form manager is provided as argument, then the provided argument is returned\n * instead.\n * @param formManager Optional argument which, when provided, is simply returned\n * as-is instead of the form manager within the context of a form.\n * @throws {NoFormManagerError} When no form manager was found.\n * @returns The form manager within the context of a form or, when provided, the\n * given form manager argument.\n */\nexport function useFormManager(formManager?: FormManager): FormManager {\n  const formContext = React.useContext(FormContext);\n  const relevantFormManager = formManager ?? formContext?.formManager;\n  if (relevantFormManager == null) {\n    throw new NoFormManagerError();\n  }\n  return relevantFormManager;\n}\n","import {\n  AbsolutePath,\n  AbsolutePathFragment,\n  CancellablePromise,\n  DisplayStatus,\n  FormManager,\n  Path,\n  Schema,\n  SealedFormManagerEvent,\n  SealedLocatedValidationIssue,\n  SealedValidationIssue,\n  SealedValueEvent,\n  StateEvent,\n  ValidationStatus,\n  ValueEvent,\n} from \"@kform/core\";\nimport * as React from \"react\";\nimport { createStore, useStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\n\nimport { ignorePromiseCancellationException } from \"../utils/ignorePromiseCancellationException\";\nimport { arrayFromAsync } from \"../utils/iterableUtils\";\nimport { isPromiseLike } from \"../utils/promiseUtils\";\nimport { shallow } from \"../utils/shallow\";\nimport { useConstant } from \"../utils/useConstant\";\nimport { useEqualityFn } from \"../utils/useEqualityFn\";\nimport { useLatestValues } from \"../utils/useLatestValues\";\nimport { useFormManager } from \"./useFormManager\";\nimport { useResolvedPath } from \"./useResolvedPath\";\n\n/**\n * Options available to the {@link useController} hook.\n */\nexport interface ControllerOptions<\n  T = unknown,\n  TState extends ControllerState<T> = ControllerState<T>,\n> {\n  /**\n   * Required if no form context is in scope.\n   *\n   * If a form context is in scope and this value is also provided, then the\n   * provided form manager will be used, in which case the current path of the\n   * form context is ignored.\n   */\n  formManager?: FormManager;\n  /**\n   * Whether to enable the controller.\n   *\n   * @default true\n   */\n  enabled?: boolean;\n  /**\n   * Default extra state.\n   * @internal\n   */\n  _defaultState?: Partial<TState>;\n  /**\n   * Function called once the controller has been initialised.\n   *\n   * @param info Controller's info.\n   */\n  onInitialized?: (\n    state: TState & InitializedControllerState<T>,\n  ) => void | PromiseLike<void>;\n  /**\n   * Function called whenever the controller is uninitialised.\n   */\n  onUninitialized?: (state: TState & UninitializedControllerState<T>) => void;\n  /**\n   * Function called whenever an event matching the controller's path is\n   * emitted.\n   *\n   * @param event Form manager event.\n   */\n  onFormManagerEvent?: (\n    event: SealedFormManagerEvent,\n    state: TState & InitializedControllerState<T>,\n  ) => void | PromiseLike<void>;\n  onValueChange?: (\n    event: SealedValueEvent,\n    state: TState & InitializedControllerState<T>,\n  ) => void | PromiseLike<void>;\n  onValidationStatusChange?: (\n    event: StateEvent.ValidationChange,\n    state: TState & InitializedControllerState<T>,\n  ) => void | PromiseLike<void>;\n  onDisplayStatusChange?: (\n    event: StateEvent.DisplayChange,\n    state: TState & InitializedControllerState<T>,\n  ) => void | PromiseLike<void>;\n  onDirtyStatusChange?: (\n    event: StateEvent.DirtyChange,\n    state: TState & InitializedControllerState<T>,\n  ) => void | PromiseLike<void>;\n  onTouchedStatusChange?: (\n    event: StateEvent.TouchedChange,\n    state: TState & InitializedControllerState<T>,\n  ) => void | PromiseLike<void>;\n}\n\n/**\n * Controller for a value of the form.\n */\nexport interface Controller<\n  T = unknown,\n  TState extends ControllerState<T> = ControllerState<T>,\n> {\n  /**\n   * Returns the current state of the controller.\n   */\n  readonly getState: () => TState;\n  /**\n   * Sets the (non-private) state of the controller.\n   * @param state State to set.\n   * @internal\n   */\n  readonly _setState: (\n    state: Partial<TState> | ((state: TState) => Partial<TState>),\n  ) => void;\n  /**\n   * Subscribes to changes in the controller's state.\n   *\n   * @param selector Selector used to select which part of the controller's\n   * state to observe.\n   * @param listener Function called whenever the selected state changes.\n   * @param options Subscription options.\n   * @returns Function which should be called to unsubscribe.\n   */\n  readonly subscribe: <TSelected = unknown>(\n    selector: (state: TState) => TSelected,\n    listener: (\n      selectedState: TSelected,\n      prevSelectedState: TSelected | undefined,\n    ) => void,\n    options?: ControllerSubscriptionOptions<TSelected>,\n  ) => () => void;\n  /**\n   * Hook used to select part of the controller's state.\n   *\n   * A component using this hook is re-rendered whenever said part of the state\n   * changes.\n   * @param selector Selector used to select part of the controller's state.\n   */\n  readonly useState: (() => TState) &\n    (<TResult = unknown>(\n      selector: (state: TState) => TResult,\n      options?: ControllerUseStateOptions<TResult>,\n    ) => TResult);\n  /**\n   * Hook which returns the form manager being used by the controller.\n   */\n  readonly useFormManager: () => FormManager;\n  /**\n   * Hook which returns the schema of the value being controlled.\n   */\n  readonly useSchema: () => Schema<T>;\n  /**\n   * Hook which returns the path of the value being controlled by this\n   * controller.\n   *\n   * This path will not contain any provided recursive wildcards.\n   */\n  readonly usePath: () => AbsolutePath;\n  /**\n   * Hook which returns the schema path of the value being controlled.\n   */\n  readonly useSchemaPath: () => AbsolutePath;\n  /**\n   * Hook which returns whether the controller is currently observing\n   * descendants.\n   */\n  readonly useObservingDescendants: () => boolean;\n  /**\n   * Hook which returns whether the controller has been initialised.\n   */\n  readonly useInitialized: () => boolean;\n  /**\n   * Hook which returns whether a value exists at the path being controlled.\n   *\n   * Returns `undefined` when the controller is not initialised.\n   */\n  readonly useExists: () => boolean | undefined;\n  /**\n   * Hook which returns the form value being controlled.\n   *\n   * Note that, when observing descendants, this hook will cause a component to\n   * rerender when a descendant is changed, even if the identity of the value\n   * hasn't changed.\n   *\n   * Returns `undefined` when the controller is not initialised.\n   */\n  readonly useValue: () => T | undefined;\n  /**\n   * Hook which returns whether the value being controlled is dirty.\n   *\n   * Returns `undefined` when the controller is not initialised.\n   */\n  readonly useDirty: () => boolean | undefined;\n  /**\n   * Hook which returns whether the value being controlled is touched.\n   *\n   * Returns `undefined` when the controller is not initialised.\n   */\n  readonly useTouched: () => boolean | undefined;\n  /**\n   * Hook which returns the issues of the value being controlled.\n   *\n   * Returns `undefined` when the controller is not initialised.\n   */\n  readonly useIssues: () => SealedValidationIssue[] | undefined;\n  /**\n   * Hook which returns the validation status of the value being controlled.\n   *\n   * Returns `undefined` when the controller is not initialised.\n   */\n  readonly useValidationStatus: () => ValidationStatus | undefined;\n  /**\n   * Hook which returns the display status of the value being controlled.\n   *\n   * Returns `undefined` when the controller is not initialised.\n   */\n  readonly useDisplayStatus: () => DisplayStatus | undefined;\n\n  readonly get: (<TValue = unknown, TResult = unknown>(\n    path: Path | string,\n    valueHandler: (value: TValue) => TResult | PromiseLike<TResult>,\n  ) => CancellablePromise<TResult>) &\n    (<TResult = unknown>(\n      valueHandler: (value: T) => TResult | PromiseLike<TResult>,\n    ) => CancellablePromise<TResult>);\n  readonly getClone: (() => CancellablePromise<T>) &\n    (<TValue = unknown>(path?: Path | string) => CancellablePromise<TValue>);\n  readonly set: ((\n    path: Path | string,\n    toSet: unknown,\n  ) => CancellablePromise<void>) &\n    ((toSet: T) => CancellablePromise<void>);\n  readonly reset: (path?: Path | string) => CancellablePromise<void>;\n  readonly remove: (path?: Path | string) => CancellablePromise<void>;\n  readonly validate: (\n    path?: Path | string,\n  ) => CancellablePromise<SealedLocatedValidationIssue[]>;\n  readonly setDirty: (path?: Path | string) => CancellablePromise<void>;\n  readonly setPristine: (path?: Path | string) => CancellablePromise<void>;\n  readonly setTouched: (path?: Path | string) => CancellablePromise<void>;\n  readonly setUntouched: (path?: Path | string) => CancellablePromise<void>;\n}\n\n/**\n * Options available to the controller's `useState` hook.\n */\nexport interface ControllerUseStateOptions<T = unknown> {\n  /**\n   * Function used to specify when two selections are considered equal to each\n   * other.\n   * @param v1 First selection.\n   * @param v2 Second selection.\n   * @returns Whether the two selections are considered equal.\n   */\n  equalityFn?: (v1: T, v2: T) => boolean;\n}\n\n/**\n * Options available when subscribing to the state of the controller.\n */\nexport interface ControllerSubscriptionOptions<T = unknown> {\n  /**\n   * Function used to specify when two selections are considered equal to each\n   * other.\n   * @param v1 First selection.\n   * @param v2 Second selection.\n   * @returns Whether the two selections are considered equal.\n   */\n  equalityFn?: (v1: T, v2: T) => boolean;\n  /**\n   * Whether the subscription's listener should be invoked immediately.\n   */\n  fireImmediately?: boolean;\n}\n\n/**\n * Controller's state.\n */\nexport type ControllerState<T = unknown> =\n  | UninitializedControllerState<T>\n  | InitializedControllerState<T>;\n\n/**\n * Base controller's state.\n */\nexport interface BaseControllerState<T = unknown> {\n  /**\n   * Form manager being used by the controller.\n   */\n  readonly formManager: FormManager;\n  /**\n   * Schema of the form value being controlled.\n   */\n  readonly schema: Schema<T>;\n  /**\n   * Path of the form value being controlled.\n   */\n  readonly path: AbsolutePath;\n  /**\n   * Schema path of the form value being controller.\n   */\n  readonly schemaPath: AbsolutePath;\n  /**\n   * Whether the controller is observing descendants.\n   *\n   * This will be `true` when the path provided to the controller ends in a\n   * recursive wildcard.\n   */\n  readonly observingDescendants: boolean;\n  /**\n   * Whether the controller has been initialised.\n   */\n  readonly initialized: boolean;\n  /**\n   * Whether the form value being controlled exists.\n   */\n  readonly exists: boolean | undefined;\n  /**\n   * Form value.\n   */\n  readonly value: T | undefined;\n  /**\n   * Whether the form value being controlled is dirty.\n   */\n  readonly dirty: boolean | undefined;\n  /**\n   * Whether the form value being controlled has been touched.\n   */\n  readonly touched: boolean | undefined;\n  /**\n   * Validation issues associated with the form value being controlled.\n   */\n  readonly issues: SealedValidationIssue[] | undefined;\n  /**\n   * Validation status of the form value being controlled.\n   */\n  readonly validationStatus: ValidationStatus | undefined;\n  /**\n   * Display status of the form value being controlled.\n   */\n  readonly displayStatus: DisplayStatus | undefined;\n}\n\n/**\n * Uninitialised controller's state.\n */\nexport interface UninitializedControllerState<T = unknown>\n  extends BaseControllerState<T> {\n  readonly initialized: false;\n  readonly exists: undefined;\n  readonly value: undefined;\n  readonly dirty: undefined;\n  readonly touched: undefined;\n  readonly issues: undefined;\n  readonly validationStatus: undefined;\n  readonly displayStatus: undefined;\n}\n\n/**\n * Initialized controller's state.\n */\nexport type InitializedControllerState<T = unknown> =\n  | NonexistentValueControllerState<T>\n  | ExistingValueControllerState<T>;\n\n/**\n * Controller state of a nonexistent form value.\n */\nexport interface NonexistentValueControllerState<T = unknown>\n  extends BaseControllerState<T> {\n  readonly initialized: true;\n  readonly exists: false;\n  readonly value: undefined;\n  readonly dirty: undefined;\n  readonly touched: undefined;\n  readonly issues: undefined;\n  readonly validationStatus: undefined;\n  readonly displayStatus: undefined;\n}\n\n/**\n * Controller state of an existing form value.\n */\nexport interface ExistingValueControllerState<T = unknown>\n  extends BaseControllerState<T> {\n  readonly initialized: true;\n  readonly exists: true;\n  readonly value: T;\n  readonly dirty: boolean;\n  readonly touched: boolean;\n  readonly issues: SealedValidationIssue[];\n  readonly validationStatus: ValidationStatus;\n  readonly displayStatus: DisplayStatus;\n}\n\n/**\n * State internal to the controller's Zustand store.\n *\n * We wrap the stored value within an array so that we can trigger Zustand\n * updates by simply replacing the wrapper, even if the underlying value's\n * identity hasn't changed.\n */\ntype InternalControllerState<\n  T = unknown,\n  TState extends ControllerState<T> = ControllerState<T>,\n> = Omit<TState, \"value\"> & {\n  value: [T] | undefined;\n} & Record<string, unknown>;\n\n/**\n * Value representing an uninitialized controller state.\n */\nconst UNINITIALIZED_CONTROLLER_STATE = {\n  initialized: false,\n  exists: undefined,\n  value: undefined,\n  dirty: undefined,\n  touched: undefined,\n  issues: undefined,\n  validationStatus: undefined,\n  displayStatus: undefined,\n} as const;\n\n/**\n * Value representing a controller state of a nonexistent form value.\n */\nconst NONEXISTENT_VALUE_CONTROLLER_STATE = {\n  initialized: true,\n  exists: false,\n  value: undefined,\n  dirty: undefined,\n  touched: undefined,\n  issues: undefined,\n  validationStatus: undefined,\n  displayStatus: undefined,\n} as const;\n\n/**\n * Hook providing access to a controller used to read and control a value of\n * the form.\n * @param path Path of the form value to control, relative to the current path.\n *\n * The path must consist of only identifiers, except for the last fragment,\n * which may be a recursive wildcard to indicate that descendants should also be\n * observed.\n * @param options Available options.\n * @throws {Error} When {@link path} is invalid or contains fragments other than\n * ids.\n * @returns A controller used to read and control the form value.\n */\nexport function useController<T = unknown>(\n  path?: Path | string,\n  options?: undefined,\n): Controller<T>;\nexport function useController<\n  T = unknown,\n  TState extends ControllerState<T> = ControllerState<T>,\n>(\n  path: Path | string | undefined,\n  options: ControllerOptions<T, TState>,\n): Controller<T, TState>;\nexport function useController<\n  T = unknown,\n  TState extends ControllerState<T> = ControllerState<T>,\n>(\n  path?: Path | string,\n  {\n    formManager: formManagerOption,\n    enabled = true,\n    _defaultState,\n    onInitialized,\n    onUninitialized,\n    onFormManagerEvent,\n    onValueChange,\n    onValidationStatusChange,\n    onDisplayStatusChange,\n    onDirtyStatusChange,\n    onTouchedStatusChange,\n  }: ControllerOptions<T, TState> = {},\n): Controller<T, TState> {\n  const formManager = useFormManager(formManagerOption);\n  const resolvedPath = useResolvedPath(\n    path,\n    formManagerOption != null ? AbsolutePath.ROOT : undefined,\n  );\n\n  // Descendants are being observed when the last fragment of the path is a\n  // recursive wildcard\n  const observingDescendants =\n    resolvedPath.lastFragment === AbsolutePathFragment.RecursiveWildcard;\n  // Path of the value being controlled (excluding the possible recursive\n  // wildcard)\n  const valuePath = React.useMemo(\n    () =>\n      observingDescendants\n        ? new AbsolutePath(resolvedPath.fragments.slice(0, -1))\n        : resolvedPath,\n    [resolvedPath, observingDescendants],\n  );\n\n  // Refuse invalid paths\n  if (!formManager.isValidPath(valuePath)) {\n    throw new Error(`Invalid path: '${resolvedPath.toString()}'.`);\n  }\n\n  // Refuse value paths that don't consist of identifiers only\n  if (\n    valuePath.fragments.some(\n      (frag) => !(frag instanceof AbsolutePathFragment.Id),\n    )\n  ) {\n    throw new Error(\n      \"Controller path must only contain ids (except for the last fragment, \" +\n        \"which may be a recursive wildcard).\",\n    );\n  }\n\n  // Schema info\n  const schemaInfo = React.useMemo(\n    () => Array.from(formManager.schemaInfo<T>(valuePath))[0],\n    [formManager, valuePath],\n  );\n\n  // Controller's Zustand store\n  const store = useConstant(() =>\n    createStore<InternalControllerState<T, TState>>()(\n      subscribeWithSelector(\n        () =>\n          ({\n            formManager,\n            schema: schemaInfo.schema,\n            path: valuePath,\n            schemaPath: schemaInfo.path,\n            observingDescendants,\n            ...UNINITIALIZED_CONTROLLER_STATE,\n            ..._defaultState,\n          }) as any,\n      ),\n    ),\n  );\n\n  // Controller functions:\n  const controller: Controller<T, TState> = React.useMemo(\n    () => ({\n      getState: () => unwrapStateValue(store.getState()),\n      _setState: (state) => store.setState(state as never),\n      subscribe: (selector, listener, options) =>\n        store.subscribe(\n          (state) => selector(unwrapStateValue(state)),\n          listener,\n          options,\n        ),\n      useState: (selector?: any, options?: any) => {\n        const hasSelector = typeof selector === \"function\";\n        const result = useStore(\n          store,\n          useEqualityFn(\n            (state) =>\n              hasSelector ? selector(unwrapStateValue(state)) : state,\n            hasSelector ? options?.equalityFn : shallow,\n          ),\n        );\n        return hasSelector\n          ? result\n          : unwrapStateValue(result as InternalControllerState);\n      },\n      useFormManager: () => useStore(store, (state) => state.formManager),\n      useSchema: () => useStore(store, (state) => state.schema),\n      usePath: () => useStore(store, (state) => state.path),\n      useSchemaPath: () => useStore(store, (state) => state.schemaPath),\n      useObservingDescendants: () =>\n        useStore(store, (state) => state.observingDescendants),\n      useInitialized: () => useStore(store, (state) => state.initialized),\n      useExists: () => useStore(store, (state) => state.exists),\n      useValue: () => useStore(store, (state) => state.value)?.[0],\n      useDirty: () => useStore(store, (state) => state.dirty),\n      useTouched: () => useStore(store, (state) => state.touched),\n      useIssues: () => useStore(store, (state) => state.issues),\n      useValidationStatus: () =>\n        useStore(store, (state) => state.validationStatus),\n      useDisplayStatus: () => useStore(store, (state) => state.displayStatus),\n      get: <TValue, TResult>(\n        pathOrValueHandler:\n          | Path\n          | string\n          | ((value: T) => TResult | PromiseLike<TResult>),\n        valueHandler?: (value: TValue) => TResult | PromiseLike<TResult>,\n      ) => {\n        const { formManager, path: valuePath } = store.getState();\n        return valueHandler !== undefined\n          ? formManager.get(\n              valuePath.resolve(pathOrValueHandler as Path | string),\n              valueHandler,\n            )\n          : formManager.get(\n              valuePath,\n              pathOrValueHandler as (\n                value: T,\n              ) => TResult | PromiseLike<TResult>,\n            );\n      },\n      getClone: <TValue>(path?: Path | string): CancellablePromise<TValue> => {\n        const { formManager, path: valuePath } = store.getState();\n        return formManager.getClone(\n          path != null ? valuePath.resolve(path) : valuePath,\n        );\n      },\n      set: (pathOrToSet: Path | string | T, toSet?: unknown) => {\n        const { formManager, path: valuePath } = store.getState();\n        return toSet !== undefined\n          ? formManager.set(\n              valuePath.resolve(pathOrToSet as Path | string),\n              toSet,\n            )\n          : formManager.set(valuePath, pathOrToSet);\n      },\n      reset: (path?: Path | string) => {\n        const { formManager, path: valuePath } = store.getState();\n        return formManager.reset(\n          path != null ? valuePath.resolve(path) : valuePath,\n        );\n      },\n      remove: (path?: Path | string) => {\n        const { formManager, path: valuePath } = store.getState();\n        return formManager.remove(\n          path != null ? valuePath.resolve(path) : valuePath,\n        );\n      },\n      validate: (path: Path | string = Path.CURRENT_DEEP) => {\n        const { formManager, path: valuePath } = store.getState();\n        return formManager.validate(\n          path != null ? valuePath.resolve(path) : valuePath,\n        );\n      },\n      setDirty: (path?: Path | string) => {\n        const { formManager, path: valuePath } = store.getState();\n        return formManager.setDirty(\n          path != null ? valuePath.resolve(path) : valuePath,\n        );\n      },\n      setPristine: (path?: Path | string) => {\n        const { formManager, path: valuePath } = store.getState();\n        return formManager.setPristine(\n          path != null ? valuePath.resolve(path) : valuePath,\n        );\n      },\n      setTouched: (path?: Path | string) => {\n        const { formManager, path: valuePath } = store.getState();\n        return formManager.setTouched(\n          path != null ? valuePath.resolve(path) : valuePath,\n        );\n      },\n      setUntouched: (path?: Path | string) => {\n        const { formManager, path: valuePath } = store.getState();\n        return formManager.setUntouched(\n          path != null ? valuePath.resolve(path) : valuePath,\n        );\n      },\n    }),\n    [store],\n  );\n\n  // Store latest values and listeners used during API calls or event handling\n  const latestValues = useLatestValues({\n    onInitialized,\n    onUninitialized,\n    onFormManagerEvent,\n    onValueChange,\n    onValidationStatusChange,\n    onDisplayStatusChange,\n    onDirtyStatusChange,\n    onTouchedStatusChange,\n  });\n\n  // Initialise controller\n  React.useEffect(() => {\n    store.setState({\n      formManager,\n      schema: schemaInfo.schema,\n      path: valuePath,\n      schemaPath: schemaInfo.path,\n    } as never);\n\n    if (!enabled) {\n      return;\n    }\n\n    let cleanedUp = false;\n    let unsubscribe: (() => CancellablePromise<void>) | undefined = undefined;\n    const initPromise = formManager\n      .info<T, void>(valuePath, async (infoIterable) => {\n        if (cleanedUp) {\n          return;\n        }\n\n        unsubscribe = await formManager.subscribe(resolvedPath, (event) => {\n          // Unsubscribing is asynchronous, so it's possible that an event is\n          // emitted after cleaning up, but before unsubscribing, which we\n          // should ignore\n          if (cleanedUp) {\n            return;\n          }\n\n          let specificEventHandlerResult: void | PromiseLike<void> = undefined;\n          if (event instanceof ValueEvent) {\n            if (!observingDescendants || event.path.equals(valuePath)) {\n              if (event instanceof ValueEvent.Init) {\n                store.setState({\n                  initialized: true,\n                  exists: true,\n                  value: [event.value as T],\n                  dirty: false,\n                  touched: false,\n                  issues: [],\n                  validationStatus: \"unvalidated\",\n                  displayStatus: \"valid\",\n                } as never);\n              } else if (event instanceof ValueEvent.Destroy) {\n                store.setState(NONEXISTENT_VALUE_CONTROLLER_STATE as never);\n              } else {\n                // Force Zustand update even if value's identity hasn't changed\n                store.setState({ value: [event.value as T] } as never);\n              }\n            } else {\n              // Force Zustand update even if value's identity hasn't changed\n              store.setState(\n                (state) =>\n                  ({\n                    value: state.value ? [state.value[0]] : undefined,\n                  }) as never,\n              );\n            }\n            specificEventHandlerResult = latestValues.onValueChange?.(\n              event,\n              controller.getState() as never,\n            );\n          } else if (event instanceof StateEvent.ValidationChange) {\n            if (!observingDescendants || event.path.equals(valuePath)) {\n              store.setState({\n                issues: event.issues,\n                validationStatus: event.status,\n              } as never);\n            }\n            specificEventHandlerResult =\n              latestValues.onValidationStatusChange?.(\n                event,\n                controller.getState() as never,\n              );\n          } else if (event instanceof StateEvent.DisplayChange) {\n            if (!observingDescendants || event.path.equals(valuePath)) {\n              store.setState({ displayStatus: event.status } as never);\n            }\n            specificEventHandlerResult = latestValues.onDisplayStatusChange?.(\n              event,\n              controller.getState() as never,\n            );\n          } else if (event instanceof StateEvent.DirtyChange) {\n            if (!observingDescendants || event.path.equals(valuePath)) {\n              store.setState({ dirty: event.status } as never);\n            }\n            specificEventHandlerResult = latestValues.onDirtyStatusChange?.(\n              event,\n              controller.getState() as never,\n            );\n          } else if (event instanceof StateEvent.TouchedChange) {\n            if (!observingDescendants || event.path.equals(valuePath)) {\n              store.setState({ touched: event.status } as never);\n            }\n            specificEventHandlerResult = latestValues.onTouchedStatusChange?.(\n              event,\n              controller.getState() as never,\n            );\n          }\n\n          // Results of handling the event\n          const formManagerEventHandlerResult =\n            latestValues.onFormManagerEvent?.(\n              event,\n              controller.getState() as never,\n            );\n\n          // Return a promise if either of the handler results is a promise\n          if (\n            isPromiseLike(formManagerEventHandlerResult) ||\n            isPromiseLike(specificEventHandlerResult)\n          ) {\n            return Promise.all([\n              formManagerEventHandlerResult,\n              specificEventHandlerResult,\n            ]).then(() => {});\n          }\n        });\n\n        const info = (await arrayFromAsync(infoIterable))[0];\n        store.setState(\n          (info\n            ? {\n                initialized: true,\n                exists: true,\n                value: [info.value],\n                dirty: info.dirty,\n                touched: info.touched,\n                issues: info.issues,\n                validationStatus: info.validationStatus,\n                displayStatus: info.displayStatus,\n              }\n            : NONEXISTENT_VALUE_CONTROLLER_STATE) as never,\n        );\n        return latestValues.onInitialized?.(controller.getState() as never);\n      })\n      .catch(ignorePromiseCancellationException);\n\n    return () => {\n      cleanedUp = true;\n      initPromise?.cancel(\n        `Clean up 'useEffect' access to info of '${valuePath.toString()}'.`,\n      );\n      void unsubscribe?.();\n      store.setState(UNINITIALIZED_CONTROLLER_STATE as never);\n      latestValues.onUninitialized?.(controller.getState() as never);\n    };\n  }, [\n    controller,\n    enabled,\n    formManager,\n    latestValues,\n    observingDescendants,\n    resolvedPath,\n    schemaInfo.path,\n    schemaInfo.schema,\n    store,\n    valuePath,\n  ]);\n\n  return controller;\n}\n\n/**\n * Unwraps the value within the controller's state.\n */\nfunction unwrapStateValue<\n  T = unknown,\n  TState extends ControllerState<T> = ControllerState<T>,\n>(state: InternalControllerState<T, TState>) {\n  return { ...state, value: state.value?.[0] } as TState;\n}\n","/**\n * Determines the equality between {@link v1} and {@link v2} via\n * {@link Object.is} or, when `!Object.is(v1, v2)`, via an `equals` function in\n * {@link v1} (when defined).\n * @param v1 First value being compared (if `!Object.is(v1, v2)` and `v1.equals`\n * is a function, then `v1.equals(v2)` is used to determine the equality).\n * @param v2 Second value being compared.\n * @returns Whether {@link v1} and {@link v2} are considered equal.\n */\nexport function equals(v1: any, v2: any): boolean {\n  return (\n    Object.is(v1, v2) || (typeof v1?.equals === \"function\" && !!v1.equals(v2))\n  );\n}\n","import * as React from \"react\";\n\n/**\n * Hook providing access to the value of a provided argument in the previous\n * render.\n * @param value Value to store and return on the next render.\n * @returns The value of the provided argument in the previous render or\n * `undefined` during the first render.\n */\nexport function usePrevious<T>(value: T): T | undefined {\n  const ref = React.useRef<T>();\n  React.useEffect(() => {\n    ref.current = value;\n  }, [value]);\n  return ref.current;\n}\n","import { FormManager, Schema, SchemaKt, ValidationMode } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { equals } from \"../utils/equals\";\nimport { usePrevious } from \"../utils/usePrevious\";\n\n/**\n * Hook that creates a new form manager given a {@link schema} and\n * [external contexts]{@link externalContexts}.\n *\n * Note that a new instance of a form manager will be created every time\n * {@link schema} changes; the external contexts and validation mode, however,\n * may change over time and the hook will simply update the external contexts of\n * the current form manager.\n * @param schema Schema of the form, used to create a new instance of a form\n * manager.\n * @param initialValue Initial form value.\n * @param externalContexts External contexts available to validations of\n * {@link schema}.\n * @param validationMode Validation mode (automatic or manual validation).\n * @returns New form manager.\n */\nexport function useNewFormManager(\n  schema: Schema | SchemaKt,\n  initialValue?: unknown,\n  externalContexts?: Record<string, unknown>,\n  validationMode: ValidationMode = \"auto\",\n): FormManager {\n  const initialValueRef = React.useRef(initialValue);\n  const formManager = React.useMemo(\n    () =>\n      new FormManager(\n        schema,\n        initialValueRef.current,\n        undefined,\n        undefined,\n        false,\n      ),\n    [schema],\n  );\n  React.useEffect(() => {\n    void formManager.init(externalContexts, validationMode);\n    return () => void formManager.destroy();\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [formManager]);\n  const prevFormManager = usePrevious(formManager);\n\n  // Manage external contexts without recreating the form manager\n  const prevExternalContexts = usePrevious(externalContexts);\n  React.useEffect(() => {\n    if (formManager === prevFormManager) {\n      // Add new external contexts\n      if (externalContexts) {\n        for (const contextName of Object.keys(externalContexts)) {\n          const externalContext = externalContexts[contextName];\n          if (\n            externalContext !== undefined &&\n            (!prevExternalContexts ||\n              !equals(externalContext, prevExternalContexts[contextName]))\n          ) {\n            void formManager.setExternalContext(contextName, externalContext);\n          }\n        }\n      }\n      // Remove old (no longer provided) external contexts\n      if (prevExternalContexts) {\n        for (const contextName of Object.keys(prevExternalContexts)) {\n          if (\n            prevExternalContexts[contextName] !== undefined &&\n            (!externalContexts || externalContexts[contextName] === undefined)\n          ) {\n            void formManager.removeExternalContext(contextName);\n          }\n        }\n      }\n    }\n  }, [externalContexts, formManager, prevExternalContexts, prevFormManager]);\n\n  // Manage validation mode without recreating the form manager\n  const prevValidationMode = usePrevious(validationMode);\n  React.useEffect(() => {\n    if (\n      formManager === prevFormManager &&\n      validationMode !== prevValidationMode\n    ) {\n      void formManager.setValidationMode(validationMode);\n    }\n  }, [formManager, validationMode, prevValidationMode, prevFormManager]);\n\n  return formManager;\n}\n","import {\n  AbsolutePath,\n  AutoValidationStatus,\n  CancellablePromise,\n  convertIssuesTableRowIndicesToIds,\n  FormManager,\n  isList,\n  isLocatedValidationIssueKt,\n  listableSize,\n  listableToArray,\n  LocatedValidationIssue,\n  locatedValidationIssueKtToJs,\n  LocatedValidationWarning,\n  Path,\n  Schema,\n  SchemaKt,\n  SealedLocatedValidationIssue,\n  sliceList,\n  ValidationMode,\n} from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { ignorePromiseCancellationException } from \"../utils/ignorePromiseCancellationException\";\nimport { DistributedOmit, MaybePromise } from \"../utils/typeUtils\";\nimport { useLatestValues } from \"../utils/useLatestValues\";\nimport {\n  Controller,\n  ControllerOptions,\n  ControllerState,\n  useController,\n} from \"./useController\";\nimport { useNewFormManager } from \"./useNewFormManager\";\n\n/**\n * Default message passed when preventing the \"before unload\" event.\n */\nexport const DEFAULT_CONFIRM_UNLOAD_MESSAGE = \"Are you sure you want to leave?\";\n\n/**\n * Type of external issues accepted by the form manager's `addExternalIssues`\n * method.\n */\ntype ExternalValidationIssues = Parameters<FormManager[\"addExternalIssues\"]>[0];\n\n/**\n * An object which is event-like.\n */\ntype EventLike = Pick<Event, \"preventDefault\" | \"defaultPrevented\">;\n\n/**\n * Options available to the {@link useForm} hook.\n */\nexport type FormOptions<T = unknown, TSubmitResult = unknown> = DistributedOmit<\n  ControllerOptions<T, FormControllerState<T>>,\n  \"formManager\"\n> &\n  FormOwnOptions<T, TSubmitResult>;\n\n/**\n * Own options available to the {@link useForm} hook.\n */\nexport interface FormOwnOptions<T = unknown, TSubmitResult = unknown>\n  extends SubmitOptions<T, TSubmitResult> {\n  /**\n   * Initial form value.\n   */\n  initialValue?: T;\n  /**\n   * External contexts available to validations. This value may change over time\n   * and will not cause a new form manager to be instantiated.\n   */\n  externalContexts?: Record<string, unknown>;\n  /**\n   * Form manager's validation mode. This value may change over time and will\n   * not cause a new form manager to be instantiated.\n   */\n  validationMode?: ValidationMode;\n  /**\n   * Whether to display a confirmation that the page should be unloaded when the\n   * form is dirty.\n   * @default true\n   */\n  confirmUnloadWhenDirty?: boolean;\n  /**\n   * Message to provide when confirming a page unload due to the dirty status of\n   * the form.\n   *\n   * Note that most recent browsers will not honour this string and will instead\n   * display a predefined message (see:\n   * https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#compatibility_notes).\n   */\n  confirmUnloadMessage?: string;\n  /**\n   * Function called during reset, before actually resetting the form. Calling\n   * [preventDefault()]{@link event.preventDefault} on the event will prevent\n   * the reset from occurring.\n   * @param event Original `onReset` event.\n   */\n  onReset?: (event?: EventLike) => MaybePromise<void>;\n}\n\n/**\n * Controller used to read and control the root form value, exposing properties\n * that should be set on a {@link HTMLFormElement <form>} element.\n */\nexport type FormController<T = unknown, TSubmitResult = unknown> = Controller<\n  T,\n  FormControllerState<T>\n> &\n  FormOwnController<T, TSubmitResult>;\n\n/**\n * Form's own controller.\n */\nexport interface FormOwnController<T = unknown, TSubmitResult = unknown> {\n  /**\n   * Function used to submit the form.\n   * @param event Event which caused the submission.\n   * @param options Options used when submitting the form.\n   */\n  readonly submit: (<TOptionsSubmitResult = TSubmitResult>(\n    event: EventLike,\n    options?: SubmitOptions<T, TOptionsSubmitResult>,\n  ) => Promise<void>) &\n    (<TOptionsSubmitResult = TSubmitResult>(\n      options?: SubmitOptions<T, TOptionsSubmitResult>,\n    ) => Promise<void>);\n  /**\n   * Hook returning the status of the form's automatic validations.\n   */\n  readonly useAutoValidationStatus: () => AutoValidationStatus;\n  /**\n   * Hook returning whether the form is currently being submitted.\n   */\n  readonly useSubmitting: () => boolean;\n  /**\n   * Hook returning whether the form is currently being reset.\n   */\n  readonly useResetting: () => boolean;\n  /**\n   * Properties to set on a {@link HTMLFormElement <form>} element.\n   */\n  readonly formProps: FormElementProps;\n}\n\n/**\n * Options available when submitting a value.\n */\nexport interface SubmitOptions<T = unknown, TSubmitResult = unknown> {\n  /**\n   * Function called during submission when the form value to submit is locally\n   * valid (no validation errors were found), or always when `validateOnSubmit`\n   * is set to `false`.\n   *\n   * This function may (possibly asynchronously) return two types of values, or\n   * throw an error:\n   * - Function returns external validation issues: the submission is considered\n   *   invalid (even if all returned issues are warnings). Returned issues that\n   *   aren't already in the form manager are added to it via\n   *   {@link FormManager.addExternalIssues}. `onInvalidSubmit` is subsequently\n   *   called with the returned issues.\n   * - Function returns any other value: the submission is considered\n   *   successful. `onSuccessfulSubmit` will be called with the returned value\n   *   after setting the form as pristine (unless\n   *   `setPristineOnSuccessfulSubmit` is set to `false`).\n   * - Function throws: the submission is considered to have failed.\n   *   `onFailedSubmit` will be called with the thrown error.\n   * @param value Form value to submit.\n   * @param warnings List of form warnings. `undefined` when `validateOnSubmit`\n   * is set to `false`.\n   * @param event Original event (with the default behaviour already prevented).\n   * @returns External validation issues, or any other value (including\n   * `undefined`) to indicate success; or a promise which resolves to such\n   * values.\n   */\n  onSubmit?: (\n    value: T,\n    warnings?: LocatedValidationWarning[],\n    event?: EventLike,\n  ) => MaybePromise<ExternalValidationIssues | TSubmitResult>;\n  /**\n   * Function called during submission when the form value to submit is locally\n   * invalid (validation errors were found), or after `onSubmit` if it returns\n   * external validation issues.\n   * @param issues List of form issues.\n   * @param event Original event (with the default behaviour already prevented).\n   */\n  onInvalidSubmit?: (\n    issues: SealedLocatedValidationIssue[],\n    event?: EventLike,\n  ) => void;\n  /**\n   * Function called after a successful submission with the result of\n   * `onSubmit`, when this result isn't external validation issues.\n   *\n   * Unless `setPristineOnSuccessfulSubmit` is set to `false`, the form will be\n   * pristine by the time this function runs, meaning that redirections that\n   * cause the form to be closed should happen within this function (so that the\n   * form unload confirmation isn't triggered).\n   * @param submitResult Result of calling `onSubmit`, when such value isn't\n   * external validation issues.\n   * @param event Original event (with the default behaviour already prevented).\n   */\n  onSuccessfulSubmit?: (submitResult: TSubmitResult, event?: EventLike) => void;\n  /**\n   * Function called after a submission which resulted in an error.\n   * @param error Error that occurred during the submission.\n   * @param event Original event (with the default behaviour already prevented).\n   */\n  onFailedSubmit?: (error: unknown, event?: EventLike) => void;\n  /**\n   * Whether to set the whole form as touched before submitting.\n   * @default true\n   */\n  setTouchedOnSubmit?: boolean;\n  /**\n   * Whether to validate the form before submitting.\n   *\n   * When set to `false`, `onSubmit` is always called and `onInvalidSubmit` is\n   * only called if `onSubmit` returns external validation issues.\n   * @default true\n   */\n  validateOnSubmit?: boolean;\n  /**\n   * Whether to set the whole form as pristine after a successful submission,\n   * but before invoking `onSuccessfulSubmit`.\n   * @default true\n   */\n  setPristineOnSuccessfulSubmit?: boolean;\n  /**\n   * Whether to convert table row indices into ids when processing external\n   * issues returned by the `onSubmit` function.\n   * @default false\n   */\n  convertExternalIssuesTableRowIndicesToIds?: boolean;\n}\n\n/**\n * Properties to provide to a form element to integrate it with the form\n * manager.\n */\nexport interface FormElementProps {\n  /**\n   * Disable native HTML validations.\n   */\n  readonly noValidate: true;\n  /**\n   * Function to run whenever the form is to be submitted. This function calls\n   * the provided `onSubmit` option with the root value and the original form\n   * element event, while preventing the default event behaviour.\n   */\n  readonly onSubmit: (event?: EventLike) => Promise<void>;\n  /**\n   * Function to run whenever the form is to be reset. This function resets the\n   * whole form, while preventing the default event behaviour.\n   */\n  readonly onReset: (event?: EventLike) => Promise<void>;\n}\n\n/**\n * Form controller's state.\n */\nexport type FormControllerState<T = unknown> = ControllerState<T> &\n  FormControllerOwnState;\n\n/**\n * Form controller's own state.\n */\nexport interface FormControllerOwnState {\n  /**\n   * Status of the automatic validations.\n   */\n  readonly autoValidationStatus: AutoValidationStatus;\n  /**\n   * Whether the root value is currently being submitted.\n   */\n  readonly submitting: boolean;\n  /**\n   * Whether the root value is currently being reset.\n   */\n  readonly resetting: boolean;\n}\n\n/**\n * Hook used to create a new form managed by a form manager given its\n * {@link schema}. It provides access to the form controller, as well as\n * properties for integration with a {@link HTMLFormElement <form>} element.\n *\n * The provided external contexts and validation mode may change over time and\n * will not cause a new form manager to be instantiated.\n * @param schema Schema of the form.\n * @param options Available options.\n * @returns A controller used to read and control the root form value, exposing\n * properties that should be set on a {@link HTMLFormElement <form>} element.\n */\nexport function useForm<T = unknown, TSubmitResult = unknown>(\n  schema: Schema<T> | SchemaKt,\n  options?: undefined,\n): FormController<T, TSubmitResult>;\nexport function useForm<T = unknown, TSubmitResult = unknown>(\n  schema: Schema<T> | SchemaKt,\n  options: FormOptions<T, TSubmitResult>,\n): FormController<T, TSubmitResult>;\nexport function useForm<T = unknown, TSubmitResult = unknown>(\n  schema: Schema<T> | SchemaKt,\n  {\n    _defaultState,\n    initialValue,\n    externalContexts,\n    validationMode,\n    confirmUnloadWhenDirty = process.env.NODE_ENV === \"production\",\n    confirmUnloadMessage,\n    onSubmit,\n    onInvalidSubmit,\n    onSuccessfulSubmit,\n    onFailedSubmit,\n    setTouchedOnSubmit = true,\n    validateOnSubmit = true,\n    setPristineOnSuccessfulSubmit = true,\n    convertExternalIssuesTableRowIndicesToIds = false,\n    onReset,\n    ...options\n  }: FormOptions<T, TSubmitResult> = {},\n): FormController<T, TSubmitResult> {\n  const formManager = useNewFormManager(\n    schema,\n    initialValue,\n    externalContexts,\n    validationMode,\n  );\n  const controller = useController<T, FormControllerState<T>>(\n    AbsolutePath.ROOT,\n    {\n      formManager,\n      _defaultState: {\n        autoValidationStatus: formManager.autoValidationStatus,\n        submitting: false,\n        resetting: false,\n        ..._defaultState,\n      },\n      ...options,\n    },\n  );\n\n  const latestValues = useLatestValues({\n    confirmUnloadMessage,\n    onSubmit,\n    onInvalidSubmit,\n    onSuccessfulSubmit,\n    onFailedSubmit,\n    setTouchedOnSubmit,\n    validateOnSubmit,\n    setPristineOnSuccessfulSubmit,\n    convertExternalIssuesTableRowIndicesToIds,\n    onReset,\n  });\n\n  const handleSubmit = React.useCallback(\n    async (\n      event?: EventLike,\n      {\n        onSubmit = latestValues.onSubmit,\n        onInvalidSubmit = latestValues.onInvalidSubmit,\n        onSuccessfulSubmit = latestValues.onSuccessfulSubmit,\n        onFailedSubmit = latestValues.onFailedSubmit,\n        setTouchedOnSubmit = latestValues.setTouchedOnSubmit,\n        validateOnSubmit = latestValues.validateOnSubmit,\n        setPristineOnSuccessfulSubmit = latestValues.setPristineOnSuccessfulSubmit,\n        convertExternalIssuesTableRowIndicesToIds = latestValues.convertExternalIssuesTableRowIndicesToIds,\n      }: SubmitOptions<T, any> = {},\n    ) => {\n      if (!onSubmit) {\n        throw new Error(\n          \"Missing `onSubmit` implementation. The `onSubmit` function may be \" +\n            \"provided as a property of the `Form` component, as an option of \" +\n            \"the `useForm` hook, or directly as an option of the `submit` \" +\n            \"function.\",\n        );\n      }\n\n      event?.preventDefault();\n      const { initialized, exists, schema } = controller.getState();\n      if (initialized && exists) {\n        controller._setState({ submitting: true });\n        try {\n          if (setTouchedOnSubmit) {\n            await controller.setTouched(Path.CURRENT_DEEP);\n          }\n          const issues = validateOnSubmit\n            ? await controller.validate(Path.CURRENT_DEEP)\n            : undefined;\n\n          if (issues?.some((issue) => issue.severity === \"error\")) {\n            // Form has local issues\n            onInvalidSubmit?.(issues, event);\n            return;\n          }\n\n          await controller.get(async (value) => {\n            const submitResult = await onSubmit(\n              value,\n              issues as LocatedValidationWarning[] | undefined,\n              event,\n            );\n\n            if (isExternalValidationIssues(submitResult)) {\n              // Handle external issues\n              const externalIssues = convertExternalIssuesTableRowIndicesToIds\n                ? await convertIssuesTableRowIndicesToIds(\n                    submitResult,\n                    schema,\n                    value,\n                  )\n                : listableToArray(submitResult).map((issue) =>\n                    isLocatedValidationIssueKt(issue)\n                      ? locatedValidationIssueKtToJs(issue)\n                      : issue,\n                  );\n\n              // Ignore returned issues that we already know about\n              const newExternalIssues =\n                issues === undefined\n                  ? externalIssues\n                  : externalIssues.filter(\n                      (externalIssue) =>\n                        !issues.some((issue) => issue.equals(externalIssue)),\n                    );\n\n              if (newExternalIssues.length > 0) {\n                void formManager.addExternalIssues(newExternalIssues);\n              }\n              onInvalidSubmit?.(externalIssues, event);\n            } else {\n              // Handle success\n              void Promise.resolve(\n                setPristineOnSuccessfulSubmit &&\n                  formManager.setPristine(Path.CURRENT),\n              ).then(() => onSuccessfulSubmit?.(submitResult, event));\n            }\n          });\n        } catch (err) {\n          if (onFailedSubmit) {\n            onFailedSubmit(err, event);\n          } else {\n            throw err;\n          }\n        } finally {\n          controller._setState({ submitting: false });\n        }\n      }\n    },\n    [controller, formManager, latestValues],\n  );\n\n  const handleReset = React.useCallback(\n    async (event?: EventLike) => {\n      const { initialized, exists } = controller.getState();\n      await latestValues.onReset?.(event);\n      if (!event?.defaultPrevented) {\n        event?.preventDefault();\n        if (initialized && exists) {\n          controller._setState({ resetting: true });\n          try {\n            await controller.reset();\n            await Promise.all([\n              controller.setPristine(),\n              controller.setUntouched(),\n            ]);\n          } finally {\n            controller._setState({ resetting: false });\n          }\n        }\n      }\n    },\n    [controller, latestValues],\n  );\n\n  React.useEffect(() => {\n    let unsubscribe: (() => CancellablePromise<void>) | undefined = undefined;\n    const subscribePromise = formManager\n      .onAutoValidationStatusChange((autoValidationStatus) =>\n        controller._setState({ autoValidationStatus }),\n      )\n      .then((fn) => (unsubscribe = fn))\n      .catch(ignorePromiseCancellationException);\n    return () => {\n      subscribePromise.cancel(\n        \"Clean up 'useEffect' subscription to auto validation status changes.\",\n      );\n      void unsubscribe?.();\n    };\n  }, [controller, formManager]);\n\n  // Confirm unload when dirty\n  React.useEffect(() => {\n    if (confirmUnloadWhenDirty) {\n      const handleBeforeUnload = (event: BeforeUnloadEvent) => {\n        if (controller.getState().dirty) {\n          event.preventDefault();\n          return (event.returnValue =\n            latestValues.confirmUnloadMessage ||\n            DEFAULT_CONFIRM_UNLOAD_MESSAGE);\n        }\n      };\n\n      window.addEventListener(\"beforeunload\", handleBeforeUnload);\n      return () =>\n        window.removeEventListener(\"beforeunload\", handleBeforeUnload);\n    }\n  }, [confirmUnloadWhenDirty, controller, latestValues]);\n\n  const formProps: FormElementProps = React.useMemo(\n    () => ({ noValidate: true, onSubmit: handleSubmit, onReset: handleReset }),\n    [handleReset, handleSubmit],\n  );\n\n  const ownController: FormOwnController<T, TSubmitResult> = React.useMemo(\n    () => ({\n      submit: <TOptionsSubmitResult = TSubmitResult>(\n        eventOrOptions?: EventLike | SubmitOptions<T, TOptionsSubmitResult>,\n        maybeOptions?: SubmitOptions<T, TOptionsSubmitResult>,\n      ) => {\n        const [event, options] = isEventLike(eventOrOptions)\n          ? [eventOrOptions, maybeOptions]\n          : [undefined, eventOrOptions];\n        return handleSubmit(event, options);\n      },\n      useAutoValidationStatus: () =>\n        controller.useState((state) => state.autoValidationStatus),\n      useSubmitting: () => controller.useState((state) => state.submitting),\n      useResetting: () => controller.useState((state) => state.resetting),\n      formProps,\n    }),\n    [controller, formProps, handleSubmit],\n  );\n\n  return React.useMemo(\n    () => ({ ...controller, ...ownController }),\n    [controller, ownController],\n  );\n}\n\n/**\n * Whether a value is event-like.\n */\nfunction isEventLike(value: any): value is EventLike {\n  return (\n    typeof value?.preventDefault === \"function\" && \"defaultPrevented\" in value\n  );\n}\n\n/**\n * Checks whether a given represents external validation issues.\n */\nfunction isExternalValidationIssues(\n  value: unknown,\n): value is ExternalValidationIssues {\n  const firstEl = isList(value)\n    ? listableSize(value) > 0\n      ? sliceList(value, 0, 1)[0]\n      : undefined\n    : Array.isArray(value)\n      ? value[0]\n      : undefined;\n  return (\n    firstEl != null &&\n    (firstEl instanceof LocatedValidationIssue ||\n      isLocatedValidationIssueKt(firstEl))\n  );\n}\n","import { AbsolutePath, Schema, SchemaKt } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { FormContext } from \"../contexts/FormContext\";\nimport { FormOptions, useForm } from \"../hooks/useForm\";\n\n/**\n * Properties of the {@link Form} component.\n */\nexport type FormProps<T = unknown, TSubmitResult = unknown> = FormOptions<\n  T,\n  TSubmitResult\n> &\n  FormOwnProps<T> &\n  React.ComponentPropsWithoutRef<\"form\">;\n\n/**\n * Own properties of the {@link Form} component.\n */\nexport interface FormOwnProps<T = unknown> {\n  /**\n   * Schema of the form.\n   */\n  schema: Schema<T> | SchemaKt;\n}\n\n/**\n * Component exposing a form managed by a [form manager]{@link FormManager},\n * initialised with the provided schema.\n */\nexport const Form = React.forwardRef(function Form<\n  T = unknown,\n  TSubmitResult = unknown,\n>(\n  {\n    schema,\n    initialValue,\n    enabled,\n    _defaultState,\n    onInitialized,\n    onUninitialized,\n    onFormManagerEvent,\n    onValueChange,\n    onValidationStatusChange,\n    onDisplayStatusChange,\n    onDirtyStatusChange,\n    onTouchedStatusChange,\n    externalContexts,\n    validationMode,\n    confirmUnloadWhenDirty,\n    confirmUnloadMessage,\n    onSubmit,\n    onInvalidSubmit,\n    onSuccessfulSubmit,\n    onFailedSubmit,\n    setTouchedOnSubmit,\n    validateOnSubmit,\n    setPristineOnSuccessfulSubmit,\n    convertExternalIssuesTableRowIndicesToIds,\n    onReset,\n    ...otherProps\n  }: FormProps<T, TSubmitResult>,\n  forwardedRef: React.ForwardedRef<React.ElementRef<\"form\">>,\n) {\n  const formController = useForm<T, TSubmitResult>(schema, {\n    initialValue,\n    enabled,\n    _defaultState,\n    onInitialized,\n    onUninitialized,\n    onFormManagerEvent,\n    onValueChange,\n    onValidationStatusChange,\n    onDisplayStatusChange,\n    onDirtyStatusChange,\n    onTouchedStatusChange,\n    externalContexts,\n    validationMode,\n    confirmUnloadWhenDirty,\n    confirmUnloadMessage,\n    onSubmit,\n    onInvalidSubmit,\n    onSuccessfulSubmit,\n    onFailedSubmit,\n    setTouchedOnSubmit,\n    validateOnSubmit,\n    setPristineOnSuccessfulSubmit,\n    convertExternalIssuesTableRowIndicesToIds,\n    onReset,\n  });\n\n  const formManager = formController.useFormManager();\n  const formContext = React.useMemo(\n    () => ({\n      formManager,\n      currentPath: AbsolutePath.ROOT,\n      controller: formController,\n    }),\n    [formController, formManager],\n  );\n\n  return (\n    <FormContext.Provider value={formContext}>\n      <form {...formController.formProps} {...otherProps} ref={forwardedRef} />\n    </FormContext.Provider>\n  );\n});\n","import { Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { isPromiseLike } from \"../utils/promiseUtils\";\nimport { useLatestValues } from \"../utils/useLatestValues\";\nimport {\n  Controller,\n  ControllerOptions,\n  ExistingValueControllerState,\n  NonexistentValueControllerState,\n  UninitializedControllerState,\n  useController,\n} from \"./useController\";\n\n/**\n * Options available to the {@link useFormatter} hook.\n */\nexport interface FormatterOptions<T = unknown, TFormatted = T | undefined>\n  extends ControllerOptions<T, FormatterControllerState<T, TFormatted>>,\n    FormatterOwnOptions<T, TFormatted> {}\n\n/**\n * Own options available to the {@link useFormatter} hook.\n */\nexport interface FormatterOwnOptions<T = unknown, TFormatted = T | undefined> {\n  /**\n   * Function used to set the formatted value. A\n   * [useState]{@link React.useState} dispatcher can be used to save the output\n   * value within React state.\n   *\n   * The passed value results from calling {@link format} on the form manager\n   * value. If {@link format} is not defined, then the form manager value is\n   * passed directly.\n   * @param formattedValue Formatted value to set.\n   * @param controller Form value's controller.\n   */\n  setFormattedValue?: (\n    formattedValue: TFormatted,\n    state: FormatterControllerState<T, TFormatted>,\n  ) => void | PromiseLike<void>;\n  /**\n   * Format function that transforms the form manager value into a value to be\n   * output. The passed {@link value} is `undefined` when the form manager value\n   * does not exist.\n   * @param value Form manager value to transform.\n   * @param controller Form value's controller.\n   * @returns Transformed value.\n   */\n  format?: (\n    value: T | undefined,\n    state: FormatterControllerState<T, TFormatted>,\n  ) => TFormatted | PromiseLike<TFormatted>;\n}\n\n/**\n * Controller which keeps track of a formatted value.\n */\nexport interface FormatterController<T = unknown, TFormatted = T | undefined>\n  extends Controller<T, FormatterControllerState<T, TFormatted>>,\n    FormatterOwnController<T, TFormatted> {}\n\n/**\n * Formatter's own controller.\n */\nexport interface FormatterOwnController<\n  T = unknown,\n  TFormatted = T | undefined,\n> {\n  readonly useFormattedValue: () => TFormatted | undefined;\n}\n\n/**\n * State of the formatter's controller.\n */\nexport type FormatterControllerState<T = unknown, TFormatted = T | undefined> =\n  | UninitializedFormatterControllerState<T, TFormatted>\n  | InitializedFormatterControllerState<T, TFormatted>;\n\n/**\n * Formatter controller's own base state.\n */\nexport interface FormatterControllerOwnBaseState<\n  T = unknown,\n  TFormatted = T | undefined,\n> {\n  /**\n   * Formatted value.\n   */\n  formattedValue: TFormatted | undefined;\n}\n\n/**\n * Uninitialised formatter controller state.\n */\nexport interface UninitializedFormatterControllerState<\n  T = unknown,\n  TFormatted = T | undefined,\n> extends FormatterControllerOwnBaseState<T, TFormatted>,\n    UninitializedControllerState<T> {\n  formattedValue: undefined;\n}\n\n/**\n * Initialised formatter controller state.\n */\nexport type InitializedFormatterControllerState<\n  T = unknown,\n  TFormatted = T | undefined,\n> =\n  | NonexistentValueFormatterControllerState<T, TFormatted>\n  | ExistingValueFormatterControllerState<T, TFormatted>;\n\n/**\n * Formatter controller state of a nonexistent form value.\n */\nexport interface NonexistentValueFormatterControllerState<\n  T = unknown,\n  TFormatted = T | undefined,\n> extends FormatterControllerOwnBaseState<T, TFormatted>,\n    FormatterControllerOwnBaseState<T, TFormatted>,\n    NonexistentValueControllerState<T> {\n  formattedValue: TFormatted;\n}\n\n/**\n * Formatter controller state of an existing form value.\n */\nexport interface ExistingValueFormatterControllerState<\n  T = unknown,\n  TFormatted = T | undefined,\n> extends FormatterControllerOwnBaseState<T, TFormatted>,\n    ExistingValueControllerState<T> {\n  formattedValue: TFormatted;\n}\n\n/**\n * Hook facilitating the formatting of a form value by providing a way of\n * formatting and setting said value (e.g. within React state).\n * @param path Path of the form value to access, relative to the current path.\n * @param options Available options.\n * @returns A controller used to read and control the form value.\n */\nexport function useFormatter<T = unknown, TFormatted = T | undefined>(\n  path: Path | string | undefined,\n  options: FormatterOptions<T, TFormatted>,\n): FormatterController<T, TFormatted>;\nexport function useFormatter<T = unknown, TFormatted = T | undefined>(\n  path: Path | string = Path.CURRENT,\n  {\n    _defaultState,\n    setFormattedValue,\n    format,\n    ...options\n  }: FormatterOptions<T, TFormatted>,\n): FormatterController<T, TFormatted> {\n  const { onInitialized, onUninitialized, onValueChange } = options;\n  const latestOptions = useLatestValues({\n    setFormattedValue,\n    format,\n    onInitialized,\n    onUninitialized,\n    onValueChange,\n  });\n\n  const controller: Controller<\n    T,\n    FormatterControllerState<T, TFormatted>\n  > = useController<T, FormatterControllerState<T, TFormatted>>(path, {\n    ...options,\n    _defaultState: {\n      formattedValue: undefined,\n      ..._defaultState,\n    },\n    onInitialized: (state) => {\n      const result = formatAndSetFormattedValue(\n        state.value,\n        latestOptions.format,\n        latestOptions.setFormattedValue,\n        controller,\n      );\n      const handlerResult = latestOptions.onInitialized?.(state);\n      return isPromiseLike(result)\n        ? Promise.all([result, handlerResult]).then(() => {})\n        : handlerResult;\n    },\n    onUninitialized: (state) => {\n      controller._setState({ formattedValue: undefined });\n      return latestOptions.onUninitialized?.(state);\n    },\n    onValueChange: (event, state) => {\n      const result = formatAndSetFormattedValue(\n        state.value,\n        latestOptions.format,\n        latestOptions.setFormattedValue,\n        controller,\n      );\n      const handlerResult = latestOptions.onValueChange?.(event, state);\n      return isPromiseLike(result)\n        ? Promise.all([result, handlerResult]).then(() => {})\n        : handlerResult;\n    },\n  });\n  const ownController: FormatterOwnController<T, TFormatted> = React.useMemo(\n    () => ({\n      useFormattedValue: () =>\n        controller.useState((state) => state.formattedValue),\n    }),\n    [controller],\n  );\n\n  // Re-set the formatted value every time `format` or `setFormattedValue`\n  // change\n  React.useEffect(() => {\n    const { initialized, value } = controller.getState();\n    if (initialized) {\n      void formatAndSetFormattedValue(\n        value,\n        format,\n        setFormattedValue,\n        controller,\n      );\n    }\n  }, [controller, format, setFormattedValue]);\n\n  return React.useMemo(\n    () => ({ ...controller, ...ownController }),\n    [controller, ownController],\n  );\n}\n\n/**\n * Formats a value and sets it.\n */\nfunction formatAndSetFormattedValue<T = unknown, TFormatted = T | undefined>(\n  value: T | undefined,\n  format: FormatterOptions<T, TFormatted>[\"format\"],\n  setFormattedValue: FormatterOptions<T, TFormatted>[\"setFormattedValue\"],\n  controller: Controller<T, FormatterControllerState<T, TFormatted>>,\n) {\n  const state = controller.getState();\n  const set = (formattedValue: TFormatted) => {\n    controller._setState({ formattedValue });\n    return setFormattedValue?.(formattedValue, state);\n  };\n\n  const formattedValue = format ? format(value, state) : (value as TFormatted);\n  if (isPromiseLike(formattedValue)) {\n    return formattedValue.then(set);\n  } else {\n    return set(formattedValue);\n  }\n}\n","import { Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { FormContext, FormContextValue } from \"../contexts/FormContext\";\nimport {\n  FormatterControllerState,\n  FormatterOptions,\n  useFormatter,\n} from \"../hooks/useFormatter\";\nimport { shallow } from \"../utils/shallow\";\nimport { DistributedOmit } from \"../utils/typeUtils\";\n\n/**\n * Properties of the {@link FormattedValue} component.\n */\nexport type FormattedValueProps<\n  T = unknown,\n  TFormatted = T | undefined,\n> = DistributedOmit<FormatterOptions<T, TFormatted>, \"setFormattedValue\"> &\n  FormattedValueOwnProps<T, TFormatted>;\n\n/**\n * Own properties of the {@link FormattedValue} component.\n */\nexport interface FormattedValueOwnProps<\n  T = unknown,\n  TFormatted = T | undefined,\n> {\n  path?: Path | string;\n  children?: (\n    state: FormatterControllerState<T, TFormatted>,\n  ) => React.ReactNode;\n}\n\n/**\n * Component used to display information about a form value. It can be used to\n * either simply display the form value (formatted as appropriate) or display\n * the value's state (such as dirty/touched status, issues, etc.).\n *\n * If intending to simply display the current value of a form value, use the\n * {@link format} property to configure how the value should be formatted. If no\n * {@link children} are provided, then the formatted value is rendered as-is\n * when it is a React element or converted to a string via\n * `formattedValue?.toString()` otherwise.\n *\n * This component is a wrapper around the {@link useFormattedValue} hook.\n *\n * Example displaying the value formatted as JSON:\n * ```tsx\n * <FormattedValue\n *   path=\"/path/to/value\"\n *   format={(value) => JSON.stringify(value)}\n * />\n * ```\n *\n * Example displaying the value as a string, plus some of the value's state:\n * ```tsx\n * <FormattedValue path=\"/path/to/value\" format={(value) => String(value)}>\n *   {({ initialized, exists, formattedValue, dirty, touched }) => (\n *     <>\n *       {!initialized && \"Loading...\"}\n *       {initialized && !exists && \"Value does not exist\"}\n *       {initialized && exists && (\n *         <dl>\n *           <dt>Formatted value:</dt>\n *           <dd>{formattedValue}</dd>\n *\n *           <dt>Dirty:</dt>\n *           <dd>{dirty ? \"Yes\" : \"No\"}</dd>\n *\n *           <dt>Touched:</dt>\n *           <dd>{touched ? \"Yes\" : \"No\"}</dd>\n *         </dl>\n *       )}\n *     </>\n *   )}\n * </FormattedValue>\n * ```\n */\nexport function FormattedValue<T = unknown, TFormatted = T | undefined>({\n  path,\n  children,\n  ...props\n}: FormattedValueProps<T, TFormatted>) {\n  const formContext = React.useContext(FormContext);\n  const formatterController = useFormatter(path, props);\n\n  const formManager = formatterController.useFormManager();\n  const currentPath = formatterController.usePath();\n  const newFormContext = React.useMemo<FormContextValue>(\n    () => ({\n      formManager,\n      currentPath,\n      controller:\n        formContext?.formManager === formManager\n          ? formContext.controller\n          : undefined,\n    }),\n    [\n      currentPath,\n      formContext?.controller,\n      formContext?.formManager,\n      formManager,\n    ],\n  );\n\n  const state = formatterController.useState(\n    (state) =>\n      children\n        ? state\n        : {\n            initialized: state.initialized,\n            formattedValue: state.formattedValue,\n          },\n    { equalityFn: shallow },\n  );\n  return (\n    <FormContext.Provider value={newFormContext}>\n      {children\n        ? children(state as FormatterControllerState<T, TFormatted>)\n        : state.initialized &&\n          (React.isValidElement(state.formattedValue)\n            ? state.formattedValue\n            : state.formattedValue?.toString())}\n    </FormContext.Provider>\n  );\n}\n","import { CancellablePromise, isComputedSchema, Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { equals } from \"../utils/equals\";\nimport { ignorePromiseCancellationException } from \"../utils/ignorePromiseCancellationException\";\nimport { DistributedOmit } from \"../utils/typeUtils\";\nimport { useLatestValues } from \"../utils/useLatestValues\";\nimport {\n  FormatterController,\n  FormatterControllerState,\n  FormatterOptions,\n  useFormatter,\n} from \"./useFormatter\";\n\n/**\n * Options available to the {@link useInput} hook.\n */\nexport type InputOptions<\n  T = unknown,\n  TFormatted = T | undefined,\n  TInput = unknown,\n> = DistributedOmit<\n  FormatterOptions<T, TFormatted>,\n  \"setFormattedValue\" | \"format\"\n> &\n  InputOwnOptions<T, TFormatted, TInput>;\n\n/**\n * Own options available to the {@link useInput} hook.\n */\nexport interface InputOwnOptions<\n  T = unknown,\n  TFormatted = T | undefined,\n  TInput = unknown,\n> {\n  /**\n   * Function used to set the formatted value in the input element.\n   *\n   * The passed value results from calling {@link format} on the form manager\n   * value.\n   * If {@link format} is not defined, then the form manager value is passed\n   * directly.\n   * @param formattedValue Formatted value to set.\n   * @param controller Controller of the form value.\n   * @param input Input element.\n   */\n  setFormattedValue?: (\n    formattedValue: TFormatted,\n    state: FormatterControllerState<T, TFormatted>,\n    input: TInput | null,\n  ) => void;\n  /**\n   * Function that formats the form manager value into a value to be set in the\n   * input element. The passed {@link value} is `undefined` when the form\n   * manager value does not exist.\n   * @param value Form manager value to transform.\n   * @param controller Controller of the value to transform.\n   * @param input Input element.\n   * @returns Transformed value.\n   */\n  format?: (\n    value: T | undefined,\n    state: FormatterControllerState<T, TFormatted>,\n    input: TInput | null,\n  ) => TFormatted | PromiseLike<TFormatted>;\n  /**\n   * Function used to parse the input element value into a value to be set in\n   * the form manager.\n   * @param formattedValue Input element value to transform.\n   * @param controller Controller of the value to transform.\n   * @param input Input element.\n   * @returns Transformed value.\n   */\n  parse?: (\n    formattedValue: TFormatted,\n    state: FormatterControllerState<T, TFormatted>,\n    input: TInput | null,\n  ) => T | PromiseLike<T>;\n}\n\n/**\n * Controller used to read and manipulate the form value associated with the\n * form input, exposing properties that should be set on the input itself.\n */\nexport type InputController<\n  T = unknown,\n  TFormatted = T | undefined,\n  TInput = unknown,\n> = FormatterController<T, TFormatted> & InputOwnController<TFormatted, TInput>;\n\n/**\n * Input own controller.\n */\nexport interface InputOwnController<TFormatted = unknown, TInput = unknown> {\n  /**\n   * Properties to be passed to the input element.\n   */\n  inputProps: InputElementProps<TFormatted, TInput>;\n}\n\n/**\n * Properties to provide to an input element to integrate it with a form\n * manager.\n */\nexport interface InputElementProps<TFormatted = unknown, TInput = unknown> {\n  /**\n   * Name of the input element.\n   */\n  name: string;\n  /**\n   * Whether the input element should be read-only.\n   *\n   * This is `true` when the schema associated with this input is computed.\n   */\n  readOnly: boolean;\n  /**\n   * Reference to the input element.\n   */\n  ref: React.Ref<TInput>;\n  /**\n   * Function to run whenever the value of the input element changes. This\n   * function can receive either a change event with a standard HTML input\n   * ({@link HTMLInputElement <input>}, {@link HTMLSelectElement <select>},\n   * {@link HTMLTextAreaElement <textarea>}) as target or a value directly.\n   *\n   * This function sets the new value in the form manager and marks the value as\n   * dirty.\n   * @param eventOrValue Either a \"change event\" or the new value.\n   */\n  onChange: (eventOrValue: React.ChangeEvent | TFormatted) => void;\n  /**\n   * Function to run whenever the input element is blurred. This function marks\n   * the form value as \"touched\").\n   */\n  onBlur: () => void;\n}\n\n/**\n * Hook used to control the integration between a value of the form manager and\n * an input of the form. It provides access to the form value, as well as\n * properties for integration with an input element.\n * @param path Path of the form value to access, relative to the current path.\n * @param options Available options.\n * @returns A controller used to read and control the form value associated with\n * the form input, exposing properties that should be set on the input itself.\n */\nexport function useInput<T = unknown, TInput = unknown>(\n  path?: Path | string,\n  options?: undefined,\n): InputController<T, T | undefined, TInput>;\nexport function useInput<\n  T = unknown,\n  TFormatted = T | undefined,\n  TInput = unknown,\n>(\n  path: Path | string | undefined,\n  options: InputOptions<T, TFormatted, TInput>,\n): InputController<T, TFormatted, TInput>;\nexport function useInput<\n  T = unknown,\n  TFormatted = T | undefined,\n  TInput = unknown,\n>(\n  path: Path | string = Path.CURRENT,\n  {\n    setFormattedValue = defaultSetFormattedValue,\n    format,\n    parse,\n    ...options\n  }: InputOptions<T, TFormatted, TInput> = {},\n): InputController<T, TFormatted, TInput> {\n  const latestOptions = useLatestValues({ parse, setFormattedValue });\n\n  const inputRef = React.useRef<TInput>(null);\n  const activeSetPromiseRef = React.useRef<CancellablePromise<void> | null>(\n    null,\n  );\n\n  // Formatter options\n  const formatterSetFormattedValue = React.useCallback(\n    (\n      formattedValue: TFormatted,\n      state: FormatterControllerState<T, TFormatted>,\n    ) => {\n      // Only set the value if we're not currently setting it\n      if (activeSetPromiseRef.current == null) {\n        setFormattedValue(formattedValue as never, state, inputRef.current);\n      }\n    },\n    [setFormattedValue],\n  );\n  const formatterFormat = React.useCallback(\n    (value: T | undefined, state: FormatterControllerState<T, TFormatted>) =>\n      format ? format(value, state, inputRef.current) : (value as TFormatted),\n    [format],\n  );\n\n  const controller = useFormatter(path, {\n    setFormattedValue: formatterSetFormattedValue,\n    format: formatterFormat,\n    ...options,\n  });\n\n  const handleChange = React.useCallback(\n    async (eventOrValue: React.ChangeEvent | TFormatted) => {\n      const {\n        schema,\n        observingDescendants,\n        initialized,\n        exists,\n        dirty,\n        formattedValue,\n      } = controller.getState();\n      if (initialized && exists && !isComputedSchema(schema)) {\n        const newValue = isChangeEvent(eventOrValue)\n          ? (getEventValue(eventOrValue.target, eventOrValue) as TFormatted)\n          : eventOrValue;\n        const parsedValue = latestOptions.parse\n          ? await latestOptions.parse(\n              newValue as never,\n              controller.getState(),\n              inputRef.current,\n            )\n          : (newValue as unknown as T);\n        if (!equals(formattedValue, parsedValue)) {\n          // Cancel previous `set`\n          activeSetPromiseRef.current?.cancel(\"New value is being set.\");\n          const newSetPromise = (activeSetPromiseRef.current = controller\n            .set(parsedValue)\n            .catch(ignorePromiseCancellationException)\n            .finally(() => {\n              if (activeSetPromiseRef.current === newSetPromise) {\n                activeSetPromiseRef.current = null;\n              }\n            }));\n          if (!dirty) {\n            void controller.setDirty(\n              observingDescendants ? Path.CURRENT_DEEP : Path.CURRENT,\n            );\n          }\n        }\n      }\n    },\n    [controller, latestOptions],\n  );\n  const handleBlur = React.useCallback(() => {\n    const {\n      observingDescendants,\n      initialized,\n      exists,\n      touched,\n      formattedValue,\n    } = controller.getState();\n    if (initialized && exists) {\n      if (!touched) {\n        void controller.setTouched(\n          observingDescendants ? Path.CURRENT_DEEP : Path.CURRENT,\n        );\n      }\n\n      if (activeSetPromiseRef.current == null) {\n        latestOptions.setFormattedValue(\n          formattedValue,\n          controller.getState(),\n          inputRef.current,\n        );\n      } else {\n        activeSetPromiseRef.current = null;\n      }\n    }\n  }, [controller, latestOptions]);\n\n  // Listeners for changes coming from the input\n  const listeners = useLatestValues({\n    onChange: handleChange,\n    onBlur: handleBlur,\n  });\n\n  const inputName = controller.useState((state) => state.path.toString());\n  const isComputed = controller.useState((state) =>\n    isComputedSchema(state.schema),\n  );\n  const inputProps = React.useMemo(\n    () => ({\n      name: inputName,\n      readOnly: isComputed,\n      ref: inputRef,\n      onChange: (eventOrValue: React.ChangeEvent | TFormatted) =>\n        listeners.onChange(eventOrValue),\n      onBlur: () => listeners.onBlur(),\n    }),\n    [inputName, isComputed, listeners],\n  );\n\n  return React.useMemo(\n    () => ({ ...controller, inputProps }),\n    [controller, inputProps],\n  );\n}\n\n/**\n * Default function used to set a formatted value within an input element.\n */\nexport function defaultSetFormattedValue(\n  formattedValue: unknown,\n  _state: any,\n  input: unknown,\n) {\n  if (input == null) {\n    return;\n  }\n\n  if (input instanceof HTMLInputElement && input.type === \"checkbox\") {\n    const oldInputValue = input.checked;\n    const newInputValue = !!formattedValue;\n    if (oldInputValue !== newInputValue) {\n      input.checked = newInputValue;\n    }\n  } else if (input instanceof HTMLInputElement && input.type === \"file\") {\n    if (formattedValue instanceof FileList) {\n      input.files = formattedValue;\n    } else {\n      input.value = \"\";\n    }\n  } else if (\n    input instanceof HTMLInputElement ||\n    input instanceof HTMLSelectElement ||\n    input instanceof HTMLTextAreaElement\n  ) {\n    const oldInputValue = input.value;\n    // eslint-disable-next-line @typescript-eslint/no-base-to-string\n    const newInputValue = String(formattedValue ?? \"\");\n    if (oldInputValue !== newInputValue) {\n      input.value = newInputValue;\n    }\n  } else {\n    throw new Error(\n      \"Unknown input element, please provide a custom `setFormattedValue` \" +\n        \"function.\",\n    );\n  }\n}\n\n/**\n * Whether a given value is a change event.\n */\nfunction isChangeEvent(value: unknown): value is React.ChangeEvent {\n  return (\n    value !== null &&\n    typeof value === \"object\" &&\n    \"target\" in value &&\n    value.target !== null &&\n    typeof value.target === \"object\"\n  );\n}\n\n/**\n * Obtains the value of an element given the event's target.\n */\nfunction getEventValue(\n  eventTarget: EventTarget,\n  defaultValue: unknown,\n): unknown {\n  return eventTarget instanceof HTMLInputElement ||\n    eventTarget instanceof HTMLTextAreaElement ||\n    eventTarget instanceof HTMLSelectElement\n    ? eventTarget.type === \"checkbox\"\n      ? (eventTarget as HTMLInputElement).checked\n      : eventTarget.type === \"file\"\n        ? (eventTarget as HTMLInputElement).files\n        : eventTarget.value\n    : defaultValue;\n}\n","import { Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { FormContext, FormContextValue } from \"../contexts/FormContext\";\nimport { FormatterControllerState } from \"../hooks/useFormatter\";\nimport { InputElementProps, InputOptions, useInput } from \"../hooks/useInput\";\nimport { shallow } from \"../utils/shallow\";\n\n/**\n * Properties of the {@link Input} component.\n */\nexport type InputProps<\n  T = unknown,\n  TFormatted = T | undefined,\n  TInput = unknown,\n> = InputOptions<T, TFormatted, TInput> & InputOwnProps<T, TFormatted, TInput>;\n\n/**\n * Own properties of the {@link Input} component.\n */\nexport interface InputOwnProps<\n  T = unknown,\n  TFormatted = T | undefined,\n  TInput = unknown,\n> {\n  path?: Path | string;\n  children: (\n    elementProps: InputElementProps<TFormatted, TInput>,\n    state: FormatterControllerState<T, TFormatted>,\n  ) => React.ReactNode;\n}\n\n/**\n * Component used to wrap an input so that it \"connects\" to a form value.\n *\n * This component is a wrapper around the {@link useInput} hook.\n */\nexport function Input<\n  T = unknown,\n  TFormatted = T | undefined,\n  TInput = unknown,\n>({ path, children, ...props }: InputProps<T, TFormatted, TInput>) {\n  const formContext = React.useContext(FormContext);\n  const inputController = useInput(path, props);\n\n  const formManager = inputController.useFormManager();\n  const currentPath = inputController.usePath();\n  const newFormContext = React.useMemo<FormContextValue>(\n    () => ({\n      formManager,\n      currentPath,\n      controller:\n        formContext?.formManager === formManager\n          ? formContext.controller\n          : undefined,\n    }),\n    [\n      currentPath,\n      formContext?.controller,\n      formContext?.formManager,\n      formManager,\n    ],\n  );\n\n  const state = inputController.useState((state) => state, {\n    equalityFn: shallow,\n  });\n  return (\n    <FormContext.Provider value={newFormContext}>\n      {children(inputController.inputProps, state)}\n    </FormContext.Provider>\n  );\n}\n","import { AbsolutePath } from \"@kform/core\";\n\nimport { useFormContext } from \"./useFormContext\";\n\n/**\n * Hook providing access to the current path within the context of a form.\n * @throws {NoFormContextError} When no form is in context.\n * @returns The current path within the context of a form.\n */\nexport function useCurrentPath(): AbsolutePath {\n  return useFormContext().currentPath;\n}\n","import {\n  emptyPlaceholderKFormFile,\n  File as KFormFile,\n  jsFileToKFormFile,\n  kFormFileToJsFile,\n  Schema,\n} from \"@kform/core\";\n\n/**\n * Formats a KForm file {@link value} as a [file list]{@link FileList}, given\n * its {@link schema}.\n * @param value KForm file value to format as a file list.\n * @param schema Schema of the numeric {@link value}.\n * @returns String representation of the numeric {@link value}.\n */\nexport function formatKFormFileAsFileList<\n  T extends KFormFile | null = KFormFile | null,\n  // Not using the `schema` is an implementation detail\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n>(value: T | undefined, schema: Schema<T>): FileList {\n  const dataTransfer = new DataTransfer();\n  if (value != null) {\n    dataTransfer.items.add(kFormFileToJsFile(value));\n  }\n  return dataTransfer.files;\n}\n\n/**\n * Parses a formatted file list [value]{@link formattedValue} as a KForm file\n * value, given the {@link schema} of the expected KForm file value.\n * @param formattedValue Formatted value to parse as a KForm file value.\n * @param schema Schema of the expected KForm file value.\n * @returns KForm file representation of the\n * [formatted value]{@link formattedValue} according to {@link schema}.\n */\nexport function parseFileListAsKFormFile<\n  T extends KFormFile | null = KFormFile | null,\n>(formattedValue: FileList, schema: Schema<T>): T | Promise<T> {\n  if (formattedValue.length === 0) {\n    return (schema.typeInfo.nullable ? null : emptyPlaceholderKFormFile()) as T;\n  }\n  return jsFileToKFormFile(formattedValue[0]) as Promise<T>;\n}\n","import { File as KFormFile, Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { PathError } from \"../utils/errors\";\nimport {\n  formatKFormFileAsFileList,\n  parseFileListAsKFormFile,\n} from \"../utils/fileUtils\";\nimport { useLatestValues } from \"../utils/useLatestValues\";\nimport { Controller } from \"./useController\";\nimport { FormatterControllerState } from \"./useFormatter\";\nimport { InputOptions, InputOwnController, useInput } from \"./useInput\";\n\n/**\n * Options available to the {@link useFileInput} hook.\n */\nexport type FileInputOptions<\n  T extends KFormFile | null = KFormFile | null,\n  TFormatted = FileList,\n  TInput = HTMLInputElement,\n> = Omit<InputOptions<T, TFormatted, TInput>, \"format\" | \"parse\"> &\n  FileInputOwnOptions<T, TFormatted, TInput>;\n\n/**\n * Own options available to the {@link useFileInput} hook.\n */\nexport interface FileInputOwnOptions<\n  T extends KFormFile | null = KFormFile | null,\n  TFormatted = FileList,\n  TInput = HTMLInputElement,\n> {\n  formatFromFileList?: (\n    fileListValue: FileList,\n    state: FormatterControllerState<T, TFormatted>,\n    input: TInput | null,\n  ) => TFormatted;\n  parseToFileList?: (\n    formattedValue: TFormatted,\n    state: FormatterControllerState<T, TFormatted>,\n    input: TInput | null,\n  ) => FileList;\n}\n\n/**\n * Controller used to read and control the form value associated with the form\n * input, exposing properties that should be set on the input itself.\n */\nexport type FileInputController<\n  T extends KFormFile | null = KFormFile | null,\n  TFormatted = FileList,\n  TInput = HTMLInputElement,\n> = Controller<T> & FileInputOwnController<TFormatted, TInput>;\n\n/**\n * Own file input controller.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface FileInputOwnController<\n  TFormatted = FileList,\n  TInput = HTMLInputElement,\n> extends InputOwnController<TFormatted, TInput> {}\n\n/**\n * Hook controlling the integration between a file value of the form manager\n * and an input of the form.\n * @param path Path of the file form value to access, relative to the current\n * path.\n * @param options Available options.\n * @throws {PathError} When the value at {@link path} is not a file.\n * @returns A controller used to read and control the file form value associated\n * with the form input, exposing properties that should be set on the input\n * itself.\n */\nexport function useFileInput<\n  T extends KFormFile | null = KFormFile | null,\n  TFormatted = File,\n  TInput = HTMLInputElement,\n>(\n  path?: Path | string,\n  options?: undefined,\n): FileInputController<T, TFormatted, TInput>;\nexport function useFileInput<\n  T extends KFormFile | null = KFormFile | null,\n  TFormatted = File,\n  TInput = HTMLInputElement,\n>(\n  path: Path | string | undefined,\n  options: FileInputOptions<T, TFormatted, TInput>,\n): FileInputController<T, TFormatted, TInput>;\nexport function useFileInput<\n  T extends KFormFile | null = KFormFile | null,\n  TFormatted = File,\n  TInput = HTMLInputElement,\n>(\n  path: Path | string = Path.CURRENT,\n  {\n    formatFromFileList,\n    parseToFileList,\n    ...options\n  }: FileInputOptions<T, TFormatted, TInput> = {},\n): FileInputController<T, TFormatted, TInput> {\n  const latestOptions = useLatestValues({ parseToFileList });\n\n  // Input options\n  const format = React.useCallback(\n    (\n      value: T | undefined,\n      state: FormatterControllerState<T, TFormatted>,\n      input: TInput | null,\n    ): TFormatted => {\n      const fileList = formatKFormFileAsFileList(value, state.schema);\n      return formatFromFileList\n        ? formatFromFileList(fileList, state, input)\n        : (fileList as TFormatted);\n    },\n    [formatFromFileList],\n  );\n  const parse = React.useCallback(\n    (\n      formattedValue: TFormatted,\n      state: FormatterControllerState<T, TFormatted>,\n      input: TInput | null,\n    ): T | Promise<T> => {\n      return parseFileListAsKFormFile(\n        latestOptions.parseToFileList\n          ? latestOptions.parseToFileList(formattedValue, state, input)\n          : (formattedValue as FileList),\n        state.schema,\n      );\n    },\n    [latestOptions],\n  );\n\n  const inputController = useInput(path, { format, parse, ...options });\n\n  // Validate schema type\n  const { typeInfo } = inputController.useSchema();\n  if (typeInfo.name !== \"File\") {\n    throw new PathError(\n      inputController.getState().path,\n      \"Unsupported schema: Expected schema representing (possibly nullable) \" +\n        \"file values, but got schema representing values of type \" +\n        `'${typeInfo.toString()}'.`,\n    );\n  }\n\n  return inputController;\n}\n","import { Path } from \"@kform/core\";\n\nimport { shallow } from \"../utils/shallow\";\nimport { DistributedOmit } from \"../utils/typeUtils\";\nimport { Controller } from \"./useController\";\nimport { FormatterOptions, useFormatter } from \"./useFormatter\";\n\n/**\n * Options available to the {@link useFormattedValue} hook.\n */\nexport type FormattedValueOptions<\n  T = unknown,\n  TFormatted = T | undefined,\n> = DistributedOmit<FormatterOptions<T, TFormatted>, \"setFormattedValue\">;\n\n/**\n * Result of the {@link useFormattedValue}: a pair used to read and control the\n * form value, containing its formatted representation in the first position of\n * the returned pair.\n */\nexport type FormattedValueResult<T = unknown, TFormatted = T | undefined> = [\n  formattedValue: TFormatted | undefined,\n  controller: Controller<T>,\n];\n\n/**\n * Hook facilitating the generation of a formatted value from a value in the\n * form manager by providing a way of formatting said value.\n * @param path Path of the form value to access, relative to the current path.\n * @param options Available options.\n * @returns A controller used to read and manipulate the form value.\n */\nexport function useFormattedValue<T = unknown>(\n  path?: Path | string,\n  options?: undefined,\n): FormattedValueResult<T, T | undefined>;\nexport function useFormattedValue<T = unknown, TFormatted = T | undefined>(\n  path: Path | string | undefined,\n  options: FormattedValueOptions<T, TFormatted>,\n): FormattedValueResult<T, TFormatted>;\nexport function useFormattedValue<T = unknown, TFormatted = T | undefined>(\n  path: Path | string = Path.CURRENT,\n  options: FormattedValueOptions<T, TFormatted> = {},\n): FormattedValueResult<T, TFormatted> {\n  const formatterController = useFormatter<T, TFormatted>(path, options);\n  return formatterController.useState(\n    (state) => [state.formattedValue, formatterController],\n    { equalityFn: shallow },\n  );\n}\n","import { NoFormControllerError } from \"../utils/errors\";\nimport { FormController } from \"./useForm\";\nimport { useFormContext } from \"./useFormContext\";\n\n/**\n * Hook providing access to the controller of the form in context.\n * @throws {NoFormContextError} When no form is in context.\n * @throws {NoFormControllerError} When no form controller is in context.\n * @returns Controller of the form in context.\n */\nexport function useFormController<T = unknown>(): FormController<T> {\n  const formController = useFormContext<T>().controller;\n  if (formController == null) {\n    throw new NoFormControllerError();\n  }\n  return formController;\n}\n","/**\n * Searches the provided array for the provided element using the binary search\n * algorithm.\n * @param array Sorted array (in an order compatible with `compareFn`) in which\n * to find the provided element.\n * @param element Element to find in the array.\n * @param compareFn Comparison function.\n * @returns The index of the element if it is contained in the array; otherwise,\n * the inverted insertion point `-i - 1`.\n */\nexport function binarySearch<T>(\n  array: T[],\n  element: T,\n  compareFn: (v1: T, v2: T) => number,\n): number {\n  let low = 0;\n  let high = array.length - 1;\n  while (low <= high) {\n    const mid = (low + high) >>> 1;\n    const cmp = compareFn(array[mid], element);\n    if (cmp < 0) {\n      low = mid + 1;\n    } else if (cmp > 0) {\n      high = mid - 1;\n    } else {\n      return mid;\n    }\n  }\n  return -(low + 1);\n}\n","import {\n  AbsolutePath,\n  CancellablePromise,\n  compareSchemaPaths,\n  DisplayStatus,\n  FormManager,\n  Info,\n  Path,\n  SealedValidationIssue,\n  StateEvent,\n  ValueEvent,\n} from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { binarySearch } from \"../utils/binarySearch\";\nimport { ignorePromiseCancellationException } from \"../utils/ignorePromiseCancellationException\";\nimport { useFormManager } from \"./useFormManager\";\nimport { useResolvedPath } from \"./useResolvedPath\";\n\n/**\n * Options available to the {@link useIssuesTracker} hook.\n */\nexport interface IssuesTrackerOptions {\n  /**\n   * Required if no form context is in scope.\n   *\n   * If a form context is in scope and this value is also provided, then the\n   * provided form manager will be used, in which case the current path of the\n   * form context is ignored.\n   */\n  formManager?: FormManager;\n  /**\n   * Function which may be provided to specify the order of the resulting\n   * issues.\n   *\n   * It receives the paths of the issues being compared and should return a\n   * number in typical\n   * [Array.prototype.sort#compareFn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#comparefn)\n   * fashion to determine the order of the issues.\n   *\n   * The default ordering is based on the order in which fields were declared\n   * within the form schema. If this function is provided, and `0` is returned,\n   * then the default schema-based ordering will be used for disambiguation.\n   *\n   * Note that this function should **not** change on every render, as any\n   * change to this function will cause the tracker to \"restart\".\n   * @param path1 First path being compared.\n   * @param path2 Second path being compared.\n   * @returns Positive number if `path1 > path2`, negative number if\n   * `path2 > path1`, `0` otherwise.\n   */\n  issuesOrderCompareFn?: (path1: AbsolutePath, path2: AbsolutePath) => number;\n  /**\n   * Whether to enable validation issues tracking.\n   * @default true\n   */\n  enabled?: boolean;\n}\n\n/**\n * Result of the {@link useIssuesTracker} hook, containing the validation issues\n * of the tracked values (when tracking and initialised).\n */\nexport type IssuesTrackerResult =\n  | UninitializedTrackedValidationIssues\n  | InitializedTrackedValidationIssues;\n\n/**\n * Base representation of the result of the {@link useIssuesTracker}\n * hook.\n */\nexport interface BaseIssuesTrackerResult {\n  /**\n   * Whether the tracking of validation issues has been initialised.\n   */\n  initialized: boolean;\n  /**\n   * Validation information about the values with issues.\n   */\n  info?: LocatedValidationInfo[];\n  /**\n   * Total number of errors.\n   */\n  errors?: number;\n  /**\n   * Total number of warnings.\n   */\n  warnings?: number;\n}\n\n/**\n * Result of the {@link useIssuesTracker} hook while initialising the\n * tracking of validation issues.\n */\nexport interface UninitializedTrackedValidationIssues\n  extends BaseIssuesTrackerResult {\n  initialized: false;\n  info?: undefined;\n  errors?: undefined;\n  warnings?: undefined;\n}\n\n/**\n * Result of the {@link useIssuesTracker} hook while tracking\n * validation issues.\n */\nexport interface InitializedTrackedValidationIssues\n  extends BaseIssuesTrackerResult {\n  initialized: true;\n  info: LocatedValidationInfo[];\n  errors: number;\n  warnings: number;\n}\n\n/**\n * Information about the issues of a certain value.\n */\nexport interface LocatedValidationInfo {\n  /**\n   * Path of the value with issues.\n   */\n  path: AbsolutePath;\n  /**\n   * Issues of the value (the array is guaranteed to not be empty).\n   */\n  issues: SealedValidationIssue[];\n  /**\n   * Local display status of the value (ignores issues of descendants).\n   */\n  localDisplayStatus: Exclude<DisplayStatus, \"valid\">;\n}\n\n/**\n * Internal validation state of a value.\n */\ntype ValidationState = Pick<Info, \"touched\" | \"issues\">;\n\n/**\n * Hook used to keep track of validation issues of values at paths matching\n * {@link path}.\n * @param path Path of values for which to keep track of validation issues.\n * Defaults to `/**`.\n * @param issuesTrackerOptions Available options.\n * @returns Object containing information on issues of values at paths matching\n * {@link path}.\n */\nexport function useIssuesTracker(\n  path: Path | string = Path.CURRENT_DEEP,\n  {\n    formManager: formManagerOption,\n    issuesOrderCompareFn,\n    enabled = true,\n  }: IssuesTrackerOptions = {},\n): IssuesTrackerResult {\n  const formManager = useFormManager(formManagerOption);\n  const absolutePath = useResolvedPath(\n    path,\n    formManagerOption != null ? AbsolutePath.ROOT : undefined,\n  );\n  const formSchema = React.useMemo(() => formManager.schema(), [formManager]);\n\n  const compareInfo = React.useCallback(\n    (info1: LocatedValidationInfo, info2: LocatedValidationInfo): number =>\n      issuesOrderCompareFn?.(info1.path, info2.path) ||\n      compareSchemaPaths(formSchema, info1.path, info2.path),\n    [formSchema, issuesOrderCompareFn],\n  );\n\n  const [trackedState, setTrackedState] = React.useState<IssuesTrackerResult>({\n    initialized: false,\n  });\n\n  React.useEffect(() => {\n    if (!enabled) {\n      return;\n    }\n\n    let cleanedUp = false;\n    let unsubscribe: (() => CancellablePromise<void>) | undefined = undefined;\n    const stateByPath = new Map<string, ValidationState>();\n    let trackedInfo: LocatedValidationInfo[] = [];\n    let errors = 0;\n    let warnings = 0;\n\n    const infoPromise = formManager\n      .info(absolutePath, async (infoIterable) => {\n        if (cleanedUp) {\n          return;\n        }\n\n        // Initialise tracked state\n        for await (const info of infoIterable) {\n          const newState = { touched: info.touched, issues: info.issues };\n          stateByPath.set(info.path.toString(), newState);\n          const newInfo = validationStateToValidationInfo(info.path, newState);\n          if (newInfo !== undefined) {\n            trackedInfo.push(newInfo);\n            const counts = countIssueSeverities(info.issues);\n            errors += counts.errors;\n            warnings += counts.warnings;\n          }\n        }\n        setTrackedState({\n          initialized: true,\n          info: trackedInfo.sort(compareInfo),\n          errors,\n          warnings,\n        });\n\n        unsubscribe = await formManager.subscribe(absolutePath, (event) => {\n          // Unsubscribing is asynchronous, so it's possible that an event is\n          // emitted after cleaning up, but before unsubscribing, which we\n          // should ignore\n          if (cleanedUp) {\n            return;\n          }\n\n          const pathStr = event.path.toString();\n          const oldState = stateByPath.get(pathStr);\n          let newState: ValidationState | undefined = oldState;\n\n          if (event instanceof ValueEvent.Init) {\n            newState = { touched: false, issues: [] };\n          } else if (event instanceof ValueEvent.Destroy) {\n            newState = undefined;\n          } else if (event instanceof StateEvent.ValidationChange) {\n            newState = {\n              touched: oldState?.touched ?? false,\n              issues: event.issues,\n            };\n          } else if (event instanceof StateEvent.TouchedChange) {\n            newState = {\n              touched: event.status,\n              issues: oldState?.issues ?? [],\n            };\n          }\n\n          if (oldState === newState) {\n            return;\n          }\n\n          // Update state by path map\n          if (!newState) {\n            stateByPath.delete(pathStr);\n          } else {\n            stateByPath.set(pathStr, newState);\n          }\n\n          // Update tracked state when something actually changes\n          const oldCountedIssues = oldState?.touched ? oldState.issues : [];\n          const newCountedIssues = newState?.touched ? newState.issues : [];\n          if (!equalIssues(oldCountedIssues, newCountedIssues)) {\n            trackedInfo = updateTrackedInfo(\n              trackedInfo,\n              event.path,\n              newState,\n              compareInfo,\n            );\n            const oldCounts = countIssueSeverities(oldCountedIssues);\n            const newCounts = countIssueSeverities(newCountedIssues);\n            errors += newCounts.errors - oldCounts.errors;\n            warnings += newCounts.warnings - oldCounts.warnings;\n\n            setTrackedState({\n              initialized: true,\n              info: trackedInfo,\n              errors,\n              warnings,\n            });\n          }\n        });\n      })\n      .catch(ignorePromiseCancellationException);\n\n    return () => {\n      cleanedUp = true;\n      infoPromise.cancel(\n        `Clean up 'useEffect' access to info of '${absolutePath.toString()}'.`,\n      );\n      void unsubscribe?.();\n      setTrackedState({ initialized: false });\n    };\n  }, [absolutePath, compareInfo, enabled, formManager]);\n\n  return trackedState;\n}\n\nfunction validationStateToValidationInfo(\n  path: AbsolutePath,\n  state: ValidationState | undefined,\n): LocatedValidationInfo | undefined {\n  return state?.touched && state.issues.length > 0\n    ? {\n        path,\n        issues: state.issues,\n        localDisplayStatus: state.issues.some(\n          (issue) => issue.severity === \"error\",\n        )\n          ? \"error\"\n          : \"warning\",\n      }\n    : undefined;\n}\n\nfunction updateTrackedInfo(\n  trackedInfo: LocatedValidationInfo[],\n  path: AbsolutePath,\n  newState: ValidationState | undefined,\n  compareInfo: (\n    info1: LocatedValidationInfo,\n    info2: LocatedValidationInfo,\n  ) => number,\n) {\n  const infoOfPath = { path } as LocatedValidationInfo;\n  const index = binarySearch(trackedInfo, infoOfPath, compareInfo);\n  const newInfo = validationStateToValidationInfo(path, newState);\n\n  if (index < 0 && newInfo === undefined) {\n    return trackedInfo;\n  }\n\n  // TODO: Use `toSpliced` and `with` instead of slicing first once browser\n  //  support is better\n  const result = trackedInfo.slice();\n  if (index >= 0) {\n    if (newInfo === undefined) {\n      result.splice(index, 1);\n    } else {\n      result[index] = newInfo;\n    }\n  } else {\n    result.splice(-index - 1, 0, newInfo!);\n  }\n  return result;\n}\n\nfunction countIssueSeverities(issues: SealedValidationIssue[]): {\n  errors: number;\n  warnings: number;\n} {\n  let errors = 0;\n  let warnings = 0;\n  for (const issue of issues) {\n    if (issue.severity === \"error\") {\n      ++errors;\n    } else {\n      ++warnings;\n    }\n  }\n  return { errors, warnings };\n}\n\nfunction equalIssues(\n  issues1: SealedValidationIssue[],\n  issues2: SealedValidationIssue[],\n): boolean {\n  return (\n    issues1.length === issues2.length &&\n    issues1.every((issue, i) => issue.equals(issues2[i]))\n  );\n}\n","import {\n  arrayToList,\n  arrayToTable,\n  KtList,\n  listableToArray,\n  Schema,\n  Table,\n} from \"@kform/core\";\n\n/**\n * Supported listable types.\n */\nexport type Listable<T = unknown> = T[] | KtList<T> | Table<T>;\n\n/**\n * Formats a listable {@link value} as an array, given its {@link schema}.\n * @param value Listable value to format as an array.\n * @param schema Schema of the listable {@link value}.\n * @returns Array representation of the listable {@link value}.\n */\nexport function formatListableAsArray<\n  T = unknown,\n  TListable extends Listable<T> | null = Listable<T> | null,\n  // Not using the `schema` is an implementation detail\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n>(value: TListable | undefined, schema: Schema<TListable>): T[] | null {\n  return value == null ? null : listableToArray(value);\n}\n\n/**\n * Parses a listable [value]{@link formattedValue} formatted as an array as a\n * listable value, given the {@link schema} of the expected listable value.\n * @param formattedValue Array value to parse as a listable value.\n * @param schema Schema of the expected listable value.\n * @returns Listable representation of the\n * [formatted value]{@link formattedValue} according to {@link schema}.\n */\nexport function parseArrayAsListable<\n  T = unknown,\n  TListable extends Listable<T> | null = Listable<T> | null,\n>(formattedValue: T[] | null, schema: Schema<TListable>): TListable {\n  const supportsNull = schema.typeInfo.nullable;\n  const schemaType = schema.typeInfo.name;\n  if (formattedValue == null) {\n    if (supportsNull) {\n      return null as TListable;\n    } else {\n      formattedValue = [];\n    }\n  }\n\n  switch (schemaType) {\n    case \"Array\":\n      return formattedValue as TListable;\n    case \"List\":\n      return arrayToList(formattedValue) as TListable;\n    default: // `Table`\n      return arrayToTable(formattedValue) as TListable;\n  }\n}\n","import { Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { PathError } from \"../utils/errors\";\nimport {\n  formatListableAsArray,\n  Listable,\n  parseArrayAsListable,\n} from \"../utils/listableUtils\";\nimport { useLatestValues } from \"../utils/useLatestValues\";\nimport { Controller } from \"./useController\";\nimport { FormatterControllerState } from \"./useFormatter\";\nimport { InputOptions, InputOwnController, useInput } from \"./useInput\";\n\n/**\n * Options available to the {@link useListableInput} hook.\n */\nexport type ListableInputOptions<\n  T = unknown,\n  TListable extends Listable<T> | null = Listable<T> | null,\n  TFormatted = T[] | null,\n  TInput = HTMLInputElement,\n> = Omit<InputOptions<TListable, TFormatted, TInput>, \"format\" | \"parse\"> &\n  ListableInputOwnOptions<T, TListable, TFormatted, TInput>;\n\n/**\n * Own options available to the {@link useListableInput} hook.\n */\nexport interface ListableInputOwnOptions<\n  T = unknown,\n  TListable extends Listable<T> | null = Listable<T> | null,\n  TFormatted = T[] | null,\n  TInput = HTMLInputElement,\n> {\n  formatFromArray?: (\n    arrayValue: T[] | null,\n    state: FormatterControllerState<TListable, TFormatted>,\n    input: TInput | null,\n  ) => TFormatted;\n  parseToArray?: (\n    formattedValue: TFormatted,\n    state: FormatterControllerState<TListable, TFormatted>,\n    input: TInput | null,\n  ) => T[] | null;\n}\n\n/**\n * Controller used to read and control the form value associated with the form\n * input, exposing properties that should be set on the input itself.\n */\nexport type ListableInputController<\n  T = unknown,\n  TListable extends Listable<T> | null = Listable<T> | null,\n  TFormatted = T[] | null,\n  TInput = HTMLInputElement,\n> = Controller<TListable> & ListableInputOwnController<T, TFormatted, TInput>;\n\n/**\n * Own listable input controller.\n */\nexport type ListableInputOwnController<\n  T = unknown,\n  TFormatted = T[],\n  TInput = HTMLInputElement,\n> = InputOwnController<TFormatted, TInput>;\n\n/**\n * Allowed listable types.\n */\nconst ALLOWED_COLLECTION_TYPES = [\"Array\", \"List\", \"Table\"];\n\n/**\n * Hook controlling the integration between a listable value (`Array`, `List`,\n * or `Table`) of the form manager and an input of the form.\n * @param path Path of the listable form value to access, relative to the\n * current path.\n * @param options Available options.\n * @throws {PathError} When the value at {@link path} is not listable (not an\n * `Array`, `List`, or `Table`).\n * @returns A controller used to read and control the listable form value\n * associated with the form input, exposing properties that should be set on the\n * input itself.\n */\nexport function useListableInput<\n  T = unknown,\n  TListable extends Listable<T> | null = Listable<T> | null,\n  TFormatted = T[] | null,\n  TInput = HTMLInputElement,\n>(\n  path?: Path | string,\n  options?: undefined,\n): ListableInputController<T, TListable, TFormatted, TInput>;\nexport function useListableInput<\n  T = unknown,\n  TListable extends Listable<T> | null = Listable<T> | null,\n  TFormatted = T[] | null,\n  TInput = HTMLInputElement,\n>(\n  path: Path | string | undefined,\n  options: ListableInputOptions<T, TListable, TFormatted, TInput>,\n): ListableInputController<T, TListable, TFormatted, TInput>;\nexport function useListableInput<\n  T = unknown,\n  TListable extends Listable<T> | null = Listable<T> | null,\n  TFormatted = T[] | null,\n  TInput = HTMLInputElement,\n>(\n  path: Path | string = Path.CURRENT,\n  {\n    formatFromArray,\n    parseToArray,\n    ...options\n  }: ListableInputOptions<T, TListable, TFormatted, TInput> = {},\n): ListableInputController<T, TListable, TFormatted, TInput> {\n  const latestOptions = useLatestValues({ parseToArray });\n\n  // Input options\n  const format = React.useCallback(\n    (\n      value: TListable | undefined,\n      state: FormatterControllerState<TListable, TFormatted>,\n      input: TInput | null,\n    ): TFormatted => {\n      const array = formatListableAsArray<T, TListable>(value, state.schema);\n      return formatFromArray\n        ? formatFromArray(array, state, input)\n        : (array as TFormatted);\n    },\n    [formatFromArray],\n  );\n  const parse = React.useCallback(\n    (\n      formattedValue: TFormatted,\n      state: FormatterControllerState<TListable, TFormatted>,\n      input: TInput | null,\n    ): TListable => {\n      return parseArrayAsListable(\n        latestOptions.parseToArray\n          ? latestOptions.parseToArray(formattedValue, state, input)\n          : (formattedValue as T[]),\n        state.schema,\n      );\n    },\n    [latestOptions],\n  );\n\n  const inputController = useInput(path, { format, parse, ...options });\n\n  // Validate schema type\n  const { typeInfo } = inputController.useSchema();\n  if (!ALLOWED_COLLECTION_TYPES.includes(typeInfo.name)) {\n    throw new PathError(\n      inputController.getState().path,\n      \"Unsupported schema: Expected schema representing (possibly nullable) \" +\n        \"listable values, but got schema representing values of type \" +\n        `'${typeInfo.toString()}'.`,\n    );\n  }\n\n  return inputController;\n}\n","import {\n  BigDecimal,\n  BigInteger,\n  Char,\n  charToCode,\n  codeToChar,\n  Long,\n  Schema,\n  stringToBigDecimal,\n  stringToBigInteger,\n  stringToLong,\n} from \"@kform/core\";\nimport fromExponential from \"from-exponential\";\n\n// Min/max numeric representations for a `Char`\nconst CHAR_MIN_NUMBER = 0x0000;\nconst CHAR_MAX_NUMBER = 0xffff;\n\n/**\n * Minimum Kotlin `Byte` value.\n */\nexport const BYTE_MIN_VALUE = -128;\n/**\n * Maximum Kotlin `Byte` value.\n */\nexport const BYTE_MAX_VALUE = 127;\n/**\n * Minimum Kotlin {@link Char} value.\n */\nexport const CHAR_MIN_VALUE: Char = codeToChar(CHAR_MIN_NUMBER);\n/**\n * Maximum Kotlin {@link Char} value.\n */\nexport const CHAR_MAX_VALUE: Char = codeToChar(CHAR_MAX_NUMBER);\n/**\n * Minimum Kotlin `Short` value.\n */\nexport const SHORT_MIN_VALUE = -32768;\n/**\n * Maximum Kotlin `Short` value.\n */\nexport const SHORT_MAX_VALUE = 32767;\n/**\n * Minimum Kotlin `Int` value.\n */\nexport const INT_MIN_VALUE = -2147483648;\n/**\n * Maximum Kotlin `Int` value.\n */\nexport const INT_MAX_VALUE = 2147483647;\n/**\n * Minimum Kotlin {@link Long} value.\n */\nexport const LONG_MIN_VALUE: Long = stringToLong(\"-9223372036854775808\");\n/**\n * Maximum Kotlin {@link Long} value.\n */\nexport const LONG_MAX_VALUE: Long = stringToLong(\"9223372036854775807\");\n\n// Representations of the number `0` as `Char`/`Long`/`BigInteger`/`BigDecimal`\nconst CHAR_ZERO: Char = CHAR_MIN_VALUE;\nconst LONG_ZERO: Long = stringToLong(\"0\");\nconst BIG_INTEGER_ZERO = stringToBigInteger(\"0\");\nconst BIG_DECIMAL_ZERO = stringToBigDecimal(\"0\");\n\n/**\n * Supported numeric types.\n */\nexport type Numeric = number | Char | Long | BigInteger | BigDecimal | string;\n\n/**\n * Formats a numeric {@link value} as a string, given its {@link schema}.\n * @param value Numeric value to format as a string.\n * @param schema Schema of the numeric {@link value}.\n * @returns String representation of the numeric {@link value}.\n */\nexport function formatNumericAsString<\n  T extends Numeric | null = Numeric | null,\n>(value: T | undefined, schema: Schema<T>): string {\n  if (value == null) {\n    return \"\";\n  }\n  const schemaType = schema.typeInfo.name;\n  switch (schemaType) {\n    case \"Char\":\n      return charToCode(value as Char).toString();\n    case \"Float\":\n    case \"Double\":\n      // Convert exponential representation of numbers into their\n      // non-exponential counterpart, e.g. `1.123e-10` -> `0.0000000001123`\n      return Number.isNaN(value as number)\n        ? \"\"\n        : fromExponential(value as number);\n    case \"String\":\n      return value === \"\" || Number.isNaN(Number(value as string))\n        ? \"\"\n        : fromExponential(value as string);\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Parses a formatted numeric [value]{@link formattedValue} as a numeric value,\n * given the {@link schema} of the expected numeric value.\n * @param formattedValue Formatted value to parse as a numeric value.\n * @param schema Schema of the expected numeric value.\n * @returns Numeric representation of the\n * [formatted value]{@link formattedValue} according to {@link schema}.\n */\nexport function parseStringAsNumeric<T extends Numeric | null = Numeric | null>(\n  formattedValue: string,\n  schema: Schema<T>,\n): T {\n  const supportsNull = schema.typeInfo.nullable;\n  const schemaType = schema.typeInfo.name;\n  if (\n    formattedValue === \"\" ||\n    formattedValue === \"-\" ||\n    formattedValue === \".\" ||\n    formattedValue === \"-.\"\n  ) {\n    return (\n      supportsNull\n        ? null\n        : schemaType === \"Char\"\n          ? CHAR_ZERO\n          : schemaType === \"Long\"\n            ? LONG_ZERO\n            : schemaType === \"String\"\n              ? \"\"\n              : 0\n    ) as T;\n  }\n\n  switch (schemaType) {\n    case \"Byte\":\n    case \"Short\":\n    case \"Int\": {\n      const { min, max } = numericTypeMinMax(schema as Schema<number>);\n      // Int types do not support `NaN`, so we convert it to `null` or `0`\n      const value = parseInt(formattedValue);\n      return (\n        Number.isNaN(value)\n          ? supportsNull\n            ? null\n            : 0\n          : Math.min(Math.max(value, min!), max!)\n      ) as T;\n    }\n    case \"Char\": {\n      // Chars do not support `NaN`, so we convert it to `null` or `0`\n      const value = parseInt(formattedValue);\n      return (\n        Number.isNaN(value)\n          ? supportsNull\n            ? null\n            : CHAR_ZERO\n          : codeToChar(\n              Math.min(Math.max(value, CHAR_MIN_NUMBER), CHAR_MAX_NUMBER),\n            )\n      ) as T;\n    }\n    case \"Long\": {\n      // Longs do not support `NaN`, so we return `null` or `0`\n      const value = parseIntString(formattedValue);\n      if (value === null) {\n        return (supportsNull ? null : LONG_ZERO) as T;\n      }\n\n      const isNegative = value.startsWith(\"-\");\n      try {\n        // This may throw in case of under/overflow, in which case we default to\n        // the min/max values\n        return stringToLong(value) as T;\n      } catch {\n        return (isNegative ? LONG_MIN_VALUE : LONG_MAX_VALUE) as T;\n      }\n    }\n    case \"BigInteger\": {\n      const value = parseIntString(formattedValue);\n      if (value === null) {\n        return (supportsNull ? null : BIG_INTEGER_ZERO) as T;\n      }\n      return stringToBigInteger(value) as T;\n    }\n    case \"BigDecimal\": {\n      const preferredScale =\n        (schema.typeInfo.restrictions.scale as number | undefined) ?? null;\n      let bigDecimal: BigDecimal | null;\n      try {\n        bigDecimal = stringToBigDecimal(formattedValue);\n      } catch {\n        bigDecimal = supportsNull ? null : BIG_DECIMAL_ZERO;\n      }\n      return (\n        bigDecimal === null ||\n        preferredScale === null ||\n        bigDecimal.scale >= preferredScale\n          ? bigDecimal\n          : bigDecimal.setScale(preferredScale)\n      ) as T;\n    }\n    case \"Float\":\n    case \"Double\":\n      // Floats support `NaN`, so no need to check for that\n      return parseFloat(formattedValue) as T;\n    default:\n      return formattedValue as T;\n  }\n}\n\n/**\n * Returns the minimum and maximum numeric values supported by the given numeric\n * {@link schema}, or `undefined` if there are no such limits.\n * @param schema Numeric schema for which to get mininum/maximum values.\n * @returns Minimum/maximum supported numeric value of {@link schema}.\n */\nexport function numericTypeMinMax<T extends Numeric | null = Numeric | null>(\n  schema: Schema<T>,\n): {\n  min: NonNullable<T> | undefined;\n  max: NonNullable<T> | undefined;\n} {\n  switch (schema.typeInfo.name) {\n    case \"Byte\":\n      return {\n        min: BYTE_MIN_VALUE as NonNullable<T>,\n        max: BYTE_MAX_VALUE as NonNullable<T>,\n      };\n    case \"Char\":\n      return {\n        min: CHAR_MIN_VALUE as unknown as NonNullable<T>,\n        max: CHAR_MAX_VALUE as unknown as NonNullable<T>,\n      };\n    case \"Short\":\n      return {\n        min: SHORT_MIN_VALUE as NonNullable<T>,\n        max: SHORT_MAX_VALUE as NonNullable<T>,\n      };\n    case \"Int\":\n      return {\n        min: INT_MIN_VALUE as NonNullable<T>,\n        max: INT_MAX_VALUE as NonNullable<T>,\n      };\n    case \"Long\":\n      return {\n        min: LONG_MIN_VALUE as unknown as NonNullable<T>,\n        max: LONG_MAX_VALUE as unknown as NonNullable<T>,\n      };\n    default:\n      return { min: undefined, max: undefined };\n  }\n}\n\n/**\n * Parses a string representing an integer by removing leading zeroes and\n * stopping when a non-digit is found.\n */\nfunction parseIntString(str: string): string | null {\n  const len = str.length;\n  const isNegative = str.startsWith(\"-\");\n  // Ignore leading zeroes\n  let start = isNegative ? 1 : 0;\n  while (\n    start < len - 1 &&\n    str[start] === \"0\" &&\n    str[start + 1] >= \"0\" &&\n    str[start + 1] <= \"9\"\n  ) {\n    ++start;\n  }\n  // Ignore non-digits\n  let end = len;\n  for (let i = start; i < len; ++i) {\n    if (str[i] < \"0\" || str[i] > \"9\") {\n      end = i;\n      break;\n    }\n  }\n  if (start === end) {\n    return null;\n  }\n  const normalized = str.slice(start, end);\n  return isNegative && normalized !== \"0\" ? `-${normalized}` : normalized;\n}\n","import { Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { PathError } from \"../utils/errors\";\nimport {\n  formatNumericAsString,\n  Numeric,\n  parseStringAsNumeric,\n} from \"../utils/numericUtils\";\nimport { DistributedOmit } from \"../utils/typeUtils\";\nimport { useLatestValues } from \"../utils/useLatestValues\";\nimport { Controller } from \"./useController\";\nimport { FormatterControllerState } from \"./useFormatter\";\nimport { InputOptions, InputOwnController, useInput } from \"./useInput\";\n\n/**\n * Options available to the {@link useNumericInput} hook.\n */\nexport type NumericInputOptions<\n  T extends Numeric | null = Numeric | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n> = DistributedOmit<InputOptions<T, TFormatted, TInput>, \"format\" | \"parse\"> &\n  NumericInputOwnOptions<T, TFormatted, TInput>;\n\n/**\n * Own options available to the {@link useNumericInput} hook.\n */\nexport interface NumericInputOwnOptions<\n  T extends Numeric | null = Numeric | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n> {\n  formatFromString?: (\n    stringValue: string,\n    state: FormatterControllerState<T, TFormatted>,\n    input: TInput | null,\n  ) => TFormatted;\n  parseToString?: (\n    formattedValue: TFormatted,\n    state: FormatterControllerState<T, TFormatted>,\n    input: TInput | null,\n  ) => string;\n}\n\n/**\n * Controller used to read and control the form value associated with the\n * form input, exposing properties that should be set on the input itself.\n */\nexport type NumericInputController<\n  T extends Numeric | null = Numeric | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n> = Controller<T> & NumericInputOwnController<TFormatted, TInput>;\n\n/**\n * Own numeric input controller.\n */\nexport type NumericInputOwnController<\n  TFormatted = string,\n  TInput = HTMLInputElement,\n> = InputOwnController<TFormatted, TInput>;\n\n/**\n * Allowed Kotlin numeric types.\n */\nconst ALLOWED_NUMERIC_TYPES = [\n  \"Byte\",\n  \"Char\",\n  \"Short\",\n  \"Int\",\n  \"Long\",\n  \"Float\",\n  \"Double\",\n  \"BigInteger\",\n  \"BigDecimal\",\n  // Not exactly a numeric type, but it is sometimes useful to treat strings\n  // with numeric patterns as \"numeric\"\n  \"String\",\n];\n\n/**\n * Hook controlling the integration between a numeric value of the form manager\n * and an input of the form.\n * @param path Path of the numeric form value to access, relative to the current\n * path.\n * @param options Available options.\n * @throws {PathError} When the value at {@link path} is not numeric.\n * @returns A controller used to read and control the numeric form value\n * associated with the form input, exposing properties that should be set on the\n * input itself.\n */\nexport function useNumericInput<\n  T extends Numeric | null = Numeric | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n>(\n  path?: Path | string,\n  options?: undefined,\n): NumericInputController<T, TFormatted, TInput>;\nexport function useNumericInput<\n  T extends Numeric | null = Numeric | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n>(\n  path: Path | string | undefined,\n  options: NumericInputOptions<T, TFormatted, TInput>,\n): NumericInputController<T, TFormatted, TInput>;\nexport function useNumericInput<\n  T extends Numeric | null = Numeric | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n>(\n  path: Path | string = Path.CURRENT,\n  {\n    formatFromString,\n    parseToString,\n    ...options\n  }: NumericInputOptions<T, TFormatted, TInput> = {},\n): NumericInputController<T, TFormatted, TInput> {\n  const latestOptions = useLatestValues({ parseToString });\n\n  // Input options\n  const format = React.useCallback(\n    (\n      value: T | undefined,\n      state: FormatterControllerState<T, TFormatted>,\n      input: TInput | null,\n    ): TFormatted => {\n      const numberString = formatNumericAsString(value, state.schema);\n      return formatFromString\n        ? formatFromString(numberString, state, input)\n        : (numberString as TFormatted);\n    },\n    [formatFromString],\n  );\n  const parse = React.useCallback(\n    (\n      formattedValue: TFormatted,\n      state: FormatterControllerState<T, TFormatted>,\n      input: TInput | null,\n    ): T => {\n      return parseStringAsNumeric(\n        latestOptions.parseToString\n          ? latestOptions.parseToString(formattedValue, state, input)\n          : String(formattedValue ?? \"\"),\n        state.schema,\n      );\n    },\n    [latestOptions],\n  );\n\n  const inputController = useInput<T, TFormatted, TInput>(path, {\n    format,\n    parse,\n    ...options,\n  });\n\n  // Validate schema type\n  const { typeInfo } = inputController.useSchema();\n  if (!ALLOWED_NUMERIC_TYPES.includes(typeInfo.name)) {\n    throw new PathError(\n      inputController.getState().path,\n      \"Unsupported schema: Expected schema representing (possibly nullable) \" +\n        \"numeric values, but got schema representing values of type \" +\n        `'${typeInfo.toString()}'.`,\n    );\n  }\n\n  return inputController;\n}\n","import { useFormController } from \"./useFormController\";\n\n/**\n * Hook providing access to the \"submitting\" status of a form in context.\n * @throws {NoFormContextError} When no form is in context.\n * @returns Whether the form in context is being submitted.\n */\nexport function useSubmitting(): boolean {\n  return useFormController().useSubmitting();\n}\n","import {\n  AbsolutePath,\n  CancellablePromise,\n  FormManager,\n  Path,\n  SealedFormManagerEvent,\n} from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { ignorePromiseCancellationException } from \"../utils/ignorePromiseCancellationException\";\nimport { useLatestValues } from \"../utils/useLatestValues\";\nimport { useFormManager } from \"./useFormManager\";\nimport { useResolvedPath } from \"./useResolvedPath\";\n\n/**\n * Options available to the {@link useSubscription} hook.\n */\nexport interface SubscriptionOptions {\n  /**\n   * Required if no form context is in scope.\n   *\n   * If a form context is in scope and this value is also provided, then the\n   * provided form manager will be used, in which case the current path of the\n   * form context is ignored.\n   */\n  formManager?: FormManager;\n  /**\n   * Function called after the subscription completes, but before any event is\n   * emitted.\n   */\n  onSubscribe?: () => void | PromiseLike<void>;\n  /**\n   * Function called after unsubscribing.\n   */\n  onUnsubscribe?: () => void;\n  /**\n   * Whether to enable the subscription.\n   * @default true\n   */\n  enabled?: boolean;\n}\n\n/**\n * Hook that subscribes to all form manager events with paths matching\n * {@link path} by running {@link onFormManagerEvent} for each event.\n *\n * Changes to {@link onFormManagerEvent}, {@link onSubscribe}, or\n * {@link onUnsubscribe} do not cause new subscriptions to be performed.\n * @param path Path of events to subscribe to.\n * @param onFormManagerEvent Function called for each event with a path matching\n * {@link path}.\n * @param subscriptionOptions Available options.\n */\nexport function useSubscription<T = unknown, TChildren = unknown>(\n  path: Path | string = Path.CURRENT,\n  onFormManagerEvent: (\n    event: SealedFormManagerEvent<T, TChildren>,\n  ) => void | PromiseLike<void>,\n  {\n    formManager: formManagerOption,\n    onSubscribe,\n    onUnsubscribe,\n    enabled = true,\n  }: SubscriptionOptions = {},\n): void {\n  const formManager = useFormManager(formManagerOption);\n  const absolutePath = useResolvedPath(\n    path,\n    formManagerOption != null ? AbsolutePath.ROOT : undefined,\n  );\n\n  // Store listeners in a stable identity object since we don't want to\n  // re-subscribe whenever they change\n  const listeners = useLatestValues({\n    onFormManagerEvent,\n    onSubscribe,\n    onUnsubscribe,\n  });\n\n  React.useEffect(() => {\n    if (!enabled) {\n      return;\n    }\n\n    let cleanedUp = false;\n    let unsubscribe: (() => CancellablePromise<void>) | undefined = undefined;\n    const subscriptionPromise = formManager\n      .subscribe<T, TChildren>(\n        absolutePath,\n        (event) => {\n          // Unsubscribing is asynchronous, so it's possible that an event is\n          // emitted after cleaning up, but before unsubscribing, which we\n          // should ignore\n          if (!cleanedUp) {\n            return listeners.onFormManagerEvent(event);\n          }\n        },\n        listeners.onSubscribe,\n      )\n      .then((fn) => (unsubscribe = fn))\n      .catch(ignorePromiseCancellationException);\n\n    return () => {\n      cleanedUp = true;\n      subscriptionPromise.cancel(\n        `Clean up 'useEffect' subscription to '${absolutePath.toString()}'.`,\n      );\n      void unsubscribe?.().then(() => listeners.onUnsubscribe?.());\n    };\n  }, [absolutePath, enabled, formManager, listeners]);\n}\n","import {\n  Instant,\n  LocalDate,\n  LocalDateTime,\n  Schema,\n  stringToInstant,\n  stringToLocalDate,\n  stringToLocalDateTime,\n} from \"@kform/core\";\n\n// Default temporal values (UNIX Epoch `0`)\nconst DEFAULT_INSTANT = stringToInstant(\"1970-01-01T00:00:00Z\");\nconst DEFAULT_LOCAL_DATE = stringToLocalDate(\"1970-01-01\");\nconst DEFAULT_LOCAL_DATE_TIME = stringToLocalDateTime(\"1970-01-01T00:00:00\");\n\n/**\n * Supported date or time related types.\n */\nexport type Temporal = Instant | LocalDate | LocalDateTime | Date;\n\n/**\n * Formats a temporal {@link value} as a string, given its {@link schema}.\n * @param value Temporal value to format as a string.\n * @param schema Schema of the temporal {@link value}.\n * @returns String representation of the temporal {@link value}.\n */\nexport function formatTemporalAsString<\n  T extends Temporal | null = Temporal | null,\n  // Not using the `schema` is an implementation detail\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n>(value: T | undefined, schema: Schema<T>): string {\n  return isJsDate(value)\n    ? Number.isNaN(+value)\n      ? \"\"\n      : value.toISOString()\n    : (value?.toString() ?? \"\");\n}\n\n/**\n * Parses a formatted temporal [value]{@link formattedValue} as a temporal\n * value, given the {@link schema} of the expected temporal value.\n * @param formattedValue Formatted value to parse as a temporal value.\n * @param schema Schema of the expected temporal value.\n * @returns Temporal representation of the\n * [formatted value]{@link formattedValue} according to {@link schema}.\n */\nexport function parseStringAsTemporal<\n  T extends Temporal | null = Temporal | null,\n>(formattedValue: string, schema: Schema<T>): T {\n  if (formattedValue === \"\" && schema.typeInfo.nullable) {\n    return null as T;\n  }\n\n  switch (schema.typeInfo.name) {\n    case \"Instant\":\n      if (formattedValue === \"\") {\n        return DEFAULT_INSTANT as T;\n      }\n      try {\n        return stringToInstant(formattedValue) as T;\n      } catch {\n        return (schema.typeInfo.nullable ? null : DEFAULT_INSTANT) as T;\n      }\n    case \"LocalDate\":\n      if (formattedValue === \"\") {\n        return DEFAULT_LOCAL_DATE as T;\n      }\n      try {\n        return stringToLocalDate(formattedValue) as T;\n      } catch {\n        return (schema.typeInfo.nullable ? null : DEFAULT_LOCAL_DATE) as T;\n      }\n    case \"LocalDateTime\":\n      if (formattedValue === \"\") {\n        return DEFAULT_LOCAL_DATE_TIME as T;\n      }\n      try {\n        return stringToLocalDateTime(formattedValue) as T;\n      } catch {\n        return (schema.typeInfo.nullable ? null : DEFAULT_LOCAL_DATE_TIME) as T;\n      }\n    default: // JavaScript `Date`\n      return new Date(formattedValue) as T;\n  }\n}\n\n/**\n * Whether the value is a JavaScript {@link Date}.\n */\nfunction isJsDate(value: unknown): value is Date {\n  return (\n    value instanceof Date ||\n    (typeof value === \"object\" &&\n      Object.prototype.toString.call(value) === \"[object Date]\")\n  );\n}\n","import { Path } from \"@kform/core\";\nimport * as React from \"react\";\n\nimport { PathError } from \"../utils/errors\";\nimport {\n  formatTemporalAsString,\n  parseStringAsTemporal,\n  Temporal,\n} from \"../utils/temporalUtils\";\nimport { useLatestValues } from \"../utils/useLatestValues\";\nimport { Controller } from \"./useController\";\nimport { FormatterControllerState } from \"./useFormatter\";\nimport { InputOptions, InputOwnController, useInput } from \"./useInput\";\n\n/**\n * Options available to the {@link useTemporalInput} hook.\n */\nexport type TemporalInputOptions<\n  T extends Temporal | null = Temporal | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n> = Omit<InputOptions<T, TFormatted, TInput>, \"format\" | \"parse\"> &\n  TemporalInputOwnOptions<T, TFormatted, TInput>;\n\n/**\n * Own options available to the {@link useTemporalInput} hook.\n */\nexport interface TemporalInputOwnOptions<\n  T extends Temporal | null = Temporal | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n> {\n  formatFromString?: (\n    stringValue: string,\n    state: FormatterControllerState<T, TFormatted>,\n    input: TInput | null,\n  ) => TFormatted;\n  parseToString?: (\n    formattedValue: TFormatted,\n    state: FormatterControllerState<T, TFormatted>,\n    input: TInput | null,\n  ) => string;\n}\n\n/**\n * Controller used to read and control the form value associated with the form\n * input, exposing properties that should be set on the input itself.\n */\nexport type TemporalInputController<\n  T extends Temporal | null = Temporal | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n> = Controller<T> & TemporalInputOwnController<TFormatted, TInput>;\n\n/**\n * Own temporal input controller.\n */\nexport type TemporalInputOwnController<\n  TFormatted = string,\n  TInput = HTMLInputElement,\n> = InputOwnController<TFormatted, TInput>;\n\n/**\n * Allowed temporal types.\n */\nconst ALLOWED_TEMPORAL_TYPES = [\n  \"Instant\",\n  \"LocalDate\",\n  \"LocalDateTime\",\n  \"Date\",\n];\n\n/**\n * Hook controlling the integration between a temporal value (`Instant`,\n * `LocalDate`, `LocalDateTime`, or `Date`) of the form manager and an input of\n * the form.\n * @param path Path of the temporal form value to access, relative to the\n * current path.\n * @param options Available options.\n * @throws {PathError} When the value at {@link path} is not temporal (not an\n * `Instant`, `LocalDate`, `LocalDateTime`, or `Date`).\n * @returns A controller used to read and control the temporal form value\n * associated with the form input, exposing properties that should be set on the\n * input itself.\n */\nexport function useTemporalInput<\n  T extends Temporal | null = Temporal | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n>(\n  path?: Path | string,\n  options?: undefined,\n): TemporalInputController<T, TFormatted, TInput>;\nexport function useTemporalInput<\n  T extends Temporal | null = Temporal | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n>(\n  path: Path | string | undefined,\n  options: TemporalInputOptions<T, TFormatted, TInput>,\n): TemporalInputController<T, TFormatted, TInput>;\nexport function useTemporalInput<\n  T extends Temporal | null = Temporal | null,\n  TFormatted = string,\n  TInput = HTMLInputElement,\n>(\n  path: Path | string = Path.CURRENT,\n  {\n    formatFromString,\n    parseToString,\n    ...options\n  }: TemporalInputOptions<T, TFormatted, TInput> = {},\n): TemporalInputController<T, TFormatted, TInput> {\n  const latestOptions = useLatestValues({ parseToString });\n\n  // Input options\n  const format = React.useCallback(\n    (\n      value: T | undefined,\n      state: FormatterControllerState<T, TFormatted>,\n      input: TInput | null,\n    ): TFormatted => {\n      const temporalString = formatTemporalAsString(value, state.schema);\n      return formatFromString\n        ? formatFromString(temporalString, state, input)\n        : (temporalString as TFormatted);\n    },\n    [formatFromString],\n  );\n  const parse = React.useCallback(\n    (\n      formattedValue: TFormatted,\n      state: FormatterControllerState<T, TFormatted>,\n      input: TInput | null,\n    ): T => {\n      return parseStringAsTemporal(\n        latestOptions.parseToString\n          ? latestOptions.parseToString(formattedValue, state, input)\n          : String(formattedValue ?? \"\"),\n        state.schema,\n      );\n    },\n    [latestOptions],\n  );\n\n  const inputController = useInput(path, { format, parse, ...options });\n\n  // Validate schema type\n  const { typeInfo } = inputController.useSchema();\n  if (!ALLOWED_TEMPORAL_TYPES.includes(typeInfo.name)) {\n    throw new PathError(\n      inputController.getState().path,\n      \"Unsupported schema: Expected schema representing (possibly nullable) \" +\n        \"temporal values, but got schema representing values of type \" +\n        `'${typeInfo.toString()}'.`,\n    );\n  }\n\n  return inputController;\n}\n","import { setLogLevel } from \"@kform/core\";\n\ndeclare global {\n  /**\n   * Sets the logging level associated with KForm's form managers.\n   *\n   * This global function is only available in non-production environments.\n   * Import {@link setLogLevel} from `@kform/core` directly otherwise.\n   */\n  // eslint-disable-next-line no-var\n  var setKFormLogLevel: typeof setLogLevel | undefined;\n}\n\n// When not in production, expose a way of changing KForm's log level from the\n// browser dev tools\nif (process.env.NODE_ENV !== \"production\") {\n  globalThis.setKFormLogLevel ??= setLogLevel;\n}\n"],"names":["React","Path","PromiseCancellationException","AbsolutePath","AbsolutePathFragment","createStore","subscribeWithSelector","useStore","shallow","formManager","valuePath","path","ValueEvent","_a","StateEvent","FormManager","onSubmit","onInvalidSubmit","onSuccessfulSubmit","onFailedSubmit","setTouchedOnSubmit","validateOnSubmit","setPristineOnSuccessfulSubmit","convertExternalIssuesTableRowIndicesToIds","schema","convertIssuesTableRowIndicesToIds","listableToArray","isLocatedValidationIssueKt","locatedValidationIssueKtToJs","options","isList","listableSize","sliceList","LocatedValidationIssue","Form","jsx","formattedValue","state","isComputedSchema","kFormFileToJsFile","emptyPlaceholderKFormFile","jsFileToKFormFile","compareSchemaPaths","arrayToList","arrayToTable","codeToChar","stringToLong","stringToBigInteger","stringToBigDecimal","charToCode","stringToInstant","stringToLocalDate","stringToLocalDateTime","setLogLevel"],"mappings":"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"}