{"version":3,"file":"scion-toolkit-operators.mjs","sources":["../../../../projects/scion/toolkit/operators/src/operators.ts","../../../../projects/scion/toolkit/operators/src/public_api.ts","../../../../projects/scion/toolkit/operators/src/scion-toolkit-operators.ts"],"sourcesContent":["/*\n * Copyright (c) 2018-2019 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n *  SPDX-License-Identifier: EPL-2.0\n */\n\nimport {catchError, defaultIfEmpty, distinctUntilChanged, map, mergeMap, share, switchMap, take} from 'rxjs/operators';\nimport {combineLatest, concat, EMPTY, from, identity, MonoTypeOperatorFunction, Observable, Observer, of, OperatorFunction, pipe, ReplaySubject, SchedulerLike, takeUntil, TeardownLogic} from 'rxjs';\nimport {Arrays, Objects, Observables} from '@scion/toolkit/util';\n\n/**\n * Filters items in the source array and emits an array with items satisfying given predicate.\n *\n * - If passing `undefined` as predicate, the filter matches all items.\n * - If passing an asynchronous predicate:\n *   - Waits for all predicates to emit at least once or to complete.\n *     TIP: If you want to emit as soon as a predicate emits, use the `startWith(false)` operator in combination with\n *     the `skip` operator. Consequently, there will be a separate emission per item, in the order in which predicates\n *     emit.\n *\n *     ```ts\n *     source$\n *       .pipe(\n *         filterArray(item => matchesItem$(item).pipe(startWith(false))), // make the predicate immediately emit `false`\n *         skip(1), // skip initial emission caused by `startWith(false)`.\n *       )\n *       .subscribe(items => {});\n *     ```\n *   - Continues filtering the source Observable even if some predicate complete without first emission. Such items are not included in the emission.\n *   - Continues filtering the source Observable even if some predicate error. Such items are not included in the emission and the error is not propagated.\n */\nexport function filterArray<T, S extends T>(predicate?: (item: T) => item is S): OperatorFunction<T[] | readonly T[], S[]>;\nexport function filterArray<T>(predicate?: (item: T) => Observable<boolean> | Promise<boolean> | boolean): OperatorFunction<T[] | readonly T[], T[]>;\nexport function filterArray<T>(predicate?: (item: T) => Observable<boolean> | Promise<boolean> | boolean): OperatorFunction<T[] | readonly T[], T[]> {\n  if (!predicate) {\n    return source$ => source$ as Observable<T[]>;\n  }\n\n  return switchMap((items: T[] | readonly T[]): Observable<T[]> => {\n    if (!items.length) {\n      return of([]);\n    }\n\n    // Filter items if all predicates return a boolean value.\n    const matches = items.map(predicate);\n    if (matches.every(match => typeof match === 'boolean')) {\n      return of(items.filter((item, i) => matches[i]));\n    }\n\n    /*\n     * Notes about `combineLatest` operator:\n     * - Passing an empty array will result in an Observable that completes immediately.\n     * - Waits for all Observables to emit at least once.\n     * - If some Observable does not emit a value but completes, resulting Observable will complete at the same moment without emitting anything.\n     * - If some Observable does not emit any value and never completes, `combineLatest` will also never emit and never complete.\n     * - If any Observable errors, `combineLatest` will error immediately as well, and all other Observables will be unsubscribed.\n     */\n    return combineLatest(matches.map(match => Observables.coerce(match).pipe(defaultIfEmpty(false), catchError(() => of(false)))))\n      .pipe(\n        distinctUntilChanged((previous, current) => Objects.isEqual(previous, current)),\n        map(matches => items.filter((item, i) => matches[i])),\n      );\n  });\n}\n\n/**\n * Maps each element in the source array to its mapped value.\n */\nexport function mapArray<I, P>(projectFn: (item: I) => P): OperatorFunction<I[] | readonly I[], P[]> {\n  return map((items: I[] | readonly I[]): P[] => items.map(item => projectFn(item)));\n}\n\n/**\n * Sorts items in the source array and emits an array with those items sorted.\n */\n\nexport function sortArray<T>(comparator: (item1: T, item2: T) => number): OperatorFunction<T[] | readonly T[], T[]> {\n  return map((items: T[] | readonly T[]): T[] => [...items].sort(comparator));\n}\n\n/**\n * Combines the Observables contained in the source array by applying {@link combineLatest}, emitting an array with the latest\n * value of each Observable of the source array. Combines only the Observables of the most recently emitted array.\n *\n * <span class=“informal”>Each time the source emits an array of Observables, combines its Observables by subscribing to each\n * of them, cancelling any subscription of a previous source emission.</span>\n */\nexport function combineArray<T>(): OperatorFunction<Array<Observable<T[]>>, T[]> {\n  return pipe(\n    switchMap((items: Array<Observable<T[]>>) => items.length ? combineLatest(items) : of([])),\n    map((items: Array<T[]>) => new Array<T>().concat(...items)),\n  );\n}\n\n/**\n * Removes duplicates of elements in the source array.\n *\n * <span class=“informal”>Each time the source emits, maps the array to a new array with duplicates removed.</span>\n */\nexport function distinctArray<T>(keySelector: (item: T) => any = identity): OperatorFunction<T[] | readonly T[], T[]> {\n  return pipe(map((items: T[] | readonly T[]): T[] => Arrays.distinct(items, keySelector)));\n}\n\n/**\n * Buffers the source Observable values until `closingNotifier$` notifier resolves, emits or completes.\n *\n * Once closed the buffer, emits its buffered values as a separate emission per buffered value, in the\n * order as collected. After that, this operator mirrors the source Observable, i.e., emits values as they\n * arrive.\n *\n * Unlike {@link bufferWhen} RxJS operator, the buffer is not re-opened once closed.\n *\n * @param closingNotifier$ Closes the buffer when the passed Promise resolves, or when the passed Observable\n *                         emits or completes.\n */\nexport function bufferUntil<T>(closingNotifier$: Observable<any> | Promise<any>): MonoTypeOperatorFunction<T> {\n  const guard$ = from(closingNotifier$)\n    .pipe(\n      take(1),\n      mergeMap(() => EMPTY),\n      share({resetOnComplete: false, resetOnError: false, resetOnRefCountZero: false}),\n    );\n  return mergeMap((item: T) => concat(guard$, of(item)));\n}\n\n/**\n * Executes a tap-function for the first percolating value.\n */\nexport function tapFirst<T>(tapFn: (value?: T) => void, scheduler?: SchedulerLike): MonoTypeOperatorFunction<T> {\n  return map((value: T, index: number): T => {\n    if (index === 0) {\n      scheduler ? scheduler.schedule(tapFn) : tapFn(value);\n    }\n    return value;\n  });\n}\n\n/**\n * Mirrors the source observable, running downstream operators (operators after the `observeIn` operator) and subscription handlers\n * (next, error, complete) in the given function.\n *\n * This operator is similar to RxJS's {@link observeOn} operator, but instead of a scheduler, it accepts a function.\n * The function is invoked each time the source emits, errors or completes and must call the provided `doContinue` function\n * to continue.\n *\n * Use this operator to set up a context for downstream operators, such as inside or outside the Angular zone.\n *\n * **Usage**\n *\n * The following example runs downstream operators inside Angular:\n *\n * ```ts\n * // Code running outside the Angular zone.\n * const zone = inject(NgZone);\n *\n * interval(1000)\n *   .pipe(\n *     tap(() => ...), // runs outside Angular\n *     observeIn(doContinue => zone.run(doContinue)),\n *     tap(() => ...), // runs inside Angular\n *   )\n *   .subscribe(() => ...); // runs inside Angular\n * ```\n *\n * @param fn - A function to set up the execution context. The function must call the provided `doContinue` function to continue.\n * @return An Observable that mirrors the source, but with downstream operators executed in the provided function.\n */\nexport function observeIn<T>(fn: (doContinue: () => void) => void): MonoTypeOperatorFunction<T> {\n  return (source: Observable<T>): Observable<T> => {\n    return new Observable((observer: Observer<T>): TeardownLogic => {\n      const subscription = source.subscribe({\n        next: next => fn(() => observer.next(next)),\n        error: error => fn(() => observer.error(error)),\n        complete: () => fn(() => observer.complete()),\n      });\n\n      return () => subscription.unsubscribe();\n    });\n  };\n}\n\n/**\n * Mirrors the source observable, subscribing to the source in the given function.\n *\n * This operator is similar to RxJS's {@link subscribeOn} operator, but instead of a scheduler, it accepts a function.\n * The function is invoked when subscribing to the source and must call the provided `doSubscribe` function to subscribe.\n *\n * Use this operator to set up a context for the subscription, such as inside or outside the Angular zone.\n *\n * **Usage**\n *\n * The following example illustrates subscribing outside Angular:\n *\n * ```ts\n * // Code running inside the Angular zone.\n * const zone = inject(NgZone);\n *\n * interval(1000)\n *   .pipe(subscribeIn(doSubscribe => zone.runOutsideAngular(doSubscribe)))\n *   .subscribe(() => ...);\n * ```\n *\n * @param fn - A function to set up the subscription context. The function must call the provided `doSubscribe` function to subscribe.\n * @return An Observable that mirrors the source, but with the subscription executed in the provided function.\n */\nexport function subscribeIn<T>(fn: (doSubscribe: () => void) => void): MonoTypeOperatorFunction<T> {\n  return (source: Observable<T>): Observable<T> => {\n    return new Observable((observer: Observer<T>): TeardownLogic => {\n      const unsubscribe$ = new ReplaySubject<void>(1);\n      fn(() => source.pipe(takeUntil(unsubscribe$)).subscribe(observer));\n      return () => unsubscribe$.next();\n    });\n  };\n}\n","/*\n * Copyright (c) 2018-2019 Swiss Federal Railways\n *\n * This program and the accompanying materials are made\n * available under the terms of the Eclipse Public License 2.0\n * which is available at https://www.eclipse.org/legal/epl-2.0/\n *\n *  SPDX-License-Identifier: EPL-2.0\n */\n\n/*\n * Secondary entrypoint: '@scion/toolkit/operators'\n *\n * @see https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md\n */\nexport * from './operators';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}