{"version":3,"file":"filter.cjs","sources":["../src/filter.ts"],"sourcesContent":["import { tap } from 'rxjs/operators';\nimport { filter as _filter } from 'rxjs/operators';\nimport { Identity, Predicate } from './types';\n\n/**\n * Enhanced filter operator that provides access to all previously emitted values.\n * Similar to the standard RxJS filter operator but with an additional parameter\n * containing all values that have been emitted so far.\n *\n * @template T - The type of values emitted by the Observable\n * @param predicate - A function that evaluates each source value and returns a boolean.\n *   - value: The current emitted value\n *   - index: The zero-based index of the current emission\n *   - all: Array containing all values emitted so far (including the current value)\n * @returns A function that takes an Observable and returns a filtered Observable\n *\n * @example\n * ```typescript\n * // Filter values based on accumulated sum\n * source$.pipe(\n *   filter((value, index, all) => {\n *     const sum = all.reduce((acc, val) => acc + val, 0);\n *     return sum <= 50;\n *   })\n * )\n *\n * // Filter duplicates using accumulated values\n * source$.pipe(\n *   filter((value, index, all) => {\n *     return all.filter(v => v === value).length === 1;\n *   })\n * )\n *\n * // Filter based on pattern in accumulated array\n * source$.pipe(\n *   filter((value, index, all) => {\n *     if (all.length < 3) return true;\n *     const last3 = all.slice(-3);\n *     return !last3.every(v => v === value);\n *   })\n * )\n * ```\n *\n * @remarks\n * This operator accumulates all emitted values in memory, which means it should be used\n * carefully with long-running or high-frequency observables to avoid memory issues.\n * The accumulated array grows with each emission and is never cleared.\n *\n * The predicate function receives:\n * - The current value being evaluated\n * - The zero-based index of the current emission\n * - An array of all values emitted so far (including the current value)\n *\n * @since 0.0.2\n */\nexport const filter = <T>(predicate: Predicate<T>): Identity<T> => {\n  return source => {\n    const all: T[] = [];\n\n    return source.pipe(\n      tap(value => all.push(value)),\n      _filter((value, index) => predicate(value, index, all)),\n    );\n  };\n};\n\ntype CompareFunction<T> = (prev: T, curr: T) => boolean;\ntype KeySelector<T> = keyof T | ((value: T) => any);\n\n/**\n * Filters values that have changed compared to the previous emission.\n * More sophisticated than distinctUntilChanged with flexible comparison options.\n *\n * @param compareBy - Optional key selector or custom comparison function\n * @returns A function that returns an Observable that emits only changed values\n *\n * @example\n * ```typescript\n * // Filter changed values using default equality\n * source$.pipe(filterChanged())\n *\n * // Filter changed values by specific property\n * source$.pipe(filterChanged('id'))\n *\n * // Filter changed values with custom comparison\n * source$.pipe(filterChanged((prev, curr) => prev.name !== curr.name))\n * ```\n */\nfilter.changed = <T>(\n  compareBy: KeySelector<T> | CompareFunction<T>,\n): Identity<T> => {\n  return source => {\n    let hasValue = false;\n    let lastValue: T;\n\n    return source.pipe(\n      _filter(currentValue => {\n        if (!hasValue) {\n          hasValue = true;\n          lastValue = currentValue;\n          return true;\n        }\n\n        let hasChanged = false;\n\n        if (typeof compareBy === 'function') {\n          if (compareBy.length === 2) {\n            // Custom comparison function\n            hasChanged = (compareBy as CompareFunction<T>)(\n              lastValue,\n              currentValue,\n            );\n          } else {\n            // Key selector function\n            const keySelector = compareBy as (value: T) => any;\n            hasChanged =\n              keySelector(lastValue) !== keySelector(currentValue);\n          }\n        } else {\n          // Property key comparison\n          const key = compareBy as keyof T;\n          hasChanged = lastValue[key] !== currentValue[key];\n        }\n\n        if (hasChanged) {\n          lastValue = currentValue;\n          return true;\n        }\n\n        return false;\n      }),\n    );\n  };\n};\n"],"names":["tap","_filter"],"mappings":";;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDG;AACI,MAAM,MAAM,GAAG,CAAI,SAAuB,KAAiB;IAChE,OAAO,MAAM,IAAG;QACd,MAAM,GAAG,GAAQ,EAAE;AAEnB,QAAA,OAAO,MAAM,CAAC,IAAI,CAChBA,aAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAC7BC,gBAAO,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CACxD;AACH,IAAA,CAAC;AACH;AAKA;;;;;;;;;;;;;;;;;;AAkBG;AACH,MAAM,CAAC,OAAO,GAAG,CACf,SAA8C,KAC/B;IACf,OAAO,MAAM,IAAG;QACd,IAAI,QAAQ,GAAG,KAAK;AACpB,QAAA,IAAI,SAAY;QAEhB,OAAO,MAAM,CAAC,IAAI,CAChBA,gBAAO,CAAC,YAAY,IAAG;YACrB,IAAI,CAAC,QAAQ,EAAE;gBACb,QAAQ,GAAG,IAAI;gBACf,SAAS,GAAG,YAAY;AACxB,gBAAA,OAAO,IAAI;YACb;YAEA,IAAI,UAAU,GAAG,KAAK;AAEtB,YAAA,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE;AACnC,gBAAA,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;;AAE1B,oBAAA,UAAU,GAAI,SAAgC,CAC5C,SAAS,EACT,YAAY,CACb;gBACH;qBAAO;;oBAEL,MAAM,WAAW,GAAG,SAA8B;oBAClD,UAAU;wBACR,WAAW,CAAC,SAAS,CAAC,KAAK,WAAW,CAAC,YAAY,CAAC;gBACxD;YACF;iBAAO;;gBAEL,MAAM,GAAG,GAAG,SAAoB;gBAChC,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,YAAY,CAAC,GAAG,CAAC;YACnD;YAEA,IAAI,UAAU,EAAE;gBACd,SAAS,GAAG,YAAY;AACxB,gBAAA,OAAO,IAAI;YACb;AAEA,YAAA,OAAO,KAAK;QACd,CAAC,CAAC,CACH;AACH,IAAA,CAAC;AACH,CAAC;;;;"}