vastgrid-js 0.0.0-stage → 0.2.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 (78) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +211 -2
  3. package/dist/aggregate.d.ts +45 -0
  4. package/dist/aggregate.d.ts.map +1 -0
  5. package/dist/aggregate.js +305 -0
  6. package/dist/aggregate.js.map +1 -0
  7. package/dist/arrow.d.ts +7 -0
  8. package/dist/arrow.d.ts.map +1 -0
  9. package/dist/arrow.js +25 -0
  10. package/dist/arrow.js.map +1 -0
  11. package/dist/engine.d.ts +40 -0
  12. package/dist/engine.d.ts.map +1 -0
  13. package/dist/engine.js +1022 -0
  14. package/dist/engine.js.map +1 -0
  15. package/dist/evaluate.d.ts +37 -0
  16. package/dist/evaluate.d.ts.map +1 -0
  17. package/dist/evaluate.js +774 -0
  18. package/dist/evaluate.js.map +1 -0
  19. package/dist/export.d.ts +23 -0
  20. package/dist/export.d.ts.map +1 -0
  21. package/dist/export.js +48 -0
  22. package/dist/export.js.map +1 -0
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +2 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/lazy.d.ts +65 -0
  28. package/dist/lazy.d.ts.map +1 -0
  29. package/dist/lazy.js +177 -0
  30. package/dist/lazy.js.map +1 -0
  31. package/dist/numbers.d.ts +20 -0
  32. package/dist/numbers.d.ts.map +1 -0
  33. package/dist/numbers.js +129 -0
  34. package/dist/numbers.js.map +1 -0
  35. package/dist/order.d.ts +67 -0
  36. package/dist/order.d.ts.map +1 -0
  37. package/dist/order.js +561 -0
  38. package/dist/order.js.map +1 -0
  39. package/dist/parquet.d.ts +38 -0
  40. package/dist/parquet.d.ts.map +1 -0
  41. package/dist/parquet.js +673 -0
  42. package/dist/parquet.js.map +1 -0
  43. package/dist/plan.d.ts +37 -0
  44. package/dist/plan.d.ts.map +1 -0
  45. package/dist/plan.js +51 -0
  46. package/dist/plan.js.map +1 -0
  47. package/dist/summary.d.ts +37 -0
  48. package/dist/summary.d.ts.map +1 -0
  49. package/dist/summary.js +175 -0
  50. package/dist/summary.js.map +1 -0
  51. package/dist/table.d.ts +172 -0
  52. package/dist/table.d.ts.map +1 -0
  53. package/dist/table.js +154 -0
  54. package/dist/table.js.map +1 -0
  55. package/dist/text.d.ts +18 -0
  56. package/dist/text.d.ts.map +1 -0
  57. package/dist/text.js +1204 -0
  58. package/dist/text.js.map +1 -0
  59. package/dist/workbook.d.ts +6 -0
  60. package/dist/workbook.d.ts.map +1 -0
  61. package/dist/workbook.js +35 -0
  62. package/dist/workbook.js.map +1 -0
  63. package/package.json +46 -4
  64. package/src/aggregate.ts +358 -0
  65. package/src/arrow.ts +24 -0
  66. package/src/engine.ts +1163 -0
  67. package/src/evaluate.ts +764 -0
  68. package/src/export.ts +73 -0
  69. package/src/index.ts +2 -0
  70. package/src/lazy.ts +185 -0
  71. package/src/numbers.ts +128 -0
  72. package/src/order.ts +594 -0
  73. package/src/parquet.ts +801 -0
  74. package/src/plan.ts +99 -0
  75. package/src/summary.ts +180 -0
  76. package/src/table.ts +297 -0
  77. package/src/text.ts +1285 -0
  78. package/src/workbook.ts +48 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 vastgrid contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,212 @@
1
- # Temporary Holding Version
1
+ # vastgrid-js
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The memory engine of [vastgrid](https://www.npmjs.com/package/vastgrid), for the browser and Node.js, in the page or
4
+ a Web Worker. It opens tables of rows of typed JSON, Apache Arrow, CSV, TSV, JSON Lines and Excel files, and Parquet
5
+ files (also over HTTP Range requests), and sorts, filters, searches, groups, pivots, derives formulas, writes cells
6
+ and exports, answering the grid's messages
7
+ ([§8 of the specification](https://github.com/yhay81/vastgrid/blob/main/docs/spec.md#8-messages)).
8
+
9
+ ```sh
10
+ npm install vastgrid vastgrid-js
11
+ ```
12
+
13
+ ```tsx
14
+ import { DataGrid, localTransport } from "vastgrid";
15
+ import "vastgrid/styles.css";
16
+ import { memoryEngine } from "vastgrid-js";
17
+
18
+ const engine = memoryEngine({
19
+ tables: {
20
+ orders: {
21
+ columns: [
22
+ { name: "id", type: "bigint" },
23
+ { name: "price", type: "decimal", precision: 10, scale: 2 },
24
+ ],
25
+ rows: [
26
+ [1, "12.50"],
27
+ [2, "8.00"],
28
+ ],
29
+ editable: true,
30
+ },
31
+ },
32
+ });
33
+
34
+ export function Orders() {
35
+ return <DataGrid transport={localTransport(engine)} table="orders" style={{ height: 480 }} />;
36
+ }
37
+ ```
38
+
39
+ In a Web Worker, the engine answers through `serveEngine` of `vastgrid/core`, and the page talks to it with
40
+ `workerTransport(worker)`, so that the page never stops while the engine reads a file or sorts a million rows:
41
+
42
+ ```ts
43
+ // engine.worker.ts: the page posts the file that the person dropped or chose
44
+ import { serveEngine, type WorkerLike } from "vastgrid/core";
45
+ import { memoryEngine } from "vastgrid-js";
46
+
47
+ self.addEventListener(
48
+ "message",
49
+ (event: MessageEvent<File>) => {
50
+ const file = event.data;
51
+ const table = /\.parquet$/i.test(file.name) ? { parquet: file } : { file, editable: true };
52
+ serveEngine(memoryEngine({ tables: { [file.name]: table } }), self as unknown as WorkerLike);
53
+ },
54
+ { once: true },
55
+ );
56
+ ```
57
+
58
+ The engine can also be called directly: `await engine.handle({ v: 2, id: 1, op: "open", ref: "orders" })`.
59
+
60
+ ## Reference
61
+
62
+ - `memoryEngine({ tables })` takes the tables that `open` opens, by their `ref`: columns of §2.1 and rows of
63
+ typed JSON values (§2.2) in row ID order. The form of a table (its columns and rows of one value per column)
64
+ is checked when it is first opened, and its values as they are read (a column whole before it is sorted or
65
+ summed), so that opening a table of millions of rows takes milliseconds; a table that does not follow §2 is
66
+ answered with `load_failed` and the JSON Pointer of the place at fault. Its rows are read as they are,
67
+ without a copy, so they must not change afterwards.
68
+ - A table may also be given as Arrow: `{ arrow }`, the bytes of an Arrow IPC stream or file of any number of
69
+ record batches (as `tableToIPC` of Flechette or Apache Arrow writes them), with `editable` as for rows. Its
70
+ columns have the logical types of their Arrow types (§2.3), and none is `readOnly`. The engine keeps them as
71
+ Arrow holds them, without a copy: integers, floats, dates, bigints, decimals of up to 18 digits, times and
72
+ timestamps as typed arrays, which checks and sorts read as numbers, and the other values read from their
73
+ buffers when they are asked for (`decodeColumns` of `vastgrid-spec/columns`). A million rows of integers,
74
+ floats, dates, decimals, timestamps and strings take 258 MB as Arrow against 494 MB as rows, the host's rows
75
+ included, and sort by a date, a decimal or a timestamp in 50–70 ms against 170–250 ms. Bytes that are not
76
+ Arrow, Arrow types that have no logical type (lists, structs, …) and names that two columns share fail with
77
+ `load_failed` at `/arrow`; values that have no typed JSON (text that is not UTF-8, dates after 9999-12-31)
78
+ fail when they are read, at `/rows/{row}/{column}`. The code that reads Arrow loads with the first such table.
79
+ - A table may also be a text file: `{ file, format }`, with `file` a `Blob` or a `File` of CSV, TSV or JSON Lines
80
+ in UTF-8, in a Web Worker or the page, and `format` `csv`, `tsv` or `jsonl`, by default from the file's name
81
+ (`.csv`, `.tsv` or `.tab`, `.jsonl` or `.ndjson`); `editable` as for rows. It is read when it is first opened, in
82
+ slices of 4 MiB and twice: once to find its columns, the types that all their values fit and the memory they
83
+ take, then into typed columns, numbers in typed arrays (sorted as an Arrow table's are) and text as UTF-8,
84
+ without making rows of JSON. The open waits for both; opens of a file share one reading, and a table that every
85
+ ID has closed is read again. A CSV file of a million rows of six columns (55 MB) opens in about 0.9 seconds into
86
+ 32 MB, where the same rows as JSON take 248 MB. The code that reads files loads with the first such table.
87
+ - A table may also be a sheet of an Excel workbook (`.xlsx`, `.xlsm`): `{ file, format: "xlsx" }`, the format by
88
+ default from the file's name. `open`'s `read` (§8.2) chooses the sheet (the first visible one by default), the
89
+ row of the names (`headerRow`: by default the first row with a value; `0` for none, which names the columns by
90
+ their letters) and whether empty rows and columns are kept (`keepEmptyRows`, `keepEmptyColumns`); `TableInfo`
91
+ lists the workbook's `sheets`, the `sheet` read and `notes` (`merged_cells`, `formulas_without_values`). The sheet
92
+ is read with `vastgrid-spec/workbook`, as the DuckDB engine reads it: a column has one type (`bigint`, `float`,
93
+ `boolean`, `date`, `timestamp`, `time` or `string`) by its cells and their number formats, a formula its saved
94
+ value, and a date the workbook's calendar. Its rows are kept as lines of CSV in a `Blob` and read as a CSV file
95
+ is, within `maxBytes`; each set of `read` options is a table of its own, and other tables ignore `read`. A file
96
+ that is not a workbook, and one that is encrypted or in the old `.xls` format, fail with `load_failed` at
97
+ `/file`. The code that reads workbooks loads with the first such table.
98
+ - A file's column has the first of these types that every value of it fits, and is a `string` otherwise:
99
+ `boolean` (`true` and `false` in any case), `integer` and `bigint` by their range, `float` (with `nan`, `inf`
100
+ and `infinity`), `time` (`HH:MM:SS` with up to 6 fraction digits), `date` (`YYYY-MM-DD` of the years 0001 to
101
+ 9999), `timestamp` (a date, a space or `T` and a time; dates fit too) and `timestamptz` (a timestamp with `Z`,
102
+ `+HH`, `+HH:MM` or `+HHMM`, kept in UTC). Text that is almost a value (`24:00:00`, ` 1`, `2023-02-29`) makes a
103
+ string column, which keeps every value as it is written.
104
+ - CSV and TSV: the first line names the columns unless `header: false` (empty names are `column0`, `column1`, …,
105
+ and a repeated name gets `_1`, `_2`, …). CSV's separator is `delimiter`, or the one of `,`, tab, `;` and `|` that
106
+ splits the first line into the most fields. A quote switches quoting on and off wherever it is, so that quotes
107
+ hold separators and line breaks and `""` within them is a quote; lines end with LF or CRLF, and empty lines are
108
+ no rows. An empty field is null, and so are the fields that a row shorter than the others lacks; a quoted empty
109
+ field (`""`) is an empty string, and null in a column of another type.
110
+ - JSON Lines: an object per line, and a column per key in the order the keys first come, null where a line lacks
111
+ it. Numbers are what `JSON.parse` reads (integers beyond 2^53 are floats), strings are strings unless they are
112
+ times, dates or timestamps, and a column of objects and lists only is their JSON text (`sourceType: "JSON"`,
113
+ `readOnly: true`); a column of other values mixed is strings, with numbers and booleans as their JSON.
114
+ - A UTF-8 byte order mark is left out. A file in UTF-16, text that is not UTF-8 (at `/rows/{row}/{column}`; §2.2
115
+ does not allow replacing it), a line of JSON Lines that is not an object (at `/rows/{row}`) and a file that cannot
116
+ be read fail with `load_failed`. Answering the first rows while a file loads (§9) is a later step.
117
+ - `maxBytes` (default 1 GiB) is the most memory that a file's columns may take. A file whose columns would take
118
+ more is not kept: its first reading notes where every 1,024th row starts, and
119
+ the open answers then. Rows are read by those blocks, wherever they lie in a view, and the last 32 MiB of blocks
120
+ read are kept; a sort, a filter, a group, a summary, `find`, `export` and `locate` by value read the columns they
121
+ go through whole, in a reading of the file, while they fit `maxBytes`. A column read whole stays so until a
122
+ request needs its room while no request reads it: the least recently used are forgotten first, and read again
123
+ when a request needs them. A request that would read more at once fails with `load_failed` at `/maxBytes`, and
124
+ the table stays open. The 10-million-row CSV file of the benchmarks (701 MB)
125
+ opens so in 5 to 6 seconds into no memory with a `maxBytes` of 256 MiB, where kept it opens in 10 seconds into
126
+ 590 MB.
127
+ - A table may also be a Parquet file: `{ parquet }`, a `Blob` or a `File`, or the URL of a file whose server answers
128
+ HTTP range requests (`headers` such as `Authorization` go with every request, and `fetch` replaces the global
129
+ one); `editable` as for rows. Opening it reads its footer only. `rows` reads the row groups that hold its rows,
130
+ column by column (hyparquet, with the codecs of hyparquet-compressors), and keeps them in a cache of 4 million
131
+ cells; a sort, a filter, a group or a summary reads the columns it names whole into typed arrays, a row group at
132
+ a time, and `find`, `export` and `locate` by value the columns they go through. The rows of a view that lie in
133
+ more than two row groups, as a sorted or filtered view's do, read their columns whole too, so that scrolling
134
+ the view reads memory rather than every row group again. `maxBytes` (default 1 GiB) is about the most memory
135
+ that the columns read whole may take (numbers in typed arrays, booleans in a byte, text as strings, which the rows
136
+ of a dictionary's value share), and columns read whole are forgotten as a text file's are: a request that would
137
+ read more at once fails with `load_failed` at `/maxBytes`, the table stays open, and its rows are read by row
138
+ groups. A million rows of eight columns (13 MB of Parquet) open in
139
+ 30 ms into 2 MB, show their first rows in 0.2 seconds, and take 130 MB once every column is read
140
+ ([measurements](https://github.com/yhay81/vastgrid/blob/main/docs/benchmarks/memory-engine.md)).
141
+ - A Parquet file's columns have the types that DuckDB reads them as, with DuckDB's names as `sourceType`: integers
142
+ by their width and sign (UINTEGER as `bigint`, UBIGINT as `decimal(38, 0)`), FLOAT and DOUBLE, decimals,
143
+ BOOLEAN, DATE, TIME, timestamps of their unit (`timestamptz` when adjusted to UTC), INTERVAL, UUID, VARCHAR and
144
+ enums as strings, BLOB as `binary`, and JSON as `readOnly` strings. Lists, structs and maps are `readOnly`
145
+ strings of their JSON text, named as DuckDB names them (`INTEGER[]`, `STRUCT(a INTEGER)`). A URL's first answer
146
+ gives its size and its `ETag` or `Last-Modified`, which every later answer must match: a file that changed fails
147
+ with `file_changed`. Ranges read are kept in a cache of 32 MiB; a server that ignores `Range` sends the file
148
+ whole, which is kept when it is at most 16 MiB and fails with `load_failed` otherwise. A server of another
149
+ origin must expose `Content-Length`, `Content-Range` and `ETag` by CORS. The code that reads Parquet loads with
150
+ the first such table.
151
+ - Float32 table values and writes must already be binary32 numbers (`Math.fround(0.1)`, not `0.1`);
152
+ `readCellText` converts typed input to them. Invalid timestamps, intervals and lone Unicode surrogates
153
+ are rejected by the same specification checks used to write Arrow blocks. An invalid write changes
154
+ no cells and identifies the offending value with `/updates/{index}/value`.
155
+ - `engine.handle(message)` answers a request with its response or error, with blocks in the structured
156
+ encoding (`{ bytes }`, §8.8), and never throws; `cancel` has no answer. `engine.subscribe(listener)` listens
157
+ to the events of §8.5: `changed` after every write.
158
+ - The engine offers what `MEMORY_CAPABILITIES` reports (§4.10): every plan of §4.1 (derive, `where`, search,
159
+ `aggregate` with `pivot`, `having` and sort), with every function of §4.4 and every measure of §4.5,
160
+ `summarize`, `find`, `locate`, `export` of CSV, TSV, JSON and xlsx, and `write` for tables given with
161
+ `editable: true` (§7.2: by row ID or by `rowKey`, every update or none, with `previous` checked, and a `changed`
162
+ event). Written values are kept apart from the host's rows, bytes or file, which stay as they were: the engine keeps
163
+ them by row and column over the column, without a copy of it, so that a write takes the memory of the values
164
+ written. A table that holds them keeps them when it is closed. Other plans fail with
165
+ `invalid_plan` (`unsupported`) only when they name functions or members that a later version adds, `write` on
166
+ other tables with `read_only`, `save` with `save_unsupported`, and an `export` of Parquet with `invalid_request`
167
+ at `/format`.
168
+ - `find` goes through the view's cells row by row from the cell after `from` and compares their text forms (§2.4)
169
+ by `lower`, as the DuckDB engine does. `export` answers the file's bytes as `data` (`delivery` `data`, §8.2) and
170
+ takes no `target`: CSV, TSV and JSON as DuckDB's `COPY` writes them (`vastgrid-spec/export`) and workbooks with
171
+ `vastgrid-spec/xlsx`, compressed with the platform's `CompressionStream`. The file is made in memory, a batch of
172
+ rows at a time, so it takes about its size besides the table; a grid downloads it as a file
173
+ (`URL.createObjectURL`). That is how a page saves: the engine writes no file, and the `File` that a table was
174
+ opened from stays as it was.
175
+ - A request that goes through many rows (`find`, `export`), reads a file's columns whole or ranks the text of the
176
+ columns that a view sorts or groups by lets other messages in every 40 ms or so, so that a `cancel` of it is read:
177
+ it then stops with `cancelled` (§8.6) within a few milliseconds. The rest of a view (ranking numbers, sorting,
178
+ filtering, grouping and deriving) runs to its end, and the view is kept; a cancel of it answers `cancelled` after.
179
+ - Expressions are compiled once per view to functions of a row ID (§3.6, §3.7, §4.4): exact numbers are
180
+ computed as integers at their scale, with BigInt where a number would not be exact, so a result that does not
181
+ fit its type is null rather than rounded; floats are 64-bit, and results that are not finite are null.
182
+ Strings compare by code point, and `lower` and `upper` map code points one by one as DuckDB 2.0 does (`İ` →
183
+ `i`, `ß` → `ẞ`). Derived columns are computed for every row of the table, then `where` keeps the rows of the
184
+ view; `locate` gives null for rows that it leaves out. A million rows derive a decimal product, filter by it
185
+ and sort by it in about 0.7 seconds.
186
+ - Groups are made from the ranks of their keys, so that values equal by §3.1 make one group (every NaN, −0.0 and
187
+ 0.0) and groups come in the order of §3.9; each measure keeps its state per group, or per group and pivot
188
+ combination. Sums of exact numbers are exact, and null when they do not fit decimal(38, s); averages come
189
+ from the exact sum; `stddev` is Welford's sample standard deviation and `quantile` interpolates as DuckDB's
190
+ `quantile_cont`. Approximate measures are computed exactly. A view of groups has no row IDs: `rows` answers
191
+ `rowIds` null, `locate` finds values of a key of the view (by `rowKey`) and nothing by row ID. A million rows
192
+ group by 1,000 keys with four measures and sort in about 0.5 seconds.
193
+ - Plans that derive, filter or group are run by a module of their own, loaded with the first such plan, so that
194
+ pages whose plans only sort do not load it.
195
+ - Views are in the order of §3.3. Each column's values are ranked once, by a radix sort of their bits for
196
+ values of fixed width and by code point for strings; a view is then one counting sort per sort key. A
197
+ million floats sort in about 0.2 seconds. Intervals compare as DuckDB 2.0 compares them (`normalizeInterval`
198
+ of `vastgrid-spec`): by their length, with months of 30 days and days of 24 hours, so that `1 month -1 day`
199
+ equals `29 days`.
200
+ - `locate` finds a value of `rowKey` at its first position in the view; `summarize` counts each cell of
201
+ `ranges` × `columns` once, sums exact numbers exactly, and gives floats that are not finite as cells but
202
+ not as numbers.
203
+
204
+ The tests run every case of the conformance corpus of [`vastgrid-spec`](https://www.npmjs.com/package/vastgrid-spec), with its tables as rows and as
205
+ Arrow, check the order of both against a comparison of values one pair at a time on generated tables, and check
206
+ every response with `checkResponse`. Files are read in slices of every size from 1 byte, and a generated CSV file
207
+ answers sorts, filters, groups and summaries as the same rows given as typed JSON. The
208
+ DuckDB engine's tests compare this engine's answers with its own on a generated table and generated plans
209
+ (`packages/duckdb-engine/test/memory-engine.test.ts`), with the table as a Parquet file that DuckDB wrote too: the
210
+ same columns, and the same answers. Another test serves a Parquet file over HTTP and counts the bytes that opening,
211
+ reading rows and sorting read. `packages/duckdb-engine/bench/memory-engine.ts` measures a million rows as CSV and as
212
+ Parquet ([results](https://github.com/yhay81/vastgrid/blob/main/docs/benchmarks/memory-engine.md)).
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Groups (docs/spec.md §3.8, §3.9, §4.5, §4.6): the rows that `where` keeps, one group for each combination
3
+ * of the ranks of their keys, with the measures of each group and the generated columns of a pivot.
4
+ *
5
+ * Ranks make groups by §3.1 equality (all NaNs are one value, −0.0 and 0.0 are one) and order them as §3.9 does:
6
+ * values ascending, then the empty string, then null. Groups are numbered in that order, so a view without
7
+ * `sort` is the groups in number order, and a sort is stable over them.
8
+ */
9
+ import { type CheckedAggregate, type Column, type JsonValue, type TypedExpr } from "vastgrid-spec";
10
+ import type { ColumnRanks } from "./order.js";
11
+ import type { Vector } from "./table.js";
12
+ /** What grouping reads: the columns of the rows before grouping, by name, and the rows that `where` keeps. */
13
+ export interface GroupInput {
14
+ aggregate: CheckedAggregate;
15
+ /** The view's columns that the checked plan knows: the keys, then the measures unless there is a pivot. */
16
+ columns: Column[];
17
+ /** The row IDs that `where` keeps, in order; null for every row of the table. */
18
+ rows: Uint32Array | null;
19
+ /** The rows of the table. */
20
+ count: number;
21
+ /** A column's values by row ID: a column of the table or a derived one. */
22
+ values(name: string): Vector;
23
+ /** A column's ranks by row ID (§3.3). */
24
+ ranks(name: string): ColumnRanks;
25
+ }
26
+ /** A column of groups: its values by group number. */
27
+ export interface GroupColumn {
28
+ column: Column;
29
+ values: JsonValue[];
30
+ }
31
+ /** The groups of a view: its columns, their values by group number, and the groups that `having` keeps. */
32
+ export interface Groups {
33
+ columns: Column[];
34
+ values: Map<string, GroupColumn>;
35
+ count: number;
36
+ /** The groups that `having` keeps, in order; null without `having`. */
37
+ kept: Uint32Array | null;
38
+ }
39
+ /**
40
+ * The groups of the rows that `where` keeps, with the measures of each, or with a pivot's generated columns, and
41
+ * those that `having` keeps. Throws a `SpecError` (`too_many_columns`) for a pivot that would make more columns
42
+ * than `maxColumns`.
43
+ */
44
+ export declare function groupRows(input: GroupInput, having: TypedExpr | null): Groups;
45
+ //# sourceMappingURL=aggregate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../src/aggregate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,MAAM,EACX,KAAK,SAAS,EAEd,KAAK,SAAS,EAKf,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,8GAA8G;AAC9G,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,2GAA2G;IAC3G,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,iFAAiF;IACjF,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,yCAAyC;IACzC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;CAClC;AAED,sDAAsD;AACtD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,2GAA2G;AAC3G,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;CAC1B;AAiOD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,CAS7E"}
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Groups (docs/spec.md §3.8, §3.9, §4.5, §4.6): the rows that `where` keeps, one group for each combination
3
+ * of the ranks of their keys, with the measures of each group and the generated columns of a pivot.
4
+ *
5
+ * Ranks make groups by §3.1 equality (all NaNs are one value, −0.0 and 0.0 are one) and order them as §3.9 does:
6
+ * values ascending, then the empty string, then null. Groups are numbered in that order, so a view without
7
+ * `sort` is the groups in number order, and a sort is stable over them.
8
+ */
9
+ import { SpecError, textOf, uniqueName, valueType, } from "vastgrid-spec";
10
+ import { comparer, decimalText, exactJson, filter, toFloat, unscaled } from "./evaluate.js";
11
+ /** Numbers the combinations of the ranks of columns among the rows, in the order of their ranks. */
12
+ function combine(ranks, rows, count) {
13
+ const length = rows ? rows.length : count;
14
+ const of = new Uint32Array(length);
15
+ if (ranks.length === 0)
16
+ return { of, firsts: length > 0 ? [rows ? rows[0] : 0] : [] };
17
+ // Each combination as one number while their product fits, otherwise as text.
18
+ const sizes = ranks.map((item) => item.distinct + 2);
19
+ const numeric = sizes.reduce((product, size) => product * size, 1) <= Number.MAX_SAFE_INTEGER;
20
+ const found = new Map();
21
+ const firsts = [];
22
+ for (let at = 0; at < length; at++) {
23
+ const row = rows ? rows[at] : at;
24
+ let key;
25
+ if (ranks.length === 1)
26
+ key = ranks[0].ranks[row];
27
+ else if (numeric) {
28
+ key = 0;
29
+ for (let which = 0; which < ranks.length; which++)
30
+ key = key * sizes[which] + ranks[which].ranks[row];
31
+ }
32
+ else
33
+ key = ranks.map((item) => item.ranks[row]).join(",");
34
+ let id = found.get(key);
35
+ if (id === undefined) {
36
+ id = firsts.length;
37
+ found.set(key, id);
38
+ firsts.push(row);
39
+ }
40
+ of[at] = id;
41
+ }
42
+ // Renumber in the order of the ranks.
43
+ const order = firsts.map((_, id) => id);
44
+ order.sort((a, b) => {
45
+ for (const item of ranks) {
46
+ const difference = item.ranks[firsts[a]] - item.ranks[firsts[b]];
47
+ if (difference !== 0)
48
+ return difference;
49
+ }
50
+ return 0;
51
+ });
52
+ const renumbered = new Uint32Array(order.length);
53
+ order.forEach((id, place) => {
54
+ renumbered[id] = place;
55
+ });
56
+ for (let at = 0; at < length; at++)
57
+ of[at] = renumbered[of[at]];
58
+ return { of, firsts: order.map((id) => firsts[id]) };
59
+ }
60
+ /** Whether a value counts for a measure (§3.8): not null, and for floats, finite except for counts. */
61
+ function counted(column, measure) {
62
+ if (column.type !== "float" || measure.fn === "count" || measure.fn === "count_distinct") {
63
+ return (value) => value !== null;
64
+ }
65
+ return (value) => value !== null && typeof value === "number";
66
+ }
67
+ function accumulator(measure, input, cells) {
68
+ const column = measure.column;
69
+ if (!column) {
70
+ const counts = new Float64Array(cells);
71
+ return {
72
+ add: (cell) => {
73
+ counts[cell]++;
74
+ },
75
+ result: (cell) => counts[cell],
76
+ };
77
+ }
78
+ const values = input.values(column.name);
79
+ const takes = counted(column, measure);
80
+ switch (measure.fn) {
81
+ case "count": {
82
+ const counts = new Float64Array(cells);
83
+ return {
84
+ add: (cell, row) => {
85
+ if (values.at(row) !== null)
86
+ counts[cell]++;
87
+ },
88
+ result: (cell) => counts[cell],
89
+ };
90
+ }
91
+ case "count_distinct": {
92
+ const { ranks, distinct } = input.ranks(column.name);
93
+ const seen = new Array(cells);
94
+ return {
95
+ add: (cell, row) => {
96
+ const rank = ranks[row];
97
+ if (rank > distinct)
98
+ return;
99
+ let set = seen[cell];
100
+ if (!set) {
101
+ set = new Set();
102
+ seen[cell] = set;
103
+ }
104
+ set.add(rank);
105
+ },
106
+ result: (cell) => seen[cell]?.size ?? 0,
107
+ };
108
+ }
109
+ case "sum":
110
+ case "avg":
111
+ return column.type === "float" ? floatSum(measure, values, cells) : exactSum(measure, column, values, cells);
112
+ case "stddev": {
113
+ // Welford's running mean and sum of squared differences.
114
+ const counts = new Float64Array(cells);
115
+ const means = new Float64Array(cells);
116
+ const squares = new Float64Array(cells);
117
+ return {
118
+ add: (cell, row) => {
119
+ const value = values.at(row);
120
+ if (!takes(value))
121
+ return;
122
+ const number = toFloat(value, column);
123
+ const count = ++counts[cell];
124
+ const delta = number - means[cell];
125
+ means[cell] += delta / count;
126
+ squares[cell] += delta * (number - means[cell]);
127
+ },
128
+ result: (cell) => (counts[cell] < 2 ? null : finite(Math.sqrt(squares[cell] / (counts[cell] - 1)))),
129
+ };
130
+ }
131
+ case "min":
132
+ case "max": {
133
+ const compare = comparer(column, column);
134
+ const greatest = measure.fn === "max";
135
+ const best = new Array(cells).fill(null);
136
+ return {
137
+ add: (cell, row) => {
138
+ const value = values.at(row);
139
+ if (!takes(value))
140
+ return;
141
+ const now = best[cell];
142
+ if (now === null || (greatest ? compare(value, now) > 0 : compare(value, now) < 0))
143
+ best[cell] = value;
144
+ },
145
+ result: (cell) => best[cell],
146
+ };
147
+ }
148
+ case "quantile": {
149
+ const p = measure.p ?? 0.5;
150
+ const numbers = new Array(cells);
151
+ return {
152
+ add: (cell, row) => {
153
+ const value = values.at(row);
154
+ if (!takes(value))
155
+ return;
156
+ let list = numbers[cell];
157
+ if (!list) {
158
+ list = [];
159
+ numbers[cell] = list;
160
+ }
161
+ list.push(toFloat(value, column));
162
+ },
163
+ // Linear interpolation between the two closest ranks (DuckDB's quantile_cont).
164
+ result: (cell) => {
165
+ const list = numbers[cell];
166
+ if (!list)
167
+ return null;
168
+ const sorted = Float64Array.from(list).sort();
169
+ const place = p * (sorted.length - 1);
170
+ const low = Math.floor(place);
171
+ const high = Math.ceil(place);
172
+ return finite(sorted[low] + (sorted[high] - sorted[low]) * (place - low));
173
+ },
174
+ };
175
+ }
176
+ }
177
+ }
178
+ function finite(value) {
179
+ return Number.isFinite(value) ? value + 0 : null;
180
+ }
181
+ /** `sum` and `avg` of floats, leaving out NaN and the infinities (§3.8). */
182
+ function floatSum(measure, values, cells) {
183
+ const counts = new Float64Array(cells);
184
+ const sums = new Float64Array(cells);
185
+ return {
186
+ add: (cell, row) => {
187
+ const value = values.at(row);
188
+ if (typeof value !== "number")
189
+ return;
190
+ counts[cell]++;
191
+ sums[cell] += value;
192
+ },
193
+ result: (cell) => {
194
+ if (counts[cell] === 0)
195
+ return null;
196
+ return measure.fn === "avg" ? finite(sums[cell] / counts[cell]) : finite(sums[cell]);
197
+ },
198
+ };
199
+ }
200
+ /**
201
+ * `sum` and `avg` of exact numbers: an exact sum, in numbers while they stay exact and in BigInt beyond; a sum
202
+ * that does not fit decimal(38, s) is null, and the average is computed from the exact sum (§3.8).
203
+ */
204
+ function exactSum(measure, column, values, cells) {
205
+ const scale = column.type === "decimal" ? (column.scale ?? 0) : 0;
206
+ const counts = new Float64Array(cells);
207
+ const small = new Float64Array(cells);
208
+ const large = new Array(cells);
209
+ return {
210
+ add: (cell, row) => {
211
+ const value = values.at(row);
212
+ if (value === null)
213
+ return;
214
+ counts[cell]++;
215
+ let number = Number.NaN;
216
+ if (typeof value === "number")
217
+ number = value;
218
+ else if (value.length <= 16)
219
+ number = Number(scale === 0 ? value : value.replace(".", ""));
220
+ const total = small[cell] + number;
221
+ if (Number.isSafeInteger(number) && Number.isSafeInteger(total))
222
+ small[cell] = total;
223
+ else
224
+ large[cell] = (large[cell] ?? 0n) + unscaled(value, column);
225
+ },
226
+ result: (cell) => {
227
+ if (counts[cell] === 0)
228
+ return null;
229
+ const total = BigInt(small[cell]) + (large[cell] ?? 0n);
230
+ if (measure.fn === "avg")
231
+ return finite(Number(decimalText(total, scale)) / counts[cell]);
232
+ return exactJson(total, measure.type);
233
+ },
234
+ };
235
+ }
236
+ /**
237
+ * The groups of the rows that `where` keeps, with the measures of each, or with a pivot's generated columns, and
238
+ * those that `having` keeps. Throws a `SpecError` (`too_many_columns`) for a pivot that would make more columns
239
+ * than `maxColumns`.
240
+ */
241
+ export function groupRows(input, having) {
242
+ const { columns, values, count } = groupColumns(input);
243
+ const byName = new Map();
244
+ for (const column of columns)
245
+ byName.set(column.name, { column, values: values.get(column.name) });
246
+ const read = (name) => {
247
+ const found = byName.get(name).values;
248
+ return (group) => found[group];
249
+ };
250
+ return { columns, values: byName, count, kept: having ? filter(having, read, count) : null };
251
+ }
252
+ function groupColumns(input) {
253
+ const { aggregate, rows, count } = input;
254
+ const { keys, measures, pivot } = aggregate;
255
+ const length = rows ? rows.length : count;
256
+ const groups = combine(keys.map((key) => input.ranks(key.name)), rows, count);
257
+ // Without keys, one group, also over no rows.
258
+ const groupCount = keys.length === 0 ? 1 : groups.firsts.length;
259
+ const combinations = pivot
260
+ ? combine(pivot.columns.map((column) => input.ranks(column.name)), rows, count)
261
+ : null;
262
+ const width = combinations ? combinations.firsts.length : 1;
263
+ if (pivot && width * measures.length > pivot.maxColumns) {
264
+ throw new SpecError("too_many_columns", `The pivot makes more than ${pivot.maxColumns} columns (§4.6).`);
265
+ }
266
+ const accumulators = measures.map((measure) => accumulator(measure, input, groupCount * width));
267
+ for (let at = 0; at < length; at++) {
268
+ const row = rows ? rows[at] : at;
269
+ const cell = groups.of[at] * width + (combinations ? combinations.of[at] : 0);
270
+ for (const item of accumulators)
271
+ item.add(cell, row);
272
+ }
273
+ const columns = [...input.columns];
274
+ const values = new Map();
275
+ for (const key of keys) {
276
+ const source = input.values(key.name);
277
+ values.set(key.name, groups.firsts.map((row) => source.at(row)));
278
+ }
279
+ const results = (measure, combination) => Array.from({ length: groupCount }, (_, group) => accumulators[measure].result(group * width + combination));
280
+ if (!pivot || !combinations) {
281
+ measures.forEach((measure, index) => {
282
+ values.set(measure.name, results(index, 0));
283
+ });
284
+ return { columns, values, count: groupCount };
285
+ }
286
+ const taken = new Set(columns.map((column) => column.name));
287
+ combinations.firsts.forEach((row, combination) => {
288
+ const combinationValues = pivot.columns.map((column) => input.values(column.name).at(row));
289
+ const labels = combinationValues.map((value, index) => {
290
+ const text = textOf(value, pivot.columns[index]);
291
+ return text === null ? "(null)" : text === "" ? "(empty)" : text;
292
+ });
293
+ measures.forEach((measure, index) => {
294
+ const name = uniqueName([...labels, measure.name].join(" / "), taken);
295
+ columns.push({
296
+ name,
297
+ ...valueType(measure.type),
298
+ pivot: { values: combinationValues, measure: measure.name },
299
+ });
300
+ values.set(name, results(index, combination));
301
+ });
302
+ });
303
+ return { columns, values, count: groupCount };
304
+ }
305
+ //# sourceMappingURL=aggregate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.js","sourceRoot":"","sources":["../src/aggregate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type CheckedTable } from "./table.js";
2
+ /**
3
+ * Checks a table given as Arrow and reads its columns: their logical types, and their values kept as Arrow holds
4
+ * them. Throws a `TableProblem` at `/arrow` for bytes that are not an Arrow table of §2.3.
5
+ */
6
+ export declare function checkArrow(bytes: unknown): CheckedTable;
7
+ //# sourceMappingURL=arrow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arrow.d.ts","sourceRoot":"","sources":["../src/arrow.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAA4B,MAAM,YAAY,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAYvD"}