@query-farm/vgi 0.6.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 (206) hide show
  1. package/LICENSE +134 -0
  2. package/README.md +494 -0
  3. package/dist/__dbg.test-d.d.ts +1 -0
  4. package/dist/arguments/argument-spec.d.ts +51 -0
  5. package/dist/arguments/arguments.d.ts +13 -0
  6. package/dist/arrow/codec/branded.d.ts +83 -0
  7. package/dist/arrow/codec/registry.d.ts +29 -0
  8. package/dist/arrow/codec/repr.d.ts +23 -0
  9. package/dist/arrow/codec/type-descriptors.d.ts +109 -0
  10. package/dist/arrow/impl-arrowjs/build.d.ts +19 -0
  11. package/dist/arrow/impl-arrowjs/canonical.d.ts +15 -0
  12. package/dist/arrow/impl-arrowjs/empty.d.ts +7 -0
  13. package/dist/arrow/impl-arrowjs/filter.d.ts +11 -0
  14. package/dist/arrow/impl-arrowjs/index.d.ts +11 -0
  15. package/dist/arrow/impl-arrowjs/ipc.d.ts +24 -0
  16. package/dist/arrow/impl-arrowjs/iterate.d.ts +39 -0
  17. package/dist/arrow/impl-arrowjs/project.d.ts +10 -0
  18. package/dist/arrow/impl-arrowjs/schema.d.ts +62 -0
  19. package/dist/arrow/impl-arrowjs/statistics.d.ts +13 -0
  20. package/dist/arrow/impl-flechette/build.d.ts +14 -0
  21. package/dist/arrow/impl-flechette/canonical.d.ts +18 -0
  22. package/dist/arrow/impl-flechette/empty.d.ts +9 -0
  23. package/dist/arrow/impl-flechette/filter.d.ts +10 -0
  24. package/dist/arrow/impl-flechette/index.d.ts +11 -0
  25. package/dist/arrow/impl-flechette/ipc.d.ts +33 -0
  26. package/dist/arrow/impl-flechette/iterate.d.ts +29 -0
  27. package/dist/arrow/impl-flechette/message-meta.d.ts +10 -0
  28. package/dist/arrow/impl-flechette/normalize-type.d.ts +11 -0
  29. package/dist/arrow/impl-flechette/project.d.ts +3 -0
  30. package/dist/arrow/impl-flechette/schema.d.ts +47 -0
  31. package/dist/arrow/impl-flechette/statistics.d.ts +13 -0
  32. package/dist/arrow/index.d.ts +11 -0
  33. package/dist/arrow/predicates.d.ts +47 -0
  34. package/dist/arrow/repr.test-d.d.ts +52 -0
  35. package/dist/arrow/schema-types.d.ts +71 -0
  36. package/dist/arrow/types.d.ts +57 -0
  37. package/dist/catalog/attach-option.d.ts +33 -0
  38. package/dist/catalog/attach-options.d.ts +30 -0
  39. package/dist/catalog/composite.d.ts +33 -0
  40. package/dist/catalog/descriptors.d.ts +154 -0
  41. package/dist/catalog/interface.d.ts +239 -0
  42. package/dist/catalog/read-only.d.ts +33 -0
  43. package/dist/client/client.d.ts +189 -0
  44. package/dist/client/errors.d.ts +26 -0
  45. package/dist/client/helpers.d.ts +12 -0
  46. package/dist/client/protocol.d.ts +16 -0
  47. package/dist/client/types.d.ts +125 -0
  48. package/dist/client-entry.d.ts +11 -0
  49. package/dist/client-entry.js +48 -0
  50. package/dist/client-entry.js.map +9 -0
  51. package/dist/codec/asd.d.ts +25 -0
  52. package/dist/crypto.d.ts +36 -0
  53. package/dist/errors.d.ts +24 -0
  54. package/dist/filter-pushdown/collector.d.ts +32 -0
  55. package/dist/filter-pushdown/deserialize.d.ts +16 -0
  56. package/dist/filter-pushdown/evaluate.d.ts +51 -0
  57. package/dist/filter-pushdown/index.d.ts +4 -0
  58. package/dist/filter-pushdown/types.d.ts +84 -0
  59. package/dist/functions/aggregate.d.ts +129 -0
  60. package/dist/functions/copy-from.d.ts +81 -0
  61. package/dist/functions/copy-to.d.ts +121 -0
  62. package/dist/functions/registry.d.ts +16 -0
  63. package/dist/functions/scalar.d.ts +98 -0
  64. package/dist/functions/storage-cf-do.d.ts +47 -0
  65. package/dist/functions/storage.d.ts +86 -0
  66. package/dist/functions/table-buffering.d.ts +99 -0
  67. package/dist/functions/table-in-out.d.ts +64 -0
  68. package/dist/functions/table.d.ts +118 -0
  69. package/dist/functions/types.d.ts +157 -0
  70. package/dist/generated/vgi-client.d.ts +466 -0
  71. package/dist/generated/vgi-protocol-schemas.d.ts +115 -0
  72. package/dist/index.core.d.ts +42 -0
  73. package/dist/index.d.ts +2 -0
  74. package/dist/index.js +10888 -0
  75. package/dist/index.js.map +85 -0
  76. package/dist/metadata/resolve.d.ts +3 -0
  77. package/dist/metadata/serialize.d.ts +12 -0
  78. package/dist/metadata/types.d.ts +47 -0
  79. package/dist/protocol/dispatch.d.ts +23 -0
  80. package/dist/protocol/handlers/aggregate.d.ts +3 -0
  81. package/dist/protocol/handlers/catalog/admin.d.ts +3 -0
  82. package/dist/protocol/handlers/catalog/index.d.ts +3 -0
  83. package/dist/protocol/handlers/catalog/index_methods.d.ts +3 -0
  84. package/dist/protocol/handlers/catalog/macro.d.ts +3 -0
  85. package/dist/protocol/handlers/catalog/shared.d.ts +70 -0
  86. package/dist/protocol/handlers/catalog/table.d.ts +3 -0
  87. package/dist/protocol/handlers/catalog/view.d.ts +3 -0
  88. package/dist/protocol/handlers/function.d.ts +8 -0
  89. package/dist/protocol/handlers/shared.d.ts +31 -0
  90. package/dist/protocol/handlers/table-buffering.d.ts +3 -0
  91. package/dist/protocol/serialize.d.ts +4 -0
  92. package/dist/protocol/serializers/arguments.d.ts +3 -0
  93. package/dist/protocol/serializers/bind.d.ts +9 -0
  94. package/dist/protocol/serializers/cardinality.d.ts +7 -0
  95. package/dist/protocol/serializers/init.d.ts +9 -0
  96. package/dist/protocol/serializers/shared.d.ts +12 -0
  97. package/dist/protocol/state-serializer.d.ts +23 -0
  98. package/dist/protocol/types.d.ts +129 -0
  99. package/dist/secrets/helpers.d.ts +15 -0
  100. package/dist/types.d.ts +52 -0
  101. package/dist/util/arrow/index.d.ts +1 -0
  102. package/dist/util/bytes.d.ts +2 -0
  103. package/dist/util/statistics.d.ts +7 -0
  104. package/dist/worker-cf-entry.d.ts +30 -0
  105. package/dist/worker-cf-entry.js +8767 -0
  106. package/dist/worker-cf-entry.js.map +74 -0
  107. package/dist/worker.d.ts +36 -0
  108. package/package.json +96 -0
  109. package/src/arguments/argument-spec.ts +200 -0
  110. package/src/arguments/arguments.ts +81 -0
  111. package/src/arrow/codec/branded.ts +206 -0
  112. package/src/arrow/codec/registry.ts +674 -0
  113. package/src/arrow/codec/repr.ts +181 -0
  114. package/src/arrow/codec/type-descriptors.ts +137 -0
  115. package/src/arrow/impl-arrowjs/build.ts +88 -0
  116. package/src/arrow/impl-arrowjs/canonical.ts +509 -0
  117. package/src/arrow/impl-arrowjs/empty.ts +72 -0
  118. package/src/arrow/impl-arrowjs/filter.ts +53 -0
  119. package/src/arrow/impl-arrowjs/index.ts +54 -0
  120. package/src/arrow/impl-arrowjs/ipc.ts +67 -0
  121. package/src/arrow/impl-arrowjs/iterate.ts +159 -0
  122. package/src/arrow/impl-arrowjs/project.ts +73 -0
  123. package/src/arrow/impl-arrowjs/schema.ts +256 -0
  124. package/src/arrow/impl-arrowjs/statistics.ts +185 -0
  125. package/src/arrow/impl-flechette/build.ts +65 -0
  126. package/src/arrow/impl-flechette/canonical.ts +289 -0
  127. package/src/arrow/impl-flechette/empty.ts +20 -0
  128. package/src/arrow/impl-flechette/filter.ts +42 -0
  129. package/src/arrow/impl-flechette/index.ts +54 -0
  130. package/src/arrow/impl-flechette/ipc.ts +110 -0
  131. package/src/arrow/impl-flechette/iterate.ts +121 -0
  132. package/src/arrow/impl-flechette/message-meta.ts +175 -0
  133. package/src/arrow/impl-flechette/normalize-type.ts +99 -0
  134. package/src/arrow/impl-flechette/project.ts +64 -0
  135. package/src/arrow/impl-flechette/schema.ts +202 -0
  136. package/src/arrow/impl-flechette/statistics.ts +198 -0
  137. package/src/arrow/index.ts +129 -0
  138. package/src/arrow/predicates.ts +66 -0
  139. package/src/arrow/repr.test-d.ts +189 -0
  140. package/src/arrow/schema-types.ts +213 -0
  141. package/src/arrow/types.ts +74 -0
  142. package/src/catalog/attach-option.ts +107 -0
  143. package/src/catalog/attach-options.ts +79 -0
  144. package/src/catalog/composite.ts +180 -0
  145. package/src/catalog/descriptors.ts +164 -0
  146. package/src/catalog/interface.ts +721 -0
  147. package/src/catalog/read-only.ts +909 -0
  148. package/src/client/client.ts +1348 -0
  149. package/src/client/errors.ts +69 -0
  150. package/src/client/helpers.ts +56 -0
  151. package/src/client/protocol.ts +33 -0
  152. package/src/client/types.ts +140 -0
  153. package/src/client-entry.ts +112 -0
  154. package/src/codec/asd.ts +147 -0
  155. package/src/crypto.ts +143 -0
  156. package/src/errors.ts +61 -0
  157. package/src/filter-pushdown/collector.ts +147 -0
  158. package/src/filter-pushdown/deserialize.ts +253 -0
  159. package/src/filter-pushdown/evaluate.ts +591 -0
  160. package/src/filter-pushdown/index.ts +28 -0
  161. package/src/filter-pushdown/types.ts +91 -0
  162. package/src/functions/aggregate.ts +384 -0
  163. package/src/functions/copy-from.ts +282 -0
  164. package/src/functions/copy-to.ts +319 -0
  165. package/src/functions/registry.ts +258 -0
  166. package/src/functions/scalar.ts +356 -0
  167. package/src/functions/storage-cf-do.ts +303 -0
  168. package/src/functions/storage.ts +521 -0
  169. package/src/functions/table-buffering.ts +562 -0
  170. package/src/functions/table-in-out.ts +373 -0
  171. package/src/functions/table.ts +521 -0
  172. package/src/functions/types.ts +192 -0
  173. package/src/generated/vgi-client.ts +560 -0
  174. package/src/generated/vgi-protocol-schemas.ts +864 -0
  175. package/src/index.core.ts +267 -0
  176. package/src/index.ts +11 -0
  177. package/src/metadata/resolve.ts +109 -0
  178. package/src/metadata/serialize.ts +242 -0
  179. package/src/metadata/types.ts +60 -0
  180. package/src/protocol/dispatch.ts +52 -0
  181. package/src/protocol/handlers/aggregate.ts +355 -0
  182. package/src/protocol/handlers/catalog/admin.ts +368 -0
  183. package/src/protocol/handlers/catalog/index.ts +25 -0
  184. package/src/protocol/handlers/catalog/index_methods.ts +65 -0
  185. package/src/protocol/handlers/catalog/macro.ts +114 -0
  186. package/src/protocol/handlers/catalog/shared.ts +291 -0
  187. package/src/protocol/handlers/catalog/table.ts +401 -0
  188. package/src/protocol/handlers/catalog/view.ts +119 -0
  189. package/src/protocol/handlers/function.ts +302 -0
  190. package/src/protocol/handlers/shared.ts +80 -0
  191. package/src/protocol/handlers/table-buffering.ts +207 -0
  192. package/src/protocol/serialize.ts +23 -0
  193. package/src/protocol/serializers/arguments.ts +160 -0
  194. package/src/protocol/serializers/bind.ts +212 -0
  195. package/src/protocol/serializers/cardinality.ts +45 -0
  196. package/src/protocol/serializers/init.ts +247 -0
  197. package/src/protocol/serializers/shared.ts +46 -0
  198. package/src/protocol/state-serializer.ts +181 -0
  199. package/src/protocol/types.ts +153 -0
  200. package/src/secrets/helpers.ts +70 -0
  201. package/src/types.ts +71 -0
  202. package/src/util/arrow/index.ts +23 -0
  203. package/src/util/bytes.ts +14 -0
  204. package/src/util/statistics.ts +40 -0
  205. package/src/worker-cf-entry.ts +172 -0
  206. package/src/worker.ts +212 -0
@@ -0,0 +1,202 @@
1
+ // Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+ // Factory-style constructors for flechette Schema/Field/DataType values.
3
+ // flechette already exposes these as factory functions, so most of this
4
+ // file is direct re-exports. The few wrapper functions handle ergonomic
5
+ // gaps (e.g. allowing a bare DataType for `list(child)` rather than
6
+ // requiring a wrapped Field).
7
+
8
+ import {
9
+ field as f_field,
10
+ nullType as f_nullType,
11
+ bool as f_bool,
12
+ int as f_int,
13
+ int8 as f_int8,
14
+ int16 as f_int16,
15
+ int32 as f_int32,
16
+ int64 as f_int64,
17
+ uint8 as f_uint8,
18
+ uint16 as f_uint16,
19
+ uint32 as f_uint32,
20
+ uint64 as f_uint64,
21
+ float as f_float,
22
+ float16 as f_float16,
23
+ float32 as f_float32,
24
+ float64 as f_float64,
25
+ utf8 as f_utf8,
26
+ binary as f_binary,
27
+ fixedSizeBinary as f_fixedSizeBinary,
28
+ decimal as f_decimal,
29
+ decimal128 as f_decimal128,
30
+ decimal256 as f_decimal256,
31
+ date as f_date,
32
+ dateDay as f_dateDay,
33
+ dateMillisecond as f_dateMillisecond,
34
+ time as f_time,
35
+ timeSecond as f_timeSecond,
36
+ timeMillisecond as f_timeMillisecond,
37
+ timeMicrosecond as f_timeMicrosecond,
38
+ timeNanosecond as f_timeNanosecond,
39
+ timestamp as f_timestamp,
40
+ duration as f_duration,
41
+ interval as f_interval,
42
+ list as f_list,
43
+ fixedSizeList as f_fixedSizeList,
44
+ struct as f_struct,
45
+ map as f_map,
46
+ dictionary as f_dictionary,
47
+ union as f_union,
48
+ TimeUnit as F_TimeUnit,
49
+ DateUnit as F_DateUnit,
50
+ IntervalUnit as F_IntervalUnit,
51
+ UnionMode as F_UnionMode,
52
+ } from "@query-farm/flechette";
53
+
54
+ import type { VgiField, VgiSchema, VgiDataType } from "../types.js";
55
+
56
+ // ----- Unit / mode constants -----------------------------------------------
57
+
58
+ export const TimeUnit = F_TimeUnit;
59
+ export const DateUnit = F_DateUnit;
60
+ export const IntervalUnit = F_IntervalUnit;
61
+ export const UnionMode = F_UnionMode;
62
+
63
+ // ----- Schema / Field ------------------------------------------------------
64
+
65
+ export function schema(
66
+ fields: readonly VgiField[],
67
+ metadata?: Map<string, string>,
68
+ ): VgiSchema {
69
+ return {
70
+ fields: fields as readonly any[] as VgiField[],
71
+ metadata: metadata ?? new Map(),
72
+ } as VgiSchema;
73
+ }
74
+
75
+ export function field(
76
+ name: string,
77
+ type: VgiDataType,
78
+ nullable = true,
79
+ metadata?: Map<string, string>,
80
+ ): VgiField {
81
+ return f_field(
82
+ name,
83
+ type as any,
84
+ nullable,
85
+ metadata ?? new Map(),
86
+ ) as unknown as VgiField;
87
+ }
88
+
89
+ // ----- Primitive types -----------------------------------------------------
90
+
91
+ export const nullType = (): VgiDataType => f_nullType() as unknown as VgiDataType;
92
+ export const bool = (): VgiDataType => f_bool() as unknown as VgiDataType;
93
+
94
+ export const int8 = (): VgiDataType => f_int8() as unknown as VgiDataType;
95
+ export const int16 = (): VgiDataType => f_int16() as unknown as VgiDataType;
96
+ export const int32 = (): VgiDataType => f_int32() as unknown as VgiDataType;
97
+ export const int64 = (): VgiDataType => f_int64() as unknown as VgiDataType;
98
+ export const uint8 = (): VgiDataType => f_uint8() as unknown as VgiDataType;
99
+ export const uint16 = (): VgiDataType => f_uint16() as unknown as VgiDataType;
100
+ export const uint32 = (): VgiDataType => f_uint32() as unknown as VgiDataType;
101
+ export const uint64 = (): VgiDataType => f_uint64() as unknown as VgiDataType;
102
+ export const int = (bitWidth: 8 | 16 | 32 | 64 = 32, signed = true): VgiDataType =>
103
+ f_int(bitWidth, signed) as unknown as VgiDataType;
104
+
105
+ export const float16 = (): VgiDataType => f_float16() as unknown as VgiDataType;
106
+ export const float32 = (): VgiDataType => f_float32() as unknown as VgiDataType;
107
+ export const float64 = (): VgiDataType => f_float64() as unknown as VgiDataType;
108
+
109
+ export const utf8 = (): VgiDataType => f_utf8() as unknown as VgiDataType;
110
+ export const binary = (): VgiDataType => f_binary() as unknown as VgiDataType;
111
+ export const fixedSizeBinary = (stride: number): VgiDataType =>
112
+ f_fixedSizeBinary(stride) as unknown as VgiDataType;
113
+
114
+ // ----- Decimal -------------------------------------------------------------
115
+
116
+ export function decimal(
117
+ precision: number,
118
+ scale: number,
119
+ bitWidth: 32 | 64 | 128 | 256 = 128,
120
+ ): VgiDataType {
121
+ return f_decimal(precision, scale, bitWidth) as unknown as VgiDataType;
122
+ }
123
+ export const decimal128 = (precision: number, scale: number): VgiDataType =>
124
+ f_decimal128(precision, scale) as unknown as VgiDataType;
125
+ export const decimal256 = (precision: number, scale: number): VgiDataType =>
126
+ f_decimal256(precision, scale) as unknown as VgiDataType;
127
+
128
+ // ----- Date / Time / Timestamp / Duration / Interval -----------------------
129
+
130
+ export const date = (unit: number = F_DateUnit.MILLISECOND): VgiDataType =>
131
+ f_date(unit as any) as unknown as VgiDataType;
132
+ export const dateDay = (): VgiDataType => f_dateDay() as unknown as VgiDataType;
133
+ export const dateMillisecond = (): VgiDataType => f_dateMillisecond() as unknown as VgiDataType;
134
+
135
+ export function time(unit: number = F_TimeUnit.MILLISECOND, _bitWidth?: 32 | 64): VgiDataType {
136
+ // bitWidth is implicit in flechette (derived from unit), so we ignore _bitWidth.
137
+ return f_time(unit as any) as unknown as VgiDataType;
138
+ }
139
+ export const timeSecond = (): VgiDataType => f_timeSecond() as unknown as VgiDataType;
140
+ export const timeMillisecond = (): VgiDataType => f_timeMillisecond() as unknown as VgiDataType;
141
+ export const timeMicrosecond = (): VgiDataType => f_timeMicrosecond() as unknown as VgiDataType;
142
+ export const timeNanosecond = (): VgiDataType => f_timeNanosecond() as unknown as VgiDataType;
143
+
144
+ export const timestamp = (
145
+ unit: number = F_TimeUnit.MILLISECOND,
146
+ timezone: string | null = null,
147
+ ): VgiDataType => f_timestamp(unit as any, timezone) as unknown as VgiDataType;
148
+
149
+ export const duration = (unit: number = F_TimeUnit.MILLISECOND): VgiDataType =>
150
+ f_duration(unit as any) as unknown as VgiDataType;
151
+
152
+ export const interval = (unit: number = F_IntervalUnit.MONTH_DAY_NANO): VgiDataType =>
153
+ f_interval(unit as any) as unknown as VgiDataType;
154
+
155
+ // ----- Nested types --------------------------------------------------------
156
+
157
+ export function list(child: VgiField | VgiDataType): VgiDataType {
158
+ return f_list(child as any) as unknown as VgiDataType;
159
+ }
160
+
161
+ export function fixedSizeList(child: VgiField | VgiDataType, listSize: number): VgiDataType {
162
+ return f_fixedSizeList(child as any, listSize) as unknown as VgiDataType;
163
+ }
164
+
165
+ export function struct(children: readonly VgiField[]): VgiDataType {
166
+ return f_struct(children as any) as unknown as VgiDataType;
167
+ }
168
+
169
+ export function map(
170
+ keyField: VgiField | VgiDataType,
171
+ valueField: VgiField | VgiDataType,
172
+ keysSorted = false,
173
+ ): VgiDataType {
174
+ return f_map(keyField as any, valueField as any, keysSorted) as unknown as VgiDataType;
175
+ }
176
+
177
+ export function dictionary(
178
+ valueType: VgiDataType,
179
+ indexType: VgiDataType = int16(),
180
+ ordered = false,
181
+ id?: number,
182
+ ): VgiDataType {
183
+ return f_dictionary(valueType as any, indexType as any, ordered, id) as unknown as VgiDataType;
184
+ }
185
+
186
+ export function union(
187
+ mode: number,
188
+ children: readonly (VgiField | VgiDataType)[],
189
+ typeIds?: number[],
190
+ ): VgiDataType {
191
+ return f_union(mode as any, children as any, typeIds) as unknown as VgiDataType;
192
+ }
193
+
194
+ export const sparseUnion = (
195
+ children: readonly (VgiField | VgiDataType)[],
196
+ typeIds?: number[],
197
+ ): VgiDataType => union(F_UnionMode.Sparse, children, typeIds);
198
+
199
+ export const denseUnion = (
200
+ children: readonly (VgiField | VgiDataType)[],
201
+ typeIds?: number[],
202
+ ): VgiDataType => union(F_UnionMode.Dense, children, typeIds);
@@ -0,0 +1,198 @@
1
+ // Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+ // flechette impl of column-statistics serialization.
3
+ //
4
+ // The empty-stats batch (NDV-only path, no min/max) ships a one-child
5
+ // sparse_union placeholder. Non-empty stats build a real sparse_union<T0,..>
6
+ // min/max column whose per-row type code selects the child holding that row's
7
+ // value — routed through the codec (rich -> canonical) and the canonical writer
8
+ // so a date/timestamp/decimal min/max is represented identically to ordinary
9
+ // column data and identically to the arrow-js backend.
10
+
11
+ import {
12
+ columnFromArray as f_columnFromArray,
13
+ union as f_union,
14
+ field as f_field,
15
+ Table,
16
+ UnionMode,
17
+ type Column,
18
+ } from "@query-farm/flechette";
19
+ import type { VgiBatch, VgiDataType } from "../types.js";
20
+ import { emptyBatch } from "./empty.js";
21
+ import { codecFor } from "../codec/registry.js";
22
+ import { prepareForFlechette } from "./canonical.js";
23
+ import { toFlechetteType } from "./normalize-type.js";
24
+ import {
25
+ bool,
26
+ field,
27
+ int64,
28
+ int8,
29
+ schema,
30
+ sparseUnion,
31
+ uint64,
32
+ utf8,
33
+ } from "./schema.js";
34
+
35
+ const COLUMN_OPTS = {
36
+ useBigInt: true,
37
+ useBigIntTimestamp: true,
38
+ useDecimalInt: true,
39
+ } as const;
40
+
41
+ export interface ColumnStatistics {
42
+ columnName: string;
43
+ arrowType: VgiDataType;
44
+ min: any;
45
+ max: any;
46
+ hasNull: boolean;
47
+ hasNotNull: boolean;
48
+ distinctCount: bigint | number | null;
49
+ containsUnicode: boolean | null;
50
+ maxStringLength: bigint | number | null;
51
+ }
52
+
53
+ // Stable, backend-agnostic type key. flechette types are plain objects whose
54
+ // `.toString()` is "[object Object]" for every type (collapsing date32/date64/
55
+ // timestamp/decimal into ONE union child), so dispatch on the structural fields
56
+ // instead: typeId + unit + bitWidth + precision/scale + byteWidth.
57
+ function typeKey(t: VgiDataType): string {
58
+ const a = t as any;
59
+ return [
60
+ t.typeId,
61
+ a.unit ?? "",
62
+ a.bitWidth ?? "",
63
+ a.precision ?? "",
64
+ a.scale ?? "",
65
+ a.byteWidth ?? "",
66
+ ].join(":");
67
+ }
68
+
69
+ // Canonical 8-column ColumnStatistics schema with a one-child sparse_union.
70
+ // flechette can't build a 0-length sparse-union whose child is Null (its
71
+ // columnBuilder rejects "Unsupported data type"); use Int8 as a structurally-
72
+ // equivalent placeholder. A 0-row batch carries no values, so the child type
73
+ // only matters for IPC schema serialization — the C++ extension treats any
74
+ // 0-row stats blob as "stats are authoritative, just empty" regardless of
75
+ // the union's child shape.
76
+ function emptyStatsSchema() {
77
+ const placeholderChild = field("0", int8(), true);
78
+ const minMaxUnion = sparseUnion([placeholderChild], [0]);
79
+ return schema([
80
+ field("column_name", utf8(), false),
81
+ field("min", minMaxUnion, true),
82
+ field("max", minMaxUnion, true),
83
+ field("has_null", bool(), true),
84
+ field("has_not_null", bool(), true),
85
+ field("distinct_count", int64(), true),
86
+ field("contains_unicode", bool(), true),
87
+ field("max_string_length", uint64(), true),
88
+ ]);
89
+ }
90
+
91
+ /**
92
+ * Build a flechette Column for `type` from RICH values, routed through the codec
93
+ * (rich -> canonical) and the same per-type preparation the public canonical
94
+ * writer uses. Keeps stat values byte-identical to ordinary column data.
95
+ */
96
+ function buildTypedColumn(values: any[], type: VgiDataType): Column<any> {
97
+ const codec = codecFor(type);
98
+ const canonical = values.map((v) => codec.richToCanonical(v));
99
+ const prepared = prepareForFlechette(type, canonical);
100
+ return f_columnFromArray(prepared, toFlechetteType(type) as any, COLUMN_OPTS);
101
+ }
102
+
103
+ /**
104
+ * Build the sparse-union min/max Column. `rowTypeCodes[i]` selects which child
105
+ * (one per distinct Arrow type) holds row i's value; the builder fills the
106
+ * other children with null at that slot (sparse-union invariant). Values are
107
+ * routed through codec rich -> canonical -> flechette prep so each child sees
108
+ * exactly what it would for ordinary column data.
109
+ */
110
+ function buildUnionColumn(
111
+ values: any[],
112
+ rowTypeCodes: number[],
113
+ typeOrder: VgiDataType[],
114
+ ): Column<any> {
115
+ const typeIds = typeOrder.map((_t, i) => i);
116
+ const children = typeOrder.map((t, code) =>
117
+ f_field(String(code), toFlechetteType(t) as any, true),
118
+ );
119
+ // Per-row prepared value (only the selected child consumes it; non-selected
120
+ // children get null from the SparseUnionBuilder).
121
+ const prepared = values.map((v, i) => {
122
+ if (v == null) return null;
123
+ const type = typeOrder[rowTypeCodes[i]];
124
+ const codec = codecFor(type);
125
+ return prepareForFlechette(type, [codec.richToCanonical(v)])[0];
126
+ });
127
+ const unionType = f_union(
128
+ UnionMode.Sparse,
129
+ children as any,
130
+ typeIds,
131
+ (_value: any, index: number) => rowTypeCodes[index],
132
+ );
133
+ return f_columnFromArray(prepared, unionType as any, COLUMN_OPTS);
134
+ }
135
+
136
+ export function buildStatisticsBatch(stats: ColumnStatistics[]): VgiBatch {
137
+ if (stats.length === 0) {
138
+ return emptyBatch(emptyStatsSchema());
139
+ }
140
+
141
+ // Group distinct Arrow types in stable insertion order to assign type codes.
142
+ const typeOrder: VgiDataType[] = [];
143
+ const typeIdMap = new Map<string, number>();
144
+ const rowTypeCodes: number[] = [];
145
+ for (const s of stats) {
146
+ const key = typeKey(s.arrowType);
147
+ let code = typeIdMap.get(key);
148
+ if (code === undefined) {
149
+ code = typeOrder.length;
150
+ typeIdMap.set(key, code);
151
+ typeOrder.push(s.arrowType);
152
+ }
153
+ rowTypeCodes.push(code);
154
+ }
155
+
156
+ const minCol = buildUnionColumn(
157
+ stats.map((s) => s.min),
158
+ rowTypeCodes,
159
+ typeOrder,
160
+ );
161
+ const maxCol = buildUnionColumn(
162
+ stats.map((s) => s.max),
163
+ rowTypeCodes,
164
+ typeOrder,
165
+ );
166
+
167
+ const minMaxUnionType = minCol.type;
168
+
169
+ const childCols: Column<any>[] = [
170
+ buildTypedColumn(stats.map((s) => s.columnName), utf8()),
171
+ minCol,
172
+ maxCol,
173
+ buildTypedColumn(stats.map((s) => s.hasNull), bool()),
174
+ buildTypedColumn(stats.map((s) => s.hasNotNull), bool()),
175
+ buildTypedColumn(
176
+ stats.map((s) => (s.distinctCount == null ? null : BigInt(s.distinctCount))),
177
+ int64(),
178
+ ),
179
+ buildTypedColumn(stats.map((s) => s.containsUnicode), bool()),
180
+ buildTypedColumn(
181
+ stats.map((s) => (s.maxStringLength == null ? null : BigInt(s.maxStringLength))),
182
+ uint64(),
183
+ ),
184
+ ];
185
+
186
+ const fields = [
187
+ f_field("column_name", toFlechetteType(utf8()) as any, false),
188
+ f_field("min", minMaxUnionType as any, true),
189
+ f_field("max", minMaxUnionType as any, true),
190
+ f_field("has_null", toFlechetteType(bool()) as any, true),
191
+ f_field("has_not_null", toFlechetteType(bool()) as any, true),
192
+ f_field("distinct_count", toFlechetteType(int64()) as any, true),
193
+ f_field("contains_unicode", toFlechetteType(bool()) as any, true),
194
+ f_field("max_string_length", toFlechetteType(uint64()) as any, true),
195
+ ];
196
+ const flechSchema = { version: 5, endianness: 0, fields, metadata: null };
197
+ return new Table(flechSchema as any, childCols) as unknown as VgiBatch;
198
+ }
@@ -0,0 +1,129 @@
1
+ // Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+ // Public facade. Internal vgi-typescript code imports Arrow operations
3
+ // from here; the active backend is selected at module-resolution time
4
+ // via the `#arrow-impl` subpath in package.json's `imports` field.
5
+ //
6
+ // Selection conditions:
7
+ // workerd / worker / browser -> impl-flechette (Cloudflare Workers, etc.)
8
+ // default -> impl-arrowjs (Bun worker, Node)
9
+
10
+ // Backend-agnostic types (defined in this package, satisfied structurally
11
+ // by both arrow-js and flechette native values).
12
+ export type {
13
+ VgiTypeId,
14
+ VgiDataType,
15
+ VgiField,
16
+ VgiSchema,
17
+ VgiColumn,
18
+ VgiColumnData,
19
+ VgiBatch,
20
+ VgiBackendInfo,
21
+ TaggedUnion,
22
+ } from "./types.js";
23
+
24
+ // Backend-agnostic predicates.
25
+ export {
26
+ TypeId,
27
+ isNull,
28
+ isInt,
29
+ isFloat,
30
+ isBinary,
31
+ isUtf8,
32
+ isBool,
33
+ isDecimal,
34
+ isDate,
35
+ isTime,
36
+ isTimestamp,
37
+ isInterval,
38
+ isList,
39
+ isStruct,
40
+ isUnion,
41
+ isFixedSizeBinary,
42
+ isFixedSizeList,
43
+ isMap,
44
+ isDuration,
45
+ isDictionary,
46
+ isBatch,
47
+ } from "./predicates.js";
48
+
49
+ // Active backend's surface (IPC, build, iterate, utilities).
50
+ export {
51
+ backend,
52
+ // batch utilities
53
+ emptyBatch, batchFromRows, batchFromColumns, columnFromArray,
54
+ iterRows, batchToScalarDict, batchToSecretDict, safeNumber, decodeDictValue,
55
+ filterBatch, projectSchema, projectBatch,
56
+ // canonical single-value read (backend-agnostic, lossless)
57
+ readCanonicalValue,
58
+ // IPC
59
+ serializeSchema, deserializeSchema, serializeBatch, deserializeBatch,
60
+ // Column statistics
61
+ buildStatisticsBatch,
62
+ } from "#arrow-impl";
63
+
64
+ export type { ColumnStatistics } from "#arrow-impl";
65
+
66
+ // Type factories — exported from the TYPED facade layer (schema-types.ts) so
67
+ // every factory carries a PRECISE nominal static descriptor (Date32Type,
68
+ // TimestampType<'us'>, StructType<...>, …). Runtime values are identical to the
69
+ // backend factories; the typed layer only refines the static return type, which
70
+ // is what makes the rich/raw value mapping (RichValue/RawValue/ValueFor) and
71
+ // the statically-typed define* author API work. Both backends report the same
72
+ // static types from here.
73
+ export {
74
+ schema, field,
75
+ nullType, bool,
76
+ int, int8, int16, int32, int64,
77
+ uint8, uint16, uint32, uint64,
78
+ float16, float32, float64,
79
+ utf8, binary, fixedSizeBinary,
80
+ decimal, decimal128, decimal256,
81
+ date, dateDay, dateMillisecond,
82
+ time, timeSecond, timeMillisecond, timeMicrosecond, timeNanosecond,
83
+ timestamp, duration, interval,
84
+ timestampSeconds, timestampMillis, timestampMicros, timestampNanos,
85
+ durationSeconds, durationMillis, durationMicros, durationNanos,
86
+ list, fixedSizeList, struct, map,
87
+ dictionary,
88
+ union, sparseUnion, denseUnion,
89
+ TimeUnit, DateUnit, IntervalUnit, UnionMode,
90
+ } from "./schema-types.js";
91
+
92
+ // Precise nominal type descriptors (the static face of the factory returns).
93
+ export type {
94
+ NullDescriptor,
95
+ BoolType,
96
+ IntType, Int8Type, Int16Type, Int32Type, Int64Type,
97
+ Uint8Type, Uint16Type, Uint32Type, Uint64Type,
98
+ FloatType, Utf8Type, LargeUtf8Type, BinaryType, LargeBinaryType,
99
+ FixedSizeBinaryType, DecimalType,
100
+ Date32Type, Date64Type, Time32Type, Time64Type,
101
+ TimestampType, DurationType, IntervalType,
102
+ ListType, FixedSizeListType, StructType, MapType, DictionaryType, UnionType,
103
+ TypedField, TUnit,
104
+ } from "./codec/type-descriptors.js";
105
+
106
+ // Rich/raw value mapping.
107
+ export type { RichValue, RawValue, ValueFor, Repr } from "./codec/repr.js";
108
+
109
+ // Codec registry (single value rich<->canonical<->raw converters for manual use).
110
+ export { codecFor } from "./codec/registry.js";
111
+ export type { Codec } from "./codec/registry.js";
112
+
113
+ // Branded raw scalar types + validating constructors / unwrappers.
114
+ export type {
115
+ Branded,
116
+ Date32, Date64Ms,
117
+ Time32S, Time32Ms, Time64Us, Time64Ns,
118
+ TimestampSeconds, TimestampMillis, TimestampMicros, TimestampNanos,
119
+ DurationSeconds, DurationMillis, DurationMicros, DurationNanos,
120
+ UnscaledDecimal, Int64 as Int64Raw, Uint64 as Uint64Raw,
121
+ } from "./codec/branded.js";
122
+ export {
123
+ asDate32, asDate64Ms,
124
+ asTime32S, asTime32Ms, asTime64Us, asTime64Ns,
125
+ asTimestampSeconds, asTimestampMillis, asTimestampMicros, asTimestampNanos,
126
+ asDurationSeconds, asDurationMillis, asDurationMicros, asDurationNanos,
127
+ asUnscaledDecimal, asInt64, asUint64,
128
+ fromBranded, fromBrandedNumber, fromBrandedBigInt,
129
+ } from "./codec/branded.js";
@@ -0,0 +1,66 @@
1
+ // Copyright 2025, 2026 Query Farm LLC - https://query.farm
2
+ // Backend-agnostic Arrow type predicates. Both arrow-js and flechette
3
+ // expose `typeId` on every DataType with identical numeric values, so a
4
+ // single `t.typeId === N` check works regardless of the active backend.
5
+
6
+ import type { VgiDataType } from "./types.js";
7
+
8
+ export const TypeId = {
9
+ Null: 1,
10
+ Int: 2,
11
+ Float: 3,
12
+ Binary: 4,
13
+ Utf8: 5,
14
+ Bool: 6,
15
+ Decimal: 7,
16
+ Date: 8,
17
+ Time: 9,
18
+ Timestamp: 10,
19
+ Interval: 11,
20
+ List: 12,
21
+ Struct: 13,
22
+ Union: 14,
23
+ FixedSizeBinary: 15,
24
+ FixedSizeList: 16,
25
+ Map: 17,
26
+ Duration: 18,
27
+ LargeBinary: 19,
28
+ LargeUtf8: 20,
29
+ Dictionary: -1,
30
+ } as const;
31
+
32
+ export function isNull(t: VgiDataType): boolean { return t.typeId === TypeId.Null; }
33
+ export function isInt(t: VgiDataType): boolean { return t.typeId === TypeId.Int; }
34
+ export function isFloat(t: VgiDataType): boolean { return t.typeId === TypeId.Float; }
35
+ export function isBinary(t: VgiDataType): boolean {
36
+ return t.typeId === TypeId.Binary || t.typeId === TypeId.LargeBinary;
37
+ }
38
+ export function isUtf8(t: VgiDataType): boolean {
39
+ return t.typeId === TypeId.Utf8 || t.typeId === TypeId.LargeUtf8;
40
+ }
41
+ export function isBool(t: VgiDataType): boolean { return t.typeId === TypeId.Bool; }
42
+ export function isDecimal(t: VgiDataType): boolean { return t.typeId === TypeId.Decimal; }
43
+ export function isDate(t: VgiDataType): boolean { return t.typeId === TypeId.Date; }
44
+ export function isTime(t: VgiDataType): boolean { return t.typeId === TypeId.Time; }
45
+ export function isTimestamp(t: VgiDataType): boolean { return t.typeId === TypeId.Timestamp; }
46
+ export function isInterval(t: VgiDataType): boolean { return t.typeId === TypeId.Interval; }
47
+ export function isList(t: VgiDataType): boolean { return t.typeId === TypeId.List; }
48
+ export function isStruct(t: VgiDataType): boolean { return t.typeId === TypeId.Struct; }
49
+ export function isUnion(t: VgiDataType): boolean { return t.typeId === TypeId.Union; }
50
+ export function isFixedSizeBinary(t: VgiDataType): boolean { return t.typeId === TypeId.FixedSizeBinary; }
51
+ export function isFixedSizeList(t: VgiDataType): boolean { return t.typeId === TypeId.FixedSizeList; }
52
+ export function isMap(t: VgiDataType): boolean { return t.typeId === TypeId.Map; }
53
+ export function isDuration(t: VgiDataType): boolean { return t.typeId === TypeId.Duration; }
54
+ export function isDictionary(t: VgiDataType): boolean { return t.typeId === TypeId.Dictionary; }
55
+
56
+ /** Runtime check: does `x` quack like a VgiBatch? Used at API boundaries
57
+ * where callers may pass either a batch or a plain column dict. Duck-typed
58
+ * because arrow-js and flechette use unrelated classes. */
59
+ export function isBatch(x: unknown): x is import("./types.js").VgiBatch {
60
+ return (
61
+ x != null &&
62
+ typeof (x as any).numRows === "number" &&
63
+ (x as any).schema != null &&
64
+ Array.isArray((x as any).schema.fields)
65
+ );
66
+ }