{"version":3,"file":"ngneat-dirty-check-forms.mjs","sources":["../../../../libs/dirty-check-forms/src/lib/utils/coercion.ts","../../../../libs/dirty-check-forms/src/lib/dirty-check.guard.ts","../../../../libs/dirty-check-forms/src/lib/is-equal.ts","../../../../libs/dirty-check-forms/src/lib/dirty-check.ts"],"sourcesContent":["import { Observable, of } from 'rxjs';\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function isFunction(value: any): value is Function {\n  return typeof value === 'function';\n}\n\nexport function isObservable(value: any): value is Observable<any> {\n  return value && isFunction(value.subscribe);\n}\n\nexport function toObservable<T>(source: T | Observable<T>): Observable<T> {\n  return isObservable(source) ? source : of(source);\n}\n","import { ActivatedRouteSnapshot, CanDeactivate } from '@angular/router';\nimport { defer, Observable, of } from 'rxjs';\nimport { switchMap, take } from 'rxjs/operators';\nimport { DirtyComponent } from './dirty-component';\nimport { isFunction, toObservable } from './utils/coercion';\n\nexport abstract class DirtyCheckGuard implements CanDeactivate<DirtyComponent> {\n  canDeactivate(\n    component: DirtyComponent,\n    currentRoute: ActivatedRouteSnapshot\n  ): Observable<boolean> {\n    let dirty$: Observable<boolean>;\n    const componentDirty = component.isDirty$;\n\n    if (isFunction(componentDirty)) {\n      dirty$ = defer(() => toObservable(componentDirty()));\n    } else {\n      dirty$ = toObservable(componentDirty);\n    }\n\n    return dirty$.pipe(\n      switchMap((isDirty) => {\n        if (isDirty === false) {\n          return of(true);\n        }\n        return toObservable(this.confirmChanges(currentRoute));\n      }),\n      take(1)\n    );\n  }\n\n  abstract confirmChanges(\n    currentRoute: ActivatedRouteSnapshot\n  ): Observable<boolean> | boolean;\n}\n","// https://github.com/epoberezkin/fast-deep-equal#readme\nexport function equal(a, b) {\n  if (a === b) return true;\n\n  if (a && b && typeof a == 'object' && typeof b == 'object') {\n    if (a.constructor !== b.constructor) return false;\n\n    let length, i;\n    if (Array.isArray(a)) {\n      length = a.length;\n      if (length != b.length) return false;\n      for (i = length; i-- !== 0; ) if (!equal(a[i], b[i])) return false;\n      return true;\n    }\n\n    if (a.constructor === RegExp)\n      return a.source === b.source && a.flags === b.flags;\n    if (a.valueOf !== Object.prototype.valueOf)\n      return a.valueOf() === b.valueOf();\n    if (a.toString !== Object.prototype.toString)\n      return a.toString() === b.toString();\n\n    const keys = Object.keys(a);\n    length = keys.length;\n    if (length !== Object.keys(b).length) return false;\n\n    for (i = length; i-- !== 0; )\n      if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;\n\n    for (i = length; i-- !== 0; ) {\n      const key = keys[i];\n\n      if (!equal(a[key], b[key])) return false;\n    }\n\n    return true;\n  }\n\n  // true if both NaN, false otherwise\n  return a !== a && b !== b;\n}\n","import { AbstractControl, FormArray, FormGroup } from '@angular/forms';\nimport { combineLatest, defer, fromEvent, merge, Observable, of } from 'rxjs';\nimport {\n  debounceTime,\n  distinctUntilChanged,\n  map,\n  shareReplay,\n  startWith,\n  withLatestFrom,\n} from 'rxjs/operators';\nimport { equal as isEqual } from './is-equal';\nimport omit from 'lodash-es/omit';\n\ninterface DirtyCheckConfig<U = unknown> {\n  debounce?: number;\n  withDisabled?: boolean;\n  useBeforeunloadEvent?: boolean;\n  excludeKeys?: Array<keyof U>;\n}\n\nconst defaults: DirtyCheckConfig = {\n  debounce: 300,\n  withDisabled: true,\n  useBeforeunloadEvent: true,\n};\n\nfunction getControlValue(control: AbstractControl, withDisabled: boolean) {\n  if (\n    withDisabled &&\n    (control instanceof FormGroup || control instanceof FormArray)\n  ) {\n    return control.getRawValue();\n  }\n  return control.value;\n}\n\nexport function dirtyCheck<\n  U,\n  Config extends U extends object\n    ? DirtyCheckConfig<U>\n    : Omit<DirtyCheckConfig<U>, 'excludeKeys'>\n>(\n  control: AbstractControl,\n  source: Observable<U>,\n  config: Config = {} as Config\n): Observable<boolean> {\n  const { debounce, withDisabled, useBeforeunloadEvent, excludeKeys } = {\n    ...defaults,\n    ...config,\n  };\n  const value = () => getControlValue(control, withDisabled);\n  const valueChanges$ = merge(\n    defer(() => of(value())),\n    control.valueChanges.pipe(\n      debounceTime(debounce),\n      distinctUntilChanged(),\n      map(() => value())\n    )\n  );\n\n  return new Observable((observer) => {\n    const isDirty$: Observable<boolean> = combineLatest([\n      source,\n      valueChanges$,\n    ]).pipe(\n      map(([a, b]) => {\n        if (excludeKeys) {\n          return !isEqual(omit(a, excludeKeys), omit(b, excludeKeys));\n        }\n\n        return !isEqual(a, b);\n      }),\n      startWith(false),\n      shareReplay({ bufferSize: 1, refCount: true })\n    );\n\n    if (useBeforeunloadEvent) {\n      observer.add(\n        fromEvent(window, 'beforeunload')\n          .pipe(withLatestFrom(isDirty$))\n          .subscribe(([event, isDirty]) => {\n            if (isDirty) {\n              event.preventDefault();\n              event.returnValue = false;\n            }\n          })\n      );\n    }\n\n    return isDirty$.subscribe(observer);\n  });\n}\n"],"names":["isEqual"],"mappings":"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"}