vastgrid-js 0.0.0-stage → 0.2.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.
- package/LICENSE +21 -0
- package/README.md +211 -2
- package/dist/aggregate.d.ts +45 -0
- package/dist/aggregate.d.ts.map +1 -0
- package/dist/aggregate.js +305 -0
- package/dist/aggregate.js.map +1 -0
- package/dist/arrow.d.ts +7 -0
- package/dist/arrow.d.ts.map +1 -0
- package/dist/arrow.js +25 -0
- package/dist/arrow.js.map +1 -0
- package/dist/engine.d.ts +40 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +1022 -0
- package/dist/engine.js.map +1 -0
- package/dist/evaluate.d.ts +37 -0
- package/dist/evaluate.d.ts.map +1 -0
- package/dist/evaluate.js +774 -0
- package/dist/evaluate.js.map +1 -0
- package/dist/export.d.ts +23 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +48 -0
- package/dist/export.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/lazy.d.ts +65 -0
- package/dist/lazy.d.ts.map +1 -0
- package/dist/lazy.js +177 -0
- package/dist/lazy.js.map +1 -0
- package/dist/numbers.d.ts +20 -0
- package/dist/numbers.d.ts.map +1 -0
- package/dist/numbers.js +129 -0
- package/dist/numbers.js.map +1 -0
- package/dist/order.d.ts +67 -0
- package/dist/order.d.ts.map +1 -0
- package/dist/order.js +561 -0
- package/dist/order.js.map +1 -0
- package/dist/parquet.d.ts +38 -0
- package/dist/parquet.d.ts.map +1 -0
- package/dist/parquet.js +673 -0
- package/dist/parquet.js.map +1 -0
- package/dist/plan.d.ts +37 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +51 -0
- package/dist/plan.js.map +1 -0
- package/dist/summary.d.ts +37 -0
- package/dist/summary.d.ts.map +1 -0
- package/dist/summary.js +175 -0
- package/dist/summary.js.map +1 -0
- package/dist/table.d.ts +172 -0
- package/dist/table.d.ts.map +1 -0
- package/dist/table.js +154 -0
- package/dist/table.js.map +1 -0
- package/dist/text.d.ts +18 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +1204 -0
- package/dist/text.js.map +1 -0
- package/dist/workbook.d.ts +6 -0
- package/dist/workbook.d.ts.map +1 -0
- package/dist/workbook.js +35 -0
- package/dist/workbook.js.map +1 -0
- package/package.json +46 -4
- package/src/aggregate.ts +358 -0
- package/src/arrow.ts +24 -0
- package/src/engine.ts +1163 -0
- package/src/evaluate.ts +764 -0
- package/src/export.ts +73 -0
- package/src/index.ts +2 -0
- package/src/lazy.ts +185 -0
- package/src/numbers.ts +128 -0
- package/src/order.ts +594 -0
- package/src/parquet.ts +801 -0
- package/src/plan.ts +99 -0
- package/src/summary.ts +180 -0
- package/src/table.ts +297 -0
- package/src/text.ts +1285 -0
- 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
|
-
#
|
|
1
|
+
# vastgrid-js
|
|
2
2
|
|
|
3
|
-
|
|
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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"}
|
package/dist/arrow.d.ts
ADDED
|
@@ -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"}
|