@pyreon/rx 0.11.3 → 0.11.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["reactive"],"sources":["../src/types.ts","../src/aggregation.ts","../src/collections.ts","../src/operators.ts","../src/pipe.ts","../src/search.ts","../src/timing.ts","../src/index.ts"],"sourcesContent":["import type { computed, signal } from \"@pyreon/reactivity\"\n\n/** A readable signal — any callable that returns a value and tracks subscribers. */\nexport type ReadableSignal<T> = (() => T) & { peek?: () => T }\n\n/** Result of a signal-aware transform — Computed when input is signal, plain when not. */\nexport type ReactiveResult<TInput, TOutput> =\n TInput extends ReadableSignal<any> ? ReturnType<typeof computed<TOutput>> : TOutput\n\n/** Key extractor — string key name or function. */\nexport type KeyOf<T> = keyof T | ((item: T) => string | number)\n\n/** Resolve a key extractor to a function. */\nexport function resolveKey<T>(key: KeyOf<T>): (item: T) => string | number {\n return typeof key === \"function\" ? key : (item: T) => String(item[key])\n}\n\n/** Check if a value is a signal (callable function with .set or .peek). */\nexport function isSignal<T>(value: unknown): value is ReadableSignal<T> {\n return typeof value === \"function\"\n}\n","import { computed } from \"@pyreon/reactivity\"\nimport type { KeyOf, ReadableSignal } from \"./types\"\nimport { isSignal, resolveKey } from \"./types\"\n\nfunction reactive<TIn, TOut>(source: TIn, fn: (val: any) => TOut): any {\n if (isSignal(source)) return computed(() => fn((source as ReadableSignal<any>)()))\n return fn(source)\n}\n\n/** Count items in collection. */\nexport function count<T>(source: ReadableSignal<T[]>): ReturnType<typeof computed<number>>\nexport function count<T>(source: T[]): number\nexport function count<T>(source: ReadableSignal<T[]> | T[]): any {\n return reactive(source, (arr: T[]) => arr.length)\n}\n\n/** Sum numeric values. Optionally by key. */\nexport function sum<T>(\n source: ReadableSignal<T[]>,\n key?: KeyOf<T>,\n): ReturnType<typeof computed<number>>\nexport function sum<T>(source: T[], key?: KeyOf<T>): number\nexport function sum<T>(source: ReadableSignal<T[]> | T[], key?: KeyOf<T>): any {\n const getVal = key ? resolveKey(key) : (item: T) => item as unknown as number\n return reactive(source, (arr: T[]) => arr.reduce((acc, item) => acc + Number(getVal(item)), 0))\n}\n\n/** Find minimum item. Optionally by key. */\nexport function min<T>(\n source: ReadableSignal<T[]>,\n key?: KeyOf<T>,\n): ReturnType<typeof computed<T | undefined>>\nexport function min<T>(source: T[], key?: KeyOf<T>): T | undefined\nexport function min<T>(source: ReadableSignal<T[]> | T[], key?: KeyOf<T>): any {\n const getVal = key ? resolveKey(key) : (item: T) => item as unknown as number\n return reactive(source, (arr: T[]) => {\n if (arr.length === 0) return undefined\n let result = arr[0] as T\n let minVal = Number(getVal(result))\n for (let i = 1; i < arr.length; i++) {\n const val = Number(getVal(arr[i] as T))\n if (val < minVal) {\n minVal = val\n result = arr[i] as T\n }\n }\n return result\n })\n}\n\n/** Find maximum item. Optionally by key. */\nexport function max<T>(\n source: ReadableSignal<T[]>,\n key?: KeyOf<T>,\n): ReturnType<typeof computed<T | undefined>>\nexport function max<T>(source: T[], key?: KeyOf<T>): T | undefined\nexport function max<T>(source: ReadableSignal<T[]> | T[], key?: KeyOf<T>): any {\n const getVal = key ? resolveKey(key) : (item: T) => item as unknown as number\n return reactive(source, (arr: T[]) => {\n if (arr.length === 0) return undefined\n let result = arr[0] as T\n let maxVal = Number(getVal(result))\n for (let i = 1; i < arr.length; i++) {\n const val = Number(getVal(arr[i] as T))\n if (val > maxVal) {\n maxVal = val\n result = arr[i] as T\n }\n }\n return result\n })\n}\n\n/** Average of numeric values. Optionally by key. */\nexport function average<T>(\n source: ReadableSignal<T[]>,\n key?: KeyOf<T>,\n): ReturnType<typeof computed<number>>\nexport function average<T>(source: T[], key?: KeyOf<T>): number\nexport function average<T>(source: ReadableSignal<T[]> | T[], key?: KeyOf<T>): any {\n const getVal = key ? resolveKey(key) : (item: T) => item as unknown as number\n return reactive(source, (arr: T[]) => {\n if (arr.length === 0) return 0\n return arr.reduce((acc, item) => acc + Number(getVal(item)), 0) / arr.length\n })\n}\n","import { computed } from \"@pyreon/reactivity\"\nimport type { KeyOf, ReadableSignal } from \"./types\"\nimport { isSignal, resolveKey } from \"./types\"\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\nfunction reactive<TIn, TOut>(\n source: TIn,\n fn: (val: any) => TOut,\n): TIn extends ReadableSignal<any> ? ReturnType<typeof computed<TOut>> : TOut {\n if (isSignal(source)) {\n return computed(() => fn((source as ReadableSignal<any>)())) as any\n }\n return fn(source) as any\n}\n\n// ─── Collection transforms ──────────────────────────────────────────────────\n\n/** Filter items by predicate. Signal in → Computed out. */\nexport function filter<T>(\n source: ReadableSignal<T[]>,\n predicate: (item: T, index: number) => boolean,\n): ReturnType<typeof computed<T[]>>\nexport function filter<T>(source: T[], predicate: (item: T, index: number) => boolean): T[]\nexport function filter<T>(\n source: ReadableSignal<T[]> | T[],\n predicate: (item: T, index: number) => boolean,\n): any {\n return reactive(source, (arr: T[]) => arr.filter(predicate))\n}\n\n/** Map items to a new type. */\nexport function map<T, U>(\n source: ReadableSignal<T[]>,\n fn: (item: T, index: number) => U,\n): ReturnType<typeof computed<U[]>>\nexport function map<T, U>(source: T[], fn: (item: T, index: number) => U): U[]\nexport function map<T, U>(\n source: ReadableSignal<T[]> | T[],\n fn: (item: T, index: number) => U,\n): any {\n return reactive(source, (arr: T[]) => arr.map(fn))\n}\n\n/** Sort items by key or comparator. */\nexport function sortBy<T>(\n source: ReadableSignal<T[]>,\n key: KeyOf<T>,\n): ReturnType<typeof computed<T[]>>\nexport function sortBy<T>(source: T[], key: KeyOf<T>): T[]\nexport function sortBy<T>(source: ReadableSignal<T[]> | T[], key: KeyOf<T>): any {\n const getKey = resolveKey(key)\n return reactive(source, (arr: T[]) =>\n [...arr].sort((a, b) => {\n const ka = getKey(a)\n const kb = getKey(b)\n return ka < kb ? -1 : ka > kb ? 1 : 0\n }),\n )\n}\n\n/** Group items by key. Returns Record<string, T[]>. */\nexport function groupBy<T>(\n source: ReadableSignal<T[]>,\n key: KeyOf<T>,\n): ReturnType<typeof computed<Record<string, T[]>>>\nexport function groupBy<T>(source: T[], key: KeyOf<T>): Record<string, T[]>\nexport function groupBy<T>(source: ReadableSignal<T[]> | T[], key: KeyOf<T>): any {\n const getKey = resolveKey(key)\n return reactive(source, (arr: T[]) => {\n const result: Record<string, T[]> = {}\n for (const item of arr) {\n const k = String(getKey(item))\n let group = result[k]\n if (!group) {\n group = []\n result[k] = group\n }\n group.push(item)\n }\n return result\n })\n}\n\n/** Index items by key. Returns Record<string, T> (last wins on collision). */\nexport function keyBy<T>(\n source: ReadableSignal<T[]>,\n key: KeyOf<T>,\n): ReturnType<typeof computed<Record<string, T>>>\nexport function keyBy<T>(source: T[], key: KeyOf<T>): Record<string, T>\nexport function keyBy<T>(source: ReadableSignal<T[]> | T[], key: KeyOf<T>): any {\n const getKey = resolveKey(key)\n return reactive(source, (arr: T[]) => {\n const result: Record<string, T> = {}\n for (const item of arr) result[String(getKey(item))] = item\n return result\n })\n}\n\n/** Deduplicate items by key. */\nexport function uniqBy<T>(\n source: ReadableSignal<T[]>,\n key: KeyOf<T>,\n): ReturnType<typeof computed<T[]>>\nexport function uniqBy<T>(source: T[], key: KeyOf<T>): T[]\nexport function uniqBy<T>(source: ReadableSignal<T[]> | T[], key: KeyOf<T>): any {\n const getKey = resolveKey(key)\n return reactive(source, (arr: T[]) => {\n const seen = new Set<string | number>()\n return arr.filter((item) => {\n const k = getKey(item)\n if (seen.has(k)) return false\n seen.add(k)\n return true\n })\n })\n}\n\n/** Take the first n items. */\nexport function take<T>(source: ReadableSignal<T[]>, n: number): ReturnType<typeof computed<T[]>>\nexport function take<T>(source: T[], n: number): T[]\nexport function take<T>(source: ReadableSignal<T[]> | T[], n: number): any {\n return reactive(source, (arr: T[]) => arr.slice(0, n))\n}\n\n/** Split into chunks of given size. */\nexport function chunk<T>(\n source: ReadableSignal<T[]>,\n size: number,\n): ReturnType<typeof computed<T[][]>>\nexport function chunk<T>(source: T[], size: number): T[][]\nexport function chunk<T>(source: ReadableSignal<T[]> | T[], size: number): any {\n return reactive(source, (arr: T[]) => {\n const result: T[][] = []\n for (let i = 0; i < arr.length; i += size) result.push(arr.slice(i, i + size))\n return result\n })\n}\n\n/** Flatten one level of nesting. */\nexport function flatten<T>(source: ReadableSignal<T[][]>): ReturnType<typeof computed<T[]>>\nexport function flatten<T>(source: T[][]): T[]\nexport function flatten<T>(source: ReadableSignal<T[][]> | T[][]): any {\n return reactive(source, (arr: T[][]) => arr.flat())\n}\n\n/** Find the first item matching a predicate. */\nexport function find<T>(\n source: ReadableSignal<T[]>,\n predicate: (item: T) => boolean,\n): ReturnType<typeof computed<T | undefined>>\nexport function find<T>(source: T[], predicate: (item: T) => boolean): T | undefined\nexport function find<T>(source: ReadableSignal<T[]> | T[], predicate: (item: T) => boolean): any {\n return reactive(source, (arr: T[]) => arr.find(predicate))\n}\n\n/** Skip the first n items. */\nexport function skip<T>(source: ReadableSignal<T[]>, n: number): ReturnType<typeof computed<T[]>>\nexport function skip<T>(source: T[], n: number): T[]\nexport function skip<T>(source: ReadableSignal<T[]> | T[], n: number): any {\n return reactive(source, (arr: T[]) => arr.slice(n))\n}\n\n/** Take the last n items. */\nexport function last<T>(source: ReadableSignal<T[]>, n: number): ReturnType<typeof computed<T[]>>\nexport function last<T>(source: T[], n: number): T[]\nexport function last<T>(source: ReadableSignal<T[]> | T[], n: number): any {\n return reactive(source, (arr: T[]) => arr.slice(-n))\n}\n\n/** Map over values of a Record. Useful after groupBy. */\nexport function mapValues<T, U>(\n source: ReadableSignal<Record<string, T>>,\n fn: (value: T, key: string) => U,\n): ReturnType<typeof computed<Record<string, U>>>\nexport function mapValues<T, U>(\n source: Record<string, T>,\n fn: (value: T, key: string) => U,\n): Record<string, U>\nexport function mapValues<T, U>(\n source: ReadableSignal<Record<string, T>> | Record<string, T>,\n fn: (value: T, key: string) => U,\n): any {\n return reactive(source, (obj: Record<string, T>) => {\n const result: Record<string, U> = {}\n for (const key of Object.keys(obj)) result[key] = fn(obj[key] as T, key)\n return result\n })\n}\n","import { computed, effect, signal } from \"@pyreon/reactivity\"\nimport type { ReadableSignal } from \"./types\"\n\n/**\n * Distinct — skip consecutive duplicate values from a signal.\n * Uses `Object.is` by default, or a custom equality function.\n */\nexport function distinct<T>(\n source: ReadableSignal<T>,\n equals: (a: T, b: T) => boolean = Object.is,\n): ReadableSignal<T> {\n const result = signal(source())\n\n effect(() => {\n const val = source()\n if (!equals(val, result.peek())) {\n result.set(val)\n }\n })\n\n return result\n}\n\n/**\n * Scan — running accumulator over signal changes.\n * Like Array.reduce but emits the accumulated value on each source change.\n *\n * @example\n * ```ts\n * const clicks = signal(0)\n * const total = rx.scan(clicks, (acc, val) => acc + val, 0)\n * // clicks: 1 → total: 1\n * // clicks: 3 → total: 4\n * // clicks: 2 → total: 6\n * ```\n */\nexport function scan<T, U>(\n source: ReadableSignal<T>,\n reducer: (acc: U, value: T) => U,\n initial: U,\n): ReadableSignal<U> {\n const result = signal(initial)\n\n effect(() => {\n const val = source()\n result.set(reducer(result.peek(), val))\n })\n\n return result\n}\n\n/**\n * Combine multiple signals into a single computed value.\n *\n * @example\n * ```ts\n * const fullName = rx.combine(firstName, lastName, (f, l) => `${f} ${l}`)\n * ```\n */\nexport function combine<A, B, R>(\n a: ReadableSignal<A>,\n b: ReadableSignal<B>,\n fn: (a: A, b: B) => R,\n): ReturnType<typeof computed<R>>\nexport function combine<A, B, C, R>(\n a: ReadableSignal<A>,\n b: ReadableSignal<B>,\n c: ReadableSignal<C>,\n fn: (a: A, b: B, c: C) => R,\n): ReturnType<typeof computed<R>>\nexport function combine(...args: any[]): any {\n const fn = args[args.length - 1] as (...vals: any[]) => any\n const sources = args.slice(0, -1) as ReadableSignal<any>[]\n return computed(() => fn(...sources.map((s) => s())))\n}\n","import { computed } from \"@pyreon/reactivity\"\nimport type { ReadableSignal } from \"./types\"\nimport { isSignal } from \"./types\"\n\n/**\n * Pipe a signal through a chain of transform functions.\n * Each transform receives the resolved value (not the signal) and returns a new value.\n * The entire chain is wrapped in a single `computed()`.\n *\n * @example\n * ```ts\n * const topRisks = rx.pipe(\n * findings,\n * (items) => items.filter(f => f.severity === \"critical\"),\n * (items) => items.sort((a, b) => b.score - a.score),\n * (items) => items.slice(0, 10),\n * )\n * // topRisks() → reactive, type-safe\n * ```\n */\nexport function pipe<A, B>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n): ReturnType<typeof computed<B>>\nexport function pipe<A, B, C>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n f2: (b: B) => C,\n): ReturnType<typeof computed<C>>\nexport function pipe<A, B, C, D>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n f2: (b: B) => C,\n f3: (c: C) => D,\n): ReturnType<typeof computed<D>>\nexport function pipe<A, B, C, D, E>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n f2: (b: B) => C,\n f3: (c: C) => D,\n f4: (d: D) => E,\n): ReturnType<typeof computed<E>>\nexport function pipe<A, B, C, D, E, F>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n f2: (b: B) => C,\n f3: (c: C) => D,\n f4: (d: D) => E,\n f5: (e: E) => F,\n): ReturnType<typeof computed<F>>\n// Plain value overloads\nexport function pipe<A, B>(source: A, f1: (a: A) => B): B\nexport function pipe<A, B, C>(source: A, f1: (a: A) => B, f2: (b: B) => C): C\nexport function pipe<A, B, C, D>(source: A, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D): D\nexport function pipe(source: any, ...fns: Array<(v: any) => any>): any {\n if (isSignal(source)) {\n return computed(() => {\n let val = (source as ReadableSignal<any>)()\n for (const fn of fns) val = fn(val)\n return val\n })\n }\n let val = source\n for (const fn of fns) val = fn(val)\n return val\n}\n","import { computed } from \"@pyreon/reactivity\"\nimport type { ReadableSignal } from \"./types\"\nimport { isSignal } from \"./types\"\n\n/**\n * Search items by substring matching across specified keys.\n * Case-insensitive. Signal-aware — reactive when either source or query is a signal.\n *\n * @example\n * ```ts\n * const results = rx.search(users, searchQuery, [\"name\", \"email\"])\n * ```\n */\nexport function search<T>(\n source: ReadableSignal<T[]> | T[],\n query: ReadableSignal<string> | string,\n keys: (keyof T)[],\n): any {\n const isReactive = isSignal(source) || isSignal(query)\n\n const doSearch = (): T[] => {\n const arr = isSignal(source) ? (source as ReadableSignal<T[]>)() : source\n const q = (isSignal(query) ? (query as ReadableSignal<string>)() : query).toLowerCase().trim()\n if (!q) return arr\n return arr.filter((item) =>\n keys.some((key) => {\n const val = item[key]\n return typeof val === \"string\" && val.toLowerCase().includes(q)\n }),\n )\n }\n\n return isReactive ? computed(doSearch) : doSearch()\n}\n","import { effect, signal } from \"@pyreon/reactivity\"\nimport type { ReadableSignal } from \"./types\"\n\n/**\n * Debounce a signal — emits the latest value after `ms` of silence.\n * Returns a new signal that updates only after the source stops changing.\n *\n * Works both inside and outside component context.\n * The returned signal has a `.dispose()` method to stop tracking.\n */\nexport function debounce<T>(\n source: ReadableSignal<T>,\n ms: number,\n): ReadableSignal<T> & { dispose: () => void } {\n const debounced = signal(source())\n let timer: ReturnType<typeof setTimeout> | undefined\n\n const fx = effect(() => {\n const val = source()\n if (timer) clearTimeout(timer)\n timer = setTimeout(() => debounced.set(val), ms)\n })\n\n const dispose = () => {\n if (timer) clearTimeout(timer)\n fx.dispose()\n }\n\n return Object.assign(debounced as ReadableSignal<T>, { dispose })\n}\n\n/**\n * Throttle a signal — emits at most once every `ms` milliseconds.\n * Immediately emits on first change, then waits for the interval.\n *\n * Works both inside and outside component context.\n * The returned signal has a `.dispose()` method to stop tracking.\n */\nexport function throttle<T>(\n source: ReadableSignal<T>,\n ms: number,\n): ReadableSignal<T> & { dispose: () => void } {\n const throttled = signal(source())\n let lastEmit = 0\n let timer: ReturnType<typeof setTimeout> | undefined\n\n const fx = effect(() => {\n const val = source()\n const now = Date.now()\n const elapsed = now - lastEmit\n\n if (elapsed >= ms) {\n throttled.set(val)\n lastEmit = now\n } else {\n if (timer) clearTimeout(timer)\n timer = setTimeout(() => {\n throttled.set(val)\n lastEmit = Date.now()\n }, ms - elapsed)\n }\n })\n\n const dispose = () => {\n if (timer) clearTimeout(timer)\n fx.dispose()\n }\n\n return Object.assign(throttled as ReadableSignal<T>, { dispose })\n}\n","import { average, count, max, min, sum } from \"./aggregation\"\nimport {\n chunk,\n filter,\n find,\n flatten,\n groupBy,\n keyBy,\n last,\n map,\n mapValues,\n skip,\n sortBy,\n take,\n uniqBy,\n} from \"./collections\"\nimport { combine, distinct, scan } from \"./operators\"\nimport { pipe } from \"./pipe\"\nimport { search } from \"./search\"\nimport { debounce, throttle } from \"./timing\"\n\nexport type { KeyOf, ReadableSignal } from \"./types\"\n\n/**\n * Signal-aware reactive transforms.\n *\n * Every function is overloaded:\n * - `Signal<T[]>` input → returns `Computed<R>` (reactive)\n * - `T[]` input → returns `R` (static)\n *\n * @example\n * ```ts\n * import { rx } from \"@pyreon/rx\"\n *\n * const users = signal<User[]>([])\n * const active = rx.filter(users, u => u.active) // Computed<User[]>\n * const sorted = rx.sortBy(active, \"name\") // Computed<User[]>\n * const top10 = rx.take(sorted, 10) // Computed<User[]>\n *\n * // Or pipe:\n * const result = rx.pipe(users,\n * items => items.filter(u => u.active),\n * items => items.sort((a, b) => a.name.localeCompare(b.name)),\n * items => items.slice(0, 10),\n * )\n * ```\n */\nexport const rx = {\n // Collections\n filter,\n map,\n sortBy,\n groupBy,\n keyBy,\n uniqBy,\n take,\n skip,\n last,\n chunk,\n flatten,\n find,\n mapValues,\n\n // Aggregation\n count,\n sum,\n min,\n max,\n average,\n\n // Operators\n distinct,\n scan,\n combine,\n\n // Timing\n debounce,\n throttle,\n\n // Search\n search,\n\n // Pipe\n pipe,\n} as const\n\n// Also export individual functions for tree-shaking\nexport {\n average,\n chunk,\n combine,\n count,\n debounce,\n distinct,\n filter,\n find,\n flatten,\n groupBy,\n keyBy,\n last,\n map,\n mapValues,\n max,\n min,\n pipe,\n scan,\n search,\n skip,\n sortBy,\n sum,\n take,\n throttle,\n uniqBy,\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["reactive"],"sources":["../src/types.ts","../src/aggregation.ts","../src/collections.ts","../src/operators.ts","../src/pipe.ts","../src/search.ts","../src/timing.ts","../src/index.ts"],"sourcesContent":["import type { computed, signal } from \"@pyreon/reactivity\"\n\n/** A readable signal — any callable that returns a value and tracks subscribers. */\nexport type ReadableSignal<T> = (() => T) & { peek?: () => T }\n\n/** Result of a signal-aware transform — Computed when input is signal, plain when not. */\nexport type ReactiveResult<TInput, TOutput> =\n TInput extends ReadableSignal<any> ? ReturnType<typeof computed<TOutput>> : TOutput\n\n/** Key extractor — string key name or function. */\nexport type KeyOf<T> = keyof T | ((item: T) => string | number)\n\n/** Resolve a key extractor to a function. */\nexport function resolveKey<T>(key: KeyOf<T>): (item: T) => string | number {\n return typeof key === \"function\" ? key : (item: T) => String(item[key])\n}\n\n/** Check if a value is a signal (callable function with .set or .peek). */\nexport function isSignal<T>(value: unknown): value is ReadableSignal<T> {\n return typeof value === \"function\"\n}\n","import { computed } from \"@pyreon/reactivity\"\nimport type { KeyOf, ReadableSignal } from \"./types\"\nimport { isSignal, resolveKey } from \"./types\"\n\nfunction reactive<TIn, TOut>(source: TIn, fn: (val: any) => TOut): any {\n if (isSignal(source)) return computed(() => fn((source as ReadableSignal<any>)()))\n return fn(source)\n}\n\n/** Count items in collection. */\nexport function count<T>(source: ReadableSignal<T[]>): ReturnType<typeof computed<number>>\nexport function count<T>(source: T[]): number\nexport function count<T>(source: ReadableSignal<T[]> | T[]): any {\n return reactive(source, (arr: T[]) => arr.length)\n}\n\n/** Sum numeric values. Optionally by key. */\nexport function sum<T>(\n source: ReadableSignal<T[]>,\n key?: KeyOf<T>,\n): ReturnType<typeof computed<number>>\nexport function sum<T>(source: T[], key?: KeyOf<T>): number\nexport function sum<T>(source: ReadableSignal<T[]> | T[], key?: KeyOf<T>): any {\n const getVal = key ? resolveKey(key) : (item: T) => item as unknown as number\n return reactive(source, (arr: T[]) => arr.reduce((acc, item) => acc + Number(getVal(item)), 0))\n}\n\n/** Find minimum item. Optionally by key. */\nexport function min<T>(\n source: ReadableSignal<T[]>,\n key?: KeyOf<T>,\n): ReturnType<typeof computed<T | undefined>>\nexport function min<T>(source: T[], key?: KeyOf<T>): T | undefined\nexport function min<T>(source: ReadableSignal<T[]> | T[], key?: KeyOf<T>): any {\n const getVal = key ? resolveKey(key) : (item: T) => item as unknown as number\n return reactive(source, (arr: T[]) => {\n if (arr.length === 0) return undefined\n let result = arr[0] as T\n let minVal = Number(getVal(result))\n for (let i = 1; i < arr.length; i++) {\n const val = Number(getVal(arr[i] as T))\n if (val < minVal) {\n minVal = val\n result = arr[i] as T\n }\n }\n return result\n })\n}\n\n/** Find maximum item. Optionally by key. */\nexport function max<T>(\n source: ReadableSignal<T[]>,\n key?: KeyOf<T>,\n): ReturnType<typeof computed<T | undefined>>\nexport function max<T>(source: T[], key?: KeyOf<T>): T | undefined\nexport function max<T>(source: ReadableSignal<T[]> | T[], key?: KeyOf<T>): any {\n const getVal = key ? resolveKey(key) : (item: T) => item as unknown as number\n return reactive(source, (arr: T[]) => {\n if (arr.length === 0) return undefined\n let result = arr[0] as T\n let maxVal = Number(getVal(result))\n for (let i = 1; i < arr.length; i++) {\n const val = Number(getVal(arr[i] as T))\n if (val > maxVal) {\n maxVal = val\n result = arr[i] as T\n }\n }\n return result\n })\n}\n\n/** Average of numeric values. Optionally by key. */\nexport function average<T>(\n source: ReadableSignal<T[]>,\n key?: KeyOf<T>,\n): ReturnType<typeof computed<number>>\nexport function average<T>(source: T[], key?: KeyOf<T>): number\nexport function average<T>(source: ReadableSignal<T[]> | T[], key?: KeyOf<T>): any {\n const getVal = key ? resolveKey(key) : (item: T) => item as unknown as number\n return reactive(source, (arr: T[]) => {\n if (arr.length === 0) return 0\n return arr.reduce((acc, item) => acc + Number(getVal(item)), 0) / arr.length\n })\n}\n","import { computed } from \"@pyreon/reactivity\"\nimport type { KeyOf, ReadableSignal } from \"./types\"\nimport { isSignal, resolveKey } from \"./types\"\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\nfunction reactive<TIn, TOut>(\n source: TIn,\n fn: (val: any) => TOut,\n): TIn extends ReadableSignal<any> ? ReturnType<typeof computed<TOut>> : TOut {\n if (isSignal(source)) {\n return computed(() => fn((source as ReadableSignal<any>)())) as any\n }\n return fn(source) as any\n}\n\n// ─── Collection transforms ──────────────────────────────────────────────────\n\n/** Filter items by predicate. Signal in → Computed out. */\nexport function filter<T>(\n source: ReadableSignal<T[]>,\n predicate: (item: T, index: number) => boolean,\n): ReturnType<typeof computed<T[]>>\nexport function filter<T>(source: T[], predicate: (item: T, index: number) => boolean): T[]\nexport function filter<T>(\n source: ReadableSignal<T[]> | T[],\n predicate: (item: T, index: number) => boolean,\n): any {\n return reactive(source, (arr: T[]) => arr.filter(predicate))\n}\n\n/** Map items to a new type. */\nexport function map<T, U>(\n source: ReadableSignal<T[]>,\n fn: (item: T, index: number) => U,\n): ReturnType<typeof computed<U[]>>\nexport function map<T, U>(source: T[], fn: (item: T, index: number) => U): U[]\nexport function map<T, U>(\n source: ReadableSignal<T[]> | T[],\n fn: (item: T, index: number) => U,\n): any {\n return reactive(source, (arr: T[]) => arr.map(fn))\n}\n\n/** Sort items by key or comparator. */\nexport function sortBy<T>(\n source: ReadableSignal<T[]>,\n key: KeyOf<T>,\n): ReturnType<typeof computed<T[]>>\nexport function sortBy<T>(source: T[], key: KeyOf<T>): T[]\nexport function sortBy<T>(source: ReadableSignal<T[]> | T[], key: KeyOf<T>): any {\n const getKey = resolveKey(key)\n return reactive(source, (arr: T[]) =>\n [...arr].sort((a, b) => {\n const ka = getKey(a)\n const kb = getKey(b)\n return ka < kb ? -1 : ka > kb ? 1 : 0\n }),\n )\n}\n\n/** Group items by key. Returns Record<string, T[]>. */\nexport function groupBy<T>(\n source: ReadableSignal<T[]>,\n key: KeyOf<T>,\n): ReturnType<typeof computed<Record<string, T[]>>>\nexport function groupBy<T>(source: T[], key: KeyOf<T>): Record<string, T[]>\nexport function groupBy<T>(source: ReadableSignal<T[]> | T[], key: KeyOf<T>): any {\n const getKey = resolveKey(key)\n return reactive(source, (arr: T[]) => {\n const result: Record<string, T[]> = {}\n for (const item of arr) {\n const k = String(getKey(item))\n let group = result[k]\n if (!group) {\n group = []\n result[k] = group\n }\n group.push(item)\n }\n return result\n })\n}\n\n/** Index items by key. Returns Record<string, T> (last wins on collision). */\nexport function keyBy<T>(\n source: ReadableSignal<T[]>,\n key: KeyOf<T>,\n): ReturnType<typeof computed<Record<string, T>>>\nexport function keyBy<T>(source: T[], key: KeyOf<T>): Record<string, T>\nexport function keyBy<T>(source: ReadableSignal<T[]> | T[], key: KeyOf<T>): any {\n const getKey = resolveKey(key)\n return reactive(source, (arr: T[]) => {\n const result: Record<string, T> = {}\n for (const item of arr) result[String(getKey(item))] = item\n return result\n })\n}\n\n/** Deduplicate items by key. */\nexport function uniqBy<T>(\n source: ReadableSignal<T[]>,\n key: KeyOf<T>,\n): ReturnType<typeof computed<T[]>>\nexport function uniqBy<T>(source: T[], key: KeyOf<T>): T[]\nexport function uniqBy<T>(source: ReadableSignal<T[]> | T[], key: KeyOf<T>): any {\n const getKey = resolveKey(key)\n return reactive(source, (arr: T[]) => {\n const seen = new Set<string | number>()\n return arr.filter((item) => {\n const k = getKey(item)\n if (seen.has(k)) return false\n seen.add(k)\n return true\n })\n })\n}\n\n/** Take the first n items. */\nexport function take<T>(source: ReadableSignal<T[]>, n: number): ReturnType<typeof computed<T[]>>\nexport function take<T>(source: T[], n: number): T[]\nexport function take<T>(source: ReadableSignal<T[]> | T[], n: number): any {\n return reactive(source, (arr: T[]) => arr.slice(0, n))\n}\n\n/** Split into chunks of given size. */\nexport function chunk<T>(\n source: ReadableSignal<T[]>,\n size: number,\n): ReturnType<typeof computed<T[][]>>\nexport function chunk<T>(source: T[], size: number): T[][]\nexport function chunk<T>(source: ReadableSignal<T[]> | T[], size: number): any {\n return reactive(source, (arr: T[]) => {\n const result: T[][] = []\n for (let i = 0; i < arr.length; i += size) result.push(arr.slice(i, i + size))\n return result\n })\n}\n\n/** Flatten one level of nesting. */\nexport function flatten<T>(source: ReadableSignal<T[][]>): ReturnType<typeof computed<T[]>>\nexport function flatten<T>(source: T[][]): T[]\nexport function flatten<T>(source: ReadableSignal<T[][]> | T[][]): any {\n return reactive(source, (arr: T[][]) => arr.flat())\n}\n\n/** Find the first item matching a predicate. */\nexport function find<T>(\n source: ReadableSignal<T[]>,\n predicate: (item: T) => boolean,\n): ReturnType<typeof computed<T | undefined>>\nexport function find<T>(source: T[], predicate: (item: T) => boolean): T | undefined\nexport function find<T>(source: ReadableSignal<T[]> | T[], predicate: (item: T) => boolean): any {\n return reactive(source, (arr: T[]) => arr.find(predicate))\n}\n\n/** Skip the first n items. */\nexport function skip<T>(source: ReadableSignal<T[]>, n: number): ReturnType<typeof computed<T[]>>\nexport function skip<T>(source: T[], n: number): T[]\nexport function skip<T>(source: ReadableSignal<T[]> | T[], n: number): any {\n return reactive(source, (arr: T[]) => arr.slice(n))\n}\n\n/** Take the last n items. */\nexport function last<T>(source: ReadableSignal<T[]>, n: number): ReturnType<typeof computed<T[]>>\nexport function last<T>(source: T[], n: number): T[]\nexport function last<T>(source: ReadableSignal<T[]> | T[], n: number): any {\n return reactive(source, (arr: T[]) => arr.slice(-n))\n}\n\n/** Map over values of a Record. Useful after groupBy. */\nexport function mapValues<T, U>(\n source: ReadableSignal<Record<string, T>>,\n fn: (value: T, key: string) => U,\n): ReturnType<typeof computed<Record<string, U>>>\nexport function mapValues<T, U>(\n source: Record<string, T>,\n fn: (value: T, key: string) => U,\n): Record<string, U>\nexport function mapValues<T, U>(\n source: ReadableSignal<Record<string, T>> | Record<string, T>,\n fn: (value: T, key: string) => U,\n): any {\n return reactive(source, (obj: Record<string, T>) => {\n const result: Record<string, U> = {}\n for (const key of Object.keys(obj)) result[key] = fn(obj[key] as T, key)\n return result\n })\n}\n","import { computed, effect, signal } from \"@pyreon/reactivity\"\nimport type { ReadableSignal } from \"./types\"\n\n/**\n * Distinct — skip consecutive duplicate values from a signal.\n * Uses `Object.is` by default, or a custom equality function.\n */\nexport function distinct<T>(\n source: ReadableSignal<T>,\n equals: (a: T, b: T) => boolean = Object.is,\n): ReadableSignal<T> {\n const result = signal(source())\n\n effect(() => {\n const val = source()\n if (!equals(val, result.peek())) {\n result.set(val)\n }\n })\n\n return result\n}\n\n/**\n * Scan — running accumulator over signal changes.\n * Like Array.reduce but emits the accumulated value on each source change.\n *\n * @example\n * ```ts\n * const clicks = signal(0)\n * const total = rx.scan(clicks, (acc, val) => acc + val, 0)\n * // clicks: 1 → total: 1\n * // clicks: 3 → total: 4\n * // clicks: 2 → total: 6\n * ```\n */\nexport function scan<T, U>(\n source: ReadableSignal<T>,\n reducer: (acc: U, value: T) => U,\n initial: U,\n): ReadableSignal<U> {\n const result = signal(initial)\n\n effect(() => {\n const val = source()\n result.set(reducer(result.peek(), val))\n })\n\n return result\n}\n\n/**\n * Combine multiple signals into a single computed value.\n *\n * @example\n * ```ts\n * const fullName = rx.combine(firstName, lastName, (f, l) => `${f} ${l}`)\n * ```\n */\nexport function combine<A, B, R>(\n a: ReadableSignal<A>,\n b: ReadableSignal<B>,\n fn: (a: A, b: B) => R,\n): ReturnType<typeof computed<R>>\nexport function combine<A, B, C, R>(\n a: ReadableSignal<A>,\n b: ReadableSignal<B>,\n c: ReadableSignal<C>,\n fn: (a: A, b: B, c: C) => R,\n): ReturnType<typeof computed<R>>\nexport function combine(...args: any[]): any {\n const fn = args[args.length - 1] as (...vals: any[]) => any\n const sources = args.slice(0, -1) as ReadableSignal<any>[]\n return computed(() => fn(...sources.map((s) => s())))\n}\n","import { computed } from \"@pyreon/reactivity\"\nimport type { ReadableSignal } from \"./types\"\nimport { isSignal } from \"./types\"\n\n/**\n * Pipe a signal through a chain of transform functions.\n * Each transform receives the resolved value (not the signal) and returns a new value.\n * The entire chain is wrapped in a single `computed()`.\n *\n * @example\n * ```ts\n * const topRisks = rx.pipe(\n * findings,\n * (items) => items.filter(f => f.severity === \"critical\"),\n * (items) => items.sort((a, b) => b.score - a.score),\n * (items) => items.slice(0, 10),\n * )\n * // topRisks() → reactive, type-safe\n * ```\n */\nexport function pipe<A, B>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n): ReturnType<typeof computed<B>>\nexport function pipe<A, B, C>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n f2: (b: B) => C,\n): ReturnType<typeof computed<C>>\nexport function pipe<A, B, C, D>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n f2: (b: B) => C,\n f3: (c: C) => D,\n): ReturnType<typeof computed<D>>\nexport function pipe<A, B, C, D, E>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n f2: (b: B) => C,\n f3: (c: C) => D,\n f4: (d: D) => E,\n): ReturnType<typeof computed<E>>\nexport function pipe<A, B, C, D, E, F>(\n source: ReadableSignal<A>,\n f1: (a: A) => B,\n f2: (b: B) => C,\n f3: (c: C) => D,\n f4: (d: D) => E,\n f5: (e: E) => F,\n): ReturnType<typeof computed<F>>\n// Plain value overloads\nexport function pipe<A, B>(source: A, f1: (a: A) => B): B\nexport function pipe<A, B, C>(source: A, f1: (a: A) => B, f2: (b: B) => C): C\nexport function pipe<A, B, C, D>(source: A, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D): D\nexport function pipe<A, B, C, D, E>(\n source: A,\n f1: (a: A) => B,\n f2: (b: B) => C,\n f3: (c: C) => D,\n f4: (d: D) => E,\n): E\nexport function pipe<A, B, C, D, E, F>(\n source: A,\n f1: (a: A) => B,\n f2: (b: B) => C,\n f3: (c: C) => D,\n f4: (d: D) => E,\n f5: (e: E) => F,\n): F\nexport function pipe(source: any, ...fns: Array<(v: any) => any>): any {\n if (isSignal(source)) {\n return computed(() => {\n let val = (source as ReadableSignal<any>)()\n for (const fn of fns) val = fn(val)\n return val\n })\n }\n let val = source\n for (const fn of fns) val = fn(val)\n return val\n}\n","import { computed } from \"@pyreon/reactivity\"\nimport type { ReadableSignal } from \"./types\"\nimport { isSignal } from \"./types\"\n\n/**\n * Search items by substring matching across specified keys.\n * Case-insensitive. Signal-aware — reactive when either source or query is a signal.\n *\n * @example\n * ```ts\n * const results = rx.search(users, searchQuery, [\"name\", \"email\"])\n * ```\n */\nexport function search<T>(\n source: ReadableSignal<T[]> | T[],\n query: ReadableSignal<string> | string,\n keys: (keyof T)[],\n): any {\n const isReactive = isSignal(source) || isSignal(query)\n\n const doSearch = (): T[] => {\n const arr = isSignal(source) ? (source as ReadableSignal<T[]>)() : source\n const q = (isSignal(query) ? (query as ReadableSignal<string>)() : query).toLowerCase().trim()\n if (!q) return arr\n return arr.filter((item) =>\n keys.some((key) => {\n const val = item[key]\n return typeof val === \"string\" && val.toLowerCase().includes(q)\n }),\n )\n }\n\n return isReactive ? computed(doSearch) : doSearch()\n}\n","import { effect, signal } from \"@pyreon/reactivity\"\nimport type { ReadableSignal } from \"./types\"\n\n/**\n * Debounce a signal — emits the latest value after `ms` of silence.\n * Returns a new signal that updates only after the source stops changing.\n *\n * Works both inside and outside component context.\n * The returned signal has a `.dispose()` method to stop tracking.\n */\nexport function debounce<T>(\n source: ReadableSignal<T>,\n ms: number,\n): ReadableSignal<T> & { dispose: () => void } {\n const debounced = signal(source())\n let timer: ReturnType<typeof setTimeout> | undefined\n\n const fx = effect(() => {\n const val = source()\n if (timer) clearTimeout(timer)\n timer = setTimeout(() => debounced.set(val), ms)\n })\n\n const dispose = () => {\n if (timer) clearTimeout(timer)\n fx.dispose()\n }\n\n return Object.assign(debounced as ReadableSignal<T>, { dispose })\n}\n\n/**\n * Throttle a signal — emits at most once every `ms` milliseconds.\n * Immediately emits on first change, then waits for the interval.\n *\n * Works both inside and outside component context.\n * The returned signal has a `.dispose()` method to stop tracking.\n */\nexport function throttle<T>(\n source: ReadableSignal<T>,\n ms: number,\n): ReadableSignal<T> & { dispose: () => void } {\n const throttled = signal(source())\n let lastEmit = 0\n let timer: ReturnType<typeof setTimeout> | undefined\n\n const fx = effect(() => {\n const val = source()\n const now = Date.now()\n const elapsed = now - lastEmit\n\n if (elapsed >= ms) {\n throttled.set(val)\n lastEmit = now\n } else {\n if (timer) clearTimeout(timer)\n timer = setTimeout(() => {\n throttled.set(val)\n lastEmit = Date.now()\n }, ms - elapsed)\n }\n })\n\n const dispose = () => {\n if (timer) clearTimeout(timer)\n fx.dispose()\n }\n\n return Object.assign(throttled as ReadableSignal<T>, { dispose })\n}\n","import { average, count, max, min, sum } from \"./aggregation\"\nimport {\n chunk,\n filter,\n find,\n flatten,\n groupBy,\n keyBy,\n last,\n map,\n mapValues,\n skip,\n sortBy,\n take,\n uniqBy,\n} from \"./collections\"\nimport { combine, distinct, scan } from \"./operators\"\nimport { pipe } from \"./pipe\"\nimport { search } from \"./search\"\nimport { debounce, throttle } from \"./timing\"\n\nexport type { KeyOf, ReadableSignal } from \"./types\"\n\n/**\n * Signal-aware reactive transforms.\n *\n * Every function is overloaded:\n * - `Signal<T[]>` input → returns `Computed<R>` (reactive)\n * - `T[]` input → returns `R` (static)\n *\n * @example\n * ```ts\n * import { rx } from \"@pyreon/rx\"\n *\n * const users = signal<User[]>([])\n * const active = rx.filter(users, u => u.active) // Computed<User[]>\n * const sorted = rx.sortBy(active, \"name\") // Computed<User[]>\n * const top10 = rx.take(sorted, 10) // Computed<User[]>\n *\n * // Or pipe:\n * const result = rx.pipe(users,\n * items => items.filter(u => u.active),\n * items => items.sort((a, b) => a.name.localeCompare(b.name)),\n * items => items.slice(0, 10),\n * )\n * ```\n */\nexport const rx = {\n // Collections\n filter,\n map,\n sortBy,\n groupBy,\n keyBy,\n uniqBy,\n take,\n skip,\n last,\n chunk,\n flatten,\n find,\n mapValues,\n\n // Aggregation\n count,\n sum,\n min,\n max,\n average,\n\n // Operators\n distinct,\n scan,\n combine,\n\n // Timing\n debounce,\n throttle,\n\n // Search\n search,\n\n // Pipe\n pipe,\n} as const\n\n// Also export individual functions for tree-shaking\nexport {\n average,\n chunk,\n combine,\n count,\n debounce,\n distinct,\n filter,\n find,\n flatten,\n groupBy,\n keyBy,\n last,\n map,\n mapValues,\n max,\n min,\n pipe,\n scan,\n search,\n skip,\n sortBy,\n sum,\n take,\n throttle,\n uniqBy,\n}\n"],"mappings":"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"}
@@ -122,6 +122,8 @@ declare function pipe<A, B, C, D, E, F>(source: ReadableSignal<A>, f1: (a: A) =>
122
122
  declare function pipe<A, B>(source: A, f1: (a: A) => B): B;
123
123
  declare function pipe<A, B, C>(source: A, f1: (a: A) => B, f2: (b: B) => C): C;
124
124
  declare function pipe<A, B, C, D>(source: A, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D): D;
125
+ declare function pipe<A, B, C, D, E>(source: A, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D, f4: (d: D) => E): E;
126
+ declare function pipe<A, B, C, D, E, F>(source: A, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D, f4: (d: D) => E, f5: (e: E) => F): F;
125
127
  //#endregion
126
128
  //#region src/search.d.ts
127
129
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/types.ts","../../../src/aggregation.ts","../../../src/collections.ts","../../../src/operators.ts","../../../src/pipe.ts","../../../src/search.ts","../../../src/timing.ts","../../../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/types.ts","../../../src/aggregation.ts","../../../src/collections.ts","../../../src/operators.ts","../../../src/pipe.ts","../../../src/search.ts","../../../src/timing.ts","../../../src/index.ts"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/rx",
3
- "version": "0.11.3",
3
+ "version": "0.11.4",
4
4
  "description": "Signal-aware reactive transforms — filter, map, sort, group, pipe for Pyreon signals",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -37,9 +37,9 @@
37
37
  "lint": "biome check ."
38
38
  },
39
39
  "peerDependencies": {
40
- "@pyreon/reactivity": "^0.11.3"
40
+ "@pyreon/reactivity": "^0.11.4"
41
41
  },
42
42
  "devDependencies": {
43
- "@pyreon/typescript": "^0.11.3"
43
+ "@pyreon/typescript": "^0.11.4"
44
44
  }
45
45
  }
package/src/pipe.ts CHANGED
@@ -52,6 +52,21 @@ export function pipe<A, B, C, D, E, F>(
52
52
  export function pipe<A, B>(source: A, f1: (a: A) => B): B
53
53
  export function pipe<A, B, C>(source: A, f1: (a: A) => B, f2: (b: B) => C): C
54
54
  export function pipe<A, B, C, D>(source: A, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D): D
55
+ export function pipe<A, B, C, D, E>(
56
+ source: A,
57
+ f1: (a: A) => B,
58
+ f2: (b: B) => C,
59
+ f3: (c: C) => D,
60
+ f4: (d: D) => E,
61
+ ): E
62
+ export function pipe<A, B, C, D, E, F>(
63
+ source: A,
64
+ f1: (a: A) => B,
65
+ f2: (b: B) => C,
66
+ f3: (c: C) => D,
67
+ f4: (d: D) => E,
68
+ f5: (e: E) => F,
69
+ ): F
55
70
  export function pipe(source: any, ...fns: Array<(v: any) => any>): any {
56
71
  if (isSignal(source)) {
57
72
  return computed(() => {
@@ -183,4 +183,31 @@ describe("collections — signal values (reactive)", () => {
183
183
  src.set({ x: 10 })
184
184
  expect(doubled()).toEqual({ x: 20 })
185
185
  })
186
+
187
+ it("mapValues with signal tracks key argument reactively", () => {
188
+ const src = signal<Record<string, number[]>>({
189
+ admin: [1, 2, 3],
190
+ viewer: [4, 5],
191
+ })
192
+ const counts = mapValues(src, (arr, key) => ({ role: key, count: arr.length }))
193
+ expect(counts()).toEqual({
194
+ admin: { role: "admin", count: 3 },
195
+ viewer: { role: "viewer", count: 2 },
196
+ })
197
+
198
+ src.set({ admin: [1], editor: [2, 3, 4, 5] })
199
+ expect(counts()).toEqual({
200
+ admin: { role: "admin", count: 1 },
201
+ editor: { role: "editor", count: 4 },
202
+ })
203
+ })
204
+
205
+ it("mapValues with signal handles empty record", () => {
206
+ const src = signal<Record<string, number>>({})
207
+ const doubled = mapValues(src, (v) => v * 2)
208
+ expect(doubled()).toEqual({})
209
+
210
+ src.set({ a: 5 })
211
+ expect(doubled()).toEqual({ a: 10 })
212
+ })
186
213
  })
@@ -48,4 +48,46 @@ describe("pipe — signal values", () => {
48
48
  )
49
49
  expect(topNames()).toEqual(["B", "A"])
50
50
  })
51
+
52
+ it("supports 4 transforms", () => {
53
+ const src = signal([10, 5, 20, 3, 15, 8])
54
+ const result = pipe(
55
+ src,
56
+ (arr) => arr.filter((n) => n > 5),
57
+ (arr) => arr.sort((a, b) => a - b),
58
+ (arr) => arr.slice(0, 3),
59
+ (arr) => arr.reduce((sum, n) => sum + n, 0),
60
+ )
61
+ // filter: [10, 20, 15, 8], sort: [8, 10, 15, 20], take 3: [8, 10, 15], sum: 33
62
+ expect(result()).toBe(33)
63
+
64
+ // Reactive: update source
65
+ src.set([100, 1, 50])
66
+ // filter: [100, 50], sort: [50, 100], take 3: [50, 100], sum: 150
67
+ expect(result()).toBe(150)
68
+ })
69
+
70
+ it("supports 5 transforms", () => {
71
+ const src = signal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
72
+ const result = pipe(
73
+ src,
74
+ (arr) => arr.filter((n) => n % 2 === 0), // [2, 4, 6, 8, 10]
75
+ (arr) => arr.map((n) => n * 10), // [20, 40, 60, 80, 100]
76
+ (arr) => arr.slice(1, 4), // [40, 60, 80]
77
+ (arr) => arr.reduce((sum, n) => sum + n, 0), // 180
78
+ (n) => `Total: ${n}`,
79
+ )
80
+ expect(result()).toBe("Total: 180")
81
+ })
82
+
83
+ it("4+ transforms with plain values (non-signal)", () => {
84
+ const result = pipe(
85
+ [5, 3, 8, 1, 9, 2],
86
+ (arr) => arr.filter((n) => n > 3),
87
+ (arr) => arr.sort((a, b) => b - a),
88
+ (arr) => arr.slice(0, 2),
89
+ (arr) => arr.join("-"),
90
+ )
91
+ expect(result).toBe("9-8")
92
+ })
51
93
  })
@@ -0,0 +1,109 @@
1
+ import { signal } from "@pyreon/reactivity"
2
+ import { describe, expect, it } from "vitest"
3
+ import { search } from "../search"
4
+
5
+ type User = { id: number; name: string; email: string }
6
+
7
+ const users: User[] = [
8
+ { id: 1, name: "Alice", email: "alice@example.com" },
9
+ { id: 2, name: "Bob", email: "bob@test.com" },
10
+ { id: 3, name: "Charlie", email: "charlie@example.com" },
11
+ { id: 4, name: "Diana", email: "diana@test.com" },
12
+ ]
13
+
14
+ describe("search — plain values", () => {
15
+ it("returns all items when query is empty", () => {
16
+ const result = search(users, "", ["name"])
17
+ expect(result).toHaveLength(4)
18
+ })
19
+
20
+ it("filters by single key", () => {
21
+ const result = search(users, "alice", ["name"])
22
+ expect(result).toHaveLength(1)
23
+ expect(result[0]!.name).toBe("Alice")
24
+ })
25
+
26
+ it("filters across multiple keys", () => {
27
+ const result = search(users, "example", ["name", "email"])
28
+ expect(result).toHaveLength(2)
29
+ expect(result.map((u: (typeof users)[number]) => u.name)).toEqual(["Alice", "Charlie"])
30
+ })
31
+
32
+ it("is case-insensitive", () => {
33
+ const result = search(users, "BOB", ["name"])
34
+ expect(result).toHaveLength(1)
35
+ expect(result[0]!.name).toBe("Bob")
36
+ })
37
+
38
+ it("trims whitespace from query", () => {
39
+ const result = search(users, " alice ", ["name"])
40
+ expect(result).toHaveLength(1)
41
+ })
42
+
43
+ it("returns empty array when no matches", () => {
44
+ const result = search(users, "zzz", ["name", "email"])
45
+ expect(result).toHaveLength(0)
46
+ })
47
+
48
+ it("only matches string values (skips non-string fields)", () => {
49
+ // id is a number — should not be matched
50
+ const result = search(users, "1", ["id" as keyof User, "name"])
51
+ expect(result).toHaveLength(0)
52
+ })
53
+ })
54
+
55
+ describe("search — signal source (reactive)", () => {
56
+ it("returns computed when source is a signal", () => {
57
+ const src = signal(users)
58
+ const result = search(src, "alice", ["name"])
59
+ expect(typeof result).toBe("function")
60
+ expect(result()).toHaveLength(1)
61
+ })
62
+
63
+ it("reacts to source changes", () => {
64
+ const src = signal(users)
65
+ const result = search(src, "test", ["email"])
66
+ expect(result()).toHaveLength(2) // bob + diana
67
+
68
+ src.set([...users, { id: 5, name: "Eve", email: "eve@test.com" }])
69
+ expect(result()).toHaveLength(3)
70
+ })
71
+
72
+ it("returns computed when query is a signal", () => {
73
+ const query = signal("")
74
+ const result = search(users, query, ["name"])
75
+
76
+ expect(typeof result).toBe("function")
77
+ expect(result()).toHaveLength(4) // empty query returns all
78
+
79
+ query.set("ali")
80
+ expect(result()).toHaveLength(1)
81
+
82
+ query.set("a") // Alice, Charlie, Diana
83
+ expect(result()).toHaveLength(3)
84
+ })
85
+
86
+ it("reacts to both source and query signal changes", () => {
87
+ const src = signal(users)
88
+ const query = signal("")
89
+ const result = search(src, query, ["name"])
90
+
91
+ expect(result()).toHaveLength(4)
92
+
93
+ query.set("bob")
94
+ expect(result()).toHaveLength(1)
95
+
96
+ // Remove Bob from source
97
+ src.set(users.filter((u) => u.name !== "Bob"))
98
+ expect(result()).toHaveLength(0)
99
+
100
+ query.set("")
101
+ expect(result()).toHaveLength(3) // all remaining users
102
+ })
103
+
104
+ it("returns empty when signal query matches nothing", () => {
105
+ const query = signal("nonexistent")
106
+ const result = search(users, query, ["name", "email"])
107
+ expect(result()).toHaveLength(0)
108
+ })
109
+ })
@@ -25,6 +25,51 @@ describe("debounce", () => {
25
25
  vi.advanceTimersByTime(200)
26
26
  expect(debounced()).toBe(1) // still 1, not 2
27
27
  })
28
+
29
+ it("dispose() clears pending timer so debounced value stays frozen", () => {
30
+ vi.useFakeTimers()
31
+ const src = signal("a")
32
+ const debounced = debounce(src, 200)
33
+ expect(debounced()).toBe("a")
34
+
35
+ // Start a debounce cycle
36
+ src.set("b")
37
+ vi.advanceTimersByTime(50) // not yet debounced
38
+
39
+ // Dispose mid-cycle — pending timer should be cleared
40
+ debounced.dispose()
41
+
42
+ // Advance well past the debounce window
43
+ vi.advanceTimersByTime(500)
44
+ // Value should remain "a" — the pending "b" was cancelled
45
+ expect(debounced()).toBe("a")
46
+ })
47
+
48
+ it("debounces rapid updates to only emit the latest", () => {
49
+ vi.useFakeTimers()
50
+ const src = signal(0)
51
+ const debounced = debounce(src, 100)
52
+
53
+ src.set(1)
54
+ src.set(2)
55
+ src.set(3)
56
+
57
+ // None should have propagated yet
58
+ expect(debounced()).toBe(0)
59
+
60
+ vi.advanceTimersByTime(100)
61
+ // Only the last value should propagate
62
+ expect(debounced()).toBe(3)
63
+ })
64
+
65
+ it("multiple dispose calls do not throw", () => {
66
+ vi.useFakeTimers()
67
+ const src = signal(0)
68
+ const debounced = debounce(src, 100)
69
+
70
+ debounced.dispose()
71
+ expect(() => debounced.dispose()).not.toThrow()
72
+ })
28
73
  })
29
74
 
30
75
  describe("throttle", () => {
@@ -52,4 +97,67 @@ describe("throttle", () => {
52
97
  vi.advanceTimersByTime(200)
53
98
  expect(throttled()).toBe(1) // still 1, not 2
54
99
  })
100
+
101
+ it("dispose() clears pending trailing timer", () => {
102
+ vi.useFakeTimers()
103
+ const src = signal(0)
104
+ const throttled = throttle(src, 200)
105
+ expect(throttled()).toBe(0)
106
+
107
+ // First change emits immediately (elapsed >= ms from init)
108
+ vi.advanceTimersByTime(200)
109
+ src.set(1)
110
+ expect(throttled()).toBe(1)
111
+
112
+ // Second rapid change — within throttle window, creates trailing timer
113
+ src.set(2)
114
+ expect(throttled()).toBe(1) // not yet
115
+
116
+ // Dispose before trailing timer fires
117
+ throttled.dispose()
118
+
119
+ vi.advanceTimersByTime(500)
120
+ expect(throttled()).toBe(1) // trailing update never fires
121
+ })
122
+
123
+ it("emits immediately on first change after window", () => {
124
+ vi.useFakeTimers()
125
+ const src = signal(0)
126
+ const throttled = throttle(src, 100)
127
+
128
+ // Wait for throttle window to pass
129
+ vi.advanceTimersByTime(100)
130
+
131
+ src.set(42)
132
+ // Should emit immediately since enough time passed
133
+ expect(throttled()).toBe(42)
134
+ })
135
+
136
+ it("trailing timer fires the latest value after throttle window", () => {
137
+ vi.useFakeTimers()
138
+ const src = signal(0)
139
+ const throttled = throttle(src, 100)
140
+ expect(throttled()).toBe(0)
141
+
142
+ vi.advanceTimersByTime(100)
143
+ src.set(1) // emits immediately
144
+ expect(throttled()).toBe(1)
145
+
146
+ // Rapid changes within window
147
+ src.set(2)
148
+ src.set(3)
149
+ expect(throttled()).toBe(1) // still 1
150
+
151
+ vi.advanceTimersByTime(100) // trailing timer fires
152
+ expect(throttled()).toBe(3) // latest value
153
+ })
154
+
155
+ it("multiple dispose calls do not throw", () => {
156
+ vi.useFakeTimers()
157
+ const src = signal(0)
158
+ const throttled = throttle(src, 100)
159
+
160
+ throttled.dispose()
161
+ expect(() => throttled.dispose()).not.toThrow()
162
+ })
55
163
  })