@loaders.gl/parquet 4.5.3 → 5.0.0-alpha.10

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 (790) hide show
  1. package/LICENSE +14 -3
  2. package/dist/bundled.d.ts +9 -0
  3. package/dist/bundled.d.ts.map +1 -0
  4. package/dist/bundled.js +10 -0
  5. package/dist/bundled.js.map +1 -0
  6. package/dist/delta-format.d.ts +9 -0
  7. package/dist/delta-format.d.ts.map +1 -0
  8. package/dist/delta-format.js +12 -0
  9. package/dist/delta-format.js.map +1 -0
  10. package/dist/delta-source-loader-types.d.ts +27 -0
  11. package/dist/delta-source-loader-types.d.ts.map +1 -0
  12. package/dist/delta-source-loader-types.js +28 -0
  13. package/dist/delta-source-loader-types.js.map +1 -0
  14. package/dist/delta-source.d.ts +48 -0
  15. package/dist/delta-source.d.ts.map +1 -0
  16. package/dist/delta-source.js +222 -0
  17. package/dist/delta-source.js.map +1 -0
  18. package/dist/delta-types.d.ts +38 -0
  19. package/dist/delta-types.d.ts.map +1 -0
  20. package/dist/delta-types.js +5 -0
  21. package/dist/delta-types.js.map +1 -0
  22. package/dist/geoparquet-loader-with-parser.d.ts +33 -0
  23. package/dist/geoparquet-loader-with-parser.d.ts.map +1 -0
  24. package/dist/geoparquet-loader-with-parser.js +52 -0
  25. package/dist/geoparquet-loader-with-parser.js.map +1 -0
  26. package/dist/geoparquet-loader.d.ts +59 -0
  27. package/dist/geoparquet-loader.d.ts.map +1 -0
  28. package/dist/geoparquet-loader.js +30 -0
  29. package/dist/geoparquet-loader.js.map +1 -0
  30. package/dist/iceberg-rest-catalog.d.ts +49 -0
  31. package/dist/iceberg-rest-catalog.d.ts.map +1 -0
  32. package/dist/iceberg-rest-catalog.js +78 -0
  33. package/dist/iceberg-rest-catalog.js.map +1 -0
  34. package/dist/iceberg-table-source.d.ts +63 -0
  35. package/dist/iceberg-table-source.d.ts.map +1 -0
  36. package/dist/iceberg-table-source.js +797 -0
  37. package/dist/iceberg-table-source.js.map +1 -0
  38. package/dist/iceberg-types.d.ts +150 -0
  39. package/dist/iceberg-types.d.ts.map +1 -0
  40. package/dist/iceberg-types.js +5 -0
  41. package/dist/iceberg-types.js.map +1 -0
  42. package/dist/index.cjs +41568 -6781
  43. package/dist/index.cjs.map +3 -4
  44. package/dist/index.d.ts +15 -9
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +11 -12
  47. package/dist/index.js.map +1 -1
  48. package/dist/lib/arrow/convert-columns-to-row-group.js +3 -0
  49. package/dist/lib/arrow/convert-columns-to-row-group.js.map +1 -1
  50. package/dist/lib/arrow/convert-schema-from-parquet.d.ts +3 -1
  51. package/dist/lib/arrow/convert-schema-from-parquet.d.ts.map +1 -1
  52. package/dist/lib/arrow/convert-schema-from-parquet.js +164 -29
  53. package/dist/lib/arrow/convert-schema-from-parquet.js.map +1 -1
  54. package/dist/lib/arrow/convert-schema-to-parquet.d.ts.map +1 -1
  55. package/dist/lib/arrow/convert-schema-to-parquet.js +16 -7
  56. package/dist/lib/arrow/convert-schema-to-parquet.js.map +1 -1
  57. package/dist/lib/arrow/create-nested-arrow-vector.d.ts +8 -0
  58. package/dist/lib/arrow/create-nested-arrow-vector.d.ts.map +1 -0
  59. package/dist/lib/arrow/create-nested-arrow-vector.js +485 -0
  60. package/dist/lib/arrow/create-nested-arrow-vector.js.map +1 -0
  61. package/dist/lib/constants.d.ts +0 -1
  62. package/dist/lib/constants.d.ts.map +1 -1
  63. package/dist/lib/constants.js +1 -2
  64. package/dist/lib/constants.js.map +1 -1
  65. package/dist/lib/encoders/encode-arrow-to-parquet.d.ts +2 -2
  66. package/dist/lib/encoders/encode-arrow-to-parquet.d.ts.map +1 -1
  67. package/dist/lib/encoders/encode-arrow-to-parquet.js +3 -10
  68. package/dist/lib/encoders/encode-arrow-to-parquet.js.map +1 -1
  69. package/dist/lib/encoders/encode-table-to-parquet-js.d.ts +5 -0
  70. package/dist/lib/encoders/encode-table-to-parquet-js.d.ts.map +1 -0
  71. package/dist/lib/encoders/encode-table-to-parquet-js.js +394 -0
  72. package/dist/lib/encoders/encode-table-to-parquet-js.js.map +1 -0
  73. package/dist/lib/geo/geoparquet-covering.d.ts +19 -0
  74. package/dist/lib/geo/geoparquet-covering.d.ts.map +1 -0
  75. package/dist/lib/geo/geoparquet-covering.js +137 -0
  76. package/dist/lib/geo/geoparquet-covering.js.map +1 -0
  77. package/dist/lib/geo/geospatial-metadata.d.ts +67 -0
  78. package/dist/lib/geo/geospatial-metadata.d.ts.map +1 -0
  79. package/dist/lib/geo/geospatial-metadata.js +412 -0
  80. package/dist/lib/geo/geospatial-metadata.js.map +1 -0
  81. package/dist/lib/parquet-bloom-filter-planner.d.ts +16 -0
  82. package/dist/lib/parquet-bloom-filter-planner.d.ts.map +1 -0
  83. package/dist/lib/parquet-bloom-filter-planner.js +57 -0
  84. package/dist/lib/parquet-bloom-filter-planner.js.map +1 -0
  85. package/dist/lib/parquet-bloom-filter.d.ts +30 -0
  86. package/dist/lib/parquet-bloom-filter.d.ts.map +1 -0
  87. package/dist/lib/parquet-bloom-filter.js +289 -0
  88. package/dist/lib/parquet-bloom-filter.js.map +1 -0
  89. package/dist/lib/parquet-encryption.d.ts +80 -0
  90. package/dist/lib/parquet-encryption.d.ts.map +1 -0
  91. package/dist/lib/parquet-encryption.js +190 -0
  92. package/dist/lib/parquet-encryption.js.map +1 -0
  93. package/dist/lib/parquet-page-index.d.ts +91 -0
  94. package/dist/lib/parquet-page-index.d.ts.map +1 -0
  95. package/dist/lib/parquet-page-index.js +463 -0
  96. package/dist/lib/parquet-page-index.js.map +1 -0
  97. package/dist/lib/parquet-predicate.d.ts +21 -0
  98. package/dist/lib/parquet-predicate.d.ts.map +1 -0
  99. package/dist/lib/parquet-predicate.js +328 -0
  100. package/dist/lib/parquet-predicate.js.map +1 -0
  101. package/dist/lib/parquet-source-worker-client.d.ts +6 -0
  102. package/dist/lib/parquet-source-worker-client.d.ts.map +1 -0
  103. package/dist/lib/parquet-source-worker-client.js +24 -0
  104. package/dist/lib/parquet-source-worker-client.js.map +1 -0
  105. package/dist/lib/parquet-source-worker-decoder.d.ts +7 -0
  106. package/dist/lib/parquet-source-worker-decoder.d.ts.map +1 -0
  107. package/dist/lib/parquet-source-worker-decoder.js +181 -0
  108. package/dist/lib/parquet-source-worker-decoder.js.map +1 -0
  109. package/dist/lib/parquet-source-worker-file.d.ts +24 -0
  110. package/dist/lib/parquet-source-worker-file.d.ts.map +1 -0
  111. package/dist/lib/parquet-source-worker-file.js +40 -0
  112. package/dist/lib/parquet-source-worker-file.js.map +1 -0
  113. package/dist/lib/parquet-source-worker-types.d.ts +121 -0
  114. package/dist/lib/parquet-source-worker-types.d.ts.map +1 -0
  115. package/dist/lib/parquet-source-worker-types.js +5 -0
  116. package/dist/lib/parquet-source-worker-types.js.map +1 -0
  117. package/dist/lib/parquet-worker-transport.d.ts +8 -0
  118. package/dist/lib/parquet-worker-transport.d.ts.map +1 -0
  119. package/dist/lib/parquet-worker-transport.js +40 -0
  120. package/dist/lib/parquet-worker-transport.js.map +1 -0
  121. package/dist/lib/parsers/convert-parquet-tables.d.ts +16 -0
  122. package/dist/lib/parsers/convert-parquet-tables.d.ts.map +1 -0
  123. package/dist/lib/parsers/convert-parquet-tables.js +30 -0
  124. package/dist/lib/parsers/convert-parquet-tables.js.map +1 -0
  125. package/dist/lib/parsers/get-parquet-schema.d.ts.map +1 -1
  126. package/dist/lib/parsers/get-parquet-schema.js +6 -2
  127. package/dist/lib/parsers/get-parquet-schema.js.map +1 -1
  128. package/dist/lib/parsers/parse-geoparquet-to-geojson.d.ts +4 -4
  129. package/dist/lib/parsers/parse-geoparquet-to-geojson.d.ts.map +1 -1
  130. package/dist/lib/parsers/parse-geoparquet-to-geojson.js +19 -6
  131. package/dist/lib/parsers/parse-geoparquet-to-geojson.js.map +1 -1
  132. package/dist/lib/parsers/parse-parquet-tables.d.ts +37 -0
  133. package/dist/lib/parsers/parse-parquet-tables.d.ts.map +1 -0
  134. package/dist/lib/parsers/parse-parquet-tables.js +50 -0
  135. package/dist/lib/parsers/parse-parquet-tables.js.map +1 -0
  136. package/dist/lib/parsers/parse-parquet-to-arrow-js.d.ts +19 -0
  137. package/dist/lib/parsers/parse-parquet-to-arrow-js.d.ts.map +1 -0
  138. package/dist/lib/parsers/parse-parquet-to-arrow-js.js +921 -0
  139. package/dist/lib/parsers/parse-parquet-to-arrow-js.js.map +1 -0
  140. package/dist/lib/parsers/parse-parquet-to-arrow.d.ts +7 -7
  141. package/dist/lib/parsers/parse-parquet-to-arrow.d.ts.map +1 -1
  142. package/dist/lib/parsers/parse-parquet-to-arrow.js +45 -32
  143. package/dist/lib/parsers/parse-parquet-to-arrow.js.map +1 -1
  144. package/dist/lib/parsers/parse-parquet-to-columns.d.ts +3 -3
  145. package/dist/lib/parsers/parse-parquet-to-columns.d.ts.map +1 -1
  146. package/dist/lib/parsers/parse-parquet-to-columns.js +4 -5
  147. package/dist/lib/parsers/parse-parquet-to-columns.js.map +1 -1
  148. package/dist/lib/parsers/parse-parquet-to-json.d.ts +3 -3
  149. package/dist/lib/parsers/parse-parquet-to-json.d.ts.map +1 -1
  150. package/dist/lib/parsers/parse-parquet-to-json.js +95 -28
  151. package/dist/lib/parsers/parse-parquet-to-json.js.map +1 -1
  152. package/dist/lib/slice-parquet-batch.d.ts +9 -0
  153. package/dist/lib/slice-parquet-batch.d.ts.map +1 -0
  154. package/dist/lib/slice-parquet-batch.js +28 -0
  155. package/dist/lib/slice-parquet-batch.js.map +1 -0
  156. package/dist/lib/sources/parquet-range-file.d.ts +80 -0
  157. package/dist/lib/sources/parquet-range-file.d.ts.map +1 -0
  158. package/dist/lib/sources/parquet-range-file.js +267 -0
  159. package/dist/lib/sources/parquet-range-file.js.map +1 -0
  160. package/dist/lib/sources/single-batch-queue.d.ts +24 -0
  161. package/dist/lib/sources/single-batch-queue.d.ts.map +1 -0
  162. package/dist/lib/sources/single-batch-queue.js +91 -0
  163. package/dist/lib/sources/single-batch-queue.js.map +1 -0
  164. package/dist/lib/utils/load-wasm-node.d.ts +3 -0
  165. package/dist/lib/utils/load-wasm-node.d.ts.map +1 -0
  166. package/dist/lib/utils/load-wasm-node.js +23 -0
  167. package/dist/lib/utils/load-wasm-node.js.map +1 -0
  168. package/dist/lib/utils/load-wasm.d.ts +2 -2
  169. package/dist/lib/utils/load-wasm.d.ts.map +1 -1
  170. package/dist/lib/utils/load-wasm.js +28 -12
  171. package/dist/lib/utils/load-wasm.js.map +1 -1
  172. package/dist/lib/utils/make-stream-iterator.d.ts +2 -0
  173. package/dist/lib/utils/make-stream-iterator.d.ts.map +1 -1
  174. package/dist/lib/utils/make-stream-iterator.js +123 -14
  175. package/dist/lib/utils/make-stream-iterator.js.map +1 -1
  176. package/dist/lib/utils/normalize-parquet-options.d.ts +5 -0
  177. package/dist/lib/utils/normalize-parquet-options.d.ts.map +1 -0
  178. package/dist/lib/utils/normalize-parquet-options.js +25 -0
  179. package/dist/lib/utils/normalize-parquet-options.js.map +1 -0
  180. package/dist/parquet-dataset-source.cjs +38974 -0
  181. package/dist/parquet-dataset-source.cjs.map +6 -0
  182. package/dist/parquet-dataset-source.d.ts +81 -0
  183. package/dist/parquet-dataset-source.d.ts.map +1 -0
  184. package/dist/parquet-dataset-source.js +602 -0
  185. package/dist/parquet-dataset-source.js.map +1 -0
  186. package/dist/parquet-encoded-page-types.d.ts +108 -0
  187. package/dist/parquet-encoded-page-types.d.ts.map +1 -0
  188. package/dist/parquet-encoded-page-types.js +5 -0
  189. package/dist/parquet-encoded-page-types.js.map +1 -0
  190. package/dist/parquet-format.d.ts +2 -0
  191. package/dist/parquet-format.d.ts.map +1 -1
  192. package/dist/parquet-format.js +2 -0
  193. package/dist/parquet-format.js.map +1 -1
  194. package/dist/parquet-js-loader-types.d.ts +59 -0
  195. package/dist/parquet-js-loader-types.d.ts.map +1 -0
  196. package/dist/parquet-js-loader-types.js +34 -0
  197. package/dist/parquet-js-loader-types.js.map +1 -0
  198. package/dist/parquet-js-loader.d.ts +18 -22
  199. package/dist/parquet-js-loader.d.ts.map +1 -1
  200. package/dist/parquet-js-loader.js +53 -14
  201. package/dist/parquet-js-loader.js.map +1 -1
  202. package/dist/parquet-js-writer.d.ts +65 -0
  203. package/dist/parquet-js-writer.d.ts.map +1 -0
  204. package/dist/parquet-js-writer.js +28 -0
  205. package/dist/parquet-js-writer.js.map +1 -0
  206. package/dist/parquet-loader-base.d.ts +25 -0
  207. package/dist/parquet-loader-base.d.ts.map +1 -0
  208. package/dist/parquet-loader-base.js +23 -0
  209. package/dist/parquet-loader-base.js.map +1 -0
  210. package/dist/parquet-loader-options.d.ts +55 -0
  211. package/dist/parquet-loader-options.d.ts.map +1 -0
  212. package/dist/parquet-loader-options.js +10 -0
  213. package/dist/parquet-loader-options.js.map +1 -0
  214. package/dist/parquet-loader-types.d.ts +61 -0
  215. package/dist/parquet-loader-types.d.ts.map +1 -0
  216. package/dist/parquet-loader-types.js +17 -0
  217. package/dist/parquet-loader-types.js.map +1 -0
  218. package/dist/parquet-loader.d.ts +42 -0
  219. package/dist/parquet-loader.d.ts.map +1 -0
  220. package/dist/parquet-loader.js +68 -0
  221. package/dist/parquet-loader.js.map +1 -0
  222. package/dist/parquet-source-capabilities.d.ts +43 -0
  223. package/dist/parquet-source-capabilities.d.ts.map +1 -0
  224. package/dist/parquet-source-capabilities.js +32 -0
  225. package/dist/parquet-source-capabilities.js.map +1 -0
  226. package/dist/parquet-source-loader-types.d.ts +82 -0
  227. package/dist/parquet-source-loader-types.d.ts.map +1 -0
  228. package/dist/parquet-source-loader-types.js +84 -0
  229. package/dist/parquet-source-loader-types.js.map +1 -0
  230. package/dist/parquet-source-loader.cjs +38261 -0
  231. package/dist/parquet-source-loader.cjs.map +6 -0
  232. package/dist/parquet-source-loader.d.ts +167 -0
  233. package/dist/parquet-source-loader.d.ts.map +1 -0
  234. package/dist/parquet-source-loader.js +1438 -0
  235. package/dist/parquet-source-loader.js.map +1 -0
  236. package/dist/parquet-source-types.d.ts +534 -0
  237. package/dist/parquet-source-types.d.ts.map +1 -0
  238. package/dist/parquet-source-types.js +5 -0
  239. package/dist/parquet-source-types.js.map +1 -0
  240. package/dist/parquet-source-worker-factory.d.ts +4 -0
  241. package/dist/parquet-source-worker-factory.d.ts.map +1 -0
  242. package/dist/parquet-source-worker-factory.js +6 -0
  243. package/dist/parquet-source-worker-factory.js.map +1 -0
  244. package/dist/parquet-source-worker-url.d.ts +3 -0
  245. package/dist/parquet-source-worker-url.d.ts.map +1 -0
  246. package/dist/parquet-source-worker-url.js +22 -0
  247. package/dist/parquet-source-worker-url.js.map +1 -0
  248. package/dist/parquet-source-worker.js +38871 -0
  249. package/dist/parquet-source-worker.js.map +7 -0
  250. package/dist/parquet-worker-node.cjs +78507 -0
  251. package/dist/parquet-worker-node.cjs.map +7 -0
  252. package/dist/parquet-worker-url.d.ts +3 -0
  253. package/dist/parquet-worker-url.d.ts.map +1 -0
  254. package/dist/parquet-worker-url.js +19 -0
  255. package/dist/parquet-worker-url.js.map +1 -0
  256. package/dist/parquet-worker.js +20094 -0
  257. package/dist/parquet-worker.js.map +7 -0
  258. package/dist/parquet-writer.d.ts +10 -0
  259. package/dist/parquet-writer.d.ts.map +1 -0
  260. package/dist/parquet-writer.js +27 -0
  261. package/dist/parquet-writer.js.map +1 -0
  262. package/dist/parquet_wasm_bg.wasm +0 -0
  263. package/dist/parquetjs/codecs/byte-stream-split.d.ts +9 -0
  264. package/dist/parquetjs/codecs/byte-stream-split.d.ts.map +1 -0
  265. package/dist/parquetjs/codecs/byte-stream-split.js +159 -0
  266. package/dist/parquetjs/codecs/byte-stream-split.js.map +1 -0
  267. package/dist/parquetjs/codecs/declare.d.ts +35 -3
  268. package/dist/parquetjs/codecs/declare.d.ts.map +1 -1
  269. package/dist/parquetjs/codecs/declare.js +17 -1
  270. package/dist/parquetjs/codecs/declare.js.map +1 -1
  271. package/dist/parquetjs/codecs/delta.d.ts +17 -0
  272. package/dist/parquetjs/codecs/delta.d.ts.map +1 -0
  273. package/dist/parquetjs/codecs/delta.js +788 -0
  274. package/dist/parquetjs/codecs/delta.js.map +1 -0
  275. package/dist/parquetjs/codecs/dictionary.d.ts +5 -2
  276. package/dist/parquetjs/codecs/dictionary.d.ts.map +1 -1
  277. package/dist/parquetjs/codecs/dictionary.js +16 -4
  278. package/dist/parquetjs/codecs/dictionary.js.map +1 -1
  279. package/dist/parquetjs/codecs/index.d.ts.map +1 -1
  280. package/dist/parquetjs/codecs/index.js +22 -0
  281. package/dist/parquetjs/codecs/index.js.map +1 -1
  282. package/dist/parquetjs/codecs/plain.d.ts +3 -3
  283. package/dist/parquetjs/codecs/plain.d.ts.map +1 -1
  284. package/dist/parquetjs/codecs/plain.js +231 -78
  285. package/dist/parquetjs/codecs/plain.js.map +1 -1
  286. package/dist/parquetjs/codecs/rle.d.ts +7 -3
  287. package/dist/parquetjs/codecs/rle.d.ts.map +1 -1
  288. package/dist/parquetjs/codecs/rle.js +613 -69
  289. package/dist/parquetjs/codecs/rle.js.map +1 -1
  290. package/dist/parquetjs/compression.d.ts +16 -8
  291. package/dist/parquetjs/compression.d.ts.map +1 -1
  292. package/dist/parquetjs/compression.js +114 -141
  293. package/dist/parquetjs/compression.js.map +1 -1
  294. package/dist/parquetjs/encoder/dictionary-planner.d.ts +17 -0
  295. package/dist/parquetjs/encoder/dictionary-planner.d.ts.map +1 -0
  296. package/dist/parquetjs/encoder/dictionary-planner.js +67 -0
  297. package/dist/parquetjs/encoder/dictionary-planner.js.map +1 -0
  298. package/dist/parquetjs/encoder/page-planner.d.ts +11 -0
  299. package/dist/parquetjs/encoder/page-planner.d.ts.map +1 -0
  300. package/dist/parquetjs/encoder/page-planner.js +60 -0
  301. package/dist/parquetjs/encoder/page-planner.js.map +1 -0
  302. package/dist/parquetjs/encoder/parquet-encoder.d.ts +54 -5
  303. package/dist/parquetjs/encoder/parquet-encoder.d.ts.map +1 -1
  304. package/dist/parquetjs/encoder/parquet-encoder.js +930 -66
  305. package/dist/parquetjs/encoder/parquet-encoder.js.map +1 -1
  306. package/dist/parquetjs/parquet-thrift/BoundingBox.d.ts +29 -0
  307. package/dist/parquetjs/parquet-thrift/BoundingBox.d.ts.map +1 -0
  308. package/dist/parquetjs/parquet-thrift/BoundingBox.js +85 -0
  309. package/dist/parquetjs/parquet-thrift/BoundingBox.js.map +1 -0
  310. package/dist/parquetjs/parquet-thrift/BsonType.d.ts +1 -1
  311. package/dist/parquetjs/parquet-thrift/BsonType.d.ts.map +1 -1
  312. package/dist/parquetjs/parquet-thrift/BsonType.js +1 -1
  313. package/dist/parquetjs/parquet-thrift/BsonType.js.map +1 -1
  314. package/dist/parquetjs/parquet-thrift/ColumnChunk.d.ts +7 -2
  315. package/dist/parquetjs/parquet-thrift/ColumnChunk.d.ts.map +1 -1
  316. package/dist/parquetjs/parquet-thrift/ColumnChunk.js +37 -2
  317. package/dist/parquetjs/parquet-thrift/ColumnChunk.js.map +1 -1
  318. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.d.ts +35 -0
  319. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.d.ts.map +1 -0
  320. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.js +135 -0
  321. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.js.map +1 -0
  322. package/dist/parquetjs/parquet-thrift/ColumnIndex.d.ts +6 -6
  323. package/dist/parquetjs/parquet-thrift/ColumnIndex.d.ts.map +1 -1
  324. package/dist/parquetjs/parquet-thrift/ColumnIndex.js +3 -3
  325. package/dist/parquetjs/parquet-thrift/ColumnIndex.js.map +1 -1
  326. package/dist/parquetjs/parquet-thrift/ColumnMetaData.d.ts +12 -2
  327. package/dist/parquetjs/parquet-thrift/ColumnMetaData.d.ts.map +1 -1
  328. package/dist/parquetjs/parquet-thrift/ColumnMetaData.js +75 -2
  329. package/dist/parquetjs/parquet-thrift/ColumnMetaData.js.map +1 -1
  330. package/dist/parquetjs/parquet-thrift/ColumnOrder.d.ts +1 -1
  331. package/dist/parquetjs/parquet-thrift/ColumnOrder.d.ts.map +1 -1
  332. package/dist/parquetjs/parquet-thrift/ColumnOrder.js +1 -1
  333. package/dist/parquetjs/parquet-thrift/ColumnOrder.js.map +1 -1
  334. package/dist/parquetjs/parquet-thrift/DataPageHeader.d.ts +1 -1
  335. package/dist/parquetjs/parquet-thrift/DataPageHeader.d.ts.map +1 -1
  336. package/dist/parquetjs/parquet-thrift/DataPageHeader.js +1 -1
  337. package/dist/parquetjs/parquet-thrift/DataPageHeader.js.map +1 -1
  338. package/dist/parquetjs/parquet-thrift/DataPageHeaderV2.d.ts +1 -1
  339. package/dist/parquetjs/parquet-thrift/DataPageHeaderV2.d.ts.map +1 -1
  340. package/dist/parquetjs/parquet-thrift/DataPageHeaderV2.js +1 -1
  341. package/dist/parquetjs/parquet-thrift/DataPageHeaderV2.js.map +1 -1
  342. package/dist/parquetjs/parquet-thrift/DateType.d.ts +1 -1
  343. package/dist/parquetjs/parquet-thrift/DateType.d.ts.map +1 -1
  344. package/dist/parquetjs/parquet-thrift/DateType.js +1 -1
  345. package/dist/parquetjs/parquet-thrift/DateType.js.map +1 -1
  346. package/dist/parquetjs/parquet-thrift/DecimalType.d.ts +1 -1
  347. package/dist/parquetjs/parquet-thrift/DecimalType.d.ts.map +1 -1
  348. package/dist/parquetjs/parquet-thrift/DecimalType.js +1 -1
  349. package/dist/parquetjs/parquet-thrift/DecimalType.js.map +1 -1
  350. package/dist/parquetjs/parquet-thrift/DictionaryPageHeader.d.ts +1 -1
  351. package/dist/parquetjs/parquet-thrift/DictionaryPageHeader.d.ts.map +1 -1
  352. package/dist/parquetjs/parquet-thrift/DictionaryPageHeader.js +1 -1
  353. package/dist/parquetjs/parquet-thrift/DictionaryPageHeader.js.map +1 -1
  354. package/dist/parquetjs/parquet-thrift/EdgeInterpolationAlgorithm.d.ts +8 -0
  355. package/dist/parquetjs/parquet-thrift/EdgeInterpolationAlgorithm.d.ts.map +1 -0
  356. package/dist/parquetjs/parquet-thrift/EdgeInterpolationAlgorithm.js +14 -0
  357. package/dist/parquetjs/parquet-thrift/EdgeInterpolationAlgorithm.js.map +1 -0
  358. package/dist/parquetjs/parquet-thrift/Encoding.d.ts +2 -1
  359. package/dist/parquetjs/parquet-thrift/Encoding.d.ts.map +1 -1
  360. package/dist/parquetjs/parquet-thrift/Encoding.js +1 -0
  361. package/dist/parquetjs/parquet-thrift/Encoding.js.map +1 -1
  362. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.d.ts +22 -0
  363. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.d.ts.map +1 -0
  364. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.js +111 -0
  365. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.js.map +1 -0
  366. package/dist/parquetjs/parquet-thrift/EnumType.d.ts +1 -1
  367. package/dist/parquetjs/parquet-thrift/EnumType.d.ts.map +1 -1
  368. package/dist/parquetjs/parquet-thrift/EnumType.js +1 -1
  369. package/dist/parquetjs/parquet-thrift/EnumType.js.map +1 -1
  370. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.d.ts +16 -0
  371. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.d.ts.map +1 -0
  372. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.js +57 -0
  373. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.js.map +1 -0
  374. package/dist/parquetjs/parquet-thrift/FileMetaData.d.ts +7 -2
  375. package/dist/parquetjs/parquet-thrift/FileMetaData.d.ts.map +1 -1
  376. package/dist/parquetjs/parquet-thrift/FileMetaData.js +37 -2
  377. package/dist/parquetjs/parquet-thrift/FileMetaData.js.map +1 -1
  378. package/dist/parquetjs/parquet-thrift/Float16Type.d.ts +9 -0
  379. package/dist/parquetjs/parquet-thrift/Float16Type.d.ts.map +1 -0
  380. package/dist/parquetjs/parquet-thrift/Float16Type.js +27 -0
  381. package/dist/parquetjs/parquet-thrift/Float16Type.js.map +1 -0
  382. package/dist/parquetjs/parquet-thrift/GeographyType.d.ts +14 -0
  383. package/dist/parquetjs/parquet-thrift/GeographyType.d.ts.map +1 -0
  384. package/dist/parquetjs/parquet-thrift/GeographyType.js +51 -0
  385. package/dist/parquetjs/parquet-thrift/GeographyType.js.map +1 -0
  386. package/dist/parquetjs/parquet-thrift/GeometryType.d.ts +11 -0
  387. package/dist/parquetjs/parquet-thrift/GeometryType.d.ts.map +1 -0
  388. package/dist/parquetjs/parquet-thrift/GeometryType.js +41 -0
  389. package/dist/parquetjs/parquet-thrift/GeometryType.js.map +1 -0
  390. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.d.ts +18 -0
  391. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.d.ts.map +1 -0
  392. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.js +62 -0
  393. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.js.map +1 -0
  394. package/dist/parquetjs/parquet-thrift/IndexPageHeader.d.ts +1 -1
  395. package/dist/parquetjs/parquet-thrift/IndexPageHeader.d.ts.map +1 -1
  396. package/dist/parquetjs/parquet-thrift/IndexPageHeader.js +1 -1
  397. package/dist/parquetjs/parquet-thrift/IndexPageHeader.js.map +1 -1
  398. package/dist/parquetjs/parquet-thrift/IntType.d.ts +1 -1
  399. package/dist/parquetjs/parquet-thrift/IntType.d.ts.map +1 -1
  400. package/dist/parquetjs/parquet-thrift/IntType.js +1 -1
  401. package/dist/parquetjs/parquet-thrift/IntType.js.map +1 -1
  402. package/dist/parquetjs/parquet-thrift/JsonType.d.ts +1 -1
  403. package/dist/parquetjs/parquet-thrift/JsonType.d.ts.map +1 -1
  404. package/dist/parquetjs/parquet-thrift/JsonType.js +1 -1
  405. package/dist/parquetjs/parquet-thrift/JsonType.js.map +1 -1
  406. package/dist/parquetjs/parquet-thrift/KeyValue.d.ts +1 -1
  407. package/dist/parquetjs/parquet-thrift/KeyValue.d.ts.map +1 -1
  408. package/dist/parquetjs/parquet-thrift/KeyValue.js +1 -1
  409. package/dist/parquetjs/parquet-thrift/KeyValue.js.map +1 -1
  410. package/dist/parquetjs/parquet-thrift/ListType.d.ts +1 -1
  411. package/dist/parquetjs/parquet-thrift/ListType.d.ts.map +1 -1
  412. package/dist/parquetjs/parquet-thrift/ListType.js +1 -1
  413. package/dist/parquetjs/parquet-thrift/ListType.js.map +1 -1
  414. package/dist/parquetjs/parquet-thrift/LogicalType.d.ts +17 -1
  415. package/dist/parquetjs/parquet-thrift/LogicalType.d.ts.map +1 -1
  416. package/dist/parquetjs/parquet-thrift/LogicalType.js +97 -1
  417. package/dist/parquetjs/parquet-thrift/LogicalType.js.map +1 -1
  418. package/dist/parquetjs/parquet-thrift/MapType.d.ts +1 -1
  419. package/dist/parquetjs/parquet-thrift/MapType.d.ts.map +1 -1
  420. package/dist/parquetjs/parquet-thrift/MapType.js +1 -1
  421. package/dist/parquetjs/parquet-thrift/MapType.js.map +1 -1
  422. package/dist/parquetjs/parquet-thrift/MicroSeconds.d.ts +1 -1
  423. package/dist/parquetjs/parquet-thrift/MicroSeconds.d.ts.map +1 -1
  424. package/dist/parquetjs/parquet-thrift/MicroSeconds.js +1 -1
  425. package/dist/parquetjs/parquet-thrift/MicroSeconds.js.map +1 -1
  426. package/dist/parquetjs/parquet-thrift/MilliSeconds.d.ts +1 -1
  427. package/dist/parquetjs/parquet-thrift/MilliSeconds.d.ts.map +1 -1
  428. package/dist/parquetjs/parquet-thrift/MilliSeconds.js +1 -1
  429. package/dist/parquetjs/parquet-thrift/MilliSeconds.js.map +1 -1
  430. package/dist/parquetjs/parquet-thrift/NanoSeconds.d.ts +9 -0
  431. package/dist/parquetjs/parquet-thrift/NanoSeconds.d.ts.map +1 -0
  432. package/dist/parquetjs/parquet-thrift/NanoSeconds.js +27 -0
  433. package/dist/parquetjs/parquet-thrift/NanoSeconds.js.map +1 -0
  434. package/dist/parquetjs/parquet-thrift/NullType.d.ts +1 -1
  435. package/dist/parquetjs/parquet-thrift/NullType.d.ts.map +1 -1
  436. package/dist/parquetjs/parquet-thrift/NullType.js +1 -1
  437. package/dist/parquetjs/parquet-thrift/NullType.js.map +1 -1
  438. package/dist/parquetjs/parquet-thrift/OffsetIndex.d.ts +1 -1
  439. package/dist/parquetjs/parquet-thrift/OffsetIndex.d.ts.map +1 -1
  440. package/dist/parquetjs/parquet-thrift/OffsetIndex.js +1 -1
  441. package/dist/parquetjs/parquet-thrift/OffsetIndex.js.map +1 -1
  442. package/dist/parquetjs/parquet-thrift/PageEncodingStats.d.ts +1 -1
  443. package/dist/parquetjs/parquet-thrift/PageEncodingStats.d.ts.map +1 -1
  444. package/dist/parquetjs/parquet-thrift/PageEncodingStats.js +1 -1
  445. package/dist/parquetjs/parquet-thrift/PageEncodingStats.js.map +1 -1
  446. package/dist/parquetjs/parquet-thrift/PageHeader.d.ts +1 -1
  447. package/dist/parquetjs/parquet-thrift/PageHeader.d.ts.map +1 -1
  448. package/dist/parquetjs/parquet-thrift/PageHeader.js +1 -1
  449. package/dist/parquetjs/parquet-thrift/PageHeader.js.map +1 -1
  450. package/dist/parquetjs/parquet-thrift/PageLocation.d.ts +2 -2
  451. package/dist/parquetjs/parquet-thrift/PageLocation.d.ts.map +1 -1
  452. package/dist/parquetjs/parquet-thrift/PageLocation.js +2 -2
  453. package/dist/parquetjs/parquet-thrift/PageLocation.js.map +1 -1
  454. package/dist/parquetjs/parquet-thrift/RowGroup.d.ts +2 -2
  455. package/dist/parquetjs/parquet-thrift/RowGroup.d.ts.map +1 -1
  456. package/dist/parquetjs/parquet-thrift/RowGroup.js +2 -2
  457. package/dist/parquetjs/parquet-thrift/RowGroup.js.map +1 -1
  458. package/dist/parquetjs/parquet-thrift/SchemaElement.d.ts +1 -1
  459. package/dist/parquetjs/parquet-thrift/SchemaElement.d.ts.map +1 -1
  460. package/dist/parquetjs/parquet-thrift/SchemaElement.js +1 -1
  461. package/dist/parquetjs/parquet-thrift/SchemaElement.js.map +1 -1
  462. package/dist/parquetjs/parquet-thrift/SizeStatistics.d.ts +26 -0
  463. package/dist/parquetjs/parquet-thrift/SizeStatistics.d.ts.map +1 -0
  464. package/dist/parquetjs/parquet-thrift/SizeStatistics.js +85 -0
  465. package/dist/parquetjs/parquet-thrift/SizeStatistics.js.map +1 -0
  466. package/dist/parquetjs/parquet-thrift/SortingColumn.d.ts +1 -1
  467. package/dist/parquetjs/parquet-thrift/SortingColumn.d.ts.map +1 -1
  468. package/dist/parquetjs/parquet-thrift/SortingColumn.js +1 -1
  469. package/dist/parquetjs/parquet-thrift/SortingColumn.js.map +1 -1
  470. package/dist/parquetjs/parquet-thrift/Statistics.d.ts +14 -10
  471. package/dist/parquetjs/parquet-thrift/Statistics.d.ts.map +1 -1
  472. package/dist/parquetjs/parquet-thrift/Statistics.js +38 -2
  473. package/dist/parquetjs/parquet-thrift/Statistics.js.map +1 -1
  474. package/dist/parquetjs/parquet-thrift/StringType.d.ts +1 -1
  475. package/dist/parquetjs/parquet-thrift/StringType.d.ts.map +1 -1
  476. package/dist/parquetjs/parquet-thrift/StringType.js +1 -1
  477. package/dist/parquetjs/parquet-thrift/StringType.js.map +1 -1
  478. package/dist/parquetjs/parquet-thrift/TimeType.d.ts +1 -1
  479. package/dist/parquetjs/parquet-thrift/TimeType.d.ts.map +1 -1
  480. package/dist/parquetjs/parquet-thrift/TimeType.js +1 -1
  481. package/dist/parquetjs/parquet-thrift/TimeType.js.map +1 -1
  482. package/dist/parquetjs/parquet-thrift/TimeUnit.d.ts +5 -1
  483. package/dist/parquetjs/parquet-thrift/TimeUnit.d.ts.map +1 -1
  484. package/dist/parquetjs/parquet-thrift/TimeUnit.js +25 -1
  485. package/dist/parquetjs/parquet-thrift/TimeUnit.js.map +1 -1
  486. package/dist/parquetjs/parquet-thrift/TimestampType.d.ts +1 -1
  487. package/dist/parquetjs/parquet-thrift/TimestampType.d.ts.map +1 -1
  488. package/dist/parquetjs/parquet-thrift/TimestampType.js +1 -1
  489. package/dist/parquetjs/parquet-thrift/TimestampType.js.map +1 -1
  490. package/dist/parquetjs/parquet-thrift/TypeDefinedOrder.d.ts +1 -1
  491. package/dist/parquetjs/parquet-thrift/TypeDefinedOrder.d.ts.map +1 -1
  492. package/dist/parquetjs/parquet-thrift/TypeDefinedOrder.js +1 -1
  493. package/dist/parquetjs/parquet-thrift/TypeDefinedOrder.js.map +1 -1
  494. package/dist/parquetjs/parquet-thrift/UUIDType.d.ts +1 -1
  495. package/dist/parquetjs/parquet-thrift/UUIDType.d.ts.map +1 -1
  496. package/dist/parquetjs/parquet-thrift/UUIDType.js +1 -1
  497. package/dist/parquetjs/parquet-thrift/UUIDType.js.map +1 -1
  498. package/dist/parquetjs/parquet-thrift/VariantType.d.ts +11 -0
  499. package/dist/parquetjs/parquet-thrift/VariantType.d.ts.map +1 -0
  500. package/dist/parquetjs/parquet-thrift/VariantType.js +41 -0
  501. package/dist/parquetjs/parquet-thrift/VariantType.js.map +1 -0
  502. package/dist/parquetjs/parquet-thrift/index.d.ts +12 -2
  503. package/dist/parquetjs/parquet-thrift/index.d.ts.map +1 -1
  504. package/dist/parquetjs/parquet-thrift/index.js +12 -2
  505. package/dist/parquetjs/parquet-thrift/index.js.map +1 -1
  506. package/dist/parquetjs/parser/decoders.d.ts +23 -3
  507. package/dist/parquetjs/parser/decoders.d.ts.map +1 -1
  508. package/dist/parquetjs/parser/decoders.js +687 -119
  509. package/dist/parquetjs/parser/decoders.js.map +1 -1
  510. package/dist/parquetjs/parser/encoded-pages.d.ts +24 -0
  511. package/dist/parquetjs/parser/encoded-pages.d.ts.map +1 -0
  512. package/dist/parquetjs/parser/encoded-pages.js +206 -0
  513. package/dist/parquetjs/parser/encoded-pages.js.map +1 -0
  514. package/dist/parquetjs/parser/parquet-reader.d.ts +111 -10
  515. package/dist/parquetjs/parser/parquet-reader.d.ts.map +1 -1
  516. package/dist/parquetjs/parser/parquet-reader.js +836 -69
  517. package/dist/parquetjs/parser/parquet-reader.js.map +1 -1
  518. package/dist/parquetjs/schema/declare.d.ts +83 -10
  519. package/dist/parquetjs/schema/declare.d.ts.map +1 -1
  520. package/dist/parquetjs/schema/declare.js.map +1 -1
  521. package/dist/parquetjs/schema/schema.d.ts +3 -0
  522. package/dist/parquetjs/schema/schema.d.ts.map +1 -1
  523. package/dist/parquetjs/schema/schema.js +31 -3
  524. package/dist/parquetjs/schema/schema.js.map +1 -1
  525. package/dist/parquetjs/schema/shred.d.ts +2 -0
  526. package/dist/parquetjs/schema/shred.d.ts.map +1 -1
  527. package/dist/parquetjs/schema/shred.js +285 -29
  528. package/dist/parquetjs/schema/shred.js.map +1 -1
  529. package/dist/parquetjs/schema/types.d.ts.map +1 -1
  530. package/dist/parquetjs/schema/types.js +290 -71
  531. package/dist/parquetjs/schema/types.js.map +1 -1
  532. package/dist/parquetjs/schema/variant.d.ts +3 -0
  533. package/dist/parquetjs/schema/variant.d.ts.map +1 -0
  534. package/dist/parquetjs/schema/variant.js +248 -0
  535. package/dist/parquetjs/schema/variant.js.map +1 -0
  536. package/dist/parquetjs/utils/binary-utils.d.ts +41 -0
  537. package/dist/parquetjs/utils/binary-utils.d.ts.map +1 -0
  538. package/dist/parquetjs/utils/binary-utils.js +106 -0
  539. package/dist/parquetjs/utils/binary-utils.js.map +1 -0
  540. package/dist/parquetjs/utils/crc32.d.ts +3 -0
  541. package/dist/parquetjs/utils/crc32.d.ts.map +1 -0
  542. package/dist/parquetjs/utils/crc32.js +15 -0
  543. package/dist/parquetjs/utils/crc32.js.map +1 -0
  544. package/dist/parquetjs/utils/file-utils.d.ts +1 -1
  545. package/dist/parquetjs/utils/file-utils.d.ts.map +1 -1
  546. package/dist/parquetjs/utils/file-utils.js +3 -3
  547. package/dist/parquetjs/utils/file-utils.js.map +1 -1
  548. package/dist/parquetjs/utils/read-utils.d.ts +25 -7
  549. package/dist/parquetjs/utils/read-utils.d.ts.map +1 -1
  550. package/dist/parquetjs/utils/read-utils.js +66 -39
  551. package/dist/parquetjs/utils/read-utils.js.map +1 -1
  552. package/dist/parquetjs/utils/thrift-runtime.d.ts +106 -0
  553. package/dist/parquetjs/utils/thrift-runtime.d.ts.map +1 -0
  554. package/dist/parquetjs/utils/thrift-runtime.js +50 -0
  555. package/dist/parquetjs/utils/thrift-runtime.js.map +1 -0
  556. package/dist/parquetjs/utils/uint8-array-compact-protocol-writer.d.ts +78 -0
  557. package/dist/parquetjs/utils/uint8-array-compact-protocol-writer.d.ts.map +1 -0
  558. package/dist/parquetjs/utils/uint8-array-compact-protocol-writer.js +213 -0
  559. package/dist/parquetjs/utils/uint8-array-compact-protocol-writer.js.map +1 -0
  560. package/dist/parquetjs/utils/uint8-array-compact-protocol.d.ts +80 -0
  561. package/dist/parquetjs/utils/uint8-array-compact-protocol.d.ts.map +1 -0
  562. package/dist/parquetjs/utils/uint8-array-compact-protocol.js +276 -0
  563. package/dist/parquetjs/utils/uint8-array-compact-protocol.js.map +1 -0
  564. package/dist/parquetjs/utils/uint8-array-transport.d.ts +25 -0
  565. package/dist/parquetjs/utils/uint8-array-transport.d.ts.map +1 -0
  566. package/dist/parquetjs/utils/uint8-array-transport.js +62 -0
  567. package/dist/parquetjs/utils/uint8-array-transport.js.map +1 -0
  568. package/dist/polyfills/process.d.ts +12 -0
  569. package/dist/polyfills/process.d.ts.map +1 -0
  570. package/dist/polyfills/process.js +17 -0
  571. package/dist/polyfills/process.js.map +1 -0
  572. package/dist/unbundled.d.ts +10 -0
  573. package/dist/unbundled.d.ts.map +1 -0
  574. package/dist/unbundled.js +11 -0
  575. package/dist/unbundled.js.map +1 -0
  576. package/dist/wasm.d.ts +3 -0
  577. package/dist/wasm.d.ts.map +1 -0
  578. package/dist/wasm.js +6 -0
  579. package/dist/wasm.js.map +1 -0
  580. package/dist/workers/parquet-source-worker.d.ts +2 -0
  581. package/dist/workers/parquet-source-worker.d.ts.map +1 -0
  582. package/dist/workers/parquet-source-worker.js +17 -0
  583. package/dist/workers/parquet-source-worker.js.map +1 -0
  584. package/dist/workers/parquet-worker-node.d.ts +2 -0
  585. package/dist/workers/parquet-worker-node.d.ts.map +1 -0
  586. package/dist/workers/parquet-worker-node.js +5 -0
  587. package/dist/workers/parquet-worker-node.js.map +1 -0
  588. package/dist/workers/parquet-worker.d.ts +2 -0
  589. package/dist/workers/parquet-worker.d.ts.map +1 -0
  590. package/dist/workers/parquet-worker.js +27 -0
  591. package/dist/workers/parquet-worker.js.map +1 -0
  592. package/package.json +84 -40
  593. package/src/bundled.ts +43 -0
  594. package/src/delta-format.ts +12 -0
  595. package/src/delta-source-loader-types.ts +40 -0
  596. package/src/delta-source.ts +305 -0
  597. package/src/delta-types.ts +40 -0
  598. package/src/geoparquet-loader-with-parser.ts +95 -0
  599. package/src/geoparquet-loader.ts +54 -0
  600. package/src/iceberg-rest-catalog.ts +122 -0
  601. package/src/iceberg-table-source.ts +1037 -0
  602. package/src/iceberg-types.ts +165 -0
  603. package/src/index.ts +105 -26
  604. package/src/lib/arrow/convert-columns-to-row-group.ts +3 -0
  605. package/src/lib/arrow/convert-schema-from-parquet.ts +193 -32
  606. package/src/lib/arrow/convert-schema-to-parquet.ts +16 -7
  607. package/src/lib/arrow/create-nested-arrow-vector.ts +705 -0
  608. package/src/lib/constants.ts +0 -2
  609. package/src/lib/encoders/encode-arrow-to-parquet.ts +10 -16
  610. package/src/lib/encoders/encode-table-to-parquet-js.ts +526 -0
  611. package/src/lib/geo/geoparquet-covering.ts +201 -0
  612. package/src/lib/geo/geospatial-metadata.ts +547 -0
  613. package/src/lib/parquet-bloom-filter-planner.ts +86 -0
  614. package/src/lib/parquet-bloom-filter.ts +345 -0
  615. package/src/lib/parquet-encryption.ts +344 -0
  616. package/src/lib/parquet-page-index.ts +727 -0
  617. package/src/lib/parquet-predicate.ts +410 -0
  618. package/src/lib/parquet-source-worker-client.ts +41 -0
  619. package/src/lib/parquet-source-worker-decoder.ts +252 -0
  620. package/src/lib/parquet-source-worker-file.ts +56 -0
  621. package/src/lib/parquet-source-worker-types.ts +132 -0
  622. package/src/lib/parquet-worker-transport.ts +57 -0
  623. package/src/lib/parsers/convert-parquet-tables.ts +39 -0
  624. package/src/lib/parsers/get-parquet-schema.ts +6 -2
  625. package/src/lib/parsers/parse-geoparquet-to-geojson.ts +27 -14
  626. package/src/lib/parsers/parse-parquet-tables.ts +82 -0
  627. package/src/lib/parsers/parse-parquet-to-arrow-js.ts +1213 -0
  628. package/src/lib/parsers/parse-parquet-to-arrow.ts +62 -36
  629. package/src/lib/parsers/parse-parquet-to-columns.ts +9 -8
  630. package/src/lib/parsers/parse-parquet-to-json.ts +119 -35
  631. package/src/lib/slice-parquet-batch.ts +32 -0
  632. package/src/lib/sources/parquet-range-file.ts +365 -0
  633. package/src/lib/sources/single-batch-queue.ts +95 -0
  634. package/src/lib/utils/load-wasm-node.ts +25 -0
  635. package/src/lib/utils/load-wasm.ts +36 -13
  636. package/src/lib/utils/make-stream-iterator.ts +126 -14
  637. package/src/lib/utils/normalize-parquet-options.ts +30 -0
  638. package/src/parquet-dataset-source.ts +800 -0
  639. package/src/parquet-encoded-page-types.ts +122 -0
  640. package/src/parquet-format.ts +2 -0
  641. package/src/parquet-js-loader-types.ts +53 -0
  642. package/src/parquet-js-loader.ts +76 -19
  643. package/src/parquet-js-writer.ts +98 -0
  644. package/src/parquet-loader-base.ts +34 -0
  645. package/src/parquet-loader-options.ts +62 -0
  646. package/src/parquet-loader-types.ts +35 -0
  647. package/src/parquet-loader.ts +115 -0
  648. package/src/parquet-source-capabilities.ts +73 -0
  649. package/src/parquet-source-loader-types.ts +97 -0
  650. package/src/parquet-source-loader.ts +2254 -0
  651. package/src/parquet-source-types.ts +627 -0
  652. package/src/parquet-source-worker-factory.ts +8 -0
  653. package/src/parquet-source-worker-url.ts +23 -0
  654. package/src/parquet-worker-url.ts +23 -0
  655. package/src/parquet-writer.ts +42 -0
  656. package/src/parquetjs/LICENSE +23 -1
  657. package/src/parquetjs/codecs/byte-stream-split.ts +221 -0
  658. package/src/parquetjs/codecs/declare.ts +62 -3
  659. package/src/parquetjs/codecs/delta.ts +1047 -0
  660. package/src/parquetjs/codecs/dictionary.ts +22 -4
  661. package/src/parquetjs/codecs/index.ts +22 -0
  662. package/src/parquetjs/codecs/plain.ts +317 -89
  663. package/src/parquetjs/codecs/rle.ts +852 -82
  664. package/src/parquetjs/compression.ts +137 -156
  665. package/src/parquetjs/encoder/dictionary-planner.ts +104 -0
  666. package/src/parquetjs/encoder/page-planner.ts +83 -0
  667. package/src/parquetjs/encoder/parquet-encoder.ts +1374 -95
  668. package/src/parquetjs/parquet-thrift/BoundingBox.ts +108 -0
  669. package/src/parquetjs/parquet-thrift/BsonType.ts +1 -1
  670. package/src/parquetjs/parquet-thrift/ColumnChunk.ts +37 -2
  671. package/src/parquetjs/parquet-thrift/ColumnCryptoMetaData.ts +139 -0
  672. package/src/parquetjs/parquet-thrift/ColumnIndex.ts +13 -13
  673. package/src/parquetjs/parquet-thrift/ColumnMetaData.ts +75 -2
  674. package/src/parquetjs/parquet-thrift/ColumnOrder.ts +1 -1
  675. package/src/parquetjs/parquet-thrift/DataPageHeader.ts +1 -1
  676. package/src/parquetjs/parquet-thrift/DataPageHeaderV2.ts +1 -1
  677. package/src/parquetjs/parquet-thrift/DateType.ts +1 -1
  678. package/src/parquetjs/parquet-thrift/DecimalType.ts +1 -1
  679. package/src/parquetjs/parquet-thrift/DictionaryPageHeader.ts +1 -1
  680. package/src/parquetjs/parquet-thrift/EdgeInterpolationAlgorithm.ts +13 -0
  681. package/src/parquetjs/parquet-thrift/Encoding.ts +2 -1
  682. package/src/parquetjs/parquet-thrift/EncryptionAlgorithm.ts +127 -0
  683. package/src/parquetjs/parquet-thrift/EnumType.ts +1 -1
  684. package/src/parquetjs/parquet-thrift/FileCryptoMetaData.ts +60 -0
  685. package/src/parquetjs/parquet-thrift/FileMetaData.ts +37 -2
  686. package/src/parquetjs/parquet-thrift/Float16Type.ts +28 -0
  687. package/src/parquetjs/parquet-thrift/GeographyType.ts +54 -0
  688. package/src/parquetjs/parquet-thrift/GeometryType.ts +43 -0
  689. package/src/parquetjs/parquet-thrift/GeospatialStatistics.ts +68 -0
  690. package/src/parquetjs/parquet-thrift/IndexPageHeader.ts +1 -1
  691. package/src/parquetjs/parquet-thrift/IntType.ts +1 -1
  692. package/src/parquetjs/parquet-thrift/JsonType.ts +1 -1
  693. package/src/parquetjs/parquet-thrift/KeyValue.ts +1 -1
  694. package/src/parquetjs/parquet-thrift/ListType.ts +1 -1
  695. package/src/parquetjs/parquet-thrift/LogicalType.ts +97 -1
  696. package/src/parquetjs/parquet-thrift/MapType.ts +1 -1
  697. package/src/parquetjs/parquet-thrift/MicroSeconds.ts +1 -1
  698. package/src/parquetjs/parquet-thrift/MilliSeconds.ts +1 -1
  699. package/src/parquetjs/parquet-thrift/NanoSeconds.ts +28 -0
  700. package/src/parquetjs/parquet-thrift/NullType.ts +1 -1
  701. package/src/parquetjs/parquet-thrift/OffsetIndex.ts +1 -1
  702. package/src/parquetjs/parquet-thrift/PageEncodingStats.ts +1 -1
  703. package/src/parquetjs/parquet-thrift/PageHeader.ts +1 -1
  704. package/src/parquetjs/parquet-thrift/PageLocation.ts +2 -2
  705. package/src/parquetjs/parquet-thrift/RowGroup.ts +2 -2
  706. package/src/parquetjs/parquet-thrift/SchemaElement.ts +1 -1
  707. package/src/parquetjs/parquet-thrift/SizeStatistics.ts +98 -0
  708. package/src/parquetjs/parquet-thrift/SortingColumn.ts +1 -1
  709. package/src/parquetjs/parquet-thrift/Statistics.ts +50 -14
  710. package/src/parquetjs/parquet-thrift/StringType.ts +1 -1
  711. package/src/parquetjs/parquet-thrift/TimeType.ts +1 -1
  712. package/src/parquetjs/parquet-thrift/TimeUnit.ts +25 -1
  713. package/src/parquetjs/parquet-thrift/TimestampType.ts +1 -1
  714. package/src/parquetjs/parquet-thrift/TypeDefinedOrder.ts +1 -1
  715. package/src/parquetjs/parquet-thrift/UUIDType.ts +1 -1
  716. package/src/parquetjs/parquet-thrift/VariantType.ts +43 -0
  717. package/src/parquetjs/parquet-thrift/index.ts +12 -4
  718. package/src/parquetjs/parser/decoders.ts +922 -143
  719. package/src/parquetjs/parser/encoded-pages.ts +278 -0
  720. package/src/parquetjs/parser/parquet-reader.ts +1334 -83
  721. package/src/parquetjs/schema/declare.ts +121 -9
  722. package/src/parquetjs/schema/schema.ts +33 -3
  723. package/src/parquetjs/schema/shred.ts +345 -41
  724. package/src/parquetjs/schema/types.ts +308 -84
  725. package/src/parquetjs/schema/variant.ts +313 -0
  726. package/src/parquetjs/utils/binary-utils.ts +132 -0
  727. package/src/parquetjs/utils/crc32.ts +15 -0
  728. package/src/parquetjs/utils/file-utils.ts +4 -4
  729. package/src/parquetjs/utils/read-utils.ts +77 -51
  730. package/src/parquetjs/utils/thrift-runtime.ts +109 -0
  731. package/src/parquetjs/utils/uint8-array-compact-protocol-writer.ts +254 -0
  732. package/src/parquetjs/utils/uint8-array-compact-protocol.ts +322 -0
  733. package/src/parquetjs/utils/uint8-array-transport.ts +79 -0
  734. package/src/polyfills/process.ts +17 -0
  735. package/src/unbundled.ts +47 -0
  736. package/src/wasm.ts +6 -0
  737. package/src/workers/parquet-source-worker.ts +21 -0
  738. package/src/workers/parquet-worker-node.ts +5 -0
  739. package/src/workers/parquet-worker.ts +31 -0
  740. package/dist/parquet-arrow-loader.d.ts +0 -43
  741. package/dist/parquet-arrow-loader.d.ts.map +0 -1
  742. package/dist/parquet-arrow-loader.js +0 -49
  743. package/dist/parquet-arrow-loader.js.map +0 -1
  744. package/dist/parquet-arrow-writer.d.ts +0 -9
  745. package/dist/parquet-arrow-writer.d.ts.map +0 -1
  746. package/dist/parquet-arrow-writer.js +0 -23
  747. package/dist/parquet-arrow-writer.js.map +0 -1
  748. package/dist/parquet-json-loader.d.ts +0 -148
  749. package/dist/parquet-json-loader.d.ts.map +0 -1
  750. package/dist/parquet-json-loader.js +0 -106
  751. package/dist/parquet-json-loader.js.map +0 -1
  752. package/dist/parquet-json-writer.d.ts +0 -19
  753. package/dist/parquet-json-writer.d.ts.map +0 -1
  754. package/dist/parquet-json-writer.js +0 -20
  755. package/dist/parquet-json-writer.js.map +0 -1
  756. package/dist/polyfills/buffer/buffer-polyfill.browser.d.ts +0 -3
  757. package/dist/polyfills/buffer/buffer-polyfill.browser.d.ts.map +0 -1
  758. package/dist/polyfills/buffer/buffer-polyfill.browser.js +0 -12
  759. package/dist/polyfills/buffer/buffer-polyfill.browser.js.map +0 -1
  760. package/dist/polyfills/buffer/buffer-polyfill.node.d.ts +0 -3
  761. package/dist/polyfills/buffer/buffer-polyfill.node.d.ts.map +0 -1
  762. package/dist/polyfills/buffer/buffer-polyfill.node.js +0 -17
  763. package/dist/polyfills/buffer/buffer-polyfill.node.js.map +0 -1
  764. package/dist/polyfills/buffer/buffer.d.ts +0 -222
  765. package/dist/polyfills/buffer/buffer.d.ts.map +0 -1
  766. package/dist/polyfills/buffer/buffer.js +0 -1868
  767. package/dist/polyfills/buffer/buffer.js.map +0 -1
  768. package/dist/polyfills/buffer/index.d.ts +0 -4
  769. package/dist/polyfills/buffer/index.d.ts.map +0 -1
  770. package/dist/polyfills/buffer/index.js +0 -9
  771. package/dist/polyfills/buffer/index.js.map +0 -1
  772. package/dist/polyfills/buffer/install-buffer-polyfill.d.ts +0 -2
  773. package/dist/polyfills/buffer/install-buffer-polyfill.d.ts.map +0 -1
  774. package/dist/polyfills/buffer/install-buffer-polyfill.js +0 -10
  775. package/dist/polyfills/buffer/install-buffer-polyfill.js.map +0 -1
  776. package/dist/workers/parquet-json-worker.d.ts +0 -2
  777. package/dist/workers/parquet-json-worker.d.ts.map +0 -1
  778. package/dist/workers/parquet-json-worker.js +0 -7
  779. package/dist/workers/parquet-json-worker.js.map +0 -1
  780. package/src/parquet-arrow-loader.ts +0 -74
  781. package/src/parquet-arrow-writer.ts +0 -33
  782. package/src/parquet-json-loader.ts +0 -160
  783. package/src/parquet-json-writer.ts +0 -27
  784. package/src/parquetjs/modules.d.ts +0 -25
  785. package/src/polyfills/buffer/buffer-polyfill.browser.ts +0 -14
  786. package/src/polyfills/buffer/buffer-polyfill.node.ts +0 -19
  787. package/src/polyfills/buffer/buffer.ts +0 -2205
  788. package/src/polyfills/buffer/index.ts +0 -11
  789. package/src/polyfills/buffer/install-buffer-polyfill.ts +0 -12
  790. package/src/workers/parquet-json-worker.ts +0 -8
@@ -3,17 +3,31 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
  // Copyright (c) 2017 ironSource Ltd.
5
5
  // Forked from https://github.com/kbajalc/parquets under MIT license
6
+ import { getWKBGeometryStatistics } from '@loaders.gl/gis';
6
7
  import { PARQUET_CODECS } from "../codecs/index.js";
7
8
  import * as Compression from "../compression.js";
8
9
  import * as Shred from "../schema/shred.js";
9
- import { ColumnChunk, ColumnMetaData, CompressionCodec, ConvertedType, DataPageHeader, DataPageHeaderV2, Encoding, FieldRepetitionType, FileMetaData, KeyValue, PageHeader, PageType, RowGroup, SchemaElement, Type } from "../parquet-thrift/index.js";
10
+ import { BsonType, BoundingBox, ColumnChunk, ColumnCryptoMetaData, ColumnIndex, ColumnMetaData, SizeStatistics, Statistics, SortingColumn, CompressionCodec, ConvertedType, DataPageHeader, DataPageHeaderV2, DateType, DecimalType, DictionaryPageHeader, EdgeInterpolationAlgorithm, Encoding, EnumType, FieldRepetitionType, FileMetaData, Float16Type, GeographyType, GeospatialStatistics, GeometryType, IntType, JsonType, KeyValue, ListType, LogicalType, MapType, MicroSeconds, MilliSeconds, NanoSeconds, NullType, PageHeader, PageEncodingStats, PageType, PageLocation, RowGroup, SchemaElement, StringType, TimeType, TimeUnit, TimestampType, Type, UUIDType, VariantType, OffsetIndex } from "../parquet-thrift/index.js";
10
11
  import { osopen, oswrite, osclose } from "../utils/file-utils.js";
11
12
  import { getBitWidth, serializeThrift } from "../utils/read-utils.js";
12
- import Int64 from 'node-int64';
13
+ import { concatUint8Arrays, encodeUtf8, writeUInt32LE } from "../utils/binary-utils.js";
14
+ import { crc32 } from "../utils/crc32.js";
15
+ import { CompactInt64 } from "../utils/uint8-array-compact-protocol.js";
16
+ import { planColumnPages } from "./page-planner.js";
17
+ import { planDictionary } from "./dictionary-planner.js";
18
+ import { decodeParquetSplitBlockBloomFilter, encodeParquetBloomFilterValue, encodeParquetSplitBlockBloomFilter } from "../../lib/parquet-bloom-filter.js";
19
+ import { BoundaryOrder } from "../parquet-thrift/BoundaryOrder.js";
20
+ import { EncryptionWithColumnKey, EncryptionWithFooterKey } from "../parquet-thrift/ColumnCryptoMetaData.js";
21
+ import { EncryptionAlgorithm } from "../parquet-thrift/EncryptionAlgorithm.js";
22
+ import { FileCryptoMetaData } from "../parquet-thrift/FileCryptoMetaData.js";
23
+ import { PARQUET_MAGIC_ENCRYPTED } from "../../lib/constants.js";
24
+ import { createParquetModuleAad, createParquetFooterSignature, encryptParquetModule } from "../../lib/parquet-encryption.js";
13
25
  /**
14
26
  * Parquet File Magic String
15
27
  */
16
28
  const PARQUET_MAGIC = 'PAR1';
29
+ const PARQUET_MAGIC_BYTES = encodeUtf8(PARQUET_MAGIC);
30
+ const PARQUET_MAGIC_ENCRYPTED_BYTES = encodeUtf8(PARQUET_MAGIC_ENCRYPTED);
17
31
  /**
18
32
  * Parquet File Format Version
19
33
  */
@@ -63,8 +77,7 @@ export class ParquetEncoder {
63
77
  constructor(schema, envelopeWriter, opts) {
64
78
  this.schema = schema;
65
79
  this.envelopeWriter = envelopeWriter;
66
- // @ts-ignore Row buffer typings...
67
- this.rowBuffer = {};
80
+ this.rowBuffer = schema.rowGroup();
68
81
  this.rowGroupSize = opts.rowGroupSize || PARQUET_DEFAULT_ROW_GROUP_SIZE;
69
82
  this.closed = false;
70
83
  this.userMetadata = {};
@@ -91,8 +104,8 @@ export class ParquetEncoder {
91
104
  }
92
105
  Shred.shredRecord(this.schema, row, this.rowBuffer);
93
106
  if (this.rowBuffer.rowCount >= this.rowGroupSize) {
94
- // @ts-ignore
95
- this.rowBuffer = {};
107
+ await this.envelopeWriter.writeRowGroup(this.rowBuffer);
108
+ this.rowBuffer = this.schema.rowGroup();
96
109
  }
97
110
  }
98
111
  /**
@@ -107,8 +120,8 @@ export class ParquetEncoder {
107
120
  }
108
121
  this.closed = true;
109
122
  if (this.rowBuffer.rowCount > 0 || this.rowBuffer.rowCount >= this.rowGroupSize) {
110
- // @ts-ignore
111
- this.rowBuffer = {};
123
+ await this.envelopeWriter.writeRowGroup(this.rowBuffer);
124
+ this.rowBuffer = this.schema.rowGroup();
112
125
  }
113
126
  await this.envelopeWriter.writeFooter(this.userMetadata);
114
127
  await this.envelopeWriter.close();
@@ -164,6 +177,21 @@ export class ParquetEnvelopeWriter {
164
177
  rowGroups;
165
178
  pageSize;
166
179
  useDataPageV2;
180
+ dictionary;
181
+ columnDictionaries;
182
+ dictionaryPageSizeLimit;
183
+ bloomFilter;
184
+ pageIndex;
185
+ writePageChecksums;
186
+ writeSizeStatistics;
187
+ writeStatistics;
188
+ sortingColumns;
189
+ /** Optional modular-encryption configuration for the footer. */
190
+ encryption;
191
+ /** Optional plaintext-footer signature configuration. */
192
+ footerSignature;
193
+ /** File identifier used for encrypted column-module AAD. */
194
+ encryptionFileUnique;
167
195
  constructor(schema, writeFn, closeFn, fileOffset, opts) {
168
196
  this.schema = schema;
169
197
  this.write = writeFn;
@@ -173,6 +201,43 @@ export class ParquetEnvelopeWriter {
173
201
  this.rowGroups = [];
174
202
  this.pageSize = opts.pageSize || PARQUET_DEFAULT_PAGE_SIZE;
175
203
  this.useDataPageV2 = 'useDataPageV2' in opts ? Boolean(opts.useDataPageV2) : false;
204
+ this.dictionary = opts.dictionary ?? 'auto';
205
+ this.columnDictionaries = opts.columnDictionaries || {};
206
+ this.dictionaryPageSizeLimit = opts.dictionaryPageSizeLimit ?? 1024 * 1024;
207
+ this.bloomFilter = opts.bloomFilter;
208
+ this.pageIndex = opts.pageIndex;
209
+ this.writePageChecksums = Boolean(opts.writePageChecksums);
210
+ this.writeSizeStatistics = Boolean(opts.writeSizeStatistics);
211
+ this.writeStatistics = opts.writeStatistics;
212
+ this.sortingColumns = opts.sortingColumns;
213
+ const encryptionFileUnique = opts.encryption?.fileUnique
214
+ ? new Uint8Array(opts.encryption.fileUnique)
215
+ : undefined;
216
+ const footerSignatureFileUnique = opts.footerSignature?.fileUnique
217
+ ? new Uint8Array(opts.footerSignature.fileUnique)
218
+ : undefined;
219
+ if (encryptionFileUnique &&
220
+ footerSignatureFileUnique &&
221
+ !encryptionFileUnique.every((value, index) => value === footerSignatureFileUnique[index])) {
222
+ throw new Error('Parquet encryption and footer signature file_unique values must match');
223
+ }
224
+ const sharedFileUnique = encryptionFileUnique ??
225
+ footerSignatureFileUnique ??
226
+ (opts.encryption || opts.footerSignature ? createFileUnique() : undefined);
227
+ this.encryption = opts.encryption
228
+ ? { ...opts.encryption, fileUnique: new Uint8Array(sharedFileUnique) }
229
+ : undefined;
230
+ this.footerSignature = opts.footerSignature
231
+ ? {
232
+ ...opts.footerSignature,
233
+ keyMetadata: new Uint8Array(opts.footerSignature.keyMetadata),
234
+ aadPrefix: opts.footerSignature.aadPrefix
235
+ ? new Uint8Array(opts.footerSignature.aadPrefix)
236
+ : undefined,
237
+ fileUnique: new Uint8Array(sharedFileUnique)
238
+ }
239
+ : undefined;
240
+ this.encryptionFileUnique = sharedFileUnique;
176
241
  }
177
242
  writeSection(buf) {
178
243
  this.offset += buf.length;
@@ -182,7 +247,7 @@ export class ParquetEnvelopeWriter {
182
247
  * Encode the parquet file header
183
248
  */
184
249
  writeHeader() {
185
- return this.writeSection(Buffer.from(PARQUET_MAGIC));
250
+ return this.writeSection(this.encryption && !this.footerSignature ? PARQUET_MAGIC_ENCRYPTED_BYTES : PARQUET_MAGIC_BYTES);
186
251
  }
187
252
  /**
188
253
  * Encode a parquet row group. The records object should be created using the
@@ -192,7 +257,19 @@ export class ParquetEnvelopeWriter {
192
257
  const rgroup = await encodeRowGroup(this.schema, records, {
193
258
  baseOffset: this.offset,
194
259
  pageSize: this.pageSize,
195
- useDataPageV2: this.useDataPageV2
260
+ useDataPageV2: this.useDataPageV2,
261
+ dictionary: this.dictionary,
262
+ columnDictionaries: this.columnDictionaries,
263
+ dictionaryPageSizeLimit: this.dictionaryPageSizeLimit,
264
+ bloomFilter: this.bloomFilter,
265
+ pageIndex: this.pageIndex,
266
+ writePageChecksums: this.writePageChecksums,
267
+ writeSizeStatistics: this.writeSizeStatistics,
268
+ writeStatistics: this.writeStatistics,
269
+ sortingColumns: this.sortingColumns,
270
+ encryption: this.encryption,
271
+ encryptionFileUnique: this.encryptionFileUnique,
272
+ rowGroupOrdinal: this.rowGroups.length
196
273
  });
197
274
  this.rowCount += records.rowCount;
198
275
  this.rowGroups.push(rgroup.metadata);
@@ -201,12 +278,21 @@ export class ParquetEnvelopeWriter {
201
278
  /**
202
279
  * Write the parquet file footer
203
280
  */
204
- writeFooter(userMetadata) {
281
+ async writeFooter(userMetadata) {
205
282
  if (!userMetadata) {
206
283
  // tslint:disable-next-line:no-parameter-reassignment
207
284
  userMetadata = {};
208
285
  }
209
- return this.writeSection(encodeFooter(this.schema, this.rowCount, this.rowGroups, userMetadata));
286
+ if (this.footerSignature) {
287
+ await this.writeSection(await encodeSignedFooter(this.schema, this.rowCount, this.rowGroups, userMetadata, this.footerSignature));
288
+ return;
289
+ }
290
+ const footer = encodeFooter(this.schema, this.rowCount, this.rowGroups, userMetadata);
291
+ if (!this.encryption) {
292
+ await this.writeSection(footer);
293
+ return;
294
+ }
295
+ await this.writeSection(await encodeEncryptedFooter(footer, this.encryption));
210
296
  }
211
297
  /**
212
298
  * Set the parquet data page size. The data page size controls the maximum
@@ -264,16 +350,16 @@ function encodeValues(type, encoding, values, opts) {
264
350
  /**
265
351
  * Encode a parquet data page
266
352
  */
267
- async function encodeDataPage(column, data) {
353
+ async function encodeDataPage(column, data, valueEncoding = column.encoding, valueBitWidth, writePageChecksums = false, statistics, int96AsTimestamp = false) {
268
354
  /* encode repetition and definition levels */
269
- let rLevelsBuf = Buffer.alloc(0);
355
+ let rLevelsBuf = new Uint8Array(0);
270
356
  if (column.rLevelMax > 0) {
271
357
  rLevelsBuf = encodeValues(PARQUET_RDLVL_TYPE, PARQUET_RDLVL_ENCODING, data.rlevels, {
272
358
  bitWidth: getBitWidth(column.rLevelMax)
273
359
  // disableEnvelope: false
274
360
  });
275
361
  }
276
- let dLevelsBuf = Buffer.alloc(0);
362
+ let dLevelsBuf = new Uint8Array(0);
277
363
  if (column.dLevelMax > 0) {
278
364
  dLevelsBuf = encodeValues(PARQUET_RDLVL_TYPE, PARQUET_RDLVL_ENCODING, data.dlevels, {
279
365
  bitWidth: getBitWidth(column.dLevelMax)
@@ -281,11 +367,12 @@ async function encodeDataPage(column, data) {
281
367
  });
282
368
  }
283
369
  /* encode values */
284
- const valuesBuf = encodeValues(column.primitiveType, column.encoding, data.values, {
370
+ const valuesBuf = encodeValues(column.primitiveType, valueEncoding, data.values, {
285
371
  typeLength: column.typeLength,
286
- bitWidth: column.typeLength
372
+ bitWidth: valueBitWidth ?? column.typeLength,
373
+ int96AsTimestamp
287
374
  });
288
- const dataBuf = Buffer.concat([rLevelsBuf, dLevelsBuf, valuesBuf]);
375
+ const dataBuf = concatUint8Arrays([rLevelsBuf, dLevelsBuf, valuesBuf]);
289
376
  // compression = column.compression === 'UNCOMPRESSED' ? (compression || 'UNCOMPRESSED') : column.compression;
290
377
  const compressedBuf = await Compression.deflate(column.compression, dataBuf);
291
378
  /* build page header */
@@ -293,38 +380,41 @@ async function encodeDataPage(column, data) {
293
380
  type: PageType.DATA_PAGE,
294
381
  data_page_header: new DataPageHeader({
295
382
  num_values: data.count,
296
- encoding: Encoding[column.encoding],
383
+ encoding: Encoding[valueEncoding],
297
384
  definition_level_encoding: Encoding[PARQUET_RDLVL_ENCODING], // [PARQUET_RDLVL_ENCODING],
298
- repetition_level_encoding: Encoding[PARQUET_RDLVL_ENCODING] // [PARQUET_RDLVL_ENCODING]
385
+ repetition_level_encoding: Encoding[PARQUET_RDLVL_ENCODING], // [PARQUET_RDLVL_ENCODING]
386
+ statistics
299
387
  }),
300
388
  uncompressed_page_size: dataBuf.length,
301
- compressed_page_size: compressedBuf.length
389
+ compressed_page_size: compressedBuf.length,
390
+ crc: writePageChecksums ? crc32(compressedBuf) : undefined
302
391
  });
303
392
  /* concat page header, repetition and definition levels and values */
304
393
  const headerBuf = serializeThrift(header);
305
- const page = Buffer.concat([headerBuf, compressedBuf]);
394
+ const page = concatUint8Arrays([headerBuf, compressedBuf]);
306
395
  return { header, headerSize: headerBuf.length, page };
307
396
  }
308
397
  /**
309
398
  * Encode a parquet data page (v2)
310
399
  */
311
- async function encodeDataPageV2(column, data, rowCount) {
400
+ async function encodeDataPageV2(column, data, rowCount, valueEncoding = column.encoding, valueBitWidth, writePageChecksums = false, statistics, int96AsTimestamp = false) {
312
401
  /* encode values */
313
- const valuesBuf = encodeValues(column.primitiveType, column.encoding, data.values, {
402
+ const valuesBuf = encodeValues(column.primitiveType, valueEncoding, data.values, {
314
403
  typeLength: column.typeLength,
315
- bitWidth: column.typeLength
404
+ bitWidth: valueBitWidth ?? column.typeLength,
405
+ int96AsTimestamp
316
406
  });
317
407
  // compression = column.compression === 'UNCOMPRESSED' ? (compression || 'UNCOMPRESSED') : column.compression;
318
408
  const compressedBuf = await Compression.deflate(column.compression, valuesBuf);
319
409
  /* encode repetition and definition levels */
320
- let rLevelsBuf = Buffer.alloc(0);
410
+ let rLevelsBuf = new Uint8Array(0);
321
411
  if (column.rLevelMax > 0) {
322
412
  rLevelsBuf = encodeValues(PARQUET_RDLVL_TYPE, PARQUET_RDLVL_ENCODING, data.rlevels, {
323
413
  bitWidth: getBitWidth(column.rLevelMax),
324
414
  disableEnvelope: true
325
415
  });
326
416
  }
327
- let dLevelsBuf = Buffer.alloc(0);
417
+ let dLevelsBuf = new Uint8Array(0);
328
418
  if (column.dLevelMax > 0) {
329
419
  dLevelsBuf = encodeValues(PARQUET_RDLVL_TYPE, PARQUET_RDLVL_ENCODING, data.dlevels, {
330
420
  bitWidth: getBitWidth(column.dLevelMax),
@@ -338,98 +428,677 @@ async function encodeDataPageV2(column, data, rowCount) {
338
428
  num_values: data.count,
339
429
  num_nulls: data.count - data.values.length,
340
430
  num_rows: rowCount,
341
- encoding: Encoding[column.encoding],
431
+ encoding: Encoding[valueEncoding],
342
432
  definition_levels_byte_length: dLevelsBuf.length,
343
433
  repetition_levels_byte_length: rLevelsBuf.length,
344
- is_compressed: column.compression !== 'UNCOMPRESSED'
434
+ is_compressed: column.compression !== 'UNCOMPRESSED',
435
+ statistics
345
436
  }),
346
437
  uncompressed_page_size: rLevelsBuf.length + dLevelsBuf.length + valuesBuf.length,
347
- compressed_page_size: rLevelsBuf.length + dLevelsBuf.length + compressedBuf.length
438
+ compressed_page_size: rLevelsBuf.length + dLevelsBuf.length + compressedBuf.length,
439
+ crc: writePageChecksums
440
+ ? crc32(concatUint8Arrays([rLevelsBuf, dLevelsBuf, compressedBuf]))
441
+ : undefined
348
442
  });
349
443
  /* concat page header, repetition and definition levels and values */
350
444
  const headerBuf = serializeThrift(header);
351
- const page = Buffer.concat([headerBuf, rLevelsBuf, dLevelsBuf, compressedBuf]);
445
+ const page = concatUint8Arrays([headerBuf, rLevelsBuf, dLevelsBuf, compressedBuf]);
352
446
  return { header, headerSize: headerBuf.length, page };
353
447
  }
448
+ /** Encodes one chunk-wide PLAIN dictionary page. */
449
+ async function encodeDictionaryPage(column, dictionaryValues, writePageChecksums = false, int96AsTimestamp = false) {
450
+ const valuesBuffer = encodeValues(column.primitiveType, 'PLAIN', dictionaryValues, {
451
+ typeLength: column.typeLength,
452
+ int96AsTimestamp
453
+ });
454
+ const compressedBuffer = await Compression.deflate(column.compression, valuesBuffer);
455
+ const header = new PageHeader({
456
+ type: PageType.DICTIONARY_PAGE,
457
+ dictionary_page_header: new DictionaryPageHeader({
458
+ num_values: dictionaryValues.length,
459
+ encoding: Encoding.PLAIN
460
+ }),
461
+ uncompressed_page_size: valuesBuffer.length,
462
+ compressed_page_size: compressedBuffer.length,
463
+ crc: writePageChecksums ? crc32(compressedBuffer) : undefined
464
+ });
465
+ const headerBuffer = serializeThrift(header);
466
+ return {
467
+ header,
468
+ headerSize: headerBuffer.length,
469
+ page: concatUint8Arrays([headerBuffer, compressedBuffer])
470
+ };
471
+ }
472
+ /** Computes native Parquet geospatial statistics for a GEOMETRY or GEOGRAPHY column chunk. */
473
+ function createGeospatialStatistics(column, values) {
474
+ const logicalType = column.logicalType?.type || column.originalType;
475
+ if (logicalType !== 'GEOMETRY' && logicalType !== 'GEOGRAPHY')
476
+ return undefined;
477
+ const geometryTypes = new Set();
478
+ let bbox;
479
+ // Vertex bounds are not conservative for GEOGRAPHY: non-linear edge algorithms can reach
480
+ // extrema between vertices. Until edge-aware geodesic bounds are available, omit the bbox while
481
+ // retaining the useful geometry-type statistics.
482
+ const canWriteBoundingBox = logicalType === 'GEOMETRY';
483
+ for (const value of values) {
484
+ if (!(value instanceof ArrayBuffer) && !ArrayBuffer.isView(value)) {
485
+ throw new Error(`${logicalType} columns must contain WKB binary values`);
486
+ }
487
+ const statistics = getWKBGeometryStatistics(value);
488
+ geometryTypes.add(statistics.geometryType);
489
+ if (canWriteBoundingBox) {
490
+ bbox = mergeGeometryBoundingBoxes(bbox, statistics.bbox);
491
+ }
492
+ }
493
+ return new GeospatialStatistics({
494
+ bbox: bbox ? new BoundingBox(bbox) : undefined,
495
+ geospatial_types: [...geometryTypes].sort((left, right) => left - right)
496
+ });
497
+ }
498
+ /** Merges finite per-dimension bounds without inventing absent Z or M dimensions. */
499
+ function mergeGeometryBoundingBoxes(target, source) {
500
+ if (!source)
501
+ return target;
502
+ if (!target)
503
+ return { ...source };
504
+ target.xmin = Math.min(target.xmin, source.xmin);
505
+ target.xmax = Math.max(target.xmax, source.xmax);
506
+ target.ymin = Math.min(target.ymin, source.ymin);
507
+ target.ymax = Math.max(target.ymax, source.ymax);
508
+ mergeOptionalBounds(target, source, 'zmin', Math.min);
509
+ mergeOptionalBounds(target, source, 'zmax', Math.max);
510
+ mergeOptionalBounds(target, source, 'mmin', Math.min);
511
+ mergeOptionalBounds(target, source, 'mmax', Math.max);
512
+ return target;
513
+ }
514
+ /** Merges one optional bound while preserving a dimension absent from every value. */
515
+ function mergeOptionalBounds(target, source, key, merge) {
516
+ const sourceValue = source[key];
517
+ if (sourceValue === undefined)
518
+ return;
519
+ target[key] = target[key] === undefined ? sourceValue : merge(target[key], sourceValue);
520
+ }
354
521
  /**
355
522
  * Encode an array of values into a parquet column chunk
356
523
  */
357
- async function encodeColumnChunk(column, buffer, offset, opts) {
524
+ async function encodeColumnChunk(column, buffer, offset, opts, rowGroupOrdinal, columnOrdinal) {
358
525
  const data = buffer.columnData[column.path.join()];
359
526
  const baseOffset = (opts.baseOffset || 0) + offset;
360
527
  /* encode data page(s) */
361
- // const pages: Buffer[] = [];
362
- let pageBuf;
528
+ const pageRecords = [];
529
+ const pageLocations = [];
363
530
  // tslint:disable-next-line:variable-name
364
531
  let total_uncompressed_size = 0;
365
532
  // tslint:disable-next-line:variable-name
366
533
  let total_compressed_size = 0;
367
- {
534
+ const plannedPages = planColumnPages(column, data, buffer.rowCount, opts.pageSize || PARQUET_DEFAULT_PAGE_SIZE);
535
+ const dictionaryPolicy = opts.columnDictionaries?.[column.path[0]] ?? opts.dictionary ?? 'auto';
536
+ const dictionaryPlan = planDictionary(column, Array.from(data.values), dictionaryPolicy, opts.dictionaryPageSizeLimit ?? 1024 * 1024);
537
+ if (dictionaryPlan) {
538
+ const result = await encodeDictionaryPage(column, dictionaryPlan.values, opts.writePageChecksums, opts.int96AsTimestamp);
539
+ pageRecords.push({ page: result.page, headerSize: result.headerSize, dictionary: true });
540
+ total_uncompressed_size += result.header.uncompressed_page_size + result.headerSize;
541
+ total_compressed_size += result.header.compressed_page_size + result.headerSize;
542
+ }
543
+ const valueEncoding = dictionaryPlan
544
+ ? column.encoding === 'PLAIN_DICTIONARY'
545
+ ? 'PLAIN_DICTIONARY'
546
+ : 'RLE_DICTIONARY'
547
+ : column.encoding === 'PLAIN_DICTIONARY' || column.encoding === 'RLE_DICTIONARY'
548
+ ? 'PLAIN'
549
+ : column.encoding;
550
+ let dictionaryIndexOffset = 0;
551
+ for (const plannedPage of plannedPages) {
552
+ const pageData = dictionaryPlan
553
+ ? {
554
+ ...plannedPage.data,
555
+ values: dictionaryPlan.indices.slice(dictionaryIndexOffset, dictionaryIndexOffset + plannedPage.data.values.length)
556
+ }
557
+ : plannedPage.data;
558
+ dictionaryIndexOffset += plannedPage.data.values.length;
368
559
  const result = opts.useDataPageV2
369
- ? await encodeDataPageV2(column, data, buffer.rowCount)
370
- : await encodeDataPage(column, data);
371
- // pages.push(result.page);
372
- pageBuf = result.page;
560
+ ? await encodeDataPageV2(column, pageData, plannedPage.rowCount, valueEncoding, dictionaryPlan?.bitWidth, opts.writePageChecksums, isStatisticsEnabled(opts.writeStatistics, column)
561
+ ? createColumnStatistics(column, plannedPage.data)
562
+ : undefined, opts.int96AsTimestamp)
563
+ : await encodeDataPage(column, pageData, valueEncoding, dictionaryPlan?.bitWidth, opts.writePageChecksums, isStatisticsEnabled(opts.writeStatistics, column)
564
+ ? createColumnStatistics(column, plannedPage.data)
565
+ : undefined, opts.int96AsTimestamp);
566
+ pageRecords.push({ page: result.page, headerSize: result.headerSize, dictionary: false });
373
567
  total_uncompressed_size += result.header.uncompressed_page_size + result.headerSize;
374
568
  total_compressed_size += result.header.compressed_page_size + result.headerSize;
375
569
  }
376
- // const pagesBuf = Buffer.concat(pages);
570
+ const encryption = opts.encryption;
571
+ const encryptedColumn = Boolean(encryption && shouldEncryptColumn(encryption, column));
572
+ const columnKeyMetadata = encryption ? getColumnKeyMetadata(encryption, column) : undefined;
573
+ const pages = encryptedColumn
574
+ ? await encryptParquetColumnPages(pageRecords, encryption, opts.encryptionFileUnique, opts.rowGroupOrdinal ?? 0, columnOrdinal, columnKeyMetadata)
575
+ : pageRecords.map(record => record.page);
576
+ let pageOffset = 0;
577
+ let dataPageIndex = 0;
578
+ let firstRowIndex = 0;
579
+ for (const [pageIndex, page] of pages.entries()) {
580
+ if (!pageRecords[pageIndex].dictionary) {
581
+ pageLocations.push(new PageLocation({
582
+ offset: baseOffset + pageOffset,
583
+ compressed_page_size: page.length,
584
+ first_row_index: firstRowIndex
585
+ }));
586
+ firstRowIndex += plannedPages[dataPageIndex++].rowCount;
587
+ }
588
+ pageOffset += page.length;
589
+ }
590
+ total_compressed_size = pages.reduce((total, page) => total + page.length, 0);
591
+ const pagesBuf = concatUint8Arrays(pages);
377
592
  // const compression = column.compression === 'UNCOMPRESSED' ? (opts.compression || 'UNCOMPRESSED') : column.compression;
593
+ const bloomFilterEnabled = opts.bloomFilter === true || opts.bloomFilter?.[column.path[0]] === true;
594
+ const bloomFilter = bloomFilterEnabled ? createColumnBloomFilter(column, data.values) : undefined;
595
+ const encodedBloomFilter = bloomFilter && encryptedColumn
596
+ ? await encryptParquetBloomFilter(bloomFilter, encryption, opts.encryptionFileUnique, opts.rowGroupOrdinal ?? 0, columnOrdinal, columnKeyMetadata)
597
+ : bloomFilter;
598
+ const pageIndexEnabled = opts.pageIndex === true || opts.pageIndex?.[column.path[0]] === true;
599
+ const pageIndexes = pageIndexEnabled
600
+ ? createColumnPageIndexes(column, plannedPages, pageLocations, opts.int96AsTimestamp)
601
+ : undefined;
602
+ const encodedPageIndexes = pageIndexes && encryptedColumn
603
+ ? await encryptParquetPageIndexes(pageIndexes, encryption, opts.encryptionFileUnique, opts.rowGroupOrdinal ?? 0, columnOrdinal, columnKeyMetadata)
604
+ : pageIndexes;
378
605
  /* prepare metadata header */
379
606
  const metadata = new ColumnMetaData({
380
607
  path_in_schema: column.path,
381
- num_values: data.count,
382
- data_page_offset: baseOffset,
608
+ num_values: int64(data.count),
609
+ data_page_offset: int64(baseOffset + (dictionaryPlan ? pages[0].length : 0)),
610
+ dictionary_page_offset: dictionaryPlan ? int64(baseOffset) : undefined,
383
611
  encodings: [],
384
- total_uncompressed_size, // : pagesBuf.length,
385
- total_compressed_size,
612
+ encoding_stats: [
613
+ ...(dictionaryPlan
614
+ ? [
615
+ new PageEncodingStats({
616
+ page_type: PageType.DICTIONARY_PAGE,
617
+ encoding: Encoding.PLAIN,
618
+ count: 1
619
+ })
620
+ ]
621
+ : []),
622
+ new PageEncodingStats({
623
+ page_type: opts.useDataPageV2 ? PageType.DATA_PAGE_V2 : PageType.DATA_PAGE,
624
+ encoding: Encoding[valueEncoding],
625
+ count: plannedPages.length
626
+ })
627
+ ],
628
+ total_uncompressed_size: int64(total_uncompressed_size), // : pagesBuf.length,
629
+ total_compressed_size: int64(total_compressed_size),
386
630
  type: Type[column.primitiveType],
387
- codec: CompressionCodec[column.compression]
631
+ codec: CompressionCodec[column.compression],
632
+ bloom_filter_offset: encodedBloomFilter ? int64(baseOffset + pagesBuf.length) : undefined,
633
+ bloom_filter_length: encodedBloomFilter?.length,
634
+ geospatial_statistics: createGeospatialStatistics(column, data.values),
635
+ size_statistics: opts.writeSizeStatistics ? createSizeStatistics(column, data) : undefined,
636
+ statistics: isStatisticsEnabled(opts.writeStatistics, column)
637
+ ? createColumnStatistics(column, data)
638
+ : undefined
388
639
  });
389
640
  /* list encodings */
390
641
  metadata.encodings.push(Encoding[PARQUET_RDLVL_ENCODING]);
391
- metadata.encodings.push(Encoding[column.encoding]);
642
+ if (dictionaryPlan)
643
+ metadata.encodings.push(Encoding.PLAIN);
644
+ metadata.encodings.push(Encoding[valueEncoding]);
392
645
  /* concat metadata header and data pages */
393
- const metadataOffset = baseOffset + pageBuf.length;
394
- const body = Buffer.concat([pageBuf, serializeThrift(metadata)]);
395
- return { body, metadata, metadataOffset };
646
+ const metadataEncoded = serializeThrift(metadata);
647
+ const metadataSection = encryptedColumn ? undefined : metadataEncoded;
648
+ const metadataOffset = baseOffset + pagesBuf.length + (encodedBloomFilter?.length || 0);
649
+ const offsetIndexOffset = encodedPageIndexes
650
+ ? metadataOffset + (metadataSection?.length || 0)
651
+ : undefined;
652
+ const columnIndexOffset = encodedPageIndexes?.columnIndex
653
+ ? metadataOffset + (metadataSection?.length || 0) + encodedPageIndexes.offsetIndex.length
654
+ : undefined;
655
+ const body = concatUint8Arrays([
656
+ pagesBuf,
657
+ ...(encodedBloomFilter ? [encodedBloomFilter] : []),
658
+ ...(metadataSection ? [metadataSection] : []),
659
+ ...(encodedPageIndexes
660
+ ? [
661
+ encodedPageIndexes.offsetIndex,
662
+ ...(encodedPageIndexes.columnIndex ? [encodedPageIndexes.columnIndex] : [])
663
+ ]
664
+ : [])
665
+ ]);
666
+ return {
667
+ body,
668
+ metadata,
669
+ metadataOffset,
670
+ offsetIndexOffset,
671
+ offsetIndexLength: encodedPageIndexes?.offsetIndex.length,
672
+ columnIndexOffset,
673
+ columnIndexLength: encodedPageIndexes?.columnIndex?.length,
674
+ ...(encryptedColumn
675
+ ? {
676
+ encryptedColumnMetadata: await encryptParquetModule(metadataEncoded, {
677
+ algorithm: encryption.algorithm ?? 'AES_GCM_V1',
678
+ aad: createParquetModuleAad(encryption.aadPrefix, opts.encryptionFileUnique, 'column-metadata', opts.rowGroupOrdinal ?? 0, columnOrdinal),
679
+ keyMetadata: columnKeyMetadata ?? encryption.keyMetadata,
680
+ keyRetriever: encryption.keyRetriever
681
+ }),
682
+ cryptoMetadata: new ColumnCryptoMetaData({
683
+ ...(columnKeyMetadata
684
+ ? {
685
+ ENCRYPTION_WITH_COLUMN_KEY: new EncryptionWithColumnKey({
686
+ path_in_schema: [...column.path],
687
+ key_metadata: new Uint8Array(columnKeyMetadata)
688
+ })
689
+ }
690
+ : { ENCRYPTION_WITH_FOOTER_KEY: new EncryptionWithFooterKey() })
691
+ })
692
+ }
693
+ : {})
694
+ };
695
+ }
696
+ /** Returns whether a writer column should use modular encryption. */
697
+ function shouldEncryptColumn(options, column) {
698
+ return Boolean(options.columnKeyMetadata?.[column.path[0]] ||
699
+ options.encryptColumns === true ||
700
+ options.encryptColumns?.[column.path[0]] === true);
701
+ }
702
+ /** Returns a defensive copy of the key metadata assigned to one top-level column. */
703
+ function getColumnKeyMetadata(options, column) {
704
+ const keyMetadata = options.columnKeyMetadata?.[column.path[0]];
705
+ return keyMetadata ? new Uint8Array(keyMetadata) : undefined;
706
+ }
707
+ /** Adds the four-byte module length required by encrypted page and Bloom-filter modules. */
708
+ function prefixEncryptedModule(module) {
709
+ const prefixed = new Uint8Array(module.byteLength + 4);
710
+ writeUInt32LE(prefixed, module.byteLength, 0);
711
+ prefixed.set(module, 4);
712
+ return prefixed;
713
+ }
714
+ /** Encrypts one column's dictionary and data pages using the Parquet module AAD rules. */
715
+ async function encryptParquetColumnPages(pageRecords, options, fileUnique, rowGroupOrdinal, columnOrdinal, keyMetadata) {
716
+ const encryptedPages = [];
717
+ let dataPageOrdinal = 0;
718
+ const algorithm = options.algorithm ?? 'AES_GCM_V1';
719
+ for (const pageRecord of pageRecords) {
720
+ const moduleType = pageRecord.dictionary ? 'dictionary-page' : 'data-page';
721
+ const headerModuleType = pageRecord.dictionary ? 'dictionary-page-header' : 'data-page-header';
722
+ const header = await encryptParquetModule(pageRecord.page.subarray(0, pageRecord.headerSize), {
723
+ algorithm,
724
+ aad: createParquetModuleAad(options.aadPrefix, fileUnique, headerModuleType, rowGroupOrdinal, columnOrdinal, pageRecord.dictionary ? undefined : dataPageOrdinal),
725
+ keyMetadata: keyMetadata ?? options.keyMetadata,
726
+ keyRetriever: options.keyRetriever
727
+ });
728
+ const body = await encryptParquetModule(pageRecord.page.subarray(pageRecord.headerSize), {
729
+ algorithm,
730
+ aad: createParquetModuleAad(options.aadPrefix, fileUnique, moduleType, rowGroupOrdinal, columnOrdinal, pageRecord.dictionary ? undefined : dataPageOrdinal),
731
+ keyMetadata: keyMetadata ?? options.keyMetadata,
732
+ keyRetriever: options.keyRetriever,
733
+ page: true
734
+ });
735
+ encryptedPages.push(concatUint8Arrays([prefixEncryptedModule(header), prefixEncryptedModule(body)]));
736
+ if (!pageRecord.dictionary)
737
+ dataPageOrdinal++;
738
+ }
739
+ return encryptedPages;
740
+ }
741
+ /** Encrypts a split-block Bloom filter header and bitset as independent Parquet modules. */
742
+ async function encryptParquetBloomFilter(bloomFilter, options, fileUnique, rowGroupOrdinal, columnOrdinal, keyMetadata) {
743
+ const parsed = decodeParquetSplitBlockBloomFilter(bloomFilter);
744
+ const algorithm = options.algorithm ?? 'AES_GCM_V1';
745
+ const keyOptions = {
746
+ algorithm,
747
+ keyMetadata: keyMetadata ?? options.keyMetadata,
748
+ keyRetriever: options.keyRetriever
749
+ };
750
+ const header = await encryptParquetModule(bloomFilter.subarray(0, parsed.headerByteLength), {
751
+ ...keyOptions,
752
+ aad: createParquetModuleAad(options.aadPrefix, fileUnique, 'bloom-filter-header', rowGroupOrdinal, columnOrdinal)
753
+ });
754
+ const bitset = await encryptParquetModule(parsed.bitset, {
755
+ ...keyOptions,
756
+ aad: createParquetModuleAad(options.aadPrefix, fileUnique, 'bloom-filter-bitset', rowGroupOrdinal, columnOrdinal)
757
+ });
758
+ return concatUint8Arrays([prefixEncryptedModule(header), prefixEncryptedModule(bitset)]);
759
+ }
760
+ /** Encrypts column and offset indexes independently while preserving their footer offsets. */
761
+ async function encryptParquetPageIndexes(pageIndexes, options, fileUnique, rowGroupOrdinal, columnOrdinal, keyMetadata) {
762
+ const algorithm = options.algorithm ?? 'AES_GCM_V1';
763
+ const encryptIndex = (bytes, module) => encryptParquetModule(bytes, {
764
+ algorithm,
765
+ aad: createParquetModuleAad(options.aadPrefix, fileUnique, module, rowGroupOrdinal, columnOrdinal),
766
+ keyMetadata: keyMetadata ?? options.keyMetadata,
767
+ keyRetriever: options.keyRetriever
768
+ });
769
+ return {
770
+ offsetIndex: await encryptIndex(pageIndexes.offsetIndex, 'offset-index'),
771
+ columnIndex: pageIndexes.columnIndex
772
+ ? await encryptIndex(pageIndexes.columnIndex, 'column-index')
773
+ : undefined
774
+ };
775
+ }
776
+ /** Builds page indexes for primitive leaves, including nested and repeated leaves. */
777
+ function createColumnPageIndexes(column, plannedPages, pageLocations, int96AsTimestamp = false) {
778
+ if (!column.primitiveType ||
779
+ !isPageIndexPhysicalType(column.primitiveType) ||
780
+ plannedPages.length !== pageLocations.length ||
781
+ plannedPages.length === 0) {
782
+ return undefined;
783
+ }
784
+ const offsetIndex = serializeThrift(new OffsetIndex({ page_locations: pageLocations }));
785
+ if (!supportsStatisticsSortOrder(column)) {
786
+ return { offsetIndex };
787
+ }
788
+ const nullPages = [];
789
+ const minValues = [];
790
+ const maxValues = [];
791
+ // A repeated leaf's definition-level count is not a row-level null count.
792
+ // Omit null_counts for those leaves so readers do not interpret entry counts
793
+ // as null counts while still benefiting from min/max page pruning.
794
+ const nullCounts = column.rLevelMax === 0 ? [] : undefined;
795
+ for (const plannedPage of plannedPages) {
796
+ const values = plannedPage.data.values;
797
+ const nullCount = plannedPage.data.count - values.length;
798
+ nullCounts?.push(nullCount);
799
+ if (values.length === 0) {
800
+ nullPages.push(true);
801
+ minValues.push(new Uint8Array(0));
802
+ maxValues.push(new Uint8Array(0));
803
+ continue;
804
+ }
805
+ const bounds = getPageBounds(values, column.primitiveType, column.typeLength, int96AsTimestamp);
806
+ if (!bounds)
807
+ return undefined;
808
+ nullPages.push(false);
809
+ minValues.push(bounds.min);
810
+ maxValues.push(bounds.max);
811
+ }
812
+ return {
813
+ offsetIndex,
814
+ columnIndex: serializeThrift(new ColumnIndex({
815
+ null_pages: nullPages,
816
+ min_values: minValues,
817
+ max_values: maxValues,
818
+ boundary_order: BoundaryOrder.UNORDERED,
819
+ null_counts: nullCounts
820
+ }))
821
+ };
822
+ }
823
+ function isPageIndexPhysicalType(physicalType) {
824
+ return (physicalType === 'BOOLEAN' ||
825
+ physicalType === 'INT32' ||
826
+ physicalType === 'INT64' ||
827
+ physicalType === 'INT96' ||
828
+ physicalType === 'FLOAT' ||
829
+ physicalType === 'DOUBLE' ||
830
+ physicalType === 'BYTE_ARRAY' ||
831
+ physicalType === 'FIXED_LEN_BYTE_ARRAY');
832
+ }
833
+ function getPageBounds(values, physicalType, typeLength, int96AsTimestamp = false) {
834
+ if (physicalType === 'INT96' && !int96AsTimestamp)
835
+ return undefined;
836
+ const normalizedValues = Array.from(values, value => normalizePageIndexValue(value, physicalType));
837
+ if (normalizedValues.some(value => value === undefined))
838
+ return undefined;
839
+ const comparableValues = normalizedValues;
840
+ let min = comparableValues[0];
841
+ let max = comparableValues[0];
842
+ for (const value of comparableValues.slice(1)) {
843
+ if (comparePageIndexValues(value, min, physicalType) < 0)
844
+ min = value;
845
+ if (comparePageIndexValues(value, max, physicalType) > 0)
846
+ max = value;
847
+ }
848
+ try {
849
+ return {
850
+ min: encodePageIndexValue(min, physicalType, typeLength, int96AsTimestamp),
851
+ max: encodePageIndexValue(max, physicalType, typeLength, int96AsTimestamp)
852
+ };
853
+ }
854
+ catch {
855
+ return undefined;
856
+ }
857
+ }
858
+ function encodePageIndexValue(value, physicalType, typeLength, int96AsTimestamp) {
859
+ if (physicalType === 'INT96') {
860
+ if (!int96AsTimestamp) {
861
+ throw new Error('INT96 page indexes require timestamp mode');
862
+ }
863
+ return PARQUET_CODECS.PLAIN.encodeValues('INT96', [value], { int96AsTimestamp });
864
+ }
865
+ return encodeParquetBloomFilterValue(value, physicalType, typeLength);
866
+ }
867
+ function normalizePageIndexValue(value, physicalType) {
868
+ if (physicalType === 'BYTE_ARRAY' || physicalType === 'FIXED_LEN_BYTE_ARRAY') {
869
+ if (typeof value === 'string')
870
+ return new TextEncoder().encode(value);
871
+ if (value instanceof ArrayBuffer)
872
+ return new Uint8Array(value);
873
+ if (ArrayBuffer.isView(value)) {
874
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength).slice();
875
+ }
876
+ return undefined;
877
+ }
878
+ if (typeof value === 'boolean' ||
879
+ typeof value === 'number' ||
880
+ typeof value === 'bigint' ||
881
+ typeof value === 'string') {
882
+ return value;
883
+ }
884
+ return undefined;
885
+ }
886
+ function comparePageIndexValues(left, right, physicalType) {
887
+ if (physicalType === 'BYTE_ARRAY' || physicalType === 'FIXED_LEN_BYTE_ARRAY') {
888
+ const leftBytes = typeof left === 'string' ? new TextEncoder().encode(left) : left;
889
+ const rightBytes = typeof right === 'string' ? new TextEncoder().encode(right) : right;
890
+ if (!(leftBytes instanceof Uint8Array) || !(rightBytes instanceof Uint8Array))
891
+ return 0;
892
+ const length = Math.min(leftBytes.length, rightBytes.length);
893
+ for (let index = 0; index < length; index++) {
894
+ if (leftBytes[index] !== rightBytes[index]) {
895
+ return leftBytes[index] < rightBytes[index] ? -1 : 1;
896
+ }
897
+ }
898
+ return leftBytes.length - rightBytes.length;
899
+ }
900
+ if (typeof left === 'boolean' && typeof right === 'boolean')
901
+ return Number(left) - Number(right);
902
+ if (physicalType !== 'INT64' && physicalType !== 'INT96') {
903
+ const leftNumber = Number(left);
904
+ const rightNumber = Number(right);
905
+ return leftNumber < rightNumber ? -1 : leftNumber > rightNumber ? 1 : 0;
906
+ }
907
+ try {
908
+ const leftNumber = BigInt(left);
909
+ const rightNumber = BigInt(right);
910
+ return leftNumber < rightNumber ? -1 : leftNumber > rightNumber ? 1 : 0;
911
+ }
912
+ catch {
913
+ const leftNumber = Number(left);
914
+ const rightNumber = Number(right);
915
+ return leftNumber < rightNumber ? -1 : leftNumber > rightNumber ? 1 : 0;
916
+ }
917
+ }
918
+ /** Builds a Bloom filter for writer-supported physical scalar columns. */
919
+ function createColumnBloomFilter(column, values) {
920
+ const physicalType = column.primitiveType;
921
+ if (physicalType !== 'BOOLEAN' &&
922
+ physicalType !== 'INT32' &&
923
+ physicalType !== 'INT64' &&
924
+ physicalType !== 'FLOAT' &&
925
+ physicalType !== 'DOUBLE' &&
926
+ physicalType !== 'BYTE_ARRAY' &&
927
+ physicalType !== 'FIXED_LEN_BYTE_ARRAY') {
928
+ return undefined;
929
+ }
930
+ const bloomValues = values.map(value => {
931
+ if (value instanceof ArrayBuffer)
932
+ return new Uint8Array(value);
933
+ if (ArrayBuffer.isView(value)) {
934
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength).slice();
935
+ }
936
+ return value;
937
+ });
938
+ return encodeParquetSplitBlockBloomFilter(bloomValues, physicalType, column.typeLength);
939
+ }
940
+ /** Builds optional size statistics from one shredded column chunk. */
941
+ function createSizeStatistics(column, data) {
942
+ const repetitionLevelHistogram = createLevelHistogram(data.rlevels, column.rLevelMax);
943
+ const definitionLevelHistogram = createLevelHistogram(data.dlevels, column.dLevelMax);
944
+ let unencodedByteArrayDataBytes = 0;
945
+ if (column.primitiveType === 'BYTE_ARRAY') {
946
+ for (const value of data.values) {
947
+ if (typeof value === 'string') {
948
+ unencodedByteArrayDataBytes += encodeUtf8(value).byteLength;
949
+ }
950
+ else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
951
+ unencodedByteArrayDataBytes += value.byteLength;
952
+ }
953
+ }
954
+ }
955
+ return new SizeStatistics({
956
+ unencoded_byte_array_data_bytes: column.primitiveType === 'BYTE_ARRAY' ? unencodedByteArrayDataBytes : undefined,
957
+ repetition_level_histogram: repetitionLevelHistogram,
958
+ definition_level_histogram: definitionLevelHistogram
959
+ });
960
+ }
961
+ /** Returns whether standard column statistics are enabled for one top-level field. */
962
+ function isStatisticsEnabled(option, column) {
963
+ return option === true || option?.[column.path[0]] === true;
964
+ }
965
+ /** Builds conservative standard min/max/null-count statistics for one column chunk. */
966
+ function createColumnStatistics(column, data) {
967
+ if (!column.primitiveType ||
968
+ !isPageIndexPhysicalType(column.primitiveType) ||
969
+ !supportsStatisticsSortOrder(column)) {
970
+ return undefined;
971
+ }
972
+ const statistics = new Statistics({
973
+ null_count: column.rLevelMax === 0 ? data.count - data.values.length : undefined,
974
+ is_min_value_exact: true,
975
+ is_max_value_exact: true
976
+ });
977
+ if (data.values.length === 0)
978
+ return statistics;
979
+ const bounds = getPageBounds(data.values, column.primitiveType, column.typeLength);
980
+ if (!bounds)
981
+ return undefined;
982
+ statistics.min_value = bounds.min;
983
+ statistics.max_value = bounds.max;
984
+ return statistics;
985
+ }
986
+ /** Returns whether the physical representation preserves the logical sort order. */
987
+ function supportsStatisticsSortOrder(column) {
988
+ const logicalType = column.logicalType?.type || column.originalType;
989
+ if (logicalType === 'FLOAT16')
990
+ return false;
991
+ if (logicalType === 'DECIMAL' || logicalType?.startsWith('DECIMAL_')) {
992
+ return column.primitiveType !== 'BYTE_ARRAY' && column.primitiveType !== 'FIXED_LEN_BYTE_ARRAY';
993
+ }
994
+ if (logicalType === 'INTEGER' || logicalType?.startsWith('UINT_')) {
995
+ return column.logicalType?.isSigned !== false && !logicalType.startsWith('UINT_');
996
+ }
997
+ return true;
998
+ }
999
+ /** Counts the occurrences of each definition or repetition level. */
1000
+ function createLevelHistogram(levels, maximumLevel) {
1001
+ const histogram = new Array(maximumLevel + 1).fill(0);
1002
+ for (const level of levels) {
1003
+ if (level >= 0 && level <= maximumLevel)
1004
+ histogram[level]++;
1005
+ }
1006
+ return histogram;
1007
+ }
1008
+ /** Converts writer-facing sort keys into Parquet leaf-column indexes. */
1009
+ function createSortingColumns(schema, sortingColumns) {
1010
+ if (!sortingColumns?.length)
1011
+ return undefined;
1012
+ const leafFields = schema.fieldList.filter(field => !field.isNested);
1013
+ const usedColumnIndexes = new Set();
1014
+ return sortingColumns.map(sortKey => {
1015
+ const columnIndex = leafFields.findIndex(field => (field.path.length === 1 && field.name === sortKey.column) ||
1016
+ (field.path.length > 1 && field.path.join('.') === sortKey.column));
1017
+ if (columnIndex < 0) {
1018
+ throw new Error(`Unknown Parquet sorting column ${sortKey.column}`);
1019
+ }
1020
+ if (usedColumnIndexes.has(columnIndex)) {
1021
+ throw new Error(`Duplicate Parquet sorting column ${sortKey.column}`);
1022
+ }
1023
+ usedColumnIndexes.add(columnIndex);
1024
+ return new SortingColumn({
1025
+ column_idx: columnIndex,
1026
+ descending: Boolean(sortKey.descending),
1027
+ nulls_first: Boolean(sortKey.nullsFirst)
1028
+ });
1029
+ });
396
1030
  }
397
1031
  /**
398
1032
  * Encode a list of column values into a parquet row group
399
1033
  */
400
1034
  async function encodeRowGroup(schema, data, opts) {
401
1035
  const metadata = new RowGroup({
402
- num_rows: data.rowCount,
1036
+ num_rows: int64(data.rowCount),
403
1037
  columns: [],
404
- total_byte_size: 0
1038
+ total_byte_size: int64(0),
1039
+ sorting_columns: createSortingColumns(schema, opts.sortingColumns)
405
1040
  });
406
- let body = Buffer.alloc(0);
1041
+ let body = new Uint8Array(0);
407
1042
  for (const field of schema.fieldList) {
408
1043
  if (field.isNested) {
409
1044
  continue; // eslint-disable-line no-continue
410
1045
  }
411
- const cchunkData = await encodeColumnChunk(field, data, body.length, opts);
1046
+ const cchunkData = await encodeColumnChunk(field, data, body.length, opts, opts.rowGroupOrdinal ?? 0, metadata.columns.length);
412
1047
  const cchunk = new ColumnChunk({
413
- file_offset: cchunkData.metadataOffset,
414
- meta_data: cchunkData.metadata
1048
+ file_offset: int64(cchunkData.metadataOffset),
1049
+ meta_data: cchunkData.encryptedColumnMetadata ? undefined : cchunkData.metadata,
1050
+ offset_index_offset: cchunkData.offsetIndexOffset === undefined
1051
+ ? undefined
1052
+ : int64(cchunkData.offsetIndexOffset),
1053
+ offset_index_length: cchunkData.offsetIndexLength,
1054
+ column_index_offset: cchunkData.columnIndexOffset === undefined
1055
+ ? undefined
1056
+ : int64(cchunkData.columnIndexOffset),
1057
+ column_index_length: cchunkData.columnIndexLength,
1058
+ crypto_metadata: cchunkData.cryptoMetadata,
1059
+ encrypted_column_metadata: cchunkData.encryptedColumnMetadata
415
1060
  });
416
1061
  metadata.columns.push(cchunk);
417
- metadata.total_byte_size = new Int64(Number(metadata.total_byte_size) + cchunkData.body.length);
418
- body = Buffer.concat([body, cchunkData.body]);
1062
+ metadata.total_byte_size = int64(Number(metadata.total_byte_size) + cchunkData.body.length);
1063
+ body = concatUint8Arrays([body, cchunkData.body]);
419
1064
  }
420
1065
  return { body, metadata };
421
1066
  }
422
1067
  /**
423
1068
  * Encode a parquet file metadata footer
424
1069
  */
425
- function encodeFooter(schema, rowCount, rowGroups, userMetadata) {
1070
+ function encodeFooterMetadata(schema, rowCount, rowGroups, userMetadata, footerSignature) {
1071
+ const signatureAlgorithm = footerSignature?.algorithm ?? 'AES_GCM_V1';
1072
+ const signatureFileUnique = footerSignature?.fileUnique
1073
+ ? new Uint8Array(footerSignature.fileUnique)
1074
+ : undefined;
426
1075
  const metadata = new FileMetaData({
427
1076
  version: PARQUET_VERSION,
428
1077
  created_by: 'parquets',
429
- num_rows: rowCount,
1078
+ num_rows: int64(rowCount),
430
1079
  row_groups: rowGroups,
431
1080
  schema: [],
432
- key_value_metadata: []
1081
+ key_value_metadata: [],
1082
+ encryption_algorithm: footerSignature
1083
+ ? new EncryptionAlgorithm({
1084
+ ...(signatureAlgorithm === 'AES_GCM_CTR_V1'
1085
+ ? {
1086
+ AES_GCM_CTR_V1: {
1087
+ aad_prefix: footerSignature.aadPrefix,
1088
+ aad_file_unique: signatureFileUnique
1089
+ }
1090
+ }
1091
+ : {
1092
+ AES_GCM_V1: {
1093
+ aad_prefix: footerSignature.aadPrefix,
1094
+ aad_file_unique: signatureFileUnique
1095
+ }
1096
+ })
1097
+ })
1098
+ : undefined,
1099
+ footer_signing_key_metadata: footerSignature
1100
+ ? new Uint8Array(footerSignature.keyMetadata)
1101
+ : undefined
433
1102
  });
434
1103
  for (const key in userMetadata) {
435
1104
  const kv = new KeyValue({
@@ -458,16 +1127,211 @@ function encodeFooter(schema, rowCount, rowGroups, userMetadata) {
458
1127
  schemaElem.type = Type[field.primitiveType];
459
1128
  }
460
1129
  if (field.originalType) {
461
- schemaElem.converted_type = ConvertedType[field.originalType];
1130
+ const convertedType = ConvertedType[field.originalType];
1131
+ if (typeof convertedType === 'number') {
1132
+ schemaElem.converted_type = convertedType;
1133
+ }
462
1134
  }
463
1135
  schemaElem.type_length = field.typeLength;
1136
+ schemaElem.precision = field.precision ?? field.presision;
1137
+ schemaElem.scale = field.scale;
1138
+ schemaElem.field_id = field.fieldId;
1139
+ const logicalType = getFieldLogicalType(field);
1140
+ if (logicalType) {
1141
+ schemaElem.logicalType = encodeParquetLogicalType(logicalType);
1142
+ }
464
1143
  metadata.schema.push(schemaElem);
465
1144
  }
466
- const metadataEncoded = serializeThrift(metadata);
467
- const footerEncoded = Buffer.alloc(metadataEncoded.length + 8);
468
- metadataEncoded.copy(footerEncoded);
469
- footerEncoded.writeUInt32LE(metadataEncoded.length, metadataEncoded.length);
470
- footerEncoded.write(PARQUET_MAGIC, metadataEncoded.length + 4);
1145
+ return serializeThrift(metadata);
1146
+ }
1147
+ /** Encodes an unsigned plaintext footer with its standard Parquet trailer. */
1148
+ function encodeFooter(schema, rowCount, rowGroups, userMetadata) {
1149
+ const metadataEncoded = encodeFooterMetadata(schema, rowCount, rowGroups, userMetadata);
1150
+ const footerEncoded = new Uint8Array(metadataEncoded.length + 8);
1151
+ footerEncoded.set(metadataEncoded);
1152
+ writeUInt32LE(footerEncoded, metadataEncoded.length, metadataEncoded.length);
1153
+ footerEncoded.set(PARQUET_MAGIC_BYTES, metadataEncoded.length + 4);
471
1154
  return footerEncoded;
472
1155
  }
1156
+ /** Encodes a plaintext footer with its trailing 28-byte authenticated signature. */
1157
+ async function encodeSignedFooter(schema, rowCount, rowGroups, userMetadata, options) {
1158
+ const metadata = encodeFooterMetadata(schema, rowCount, rowGroups, userMetadata, options);
1159
+ const signature = await createParquetFooterSignature(metadata, options);
1160
+ const footerEncoded = new Uint8Array(metadata.length + signature.length + 8);
1161
+ footerEncoded.set(metadata);
1162
+ footerEncoded.set(signature, metadata.length);
1163
+ writeUInt32LE(footerEncoded, metadata.length + signature.length, metadata.length + signature.length);
1164
+ footerEncoded.set(PARQUET_MAGIC_BYTES, metadata.length + signature.length + 4);
1165
+ return footerEncoded;
1166
+ }
1167
+ /** Wraps a serialized footer in Parquet modular-encryption metadata and AES-GCM. */
1168
+ async function encodeEncryptedFooter(footer, options) {
1169
+ const algorithm = options.algorithm ?? 'AES_GCM_V1';
1170
+ const fileUnique = options.fileUnique ? new Uint8Array(options.fileUnique) : createFileUnique();
1171
+ if (fileUnique.byteLength !== 8) {
1172
+ throw new Error(`Parquet encrypted footer file_unique must be 8 bytes`);
1173
+ }
1174
+ const algorithmParameters = {
1175
+ aad_prefix: options.aadPrefix && new Uint8Array(options.aadPrefix),
1176
+ aad_file_unique: fileUnique,
1177
+ supply_aad_prefix: undefined
1178
+ };
1179
+ const encryptionAlgorithm = algorithm === 'AES_GCM_CTR_V1'
1180
+ ? new EncryptionAlgorithm({ AES_GCM_CTR_V1: algorithmParameters })
1181
+ : new EncryptionAlgorithm({ AES_GCM_V1: algorithmParameters });
1182
+ const cryptoMetadata = serializeThrift(new FileCryptoMetaData({
1183
+ encryption_algorithm: encryptionAlgorithm,
1184
+ key_metadata: options.keyMetadata && new Uint8Array(options.keyMetadata)
1185
+ }));
1186
+ const footerMetadata = footer.subarray(0, footer.byteLength - 8);
1187
+ const encryptedFooter = await encryptParquetModule(footerMetadata, {
1188
+ algorithm,
1189
+ aad: createParquetModuleAad(options.aadPrefix, fileUnique, 'footer'),
1190
+ keyMetadata: options.keyMetadata,
1191
+ keyRetriever: options.keyRetriever
1192
+ });
1193
+ const metadataSize = cryptoMetadata.byteLength + encryptedFooter.byteLength;
1194
+ const trailer = new Uint8Array(8);
1195
+ writeUInt32LE(trailer, metadataSize, 0);
1196
+ trailer.set(encodeUtf8(PARQUET_MAGIC_ENCRYPTED), 4);
1197
+ return concatUint8Arrays([cryptoMetadata, encryptedFooter, trailer]);
1198
+ }
1199
+ /** Generates the eight-byte file identifier required by Parquet module AAD. */
1200
+ function createFileUnique() {
1201
+ const fileUnique = new Uint8Array(8);
1202
+ const cryptoProvider = globalThis.crypto;
1203
+ if (!cryptoProvider?.getRandomValues) {
1204
+ throw new Error('Parquet encrypted footer requires Web Crypto random values');
1205
+ }
1206
+ cryptoProvider.getRandomValues(fileUnique);
1207
+ return fileUnique;
1208
+ }
1209
+ /** Returns an explicit or inferred modern logical annotation for a writer field. */
1210
+ function getFieldLogicalType(field) {
1211
+ if (field.logicalType)
1212
+ return field.logicalType;
1213
+ const originalType = field.originalType;
1214
+ if (!originalType)
1215
+ return undefined;
1216
+ if (originalType === 'UTF8')
1217
+ return { type: 'STRING' };
1218
+ if (originalType === 'ENUM')
1219
+ return { type: 'ENUM' };
1220
+ if (originalType.startsWith('DECIMAL_')) {
1221
+ return {
1222
+ type: 'DECIMAL',
1223
+ precision: field.precision ?? field.presision,
1224
+ scale: field.scale
1225
+ };
1226
+ }
1227
+ if (originalType === 'DATE')
1228
+ return { type: 'DATE' };
1229
+ if (originalType.startsWith('TIME_')) {
1230
+ return {
1231
+ type: 'TIME',
1232
+ unit: originalType.slice(5),
1233
+ isAdjustedToUTC: true
1234
+ };
1235
+ }
1236
+ if (originalType.startsWith('TIMESTAMP_')) {
1237
+ return {
1238
+ type: 'TIMESTAMP',
1239
+ unit: originalType.slice(10),
1240
+ isAdjustedToUTC: true
1241
+ };
1242
+ }
1243
+ if (originalType.startsWith('UINT_') || originalType.startsWith('INT_')) {
1244
+ return {
1245
+ type: 'INTEGER',
1246
+ bitWidth: Number(originalType.slice(originalType.indexOf('_') + 1)),
1247
+ isSigned: originalType.startsWith('INT_')
1248
+ };
1249
+ }
1250
+ if (originalType === 'JSON' || originalType === 'BSON')
1251
+ return { type: originalType };
1252
+ if (originalType === 'UUID' ||
1253
+ originalType === 'FLOAT16' ||
1254
+ originalType === 'UNKNOWN' ||
1255
+ originalType === 'VARIANT' ||
1256
+ originalType === 'GEOMETRY' ||
1257
+ originalType === 'GEOGRAPHY') {
1258
+ return { type: originalType };
1259
+ }
1260
+ return undefined;
1261
+ }
1262
+ /** Converts the internal logical annotation into the Parquet 2.13 Thrift union. */
1263
+ function encodeParquetLogicalType(logicalType) {
1264
+ switch (logicalType.type) {
1265
+ case 'STRING':
1266
+ return LogicalType.fromSTRING(new StringType());
1267
+ case 'MAP':
1268
+ return LogicalType.fromMAP(new MapType());
1269
+ case 'LIST':
1270
+ return LogicalType.fromLIST(new ListType());
1271
+ case 'ENUM':
1272
+ return LogicalType.fromENUM(new EnumType());
1273
+ case 'DECIMAL':
1274
+ if (logicalType.precision === undefined || logicalType.scale === undefined) {
1275
+ throw new Error('Parquet DECIMAL requires precision and scale');
1276
+ }
1277
+ return LogicalType.fromDECIMAL(new DecimalType({ precision: logicalType.precision, scale: logicalType.scale }));
1278
+ case 'DATE':
1279
+ return LogicalType.fromDATE(new DateType());
1280
+ case 'TIME':
1281
+ return LogicalType.fromTIME(new TimeType({
1282
+ isAdjustedToUTC: logicalType.isAdjustedToUTC ?? false,
1283
+ unit: encodeParquetTimeUnit(logicalType.unit)
1284
+ }));
1285
+ case 'TIMESTAMP':
1286
+ return LogicalType.fromTIMESTAMP(new TimestampType({
1287
+ isAdjustedToUTC: logicalType.isAdjustedToUTC ?? false,
1288
+ unit: encodeParquetTimeUnit(logicalType.unit)
1289
+ }));
1290
+ case 'INTEGER':
1291
+ if (logicalType.bitWidth === undefined || logicalType.isSigned === undefined) {
1292
+ throw new Error('Parquet INTEGER requires bitWidth and isSigned');
1293
+ }
1294
+ return LogicalType.fromINTEGER(new IntType({ bitWidth: logicalType.bitWidth, isSigned: logicalType.isSigned }));
1295
+ case 'UNKNOWN':
1296
+ return LogicalType.fromUNKNOWN(new NullType());
1297
+ case 'JSON':
1298
+ return LogicalType.fromJSON(new JsonType());
1299
+ case 'BSON':
1300
+ return LogicalType.fromBSON(new BsonType());
1301
+ case 'UUID':
1302
+ return LogicalType.fromUUID(new UUIDType());
1303
+ case 'FLOAT16':
1304
+ return LogicalType.fromFLOAT16(new Float16Type());
1305
+ case 'VARIANT':
1306
+ return LogicalType.fromVARIANT(new VariantType({ specification_version: logicalType.specificationVersion }));
1307
+ case 'GEOMETRY':
1308
+ return LogicalType.fromGEOMETRY(new GeometryType({ crs: logicalType.crs }));
1309
+ case 'GEOGRAPHY':
1310
+ return LogicalType.fromGEOGRAPHY(new GeographyType({
1311
+ crs: logicalType.crs,
1312
+ algorithm: logicalType.algorithm === undefined
1313
+ ? undefined
1314
+ : EdgeInterpolationAlgorithm[logicalType.algorithm]
1315
+ }));
1316
+ default:
1317
+ throw new Error(`Unsupported Parquet logical type ${logicalType.type}`);
1318
+ }
1319
+ }
1320
+ /** Encodes one Parquet logical time unit. */
1321
+ function encodeParquetTimeUnit(unit) {
1322
+ switch (unit) {
1323
+ case 'MILLIS':
1324
+ return TimeUnit.fromMILLIS(new MilliSeconds());
1325
+ case 'MICROS':
1326
+ return TimeUnit.fromMICROS(new MicroSeconds());
1327
+ case 'NANOS':
1328
+ return TimeUnit.fromNANOS(new NanoSeconds());
1329
+ default:
1330
+ throw new Error('Parquet TIME and TIMESTAMP require a unit');
1331
+ }
1332
+ }
1333
+ /** Wrap a writer metadata number in the thrift int64 compatibility object. */
1334
+ function int64(value) {
1335
+ return new CompactInt64(BigInt(value));
1336
+ }
473
1337
  //# sourceMappingURL=parquet-encoder.js.map