@pyreon/rx 0.11.0

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 ADDED
@@ -0,0 +1,343 @@
1
+ import { computed, effect, signal } from "@pyreon/reactivity";
2
+
3
+ //#region src/types.ts
4
+ /** Resolve a key extractor to a function. */
5
+ function resolveKey(key) {
6
+ return typeof key === "function" ? key : (item) => String(item[key]);
7
+ }
8
+ /** Check if a value is a signal (callable function with .set or .peek). */
9
+ function isSignal(value) {
10
+ return typeof value === "function";
11
+ }
12
+
13
+ //#endregion
14
+ //#region src/aggregation.ts
15
+ function reactive$1(source, fn) {
16
+ if (isSignal(source)) return computed(() => fn(source()));
17
+ return fn(source);
18
+ }
19
+ function count(source) {
20
+ return reactive$1(source, (arr) => arr.length);
21
+ }
22
+ function sum(source, key) {
23
+ const getVal = key ? resolveKey(key) : (item) => item;
24
+ return reactive$1(source, (arr) => arr.reduce((acc, item) => acc + Number(getVal(item)), 0));
25
+ }
26
+ function min(source, key) {
27
+ const getVal = key ? resolveKey(key) : (item) => item;
28
+ return reactive$1(source, (arr) => {
29
+ if (arr.length === 0) return void 0;
30
+ let result = arr[0];
31
+ let minVal = Number(getVal(result));
32
+ for (let i = 1; i < arr.length; i++) {
33
+ const val = Number(getVal(arr[i]));
34
+ if (val < minVal) {
35
+ minVal = val;
36
+ result = arr[i];
37
+ }
38
+ }
39
+ return result;
40
+ });
41
+ }
42
+ function max(source, key) {
43
+ const getVal = key ? resolveKey(key) : (item) => item;
44
+ return reactive$1(source, (arr) => {
45
+ if (arr.length === 0) return void 0;
46
+ let result = arr[0];
47
+ let maxVal = Number(getVal(result));
48
+ for (let i = 1; i < arr.length; i++) {
49
+ const val = Number(getVal(arr[i]));
50
+ if (val > maxVal) {
51
+ maxVal = val;
52
+ result = arr[i];
53
+ }
54
+ }
55
+ return result;
56
+ });
57
+ }
58
+ function average(source, key) {
59
+ const getVal = key ? resolveKey(key) : (item) => item;
60
+ return reactive$1(source, (arr) => {
61
+ if (arr.length === 0) return 0;
62
+ return arr.reduce((acc, item) => acc + Number(getVal(item)), 0) / arr.length;
63
+ });
64
+ }
65
+
66
+ //#endregion
67
+ //#region src/collections.ts
68
+ function reactive(source, fn) {
69
+ if (isSignal(source)) return computed(() => fn(source()));
70
+ return fn(source);
71
+ }
72
+ function filter(source, predicate) {
73
+ return reactive(source, (arr) => arr.filter(predicate));
74
+ }
75
+ function map(source, fn) {
76
+ return reactive(source, (arr) => arr.map(fn));
77
+ }
78
+ function sortBy(source, key) {
79
+ const getKey = resolveKey(key);
80
+ return reactive(source, (arr) => [...arr].sort((a, b) => {
81
+ const ka = getKey(a);
82
+ const kb = getKey(b);
83
+ return ka < kb ? -1 : ka > kb ? 1 : 0;
84
+ }));
85
+ }
86
+ function groupBy(source, key) {
87
+ const getKey = resolveKey(key);
88
+ return reactive(source, (arr) => {
89
+ const result = {};
90
+ for (const item of arr) {
91
+ const k = String(getKey(item));
92
+ let group = result[k];
93
+ if (!group) {
94
+ group = [];
95
+ result[k] = group;
96
+ }
97
+ group.push(item);
98
+ }
99
+ return result;
100
+ });
101
+ }
102
+ function keyBy(source, key) {
103
+ const getKey = resolveKey(key);
104
+ return reactive(source, (arr) => {
105
+ const result = {};
106
+ for (const item of arr) result[String(getKey(item))] = item;
107
+ return result;
108
+ });
109
+ }
110
+ function uniqBy(source, key) {
111
+ const getKey = resolveKey(key);
112
+ return reactive(source, (arr) => {
113
+ const seen = /* @__PURE__ */ new Set();
114
+ return arr.filter((item) => {
115
+ const k = getKey(item);
116
+ if (seen.has(k)) return false;
117
+ seen.add(k);
118
+ return true;
119
+ });
120
+ });
121
+ }
122
+ function take(source, n) {
123
+ return reactive(source, (arr) => arr.slice(0, n));
124
+ }
125
+ function chunk(source, size) {
126
+ return reactive(source, (arr) => {
127
+ const result = [];
128
+ for (let i = 0; i < arr.length; i += size) result.push(arr.slice(i, i + size));
129
+ return result;
130
+ });
131
+ }
132
+ function flatten(source) {
133
+ return reactive(source, (arr) => arr.flat());
134
+ }
135
+ function find(source, predicate) {
136
+ return reactive(source, (arr) => arr.find(predicate));
137
+ }
138
+ function skip(source, n) {
139
+ return reactive(source, (arr) => arr.slice(n));
140
+ }
141
+ function last(source, n) {
142
+ return reactive(source, (arr) => arr.slice(-n));
143
+ }
144
+ function mapValues(source, fn) {
145
+ return reactive(source, (obj) => {
146
+ const result = {};
147
+ for (const key of Object.keys(obj)) result[key] = fn(obj[key], key);
148
+ return result;
149
+ });
150
+ }
151
+
152
+ //#endregion
153
+ //#region src/operators.ts
154
+ /**
155
+ * Distinct — skip consecutive duplicate values from a signal.
156
+ * Uses `Object.is` by default, or a custom equality function.
157
+ */
158
+ function distinct(source, equals = Object.is) {
159
+ const result = signal(source());
160
+ effect(() => {
161
+ const val = source();
162
+ if (!equals(val, result.peek())) result.set(val);
163
+ });
164
+ return result;
165
+ }
166
+ /**
167
+ * Scan — running accumulator over signal changes.
168
+ * Like Array.reduce but emits the accumulated value on each source change.
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * const clicks = signal(0)
173
+ * const total = rx.scan(clicks, (acc, val) => acc + val, 0)
174
+ * // clicks: 1 → total: 1
175
+ * // clicks: 3 → total: 4
176
+ * // clicks: 2 → total: 6
177
+ * ```
178
+ */
179
+ function scan(source, reducer, initial) {
180
+ const result = signal(initial);
181
+ effect(() => {
182
+ const val = source();
183
+ result.set(reducer(result.peek(), val));
184
+ });
185
+ return result;
186
+ }
187
+ function combine(...args) {
188
+ const fn = args[args.length - 1];
189
+ const sources = args.slice(0, -1);
190
+ return computed(() => fn(...sources.map((s) => s())));
191
+ }
192
+
193
+ //#endregion
194
+ //#region src/pipe.ts
195
+ function pipe(source, ...fns) {
196
+ if (isSignal(source)) return computed(() => {
197
+ let val = source();
198
+ for (const fn of fns) val = fn(val);
199
+ return val;
200
+ });
201
+ let val = source;
202
+ for (const fn of fns) val = fn(val);
203
+ return val;
204
+ }
205
+
206
+ //#endregion
207
+ //#region src/search.ts
208
+ /**
209
+ * Search items by substring matching across specified keys.
210
+ * Case-insensitive. Signal-aware — reactive when either source or query is a signal.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * const results = rx.search(users, searchQuery, ["name", "email"])
215
+ * ```
216
+ */
217
+ function search(source, query, keys) {
218
+ const isReactive = isSignal(source) || isSignal(query);
219
+ const doSearch = () => {
220
+ const arr = isSignal(source) ? source() : source;
221
+ const q = (isSignal(query) ? query() : query).toLowerCase().trim();
222
+ if (!q) return arr;
223
+ return arr.filter((item) => keys.some((key) => {
224
+ const val = item[key];
225
+ return typeof val === "string" && val.toLowerCase().includes(q);
226
+ }));
227
+ };
228
+ return isReactive ? computed(doSearch) : doSearch();
229
+ }
230
+
231
+ //#endregion
232
+ //#region src/timing.ts
233
+ /**
234
+ * Debounce a signal — emits the latest value after `ms` of silence.
235
+ * Returns a new signal that updates only after the source stops changing.
236
+ *
237
+ * Works both inside and outside component context.
238
+ * The returned signal has a `.dispose()` method to stop tracking.
239
+ */
240
+ function debounce(source, ms) {
241
+ const debounced = signal(source());
242
+ let timer;
243
+ const fx = effect(() => {
244
+ const val = source();
245
+ if (timer) clearTimeout(timer);
246
+ timer = setTimeout(() => debounced.set(val), ms);
247
+ });
248
+ const dispose = () => {
249
+ if (timer) clearTimeout(timer);
250
+ fx.dispose();
251
+ };
252
+ return Object.assign(debounced, { dispose });
253
+ }
254
+ /**
255
+ * Throttle a signal — emits at most once every `ms` milliseconds.
256
+ * Immediately emits on first change, then waits for the interval.
257
+ *
258
+ * Works both inside and outside component context.
259
+ * The returned signal has a `.dispose()` method to stop tracking.
260
+ */
261
+ function throttle(source, ms) {
262
+ const throttled = signal(source());
263
+ let lastEmit = 0;
264
+ let timer;
265
+ const fx = effect(() => {
266
+ const val = source();
267
+ const now = Date.now();
268
+ const elapsed = now - lastEmit;
269
+ if (elapsed >= ms) {
270
+ throttled.set(val);
271
+ lastEmit = now;
272
+ } else {
273
+ if (timer) clearTimeout(timer);
274
+ timer = setTimeout(() => {
275
+ throttled.set(val);
276
+ lastEmit = Date.now();
277
+ }, ms - elapsed);
278
+ }
279
+ });
280
+ const dispose = () => {
281
+ if (timer) clearTimeout(timer);
282
+ fx.dispose();
283
+ };
284
+ return Object.assign(throttled, { dispose });
285
+ }
286
+
287
+ //#endregion
288
+ //#region src/index.ts
289
+ /**
290
+ * Signal-aware reactive transforms.
291
+ *
292
+ * Every function is overloaded:
293
+ * - `Signal<T[]>` input → returns `Computed<R>` (reactive)
294
+ * - `T[]` input → returns `R` (static)
295
+ *
296
+ * @example
297
+ * ```ts
298
+ * import { rx } from "@pyreon/rx"
299
+ *
300
+ * const users = signal<User[]>([])
301
+ * const active = rx.filter(users, u => u.active) // Computed<User[]>
302
+ * const sorted = rx.sortBy(active, "name") // Computed<User[]>
303
+ * const top10 = rx.take(sorted, 10) // Computed<User[]>
304
+ *
305
+ * // Or pipe:
306
+ * const result = rx.pipe(users,
307
+ * items => items.filter(u => u.active),
308
+ * items => items.sort((a, b) => a.name.localeCompare(b.name)),
309
+ * items => items.slice(0, 10),
310
+ * )
311
+ * ```
312
+ */
313
+ const rx = {
314
+ filter,
315
+ map,
316
+ sortBy,
317
+ groupBy,
318
+ keyBy,
319
+ uniqBy,
320
+ take,
321
+ skip,
322
+ last,
323
+ chunk,
324
+ flatten,
325
+ find,
326
+ mapValues,
327
+ count,
328
+ sum,
329
+ min,
330
+ max,
331
+ average,
332
+ distinct,
333
+ scan,
334
+ combine,
335
+ debounce,
336
+ throttle,
337
+ search,
338
+ pipe
339
+ };
340
+
341
+ //#endregion
342
+ export { average, chunk, combine, count, debounce, distinct, filter, find, flatten, groupBy, keyBy, last, map, mapValues, max, min, pipe, rx, scan, search, skip, sortBy, sum, take, throttle, uniqBy };
343
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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":";;;;AAaA,SAAgB,WAAc,KAA6C;AACzE,QAAO,OAAO,QAAQ,aAAa,OAAO,SAAY,OAAO,KAAK,KAAK;;;AAIzE,SAAgB,SAAY,OAA4C;AACtE,QAAO,OAAO,UAAU;;;;;ACf1B,SAASA,WAAoB,QAAa,IAA6B;AACrE,KAAI,SAAS,OAAO,CAAE,QAAO,eAAe,GAAI,QAAgC,CAAC,CAAC;AAClF,QAAO,GAAG,OAAO;;AAMnB,SAAgB,MAAS,QAAwC;AAC/D,QAAOA,WAAS,SAAS,QAAa,IAAI,OAAO;;AASnD,SAAgB,IAAO,QAAmC,KAAqB;CAC7E,MAAM,SAAS,MAAM,WAAW,IAAI,IAAI,SAAY;AACpD,QAAOA,WAAS,SAAS,QAAa,IAAI,QAAQ,KAAK,SAAS,MAAM,OAAO,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC;;AASjG,SAAgB,IAAO,QAAmC,KAAqB;CAC7E,MAAM,SAAS,MAAM,WAAW,IAAI,IAAI,SAAY;AACpD,QAAOA,WAAS,SAAS,QAAa;AACpC,MAAI,IAAI,WAAW,EAAG,QAAO;EAC7B,IAAI,SAAS,IAAI;EACjB,IAAI,SAAS,OAAO,OAAO,OAAO,CAAC;AACnC,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;GACnC,MAAM,MAAM,OAAO,OAAO,IAAI,GAAQ,CAAC;AACvC,OAAI,MAAM,QAAQ;AAChB,aAAS;AACT,aAAS,IAAI;;;AAGjB,SAAO;GACP;;AASJ,SAAgB,IAAO,QAAmC,KAAqB;CAC7E,MAAM,SAAS,MAAM,WAAW,IAAI,IAAI,SAAY;AACpD,QAAOA,WAAS,SAAS,QAAa;AACpC,MAAI,IAAI,WAAW,EAAG,QAAO;EAC7B,IAAI,SAAS,IAAI;EACjB,IAAI,SAAS,OAAO,OAAO,OAAO,CAAC;AACnC,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;GACnC,MAAM,MAAM,OAAO,OAAO,IAAI,GAAQ,CAAC;AACvC,OAAI,MAAM,QAAQ;AAChB,aAAS;AACT,aAAS,IAAI;;;AAGjB,SAAO;GACP;;AASJ,SAAgB,QAAW,QAAmC,KAAqB;CACjF,MAAM,SAAS,MAAM,WAAW,IAAI,IAAI,SAAY;AACpD,QAAOA,WAAS,SAAS,QAAa;AACpC,MAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,SAAO,IAAI,QAAQ,KAAK,SAAS,MAAM,OAAO,OAAO,KAAK,CAAC,EAAE,EAAE,GAAG,IAAI;GACtE;;;;;AC9EJ,SAAS,SACP,QACA,IAC4E;AAC5E,KAAI,SAAS,OAAO,CAClB,QAAO,eAAe,GAAI,QAAgC,CAAC,CAAC;AAE9D,QAAO,GAAG,OAAO;;AAWnB,SAAgB,OACd,QACA,WACK;AACL,QAAO,SAAS,SAAS,QAAa,IAAI,OAAO,UAAU,CAAC;;AAS9D,SAAgB,IACd,QACA,IACK;AACL,QAAO,SAAS,SAAS,QAAa,IAAI,IAAI,GAAG,CAAC;;AASpD,SAAgB,OAAU,QAAmC,KAAoB;CAC/E,MAAM,SAAS,WAAW,IAAI;AAC9B,QAAO,SAAS,SAAS,QACvB,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,MAAM;EACtB,MAAM,KAAK,OAAO,EAAE;EACpB,MAAM,KAAK,OAAO,EAAE;AACpB,SAAO,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI;GACpC,CACH;;AASH,SAAgB,QAAW,QAAmC,KAAoB;CAChF,MAAM,SAAS,WAAW,IAAI;AAC9B,QAAO,SAAS,SAAS,QAAa;EACpC,MAAM,SAA8B,EAAE;AACtC,OAAK,MAAM,QAAQ,KAAK;GACtB,MAAM,IAAI,OAAO,OAAO,KAAK,CAAC;GAC9B,IAAI,QAAQ,OAAO;AACnB,OAAI,CAAC,OAAO;AACV,YAAQ,EAAE;AACV,WAAO,KAAK;;AAEd,SAAM,KAAK,KAAK;;AAElB,SAAO;GACP;;AASJ,SAAgB,MAAS,QAAmC,KAAoB;CAC9E,MAAM,SAAS,WAAW,IAAI;AAC9B,QAAO,SAAS,SAAS,QAAa;EACpC,MAAM,SAA4B,EAAE;AACpC,OAAK,MAAM,QAAQ,IAAK,QAAO,OAAO,OAAO,KAAK,CAAC,IAAI;AACvD,SAAO;GACP;;AASJ,SAAgB,OAAU,QAAmC,KAAoB;CAC/E,MAAM,SAAS,WAAW,IAAI;AAC9B,QAAO,SAAS,SAAS,QAAa;EACpC,MAAM,uBAAO,IAAI,KAAsB;AACvC,SAAO,IAAI,QAAQ,SAAS;GAC1B,MAAM,IAAI,OAAO,KAAK;AACtB,OAAI,KAAK,IAAI,EAAE,CAAE,QAAO;AACxB,QAAK,IAAI,EAAE;AACX,UAAO;IACP;GACF;;AAMJ,SAAgB,KAAQ,QAAmC,GAAgB;AACzE,QAAO,SAAS,SAAS,QAAa,IAAI,MAAM,GAAG,EAAE,CAAC;;AASxD,SAAgB,MAAS,QAAmC,MAAmB;AAC7E,QAAO,SAAS,SAAS,QAAa;EACpC,MAAM,SAAgB,EAAE;AACxB,OAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,KAAM,QAAO,KAAK,IAAI,MAAM,GAAG,IAAI,KAAK,CAAC;AAC9E,SAAO;GACP;;AAMJ,SAAgB,QAAW,QAA4C;AACrE,QAAO,SAAS,SAAS,QAAe,IAAI,MAAM,CAAC;;AASrD,SAAgB,KAAQ,QAAmC,WAAsC;AAC/F,QAAO,SAAS,SAAS,QAAa,IAAI,KAAK,UAAU,CAAC;;AAM5D,SAAgB,KAAQ,QAAmC,GAAgB;AACzE,QAAO,SAAS,SAAS,QAAa,IAAI,MAAM,EAAE,CAAC;;AAMrD,SAAgB,KAAQ,QAAmC,GAAgB;AACzE,QAAO,SAAS,SAAS,QAAa,IAAI,MAAM,CAAC,EAAE,CAAC;;AAYtD,SAAgB,UACd,QACA,IACK;AACL,QAAO,SAAS,SAAS,QAA2B;EAClD,MAAM,SAA4B,EAAE;AACpC,OAAK,MAAM,OAAO,OAAO,KAAK,IAAI,CAAE,QAAO,OAAO,GAAG,IAAI,MAAW,IAAI;AACxE,SAAO;GACP;;;;;;;;;ACpLJ,SAAgB,SACd,QACA,SAAkC,OAAO,IACtB;CACnB,MAAM,SAAS,OAAO,QAAQ,CAAC;AAE/B,cAAa;EACX,MAAM,MAAM,QAAQ;AACpB,MAAI,CAAC,OAAO,KAAK,OAAO,MAAM,CAAC,CAC7B,QAAO,IAAI,IAAI;GAEjB;AAEF,QAAO;;;;;;;;;;;;;;;AAgBT,SAAgB,KACd,QACA,SACA,SACmB;CACnB,MAAM,SAAS,OAAO,QAAQ;AAE9B,cAAa;EACX,MAAM,MAAM,QAAQ;AACpB,SAAO,IAAI,QAAQ,OAAO,MAAM,EAAE,IAAI,CAAC;GACvC;AAEF,QAAO;;AAsBT,SAAgB,QAAQ,GAAG,MAAkB;CAC3C,MAAM,KAAK,KAAK,KAAK,SAAS;CAC9B,MAAM,UAAU,KAAK,MAAM,GAAG,GAAG;AACjC,QAAO,eAAe,GAAG,GAAG,QAAQ,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC;;;;;ACnBvD,SAAgB,KAAK,QAAa,GAAG,KAAkC;AACrE,KAAI,SAAS,OAAO,CAClB,QAAO,eAAe;EACpB,IAAI,MAAO,QAAgC;AAC3C,OAAK,MAAM,MAAM,IAAK,OAAM,GAAG,IAAI;AACnC,SAAO;GACP;CAEJ,IAAI,MAAM;AACV,MAAK,MAAM,MAAM,IAAK,OAAM,GAAG,IAAI;AACnC,QAAO;;;;;;;;;;;;;;ACnDT,SAAgB,OACd,QACA,OACA,MACK;CACL,MAAM,aAAa,SAAS,OAAO,IAAI,SAAS,MAAM;CAEtD,MAAM,iBAAsB;EAC1B,MAAM,MAAM,SAAS,OAAO,GAAI,QAAgC,GAAG;EACnE,MAAM,KAAK,SAAS,MAAM,GAAI,OAAkC,GAAG,OAAO,aAAa,CAAC,MAAM;AAC9F,MAAI,CAAC,EAAG,QAAO;AACf,SAAO,IAAI,QAAQ,SACjB,KAAK,MAAM,QAAQ;GACjB,MAAM,MAAM,KAAK;AACjB,UAAO,OAAO,QAAQ,YAAY,IAAI,aAAa,CAAC,SAAS,EAAE;IAC/D,CACH;;AAGH,QAAO,aAAa,SAAS,SAAS,GAAG,UAAU;;;;;;;;;;;;ACtBrD,SAAgB,SACd,QACA,IAC6C;CAC7C,MAAM,YAAY,OAAO,QAAQ,CAAC;CAClC,IAAI;CAEJ,MAAM,KAAK,aAAa;EACtB,MAAM,MAAM,QAAQ;AACpB,MAAI,MAAO,cAAa,MAAM;AAC9B,UAAQ,iBAAiB,UAAU,IAAI,IAAI,EAAE,GAAG;GAChD;CAEF,MAAM,gBAAgB;AACpB,MAAI,MAAO,cAAa,MAAM;AAC9B,KAAG,SAAS;;AAGd,QAAO,OAAO,OAAO,WAAgC,EAAE,SAAS,CAAC;;;;;;;;;AAUnE,SAAgB,SACd,QACA,IAC6C;CAC7C,MAAM,YAAY,OAAO,QAAQ,CAAC;CAClC,IAAI,WAAW;CACf,IAAI;CAEJ,MAAM,KAAK,aAAa;EACtB,MAAM,MAAM,QAAQ;EACpB,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,UAAU,MAAM;AAEtB,MAAI,WAAW,IAAI;AACjB,aAAU,IAAI,IAAI;AAClB,cAAW;SACN;AACL,OAAI,MAAO,cAAa,MAAM;AAC9B,WAAQ,iBAAiB;AACvB,cAAU,IAAI,IAAI;AAClB,eAAW,KAAK,KAAK;MACpB,KAAK,QAAQ;;GAElB;CAEF,MAAM,gBAAgB;AACpB,MAAI,MAAO,cAAa,MAAM;AAC9B,KAAG,SAAS;;AAGd,QAAO,OAAO,OAAO,WAAgC,EAAE,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrBnE,MAAa,KAAK;CAEhB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CAGA;CACA;CAGA;CAGA;CACD"}
@@ -0,0 +1,214 @@
1
+ import { computed } from "@pyreon/reactivity";
2
+
3
+ //#region src/types.d.ts
4
+ /** A readable signal — any callable that returns a value and tracks subscribers. */
5
+ type ReadableSignal<T> = (() => T) & {
6
+ peek?: () => T;
7
+ };
8
+ /** Key extractor — string key name or function. */
9
+ type KeyOf<T> = keyof T | ((item: T) => string | number);
10
+ //#endregion
11
+ //#region src/aggregation.d.ts
12
+ /** Count items in collection. */
13
+ declare function count<T>(source: ReadableSignal<T[]>): ReturnType<typeof computed<number>>;
14
+ declare function count<T>(source: T[]): number;
15
+ /** Sum numeric values. Optionally by key. */
16
+ declare function sum<T>(source: ReadableSignal<T[]>, key?: KeyOf<T>): ReturnType<typeof computed<number>>;
17
+ declare function sum<T>(source: T[], key?: KeyOf<T>): number;
18
+ /** Find minimum item. Optionally by key. */
19
+ declare function min<T>(source: ReadableSignal<T[]>, key?: KeyOf<T>): ReturnType<typeof computed<T | undefined>>;
20
+ declare function min<T>(source: T[], key?: KeyOf<T>): T | undefined;
21
+ /** Find maximum item. Optionally by key. */
22
+ declare function max<T>(source: ReadableSignal<T[]>, key?: KeyOf<T>): ReturnType<typeof computed<T | undefined>>;
23
+ declare function max<T>(source: T[], key?: KeyOf<T>): T | undefined;
24
+ /** Average of numeric values. Optionally by key. */
25
+ declare function average<T>(source: ReadableSignal<T[]>, key?: KeyOf<T>): ReturnType<typeof computed<number>>;
26
+ declare function average<T>(source: T[], key?: KeyOf<T>): number;
27
+ //#endregion
28
+ //#region src/collections.d.ts
29
+ /** Filter items by predicate. Signal in → Computed out. */
30
+ declare function filter<T>(source: ReadableSignal<T[]>, predicate: (item: T, index: number) => boolean): ReturnType<typeof computed<T[]>>;
31
+ declare function filter<T>(source: T[], predicate: (item: T, index: number) => boolean): T[];
32
+ /** Map items to a new type. */
33
+ declare function map<T, U>(source: ReadableSignal<T[]>, fn: (item: T, index: number) => U): ReturnType<typeof computed<U[]>>;
34
+ declare function map<T, U>(source: T[], fn: (item: T, index: number) => U): U[];
35
+ /** Sort items by key or comparator. */
36
+ declare function sortBy<T>(source: ReadableSignal<T[]>, key: KeyOf<T>): ReturnType<typeof computed<T[]>>;
37
+ declare function sortBy<T>(source: T[], key: KeyOf<T>): T[];
38
+ /** Group items by key. Returns Record<string, T[]>. */
39
+ declare function groupBy<T>(source: ReadableSignal<T[]>, key: KeyOf<T>): ReturnType<typeof computed<Record<string, T[]>>>;
40
+ declare function groupBy<T>(source: T[], key: KeyOf<T>): Record<string, T[]>;
41
+ /** Index items by key. Returns Record<string, T> (last wins on collision). */
42
+ declare function keyBy<T>(source: ReadableSignal<T[]>, key: KeyOf<T>): ReturnType<typeof computed<Record<string, T>>>;
43
+ declare function keyBy<T>(source: T[], key: KeyOf<T>): Record<string, T>;
44
+ /** Deduplicate items by key. */
45
+ declare function uniqBy<T>(source: ReadableSignal<T[]>, key: KeyOf<T>): ReturnType<typeof computed<T[]>>;
46
+ declare function uniqBy<T>(source: T[], key: KeyOf<T>): T[];
47
+ /** Take the first n items. */
48
+ declare function take<T>(source: ReadableSignal<T[]>, n: number): ReturnType<typeof computed<T[]>>;
49
+ declare function take<T>(source: T[], n: number): T[];
50
+ /** Split into chunks of given size. */
51
+ declare function chunk<T>(source: ReadableSignal<T[]>, size: number): ReturnType<typeof computed<T[][]>>;
52
+ declare function chunk<T>(source: T[], size: number): T[][];
53
+ /** Flatten one level of nesting. */
54
+ declare function flatten<T>(source: ReadableSignal<T[][]>): ReturnType<typeof computed<T[]>>;
55
+ declare function flatten<T>(source: T[][]): T[];
56
+ /** Find the first item matching a predicate. */
57
+ declare function find<T>(source: ReadableSignal<T[]>, predicate: (item: T) => boolean): ReturnType<typeof computed<T | undefined>>;
58
+ declare function find<T>(source: T[], predicate: (item: T) => boolean): T | undefined;
59
+ /** Skip the first n items. */
60
+ declare function skip<T>(source: ReadableSignal<T[]>, n: number): ReturnType<typeof computed<T[]>>;
61
+ declare function skip<T>(source: T[], n: number): T[];
62
+ /** Take the last n items. */
63
+ declare function last<T>(source: ReadableSignal<T[]>, n: number): ReturnType<typeof computed<T[]>>;
64
+ declare function last<T>(source: T[], n: number): T[];
65
+ /** Map over values of a Record. Useful after groupBy. */
66
+ declare function mapValues<T, U>(source: ReadableSignal<Record<string, T>>, fn: (value: T, key: string) => U): ReturnType<typeof computed<Record<string, U>>>;
67
+ declare function mapValues<T, U>(source: Record<string, T>, fn: (value: T, key: string) => U): Record<string, U>;
68
+ //#endregion
69
+ //#region src/operators.d.ts
70
+ /**
71
+ * Distinct — skip consecutive duplicate values from a signal.
72
+ * Uses `Object.is` by default, or a custom equality function.
73
+ */
74
+ declare function distinct<T>(source: ReadableSignal<T>, equals?: (a: T, b: T) => boolean): ReadableSignal<T>;
75
+ /**
76
+ * Scan — running accumulator over signal changes.
77
+ * Like Array.reduce but emits the accumulated value on each source change.
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const clicks = signal(0)
82
+ * const total = rx.scan(clicks, (acc, val) => acc + val, 0)
83
+ * // clicks: 1 → total: 1
84
+ * // clicks: 3 → total: 4
85
+ * // clicks: 2 → total: 6
86
+ * ```
87
+ */
88
+ declare function scan<T, U>(source: ReadableSignal<T>, reducer: (acc: U, value: T) => U, initial: U): ReadableSignal<U>;
89
+ /**
90
+ * Combine multiple signals into a single computed value.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * const fullName = rx.combine(firstName, lastName, (f, l) => `${f} ${l}`)
95
+ * ```
96
+ */
97
+ declare function combine<A, B, R>(a: ReadableSignal<A>, b: ReadableSignal<B>, fn: (a: A, b: B) => R): ReturnType<typeof computed<R>>;
98
+ declare function combine<A, B, C, R>(a: ReadableSignal<A>, b: ReadableSignal<B>, c: ReadableSignal<C>, fn: (a: A, b: B, c: C) => R): ReturnType<typeof computed<R>>;
99
+ //#endregion
100
+ //#region src/pipe.d.ts
101
+ /**
102
+ * Pipe a signal through a chain of transform functions.
103
+ * Each transform receives the resolved value (not the signal) and returns a new value.
104
+ * The entire chain is wrapped in a single `computed()`.
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * const topRisks = rx.pipe(
109
+ * findings,
110
+ * (items) => items.filter(f => f.severity === "critical"),
111
+ * (items) => items.sort((a, b) => b.score - a.score),
112
+ * (items) => items.slice(0, 10),
113
+ * )
114
+ * // topRisks() → reactive, type-safe
115
+ * ```
116
+ */
117
+ declare function pipe<A, B>(source: ReadableSignal<A>, f1: (a: A) => B): ReturnType<typeof computed<B>>;
118
+ declare function pipe<A, B, C>(source: ReadableSignal<A>, f1: (a: A) => B, f2: (b: B) => C): ReturnType<typeof computed<C>>;
119
+ declare function pipe<A, B, C, D>(source: ReadableSignal<A>, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D): ReturnType<typeof computed<D>>;
120
+ declare function pipe<A, B, C, D, E>(source: ReadableSignal<A>, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D, f4: (d: D) => E): ReturnType<typeof computed<E>>;
121
+ declare function pipe<A, B, C, D, E, F>(source: ReadableSignal<A>, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D, f4: (d: D) => E, f5: (e: E) => F): ReturnType<typeof computed<F>>;
122
+ declare function pipe<A, B>(source: A, f1: (a: A) => B): B;
123
+ declare function pipe<A, B, C>(source: A, f1: (a: A) => B, f2: (b: B) => C): C;
124
+ declare function pipe<A, B, C, D>(source: A, f1: (a: A) => B, f2: (b: B) => C, f3: (c: C) => D): D;
125
+ //#endregion
126
+ //#region src/search.d.ts
127
+ /**
128
+ * Search items by substring matching across specified keys.
129
+ * Case-insensitive. Signal-aware — reactive when either source or query is a signal.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * const results = rx.search(users, searchQuery, ["name", "email"])
134
+ * ```
135
+ */
136
+ declare function search<T>(source: ReadableSignal<T[]> | T[], query: ReadableSignal<string> | string, keys: (keyof T)[]): any;
137
+ //#endregion
138
+ //#region src/timing.d.ts
139
+ /**
140
+ * Debounce a signal — emits the latest value after `ms` of silence.
141
+ * Returns a new signal that updates only after the source stops changing.
142
+ *
143
+ * Works both inside and outside component context.
144
+ * The returned signal has a `.dispose()` method to stop tracking.
145
+ */
146
+ declare function debounce<T>(source: ReadableSignal<T>, ms: number): ReadableSignal<T> & {
147
+ dispose: () => void;
148
+ };
149
+ /**
150
+ * Throttle a signal — emits at most once every `ms` milliseconds.
151
+ * Immediately emits on first change, then waits for the interval.
152
+ *
153
+ * Works both inside and outside component context.
154
+ * The returned signal has a `.dispose()` method to stop tracking.
155
+ */
156
+ declare function throttle<T>(source: ReadableSignal<T>, ms: number): ReadableSignal<T> & {
157
+ dispose: () => void;
158
+ };
159
+ //#endregion
160
+ //#region src/index.d.ts
161
+ /**
162
+ * Signal-aware reactive transforms.
163
+ *
164
+ * Every function is overloaded:
165
+ * - `Signal<T[]>` input → returns `Computed<R>` (reactive)
166
+ * - `T[]` input → returns `R` (static)
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * import { rx } from "@pyreon/rx"
171
+ *
172
+ * const users = signal<User[]>([])
173
+ * const active = rx.filter(users, u => u.active) // Computed<User[]>
174
+ * const sorted = rx.sortBy(active, "name") // Computed<User[]>
175
+ * const top10 = rx.take(sorted, 10) // Computed<User[]>
176
+ *
177
+ * // Or pipe:
178
+ * const result = rx.pipe(users,
179
+ * items => items.filter(u => u.active),
180
+ * items => items.sort((a, b) => a.name.localeCompare(b.name)),
181
+ * items => items.slice(0, 10),
182
+ * )
183
+ * ```
184
+ */
185
+ declare const rx: {
186
+ readonly filter: typeof filter;
187
+ readonly map: typeof map;
188
+ readonly sortBy: typeof sortBy;
189
+ readonly groupBy: typeof groupBy;
190
+ readonly keyBy: typeof keyBy;
191
+ readonly uniqBy: typeof uniqBy;
192
+ readonly take: typeof take;
193
+ readonly skip: typeof skip;
194
+ readonly last: typeof last;
195
+ readonly chunk: typeof chunk;
196
+ readonly flatten: typeof flatten;
197
+ readonly find: typeof find;
198
+ readonly mapValues: typeof mapValues;
199
+ readonly count: typeof count;
200
+ readonly sum: typeof sum;
201
+ readonly min: typeof min;
202
+ readonly max: typeof max;
203
+ readonly average: typeof average;
204
+ readonly distinct: typeof distinct;
205
+ readonly scan: typeof scan;
206
+ readonly combine: typeof combine;
207
+ readonly debounce: typeof debounce;
208
+ readonly throttle: typeof throttle;
209
+ readonly search: typeof search;
210
+ readonly pipe: typeof pipe;
211
+ };
212
+ //#endregion
213
+ export { type KeyOf, type ReadableSignal, average, chunk, combine, count, debounce, distinct, filter, find, flatten, groupBy, keyBy, last, map, mapValues, max, min, pipe, rx, scan, search, skip, sortBy, sum, take, throttle, uniqBy };
214
+ //# sourceMappingURL=index2.d.ts.map
@@ -0,0 +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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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@pyreon/rx",
3
+ "version": "0.11.0",
4
+ "description": "Signal-aware reactive transforms — filter, map, sort, group, pipe for Pyreon signals",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/pyreon/pyreon.git",
9
+ "directory": "packages/fundamentals/rx"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/pyreon/pyreon/issues"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "files": [
18
+ "lib",
19
+ "src",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "type": "module",
24
+ "sideEffects": false,
25
+ "exports": {
26
+ ".": {
27
+ "bun": "./src/index.ts",
28
+ "import": "./lib/index.js",
29
+ "types": "./lib/types/index.d.ts"
30
+ }
31
+ },
32
+ "scripts": {
33
+ "build": "vl_rolldown_build",
34
+ "dev": "vl_rolldown_build-watch",
35
+ "test": "vitest run",
36
+ "typecheck": "tsc --noEmit",
37
+ "lint": "biome check ."
38
+ },
39
+ "peerDependencies": {
40
+ "@pyreon/reactivity": "^0.11.0"
41
+ },
42
+ "devDependencies": {
43
+ "@pyreon/typescript": "^0.11.0"
44
+ }
45
+ }