@query-farm/vgi-rpc 0.6.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-log.d.ts +50 -0
- package/dist/access-log.d.ts.map +1 -0
- package/dist/arrow/impl-arrowjs/index.d.ts +96 -0
- package/dist/arrow/impl-arrowjs/index.d.ts.map +1 -0
- package/dist/arrow/impl-flechette/index.d.ts +102 -0
- package/dist/arrow/impl-flechette/index.d.ts.map +1 -0
- package/dist/arrow/impl-flechette/message-meta.d.ts +11 -0
- package/dist/arrow/impl-flechette/message-meta.d.ts.map +1 -0
- package/dist/arrow/index.d.ts +4 -0
- package/dist/arrow/index.d.ts.map +1 -0
- package/dist/arrow/predicates.d.ts +44 -0
- package/dist/arrow/predicates.d.ts.map +1 -0
- package/dist/arrow/types.d.ts +62 -0
- package/dist/arrow/types.d.ts.map +1 -0
- package/dist/client/capabilities.d.ts +25 -0
- package/dist/client/capabilities.d.ts.map +1 -0
- package/dist/client/connect.d.ts.map +1 -1
- package/dist/client/introspect.d.ts +7 -0
- package/dist/client/introspect.d.ts.map +1 -1
- package/dist/client/ipc.d.ts +8 -2
- package/dist/client/ipc.d.ts.map +1 -1
- package/dist/client/pipe.d.ts.map +1 -1
- package/dist/client/stream.d.ts +11 -2
- package/dist/client/stream.d.ts.map +1 -1
- package/dist/client/uploadUrl.d.ts +25 -0
- package/dist/client/uploadUrl.d.ts.map +1 -0
- package/dist/constants.d.ts +15 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/crypto.d.ts +22 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/dispatch/describe.d.ts +10 -6
- package/dist/dispatch/describe.d.ts.map +1 -1
- package/dist/dispatch/stream.d.ts +2 -2
- package/dist/dispatch/stream.d.ts.map +1 -1
- package/dist/dispatch/unary.d.ts +2 -2
- package/dist/dispatch/unary.d.ts.map +1 -1
- package/dist/errors.d.ts +46 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/external.d.ts +25 -5
- package/dist/external.d.ts.map +1 -1
- package/dist/http/bearer.d.ts.map +1 -1
- package/dist/http/common.d.ts +42 -7
- package/dist/http/common.d.ts.map +1 -1
- package/dist/http/dispatch.d.ts +20 -2
- package/dist/http/dispatch.d.ts.map +1 -1
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/index.d.ts +1 -0
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/mtls.d.ts +2 -1
- package/dist/http/mtls.d.ts.map +1 -1
- package/dist/http/oauth-pkce.d.ts +141 -0
- package/dist/http/oauth-pkce.d.ts.map +1 -0
- package/dist/http/pages.d.ts +3 -0
- package/dist/http/pages.d.ts.map +1 -1
- package/dist/http/sticky.d.ts +124 -0
- package/dist/http/sticky.d.ts.map +1 -0
- package/dist/http/token.d.ts +38 -12
- package/dist/http/token.d.ts.map +1 -1
- package/dist/http/types.d.ts +68 -5
- package/dist/http/types.d.ts.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1275 -3507
- package/dist/index.js.map +19 -37
- package/dist/launcher/hash.d.ts +22 -0
- package/dist/launcher/hash.d.ts.map +1 -0
- package/dist/launcher/index.d.ts +23 -0
- package/dist/launcher/index.d.ts.map +1 -0
- package/dist/launcher/launch.d.ts +27 -0
- package/dist/launcher/launch.d.ts.map +1 -0
- package/dist/launcher/lock.d.ts +19 -0
- package/dist/launcher/lock.d.ts.map +1 -0
- package/dist/launcher/serve-unix.d.ts +54 -0
- package/dist/launcher/serve-unix.d.ts.map +1 -0
- package/dist/launcher/state.d.ts +59 -0
- package/dist/launcher/state.d.ts.map +1 -0
- package/dist/otel.d.ts.map +1 -1
- package/dist/protocol.d.ts +16 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/schema.d.ts +45 -18
- package/dist/schema.d.ts.map +1 -1
- package/dist/server.d.ts +23 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/types.d.ts +216 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/util/gzip.d.ts +10 -0
- package/dist/util/gzip.d.ts.map +1 -0
- package/dist/util/schema.d.ts +3 -15
- package/dist/util/schema.d.ts.map +1 -1
- package/dist/util/web-crypto.d.ts +22 -0
- package/dist/util/web-crypto.d.ts.map +1 -0
- package/dist/util/zstd.d.ts +26 -3
- package/dist/util/zstd.d.ts.map +1 -1
- package/dist/wire/opaque.d.ts +11 -0
- package/dist/wire/opaque.d.ts.map +1 -0
- package/dist/wire/reader.d.ts +5 -5
- package/dist/wire/reader.d.ts.map +1 -1
- package/dist/wire/request.d.ts +11 -3
- package/dist/wire/request.d.ts.map +1 -1
- package/dist/wire/response.d.ts +6 -6
- package/dist/wire/response.d.ts.map +1 -1
- package/dist/wire/writer.d.ts +49 -39
- package/dist/wire/writer.d.ts.map +1 -1
- package/package.json +24 -10
- package/src/access-log.ts +195 -0
- package/src/arrow/impl-arrowjs/index.ts +433 -0
- package/src/arrow/impl-flechette/index.ts +414 -0
- package/src/arrow/impl-flechette/message-meta.ts +174 -0
- package/src/arrow/index.ts +89 -0
- package/src/arrow/predicates.ts +56 -0
- package/src/arrow/types.ts +73 -0
- package/src/client/capabilities.ts +84 -0
- package/src/client/connect.ts +103 -26
- package/src/client/introspect.ts +60 -38
- package/src/client/ipc.ts +37 -27
- package/src/client/pipe.ts +12 -9
- package/src/client/stream.ts +34 -19
- package/src/client/uploadUrl.ts +169 -0
- package/src/constants.ts +18 -1
- package/src/crypto.ts +95 -0
- package/src/dispatch/describe.ts +146 -107
- package/src/dispatch/stream.ts +53 -24
- package/src/dispatch/unary.ts +5 -4
- package/src/errors.ts +76 -0
- package/src/external.ts +43 -29
- package/src/http/bearer.ts +2 -5
- package/src/http/common.ts +90 -23
- package/src/http/dispatch.ts +373 -46
- package/src/http/handler.ts +794 -68
- package/src/http/index.ts +1 -0
- package/src/http/mtls.ts +18 -3
- package/src/http/oauth-pkce.ts +1035 -0
- package/src/http/pages.ts +30 -15
- package/src/http/sticky.ts +429 -0
- package/src/http/token.ts +165 -75
- package/src/http/types.ts +69 -5
- package/src/index.ts +40 -1
- package/src/launcher/hash.ts +104 -0
- package/src/launcher/index.ts +35 -0
- package/src/launcher/launch.ts +284 -0
- package/src/launcher/lock.ts +171 -0
- package/src/launcher/serve-unix.ts +385 -0
- package/src/launcher/state.ts +245 -0
- package/src/otel.ts +39 -33
- package/src/protocol.ts +27 -3
- package/src/schema.ts +107 -56
- package/src/server.ts +196 -20
- package/src/types.ts +322 -18
- package/src/util/gzip.ts +63 -0
- package/src/util/schema.ts +4 -22
- package/src/util/web-crypto.ts +98 -0
- package/src/util/zstd.ts +133 -14
- package/src/wire/opaque.ts +37 -0
- package/src/wire/reader.ts +5 -4
- package/src/wire/request.ts +67 -8
- package/src/wire/response.ts +51 -85
- package/src/wire/writer.ts +165 -69
- package/dist/util/conform.d.ts +0 -18
- package/dist/util/conform.d.ts.map +0 -1
- package/src/util/conform.ts +0 -94
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
// flechette backend for vgi-rpc-typescript's Arrow facade.
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type Column,
|
|
5
|
+
TimeUnit as F_TimeUnit,
|
|
6
|
+
binary as f_binary,
|
|
7
|
+
bool as f_bool,
|
|
8
|
+
columnFromArray as f_columnFromArray,
|
|
9
|
+
dateDay as f_dateDay,
|
|
10
|
+
decimal as f_decimal,
|
|
11
|
+
dictionary as f_dictionary,
|
|
12
|
+
duration as f_duration,
|
|
13
|
+
field as f_field,
|
|
14
|
+
fixedSizeBinary as f_fixedSizeBinary,
|
|
15
|
+
float32 as f_float32,
|
|
16
|
+
float64 as f_float64,
|
|
17
|
+
int8 as f_int8,
|
|
18
|
+
int16 as f_int16,
|
|
19
|
+
int32 as f_int32,
|
|
20
|
+
int64 as f_int64,
|
|
21
|
+
largeBinary as f_largeBinary,
|
|
22
|
+
largeUtf8 as f_largeUtf8,
|
|
23
|
+
list as f_list,
|
|
24
|
+
map as f_map,
|
|
25
|
+
nullType as f_nullType,
|
|
26
|
+
struct as f_struct,
|
|
27
|
+
timeMicrosecond as f_timeMicrosecond,
|
|
28
|
+
timestamp as f_timestamp,
|
|
29
|
+
uint8 as f_uint8,
|
|
30
|
+
uint16 as f_uint16,
|
|
31
|
+
uint32 as f_uint32,
|
|
32
|
+
uint64 as f_uint64,
|
|
33
|
+
utf8 as f_utf8,
|
|
34
|
+
Table,
|
|
35
|
+
tableFromColumns,
|
|
36
|
+
tableFromIPC,
|
|
37
|
+
tablesToIPC,
|
|
38
|
+
tableToIPC,
|
|
39
|
+
} from "@uwdata/flechette";
|
|
40
|
+
|
|
41
|
+
import type {
|
|
42
|
+
IncrementalEncoder,
|
|
43
|
+
VgiBackendInfo,
|
|
44
|
+
VgiBatch,
|
|
45
|
+
VgiColumnData,
|
|
46
|
+
VgiDataType,
|
|
47
|
+
VgiField,
|
|
48
|
+
VgiSchema,
|
|
49
|
+
} from "../types.js";
|
|
50
|
+
import { readFirstRecordBatchMeta } from "./message-meta.js";
|
|
51
|
+
|
|
52
|
+
export const backend: VgiBackendInfo = { name: "flechette", opaquePassthrough: false };
|
|
53
|
+
|
|
54
|
+
const EXTRACT_OPTS = {
|
|
55
|
+
useBigInt: true,
|
|
56
|
+
useBigIntTimestamp: true,
|
|
57
|
+
useDecimalInt: true,
|
|
58
|
+
useMap: false,
|
|
59
|
+
} as const;
|
|
60
|
+
|
|
61
|
+
// ----- Type factories ------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
export const nullType = (): VgiDataType => f_nullType() as unknown as VgiDataType;
|
|
64
|
+
export const bool = (): VgiDataType => f_bool() as unknown as VgiDataType;
|
|
65
|
+
export const int8 = (): VgiDataType => f_int8() as unknown as VgiDataType;
|
|
66
|
+
export const int16 = (): VgiDataType => f_int16() as unknown as VgiDataType;
|
|
67
|
+
export const int32 = (): VgiDataType => f_int32() as unknown as VgiDataType;
|
|
68
|
+
export const int64 = (): VgiDataType => f_int64() as unknown as VgiDataType;
|
|
69
|
+
export const uint8 = (): VgiDataType => f_uint8() as unknown as VgiDataType;
|
|
70
|
+
export const uint16 = (): VgiDataType => f_uint16() as unknown as VgiDataType;
|
|
71
|
+
export const uint32 = (): VgiDataType => f_uint32() as unknown as VgiDataType;
|
|
72
|
+
export const uint64 = (): VgiDataType => f_uint64() as unknown as VgiDataType;
|
|
73
|
+
export const float32 = (): VgiDataType => f_float32() as unknown as VgiDataType;
|
|
74
|
+
export const float64 = (): VgiDataType => f_float64() as unknown as VgiDataType;
|
|
75
|
+
export const utf8 = (): VgiDataType => f_utf8() as unknown as VgiDataType;
|
|
76
|
+
export const binary = (): VgiDataType => f_binary() as unknown as VgiDataType;
|
|
77
|
+
|
|
78
|
+
/** Microsecond Timestamp with optional timezone. */
|
|
79
|
+
export const timestampMicro = (timezone: string | null = null): VgiDataType =>
|
|
80
|
+
f_timestamp(F_TimeUnit.MICROSECOND, timezone) as unknown as VgiDataType;
|
|
81
|
+
|
|
82
|
+
/** Date32 with day resolution. */
|
|
83
|
+
export const dateDay = (): VgiDataType => f_dateDay() as unknown as VgiDataType;
|
|
84
|
+
/** Time64 with microsecond resolution. */
|
|
85
|
+
export const timeMicro = (): VgiDataType => f_timeMicrosecond() as unknown as VgiDataType;
|
|
86
|
+
/** Duration with microsecond resolution. */
|
|
87
|
+
export const durationMicro = (): VgiDataType => f_duration(F_TimeUnit.MICROSECOND) as unknown as VgiDataType;
|
|
88
|
+
/** Decimal128 by default; pass bitWidth=256 for Decimal256. */
|
|
89
|
+
export const decimal = (precision: number, scale: number, bitWidth: 128 | 256 = 128): VgiDataType =>
|
|
90
|
+
f_decimal(precision, scale, bitWidth) as unknown as VgiDataType;
|
|
91
|
+
/** FixedSizeBinary with the given byte width. */
|
|
92
|
+
export const fixedSizeBinary = (byteWidth: number): VgiDataType =>
|
|
93
|
+
f_fixedSizeBinary(byteWidth) as unknown as VgiDataType;
|
|
94
|
+
/** LargeUtf8 — 64-bit-offset UTF-8 string. */
|
|
95
|
+
export const largeUtf8 = (): VgiDataType => f_largeUtf8() as unknown as VgiDataType;
|
|
96
|
+
/** LargeBinary — 64-bit-offset binary blob. */
|
|
97
|
+
export const largeBinary = (): VgiDataType => f_largeBinary() as unknown as VgiDataType;
|
|
98
|
+
/** List of `child` items. */
|
|
99
|
+
export const list = (child: VgiField): VgiDataType => f_list(child as any) as unknown as VgiDataType;
|
|
100
|
+
/** Struct of `fields`. */
|
|
101
|
+
export const struct = (fields: readonly VgiField[]): VgiDataType => f_struct(fields as any) as unknown as VgiDataType;
|
|
102
|
+
/** Map (key → value). flechette's `map(keyField, valueField, keysSorted)`
|
|
103
|
+
* builds the entries Struct internally — same shape as arrow-js's Map_
|
|
104
|
+
* but a less verbose API. */
|
|
105
|
+
export const map = (keyField: VgiField, valueField: VgiField, keysSorted = false): VgiDataType =>
|
|
106
|
+
f_map(keyField as any, valueField as any, keysSorted) as unknown as VgiDataType;
|
|
107
|
+
/** Dictionary-encoded type. `indices` must be an integer type. */
|
|
108
|
+
export const dictionary = (indices: VgiDataType, values: VgiDataType, id = -1, ordered = false): VgiDataType =>
|
|
109
|
+
f_dictionary(values as any, indices as any, ordered, id) as unknown as VgiDataType;
|
|
110
|
+
|
|
111
|
+
export function field(name: string, type: VgiDataType, nullable = true, metadata?: Map<string, string>): VgiField {
|
|
112
|
+
return f_field(name, type as any, nullable, metadata ?? new Map()) as unknown as VgiField;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function schema(fields: readonly VgiField[], metadata?: Map<string, string>): VgiSchema {
|
|
116
|
+
return {
|
|
117
|
+
fields,
|
|
118
|
+
metadata: metadata ?? new Map(),
|
|
119
|
+
} as VgiSchema;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ----- IPC -----------------------------------------------------------------
|
|
123
|
+
|
|
124
|
+
export function serializeSchema(s: VgiSchema): Uint8Array {
|
|
125
|
+
// Build directly so per-field nullable/metadata round-trip (same
|
|
126
|
+
// reason `batchFromColumns` goes through `buildTablePreservingNullable`
|
|
127
|
+
// below) AND so empty schemas stay empty on the wire — the previous
|
|
128
|
+
// version of this function injected a `__placeholder` column for
|
|
129
|
+
// empty schemas, which then leaked into state-token-embedded schema
|
|
130
|
+
// bytes and made `exchange_zero_columns` etc. see a 1-column schema
|
|
131
|
+
// on the next round-trip.
|
|
132
|
+
const cols = s.fields.map((f) => f_columnFromArray([], f.type as any));
|
|
133
|
+
const table = buildTablePreservingNullable(s, cols) as any;
|
|
134
|
+
return tableToIPC(table, { format: "stream" }) as Uint8Array;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function deserializeSchema(bytes: Uint8Array): VgiSchema {
|
|
138
|
+
return tableFromIPC(bytes, EXTRACT_OPTS).schema as unknown as VgiSchema;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function serializeBatch(batch: VgiBatch): Uint8Array {
|
|
142
|
+
return tableToIPC(batch as any, { format: "stream" }) as Uint8Array;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function deserializeBatch(bytes: Uint8Array): VgiBatch {
|
|
146
|
+
const table: any = tableFromIPC(bytes, EXTRACT_OPTS);
|
|
147
|
+
// The patched flechette decoder surfaces per-record-batch custom_metadata
|
|
148
|
+
// on `_vgiRecordMetadata`. flechette still doesn't carry RecordBatch
|
|
149
|
+
// length when the schema has zero columns (it derives numRows from the
|
|
150
|
+
// first column's batch length, which doesn't exist), so we still
|
|
151
|
+
// re-parse the FlatBuffer to recover the row count for that one
|
|
152
|
+
// shape. See message-meta.ts.
|
|
153
|
+
const recordMd: Map<string, string> | undefined = table._vgiRecordMetadata;
|
|
154
|
+
const wantMeta = !!recordMd && recordMd.size > 0;
|
|
155
|
+
// numRows fallback is only needed for zero-column batches.
|
|
156
|
+
const needRowsFallback = table.numRows === 0 && table.schema.fields.length === 0;
|
|
157
|
+
const meta = needRowsFallback ? readFirstRecordBatchMeta(bytes) : null;
|
|
158
|
+
const wantRows = meta !== null && meta.numRows > 0;
|
|
159
|
+
if (!wantRows && !wantMeta) return table as VgiBatch;
|
|
160
|
+
return new Proxy(table, {
|
|
161
|
+
get(target, prop, receiver) {
|
|
162
|
+
if (wantRows && prop === "numRows") return meta!.numRows;
|
|
163
|
+
if (wantMeta && prop === "metadata") return recordMd;
|
|
164
|
+
return Reflect.get(target, prop, receiver);
|
|
165
|
+
},
|
|
166
|
+
}) as unknown as VgiBatch;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ----- Construction --------------------------------------------------------
|
|
170
|
+
|
|
171
|
+
export function columnFromArray(values: any[], type: VgiDataType): VgiColumnData {
|
|
172
|
+
return f_columnFromArray(values, type as any, EXTRACT_OPTS) as VgiColumnData;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// flechette's `tableFromColumns` discards per-field `nullable`/`metadata` —
|
|
176
|
+
// it always builds nullable=true fields. The vgi-rpc wire protocol cares:
|
|
177
|
+
// the C++ extension validates response schemas exactly, and a `nullable`
|
|
178
|
+
// mismatch on a `not null` field rejects the whole batch. Build the Table
|
|
179
|
+
// directly with a schema that preserves the source VgiSchema's flags.
|
|
180
|
+
function buildTablePreservingNullable(s: VgiSchema, cols: Column<any>[]): VgiBatch {
|
|
181
|
+
const fields = s.fields.map((f, i) =>
|
|
182
|
+
f_field(f.name, cols[i].type as any, (f as any).nullable ?? true, (f as any).metadata ?? null),
|
|
183
|
+
);
|
|
184
|
+
const flechSchema = {
|
|
185
|
+
version: 5,
|
|
186
|
+
endianness: 0,
|
|
187
|
+
fields,
|
|
188
|
+
metadata: (s as any).metadata ?? null,
|
|
189
|
+
};
|
|
190
|
+
return new Table(flechSchema as any, cols) as unknown as VgiBatch;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// flechette's Map builder iterates values via for-of and rejects plain
|
|
194
|
+
// objects (`{}`) with "value is not iterable". Coerce Map-typed inputs so
|
|
195
|
+
// producer code passing `{}` (legal under arrow-js) keeps working.
|
|
196
|
+
function isMapType(t: VgiDataType): boolean {
|
|
197
|
+
return (t as any)?.typeId === 17;
|
|
198
|
+
}
|
|
199
|
+
function coerceForMap(v: any): any {
|
|
200
|
+
if (v == null || v instanceof Map) return v;
|
|
201
|
+
if (Array.isArray(v)) return new Map(v);
|
|
202
|
+
if (typeof v === "object") return new Map(Object.entries(v));
|
|
203
|
+
return v;
|
|
204
|
+
}
|
|
205
|
+
function coerceValuesForType(values: any[], type: VgiDataType): any[] {
|
|
206
|
+
return isMapType(type) ? values.map(coerceForMap) : values;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function singleRowBatch(s: VgiSchema, values: Record<string, any>): VgiBatch {
|
|
210
|
+
const cols: Column<any>[] = [];
|
|
211
|
+
for (const f of s.fields) {
|
|
212
|
+
let val = values[f.name];
|
|
213
|
+
if (f.type.typeId === 2 /* Int */ && (f.type as any).bitWidth === 64 && typeof val === "number") {
|
|
214
|
+
val = BigInt(val);
|
|
215
|
+
}
|
|
216
|
+
cols.push(f_columnFromArray(coerceValuesForType([val], f.type), f.type as any, EXTRACT_OPTS));
|
|
217
|
+
}
|
|
218
|
+
return buildTablePreservingNullable(s, cols);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function batchFromColumns(s: VgiSchema, columns: Record<string, any[]>): VgiBatch {
|
|
222
|
+
const numRows = s.fields.length > 0 ? (columns[s.fields[0].name]?.length ?? 0) : 0;
|
|
223
|
+
const cols: Column<any>[] = [];
|
|
224
|
+
for (const f of s.fields) {
|
|
225
|
+
const vals = columns[f.name] ?? new Array(numRows).fill(null);
|
|
226
|
+
cols.push(f_columnFromArray(coerceValuesForType(vals, f.type), f.type as any, EXTRACT_OPTS));
|
|
227
|
+
}
|
|
228
|
+
return buildTablePreservingNullable(s, cols);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function batchFromColumnData(
|
|
232
|
+
s: VgiSchema,
|
|
233
|
+
_numRows: number,
|
|
234
|
+
columnData: VgiColumnData[],
|
|
235
|
+
_metadata?: Map<string, string>,
|
|
236
|
+
): VgiBatch {
|
|
237
|
+
// flechette's Column objects ARE the column-data handles; build directly so
|
|
238
|
+
// we preserve the schema's per-field nullable/metadata flags.
|
|
239
|
+
return buildTablePreservingNullable(s, columnData as any);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function emptyColumnData(type: VgiDataType): VgiColumnData {
|
|
243
|
+
return f_columnFromArray([], type as any, EXTRACT_OPTS) as VgiColumnData;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* 0-row batch carrying per-record-batch (NOT schema) custom metadata.
|
|
248
|
+
*
|
|
249
|
+
* The vgi-rpc wire protocol puts per-call metadata (`vgi_rpc.log_level`,
|
|
250
|
+
* `vgi_rpc.server_id`, `vgi_rpc.request_id`, etc.) on the RecordBatch
|
|
251
|
+
* message — not on the Schema message. We stash it on the Table via
|
|
252
|
+
* `_vgiRecordMetadata`; our patched `tablesToIPC` picks it up and emits
|
|
253
|
+
* it as the Message FlatBuffer's `custom_metadata` field.
|
|
254
|
+
*/
|
|
255
|
+
export function emptyBatchWithMetadata(s: VgiSchema, metadata?: Map<string, string>): VgiBatch {
|
|
256
|
+
const cols: Record<string, Column<any>> = {};
|
|
257
|
+
for (const f of s.fields) {
|
|
258
|
+
cols[f.name] = f_columnFromArray([], f.type as any, EXTRACT_OPTS);
|
|
259
|
+
}
|
|
260
|
+
const t = tableFromColumns(cols) as any;
|
|
261
|
+
attachBatchMetadata(t, metadata);
|
|
262
|
+
return t as unknown as VgiBatch;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** 1-row result batch with optional per-record-batch metadata. */
|
|
266
|
+
export function singleRowBatchWithMetadata(
|
|
267
|
+
s: VgiSchema,
|
|
268
|
+
values: Record<string, any>,
|
|
269
|
+
metadata?: Map<string, string>,
|
|
270
|
+
): VgiBatch {
|
|
271
|
+
const cols: Record<string, Column<any>> = {};
|
|
272
|
+
for (const f of s.fields) {
|
|
273
|
+
let val = values[f.name];
|
|
274
|
+
if (f.type.typeId === 2 /* Int */ && (f.type as any).bitWidth === 64 && typeof val === "number") {
|
|
275
|
+
val = BigInt(val);
|
|
276
|
+
}
|
|
277
|
+
cols[f.name] = f_columnFromArray([val], f.type as any, EXTRACT_OPTS);
|
|
278
|
+
}
|
|
279
|
+
const t = tableFromColumns(cols) as any;
|
|
280
|
+
attachBatchMetadata(t, metadata);
|
|
281
|
+
return t as unknown as VgiBatch;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/** Pin per-record-batch metadata so that:
|
|
285
|
+
* - `batch.metadata` surfaces it to consumer code (matching arrow-js's
|
|
286
|
+
* RecordBatch.metadata getter behavior).
|
|
287
|
+
* - The patched flechette encoder picks it up via `_vgiRecordMetadata`
|
|
288
|
+
* and emits it as the IPC Message's `custom_metadata` field. */
|
|
289
|
+
function attachBatchMetadata(t: any, metadata?: Map<string, string>): void {
|
|
290
|
+
if (!metadata || metadata.size === 0) return;
|
|
291
|
+
t._vgiRecordMetadata = metadata;
|
|
292
|
+
// Surface as `batch.metadata` so wire/dispatch code (which expects the
|
|
293
|
+
// arrow-js shape) works uniformly. flechette's Table class has no
|
|
294
|
+
// top-level `metadata` property, so this assignment is non-shadowing.
|
|
295
|
+
t.metadata = metadata;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/** flechette has no Data passthrough concept (no opaque-type quirk). */
|
|
299
|
+
export function isOpaqueData(_val: unknown): boolean {
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** Re-emit a batch with a different per-record-batch metadata map (same
|
|
304
|
+
* schema + data). Shallow-clones the Table so the caller's reference is
|
|
305
|
+
* not mutated. */
|
|
306
|
+
export function withBatchMetadata(batch: VgiBatch, metadata: Map<string, string>): VgiBatch {
|
|
307
|
+
const t = batch as any;
|
|
308
|
+
const clone = Object.assign(Object.create(Object.getPrototypeOf(t)), t);
|
|
309
|
+
attachBatchMetadata(clone, metadata);
|
|
310
|
+
return clone as unknown as VgiBatch;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Serialize a sequence of batches into a single multi-batch IPC stream.
|
|
315
|
+
* Uses our flechette fork's `tablesToIPC` (added in
|
|
316
|
+
* github:Query-farm/flechette#fix/timestamp-bigint-encode) to do the
|
|
317
|
+
* concat-then-encode atomically — naive concatenation of multiple
|
|
318
|
+
* `tableToIPC` outputs produces multiple EOS markers, dropping batches
|
|
319
|
+
* past the first.
|
|
320
|
+
*/
|
|
321
|
+
export function serializeBatches(_schema: VgiSchema, batches: VgiBatch[]): Uint8Array {
|
|
322
|
+
if (batches.length === 0) {
|
|
323
|
+
// 0-batch case: emit just the schema with EOS so readers don't choke.
|
|
324
|
+
return serializeSchema(_schema);
|
|
325
|
+
}
|
|
326
|
+
return tablesToIPC(batches as any[], { format: "stream" }) as Uint8Array;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/** Arrow Type ids: Int=2, Float=3. */
|
|
330
|
+
function isNumericTypeId(typeId: number): boolean {
|
|
331
|
+
return typeId === 2 || typeId === 3;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/** Materialize a source column's values cast to a numeric destination type:
|
|
335
|
+
* int64/uint64 want BigInt, everything else (smaller ints, floats) wants
|
|
336
|
+
* Number. Nulls pass through. */
|
|
337
|
+
function castNumericValues(col: any, dstType: VgiDataType): any[] {
|
|
338
|
+
const wantsBigInt = dstType.typeId === 2 && (dstType as any).bitWidth === 64;
|
|
339
|
+
const out: any[] = [];
|
|
340
|
+
for (let r = 0; r < col.length; r++) {
|
|
341
|
+
const v = col.get(r);
|
|
342
|
+
if (v == null) {
|
|
343
|
+
out.push(v);
|
|
344
|
+
} else if (wantsBigInt) {
|
|
345
|
+
out.push(typeof v === "bigint" ? v : BigInt(Math.trunc(Number(v))));
|
|
346
|
+
} else {
|
|
347
|
+
out.push(typeof v === "bigint" ? Number(v) : v);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return out;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Rebuild a batch's columns to match a target schema's field types.
|
|
355
|
+
*
|
|
356
|
+
* flechette's IPC reader produces specific types upfront (no Int_/Float_
|
|
357
|
+
* generic-type quirk that arrow-js exhibits), but a cast-compatible client
|
|
358
|
+
* can still send e.g. int64 where the method declares float64. Mirror the
|
|
359
|
+
* arrow-js backend: materialize+rebuild numeric columns whose type differs
|
|
360
|
+
* from the expected field type. Non-numeric mismatches (and matching types)
|
|
361
|
+
* keep their existing column. Field-name / field-count mismatches surface as
|
|
362
|
+
* TypeErrors so the dispatch layer can convert them to RpcError.
|
|
363
|
+
*/
|
|
364
|
+
export function conformBatchToSchema(batch: VgiBatch, schema: VgiSchema): VgiBatch {
|
|
365
|
+
const t = batch as any;
|
|
366
|
+
const batchSchema = t?.schema;
|
|
367
|
+
if (!batchSchema || !schema) return batch;
|
|
368
|
+
const batchFields = batchSchema.fields ?? [];
|
|
369
|
+
const expectedFields = schema.fields ?? [];
|
|
370
|
+
if (batchFields.length !== expectedFields.length) {
|
|
371
|
+
throw new TypeError(`Batch has ${batchFields.length} fields, expected ${expectedFields.length}.`);
|
|
372
|
+
}
|
|
373
|
+
for (let i = 0; i < expectedFields.length; i++) {
|
|
374
|
+
const got = batchFields[i]?.name;
|
|
375
|
+
const want = expectedFields[i]?.name;
|
|
376
|
+
if (got !== want) {
|
|
377
|
+
throw new TypeError(`Batch field[${i}] is '${got}', expected '${want}'.`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
let mutated = false;
|
|
382
|
+
const cols: Column<any>[] = expectedFields.map((f: VgiField, i: number) => {
|
|
383
|
+
const srcCol = t.getChildAt(i);
|
|
384
|
+
const srcType = srcCol.type as VgiDataType;
|
|
385
|
+
const dstType = f.type;
|
|
386
|
+
if (srcType.typeId === dstType.typeId) return srcCol;
|
|
387
|
+
if (isNumericTypeId(srcType.typeId) && isNumericTypeId(dstType.typeId)) {
|
|
388
|
+
mutated = true;
|
|
389
|
+
return f_columnFromArray(castNumericValues(srcCol, dstType), dstType as any, EXTRACT_OPTS);
|
|
390
|
+
}
|
|
391
|
+
return srcCol;
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
if (!mutated) return batch;
|
|
395
|
+
const rebuilt = buildTablePreservingNullable(schema, cols) as any;
|
|
396
|
+
if (t._vgiRecordMetadata) attachBatchMetadata(rebuilt, t._vgiRecordMetadata);
|
|
397
|
+
return rebuilt as unknown as VgiBatch;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Not supported on flechette: the lockstep stdio exchange protocol needs an
|
|
402
|
+
* incremental IPC writer (emit each batch's framing bytes before reading
|
|
403
|
+
* the next input), and flechette only exposes a one-shot table encoder.
|
|
404
|
+
* The flechette backend is selected for workerd / browser / worker, which
|
|
405
|
+
* are HTTP-only (no stdio), so this factory is never reached there. The
|
|
406
|
+
* stdio server requires the arrow-js backend.
|
|
407
|
+
*/
|
|
408
|
+
export function createIncrementalEncoder(_s: VgiSchema): IncrementalEncoder {
|
|
409
|
+
throw new Error(
|
|
410
|
+
"Incremental IPC streaming (stdio producer/exchange) is not supported on the flechette " +
|
|
411
|
+
"Arrow backend. Use the arrow-js backend for the stdio transport, or the HTTP transport " +
|
|
412
|
+
"on workerd/browser builds.",
|
|
413
|
+
);
|
|
414
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// Minimal Arrow Message-envelope reader.
|
|
2
|
+
//
|
|
3
|
+
// flechette's IPC parser ignores the Message-level `custom_metadata` field
|
|
4
|
+
// (vtable offset 12 in the Message FlatBuffer) and only surfaces row count
|
|
5
|
+
// through column children — both of which are needed to round-trip vgi
|
|
6
|
+
// "params" batches that carry zero-field schemas with auth/state tokens
|
|
7
|
+
// in batch metadata. arrow-js exposes both via `RecordBatch.metadata` and
|
|
8
|
+
// `RecordBatch.numRows`.
|
|
9
|
+
//
|
|
10
|
+
// This file is a self-contained, dependency-free reader that walks an IPC
|
|
11
|
+
// stream and pulls out, for the first RecordBatch message it sees:
|
|
12
|
+
// * `numRows` — from RecordBatch.length (Message header_value, RB vtable offset 4)
|
|
13
|
+
// * `metadata` — Message.custom_metadata (Message vtable offset 12)
|
|
14
|
+
//
|
|
15
|
+
// Schema fields are 0/1/2/3/4; same for RecordBatch — see Arrow's
|
|
16
|
+
// `format/Message.fbs` and `format/Schema.fbs`.
|
|
17
|
+
|
|
18
|
+
const TYPE_SCHEMA = 1;
|
|
19
|
+
const TYPE_RECORD_BATCH = 3;
|
|
20
|
+
|
|
21
|
+
function readU32LE(b: Uint8Array, p: number): number {
|
|
22
|
+
return (b[p] | (b[p + 1] << 8) | (b[p + 2] << 16) | (b[p + 3] << 24)) >>> 0;
|
|
23
|
+
}
|
|
24
|
+
function readI32LE(b: Uint8Array, p: number): number {
|
|
25
|
+
return readU32LE(b, p) | 0;
|
|
26
|
+
}
|
|
27
|
+
function readI16LE(b: Uint8Array, p: number): number {
|
|
28
|
+
const v = b[p] | (b[p + 1] << 8);
|
|
29
|
+
return v < 0x8000 ? v : v - 0x10000;
|
|
30
|
+
}
|
|
31
|
+
function readI64LE(b: Uint8Array, p: number): bigint {
|
|
32
|
+
const lo = BigInt(readU32LE(b, p));
|
|
33
|
+
const hi = BigInt(readU32LE(b, p + 4));
|
|
34
|
+
// Sign-extend if hi's top bit is set.
|
|
35
|
+
const top = hi & 0x80000000n;
|
|
36
|
+
const combined = (hi << 32n) | lo;
|
|
37
|
+
return top ? combined - (1n << 64n) : combined;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// FlatBuffer table accessor. Holds the absolute byte offset of the table
|
|
41
|
+
// (root or sub-table) plus the parsed vtable field offsets.
|
|
42
|
+
interface FbTable {
|
|
43
|
+
pos: number;
|
|
44
|
+
fields: Int16Array;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readTable(buf: Uint8Array, tablePos: number): FbTable {
|
|
48
|
+
// First field at tablePos is the (signed) offset back to the vtable.
|
|
49
|
+
const vtableRel = readI32LE(buf, tablePos);
|
|
50
|
+
const vtablePos = tablePos - vtableRel;
|
|
51
|
+
const vtableSize = readI16LE(buf, vtablePos);
|
|
52
|
+
const fieldCount = (vtableSize - 4) >> 1;
|
|
53
|
+
const fields = new Int16Array(fieldCount);
|
|
54
|
+
for (let i = 0; i < fieldCount; i++) {
|
|
55
|
+
fields[i] = readI16LE(buf, vtablePos + 4 + i * 2);
|
|
56
|
+
}
|
|
57
|
+
return { pos: tablePos, fields };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Position of a field in the table buffer, or null if absent (offset 0). */
|
|
61
|
+
function fieldAt(t: FbTable, fieldIndex: number): number | null {
|
|
62
|
+
if (fieldIndex >= t.fields.length) return null;
|
|
63
|
+
const off = t.fields[fieldIndex];
|
|
64
|
+
return off === 0 ? null : t.pos + off;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Follow a uoffset_t at `ptrPos` to the absolute target byte position. */
|
|
68
|
+
function follow(buf: Uint8Array, ptrPos: number): number {
|
|
69
|
+
return ptrPos + readU32LE(buf, ptrPos);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function readString(buf: Uint8Array, strPos: number): string {
|
|
73
|
+
const len = readU32LE(buf, strPos);
|
|
74
|
+
return new TextDecoder().decode(buf.subarray(strPos + 4, strPos + 4 + len));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface ParsedMessage {
|
|
78
|
+
/** Header type tag — 1 = Schema, 2 = DictionaryBatch, 3 = RecordBatch. */
|
|
79
|
+
headerType: number;
|
|
80
|
+
/** RecordBatch.length (rows). Zero if not a RecordBatch or absent. */
|
|
81
|
+
numRows: number;
|
|
82
|
+
/** Message-level body length (offset 10). Used to skip past the body. */
|
|
83
|
+
bodyLength: number;
|
|
84
|
+
/** Message.custom_metadata, parsed into a Map. Empty if absent. */
|
|
85
|
+
metadata: Map<string, string>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function readMessageEnvelope(head: Uint8Array): ParsedMessage {
|
|
89
|
+
const rootOffset = readU32LE(head, 0);
|
|
90
|
+
const msg = readTable(head, rootOffset);
|
|
91
|
+
|
|
92
|
+
// Message field indices (Message.fbs):
|
|
93
|
+
// 0: version (int16) vtable offset 4
|
|
94
|
+
// 1: headerType (uint8) vtable offset 6
|
|
95
|
+
// 2: header (table) vtable offset 8
|
|
96
|
+
// 3: bodyLength (int64) vtable offset 10
|
|
97
|
+
// 4: custom_metadata ([KeyVal]) vtable offset 12
|
|
98
|
+
const headerTypePos = fieldAt(msg, 1);
|
|
99
|
+
const headerType = headerTypePos === null ? 0 : head[headerTypePos];
|
|
100
|
+
|
|
101
|
+
const bodyLengthPos = fieldAt(msg, 3);
|
|
102
|
+
const bodyLengthBig = bodyLengthPos === null ? 0n : readI64LE(head, bodyLengthPos);
|
|
103
|
+
// Bodies are bounded by maxDecompressedRequestBytes upstream — safe to coerce.
|
|
104
|
+
const bodyLength = Number(bodyLengthBig);
|
|
105
|
+
|
|
106
|
+
let numRows = 0;
|
|
107
|
+
if (headerType === TYPE_RECORD_BATCH) {
|
|
108
|
+
const headerValuePos = fieldAt(msg, 2);
|
|
109
|
+
if (headerValuePos !== null) {
|
|
110
|
+
const rbPos = follow(head, headerValuePos);
|
|
111
|
+
const rb = readTable(head, rbPos);
|
|
112
|
+
// RecordBatch.length is field 0 (vtable offset 4), int64.
|
|
113
|
+
const lenPos = fieldAt(rb, 0);
|
|
114
|
+
numRows = lenPos === null ? 0 : Number(readI64LE(head, lenPos));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const metadata = new Map<string, string>();
|
|
119
|
+
const metaVecPtr = fieldAt(msg, 4);
|
|
120
|
+
if (metaVecPtr !== null) {
|
|
121
|
+
const vecPos = follow(head, metaVecPtr);
|
|
122
|
+
const vecLen = readU32LE(head, vecPos);
|
|
123
|
+
for (let i = 0; i < vecLen; i++) {
|
|
124
|
+
// Vector of tables: each entry is a uoffset_t (4 bytes) pointing to the table.
|
|
125
|
+
const itemPtr = vecPos + 4 + i * 4;
|
|
126
|
+
const kvPos = follow(head, itemPtr);
|
|
127
|
+
const kv = readTable(head, kvPos);
|
|
128
|
+
const keyPtr = fieldAt(kv, 0);
|
|
129
|
+
const valPtr = fieldAt(kv, 1);
|
|
130
|
+
const key = keyPtr === null ? "" : readString(head, follow(head, keyPtr));
|
|
131
|
+
const val = valPtr === null ? "" : readString(head, follow(head, valPtr));
|
|
132
|
+
metadata.set(key, val);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { headerType, numRows, bodyLength, metadata };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Walk an Arrow IPC stream and return the first RecordBatch message's
|
|
141
|
+
* (numRows, metadata) — the bits flechette drops on the floor.
|
|
142
|
+
*
|
|
143
|
+
* Returns null if the stream contains no RecordBatch.
|
|
144
|
+
*/
|
|
145
|
+
export function readFirstRecordBatchMeta(
|
|
146
|
+
stream: Uint8Array,
|
|
147
|
+
): { numRows: number; metadata: Map<string, string> } | null {
|
|
148
|
+
let pos = 0;
|
|
149
|
+
while (pos + 4 <= stream.length) {
|
|
150
|
+
let metaLen = readI32LE(stream, pos);
|
|
151
|
+
pos += 4;
|
|
152
|
+
// Continuation-marker form (post-Arrow 0.15): the real length follows.
|
|
153
|
+
if (metaLen === -1) {
|
|
154
|
+
if (pos + 4 > stream.length) return null;
|
|
155
|
+
metaLen = readI32LE(stream, pos);
|
|
156
|
+
pos += 4;
|
|
157
|
+
}
|
|
158
|
+
if (metaLen === 0) return null; // EOS
|
|
159
|
+
if (pos + metaLen > stream.length) return null;
|
|
160
|
+
const head = stream.subarray(pos, pos + metaLen);
|
|
161
|
+
pos += metaLen;
|
|
162
|
+
const parsed = readMessageEnvelope(head);
|
|
163
|
+
if (parsed.headerType === TYPE_RECORD_BATCH) {
|
|
164
|
+
return { numRows: parsed.numRows, metadata: parsed.metadata };
|
|
165
|
+
}
|
|
166
|
+
// Skip the body (Schema messages have bodyLength = 0).
|
|
167
|
+
pos += parsed.bodyLength;
|
|
168
|
+
if (parsed.headerType !== TYPE_SCHEMA && parsed.headerType !== 2 /* Dict */) {
|
|
169
|
+
// Unknown header — stop walking.
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// vgi-rpc-typescript Arrow facade. Mirrors vgi-typescript's facade so types
|
|
2
|
+
// flow freely between the two packages. Backend selected via `#vgi-rpc-arrow`
|
|
3
|
+
// in package.json's `imports` field (workerd/worker/browser → impl-flechette,
|
|
4
|
+
// default → impl-arrowjs).
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
backend,
|
|
8
|
+
batchFromColumnData,
|
|
9
|
+
batchFromColumns,
|
|
10
|
+
binary,
|
|
11
|
+
bool,
|
|
12
|
+
// Construction
|
|
13
|
+
columnFromArray,
|
|
14
|
+
conformBatchToSchema,
|
|
15
|
+
createIncrementalEncoder,
|
|
16
|
+
dateDay,
|
|
17
|
+
decimal,
|
|
18
|
+
deserializeBatch,
|
|
19
|
+
deserializeSchema,
|
|
20
|
+
dictionary,
|
|
21
|
+
durationMicro,
|
|
22
|
+
emptyBatchWithMetadata,
|
|
23
|
+
emptyColumnData,
|
|
24
|
+
field,
|
|
25
|
+
fixedSizeBinary,
|
|
26
|
+
float32,
|
|
27
|
+
float64,
|
|
28
|
+
int8,
|
|
29
|
+
int16,
|
|
30
|
+
int32,
|
|
31
|
+
int64,
|
|
32
|
+
isOpaqueData,
|
|
33
|
+
largeBinary,
|
|
34
|
+
largeUtf8,
|
|
35
|
+
list,
|
|
36
|
+
map,
|
|
37
|
+
// Type factories
|
|
38
|
+
nullType,
|
|
39
|
+
schema,
|
|
40
|
+
serializeBatch,
|
|
41
|
+
serializeBatches,
|
|
42
|
+
// IPC
|
|
43
|
+
serializeSchema,
|
|
44
|
+
singleRowBatch,
|
|
45
|
+
singleRowBatchWithMetadata,
|
|
46
|
+
struct,
|
|
47
|
+
timeMicro,
|
|
48
|
+
timestampMicro,
|
|
49
|
+
uint8,
|
|
50
|
+
uint16,
|
|
51
|
+
uint32,
|
|
52
|
+
uint64,
|
|
53
|
+
utf8,
|
|
54
|
+
withBatchMetadata,
|
|
55
|
+
} from "#vgi-rpc-arrow";
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
isBatch,
|
|
59
|
+
isBinary,
|
|
60
|
+
isBool,
|
|
61
|
+
isDate,
|
|
62
|
+
isDecimal,
|
|
63
|
+
isDictionary,
|
|
64
|
+
isDuration,
|
|
65
|
+
isFixedSizeBinary,
|
|
66
|
+
isFloat,
|
|
67
|
+
isInt,
|
|
68
|
+
isLargeBinary,
|
|
69
|
+
isLargeUtf8,
|
|
70
|
+
isList,
|
|
71
|
+
isMap,
|
|
72
|
+
isNull,
|
|
73
|
+
isStruct,
|
|
74
|
+
isTime,
|
|
75
|
+
isTimestamp,
|
|
76
|
+
isUtf8,
|
|
77
|
+
TypeId,
|
|
78
|
+
} from "./predicates.js";
|
|
79
|
+
export type {
|
|
80
|
+
IncrementalEncoder,
|
|
81
|
+
VgiBackendInfo,
|
|
82
|
+
VgiBatch,
|
|
83
|
+
VgiColumn,
|
|
84
|
+
VgiColumnData,
|
|
85
|
+
VgiDataType,
|
|
86
|
+
VgiField,
|
|
87
|
+
VgiSchema,
|
|
88
|
+
VgiTypeId,
|
|
89
|
+
} from "./types.js";
|