{"version":3,"sources":["../src/index.ts","../src/LensCore.ts","../src/LensesStorage.ts","../src/useLens.ts"],"sourcesContent":["export * from './LensCore';\nexport * from './LensesStorage';\nexport type * from './types';\nexport * from './useLens';\n","import { type Control, type FieldValues, get, set } from 'react-hook-form';\n\nimport type { LensesStorage } from './LensesStorage';\nimport type { Lens } from './types';\n\nexport interface LensCoreInteropBinding<T extends FieldValues> {\n  control: Control<T>;\n  name: string | undefined;\n  getTransformer?: (value: unknown) => unknown;\n  setTransformer?: (value: unknown) => unknown;\n}\n\n/**\n * Runtime lens implementation.\n */\nexport class LensCore<T extends FieldValues> {\n  public control: Control<T>;\n  public path: string;\n  public cache?: LensesStorage<T> | undefined;\n\n  private isArrayItemReflection?: boolean;\n  private override?: Record<string, LensCore<T>> | [Record<string, LensCore<T>>];\n  private interopCache?: LensCoreInteropBinding<T>;\n\n  constructor(control: Control<T>, path: string, cache?: LensesStorage<T> | undefined) {\n    this.control = control;\n    this.path = path;\n    this.cache = cache;\n  }\n\n  public static create<TFieldValues extends FieldValues = FieldValues>(\n    control: Control<TFieldValues>,\n    cache?: LensesStorage<TFieldValues>,\n  ): Lens<TFieldValues> {\n    return new LensCore(control, '', cache) as unknown as Lens<TFieldValues>;\n  }\n\n  public focus(prop: string | number): LensCore<T> {\n    const propString = prop.toString();\n    const nestedPath = this.path ? `${this.path}.${propString}` : propString;\n\n    const fromCache = this.cache?.get(nestedPath);\n\n    if (fromCache) {\n      return fromCache;\n    }\n\n    if (Array.isArray(this.override)) {\n      const [template] = this.override;\n      const result = new LensCore(this.control, nestedPath, this.cache);\n      result.isArrayItemReflection = true;\n      result.override = template;\n\n      this.cache?.set(result, nestedPath);\n\n      return result;\n    } else if (this.override) {\n      const overriddenLens: LensCore<T> | undefined = get(this.override, propString);\n\n      if (!overriddenLens) {\n        const result = new LensCore(this.control, nestedPath, this.cache);\n        this.cache?.set(result, nestedPath);\n        return result;\n      }\n\n      if (this.isArrayItemReflection) {\n        const arrayItemNestedPath = `${this.path}.${overriddenLens.path}`;\n        const result = new LensCore(this.control, arrayItemNestedPath, this.cache);\n        this.cache?.set(result, arrayItemNestedPath);\n        return result;\n      } else {\n        this.cache?.set(overriddenLens, nestedPath);\n        return overriddenLens;\n      }\n    }\n\n    const result = new LensCore(this.control, nestedPath, this.cache);\n    this.cache?.set(result, nestedPath);\n    return result;\n  }\n\n  public reflect(\n    getter: (\n      dictionary: ProxyHandler<Record<string, LensCore<T>>>,\n      lens: LensCore<T>,\n    ) => Record<string, LensCore<T>> | [Record<string, LensCore<T>>],\n  ): LensCore<T> {\n    const fromCache = this.cache?.get(this.path, getter);\n\n    if (fromCache) {\n      return fromCache;\n    }\n\n    const template = new LensCore(this.control, this.path, this.cache);\n\n    const dictionary = new Proxy(\n      {},\n      {\n        get: (target, prop) => {\n          if (typeof prop === 'string') {\n            return template.focus(prop);\n          }\n\n          return target;\n        },\n      },\n    );\n\n    const override = getter(dictionary, template);\n\n    if (Array.isArray(override)) {\n      const result = new LensCore(this.control, this.path, this.cache);\n      template.path = '';\n      result.override = getter(dictionary, template);\n      this.cache?.set(result, this.path, getter);\n      return result;\n    } else {\n      template.override = override;\n      template.path = this.path;\n      this.cache?.set(template, this.path, getter);\n      return template;\n    }\n  }\n\n  public map<R>(\n    fields: Record<string, any>[],\n    mapper: (value: unknown, item: LensCore<T>, index: number, array: unknown[], lens: this) => R,\n  ): R[] {\n    return fields.map((value, index, array) => {\n      const item = this.focus(index.toString());\n      const res = mapper(value, item, index, array, this);\n      return res;\n    });\n  }\n\n  public interop(cb?: (control: Control<T>, name: string | undefined) => any): LensCoreInteropBinding<T> | undefined {\n    if (cb) {\n      return cb(this.control, this.path);\n    }\n\n    this.interopCache ??= {\n      control: this.control,\n      name: this.path,\n      ...(this.override ? { getTransformer: this.getTransformer.bind(this), setTransformer: this.setTransformer.bind(this) } : {}),\n    };\n\n    return this.interopCache;\n  }\n\n  private getTransformer(value: unknown): unknown {\n    const [template] = Array.isArray(this.override) ? this.override : [this.override];\n\n    if (!value || !template) {\n      return value;\n    }\n\n    const newValue = {} as typeof value;\n\n    Object.entries(template).forEach(([key, valueTemplate]) => {\n      const restructuredLens = valueTemplate;\n\n      if (!restructuredLens) {\n        return;\n      }\n\n      const v = get(value, restructuredLens.path);\n      set(newValue, key, v);\n    });\n\n    return newValue;\n  }\n\n  private setTransformer(value: unknown): unknown {\n    const [template] = Array.isArray(this.override) ? this.override : [this.override];\n\n    if (!value || !template) {\n      return value;\n    }\n\n    const newValue = {} as typeof value;\n\n    Object.entries(value).forEach(([key, value]) => {\n      const restructuredLens = template[key];\n\n      if (!restructuredLens) {\n        return;\n      }\n\n      set(newValue, restructuredLens.path, value);\n    });\n\n    return newValue;\n  }\n}\n","import type { Control, FieldValues } from 'react-hook-form';\n\nimport type { LensCore } from './LensCore';\n\nexport type LensesStorageComplexKey = (...args: any[]) => any;\n\nexport interface LensesStorageValue<T extends FieldValues> {\n  plain?: LensCore<T>;\n  complex: WeakMap<LensesStorageComplexKey, LensCore<T>>;\n}\n\nexport type LensCache<T extends FieldValues> = Map<string, LensesStorageValue<T>>;\n\n/**\n * Cache storage for lenses.\n */\nexport class LensesStorage<T extends FieldValues> {\n  private cache: LensCache<T>;\n\n  constructor(control: Control<T>) {\n    this.cache = new Map();\n\n    control?._subjects?.values?.subscribe?.({\n      next: () => {\n        control._names.unMount.forEach((name) => {\n          this.delete(name);\n        });\n      },\n    });\n  }\n\n  public get(path: string, complexKey?: LensesStorageComplexKey): LensCore<T> | undefined {\n    const cached = this.cache.get(path);\n\n    if (cached) {\n      if (complexKey) {\n        return cached.complex.get(complexKey);\n      }\n\n      return cached.plain;\n    }\n\n    return undefined;\n  }\n\n  public set(lens: LensCore<T>, path: string, complexKey?: LensesStorageComplexKey): void {\n    let cached = this.cache.get(path);\n\n    if (!cached) {\n      cached = {\n        complex: new WeakMap(),\n      };\n\n      this.cache.set(path, cached);\n    }\n\n    if (complexKey) {\n      cached.complex.set(complexKey, lens);\n    } else {\n      cached.plain = lens;\n    }\n  }\n\n  public has(path: string, complexKey?: LensesStorageComplexKey): boolean {\n    if (complexKey) {\n      return this.cache.get(path)?.complex.has(complexKey) ?? false;\n    }\n\n    return this.cache.has(path);\n  }\n\n  public delete(path: string): void {\n    for (const key of this.cache.keys()) {\n      if (key.startsWith(path)) {\n        this.cache.delete(key);\n      }\n    }\n  }\n\n  public clear(): void {\n    this.cache.clear();\n  }\n}\n","import { type DependencyList, useMemo } from 'react';\nimport type { Control, FieldValues } from 'react-hook-form';\n\nimport { LensCore } from './LensCore';\nimport { LensesStorage } from './LensesStorage';\nimport type { Lens } from './types';\n\nexport interface UseLensProps<TFieldValues extends FieldValues = FieldValues> {\n  control: Control<TFieldValues>;\n}\n\n/**\n * Creates lens from react-hook-form control.\n *\n * @example\n * ```tsx\n * function App() {\n *   const { control } = useForm<{\n *     firstName: string;\n *   }>();\n *\n *   const lens = useLens({ control });\n * }\n * ```\n */\nexport function useLens<TFieldValues extends FieldValues = FieldValues>(\n  props: UseLensProps<TFieldValues>,\n  deps: DependencyList = [],\n): Lens<TFieldValues> {\n  return useMemo(() => {\n    const cache = new LensesStorage(props.control);\n    const lens = LensCore.create<TFieldValues>(props.control, cache);\n\n    return lens;\n  }, [props.control, ...deps]);\n}\n"],"mappings":"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","names":["result","value"]}