df-script 1.7.0 → 1.9.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.
Files changed (36) hide show
  1. package/README.md +51 -12
  2. package/dist/api.d.ts +2 -1
  3. package/dist/columnExpressions/ExprBase.d.ts +8 -0
  4. package/dist/columnExpressions/constants.d.ts +2 -0
  5. package/dist/columnExpressions/functions/duration.d.ts +33 -0
  6. package/dist/columnExpressions/functions/when.d.ts +8 -6
  7. package/dist/columnExpressions/index.d.ts +2 -0
  8. package/dist/columnExpressions/mixins/AggregationExpr.d.ts +203 -1
  9. package/dist/columnExpressions/mixins/ArrayExpr.d.ts +57 -41
  10. package/dist/columnExpressions/mixins/StringExpr.d.ts +277 -13
  11. package/dist/columnExpressions/mixins/StructExpr.d.ts +7 -7
  12. package/dist/columnExpressions/mixins/TemporalExpr.d.ts +123 -72
  13. package/dist/columnExpressions/typeInference.d.ts +13 -0
  14. package/dist/columnExpressions/types.d.ts +1 -1
  15. package/dist/columnExpressions/utils.d.ts +19 -0
  16. package/dist/constants.d.ts +44 -3
  17. package/dist/dataframe/dataframe.d.ts +233 -109
  18. package/dist/dataframe/types.d.ts +25 -3
  19. package/dist/dataframe/utils.d.ts +21 -1
  20. package/dist/datatypes/types.d.ts +8 -3
  21. package/dist/exceptions/index.d.ts +10 -0
  22. package/dist/exceptions/utils.d.ts +2 -0
  23. package/dist/index.js +5 -5
  24. package/dist/index.mjs +5 -5
  25. package/dist/types.d.ts +132 -1
  26. package/dist/utils/array.d.ts +62 -6
  27. package/dist/utils/binary.d.ts +6 -2
  28. package/dist/utils/date.d.ts +6 -2
  29. package/dist/utils/duration.d.ts +5 -0
  30. package/dist/utils/index.d.ts +1 -0
  31. package/dist/utils/json.d.ts +54 -2
  32. package/dist/utils/number.d.ts +5 -2
  33. package/dist/utils/object.d.ts +13 -0
  34. package/dist/utils/string.d.ts +78 -2
  35. package/dist/utils/table.d.ts +76 -0
  36. package/package.json +13 -3
@@ -1,6 +1,6 @@
1
1
  import { GroupedData } from "./grouped/grouped";
2
2
  import type { IExpr, ColumnData, ColumnDict, DataFrameColumns, ConcatOptions, ConcatItem, HorizontalConcatOptions, RowRecord, DataFrameSchema, RegisteredDataType, ExplodeOptions, IntoExpr, FillNullOptions } from "../types";
3
- import type { LimitOptions, SortOptions, PivotOptions, JoinOptions, UnpivotOptions, TransposeOptions, WriteJSONOptions, WriteCSVOptions } from "./types";
3
+ import type { LimitOptions, SortOptions, PivotOptions, JoinOptions, AsofJoinOptions, UnpivotOptions, TransposeOptions, WriteJSONOptions, WriteCSVOptions } from "./types";
4
4
  /**
5
5
  * Two-dimensional columnar tabular data structure supporting expression execution and reshaping.
6
6
  */
@@ -50,11 +50,11 @@ export declare class DataFrame<T extends RowRecord = any> {
50
50
  /**
51
51
  * Concatenates items vertically, horizontally, or diagonally.
52
52
  *
53
- * @param items Single DataFrame or array of DataFrames/rows to concatenate.
54
- * @param [options] Configuration options for concatenation layout and strictness.
55
- * @param [options.how] Layout strategy: `"vertical"` (default, appends rows top-to-bottom), `"horizontal"` (joins unique columns side-by-side), or `"diagonal"` (concatenates mismatched columns with null padding).
56
- * @param [options.horizontal.strict] When `true` (default), throws an error if row counts mismatch in horizontal concatenation. Set `false` to pad shorter DataFrames with `null`.
57
- * @returns DataFrame
53
+ * @param {ConcatItem | ConcatItem[]} items Single DataFrame or array of DataFrames/rows to concatenate.
54
+ * @param {ConcatOptions} [options] Configuration options for concatenation layout and strictness.
55
+ * @param {ConcatHow} [options.how] Layout strategy: `"vertical"` (default, appends rows top-to-bottom), `"horizontal"` (joins unique columns side-by-side), or `"diagonal"` (concatenates mismatched columns with null padding).
56
+ * @param {boolean} [options.horizontal.strict] When `true` (default), throws an error if row counts mismatch in horizontal concatenation. Set `false` to pad shorter DataFrames with `null`.
57
+ * @returns {DataFrame}
58
58
  *
59
59
  * @example
60
60
  * // 1. Vertical Concatenation (default):
@@ -105,8 +105,8 @@ export declare class DataFrame<T extends RowRecord = any> {
105
105
  concat<U extends RowRecord = any>(items: ConcatItem | ConcatItem[], options?: ConcatOptions): DataFrame<U>;
106
106
  /**
107
107
  * Drops specified columns from the DataFrame.
108
- * @param args Column names or arrays of column names to remove.
109
- * @returns DataFrame
108
+ * @param {(K | K[])[]} args Column names or arrays of column names to remove.
109
+ * @returns {DataFrame}
110
110
  * @example
111
111
  * >>> const df = $df.data({ a: [1], b: [2] })
112
112
  * >>> df
@@ -127,8 +127,8 @@ export declare class DataFrame<T extends RowRecord = any> {
127
127
  drop<K extends keyof T>(...args: (K | K[])[]): DataFrame<Omit<T, K>>;
128
128
  /**
129
129
  * Drops rows containing null or undefined values in specified subset columns.
130
- * @param subset Column name or array of column names to check for nulls.
131
- * @returns DataFrame
130
+ * @param {string | string[]} [subset] Column name or array of column names to check for nulls.
131
+ * @returns {DataFrame}
132
132
  * @example
133
133
  * >>> const df = $df.data({ a: [1, null, 3] })
134
134
  * >>> df
@@ -168,11 +168,11 @@ export declare class DataFrame<T extends RowRecord = any> {
168
168
  get dtypes(): RegisteredDataType[];
169
169
  /**
170
170
  * Explodes an array column into multiple rows, replicating non-target row attributes.
171
- * @param columns Target column expression or array column name to explode.
172
- * @param [options] Configuration options for empty array and null handling.
173
- * @param [options.empty_as_null] When `true`, converts empty arrays to `null` rows.
174
- * @param [options.keep_nulls] When `true`, retains `null` array values during explosion.
175
- * @returns DataFrame
171
+ * @param {IntoExpr | IntoExpr[]} columns Target column expression or array column name to explode.
172
+ * @param {ExplodeOptions} [options] Configuration options for empty array and null handling.
173
+ * @param {boolean} [options.empty_as_null] When `true`, converts empty arrays to `null` rows.
174
+ * @param {boolean} [options.keep_nulls] When `true`, retains `null` array values during explosion.
175
+ * @returns {DataFrame}
176
176
  * @example
177
177
  * >>> const df = $df.data({ group: ["A"], values: [[1, 2]] })
178
178
  * >>> df
@@ -194,11 +194,11 @@ export declare class DataFrame<T extends RowRecord = any> {
194
194
  explode(columns: IntoExpr | IntoExpr[], options?: ExplodeOptions): DataFrame<any>;
195
195
  /**
196
196
  * Fills null values across columns using scalar values or statistical strategies.
197
- * @param [options] Configuration options for null replacement.
198
- * @param [options.value] Scalar replacement value or dict mapping column names to values.
199
- * @param [options.strategy] Statistical filling strategy (`"zero"`, `"mean"`, `"min"`, `"max"`, `"forward"`, `"backward"`).
200
- * @param [options.limit] Maximum consecutive nulls to fill when using propagation strategies.
201
- * @returns DataFrame
197
+ * @param {FillNullOptions} [options] Configuration options for null replacement.
198
+ * @param {any} [options.value] Scalar replacement value or dict mapping column names to values.
199
+ * @param {FillNullStrategy} [options.strategy] Statistical filling strategy (`"zero"`, `"mean"`, `"min"`, `"max"`, `"forward"`, `"backward"`).
200
+ * @param {number} [options.limit] Maximum consecutive nulls to fill when using propagation strategies.
201
+ * @returns {DataFrame}
202
202
  * @example
203
203
  * >>> const df = $df.data({ a: [1, null, 3] })
204
204
  * >>> df
@@ -223,8 +223,8 @@ export declare class DataFrame<T extends RowRecord = any> {
223
223
  fill_null(options?: FillNullOptions): DataFrame<T>;
224
224
  /**
225
225
  * Filters rows matching boolean column expressions or predicate callbacks.
226
- * @param exprs Expressions or predicate functions evaluated per row.
227
- * @returns DataFrame
226
+ * @param {(IExpr | ((row: T) => any))[]} exprs Expressions or predicate functions evaluated per row.
227
+ * @returns {DataFrame}
228
228
  * @example
229
229
  * >>> const df = $df.data({ a: [1, 2, 3] })
230
230
  * >>> df
@@ -246,26 +246,10 @@ export declare class DataFrame<T extends RowRecord = any> {
246
246
  * └───┘
247
247
  */
248
248
  filter(...exprs: (IExpr | ((row: T) => any))[]): DataFrame<T>;
249
- /**
250
- * Returns the mapping dictionary of column names to DataType.
251
- * @returns DataFrameSchema
252
- * @example
253
- * >>> const df = $df.data({ a: [1], b: ["text"] })
254
- * >>> df
255
- * shape: (1, 2)
256
- * ┌───┬──────┐
257
- * │ a │ b │
258
- * ├───┼──────┤
259
- * │ 1 │ text │
260
- * └───┴──────┘
261
- * >>> df.get_schema()
262
- * { a: Float64, b: Utf8 }
263
- */
264
- get_schema(): DataFrameSchema;
265
249
  /**
266
250
  * Groups rows by key columns to prepare for aggregations.
267
- * @param keys Column name or array of key column names.
268
- * @returns GroupedData
251
+ * @param {K | K[]} keys Column name or array of key column names.
252
+ * @returns {GroupedData}
269
253
  * @example
270
254
  * >>> const df = $df.data({ cat: ["A", "A", "B"], val: [10, 20, 30] })
271
255
  * >>> df
@@ -313,6 +297,35 @@ export declare class DataFrame<T extends RowRecord = any> {
313
297
  * └───┘
314
298
  */
315
299
  head(n?: number): DataFrame<T>;
300
+ /**
301
+ * Creates a deep copy of the current DataFrame instance, duplicating all underlying column data arrays and schema metadata.
302
+ * Modifying columns or values in the cloned DataFrame will not mutate the original.
303
+ * @returns {DataFrame<T>}
304
+ * @example
305
+ * >>> // Example 1: Basic cloning and independence
306
+ * >>> const df1 = $df.data({ a: [10, 20], b: ["x", "y"] })
307
+ * >>> const copy1 = df1.clone()
308
+ * >>> copy1
309
+ * shape: (2, 2)
310
+ * ┌────┬───┐
311
+ * │ a │ b │
312
+ * ├────┼───┤
313
+ * │ 10 │ x │
314
+ * │ 20 │ y │
315
+ * └────┴───┘
316
+ *
317
+ * >>> // Example 2: Verifying mutation isolation
318
+ * >>> copy1._columns.a[0] = 999
319
+ * >>> df1.to_dicts()[0].a
320
+ * 10
321
+ *
322
+ * >>> // Example 3: Cloning empty DataFrames
323
+ * >>> const emptyDf = $df.data({ x: [], y: [] })
324
+ * >>> const emptyCopy = emptyDf.clone()
325
+ * >>> emptyCopy.height
326
+ * 0
327
+ */
328
+ clone(): DataFrame<T>;
316
329
  /**
317
330
  * Gets height (total row count) of the DataFrame.
318
331
  * @returns Number of rows.
@@ -333,10 +346,10 @@ export declare class DataFrame<T extends RowRecord = any> {
333
346
  get height(): number;
334
347
  /**
335
348
  * Concatenates columns horizontally to the current DataFrame.
336
- * @param other DataFrame or array of DataFrames to append side-by-side.
337
- * @param [options] Horizontal concat configuration options.
338
- * @param [options.strict] When `true` (default), throws an error if row counts mismatch. Set `false` to allow null padding.
339
- * @returns DataFrame
349
+ * @param {ConcatItem | ConcatItem[]} other DataFrame or array of DataFrames to append side-by-side.
350
+ * @param {HorizontalConcatOptions} [options] Horizontal concat configuration options.
351
+ * @param {boolean} [options.strict] When `true` (default), throws an error if row counts mismatch. Set `false` to allow null padding.
352
+ * @returns {DataFrame}
340
353
  * @example
341
354
  * >>> const df1 = $df.data({ a: [1, 2] })
342
355
  * >>> df1
@@ -360,10 +373,10 @@ export declare class DataFrame<T extends RowRecord = any> {
360
373
  hstack<U extends RowRecord = any>(other: ConcatItem | ConcatItem[], options?: HorizontalConcatOptions): DataFrame<U>;
361
374
  /**
362
375
  * Inserts a new column at a specific ordinal index position.
363
- * @param index Target column index position.
364
- * @param name Name of the inserted column.
365
- * @param expr Value expression or column definition.
366
- * @returns DataFrame
376
+ * @param {number} index Target column index position.
377
+ * @param {string} name Name of the inserted column.
378
+ * @param {IntoExpr} expr Value expression or column definition.
379
+ * @returns {DataFrame}
367
380
  * @example
368
381
  * >>> const df = $df.data({ a: [1], c: [3] })
369
382
  * >>> df
@@ -384,9 +397,9 @@ export declare class DataFrame<T extends RowRecord = any> {
384
397
  insert_column(index: number, name: string, expr: IntoExpr): DataFrame<any>;
385
398
  /**
386
399
  * Retrieves a single scalar cell value by row and column position or name.
387
- * @param row Row index position.
388
- * @param column Column index or column name string.
389
- * @returns Cell scalar value.
400
+ * @param {number} [row] Row index position.
401
+ * @param {number | string} [column] Column index or column name string.
402
+ * @returns {any} Cell scalar value.
390
403
  * @throws {DataFrameError} If shape is not (1, 1) when called without arguments.
391
404
  * @throws {ShapeError} If row or column index is out of bounds.
392
405
  * @example
@@ -443,13 +456,32 @@ export declare class DataFrame<T extends RowRecord = any> {
443
456
  named?: boolean;
444
457
  }): Generator<any[] | Record<string, any>>;
445
458
  /**
446
- * Joins two DataFrames on key columns using inner, left, right, or outer join strategy.
447
- * @param config Join configuration object.
448
- * @param config.other Right DataFrame to join with left DataFrame.
449
- * @param config.on Join key column name or array of key column names.
450
- * @param [config.how] Join strategy (`"inner"`, `"left"`, `"right"`, or `"outer"`). Default `"inner"`.
451
- * @param [config.suffixes] Custom column name suffix tuple `[leftSuffix, rightSuffix]` for overlapping non-key columns (default `["", "_right"]`).
452
- * @returns DataFrame
459
+ * Joins two DataFrames on key columns using a specified join strategy.
460
+ * @param {JoinOptions} config Join configuration object.
461
+ * @param {DataFrame} config.other Right DataFrame to join with.
462
+ * @param {string | string[]} [config.on] Join key column name or array of key column names that exist in both DataFrames.
463
+ * @param {string | string[]} [config.leftOn] Join key column(s) in the left DataFrame when key names differ.
464
+ * @param {string | string[]} [config.rightOn] Join key column(s) in the right DataFrame when key names differ.
465
+ * @param {JoinType} [config.how] Join strategy. Default `"inner"`.
466
+ * - `"inner"` — Only rows with matching keys in both DataFrames.
467
+ * - `"left"` — All left rows; unmatched right values are `null`.
468
+ * - `"right"` — All right rows; unmatched left values are `null`.
469
+ * - `"outer"` — All rows from both sides; unmatched values are `null`.
470
+ * - `"semi"` — Left rows that have a match in the right DataFrame (only left columns retained).
471
+ * - `"anti"` — Left rows that have **no** match in the right DataFrame (only left columns retained).
472
+ * - `"cross"` — Cartesian product pairing every left row with every right row (keyless).
473
+ * @param {[string, string]} [config.suffixes] Suffix tuple `[leftSuffix, rightSuffix]` appended to overlapping
474
+ * non-key column names (default `["", "_right"]`). Ignored for `"semi"` and `"anti"` joins.
475
+ * @param {boolean} [config.join_nulls] If `true`, null key values are treated as equal and will match each other
476
+ * across DataFrames. Default `false` (SQL-standard: `NULL != NULL`).
477
+ * @param {boolean} [config.coalesce] Coalescing behavior for join key columns. Default `true`. If `true`, coalesces join key values into left key columns and drops right key columns. If `false`, keeps join key columns separate.
478
+ * @param {JoinMaintainOrder | boolean} [config.maintain_order] Row order preservation strategy. Default `"none"`.
479
+ * - `"none"` (or `false`) — No specific ordering is desired.
480
+ * - `"left"` (or `true`) — Preserves the order of the left DataFrame.
481
+ * - `"right"` — Preserves the order of the right DataFrame.
482
+ * - `"left_right"` — Preserves the order of the left DataFrame first, then the right.
483
+ * - `"right_left"` — Preserves the order of the right DataFrame first, then the left.
484
+ * @returns {DataFrame}
453
485
  * @example
454
486
  * >>> const df1 = $df.data({ id: [1, 2], val: ["a", "b"] })
455
487
  * >>> df1
@@ -471,13 +503,85 @@ export declare class DataFrame<T extends RowRecord = any> {
471
503
  * └────┴─────┴─────┘
472
504
  */
473
505
  join<U extends RowRecord = any, R extends RowRecord = any>(config: JoinOptions<T, U>): DataFrame<R>;
506
+ /**
507
+ * Performs an asof (as-of) join for inexact matching on ordered numeric or temporal key columns.
508
+ *
509
+ * Similar to a left join, but instead of exact key equality, matches the nearest key row from the right
510
+ * DataFrame according to the selected `strategy` ("backward", "forward", or "nearest") and optional `tolerance`.
511
+ * Both DataFrames must be sorted in ascending order on their respective `on` / `leftOn` / `rightOn` join keys.
512
+ *
513
+ * @param {AsofJoinOptions} options Asof join configuration options.
514
+ * @param {DataFrame} options.other The right DataFrame to join with.
515
+ * @param {string} [options.on] Column name to join on (must exist in both DataFrames and be sorted ascending).
516
+ * @param {string} [options.leftOn] Left DataFrame join key column name.
517
+ * @param {string} [options.rightOn] Right DataFrame join key column name.
518
+ * @param {string | string[]} [options.by] Optional exact-match group column(s) present in both DataFrames.
519
+ * @param {string | string[]} [options.leftBy] Group column(s) for exact key matching in left DataFrame.
520
+ * @param {string | string[]} [options.rightBy] Group column(s) for exact key matching in right DataFrame.
521
+ * @param {AsofJoinStrategy} [options.strategy] Match search strategy. Default `"backward"`.
522
+ * - `"backward"` — Matches the latest right row where `rightKey <= leftKey`.
523
+ * - `"forward"` — Matches the earliest right row where `rightKey >= leftKey`.
524
+ * - `"nearest"` — Matches the right row with the absolute nearest key value to `leftKey`.
525
+ * @param {number | string} [options.tolerance] Maximum allowed distance between left key and right key.
526
+ * @param {boolean} [options.allow_exact_matches] Whether exact key matches are permitted. Default `true`.
527
+ * @param {[string, string]} [options.suffixes] Column name suffixes `[leftSuffix, rightSuffix]` to resolve name collisions. Default `["", "_right"]`.
528
+ * @param {boolean} [options.coalesce] Coalescing behavior for join key columns. Default `true`.
529
+ * @param {boolean} [options.check_sorted] Whether to verify that join keys are sorted ascending prior to matching. Default `true`.
530
+ * @returns A new DataFrame containing the joined results.
531
+ *
532
+ * @namespace df
533
+ * @category DataFrame
534
+ * @syntax
535
+ * df.join_asof({
536
+ * other,
537
+ * on,
538
+ * leftOn,
539
+ * rightOn,
540
+ * by,
541
+ * leftBy,
542
+ * rightBy,
543
+ * strategy,
544
+ * tolerance,
545
+ * allow_exact_matches,
546
+ * suffixes,
547
+ * coalesce,
548
+ * check_sorted
549
+ * })
550
+ * @example
551
+ * >>> const trades = new DataFrame([
552
+ * ... { time: 1000, ticker: "AAPL", price: 150.0 },
553
+ * ... { time: 1005, ticker: "AAPL", price: 150.5 },
554
+ * ... { time: 1015, ticker: "AAPL", price: 151.0 }
555
+ * ... ]);
556
+ * >>> const quotes = new DataFrame([
557
+ * ... { time: 998, ticker: "AAPL", bid: 149.9 },
558
+ * ... { time: 1004, ticker: "AAPL", bid: 150.4 },
559
+ * ... { time: 1010, ticker: "AAPL", bid: 150.8 }
560
+ * ... ]);
561
+ * >>> const joined = trades.join_asof({
562
+ * ... other: quotes,
563
+ * ... on: "time",
564
+ * ... by: "ticker",
565
+ * ... strategy: "backward"
566
+ * ... });
567
+ * >>> joined
568
+ * shape: (3, 4)
569
+ * ┌──────┬────────┬───────┬──────┐
570
+ * │ time │ ticker │ price │ bid │
571
+ * ├──────┼────────┼───────┼──────┤
572
+ * │ 1000 │ AAPL │ 150.0 │ 149.9│
573
+ * │ 1005 │ AAPL │ 150.5 │ 150.4│
574
+ * │ 1015 │ AAPL │ 151.0 │ 150.8│
575
+ * └──────┴────────┴───────┴──────┘
576
+ */
577
+ join_asof<U extends RowRecord = any, R extends RowRecord = any>(options: AsofJoinOptions<T, U>): DataFrame<R>;
474
578
  /**
475
579
  * Limits the output to N rows starting from offset.
476
- * @param n Maximum number of rows to take.
477
- * @param [options] Offset and slice direction options.
478
- * @param [options.offset] Number of rows to skip before taking `n` rows (default 0).
479
- * @param [options.from] Slice direction starting point (`"start"` or `"end"`). Default `"start"`.
480
- * @returns DataFrame
580
+ * @param {number} n Maximum number of rows to take.
581
+ * @param {LimitOptions} [options] Offset and slice direction options.
582
+ * @param {number} [options.offset] Number of rows to skip before taking `n` rows (default 0).
583
+ * @param {LimitPosition} [options.from] Slice direction starting point (`"start"` or `"end"`). Default `"start"`.
584
+ * @returns {DataFrame}
481
585
  * @example
482
586
  * >>> const df = $df.data({ a: [10, 20, 30, 40] })
483
587
  * >>> df
@@ -536,8 +640,8 @@ export declare class DataFrame<T extends RowRecord = any> {
536
640
  pivot<U extends RowRecord = any>(config: PivotOptions<T>): DataFrame<U>;
537
641
  /**
538
642
  * Renames columns based on a key-value mapping dictionary.
539
- * @param mapping Dictionary mapping old column names to new names.
540
- * @returns DataFrame
643
+ * @param {Partial<Record<keyof T, string>>} [mapping] Dictionary mapping old column names to new names.
644
+ * @returns {DataFrame}
541
645
  * @example
542
646
  * >>> const df = $df.data({ old_name: [1] })
543
647
  * >>> df
@@ -599,8 +703,8 @@ export declare class DataFrame<T extends RowRecord = any> {
599
703
  get schema(): DataFrameSchema;
600
704
  /**
601
705
  * Selects specific columns or evaluates column expressions.
602
- * @param args Column names, column expressions, or object maps to evaluate.
603
- * @returns DataFrame
706
+ * @param {(string | IExpr | Record<string, any> | (string | IExpr | Record<string, any>)[])[]} args Column names, column expressions, or object maps to evaluate.
707
+ * @returns {DataFrame}
604
708
  * @example
605
709
  * >>> const df = $df.data({ a: [1, 2], b: [10, 20] })
606
710
  * >>> df
@@ -640,9 +744,9 @@ export declare class DataFrame<T extends RowRecord = any> {
640
744
  get shape(): [number, number];
641
745
  /**
642
746
  * Slices a subset range of rows between start and end index.
643
- * @param start Starting row index.
644
- * @param end Optional ending row index (exclusive).
645
- * @returns DataFrame
747
+ * @param {number} start Starting row index.
748
+ * @param {number} [end] Optional ending row index (exclusive).
749
+ * @returns {DataFrame}
646
750
  * @example
647
751
  * >>> const df = $df.data({ a: [10, 20, 30, 40] })
648
752
  * >>> df
@@ -667,12 +771,12 @@ export declare class DataFrame<T extends RowRecord = any> {
667
771
  slice(start: number, end?: number): DataFrame<T>;
668
772
  /**
669
773
  * Sorts DataFrame rows by one or more column expressions or custom sorters.
670
- * @param config Sort configuration options.
671
- * @param config.by Column name(s) or expression(s) to sort by.
672
- * @param [config.descending] Sort order boolean or array of booleans per key (default `false`).
673
- * @param [config.nullsLast] When `true` (default), places nulls at the end of sorted output.
674
- * @param [config.custom] Optional dictionary mapping column names to custom comparator functions.
675
- * @returns DataFrame
774
+ * @param {SortOptions<T>} [config] Sort configuration options.
775
+ * @param {keyof T | (keyof T)[] | IExpr | IExpr[]} config.by Column name(s) or expression(s) to sort by.
776
+ * @param {boolean | boolean[]} [config.descending] Sort order boolean or array of booleans per key (default `false`).
777
+ * @param {boolean} [config.nullsLast] When `true` (default), places nulls at the end of sorted output.
778
+ * @param {Partial<Record<keyof T, (a: any, b: any) => number>>} [config.custom] Optional dictionary mapping column names to custom comparator functions.
779
+ * @returns {DataFrame}
676
780
  * @example
677
781
  * >>> const df = $df.data({ val: [3, 1, 2] })
678
782
  * >>> df
@@ -756,8 +860,8 @@ export declare class DataFrame<T extends RowRecord = any> {
756
860
  to_dicts(): T[];
757
861
  /**
758
862
  * Evaluates a column expression or retrieves column values as a raw JavaScript array.
759
- * @param nameOrExpr Target column name or column expression.
760
- * @returns Array of column scalar values.
863
+ * @param {K | IExpr} nameOrExpr Target column name or column expression.
864
+ * @returns {any[]} Array of column scalar values.
761
865
  * @example
762
866
  * >>> const df = $df.data({ a: [10, 20] })
763
867
  * >>> df
@@ -774,11 +878,11 @@ export declare class DataFrame<T extends RowRecord = any> {
774
878
  to_array<K extends keyof T>(nameOrExpr: K | IExpr): any[];
775
879
  /**
776
880
  * Transposes rows into columns and columns into rows.
777
- * @param [options] Transpose layout options.
778
- * @param [options.include_header] When `true`, includes original column names as a new header column (default `false`).
779
- * @param [options.header_name] Name of the header column when `include_header` is `true` (default `"column"`).
780
- * @param [options.column_names] Column name or iterable of strings to use as transposed column headers.
781
- * @returns DataFrame
881
+ * @param {TransposeOptions} [options] Transpose layout options.
882
+ * @param {boolean} [options.include_header] When `true`, includes original column names as a new header column (default `false`).
883
+ * @param {string} [options.header_name] Name of the header column when `include_header` is `true` (default `"column"`).
884
+ * @param {string | Iterable<string>} [options.column_names] Column name or iterable of strings to use as transposed column headers.
885
+ * @returns {DataFrame}
782
886
  * @example
783
887
  * >>> const df = $df.data({ metric: ["sales", "clicks"], q1: [100, 500], q2: [120, 600] })
784
888
  * >>> df
@@ -801,8 +905,8 @@ export declare class DataFrame<T extends RowRecord = any> {
801
905
  transpose({ include_header: includeHeader, header_name: headerName, column_names: colNamesOpt }?: TransposeOptions): DataFrame<any>;
802
906
  /**
803
907
  * Filters distinct unique rows matching target key columns.
804
- * @param columns Target column or array of column names to evaluate uniqueness.
805
- * @returns DataFrame
908
+ * @param {K | K[]} [columns] Target column or array of column names to evaluate uniqueness.
909
+ * @returns {DataFrame}
806
910
  * @example
807
911
  * >>> const df = $df.data({ a: [1, 2, 2], b: ["x", "y", "y"] })
808
912
  * >>> df
@@ -826,12 +930,12 @@ export declare class DataFrame<T extends RowRecord = any> {
826
930
  unique<K extends keyof T>(columns?: K | K[]): DataFrame<T>;
827
931
  /**
828
932
  * Unpivots a wide DataFrame into a long format structure.
829
- * @param config Unpivot configuration options.
830
- * @param config.idVars Key column(s) to retain as identifier variables.
831
- * @param config.valueVars Column(s) to unpivot into variable-value pairs.
832
- * @param [config.varName] Name for the new variable column holding old column headers (default `"variable"`).
833
- * @param [config.valueName] Name for the new value column holding cell values (default `"value"`).
834
- * @returns DataFrame
933
+ * @param {UnpivotOptions<T>} config Unpivot configuration options.
934
+ * @param {keyof T | (keyof T)[]} config.idVars Key column(s) to retain as identifier variables.
935
+ * @param {keyof T | (keyof T)[]} config.valueVars Column(s) to unpivot into variable-value pairs.
936
+ * @param {string} [config.varName] Name for the new variable column holding old column headers (default `"variable"`).
937
+ * @param {string} [config.valueName] Name for the new value column holding cell values (default `"value"`).
938
+ * @returns {DataFrame}
835
939
  * @example
836
940
  * >>> const df = $df.data({ year: [2020], Jan: [100], Feb: [150] })
837
941
  * >>> df
@@ -853,8 +957,8 @@ export declare class DataFrame<T extends RowRecord = any> {
853
957
  unpivot<U extends RowRecord = any>(config: UnpivotOptions<T>): DataFrame<U>;
854
958
  /**
855
959
  * Concatenates DataFrames vertically. Alias for concat({ how: "vertical" }).
856
- * @param other Single DataFrame or array of DataFrames to append vertically.
857
- * @returns DataFrame
960
+ * @param {ConcatItem | ConcatItem[]} other Single DataFrame or array of DataFrames to append vertically.
961
+ * @returns {DataFrame}
858
962
  * @example
859
963
  * >>> const df1 = $df.data({ a: [1] })
860
964
  * >>> df1
@@ -894,8 +998,8 @@ export declare class DataFrame<T extends RowRecord = any> {
894
998
  private _normalizeArgs;
895
999
  /**
896
1000
  * Adds new columns or updates existing ones using column expressions.
897
- * @param args Expressions or field objects defining column calculations.
898
- * @returns DataFrame
1001
+ * @param {(string | IExpr | Record<string, any> | (string | IExpr | Record<string, any>)[])[]} args Expressions or field objects defining column calculations.
1002
+ * @returns {DataFrame}
899
1003
  * @example
900
1004
  * >>> const df = $df.data({ a: [1, 2] })
901
1005
  * >>> df
@@ -918,9 +1022,9 @@ export declare class DataFrame<T extends RowRecord = any> {
918
1022
  with_columns(...args: (string | IExpr | Record<string, any> | (string | IExpr | Record<string, any>)[])[]): DataFrame<any>;
919
1023
  /**
920
1024
  * Appends an incremental index column.
921
- * @param name Name of index column (default "index").
922
- * @param offset Starting numeric index offset (default 0).
923
- * @returns DataFrame
1025
+ * @param {string} [name] Name of index column (default "index").
1026
+ * @param {number} [offset] Starting numeric index offset (default 0).
1027
+ * @returns {DataFrame}
924
1028
  * @example
925
1029
  * >>> const df = $df.data({ val: ["a", "b"] })
926
1030
  * >>> df
@@ -943,11 +1047,31 @@ export declare class DataFrame<T extends RowRecord = any> {
943
1047
  with_row_index(name?: string, offset?: number): DataFrame<any>;
944
1048
  /**
945
1049
  * Writes DataFrame rows to JSON format string or file/stream target.
946
- * @param [file] Target file path or writable stream target (optional).
947
- * @param [options] JSON formatting and replacer options.
948
- * @param [options.format] JSON output format structure (`"json"` or `"ndjson"`). Default `"json"`.
949
- * @param [options.replacerOptions] Serialization options including custom `replacer` function or replacer array.
950
- * @returns JSON string representation.
1050
+ * @param {string | { write: (str: string) => void }} [file] Target file path or writable stream target (optional).
1051
+ * @param {WriteJSONOptions} [options] JSON formatting and replacer options.
1052
+ * @param {JSONFormat} [options.format] JSON output format structure (`"json"` or `"ndjson"`). Default `"json"`.
1053
+ * @param {SafeJsonReplacerOptions} [options.replacerOptions] Serialization options for custom type handling.
1054
+ * @param {(v: Date) => string} [options.replacerOptions.formatDate] Custom formatter function for Date objects. Ignored if `onDate` is specified.
1055
+ * @param {"string" | "number"} [options.replacerOptions.bigintStrategy] Convert BigInts to numeric strings or numbers if safe. Default `"string"`.
1056
+ * @param {(v: bigint) => any} [options.replacerOptions.onBigInt] Custom serialization override for BigInt values.
1057
+ * @param {(v: any) => any} [options.replacerOptions.onTypedArray] Custom serialization override for TypedArray values.
1058
+ * @param {(v: Set<any>) => any} [options.replacerOptions.onSet] Custom serialization override for Set objects.
1059
+ * @param {(v: Map<any, any>) => any} [options.replacerOptions.onMap] Custom serialization override for Map objects.
1060
+ * @param {(v: RegExp) => any} [options.replacerOptions.onRegExp] Custom serialization override for RegExp objects.
1061
+ * @param {(v: Date) => any} [options.replacerOptions.onDate] Custom serialization override for Date objects. Takes precedence over `formatDate`.
1062
+ * @param {(v: Error) => any} [options.replacerOptions.onError] Custom serialization override for Error objects. Prevents empty `{}` output.
1063
+ * @param {(v: URLSearchParams) => any} [options.replacerOptions.onURLSearchParams] Custom serialization override for URLSearchParams objects.
1064
+ * @param {(this: any, k: string, v: any) => any} [options.replacerOptions.onCustom] Catch-all serialization override for custom types. Runs after native type checks.
1065
+ * @param {boolean} [options.replacerOptions.handleCircular] If `true`, handles circular references by replacing them instead of throwing.
1066
+ * @param {(this: any, k: string, v: any) => any} [options.replacerOptions.onCircular] Custom fallback when a circular reference is found. Default `"[Circular]"`.
1067
+ * @param {boolean} [options.replacerOptions.voidBigIntReplacement] If `true`, disables the default safe serialization for BigInt values.
1068
+ * @param {boolean} [options.replacerOptions.voidTypedArrayReplacement] If `true`, disables the default safe serialization for TypedArray values.
1069
+ * @param {boolean} [options.replacerOptions.voidSetReplacement] If `true`, disables the default safe serialization for Set objects.
1070
+ * @param {boolean} [options.replacerOptions.voidMapReplacement] If `true`, disables the default safe serialization for Map objects.
1071
+ * @param {boolean} [options.replacerOptions.voidRegExpReplacement] If `true`, disables the default safe serialization for RegExp objects.
1072
+ * @param {boolean} [options.replacerOptions.voidDateReplacement] If `true`, disables the default safe serialization for Date objects.
1073
+ * @param {((this: any, k: string, v: any) => any) | (string | number)[] | null} [options.replacerOptions.replacer] Custom replacer function or array whitelist that runs first for pre-processing.
1074
+ * @returns {string} JSON string representation.
951
1075
  * @example
952
1076
  * >>> const df = $df.data({ a: [1], b: ["x"] })
953
1077
  * >>> df
@@ -965,12 +1089,12 @@ export declare class DataFrame<T extends RowRecord = any> {
965
1089
  }, { format, replacerOptions }?: WriteJSONOptions): string;
966
1090
  /**
967
1091
  * Writes DataFrame to CSV format string or file/stream target.
968
- * @param [file] Target file path or writable stream target (optional).
969
- * @param [options] CSV formatting options.
970
- * @param [options.delimiter] Column delimiter character (default `","`).
971
- * @param [options.header] When `true` (default), includes column header row.
972
- * @param [options.quoteChar] Character used to enclose fields containing special characters (default `'"'`).
973
- * @returns CSV string output.
1092
+ * @param {string | { write: (str: string) => void }} [file] Target file path or writable stream target (optional).
1093
+ * @param {WriteCSVOptions} [options] CSV formatting options.
1094
+ * @param {string} [options.delimiter] Column delimiter character (default `","`).
1095
+ * @param {boolean} [options.header] When `true` (default), includes column header row.
1096
+ * @param {string} [options.quoteChar] Character used to enclose fields containing special characters (default `'"'`).
1097
+ * @returns {string} CSV string output.
974
1098
  * @example
975
1099
  * >>> const df = $df.data({ a: [1], b: ["x"] })
976
1100
  * >>> df
@@ -3,7 +3,8 @@ import type { IExpr, AggFn, RowRecord, DataFrameSchema, JSONFormat } from "../ty
3
3
  import type { DataFrame } from "./dataframe";
4
4
  import type { JSONParseOptions, SafeJsonReplacerOptions, NDJSONParseOptions } from "../utils";
5
5
  export type { JSONParseOptions, SafeJsonReplacerOptions, NDJSONParseOptions };
6
- export type JoinType = "inner" | "left" | "outer" | "right";
6
+ export type JoinType = "inner" | "outer" | "left" | "right" | "semi" | "anti" | "cross";
7
+ export type JoinMaintainOrder = "none" | "left" | "right" | "left_right" | "right_left";
7
8
  export type LimitPosition = "start" | "end";
8
9
  export type GroupMap = Map<string, number[]>;
9
10
  export interface LimitOptions {
@@ -22,11 +23,32 @@ export interface PivotOptions<T> {
22
23
  values: keyof T;
23
24
  agg?: AggFn<any> | string;
24
25
  }
25
- export interface JoinOptions<T, U extends RowRecord = any> {
26
+ export interface JoinOptions<T = any, U extends RowRecord = any> {
26
27
  other: DataFrame<U>;
27
- on: (keyof T & keyof U) | (keyof T & keyof U)[];
28
+ on?: (keyof T & keyof U) | (keyof T & keyof U)[];
29
+ leftOn?: (keyof T) | (keyof T)[];
30
+ rightOn?: (keyof U) | (keyof U)[];
28
31
  how?: JoinType;
29
32
  suffixes?: [string, string];
33
+ join_nulls?: boolean;
34
+ coalesce?: boolean;
35
+ maintain_order?: JoinMaintainOrder | boolean;
36
+ }
37
+ export type AsofJoinStrategy = "backward" | "forward" | "nearest";
38
+ export interface AsofJoinOptions<T = any, U extends RowRecord = any> {
39
+ other: DataFrame<U>;
40
+ on?: (keyof T & keyof U);
41
+ leftOn?: (keyof T);
42
+ rightOn?: (keyof U);
43
+ by?: (keyof T & keyof U) | (keyof T & keyof U)[];
44
+ leftBy?: (keyof T) | (keyof T)[];
45
+ rightBy?: (keyof U) | (keyof U)[];
46
+ strategy?: AsofJoinStrategy;
47
+ tolerance?: number | string;
48
+ allow_exact_matches?: boolean;
49
+ suffixes?: [string, string];
50
+ coalesce?: boolean;
51
+ check_sorted?: boolean;
30
52
  }
31
53
  export interface UnpivotOptions<T> {
32
54
  idVars: (keyof T) | (keyof T)[];
@@ -1,5 +1,7 @@
1
1
  /** @internalfile */
2
- import type { IExpr, ColumnData, ColumnDict, RegisteredDataType } from "../types";
2
+ import type { IExpr, ColumnData, ColumnDict, RegisteredDataType, DataFrameSchema, RowRecord } from "../types";
3
+ import type { JoinOptions, AsofJoinOptions } from "./types";
4
+ import { DataFrame } from "./dataframe";
3
5
  export declare function resolveWindowExpr(expr: IExpr, columns: ColumnDict, height: number): ColumnData;
4
6
  export declare function rowsToColumns(rows: any[]): {
5
7
  columns: ColumnDict;
@@ -18,3 +20,21 @@ export declare function coerceColumn(col: ColumnData, type: RegisteredDataType,
18
20
  export declare function writeStringToFileOrStream(file: string | {
19
21
  write: (str: string) => void;
20
22
  } | undefined, content: string): void;
23
+ /**
24
+ * Generic key-alignment engine computing positional row index mappings (leftIndex <-> rightIndex)
25
+ * between two columnar datasets based on key hashing.
26
+ * Reusable for Joins, Set Operations (Intersect/Difference), Upserts, and Alignments.
27
+ */
28
+ export declare function alignKeyIndices(leftCols: ColumnDict, rightCols: ColumnDict, leftHeight: number, rightHeight: number, leftKeys: string[], rightKeys: string[], options?: Partial<JoinOptions>): {
29
+ leftIndices: number[];
30
+ rightIndices: (number | null)[];
31
+ };
32
+ export declare function alignAsofIndices(leftCols: ColumnDict, rightCols: ColumnDict, leftHeight: number, rightHeight: number, leftOnKey: string, rightOnKey: string, leftByKeys: string[], rightByKeys: string[], options?: AsofJoinOptions): {
33
+ leftIndices: number[];
34
+ rightIndices: (number | null)[];
35
+ };
36
+ export declare function materializeJoinedDataFrame<R extends RowRecord = any>(leftCols: ColumnDict, rightCols: ColumnDict, leftSchema: DataFrameSchema, rightSchema: DataFrameSchema, leftIndices: number[], rightIndices: (number | null)[], leftKeysStr: string[], rightKeysStr: string[], options?: {
37
+ suffixes?: [string, string];
38
+ coalesce?: boolean;
39
+ how?: string;
40
+ }): DataFrame<R>;
@@ -1,6 +1,6 @@
1
1
  /** @typefile */
2
2
  import { DataType, SignedIntegerType, UnsignedIntegerType, FloatDataType, TemporalDataType, NestedDataType, NumericDataType } from "./DataType";
3
- import type { RowRecord } from "../types";
3
+ import type { RowRecord, DatetimeTimeUnit } from "../types";
4
4
  export declare class Int8Type extends SignedIntegerType {
5
5
  readonly name = "Int8";
6
6
  coerce(val: unknown): number | null;
@@ -159,11 +159,14 @@ export declare class DateType extends TemporalDataType<Date | null> {
159
159
  }
160
160
  export declare const DateDataType: DateType;
161
161
  /**
162
- * Date and time type (year, month, day, hour, minute, second, millisecond).
163
- *
162
+ * Date and time type (year, month, day, hour, minute, second, millisecond)
163
+ * with timeUnit precision and optional timezone awareness.
164
164
  */
165
165
  export declare class DatetimeType extends TemporalDataType<Date | null> {
166
166
  readonly name = "Datetime";
167
+ readonly timeUnit: DatetimeTimeUnit;
168
+ readonly timeZone: string | null;
169
+ constructor(timeUnit?: DatetimeTimeUnit, timeZone?: string | null);
167
170
  coerce(val: unknown): Date | null;
168
171
  equals(other: DataType): boolean;
169
172
  allocate(size: number): (Date | null)[];
@@ -178,6 +181,8 @@ export declare class TimeType extends TemporalDataType<string | null> {
178
181
  export declare const Time: TimeType;
179
182
  export declare class DurationType extends TemporalDataType<number | null> {
180
183
  readonly name = "Duration";
184
+ readonly timeUnit: DatetimeTimeUnit;
185
+ constructor(timeUnit?: DatetimeTimeUnit);
181
186
  coerce(val: unknown): number | null;
182
187
  equals(other: DataType): boolean;
183
188
  allocate(size: number): (number | null)[];