@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
@@ -9,13 +9,18 @@ import {
9
9
  ParquetColumnChunk,
10
10
  ParquetReaderContext,
11
11
  ParquetPageData,
12
+ ParquetLogicalType,
13
+ ParquetLevelBuffer,
14
+ ParquetTimeUnit,
12
15
  ParquetType,
13
16
  PrimitiveType,
14
17
  SchemaDefinition
15
18
  } from '../schema/declare';
16
19
  import {CursorBuffer, ParquetCodecOptions, PARQUET_CODECS} from '../codecs/index';
20
+ import type {ParquetByteArrayOutput, ParquetValueBuffer} from '../codecs/declare';
17
21
  import {
18
22
  ConvertedType,
23
+ EdgeInterpolationAlgorithm,
19
24
  Encoding,
20
25
  FieldRepetitionType,
21
26
  PageHeader,
@@ -24,8 +29,24 @@ import {
24
29
  Type
25
30
  } from '../parquet-thrift/index';
26
31
  import {decompress} from '../compression';
32
+ import type {TimeUnit as ParquetThriftTimeUnit} from '../parquet-thrift/TimeUnit';
27
33
  import {PARQUET_RDLVL_TYPE, PARQUET_RDLVL_ENCODING} from '../../lib/constants';
28
34
  import {decodePageHeader, getThriftEnum, getBitWidth} from '../utils/read-utils';
35
+ import {crc32} from '../utils/crc32';
36
+
37
+ /** Shared empty level storage for required flat columns, whose levels are implicit. */
38
+ const EMPTY_PARQUET_LEVEL_BUFFER = new Uint8Array(0);
39
+
40
+ /** Preallocated column destination used to bypass page-local value and level arrays. */
41
+ type ParquetPageDecodeTarget = {
42
+ values: ParquetValueBuffer;
43
+ valueOffset: number;
44
+ byteArrayOutput?: ParquetByteArrayOutput;
45
+ dictionary: readonly unknown[];
46
+ rlevels: ParquetLevelBuffer;
47
+ dlevels: ParquetLevelBuffer;
48
+ levelOffset: number;
49
+ };
29
50
 
30
51
  /**
31
52
  * Decode data pages
@@ -35,7 +56,7 @@ import {decodePageHeader, getThriftEnum, getBitWidth} from '../utils/read-utils'
35
56
  * @returns parquet data page data
36
57
  */
37
58
  export async function decodeDataPages(
38
- buffer: Buffer,
59
+ buffer: Uint8Array,
39
60
  context: ParquetReaderContext
40
61
  ): Promise<ParquetColumnChunk> {
41
62
  const cursor: CursorBuffer = {
@@ -44,23 +65,49 @@ export async function decodeDataPages(
44
65
  size: buffer.length
45
66
  };
46
67
 
68
+ const expectedLevelCount =
69
+ context.numValues === undefined ? undefined : Number(context.numValues);
70
+ if (
71
+ expectedLevelCount !== undefined &&
72
+ (!Number.isSafeInteger(expectedLevelCount) || expectedLevelCount < 0)
73
+ ) {
74
+ throw new Error(`Invalid Parquet column value count ${expectedLevelCount}`);
75
+ }
76
+
77
+ const outputCapacity = expectedLevelCount ?? 0;
78
+ const byteArrayOutput = createArrowByteArrayOutput(buffer, context, outputCapacity);
47
79
  const data: ParquetColumnChunk = {
48
- rlevels: [],
49
- dlevels: [],
50
- values: [],
80
+ rlevels: createParquetLevelBuffer(context, outputCapacity, context.rLevelMax),
81
+ dlevels: createParquetLevelBuffer(context, outputCapacity, context.dLevelMax),
82
+ values: byteArrayOutput ? [] : createParquetColumnValueBuffer(context, outputCapacity),
51
83
  pageHeaders: [],
52
- count: 0
84
+ count: 0,
85
+ nullCount: 0
53
86
  };
54
87
 
55
88
  let dictionary = context.dictionary || [];
89
+ let levelOffset = 0;
90
+ let valueOffset = 0;
56
91
 
57
92
  while (
58
93
  // @ts-ignore size can be undefined
59
94
  cursor.offset < cursor.size &&
60
- (!context.numValues || data.dlevels.length < Number(context.numValues))
95
+ (expectedLevelCount === undefined || levelOffset < expectedLevelCount)
61
96
  ) {
62
97
  // Looks like we have to decode these in sequence due to cursor updates?
63
- const page = await decodePage(cursor, context);
98
+ const target = {
99
+ values: data.values,
100
+ valueOffset,
101
+ byteArrayOutput,
102
+ dictionary,
103
+ rlevels: data.rlevels,
104
+ dlevels: data.dlevels,
105
+ levelOffset
106
+ };
107
+ const page =
108
+ context.compression === 'UNCOMPRESSED'
109
+ ? decodeUncompressedPage(cursor, context, target)
110
+ : await decodePage(cursor, context, target);
64
111
 
65
112
  if (page.dictionary) {
66
113
  dictionary = page.dictionary;
@@ -68,34 +115,141 @@ export async function decodeDataPages(
68
115
  continue;
69
116
  }
70
117
 
71
- const valueEncoding = getThriftEnum(
72
- Encoding,
73
- page.pageHeader.data_page_header?.encoding!
74
- ) as ParquetCodec;
75
- // Pages might be in different encodings. We don't need to decode in case
76
- // of 'PLAIN' encoding because all values are already in place
77
- if (dictionary.length && valueEncoding !== 'PLAIN') {
78
- // eslint-disable-next-line no-loop-func
79
- page.values = page.values.map((value) => dictionary[value]);
118
+ levelOffset += page.count;
119
+
120
+ if (page.directValuesWritten !== undefined) {
121
+ valueOffset += page.directValuesWritten;
122
+ data.nullCount! += page.count - page.directValuesWritten;
123
+ } else {
124
+ const valueEncoding = getThriftEnum(
125
+ Encoding,
126
+ page.pageHeader.data_page_header?.encoding ?? page.pageHeader.data_page_header_v2?.encoding!
127
+ ) as ParquetCodec;
128
+ const usesDictionary =
129
+ dictionary.length &&
130
+ (valueEncoding === 'PLAIN_DICTIONARY' || valueEncoding === 'RLE_DICTIONARY');
131
+ for (let index = 0; index < page.values.length; index++) {
132
+ const value = usesDictionary ? dictionary[Number(page.values[index])] : page.values[index];
133
+ if (value !== undefined) {
134
+ data.values[valueOffset++] = value;
135
+ }
136
+ }
80
137
  }
81
138
 
82
- for (let index = 0; index < page.rlevels.length; index++) {
83
- data.rlevels.push(page.rlevels[index]);
84
- data.dlevels.push(page.dlevels[index]);
85
- const value = page.values[index];
139
+ data.count += page.count;
140
+ data.pageHeaders.push(page.pageHeader);
141
+ }
86
142
 
87
- if (value !== undefined) {
88
- data.values.push(value);
89
- }
143
+ data.rlevels = trimParquetLevelBuffer(data.rlevels, levelOffset);
144
+ data.dlevels = trimParquetLevelBuffer(data.dlevels, levelOffset);
145
+ if (byteArrayOutput) {
146
+ data.values = [];
147
+ data.byteArrayData = {
148
+ data: byteArrayOutput.data.subarray(0, byteArrayOutput.byteLength),
149
+ valueOffsets: byteArrayOutput.valueOffsets.subarray(0, valueOffset + 1)
150
+ };
151
+ } else {
152
+ data.values = trimParquetValueBuffer(data.values, valueOffset);
153
+ }
154
+
155
+ return data;
156
+ }
157
+
158
+ /**
159
+ * Decodes an uncompressed column chunk synchronously.
160
+ *
161
+ * In-memory Parquet reads use this entry point to avoid one resolved Promise per selected column.
162
+ */
163
+ export function decodeUncompressedDataPages(
164
+ buffer: Uint8Array,
165
+ context: ParquetReaderContext
166
+ ): ParquetColumnChunk {
167
+ const cursor: CursorBuffer = {buffer, offset: 0, size: buffer.length};
168
+ const expectedLevelCount =
169
+ context.numValues === undefined ? undefined : Number(context.numValues);
170
+ if (
171
+ expectedLevelCount !== undefined &&
172
+ (!Number.isSafeInteger(expectedLevelCount) || expectedLevelCount < 0)
173
+ ) {
174
+ throw new Error(`Invalid Parquet column value count ${expectedLevelCount}`);
175
+ }
176
+
177
+ const outputCapacity = expectedLevelCount ?? 0;
178
+ const byteArrayOutput = createArrowByteArrayOutput(buffer, context, outputCapacity);
179
+ const data: ParquetColumnChunk = {
180
+ rlevels: createParquetLevelBuffer(context, outputCapacity, context.rLevelMax),
181
+ dlevels: createParquetLevelBuffer(context, outputCapacity, context.dLevelMax),
182
+ values: byteArrayOutput ? [] : createParquetColumnValueBuffer(context, outputCapacity),
183
+ pageHeaders: [],
184
+ count: 0,
185
+ nullCount: 0
186
+ };
187
+ let dictionary = context.dictionary || [];
188
+ let levelOffset = 0;
189
+ let valueOffset = 0;
190
+
191
+ while (
192
+ cursor.offset < (cursor.size ?? cursor.buffer.length) &&
193
+ (expectedLevelCount === undefined || levelOffset < expectedLevelCount)
194
+ ) {
195
+ const page = decodeUncompressedPage(cursor, context, {
196
+ values: data.values,
197
+ valueOffset,
198
+ byteArrayOutput,
199
+ dictionary,
200
+ rlevels: data.rlevels,
201
+ dlevels: data.dlevels,
202
+ levelOffset
203
+ });
204
+ if (page.dictionary) {
205
+ dictionary = page.dictionary;
206
+ continue;
90
207
  }
91
208
 
209
+ levelOffset += page.count;
210
+ if (page.directValuesWritten !== undefined) {
211
+ valueOffset += page.directValuesWritten;
212
+ data.nullCount! += page.count - page.directValuesWritten;
213
+ } else {
214
+ const valueEncoding = getThriftEnum(
215
+ Encoding,
216
+ page.pageHeader.data_page_header?.encoding ?? page.pageHeader.data_page_header_v2?.encoding!
217
+ ) as ParquetCodec;
218
+ const usesDictionary =
219
+ dictionary.length &&
220
+ (valueEncoding === 'PLAIN_DICTIONARY' || valueEncoding === 'RLE_DICTIONARY');
221
+ for (let index = 0; index < page.values.length; index++) {
222
+ const value = usesDictionary ? dictionary[Number(page.values[index])] : page.values[index];
223
+ if (value !== undefined) data.values[valueOffset++] = value;
224
+ }
225
+ }
92
226
  data.count += page.count;
93
227
  data.pageHeaders.push(page.pageHeader);
94
228
  }
95
229
 
230
+ data.rlevels = trimParquetLevelBuffer(data.rlevels, levelOffset);
231
+ data.dlevels = trimParquetLevelBuffer(data.dlevels, levelOffset);
232
+ if (byteArrayOutput) {
233
+ data.values = [];
234
+ data.byteArrayData = {
235
+ data: byteArrayOutput.data.subarray(0, byteArrayOutput.byteLength),
236
+ valueOffsets: byteArrayOutput.valueOffsets.subarray(0, valueOffset + 1)
237
+ };
238
+ } else {
239
+ data.values = trimParquetValueBuffer(data.values, valueOffset);
240
+ }
96
241
  return data;
97
242
  }
98
243
 
244
+ /** Decodes a dictionary page from an uncompressed in-memory column chunk. */
245
+ export function decodeUncompressedDictionaryBuffer(
246
+ buffer: Uint8Array,
247
+ context: ParquetReaderContext
248
+ ): unknown[] {
249
+ const cursor: CursorBuffer = {buffer, offset: 0, size: buffer.length};
250
+ return decodeUncompressedPage(cursor, context).dictionary!;
251
+ }
252
+
99
253
  /**
100
254
  * Decode parquet page based on page type
101
255
  * @param cursor
@@ -103,7 +257,8 @@ export async function decodeDataPages(
103
257
  */
104
258
  export async function decodePage(
105
259
  cursor: CursorBuffer,
106
- context: ParquetReaderContext
260
+ context: ParquetReaderContext,
261
+ target?: ParquetPageDecodeTarget
107
262
  ): Promise<ParquetPageData> {
108
263
  let page;
109
264
 
@@ -111,13 +266,15 @@ export async function decodePage(
111
266
  cursor.offset += length;
112
267
 
113
268
  const pageType = getThriftEnum(PageType, pageHeader.type);
269
+ const pageEnd = cursor.offset + pageHeader.compressed_page_size;
270
+ verifyPageChecksum(cursor, pageHeader, pageEnd, context);
114
271
 
115
272
  switch (pageType) {
116
273
  case 'DATA_PAGE':
117
- page = await decodeDataPage(cursor, pageHeader, context);
274
+ page = await decodeDataPage(cursor, pageHeader, context, target);
118
275
  break;
119
276
  case 'DATA_PAGE_V2':
120
- page = await decodeDataPageV2(cursor, pageHeader, context);
277
+ page = await decodeDataPageV2(cursor, pageHeader, context, target);
121
278
  break;
122
279
  case 'DICTIONARY_PAGE':
123
280
  page = {
@@ -132,6 +289,56 @@ export async function decodePage(
132
289
  return page;
133
290
  }
134
291
 
292
+ /** Decodes one uncompressed page without introducing a Promise/microtask boundary. */
293
+ function decodeUncompressedPage(
294
+ cursor: CursorBuffer,
295
+ context: ParquetReaderContext,
296
+ target?: ParquetPageDecodeTarget
297
+ ): ParquetPageData {
298
+ const {pageHeader, length} = decodePageHeader(cursor.buffer, cursor.offset);
299
+ cursor.offset += length;
300
+ const pageEnd = cursor.offset + pageHeader.compressed_page_size;
301
+ verifyPageChecksum(cursor, pageHeader, pageEnd, context);
302
+
303
+ const pageType = getThriftEnum(PageType, pageHeader.type);
304
+ switch (pageType) {
305
+ case 'DATA_PAGE':
306
+ return decodeDataPageValues(cursor, pageHeader, context, target);
307
+ case 'DATA_PAGE_V2':
308
+ return decodeUncompressedDataPageV2(cursor, pageHeader, context, target);
309
+ case 'DICTIONARY_PAGE':
310
+ return {
311
+ dictionary: decodeUncompressedDictionaryPage(cursor, pageHeader, context),
312
+ dlevels: EMPTY_PARQUET_LEVEL_BUFFER,
313
+ rlevels: EMPTY_PARQUET_LEVEL_BUFFER,
314
+ values: [],
315
+ count: 0,
316
+ pageHeader
317
+ };
318
+ default:
319
+ throw new Error(`invalid page type: ${pageType}`);
320
+ }
321
+ }
322
+
323
+ /** Verifies a page checksum before either the synchronous or asynchronous decode path consumes it. */
324
+ function verifyPageChecksum(
325
+ cursor: CursorBuffer,
326
+ pageHeader: PageHeader,
327
+ pageEnd: number,
328
+ context: ParquetReaderContext
329
+ ): void {
330
+ if (!context.verifyPageChecksums) return;
331
+ if (pageEnd > (cursor.size ?? cursor.buffer.length)) {
332
+ throw new Error('Parquet page extends beyond the available buffer');
333
+ }
334
+ if (pageHeader.crc === undefined) return;
335
+ const expected = pageHeader.crc >>> 0;
336
+ const actual = crc32(cursor.buffer.subarray(cursor.offset, pageEnd));
337
+ if (actual !== expected) {
338
+ throw new Error(`Parquet page checksum mismatch: expected ${expected}, calculated ${actual}`);
339
+ }
340
+ }
341
+
135
342
  /**
136
343
  * Decode parquet schema
137
344
  * @param schemaElements input schema elements data
@@ -178,31 +385,28 @@ export function decodeSchema(
178
385
  const res = decodeSchema(schemaElements, next + 1, schemaElement.num_children!);
179
386
  next = res.next;
180
387
  schema[schemaElement.name] = {
181
- // type: undefined,
182
388
  optional,
183
389
  repeated,
390
+ logicalType: decodeSchemaLogicalType(schemaElement),
391
+ fieldId: schemaElement.field_id,
184
392
  fields: res.schema
185
393
  };
186
394
  } else {
187
- const type = getThriftEnum(Type, schemaElement.type!);
188
- let logicalType = type;
189
-
190
- if (schemaElement.converted_type) {
191
- logicalType = getThriftEnum(ConvertedType, schemaElement.converted_type);
192
- }
193
-
194
- switch (logicalType) {
195
- case 'DECIMAL':
196
- logicalType = `${logicalType}_${type}` as ParquetType;
197
- break;
198
- default:
199
- }
395
+ const physicalType = getThriftEnum(Type, schemaElement.type!) as PrimitiveType;
396
+ const logicalType = decodeSchemaLogicalType(schemaElement);
397
+ const parquetType = getSchemaParquetType(schemaElement, physicalType, logicalType);
398
+ const precision = logicalType?.precision ?? schemaElement.precision;
399
+ const scale = logicalType?.scale ?? schemaElement.scale;
200
400
 
201
401
  schema[schemaElement.name] = {
202
- type: logicalType as ParquetType,
402
+ type: parquetType,
403
+ physicalType,
203
404
  typeLength: schemaElement.type_length,
204
- presision: schemaElement.precision,
205
- scale: schemaElement.scale,
405
+ presision: precision,
406
+ precision,
407
+ scale,
408
+ logicalType,
409
+ fieldId: schemaElement.field_id,
206
410
  optional,
207
411
  repeated
208
412
  };
@@ -212,6 +416,166 @@ export function decodeSchema(
212
416
  return {schema, offset, next};
213
417
  }
214
418
 
419
+ /** Decodes the parameterized Parquet LogicalType union, falling back to ConvertedType metadata. */
420
+ function decodeSchemaLogicalType(schemaElement: SchemaElement): ParquetLogicalType | undefined {
421
+ const logicalType = schemaElement.logicalType;
422
+ if (logicalType?.STRING) return {type: 'STRING'};
423
+ if (logicalType?.MAP) return {type: 'MAP'};
424
+ if (logicalType?.LIST) return {type: 'LIST'};
425
+ if (logicalType?.ENUM) return {type: 'ENUM'};
426
+ if (logicalType?.DECIMAL) {
427
+ return {
428
+ type: 'DECIMAL',
429
+ precision: logicalType.DECIMAL.precision,
430
+ scale: logicalType.DECIMAL.scale
431
+ };
432
+ }
433
+ if (logicalType?.DATE) return {type: 'DATE'};
434
+ if (logicalType?.TIME) {
435
+ return {
436
+ type: 'TIME',
437
+ unit: decodeTimeUnit(logicalType.TIME.unit),
438
+ isAdjustedToUTC: logicalType.TIME.isAdjustedToUTC
439
+ };
440
+ }
441
+ if (logicalType?.TIMESTAMP) {
442
+ return {
443
+ type: 'TIMESTAMP',
444
+ unit: decodeTimeUnit(logicalType.TIMESTAMP.unit),
445
+ isAdjustedToUTC: logicalType.TIMESTAMP.isAdjustedToUTC
446
+ };
447
+ }
448
+ if (logicalType?.INTEGER) {
449
+ const bitWidth = logicalType.INTEGER.bitWidth;
450
+ if (bitWidth !== 8 && bitWidth !== 16 && bitWidth !== 32 && bitWidth !== 64) {
451
+ throw new Error(`parquet: invalid INTEGER bit width ${bitWidth}`);
452
+ }
453
+ return {type: 'INTEGER', bitWidth, isSigned: logicalType.INTEGER.isSigned};
454
+ }
455
+ if (logicalType?.UNKNOWN) return {type: 'UNKNOWN'};
456
+ if (logicalType?.JSON) return {type: 'JSON'};
457
+ if (logicalType?.BSON) return {type: 'BSON'};
458
+ if (logicalType?.UUID) return {type: 'UUID'};
459
+ if (logicalType?.FLOAT16) return {type: 'FLOAT16'};
460
+ if (logicalType?.VARIANT) {
461
+ return {type: 'VARIANT', specificationVersion: logicalType.VARIANT.specification_version};
462
+ }
463
+ if (logicalType?.GEOMETRY) return {type: 'GEOMETRY', crs: logicalType.GEOMETRY.crs};
464
+ if (logicalType?.GEOGRAPHY) {
465
+ return {
466
+ type: 'GEOGRAPHY',
467
+ crs: logicalType.GEOGRAPHY.crs,
468
+ algorithm:
469
+ logicalType.GEOGRAPHY.algorithm === undefined
470
+ ? undefined
471
+ : getThriftEnum(EdgeInterpolationAlgorithm, logicalType.GEOGRAPHY.algorithm)
472
+ };
473
+ }
474
+
475
+ if (schemaElement.converted_type === undefined || schemaElement.converted_type === null) {
476
+ return undefined;
477
+ }
478
+ const convertedType = getThriftEnum(ConvertedType, schemaElement.converted_type);
479
+ switch (convertedType) {
480
+ case 'UTF8':
481
+ return {type: 'STRING'};
482
+ case 'MAP':
483
+ case 'MAP_KEY_VALUE':
484
+ return {type: 'MAP'};
485
+ case 'LIST':
486
+ return {type: 'LIST'};
487
+ case 'ENUM':
488
+ return {type: 'ENUM'};
489
+ case 'DECIMAL':
490
+ return {type: 'DECIMAL', precision: schemaElement.precision, scale: schemaElement.scale};
491
+ case 'DATE':
492
+ return {type: 'DATE'};
493
+ case 'TIME_MILLIS':
494
+ return {type: 'TIME', unit: 'MILLIS', isAdjustedToUTC: true};
495
+ case 'TIME_MICROS':
496
+ return {type: 'TIME', unit: 'MICROS', isAdjustedToUTC: true};
497
+ case 'TIMESTAMP_MILLIS':
498
+ return {type: 'TIMESTAMP', unit: 'MILLIS', isAdjustedToUTC: true};
499
+ case 'TIMESTAMP_MICROS':
500
+ return {type: 'TIMESTAMP', unit: 'MICROS', isAdjustedToUTC: true};
501
+ case 'UINT_8':
502
+ case 'UINT_16':
503
+ case 'UINT_32':
504
+ case 'UINT_64':
505
+ return {
506
+ type: 'INTEGER',
507
+ bitWidth: Number(convertedType.slice(5)) as 8 | 16 | 32 | 64,
508
+ isSigned: false
509
+ };
510
+ case 'INT_8':
511
+ case 'INT_16':
512
+ case 'INT_32':
513
+ case 'INT_64':
514
+ return {
515
+ type: 'INTEGER',
516
+ bitWidth: Number(convertedType.slice(4)) as 8 | 16 | 32 | 64,
517
+ isSigned: true
518
+ };
519
+ case 'JSON':
520
+ return {type: 'JSON'};
521
+ case 'BSON':
522
+ return {type: 'BSON'};
523
+ default:
524
+ return undefined;
525
+ }
526
+ }
527
+
528
+ /** Resolves one physical/logical pair to the internal Parquet value converter. */
529
+ function getSchemaParquetType(
530
+ schemaElement: SchemaElement,
531
+ physicalType: PrimitiveType,
532
+ logicalType?: ParquetLogicalType
533
+ ): ParquetType {
534
+ if (!logicalType) {
535
+ return schemaElement.converted_type === undefined || schemaElement.converted_type === null
536
+ ? physicalType
537
+ : (getThriftEnum(ConvertedType, schemaElement.converted_type) as ParquetType);
538
+ }
539
+ switch (logicalType.type) {
540
+ case 'STRING':
541
+ return 'UTF8';
542
+ case 'ENUM':
543
+ return 'ENUM';
544
+ case 'DECIMAL':
545
+ return `DECIMAL_${physicalType}` as ParquetType;
546
+ case 'DATE':
547
+ return 'DATE';
548
+ case 'TIME':
549
+ return `TIME_${logicalType.unit}` as ParquetType;
550
+ case 'TIMESTAMP':
551
+ return `TIMESTAMP_${logicalType.unit}` as ParquetType;
552
+ case 'INTEGER':
553
+ return `${logicalType.isSigned ? 'INT' : 'UINT'}_${logicalType.bitWidth}` as ParquetType;
554
+ case 'UNKNOWN':
555
+ case 'JSON':
556
+ case 'BSON':
557
+ case 'UUID':
558
+ case 'FLOAT16':
559
+ case 'VARIANT':
560
+ case 'GEOMETRY':
561
+ case 'GEOGRAPHY':
562
+ return logicalType.type;
563
+ default:
564
+ if (schemaElement.converted_type !== undefined && schemaElement.converted_type !== null) {
565
+ return getThriftEnum(ConvertedType, schemaElement.converted_type) as ParquetType;
566
+ }
567
+ return physicalType;
568
+ }
569
+ }
570
+
571
+ /** Returns the selected member of the Parquet TimeUnit union. */
572
+ function decodeTimeUnit(timeUnit: ParquetThriftTimeUnit): ParquetTimeUnit {
573
+ if (timeUnit?.MILLIS) return 'MILLIS';
574
+ if (timeUnit?.MICROS) return 'MICROS';
575
+ if (timeUnit?.NANOS) return 'NANOS';
576
+ throw new Error('parquet: TIME or TIMESTAMP logical type is missing its unit');
577
+ }
578
+
215
579
  /**
216
580
  * Decode a consecutive array of data using one of the parquet encodings
217
581
  */
@@ -221,7 +585,7 @@ function decodeValues(
221
585
  cursor: CursorBuffer,
222
586
  count: number,
223
587
  opts: ParquetCodecOptions
224
- ): any[] {
588
+ ): ParquetValueBuffer {
225
589
  if (!(encoding in PARQUET_CODECS)) {
226
590
  throw new Error(`invalid encoding: ${encoding}`);
227
591
  }
@@ -237,20 +601,19 @@ function decodeValues(
237
601
  async function decodeDataPage(
238
602
  cursor: CursorBuffer,
239
603
  header: PageHeader,
240
- context: ParquetReaderContext
604
+ context: ParquetReaderContext,
605
+ target?: ParquetPageDecodeTarget
241
606
  ): Promise<ParquetPageData> {
242
607
  const cursorEnd = cursor.offset + header.compressed_page_size;
243
- const valueCount = header.data_page_header?.num_values;
244
608
 
245
609
  /* uncompress page */
246
610
  let dataCursor = cursor;
247
611
 
248
612
  if (context.compression !== 'UNCOMPRESSED') {
249
- const valuesBuf = await decompress(
250
- context.compression,
251
- cursor.buffer.slice(cursor.offset, cursorEnd),
252
- header.uncompressed_page_size
253
- );
613
+ const compressedValues = cursor.buffer.slice(cursor.offset, cursorEnd);
614
+ const valuesBuf = context.decompressPage
615
+ ? await context.decompressPage(compressedValues, header.uncompressed_page_size)
616
+ : await decompress(context.compression, compressedValues, header.uncompressed_page_size);
254
617
  dataCursor = {
255
618
  buffer: valuesBuf,
256
619
  offset: 0,
@@ -259,44 +622,56 @@ async function decodeDataPage(
259
622
  cursor.offset = cursorEnd;
260
623
  }
261
624
 
625
+ return decodeDataPageValues(dataCursor, header, context, target);
626
+ }
627
+
628
+ /** Decodes one uncompressed Data Page V1 body without introducing an asynchronous boundary. */
629
+ function decodeDataPageValues(
630
+ dataCursor: CursorBuffer,
631
+ header: PageHeader,
632
+ context: ParquetReaderContext,
633
+ target?: ParquetPageDecodeTarget
634
+ ): ParquetPageData {
635
+ const valueCount = header.data_page_header?.num_values;
636
+
262
637
  /* read repetition levels */
263
638
  const rLevelEncoding = getThriftEnum(
264
639
  Encoding,
265
640
  header.data_page_header?.repetition_level_encoding!
266
641
  ) as ParquetCodec;
267
- // tslint:disable-next-line:prefer-array-literal
268
- let rLevels = new Array(valueCount);
269
-
270
- if (context.column.rLevelMax > 0) {
271
- rLevels = decodeValues(PARQUET_RDLVL_TYPE, rLevelEncoding, dataCursor, valueCount!, {
272
- bitWidth: getBitWidth(context.column.rLevelMax),
273
- disableEnvelope: false
274
- // column: opts.column
275
- });
276
- } else {
277
- rLevels.fill(0);
278
- }
642
+ const rLevels = decodeLevels(
643
+ dataCursor,
644
+ valueCount!,
645
+ context.column.rLevelMax,
646
+ rLevelEncoding,
647
+ false,
648
+ target?.rlevels,
649
+ target?.levelOffset
650
+ );
279
651
 
280
652
  /* read definition levels */
281
653
  const dLevelEncoding = getThriftEnum(
282
654
  Encoding,
283
655
  header.data_page_header?.definition_level_encoding!
284
656
  ) as ParquetCodec;
285
- // tslint:disable-next-line:prefer-array-literal
286
- let dLevels = new Array(valueCount);
657
+ const dLevels = decodeLevels(
658
+ dataCursor,
659
+ valueCount!,
660
+ context.column.dLevelMax,
661
+ dLevelEncoding,
662
+ false,
663
+ target?.dlevels,
664
+ target?.levelOffset
665
+ );
666
+ let valueCountNonNull = valueCount!;
287
667
  if (context.column.dLevelMax > 0) {
288
- dLevels = decodeValues(PARQUET_RDLVL_TYPE, dLevelEncoding, dataCursor, valueCount!, {
289
- bitWidth: getBitWidth(context.column.dLevelMax),
290
- disableEnvelope: false
291
- // column: opts.column
292
- });
293
- } else {
294
- dLevels.fill(0);
295
- }
296
- let valueCountNonNull = 0;
297
- for (const dlvl of dLevels) {
298
- if (dlvl === context.column.dLevelMax) {
299
- valueCountNonNull++;
668
+ valueCountNonNull = 0;
669
+ const decodedDefinitionLevels = target?.dlevels || dLevels;
670
+ const definitionLevelOffset = target?.levelOffset || 0;
671
+ for (let index = 0; index < valueCount!; index++) {
672
+ if (decodedDefinitionLevels[definitionLevelOffset + index] === context.column.dLevelMax) {
673
+ valueCountNonNull++;
674
+ }
300
675
  }
301
676
  }
302
677
 
@@ -304,7 +679,14 @@ async function decodeDataPage(
304
679
  const valueEncoding = getThriftEnum(Encoding, header.data_page_header?.encoding!) as ParquetCodec;
305
680
  const decodeOptions: ParquetCodecOptions = {
306
681
  typeLength: context.column.typeLength,
307
- bitWidth: context.column.typeLength
682
+ bitWidth: getValueBitWidth(context, valueEncoding),
683
+ retainByteArrayViews: context.retainByteArrayViews,
684
+ output: target?.values,
685
+ outputOffset: target?.valueOffset,
686
+ dictionary: isDictionaryEncoding(valueEncoding) ? target?.dictionary : undefined,
687
+ byteArrayOutput: target?.byteArrayOutput,
688
+ int64AsBigInt: shouldDecodeInt64AsBigInt(context),
689
+ int96AsTimestamp: context.int96AsTimestamp
308
690
  };
309
691
 
310
692
  const values = decodeValues(
@@ -319,6 +701,7 @@ async function decodeDataPage(
319
701
  dlevels: dLevels,
320
702
  rlevels: rLevels,
321
703
  values,
704
+ directValuesWritten: target ? valueCountNonNull : undefined,
322
705
  count: valueCount!,
323
706
  pageHeader: header
324
707
  };
@@ -334,64 +717,214 @@ async function decodeDataPage(
334
717
  async function decodeDataPageV2(
335
718
  cursor: CursorBuffer,
336
719
  header: PageHeader,
337
- context: ParquetReaderContext
720
+ context: ParquetReaderContext,
721
+ target?: ParquetPageDecodeTarget
338
722
  ): Promise<ParquetPageData> {
723
+ const dataPageHeader = header.data_page_header_v2;
724
+ if (!dataPageHeader) {
725
+ throw new Error('Missing Parquet data page v2 header');
726
+ }
339
727
  const cursorEnd = cursor.offset + header.compressed_page_size;
340
-
341
- const valueCount = header.data_page_header_v2?.num_values;
342
- // @ts-ignore
343
- const valueCountNonNull = valueCount - header.data_page_header_v2?.num_nulls;
344
- const valueEncoding = getThriftEnum(
345
- Encoding,
346
- header.data_page_header_v2?.encoding!
347
- ) as ParquetCodec;
728
+ const levelsOffset = cursor.offset;
729
+ const valueCount = dataPageHeader.num_values;
730
+ const valueCountNonNull = valueCount - dataPageHeader.num_nulls;
731
+ const valueEncoding = getThriftEnum(Encoding, dataPageHeader.encoding) as ParquetCodec;
732
+ if (
733
+ header.compressed_page_size < 0 ||
734
+ cursorEnd > (cursor.size ?? cursor.buffer.length) ||
735
+ valueCountNonNull < 0
736
+ ) {
737
+ throw new Error('Invalid Parquet data page v2 header');
738
+ }
348
739
 
349
740
  /* read repetition levels */
350
- // tslint:disable-next-line:prefer-array-literal
351
- let rLevels = new Array(valueCount);
741
+ let rLevels: number[] = [];
352
742
  if (context.column.rLevelMax > 0) {
353
- rLevels = decodeValues(PARQUET_RDLVL_TYPE, PARQUET_RDLVL_ENCODING, cursor, valueCount!, {
354
- bitWidth: getBitWidth(context.column.rLevelMax),
355
- disableEnvelope: true
356
- });
357
- } else {
743
+ const repetitionLevelCursor = createPageSliceCursor(
744
+ cursor,
745
+ levelsOffset,
746
+ dataPageHeader.repetition_levels_byte_length
747
+ );
748
+ rLevels = decodeLevels(
749
+ repetitionLevelCursor,
750
+ valueCount,
751
+ context.column.rLevelMax,
752
+ PARQUET_RDLVL_ENCODING,
753
+ true,
754
+ target?.rlevels,
755
+ target?.levelOffset
756
+ );
757
+ } else if (!target) {
758
+ rLevels = new Array(valueCount);
358
759
  rLevels.fill(0);
359
760
  }
761
+ const definitionLevelsOffset = levelsOffset + dataPageHeader.repetition_levels_byte_length;
360
762
 
361
763
  /* read definition levels */
362
- // tslint:disable-next-line:prefer-array-literal
363
- let dLevels = new Array(valueCount);
764
+ let dLevels: number[] = [];
364
765
  if (context.column.dLevelMax > 0) {
365
- dLevels = decodeValues(PARQUET_RDLVL_TYPE, PARQUET_RDLVL_ENCODING, cursor, valueCount!, {
366
- bitWidth: getBitWidth(context.column.dLevelMax),
367
- disableEnvelope: true
368
- });
369
- } else {
766
+ const definitionLevelCursor = createPageSliceCursor(
767
+ cursor,
768
+ definitionLevelsOffset,
769
+ dataPageHeader.definition_levels_byte_length
770
+ );
771
+ dLevels = decodeLevels(
772
+ definitionLevelCursor,
773
+ valueCount,
774
+ context.column.dLevelMax,
775
+ PARQUET_RDLVL_ENCODING,
776
+ true,
777
+ target?.dlevels,
778
+ target?.levelOffset
779
+ );
780
+ } else if (!target) {
781
+ dLevels = new Array(valueCount);
370
782
  dLevels.fill(0);
371
783
  }
372
784
 
373
785
  /* read values */
374
- let valuesBufCursor = cursor;
786
+ const valuesOffset = definitionLevelsOffset + dataPageHeader.definition_levels_byte_length;
787
+ const valuesCompressedByteLength = cursorEnd - valuesOffset;
788
+ const valuesUncompressedByteLength =
789
+ header.uncompressed_page_size -
790
+ dataPageHeader.repetition_levels_byte_length -
791
+ dataPageHeader.definition_levels_byte_length;
792
+ if (valuesCompressedByteLength < 0 || valuesUncompressedByteLength < 0) {
793
+ throw new Error('Invalid Parquet data page v2 level lengths');
794
+ }
795
+ let valuesBuffer = cursor.buffer.subarray(valuesOffset, cursorEnd);
796
+
797
+ if (dataPageHeader.is_compressed !== false && context.compression !== 'UNCOMPRESSED') {
798
+ valuesBuffer = context.decompressPage
799
+ ? await context.decompressPage(valuesBuffer, valuesUncompressedByteLength)
800
+ : await decompress(context.compression, valuesBuffer, valuesUncompressedByteLength);
801
+ }
802
+ cursor.offset = cursorEnd;
803
+ return decodeDataPageV2Values(
804
+ valuesBuffer,
805
+ header,
806
+ context,
807
+ target,
808
+ rLevels,
809
+ dLevels,
810
+ valueCount,
811
+ valueCountNonNull,
812
+ valueEncoding
813
+ );
814
+ }
815
+
816
+ /** Decodes one uncompressed Data Page V2 without awaiting an unused decompressor. */
817
+ function decodeUncompressedDataPageV2(
818
+ cursor: CursorBuffer,
819
+ header: PageHeader,
820
+ context: ParquetReaderContext,
821
+ target?: ParquetPageDecodeTarget
822
+ ): ParquetPageData {
823
+ const dataPageHeader = header.data_page_header_v2;
824
+ if (!dataPageHeader) {
825
+ throw new Error('Missing Parquet data page v2 header');
826
+ }
827
+ const cursorEnd = cursor.offset + header.compressed_page_size;
828
+ const levelsOffset = cursor.offset;
829
+ const valueCount = dataPageHeader.num_values;
830
+ const valueCountNonNull = valueCount - dataPageHeader.num_nulls;
831
+ const valueEncoding = getThriftEnum(Encoding, dataPageHeader.encoding) as ParquetCodec;
832
+ if (
833
+ header.compressed_page_size < 0 ||
834
+ cursorEnd > (cursor.size ?? cursor.buffer.length) ||
835
+ valueCountNonNull < 0
836
+ ) {
837
+ throw new Error('Invalid Parquet data page v2 header');
838
+ }
375
839
 
376
- if (header.data_page_header_v2?.is_compressed) {
377
- const valuesBuf = await decompress(
378
- context.compression,
379
- cursor.buffer.slice(cursor.offset, cursorEnd),
380
- header.uncompressed_page_size
840
+ let rLevels: number[] = [];
841
+ if (context.column.rLevelMax > 0) {
842
+ const repetitionLevelCursor = createPageSliceCursor(
843
+ cursor,
844
+ levelsOffset,
845
+ dataPageHeader.repetition_levels_byte_length
846
+ );
847
+ rLevels = decodeLevels(
848
+ repetitionLevelCursor,
849
+ valueCount,
850
+ context.column.rLevelMax,
851
+ PARQUET_RDLVL_ENCODING,
852
+ true,
853
+ target?.rlevels,
854
+ target?.levelOffset
381
855
  );
856
+ } else if (!target) {
857
+ rLevels = new Array(valueCount).fill(0);
858
+ }
382
859
 
383
- valuesBufCursor = {
384
- buffer: valuesBuf,
385
- offset: 0,
386
- size: valuesBuf.length
387
- };
860
+ const definitionLevelsOffset = levelsOffset + dataPageHeader.repetition_levels_byte_length;
861
+ let dLevels: number[] = [];
862
+ if (context.column.dLevelMax > 0) {
863
+ const definitionLevelCursor = createPageSliceCursor(
864
+ cursor,
865
+ definitionLevelsOffset,
866
+ dataPageHeader.definition_levels_byte_length
867
+ );
868
+ dLevels = decodeLevels(
869
+ definitionLevelCursor,
870
+ valueCount,
871
+ context.column.dLevelMax,
872
+ PARQUET_RDLVL_ENCODING,
873
+ true,
874
+ target?.dlevels,
875
+ target?.levelOffset
876
+ );
877
+ } else if (!target) {
878
+ dLevels = new Array(valueCount).fill(0);
879
+ }
388
880
 
389
- cursor.offset = cursorEnd;
881
+ const valuesOffset = definitionLevelsOffset + dataPageHeader.definition_levels_byte_length;
882
+ const valuesUncompressedByteLength =
883
+ header.uncompressed_page_size -
884
+ dataPageHeader.repetition_levels_byte_length -
885
+ dataPageHeader.definition_levels_byte_length;
886
+ if (valuesOffset > cursorEnd || valuesUncompressedByteLength < 0) {
887
+ throw new Error('Invalid Parquet data page v2 level lengths');
390
888
  }
889
+ const valuesBuffer = cursor.buffer.subarray(valuesOffset, cursorEnd);
890
+ cursor.offset = cursorEnd;
891
+ return decodeDataPageV2Values(
892
+ valuesBuffer,
893
+ header,
894
+ context,
895
+ target,
896
+ rLevels,
897
+ dLevels,
898
+ valueCount,
899
+ valueCountNonNull,
900
+ valueEncoding
901
+ );
902
+ }
903
+
904
+ /** Decodes a prepared Data Page V2 value section without an asynchronous boundary. */
905
+ function decodeDataPageV2Values(
906
+ valuesBuffer: Uint8Array,
907
+ header: PageHeader,
908
+ context: ParquetReaderContext,
909
+ target: ParquetPageDecodeTarget | undefined,
910
+ rLevels: number[],
911
+ dLevels: number[],
912
+ valueCount: number,
913
+ valueCountNonNull: number,
914
+ valueEncoding: ParquetCodec
915
+ ): ParquetPageData {
916
+ const valuesBufCursor = {buffer: valuesBuffer, offset: 0, size: valuesBuffer.length};
391
917
 
392
918
  const decodeOptions = {
393
919
  typeLength: context.column.typeLength,
394
- bitWidth: context.column.typeLength
920
+ bitWidth: getValueBitWidth(context, valueEncoding),
921
+ retainByteArrayViews: context.retainByteArrayViews,
922
+ output: target?.values,
923
+ outputOffset: target?.valueOffset,
924
+ dictionary: isDictionaryEncoding(valueEncoding) ? target?.dictionary : undefined,
925
+ byteArrayOutput: target?.byteArrayOutput,
926
+ int64AsBigInt: shouldDecodeInt64AsBigInt(context),
927
+ int96AsTimestamp: context.int96AsTimestamp
395
928
  };
396
929
 
397
930
  const values = decodeValues(
@@ -406,11 +939,234 @@ async function decodeDataPageV2(
406
939
  dlevels: dLevels,
407
940
  rlevels: rLevels,
408
941
  values,
409
- count: valueCount!,
942
+ directValuesWritten: target ? valueCountNonNull : undefined,
943
+ count: valueCount,
410
944
  pageHeader: header
411
945
  };
412
946
  }
413
947
 
948
+ /** Decodes repetition or definition levels into an optional column-level destination. */
949
+ function decodeLevels(
950
+ cursor: CursorBuffer,
951
+ count: number,
952
+ levelMax: number,
953
+ encoding: ParquetCodec,
954
+ disableEnvelope: boolean,
955
+ output?: ParquetLevelBuffer,
956
+ outputOffset = 0
957
+ ): number[] {
958
+ if (levelMax === 0) {
959
+ return output ? [] : new Array<number>(count).fill(0);
960
+ }
961
+ const levels = decodeValues(PARQUET_RDLVL_TYPE, encoding, cursor, count, {
962
+ bitWidth: getBitWidth(levelMax),
963
+ disableEnvelope,
964
+ output,
965
+ outputOffset
966
+ }) as number[];
967
+ return output ? [] : levels;
968
+ }
969
+
970
+ /**
971
+ * Allocates a compact Arrow-compatible destination for supported uncompressed byte pages.
972
+ *
973
+ * Scanning only the small Thrift page headers avoids committing to the fast path when a column
974
+ * mixes in an encoding that still requires materialized values. The page buffer is a useful
975
+ * initial capacity; the destination grows for prefix-reconstructed delta values when necessary.
976
+ */
977
+ function createArrowByteArrayOutput(
978
+ buffer: Uint8Array,
979
+ context: ParquetReaderContext,
980
+ valueCapacity: number
981
+ ): ParquetByteArrayOutput | undefined {
982
+ if (
983
+ !context.useArrowByteArrayBuffers ||
984
+ context.compression !== 'UNCOMPRESSED' ||
985
+ !supportsArrowByteArrayOutput(context.column) ||
986
+ valueCapacity === 0
987
+ ) {
988
+ return undefined;
989
+ }
990
+ if (
991
+ !context.hasOnlyArrowByteArrayDataPages &&
992
+ !hasOnlyArrowByteArrayDataPages(buffer, valueCapacity)
993
+ ) {
994
+ return undefined;
995
+ }
996
+ return {
997
+ data:
998
+ context.column.primitiveType === 'FIXED_LEN_BYTE_ARRAY'
999
+ ? new Uint8Array(0)
1000
+ : new Uint8Array(Math.max(1, buffer.byteLength)),
1001
+ valueOffsets: new Int32Array(valueCapacity + 1),
1002
+ byteLength: 0
1003
+ };
1004
+ }
1005
+
1006
+ /** Returns whether a BYTE_ARRAY field maps directly to Arrow Utf8 or Binary without conversion. */
1007
+ function supportsArrowByteArrayOutput(column: ParquetReaderContext['column']): boolean {
1008
+ if (column.primitiveType !== 'BYTE_ARRAY' && column.primitiveType !== 'FIXED_LEN_BYTE_ARRAY') {
1009
+ return false;
1010
+ }
1011
+ if (column.logicalType) {
1012
+ return (
1013
+ column.logicalType.type === 'STRING' ||
1014
+ column.logicalType.type === 'ENUM' ||
1015
+ column.logicalType.type === 'JSON' ||
1016
+ column.logicalType.type === 'BSON' ||
1017
+ column.logicalType.type === 'VARIANT' ||
1018
+ column.logicalType.type === 'GEOMETRY' ||
1019
+ column.logicalType.type === 'GEOGRAPHY'
1020
+ );
1021
+ }
1022
+ return (
1023
+ !column.originalType ||
1024
+ column.originalType === 'UTF8' ||
1025
+ column.originalType === 'ENUM' ||
1026
+ column.originalType === 'JSON' ||
1027
+ column.originalType === 'BSON' ||
1028
+ column.originalType === 'INTERVAL'
1029
+ );
1030
+ }
1031
+
1032
+ /** Returns whether a complete column buffer contains only direct Arrow byte-array data pages. */
1033
+ function hasOnlyArrowByteArrayDataPages(buffer: Uint8Array, expectedLevelCount: number): boolean {
1034
+ let offset = 0;
1035
+ let levelCount = 0;
1036
+ while (offset < buffer.byteLength && levelCount < expectedLevelCount) {
1037
+ const {pageHeader, length} = decodePageHeader(buffer, offset);
1038
+ const pageType = getThriftEnum(PageType, pageHeader.type);
1039
+ if (pageType !== 'DATA_PAGE' && pageType !== 'DATA_PAGE_V2') {
1040
+ return false;
1041
+ }
1042
+ const encoding = getThriftEnum(
1043
+ Encoding,
1044
+ pageHeader.data_page_header?.encoding ?? pageHeader.data_page_header_v2?.encoding!
1045
+ );
1046
+ if (
1047
+ encoding !== 'PLAIN' &&
1048
+ encoding !== 'DELTA_LENGTH_BYTE_ARRAY' &&
1049
+ encoding !== 'DELTA_BYTE_ARRAY'
1050
+ ) {
1051
+ return false;
1052
+ }
1053
+ const valueCount =
1054
+ pageHeader.data_page_header?.num_values ?? pageHeader.data_page_header_v2?.num_values;
1055
+ if (valueCount === undefined || valueCount < 0) {
1056
+ return false;
1057
+ }
1058
+ levelCount += valueCount;
1059
+ offset += length + pageHeader.compressed_page_size;
1060
+ if (offset > buffer.byteLength) {
1061
+ return false;
1062
+ }
1063
+ }
1064
+ return levelCount === expectedLevelCount;
1065
+ }
1066
+
1067
+ /** Allocates compact unsigned storage for repetition and definition levels. */
1068
+ function createParquetLevelBuffer(
1069
+ context: ParquetReaderContext,
1070
+ capacity: number,
1071
+ levelMax: number
1072
+ ): ParquetLevelBuffer {
1073
+ if (context.useTypedLevelBuffers && levelMax === 0) {
1074
+ // Required flat columns have no encoded levels. Avoid allocating two row-sized zero buffers
1075
+ // that neither direct Arrow construction nor level decoding will inspect.
1076
+ return EMPTY_PARQUET_LEVEL_BUFFER;
1077
+ }
1078
+ if (!context.useTypedLevelBuffers || capacity === 0) {
1079
+ return levelMax > 0 ? new Array<number>(capacity) : new Array<number>(capacity).fill(0);
1080
+ }
1081
+ if (levelMax <= 0xff) {
1082
+ return new Uint8Array(capacity);
1083
+ }
1084
+ if (levelMax <= 0xffff) {
1085
+ return new Uint16Array(capacity);
1086
+ }
1087
+ return new Uint32Array(capacity);
1088
+ }
1089
+
1090
+ /** Restricts an overallocated level buffer to the number of decoded levels. */
1091
+ function trimParquetLevelBuffer(levels: ParquetLevelBuffer, length: number): ParquetLevelBuffer {
1092
+ if (Array.isArray(levels)) {
1093
+ levels.length = length;
1094
+ return levels;
1095
+ }
1096
+ if (levels.length === 0 || levels.length === length) return levels;
1097
+ return levels.subarray(0, length) as ParquetLevelBuffer;
1098
+ }
1099
+
1100
+ /** Returns whether an encoding stores RLE dictionary indices instead of physical values. */
1101
+ function isDictionaryEncoding(encoding: ParquetCodec): boolean {
1102
+ return encoding === 'PLAIN_DICTIONARY' || encoding === 'RLE_DICTIONARY';
1103
+ }
1104
+
1105
+ /** Preserves exact physical signed INT64 values in every output shape. */
1106
+ function shouldDecodeInt64AsBigInt(context: ParquetReaderContext): boolean {
1107
+ return context.column.primitiveType === 'INT64';
1108
+ }
1109
+
1110
+ /** Allocates the narrowest lossless column buffer supported by the current JavaScript decoder. */
1111
+ function createParquetColumnValueBuffer(
1112
+ context: ParquetReaderContext,
1113
+ capacity: number
1114
+ ): ParquetValueBuffer {
1115
+ if (!context.useTypedValueBuffers || capacity === 0) {
1116
+ return new Array<unknown>(capacity);
1117
+ }
1118
+ switch (context.column.primitiveType) {
1119
+ case 'BOOLEAN':
1120
+ return new Uint8Array(capacity);
1121
+ case 'INT32':
1122
+ return new Int32Array(capacity);
1123
+ case 'INT64':
1124
+ return new BigInt64Array(capacity);
1125
+ case 'INT96':
1126
+ return context.int96AsTimestamp ? new BigInt64Array(capacity) : new Float64Array(capacity);
1127
+ case 'DOUBLE':
1128
+ return new Float64Array(capacity);
1129
+ case 'FLOAT':
1130
+ return new Float32Array(capacity);
1131
+ default:
1132
+ return new Array<unknown>(capacity);
1133
+ }
1134
+ }
1135
+
1136
+ /** Restricts an overallocated typed column buffer to its decoded non-null values. */
1137
+ function trimParquetValueBuffer(values: ParquetValueBuffer, length: number): ParquetValueBuffer {
1138
+ if (Array.isArray(values)) {
1139
+ values.length = length;
1140
+ return values;
1141
+ }
1142
+ return values.subarray(0, length) as ParquetValueBuffer;
1143
+ }
1144
+
1145
+ /** Returns the physical value bit width required by encodings such as RLE BOOLEAN. */
1146
+ function getValueBitWidth(
1147
+ context: ParquetReaderContext,
1148
+ encoding: ParquetCodec
1149
+ ): number | undefined {
1150
+ if (encoding === 'RLE' && context.column.primitiveType === 'BOOLEAN') {
1151
+ return 1;
1152
+ }
1153
+ return context.column.typeLength;
1154
+ }
1155
+
1156
+ /** Creates a bounded cursor over one uncompressed data page v2 level section. */
1157
+ function createPageSliceCursor(
1158
+ cursor: CursorBuffer,
1159
+ offset: number,
1160
+ byteLength: number
1161
+ ): CursorBuffer {
1162
+ const end = offset + byteLength;
1163
+ if (byteLength < 0 || end > (cursor.size ?? cursor.buffer.length)) {
1164
+ throw new Error('Invalid Parquet data page v2 level lengths');
1165
+ }
1166
+ const buffer = cursor.buffer.subarray(offset, end);
1167
+ return {buffer, offset: 0, size: buffer.length};
1168
+ }
1169
+
414
1170
  /**
415
1171
  * Do decoding of dictionary page which helps to iterate over all indexes and get dataPage values.
416
1172
  * @param cursor
@@ -433,11 +1189,10 @@ async function decodeDictionaryPage(
433
1189
  cursor.offset = cursorEnd;
434
1190
 
435
1191
  if (context.compression !== 'UNCOMPRESSED') {
436
- const valuesBuf = await decompress(
437
- context.compression,
438
- dictCursor.buffer.slice(dictCursor.offset, cursorEnd),
439
- pageHeader.uncompressed_page_size
440
- );
1192
+ const compressedValues = dictCursor.buffer.subarray(dictCursor.offset);
1193
+ const valuesBuf = context.decompressPage
1194
+ ? await context.decompressPage(compressedValues, pageHeader.uncompressed_page_size)
1195
+ : await decompress(context.compression, compressedValues, pageHeader.uncompressed_page_size);
441
1196
 
442
1197
  dictCursor = {
443
1198
  buffer: valuesBuf,
@@ -448,34 +1203,58 @@ async function decodeDictionaryPage(
448
1203
  cursor.offset = cursorEnd;
449
1204
  }
450
1205
 
1206
+ return decodeDictionaryValues(dictCursor, pageHeader, context);
1207
+ }
1208
+
1209
+ /** Decodes an uncompressed dictionary page directly from a view of the column chunk. */
1210
+ function decodeUncompressedDictionaryPage(
1211
+ cursor: CursorBuffer,
1212
+ pageHeader: PageHeader,
1213
+ context: ParquetReaderContext
1214
+ ): (string | ArrayBuffer)[] {
1215
+ const cursorEnd = cursor.offset + pageHeader.compressed_page_size;
1216
+ if (cursorEnd > (cursor.size ?? cursor.buffer.length)) {
1217
+ throw new Error('Parquet dictionary page exceeds the available buffer');
1218
+ }
1219
+ const dictionaryCursor: CursorBuffer = {
1220
+ buffer: cursor.buffer.subarray(cursor.offset, cursorEnd),
1221
+ offset: 0,
1222
+ size: pageHeader.compressed_page_size
1223
+ };
1224
+ cursor.offset = cursorEnd;
1225
+ return decodeDictionaryValues(dictionaryCursor, pageHeader, context);
1226
+ }
1227
+
1228
+ /** Decodes one dictionary body from its current cursor without copying uncompressed page bytes. */
1229
+ function decodeDictionaryValues(
1230
+ dictionaryCursor: CursorBuffer,
1231
+ pageHeader: PageHeader,
1232
+ context: ParquetReaderContext
1233
+ ): (string | ArrayBuffer)[] {
451
1234
  const numValues = pageHeader?.dictionary_page_header?.num_values || 0;
1235
+ const declaredEncoding = getThriftEnum(
1236
+ Encoding,
1237
+ pageHeader.dictionary_page_header?.encoding!
1238
+ ) as ParquetCodec;
1239
+ // Some established writers put the data-page dictionary encoding in this field even though
1240
+ // dictionary values themselves use PLAIN. Preserve compatibility with those files.
1241
+ const dictionaryValueEncoding =
1242
+ declaredEncoding === 'PLAIN_DICTIONARY' || declaredEncoding === 'RLE_DICTIONARY'
1243
+ ? 'PLAIN'
1244
+ : declaredEncoding;
452
1245
 
453
1246
  const decodedDictionaryValues = decodeValues(
454
1247
  context.column.primitiveType!,
455
- context.column.encoding!,
456
- dictCursor,
1248
+ dictionaryValueEncoding,
1249
+ dictionaryCursor,
457
1250
  numValues,
458
- // TODO - this looks wrong?
459
- context as ParquetCodecOptions
1251
+ {
1252
+ ...context,
1253
+ typeLength: context.column.typeLength,
1254
+ int64AsBigInt: shouldDecodeInt64AsBigInt(context),
1255
+ int96AsTimestamp: context.int96AsTimestamp
1256
+ } as ParquetCodecOptions
460
1257
  );
461
1258
 
462
- // Makes it look a little easier
463
- let values: any[];
464
- if (context?.preserveBinary) {
465
- values = decodedDictionaryValues.map((d) => preserveBinary(d));
466
- } else {
467
- values = decodedDictionaryValues.map((d) => d.toString());
468
- }
469
- return values;
470
- }
471
-
472
- function preserveBinary(d: any): ArrayBuffer | ArrayBufferView | string {
473
- if (ArrayBuffer.isView(d)) {
474
- return d;
475
- }
476
- // Convert to ArrayBuffer
477
- if (Buffer.isBuffer(d)) {
478
- return new Uint8Array(d.buffer, d.byteOffset, d.byteLength).slice().buffer;
479
- }
480
- return d.toString();
1259
+ return decodedDictionaryValues as (string | ArrayBuffer)[];
481
1260
  }