@tidyjs/tidy 2.6.0 → 2.6.1

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.
@@ -0,0 +1,357 @@
1
+ # tidyjs Core API Reference
2
+
3
+ > AI-optimized reference for the core tidy verbs. These functions go directly inside `tidy()` pipelines.
4
+ > Import: `import { tidy, filter, mutate, transmute, arrange, asc, desc, fixedOrder, select, distinct, rename, when, debug, map } from '@tidyjs/tidy'`
5
+
6
+ ---
7
+
8
+ <!-- keywords: tidy, pipeline, pipe, chain, flow -->
9
+ ## tidy
10
+
11
+ Run a pipeline of tidy functions on a flat array of objects.
12
+
13
+ **Signature:** `tidy(items, ...fns) => T[]`
14
+
15
+ ### Parameters
16
+ - `items` -- the input array of objects (`T[]`). Must NOT be a function (throws if it is).
17
+ - `...fns` -- any number of tidy functions to apply sequentially. Output of each is input to the next. Falsy values are skipped.
18
+
19
+ ### Behavior
20
+ - Supports up to 10 chained functions with full TypeScript inference.
21
+ - If the last function is a `groupBy` with an export option, the return type matches the export shape (not necessarily an array).
22
+ - Common mistake: passing a function as the first argument instead of data throws `"You must supply the data as the first argument to tidy()"`.
23
+
24
+ ### Example
25
+ ```js
26
+ const data = [
27
+ { str: 'foo', value: 3 },
28
+ { str: 'bar', value: 1 },
29
+ { str: 'bar', value: 7 },
30
+ ];
31
+
32
+ tidy(data,
33
+ filter((d) => d.value > 1),
34
+ arrange('value')
35
+ )
36
+ // => [{ str: 'foo', value: 3 }, { str: 'bar', value: 7 }]
37
+ ```
38
+
39
+ ---
40
+
41
+ <!-- keywords: filter, where, predicate, filterFn, keep, remove rows -->
42
+ ## filter
43
+
44
+ Keep only items where the predicate returns true. Equivalent to `Array.prototype.filter`.
45
+
46
+ **Signature:** `filter(filterFn) => TidyFn<T>`
47
+ **Goes inside:** `tidy()` pipeline
48
+
49
+ ### Parameters
50
+ - `filterFn` -- `(item: T, index: number, array: T[]) => boolean`. Returns true to keep the item.
51
+
52
+ ### Example
53
+ ```js
54
+ const data = [{ value: 1 }, { value: 2 }, { value: 3 }];
55
+
56
+ tidy(data, filter((d) => d.value > 1))
57
+ // => [{ value: 2 }, { value: 3 }]
58
+ ```
59
+
60
+ ---
61
+
62
+ <!-- keywords: mutate, add column, modify, transform, mutateSpec, computed column -->
63
+ ## mutate
64
+
65
+ Add or modify columns on each item. Processes items one at a time.
66
+
67
+ **Signature:** `mutate(mutateSpec) => TidyFn<T, Mutated<T>>`
68
+ **Goes inside:** `tidy()` pipeline
69
+
70
+ ### Parameters
71
+ - `mutateSpec` -- an object `{ [key]: value | (item, index, array) => value }`.
72
+ - If value is a **function**, called as `(item: T, index: number, array: Iterable<T>) => any` per item.
73
+ - If value is a **non-function**, assigned directly to every item.
74
+ - Key order matters: later keys can reference values set by earlier keys in the same spec.
75
+
76
+ ### Behavior
77
+ - Each item is shallow-copied (`{ ...item }`) before mutation; the original array is not modified.
78
+ - The mutate function receives the **already-mutated item** (with earlier keys applied), the index, and the mutated array.
79
+ - For mutations that need to look across multiple items (e.g. running totals), use `mutateWithSummary` instead.
80
+
81
+ ### Example
82
+ ```js
83
+ const data = [
84
+ { str: 'foo', value: 3 },
85
+ { str: 'bar', value: 1 },
86
+ ];
87
+
88
+ tidy(data, mutate({
89
+ x2: (d) => d.value * 2,
90
+ x4: (d) => d.x2 * 2, // references x2 from above
91
+ constant: 99,
92
+ }))
93
+ // => [
94
+ // { str: 'foo', value: 3, x2: 6, x4: 12, constant: 99 },
95
+ // { str: 'bar', value: 1, x2: 2, x4: 4, constant: 99 },
96
+ // ]
97
+ ```
98
+
99
+ ---
100
+
101
+ <!-- keywords: transmute, mutate and select, drop columns, keep only new columns -->
102
+ ## transmute
103
+
104
+ Like `mutate`, but drops all columns not specified in the spec. Internally runs `mutate` then `select` on the spec keys.
105
+
106
+ **Signature:** `transmute(mutateSpec) => TidyFn<T, ResolvedObj<MSpec>>`
107
+ **Goes inside:** `tidy()` pipeline
108
+
109
+ ### Parameters
110
+ - `mutateSpec` -- same as `mutate`. Object `{ [key]: value | (item, index, array) => value }`.
111
+
112
+ ### Example
113
+ ```js
114
+ const data = [
115
+ { str: 'foo', value: 3 },
116
+ { str: 'bar', value: 1 },
117
+ ];
118
+
119
+ tidy(data, transmute({
120
+ value_x2: (d) => d.value * 2,
121
+ value_x4: (d) => d.value_x2 * 2,
122
+ }))
123
+ // => [
124
+ // { value_x2: 6, value_x4: 12 },
125
+ // { value_x2: 2, value_x4: 4 },
126
+ // ]
127
+ ```
128
+
129
+ ---
130
+
131
+ <!-- keywords: arrange, sort, order, asc, desc, fixedOrder, comparator, ascending, descending -->
132
+ ## arrange
133
+
134
+ Sort items by keys or comparator functions.
135
+
136
+ **Signature:** `arrange(comparators) => TidyFn<T>`
137
+ **Goes inside:** `tidy()` pipeline
138
+ **Alias:** `sort`
139
+
140
+ ### Parameters
141
+ - `comparators` -- a single value or array of:
142
+ - `string` (key name) -- auto-promoted to `asc(key)`.
143
+ - `(d: T) => any` (single-arg accessor) -- auto-promoted to `asc(accessor)`.
144
+ - `(a: T, b: T) => number` (two-arg comparator) -- used directly.
145
+
146
+ ### Sorting helpers
147
+
148
+ - **`asc(key | accessor)`** -- ascending comparator. Nulls/undefined/NaN sort last.
149
+ - **`desc(key | accessor)`** -- descending comparator. Nulls/undefined/NaN sort last.
150
+ - **`fixedOrder(key, order, options?)`** -- sort values by a predefined order array.
151
+ - `key` -- string key or accessor function.
152
+ - `order` -- array of values in desired order.
153
+ - `options.position` -- `'start'` (default) or `'end'`. Items not in the order array appear at the opposite end.
154
+
155
+ ### Example
156
+ ```js
157
+ const data = [
158
+ { str: 'foo', value: 3 },
159
+ { str: 'bar', value: 5 },
160
+ { str: 'bar', value: 1 },
161
+ ];
162
+
163
+ tidy(data, arrange(['str', desc('value')]))
164
+ // => [
165
+ // { str: 'bar', value: 5 },
166
+ // { str: 'bar', value: 1 },
167
+ // { str: 'foo', value: 3 },
168
+ // ]
169
+
170
+ tidy(data, arrange([fixedOrder('str', ['foo', 'bar'])]))
171
+ // => [
172
+ // { str: 'foo', value: 3 },
173
+ // { str: 'bar', value: 5 },
174
+ // { str: 'bar', value: 1 },
175
+ // ]
176
+ ```
177
+
178
+ ---
179
+
180
+ <!-- keywords: select, pick, columns, drop, omit, negate, selectors, everything, startsWith, endsWith, contains, matches, negate -->
181
+ ## select
182
+
183
+ Pick or drop columns from items. Supports selector functions and `-` prefix negation.
184
+
185
+ **Signature:** `select(selectKeys) => TidyFn<T, Pick<T, ...>>`
186
+ **Goes inside:** `tidy()` pipeline
187
+ **Alias:** `pick`
188
+
189
+ ### Parameters
190
+ - `selectKeys` -- a single key, or an array of:
191
+ - `string` -- a key name to include.
192
+ - `'-keyName'` -- a key prefixed with `-` to exclude.
193
+ - `(items: T[]) => string[]` -- a selector function (e.g. `everything()`, `startsWith('foo')`, `contains('val')`, `matches(/regex/)`, `numRange('x', [1,3])`).
194
+
195
+ ### Behavior
196
+ - If the first key starts with `-`, an implicit `everything()` is prepended (so `-foo` means "all keys except foo").
197
+ - Negations cancel out inclusions: `['a', 'b', '-b']` selects only `a`.
198
+ - Duplicates are removed.
199
+
200
+ ### Example
201
+ ```js
202
+ const data = [
203
+ { foo: 1, bar: 2, baz: 3, qux: 4 },
204
+ ];
205
+
206
+ tidy(data, select(['foo', 'bar']))
207
+ // => [{ foo: 1, bar: 2 }]
208
+
209
+ tidy(data, select(['-baz', '-qux']))
210
+ // => [{ foo: 1, bar: 2 }]
211
+
212
+ tidy(data, select([startsWith('b'), '-baz']))
213
+ // => [{ bar: 2 }]
214
+ ```
215
+
216
+ ---
217
+
218
+ <!-- keywords: distinct, unique, deduplicate, dedup, remove duplicates -->
219
+ ## distinct
220
+
221
+ Remove items with duplicate values for the specified keys. Keeps the first occurrence.
222
+
223
+ **Signature:** `distinct(keys?) => TidyFn<T>`
224
+ **Goes inside:** `tidy()` pipeline
225
+
226
+ ### Parameters
227
+ - `keys` (optional) -- a single key/accessor or array of keys/accessors:
228
+ - `string` -- key name.
229
+ - `(item: T) => any` -- accessor function.
230
+ - If omitted or empty, uses strict reference equality on the whole item.
231
+
232
+ ### Example
233
+ ```js
234
+ const data = [
235
+ { str: 'foo', value: 1 },
236
+ { str: 'foo', value: 3 },
237
+ { str: 'foo', value: 3 },
238
+ { str: 'bar', value: 1 },
239
+ ];
240
+
241
+ tidy(data, distinct(['str', 'value']))
242
+ // => [
243
+ // { str: 'foo', value: 1 },
244
+ // { str: 'foo', value: 3 },
245
+ // { str: 'bar', value: 1 },
246
+ // ]
247
+ ```
248
+
249
+ ---
250
+
251
+ <!-- keywords: rename, rename columns, rename keys, renameSpec -->
252
+ ## rename
253
+
254
+ Rename keys in each item. Non-renamed keys are preserved.
255
+
256
+ **Signature:** `rename(renameSpec) => TidyFn<T, OutputT>`
257
+ **Goes inside:** `tidy()` pipeline
258
+
259
+ ### Parameters
260
+ - `renameSpec` -- `{ [oldKey]: 'newKey' }`. Maps existing key names to new names.
261
+
262
+ ### Example
263
+ ```js
264
+ const data = [
265
+ { a: 1, b: 'b10', c: 100 },
266
+ { a: 2, b: 'b20', c: 200 },
267
+ ];
268
+
269
+ tidy(data, rename({ b: 'label', c: 'score' }))
270
+ // => [
271
+ // { a: 1, label: 'b10', score: 100 },
272
+ // { a: 2, label: 'b20', score: 200 },
273
+ // ]
274
+ ```
275
+
276
+ ---
277
+
278
+ <!-- keywords: when, conditional, if, predicate, branch, conditional pipeline -->
279
+ ## when
280
+
281
+ Conditionally run a sub-pipeline. If the predicate is false, items pass through unchanged.
282
+
283
+ **Signature:** `when(predicate, fns) => TidyFn<T>`
284
+ **Goes inside:** `tidy()` pipeline
285
+
286
+ ### Parameters
287
+ - `predicate` -- `boolean | (items: T[]) => boolean`. The condition to evaluate.
288
+ - `fns` -- `TidyFn[]`. Array of tidy functions to run when the predicate is true. Executed as a `tidy()` sub-pipeline.
289
+
290
+ ### Example
291
+ ```js
292
+ const data = [{ x: 1 }, { x: 2 }, { x: 3 }];
293
+
294
+ tidy(data, when(true, [mutate({ y: 10 })]))
295
+ // => [{ x: 1, y: 10 }, { x: 2, y: 10 }, { x: 3, y: 10 }]
296
+
297
+ tidy(data, when((items) => items.length > 5, [mutate({ y: 10 })]))
298
+ // => [{ x: 1 }, { x: 2 }, { x: 3 }] (unchanged, predicate was false)
299
+ ```
300
+
301
+ ---
302
+
303
+ <!-- keywords: debug, log, console, inspect, table -->
304
+ ## debug
305
+
306
+ Log the current pipeline state to the console. Data passes through unmodified.
307
+
308
+ **Signature:** `debug(label?, options?) => TidyFn<T>`
309
+ **Goes inside:** `tidy()` pipeline
310
+
311
+ ### Parameters
312
+ - `label` (optional) -- `string`. Label displayed in the console output prefix.
313
+ - `options` (optional) -- `{ limit?: number | null, output?: 'log' | 'table' }`.
314
+ - `limit` (default `10`) -- max items to display. Set to `null` for all.
315
+ - `output` (default `'table'`) -- use `console.table` or `console.log`.
316
+
317
+ ### Behavior
318
+ - Output is prefixed with `[tidy.debug]` (plus group keys if inside `groupBy`).
319
+ - Returns items unchanged -- safe to insert anywhere in a pipeline for inspection.
320
+
321
+ ### Example
322
+ ```js
323
+ tidy(data,
324
+ filter((d) => d.value > 1),
325
+ debug('after filter'),
326
+ arrange('value')
327
+ )
328
+ // Logs: [tidy.debug] after filter --------
329
+ // (console.table of up to 10 items)
330
+ ```
331
+
332
+ ---
333
+
334
+ <!-- keywords: map, transform, mapFn, convert, reshape -->
335
+ ## map
336
+
337
+ Transform each item to a new shape. Equivalent to `Array.prototype.map`.
338
+
339
+ **Signature:** `map(mapFn) => TidyFn<T, OutputT>`
340
+ **Goes inside:** `tidy()` pipeline
341
+
342
+ ### Parameters
343
+ - `mapFn` -- `(item: T, index: number, array: T[]) => OutputT`. Returns the new item.
344
+
345
+ ### Example
346
+ ```js
347
+ const data = [
348
+ { value: 1, nested: { a: 10, b: 100 } },
349
+ { value: 2, nested: { a: 20, b: 200 } },
350
+ ];
351
+
352
+ tidy(data, map((d) => ({ value: d.value, ...d.nested })))
353
+ // => [
354
+ // { value: 1, a: 10, b: 100 },
355
+ // { value: 2, a: 20, b: 200 },
356
+ // ]
357
+ ```