@pyreon/rx 0.11.3 → 0.11.5
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 +1 -1
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/pipe.ts +15 -0
- package/src/tests/collections.test.ts +27 -0
- package/src/tests/pipe.test.ts +42 -0
- package/src/tests/search.test.ts +109 -0
- package/src/tests/timing.test.ts +108 -0
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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"}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -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
|
/**
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -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
|
+
"version": "0.11.5",
|
|
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.
|
|
40
|
+
"@pyreon/reactivity": "^0.11.5"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@pyreon/typescript": "^0.11.
|
|
43
|
+
"@pyreon/typescript": "^0.11.5"
|
|
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
|
})
|
package/src/tests/pipe.test.ts
CHANGED
|
@@ -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
|
+
})
|
package/src/tests/timing.test.ts
CHANGED
|
@@ -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
|
})
|