{"version":3,"file":"tanstack-angular-virtual.mjs","sources":["../../src/proxy.ts","../../src/index.ts","../../src/tanstack-angular-virtual.ts"],"sourcesContent":["import { computed, untracked } from '@angular/core'\nimport type { Signal, WritableSignal } from '@angular/core'\nimport type { Virtualizer } from '@tanstack/virtual-core'\nimport type { AngularVirtualizer } from './types'\n\nexport function proxyVirtualizer<\n  V extends Virtualizer<any, any>,\n  S extends Element | Window = V extends Virtualizer<infer U, any> ? U : never,\n  I extends Element = V extends Virtualizer<any, infer U> ? U : never,\n>(\n  virtualizerSignal: WritableSignal<V>,\n  lazyInit: () => V,\n): AngularVirtualizer<S, I> {\n  return new Proxy(virtualizerSignal, {\n    apply() {\n      return virtualizerSignal()\n    },\n    get(target, property) {\n      const untypedTarget = target as any\n      if (untypedTarget[property]) {\n        return untypedTarget[property]\n      }\n      let virtualizer = untracked(virtualizerSignal)\n      if (virtualizer == null) {\n        virtualizer = lazyInit()\n        untracked(() => virtualizerSignal.set(virtualizer))\n      }\n\n      // Create computed signals for each property that represents a reactive value\n      if (\n        typeof property === 'string' &&\n        [\n          'getTotalSize',\n          'getVirtualItems',\n          'isScrolling',\n          'options',\n          'range',\n          'scrollDirection',\n          'scrollElement',\n          'scrollOffset',\n          'scrollRect',\n          'measureElementCache',\n          'measurementsCache',\n        ].includes(property)\n      ) {\n        const isFunction =\n          typeof virtualizer[property as keyof V] === 'function'\n        Object.defineProperty(untypedTarget, property, {\n          value: isFunction\n            ? computed(() => (target()[property as keyof V] as Function)())\n            : computed(() => target()[property as keyof V]),\n          configurable: true,\n          enumerable: true,\n        })\n      }\n\n      // Create plain signals for functions that accept arguments and return reactive values\n      if (\n        typeof property === 'string' &&\n        [\n          'getOffsetForAlignment',\n          'getOffsetForIndex',\n          'getVirtualItemForOffset',\n          'indexFromElement',\n        ].includes(property)\n      ) {\n        const fn = virtualizer[property as keyof V] as Function\n        Object.defineProperty(untypedTarget, property, {\n          value: toComputed(virtualizerSignal, fn),\n          configurable: true,\n          enumerable: true,\n        })\n      }\n\n      return untypedTarget[property] || virtualizer[property as keyof V]\n    },\n    has(_, property: string) {\n      return !!untracked(virtualizerSignal)[property as keyof V]\n    },\n    ownKeys() {\n      return Reflect.ownKeys(untracked(virtualizerSignal))\n    },\n    getOwnPropertyDescriptor() {\n      return {\n        enumerable: true,\n        configurable: true,\n      }\n    },\n  }) as unknown as AngularVirtualizer<S, I>\n}\n\nfunction toComputed<V extends Virtualizer<any, any>>(\n  signal: Signal<V>,\n  fn: Function,\n) {\n  const computedCache: Record<string, Signal<unknown>> = {}\n\n  return (...args: Array<any>) => {\n    // Cache computeds by their arguments to avoid re-creating the computed on each call\n    const serializedArgs = serializeArgs(...args)\n    if (computedCache.hasOwnProperty(serializedArgs)) {\n      return computedCache[serializedArgs]?.()\n    }\n    const computedSignal = computed(() => {\n      void signal()\n      return fn(...args)\n    })\n\n    computedCache[serializedArgs] = computedSignal\n\n    return computedSignal()\n  }\n}\n\nfunction serializeArgs(...args: Array<any>) {\n  return JSON.stringify(args)\n}\n","import {\n  AfterRenderPhase,\n  DestroyRef,\n  afterNextRender,\n  computed,\n  effect,\n  inject,\n  signal,\n  untracked,\n} from '@angular/core'\nimport {\n  Virtualizer,\n  elementScroll,\n  observeElementOffset,\n  observeElementRect,\n  observeWindowOffset,\n  observeWindowRect,\n  windowScroll,\n} from '@tanstack/virtual-core'\nimport { proxyVirtualizer } from './proxy'\nimport type { ElementRef, Signal } from '@angular/core'\nimport type { PartialKeys, VirtualizerOptions } from '@tanstack/virtual-core'\nimport type { AngularVirtualizer } from './types'\n\nexport * from '@tanstack/virtual-core'\nexport * from './types'\n\nfunction createVirtualizerBase<\n  TScrollElement extends Element | Window,\n  TItemElement extends Element,\n>(\n  options: Signal<VirtualizerOptions<TScrollElement, TItemElement>>,\n): AngularVirtualizer<TScrollElement, TItemElement> {\n  let virtualizer: Virtualizer<TScrollElement, TItemElement>\n  function lazyInit() {\n    virtualizer ??= new Virtualizer(options())\n    return virtualizer\n  }\n\n  const virtualizerSignal = signal(virtualizer!, { equal: () => false })\n\n  // two-way sync options\n  effect(\n    () => {\n      const _options = options()\n      lazyInit()\n      virtualizerSignal.set(virtualizer)\n      virtualizer.setOptions({\n        ..._options,\n        onChange: (instance, sync) => {\n          // update virtualizerSignal so that dependent computeds recompute.\n          virtualizerSignal.set(instance)\n          _options.onChange?.(instance, sync)\n        },\n      })\n      // update virtualizerSignal so that dependent computeds recompute.\n      virtualizerSignal.set(virtualizer)\n    },\n    { allowSignalWrites: true },\n  )\n\n  const scrollElement = computed(() => options().getScrollElement())\n  // let the virtualizer know when the scroll element is changed\n  effect(\n    () => {\n      const el = scrollElement()\n      if (el) {\n        untracked(virtualizerSignal)._willUpdate()\n      }\n    },\n    { allowSignalWrites: true },\n  )\n\n  let cleanup: () => void | undefined\n  afterNextRender(() => (virtualizer ?? lazyInit())._didMount(), {\n    phase: AfterRenderPhase.Read,\n  })\n\n  inject(DestroyRef).onDestroy(() => cleanup?.())\n\n  return proxyVirtualizer(virtualizerSignal, lazyInit)\n}\n\nexport function injectVirtualizer<\n  TScrollElement extends Element,\n  TItemElement extends Element,\n>(\n  options: () => PartialKeys<\n    Omit<VirtualizerOptions<TScrollElement, TItemElement>, 'getScrollElement'>,\n    'observeElementRect' | 'observeElementOffset' | 'scrollToFn'\n  > & {\n    scrollElement: ElementRef<TScrollElement> | TScrollElement | undefined\n  },\n): AngularVirtualizer<TScrollElement, TItemElement> {\n  const resolvedOptions = computed(() => {\n    return {\n      observeElementRect: observeElementRect,\n      observeElementOffset: observeElementOffset,\n      scrollToFn: elementScroll,\n      getScrollElement: () => {\n        const elementOrRef = options().scrollElement\n        return (\n          (isElementRef(elementOrRef)\n            ? elementOrRef.nativeElement\n            : elementOrRef) ?? null\n        )\n      },\n      ...options(),\n    }\n  })\n  return createVirtualizerBase<TScrollElement, TItemElement>(resolvedOptions)\n}\n\nfunction isElementRef<T extends Element>(\n  elementOrRef: ElementRef<T> | T | undefined,\n): elementOrRef is ElementRef<T> {\n  return elementOrRef != null && 'nativeElement' in elementOrRef\n}\n\nexport function injectWindowVirtualizer<TItemElement extends Element>(\n  options: () => PartialKeys<\n    VirtualizerOptions<Window, TItemElement>,\n    | 'getScrollElement'\n    | 'observeElementRect'\n    | 'observeElementOffset'\n    | 'scrollToFn'\n  >,\n): AngularVirtualizer<Window, TItemElement> {\n  const resolvedOptions = computed(() => {\n    return {\n      getScrollElement: () => (typeof document !== 'undefined' ? window : null),\n      observeElementRect: observeWindowRect,\n      observeElementOffset: observeWindowOffset,\n      scrollToFn: windowScroll,\n      initialOffset: () =>\n        typeof document !== 'undefined' ? window.scrollY : 0,\n      ...options(),\n    }\n  })\n  return createVirtualizerBase<Window, TItemElement>(resolvedOptions)\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}