{"version":3,"file":"tstdl-angular-react.mjs","sources":["../../../../projects/tstdl/angular/react/source/react.component.ts","../../../../projects/tstdl/angular/react/source/react.component.html","../../../../projects/tstdl/angular/react/tstdl-angular-react.ts"],"sourcesContent":["import type { EffectRef, OnChanges, OnDestroy, OnInit, Signal, SimpleChanges } from '@angular/core';\nimport { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Injector, Input, effect, inject, isSignal } from '@angular/core';\nimport type { ReadonlySignal as PreactReadonlySignal } from '@preact/signals';\nimport { signal as preactSignal } from '@preact/signals';\nimport type { Record, Type } from '@tstdl/base/types';\nimport { isFunction, isUndefined } from '@tstdl/base/utils';\nimport { memoizeSingle } from '@tstdl/base/utils/function';\nimport { fromEntries, hasOwnProperty, objectEntries } from '@tstdl/base/utils/object';\nimport type { Attributes, FunctionComponent, Component as PreactComponent } from 'preact';\nimport { createElement, render } from 'preact';\n\n@Component({\n  selector: 'tsl-react',\n  standalone: true,\n  templateUrl: './react.component.html',\n  styleUrls: ['./react.component.scss'],\n  changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ReactComponent<Properties extends Record = any, State = any> implements OnInit, OnChanges, OnDestroy {\n  private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n  private readonly changeDetector = inject(ChangeDetectorRef);\n  private readonly injector = inject(Injector);\n\n  private readonly adaptSignal = memoizeSingle(<T>(source: Signal<T>) => _adaptSignal(source, this.injector), { weak: true });\n  private readonly wrapFunction = memoizeSingle(<T extends (...args: any[]) => any>(fn: T) => _wrapFunction(fn, this.changeDetector), { weak: true });\n\n  private propertiesEffectRef: EffectRef | undefined;\n\n  @Input() component: FunctionComponent<Properties> | Type<PreactComponent<Properties, State>>;\n  @Input() properties: Properties | Signal<Properties>;\n\n  /** adapt angular signals to preact signals (readonly) */\n  @Input() adaptSignals = true;\n\n  /** wrap functions in properties (1st level only) to run change detection afterwards */\n  @Input() wrapFunctions = true;\n\n  get propertiesValue(): Properties {\n    return isSignal(this.properties as any) ? (this.properties as Signal<Properties>)() : this.properties as Properties;\n  }\n\n  ngOnInit(): void {\n    this.render();\n  }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    this.render();\n\n    if (hasOwnProperty(changes, 'properties')) {\n      this.propertiesEffectRef?.destroy();\n\n      if (isSignal(this.properties as any)) {\n        this.propertiesEffectRef = effect(() => {\n          (this.properties as Signal<Properties>)();\n          this.render();\n        }, { injector: this.injector });\n      }\n    }\n  }\n\n  ngOnDestroy(): void {\n    this.propertiesEffectRef?.destroy();\n    render(null, this.elementRef.nativeElement);\n  }\n\n  render(): void {\n    const properties = this.prepareProperties(this.propertiesValue);\n    const element = createElement<Properties>(this.component, properties);\n    render(element, this.elementRef.nativeElement);\n  }\n\n  private prepareProperties<T extends Record>(properties: T): Properties & Attributes {\n    if (!this.adaptSignals && !this.wrapFunctions) {\n      return properties;\n    }\n\n    const entries = objectEntries(properties)\n      .map(([key, value]) => {\n        if (isSignal(value)) {\n          return [key, this.adaptSignal(value as unknown as Signal<T>)];\n        }\n        else if (isFunction(value)) {\n          return [key, this.wrapFunction(value)];\n        }\n\n        return [key, value];\n      });\n\n    return fromEntries(entries);\n  }\n}\n\nfunction _wrapFunction<T extends (...args: any[]) => any>(fn: T, changeDetector: ChangeDetectorRef): T {\n  return ((...args: Parameters<T>): ReturnType<T> => {\n    try {\n      return fn(...args); // eslint-disable-line @typescript-eslint/no-unsafe-return\n    }\n    finally {\n      changeDetector.markForCheck();\n    }\n  }) as T;\n}\n\nfunction _adaptSignal<T>(source: Signal<T>, injector: Injector): PreactReadonlySignal<T> {\n  const adaptedSignal = preactSignal(source());\n  const adaptedSignalWeakRef = new WeakRef(adaptedSignal);\n\n  const subscription = effect(() => {\n    const adaptedSignalRef = adaptedSignalWeakRef.deref();\n\n    if (isUndefined(adaptedSignalRef)) {\n      subscription.destroy();\n      return;\n    }\n\n    adaptedSignalRef.value = source();\n  }, { injector });\n\n  return adaptedSignal;\n}\n","","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["preactSignal"],"mappings":"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"}