@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
@@ -4,11 +4,46 @@
4
4
  // Copyright (c) 2017 ironSource Ltd.
5
5
  // Forked from https://github.com/kbajalc/parquets under MIT license
6
6
  import { ParquetSchema } from "../schema/schema.js";
7
- import { decodeSchema, decodeDataPages, decodePage } from "./decoders.js";
7
+ import { decodeSchema, decodeDataPages, decodePage, decodeUncompressedDataPages, decodeUncompressedDictionaryBuffer } from "./decoders.js";
8
+ import { scanParquetEncodedPages } from "./encoded-pages.js";
8
9
  import { materializeRows } from "../schema/shred.js";
10
+ import { createParquetPageDecompressor } from "../compression.js";
9
11
  import { PARQUET_MAGIC, PARQUET_MAGIC_ENCRYPTED } from "../../lib/constants.js";
10
- import { CompressionCodec, Type } from "../parquet-thrift/index.js";
11
- import { decodeFileMetadata, getThriftEnum, fieldIndexOf } from "../utils/read-utils.js";
12
+ import { CompressionCodec, Encoding, PageType, Type } from "../parquet-thrift/index.js";
13
+ import { decodeColumnMetadata, decodeFileCryptoMetadata, decodeFileMetadata, decodePageHeader, getThriftEnum, fieldIndexOf, serializeThrift } from "../utils/read-utils.js";
14
+ import { decodeString, readUInt32LE, toUint8Array } from "../utils/binary-utils.js";
15
+ import { CompactInt64 } from "../utils/uint8-array-compact-protocol.js";
16
+ import { createParquetModuleAad, decryptParquetModule, readParquetEncryptedModule, verifyParquetFooterSignature } from "../../lib/parquet-encryption.js";
17
+ /** Bounds concurrent range requests when a row group contains unusually many selected columns. */
18
+ const MAXIMUM_CONCURRENT_COLUMN_READS = 16;
19
+ /**
20
+ * Returns whether column metadata guarantees that every data page can decode directly into an
21
+ * Arrow-compatible byte buffer. Level encodings are included in the metadata encoding set and do
22
+ * not prevent the byte-array fast path.
23
+ */
24
+ function hasOnlyArrowByteArrayDataPageEncodings(encodings, dictionaryPageOffset) {
25
+ if (dictionaryPageOffset !== undefined || encodings.length === 0) {
26
+ return false;
27
+ }
28
+ for (const encoding of encodings) {
29
+ if (encoding !== Encoding.PLAIN &&
30
+ encoding !== Encoding.DELTA_LENGTH_BYTE_ARRAY &&
31
+ encoding !== Encoding.DELTA_BYTE_ARRAY &&
32
+ encoding !== Encoding.RLE &&
33
+ encoding !== Encoding.BIT_PACKED) {
34
+ return false;
35
+ }
36
+ }
37
+ return true;
38
+ }
39
+ /** Returns the algorithm name represented by the Thrift encryption union. */
40
+ function getEncryptionAlgorithm(value) {
41
+ if (value.AES_GCM_V1)
42
+ return 'AES_GCM_V1';
43
+ if (value.AES_GCM_CTR_V1)
44
+ return 'AES_GCM_CTR_V1';
45
+ throw new Error('Unsupported Parquet encryption algorithm');
46
+ }
12
47
  /**
13
48
  * The parquet envelope reader allows direct, unbuffered access to the individual
14
49
  * sections of the parquet file, namely the header, footer and the row groups.
@@ -19,19 +54,118 @@ export class ParquetReader {
19
54
  static defaultProps = {
20
55
  // max ArrayBuffer size in js is 2Gb
21
56
  defaultDictionarySize: 2147483648,
22
- preserveBinary: false
57
+ preserveBinary: false,
58
+ retainByteArrayViews: false,
59
+ useTypedValueBuffers: false,
60
+ useTypedLevelBuffers: false,
61
+ useArrowByteArrayBuffers: false,
62
+ verifyPageChecksums: false,
63
+ int96AsTimestamp: false,
64
+ verifyFooterSignature: true,
65
+ signal: undefined,
66
+ keyRetriever: undefined,
67
+ aadPrefix: undefined,
68
+ encryptionContext: undefined
23
69
  };
24
70
  props;
25
71
  file;
26
72
  metadata = null;
73
+ /** Parsed Parquet schema shared by metadata, iteration, and materialization paths. */
74
+ schema = null;
75
+ /** Encryption parameters decoded from plaintext or encrypted footer metadata. */
76
+ encryptionContext;
77
+ /** Resolved keys shared by encrypted modules in this reader instance. */
78
+ encryptionKeyCache = new Map();
79
+ /** Compression backends selected once and shared by every page in this reader. */
80
+ pageDecompressors = new Map();
27
81
  constructor(file, props) {
28
82
  this.file = file;
29
83
  this.props = { ...ParquetReader.defaultProps, ...props };
84
+ this.encryptionContext = this.props.encryptionContext;
85
+ }
86
+ /** Whether the decoded footer describes an encrypted Parquet file. */
87
+ get encrypted() {
88
+ return Boolean(this.encryptionContext);
89
+ }
90
+ /** Whether this reader decodes legacy INT96 values as epoch nanoseconds. */
91
+ get int96AsTimestamp() {
92
+ return this.props.int96AsTimestamp;
93
+ }
94
+ /** Returns a cloneable snapshot of the file encryption context for worker decoding. */
95
+ getEncryptionContextForWorker() {
96
+ const encryptionContext = this.encryptionContext;
97
+ if (!encryptionContext)
98
+ return undefined;
99
+ return {
100
+ algorithm: encryptionContext.algorithm,
101
+ aadPrefix: encryptionContext.aadPrefix && new Uint8Array(encryptionContext.aadPrefix),
102
+ fileUnique: new Uint8Array(encryptionContext.fileUnique),
103
+ footerKeyMetadata: encryptionContext.footerKeyMetadata && new Uint8Array(encryptionContext.footerKeyMetadata)
104
+ };
105
+ }
106
+ /** Resolves one column key on the caller thread before transferring encrypted ranges. */
107
+ async getColumnKeyForWorker(columnChunk, rowGroupOrdinal, columnOrdinal) {
108
+ if (!this.encryptionContext || !this.props.keyRetriever) {
109
+ throw new Error('Encrypted Parquet worker reads require parquet.keyRetriever');
110
+ }
111
+ const keyMetadata = this.getColumnKeyMetadata(columnChunk);
112
+ const keyMaterial = await this.props.keyRetriever(keyMetadata, {
113
+ algorithm: this.encryptionContext.algorithm,
114
+ aad: createParquetModuleAad(this.encryptionContext.aadPrefix, this.encryptionContext.fileUnique, 'data-page', rowGroupOrdinal, columnOrdinal, 0)
115
+ });
116
+ const keyBytes = keyMaterial instanceof ArrayBuffer
117
+ ? new Uint8Array(keyMaterial)
118
+ : new Uint8Array(keyMaterial.buffer, keyMaterial.byteOffset, keyMaterial.byteLength);
119
+ return { keyMetadata, keyMaterial: keyBytes };
30
120
  }
31
121
  close() {
122
+ this.encryptionKeyCache.clear();
123
+ this.pageDecompressors.clear();
32
124
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
33
125
  this.file.close();
34
126
  }
127
+ /** Returns the reader-scoped decoder for one Parquet compression method. */
128
+ getPageDecompressor(compression) {
129
+ let decompressor = this.pageDecompressors.get(compression);
130
+ if (!decompressor) {
131
+ decompressor = createParquetPageDecompressor(compression);
132
+ this.pageDecompressors.set(compression, decompressor);
133
+ }
134
+ return decompressor;
135
+ }
136
+ /** Reads a byte range, retaining a zero-copy view when the complete file is already in memory. */
137
+ async readBytes(start, length, signal) {
138
+ const effectiveSignal = signal ?? this.props.signal;
139
+ if (effectiveSignal?.aborted) {
140
+ throw new Error('Request aborted');
141
+ }
142
+ if (this.file.handle instanceof ArrayBuffer) {
143
+ return new Uint8Array(this.file.handle, start, length);
144
+ }
145
+ return toUint8Array(await this.file.read(start, length, effectiveSignal));
146
+ }
147
+ /** Returns a reader-scoped key resolver that avoids repeating key-provider work per module. */
148
+ getCachedKeyRetriever() {
149
+ const keyRetriever = this.props.keyRetriever;
150
+ if (!keyRetriever) {
151
+ throw new Error('Encrypted Parquet requires parquet.keyRetriever');
152
+ }
153
+ return (keyMetadata, context) => {
154
+ const encryptionContext = this.encryptionContext;
155
+ const cacheKey = createEncryptionKeyCacheKey(context.algorithm, keyMetadata, context.aad, encryptionContext?.aadPrefix?.byteLength ?? this.props.aadPrefix?.byteLength, encryptionContext?.fileUnique.byteLength);
156
+ let keyPromise = this.encryptionKeyCache.get(cacheKey);
157
+ if (!keyPromise) {
158
+ keyPromise = Promise.resolve().then(() => keyRetriever(keyMetadata, context));
159
+ this.encryptionKeyCache.set(cacheKey, keyPromise);
160
+ void keyPromise.catch(() => {
161
+ if (this.encryptionKeyCache.get(cacheKey) === keyPromise) {
162
+ this.encryptionKeyCache.delete(cacheKey);
163
+ }
164
+ });
165
+ }
166
+ return keyPromise;
167
+ };
168
+ }
35
169
  // HIGH LEVEL METHODS
36
170
  /** Yield one row at a time */
37
171
  async *rowIterator(props) {
@@ -52,25 +186,30 @@ export class ParquetReader {
52
186
  /** Iterate over the raw row groups */
53
187
  async *rowGroupIterator(props) {
54
188
  // Ensure strings are nested in arrays
55
- const columnList = (props?.columnList || []).map((x) => Array.isArray(x) ? x : [x]);
56
- const metadata = await this.getFileMetadata();
57
- const schema = await this.getSchema();
189
+ const columnList = (props?.columnList || []).map(x => (Array.isArray(x) ? x : [x]));
190
+ const metadata = await this.getFileMetadata(props?.signal);
191
+ const schema = await this.getSchema(props?.signal);
58
192
  const rowGroupCount = metadata?.row_groups.length || 0;
59
- for (let rowGroupIndex = 0; rowGroupIndex < rowGroupCount; rowGroupIndex++) {
60
- const rowGroup = await this.readRowGroup(schema, metadata.row_groups[rowGroupIndex], columnList);
193
+ const rowGroupIndices = props?.rowGroups || Array.from({ length: rowGroupCount }, (_, index) => index);
194
+ for (const rowGroupIndex of rowGroupIndices) {
195
+ if (!Number.isInteger(rowGroupIndex) || rowGroupIndex < 0 || rowGroupIndex >= rowGroupCount) {
196
+ throw new Error(`Invalid Parquet row-group index ${rowGroupIndex}`);
197
+ }
198
+ const rowGroup = await this.readRowGroup(schema, metadata.row_groups[rowGroupIndex], columnList, props?.signal, rowGroupIndex);
61
199
  yield rowGroup;
62
200
  }
63
201
  }
64
- async getRowCount() {
65
- const metadata = await this.getFileMetadata();
202
+ async getRowCount(signal) {
203
+ const metadata = await this.getFileMetadata(signal);
66
204
  return Number(metadata.num_rows);
67
205
  }
68
- async getSchema() {
69
- const metadata = await this.getFileMetadata();
70
- const root = metadata.schema[0];
71
- const { schema: schemaDefinition } = decodeSchema(metadata.schema, 1, root.num_children);
72
- const schema = new ParquetSchema(schemaDefinition);
73
- return schema;
206
+ async getSchema(signal) {
207
+ this.schema ||= this.getFileMetadata(signal).then(metadata => {
208
+ const root = metadata.schema[0];
209
+ const { schema: schemaDefinition } = decodeSchema(metadata.schema, 1, root.num_children);
210
+ return new ParquetSchema(schemaDefinition);
211
+ });
212
+ return await this.schema;
74
213
  }
75
214
  /**
76
215
  * Returns the user (key/value) metadata for this file
@@ -84,106 +223,655 @@ export class ParquetReader {
84
223
  }
85
224
  return md;
86
225
  }
87
- async getFileMetadata() {
226
+ async getFileMetadata(signal) {
88
227
  if (!this.metadata) {
89
- await this.readHeader();
90
- this.metadata = this.readFooter();
228
+ await this.readHeader(signal);
229
+ this.metadata = this.readFooter(signal);
91
230
  }
92
231
  return this.metadata;
93
232
  }
94
233
  // LOW LEVEL METHODS
95
234
  /** Metadata is stored in the footer */
96
- async readHeader() {
97
- const arrayBuffer = await this.file.read(0, PARQUET_MAGIC.length);
98
- const buffer = Buffer.from(arrayBuffer);
99
- const magic = buffer.toString();
235
+ async readHeader(signal) {
236
+ const magic = decodeString(await this.readBytes(0, PARQUET_MAGIC.length, signal));
100
237
  switch (magic) {
101
238
  case PARQUET_MAGIC:
102
239
  break;
103
240
  case PARQUET_MAGIC_ENCRYPTED:
104
- throw new Error('Encrypted parquet file not supported');
241
+ break;
105
242
  default:
106
243
  throw new Error(`Invalid parquet file (magic=${magic})`);
107
244
  }
108
245
  }
109
246
  /** Metadata is stored in the footer */
110
- async readFooter() {
247
+ async readFooter(signal) {
111
248
  const trailerLen = PARQUET_MAGIC.length + 4;
112
- const arrayBuffer = await this.file.read(this.file.size - trailerLen, trailerLen);
113
- const trailerBuf = Buffer.from(arrayBuffer);
114
- const magic = trailerBuf.slice(4).toString();
249
+ const trailer = await this.readBytes(this.file.size - trailerLen, trailerLen, signal);
250
+ const magic = decodeString(trailer, 4);
251
+ const metadataSize = readUInt32LE(trailer, 0);
252
+ const metadataOffset = this.file.size - metadataSize - trailerLen;
253
+ if (magic === PARQUET_MAGIC_ENCRYPTED) {
254
+ return await this.readEncryptedFooter(metadataSize, metadataOffset, signal);
255
+ }
115
256
  if (magic !== PARQUET_MAGIC) {
116
257
  throw new Error(`Not a valid parquet file (magic="${magic})`);
117
258
  }
118
- const metadataSize = trailerBuf.readUInt32LE(0);
119
- const metadataOffset = this.file.size - metadataSize - trailerLen;
120
259
  if (metadataOffset < PARQUET_MAGIC.length) {
121
260
  throw new Error(`Invalid metadata size ${metadataOffset}`);
122
261
  }
123
- const arrayBuffer2 = await this.file.read(metadataOffset, metadataSize);
124
- const metadataBuf = Buffer.from(arrayBuffer2);
262
+ const metadataBuf = await this.readBytes(metadataOffset, metadataSize, signal);
125
263
  // let metadata = new parquet_thrift.FileMetaData();
126
264
  // parquet_util.decodeThrift(metadata, metadataBuf);
127
- const { metadata } = decodeFileMetadata(metadataBuf);
265
+ const decoded = decodeFileMetadata(metadataBuf);
266
+ const { metadata } = decoded;
267
+ this.setEncryptionContext(metadata);
268
+ if (this.props.verifyFooterSignature && this.encryptionContext?.footerSigningKeyMetadata) {
269
+ // The compact-protocol decoder may consume bytes from the signature that
270
+ // happen to look like valid Thrift fields. The format defines the
271
+ // signature as the final fixed 28 bytes of the footer range, so use the
272
+ // physical boundary rather than the decoder's consumed length.
273
+ const signatureOffset = metadataBuf.byteLength - 28;
274
+ if (signatureOffset < decoded.length) {
275
+ throw new Error('Invalid Parquet plaintext-footer signature boundary');
276
+ }
277
+ const signature = metadataBuf.subarray(signatureOffset);
278
+ const encryptionContext = this.encryptionContext;
279
+ if (!this.props.keyRetriever) {
280
+ throw new Error('Signed Parquet footer requires parquet.keyRetriever');
281
+ }
282
+ await verifyParquetFooterSignature(metadataBuf.subarray(0, signatureOffset), signature, {
283
+ algorithm: encryptionContext.algorithm,
284
+ aad: createParquetModuleAad(encryptionContext.aadPrefix, encryptionContext.fileUnique, 'footer'),
285
+ keyMetadata: encryptionContext.footerSigningKeyMetadata,
286
+ keyRetriever: this.getCachedKeyRetriever()
287
+ });
288
+ }
289
+ return metadata;
290
+ }
291
+ /** Reads and decrypts an encrypted footer after the standard trailer. */
292
+ async readEncryptedFooter(metadataSize, metadataOffset, signal) {
293
+ if (!this.props.keyRetriever) {
294
+ throw new Error('Encrypted Parquet footer requires parquet.keyRetriever');
295
+ }
296
+ const encryptedFooter = await this.readBytes(metadataOffset, metadataSize, signal);
297
+ const cryptoMetadata = decodeFileCryptoMetadata(encryptedFooter);
298
+ const algorithm = getEncryptionAlgorithm(cryptoMetadata.metadata.encryption_algorithm);
299
+ const algorithmMetadata = cryptoMetadata.metadata.encryption_algorithm.AES_GCM_V1 ||
300
+ cryptoMetadata.metadata.encryption_algorithm.AES_GCM_CTR_V1;
301
+ const aadPrefix = algorithmMetadata?.aad_prefix || this.props.aadPrefix;
302
+ if (!algorithmMetadata?.aad_file_unique) {
303
+ throw new Error('Encrypted Parquet footer is missing aad_file_unique');
304
+ }
305
+ const aad = createParquetModuleAad(aadPrefix, algorithmMetadata.aad_file_unique, 'footer');
306
+ const plaintext = await decryptParquetModule(encryptedFooter.subarray(cryptoMetadata.length), {
307
+ algorithm,
308
+ aad,
309
+ keyMetadata: cryptoMetadata.metadata.key_metadata,
310
+ keyRetriever: this.getCachedKeyRetriever()
311
+ });
312
+ this.encryptionContext = {
313
+ algorithm,
314
+ aadPrefix,
315
+ fileUnique: algorithmMetadata.aad_file_unique,
316
+ footerKeyMetadata: cryptoMetadata.metadata.key_metadata
317
+ };
318
+ const metadata = decodeFileMetadata(plaintext).metadata;
319
+ return metadata;
320
+ }
321
+ /** Records the encryption parameters exposed by plaintext-footer files. */
322
+ setEncryptionContext(metadata) {
323
+ const encryptionAlgorithm = metadata.encryption_algorithm;
324
+ if (!encryptionAlgorithm)
325
+ return;
326
+ const algorithm = getEncryptionAlgorithm(encryptionAlgorithm);
327
+ const algorithmMetadata = encryptionAlgorithm.AES_GCM_V1 || encryptionAlgorithm.AES_GCM_CTR_V1;
328
+ if (!algorithmMetadata?.aad_file_unique) {
329
+ throw new Error('Encrypted Parquet footer is missing aad_file_unique');
330
+ }
331
+ this.encryptionContext = {
332
+ algorithm,
333
+ aadPrefix: algorithmMetadata.aad_prefix || this.props.aadPrefix,
334
+ fileUnique: algorithmMetadata.aad_file_unique,
335
+ footerSigningKeyMetadata: metadata.footer_signing_key_metadata
336
+ };
337
+ }
338
+ /** Resolves only the selected encrypted columns, using crypto metadata paths before decryption. */
339
+ async resolveColumnMetadata(rowGroup, rowGroupOrdinal, selectedColumnPaths) {
340
+ for (let columnOrdinal = 0; columnOrdinal < rowGroup.columns.length; columnOrdinal++) {
341
+ const columnChunk = rowGroup.columns[columnOrdinal];
342
+ const path = getColumnChunkPath(columnChunk);
343
+ if (selectedColumnPaths &&
344
+ path &&
345
+ !selectedColumnPaths.some(selectedPath => fieldIndexOf([Array.from(selectedPath)], path) >= 0)) {
346
+ continue;
347
+ }
348
+ if (columnChunk.encrypted_column_metadata && !columnChunk.meta_data) {
349
+ columnChunk.meta_data = await this.getColumnMetadata(columnChunk, rowGroupOrdinal, getPhysicalColumnOrdinal(columnChunk, columnOrdinal));
350
+ }
351
+ }
352
+ }
353
+ /** Decrypts one encrypted column index or offset index module for selective planning. */
354
+ async decryptIndexModule(bytes, module, rowGroupOrdinal, columnOrdinal, columnChunk) {
355
+ if (!columnChunk.crypto_metadata)
356
+ return bytes;
357
+ const encryptionContext = this.encryptionContext;
358
+ if (!encryptionContext || !this.props.keyRetriever) {
359
+ throw new Error('Encrypted Parquet indexes require parquet.keyRetriever');
360
+ }
361
+ const aad = createParquetModuleAad(encryptionContext.aadPrefix, encryptionContext.fileUnique, module, rowGroupOrdinal, columnOrdinal);
362
+ return await decryptParquetModule(bytes, {
363
+ algorithm: encryptionContext.algorithm,
364
+ aad,
365
+ keyMetadata: this.getColumnKeyMetadata(columnChunk),
366
+ keyRetriever: this.getCachedKeyRetriever()
367
+ });
368
+ }
369
+ /** Decrypts the encrypted Bloom-filter header and bitset modules for one column chunk. */
370
+ async decryptBloomFilter(bytes, rowGroupOrdinal, columnOrdinal, columnChunk) {
371
+ if (!columnChunk.crypto_metadata)
372
+ return bytes;
373
+ const encryptionContext = this.encryptionContext;
374
+ if (!encryptionContext || !this.props.keyRetriever) {
375
+ throw new Error('Encrypted Parquet Bloom filters require parquet.keyRetriever');
376
+ }
377
+ const header = readParquetEncryptedModule(bytes);
378
+ const bitset = readParquetEncryptedModule(bytes, header.nextOffset);
379
+ const keyMetadata = this.getColumnKeyMetadata(columnChunk);
380
+ const headerBytes = await decryptParquetModule(header.bytes, {
381
+ algorithm: encryptionContext.algorithm,
382
+ aad: createParquetModuleAad(encryptionContext.aadPrefix, encryptionContext.fileUnique, 'bloom-filter-header', rowGroupOrdinal, columnOrdinal),
383
+ keyMetadata,
384
+ keyRetriever: this.getCachedKeyRetriever()
385
+ });
386
+ const bitsetBytes = await decryptParquetModule(bitset.bytes, {
387
+ algorithm: encryptionContext.algorithm,
388
+ aad: createParquetModuleAad(encryptionContext.aadPrefix, encryptionContext.fileUnique, 'bloom-filter-bitset', rowGroupOrdinal, columnOrdinal),
389
+ keyMetadata,
390
+ keyRetriever: this.getCachedKeyRetriever()
391
+ });
392
+ const plaintext = new Uint8Array(headerBytes.byteLength + bitsetBytes.byteLength);
393
+ plaintext.set(headerBytes);
394
+ plaintext.set(bitsetBytes, headerBytes.byteLength);
395
+ return plaintext;
396
+ }
397
+ /** Resolves a column's plaintext metadata, decrypting column-specific metadata when present. */
398
+ async getColumnMetadata(columnChunk, rowGroupOrdinal, columnOrdinal) {
399
+ if (!columnChunk.encrypted_column_metadata) {
400
+ if (!columnChunk.meta_data) {
401
+ throw new Error('Parquet column metadata is missing');
402
+ }
403
+ return columnChunk.meta_data;
404
+ }
405
+ if (!this.props.keyRetriever) {
406
+ throw new Error('Encrypted Parquet column metadata requires parquet.keyRetriever');
407
+ }
408
+ const encryptionContext = this.encryptionContext;
409
+ if (!encryptionContext) {
410
+ throw new Error('Encrypted Parquet column metadata has no file encryption context');
411
+ }
412
+ const columnKey = columnChunk.crypto_metadata?.ENCRYPTION_WITH_COLUMN_KEY;
413
+ const usesFooterKey = Boolean(columnChunk.crypto_metadata?.ENCRYPTION_WITH_FOOTER_KEY);
414
+ if (!columnKey && !usesFooterKey) {
415
+ throw new Error('Encrypted Parquet column metadata has no key reference');
416
+ }
417
+ const aad = createParquetModuleAad(encryptionContext.aadPrefix, encryptionContext.fileUnique, 'column-metadata', rowGroupOrdinal, columnOrdinal);
418
+ const plaintext = await decryptParquetModule(columnChunk.encrypted_column_metadata, {
419
+ algorithm: encryptionContext.algorithm,
420
+ aad,
421
+ keyMetadata: columnKey?.key_metadata ??
422
+ encryptionContext.footerKeyMetadata ??
423
+ encryptionContext.footerSigningKeyMetadata,
424
+ keyRetriever: this.getCachedKeyRetriever()
425
+ });
426
+ const metadata = decodeColumnMetadata(plaintext).metadata;
427
+ if (columnKey &&
428
+ JSON.stringify(metadata.path_in_schema) !== JSON.stringify(columnKey.path_in_schema)) {
429
+ throw new Error('Encrypted Parquet column metadata path does not match crypto metadata');
430
+ }
128
431
  return metadata;
129
432
  }
130
433
  /** Data is stored in row groups (similar to Apache Arrow record batches) */
131
- async readRowGroup(schema, rowGroup, columnList) {
132
- const buffer = {
434
+ async readRowGroup(schema, rowGroup, columnList, signal, rowGroupOrdinal = 0) {
435
+ await this.resolveColumnMetadata(rowGroup, rowGroupOrdinal, columnList);
436
+ const selectedColumnChunks = [];
437
+ for (let columnOrdinal = 0; columnOrdinal < rowGroup.columns.length; columnOrdinal++) {
438
+ const columnChunk = rowGroup.columns[columnOrdinal];
439
+ const path = getColumnChunkPath(columnChunk);
440
+ if (columnList.length > 0 && (!path || fieldIndexOf(columnList, path) < 0)) {
441
+ continue;
442
+ }
443
+ const physicalColumnOrdinal = getPhysicalColumnOrdinal(columnChunk, columnOrdinal);
444
+ const metadata = columnChunk.meta_data ||
445
+ (await this.getColumnMetadata(columnChunk, rowGroupOrdinal, physicalColumnOrdinal));
446
+ if (columnList.length === 0 || fieldIndexOf(columnList, metadata.path_in_schema) >= 0) {
447
+ selectedColumnChunks.push({ columnChunk, metadata, columnOrdinal: physicalColumnOrdinal });
448
+ }
449
+ }
450
+ if (this.file.handle instanceof ArrayBuffer &&
451
+ selectedColumnChunks.every(({ columnChunk, metadata }) => (columnChunk.file_path === undefined || columnChunk.file_path === null) &&
452
+ !columnChunk.crypto_metadata &&
453
+ getThriftEnum(CompressionCodec, metadata.codec) === 'UNCOMPRESSED')) {
454
+ return {
455
+ rowCount: Number(rowGroup.num_rows),
456
+ columnData: Object.fromEntries(selectedColumnChunks.map(({ columnChunk, metadata }) => [
457
+ metadata.path_in_schema.join(),
458
+ this.readUncompressedColumnChunkFromMemory(schema, columnChunk, metadata)
459
+ ]))
460
+ };
461
+ }
462
+ const columnEntries = [];
463
+ for (let batchStart = 0; batchStart < selectedColumnChunks.length; batchStart += MAXIMUM_CONCURRENT_COLUMN_READS) {
464
+ const columnBatch = selectedColumnChunks.slice(batchStart, batchStart + MAXIMUM_CONCURRENT_COLUMN_READS);
465
+ columnEntries.push(...(await Promise.all(columnBatch.map(({ columnChunk, metadata, columnOrdinal }) => {
466
+ const columnKey = metadata.path_in_schema.join();
467
+ if (this.file.handle instanceof ArrayBuffer &&
468
+ (columnChunk.file_path === undefined || columnChunk.file_path === null) &&
469
+ !columnChunk.crypto_metadata &&
470
+ getThriftEnum(CompressionCodec, metadata.codec) === 'UNCOMPRESSED') {
471
+ return [
472
+ columnKey,
473
+ this.readUncompressedColumnChunkFromMemory(schema, columnChunk, metadata)
474
+ ];
475
+ }
476
+ return this.readColumnChunk(schema, columnChunk, signal, rowGroupOrdinal, columnOrdinal, metadata).then(columnData => [columnKey, columnData]);
477
+ }))));
478
+ }
479
+ return {
133
480
  rowCount: Number(rowGroup.num_rows),
134
- columnData: {}
481
+ columnData: Object.fromEntries(columnEntries)
135
482
  };
136
- for (const colChunk of rowGroup.columns) {
137
- const colMetadata = colChunk.meta_data;
138
- const colKey = colMetadata?.path_in_schema;
139
- if (columnList.length > 0 && fieldIndexOf(columnList, colKey) < 0) {
140
- continue; // eslint-disable-line no-continue
483
+ }
484
+ /**
485
+ * Reads selected column chunks as encoded page descriptors without materializing values.
486
+ *
487
+ * Page headers, encryption, checksums, and optional decompression remain reader concerns. Value,
488
+ * dictionary, and level decoding is deliberately left to the downstream consumer.
489
+ */
490
+ async readRowGroupEncodedPages(schema, rowGroup, columnList, preserveCompression, signal, rowGroupOrdinal = 0) {
491
+ await this.resolveColumnMetadata(rowGroup, rowGroupOrdinal, columnList);
492
+ const selectedColumnChunks = [];
493
+ for (let columnOrdinal = 0; columnOrdinal < rowGroup.columns.length; columnOrdinal++) {
494
+ const columnChunk = rowGroup.columns[columnOrdinal];
495
+ const path = getColumnChunkPath(columnChunk);
496
+ if (columnList.length > 0 && (!path || fieldIndexOf(columnList, path) < 0))
497
+ continue;
498
+ const physicalColumnOrdinal = getPhysicalColumnOrdinal(columnChunk, columnOrdinal);
499
+ const metadata = columnChunk.meta_data ||
500
+ (await this.getColumnMetadata(columnChunk, rowGroupOrdinal, physicalColumnOrdinal));
501
+ if (columnList.length === 0 || fieldIndexOf(columnList, metadata.path_in_schema) >= 0) {
502
+ selectedColumnChunks.push({
503
+ columnChunk,
504
+ metadata,
505
+ columnOrdinal: physicalColumnOrdinal
506
+ });
507
+ }
508
+ }
509
+ const columns = [];
510
+ for (let batchStart = 0; batchStart < selectedColumnChunks.length; batchStart += MAXIMUM_CONCURRENT_COLUMN_READS) {
511
+ columns.push(...(await Promise.all(selectedColumnChunks
512
+ .slice(batchStart, batchStart + MAXIMUM_CONCURRENT_COLUMN_READS)
513
+ .map(async ({ columnChunk, metadata, columnOrdinal }) => {
514
+ const encodedColumn = await this.readColumnChunkEncodedPages(schema, columnChunk, preserveCompression, signal, rowGroupOrdinal, columnOrdinal, metadata);
515
+ return encodedColumn;
516
+ }))));
517
+ }
518
+ return Object.freeze(columns);
519
+ }
520
+ /** Reads independently materializable non-repeated columns for one row range using page indexes. */
521
+ async readRowGroupRange(schema, rowGroup, columnList, rowRange, pageLocations, signal, rowGroupOrdinal = 0) {
522
+ await this.resolveColumnMetadata(rowGroup, rowGroupOrdinal, columnList);
523
+ const selectedColumnChunks = [];
524
+ for (let columnOrdinal = 0; columnOrdinal < rowGroup.columns.length; columnOrdinal++) {
525
+ const columnChunk = rowGroup.columns[columnOrdinal];
526
+ const path = getColumnChunkPath(columnChunk);
527
+ if (columnList.length > 0 && (!path || fieldIndexOf(columnList, path) < 0)) {
528
+ continue;
529
+ }
530
+ const physicalColumnOrdinal = getPhysicalColumnOrdinal(columnChunk, columnOrdinal);
531
+ const metadata = columnChunk.meta_data ||
532
+ (await this.getColumnMetadata(columnChunk, rowGroupOrdinal, physicalColumnOrdinal));
533
+ if (columnList.length === 0 || fieldIndexOf(columnList, metadata.path_in_schema) >= 0) {
534
+ selectedColumnChunks.push({ columnChunk, metadata, columnOrdinal: physicalColumnOrdinal });
535
+ }
536
+ }
537
+ const columnEntries = await Promise.all(selectedColumnChunks.map(async ({ columnChunk, metadata, columnOrdinal }) => {
538
+ const columnKey = metadata.path_in_schema.join();
539
+ const pages = pageLocations[JSON.stringify(metadata.path_in_schema)];
540
+ if (!pages) {
541
+ throw new Error(`Parquet offset index missing for ${columnKey}`);
141
542
  }
142
- buffer.columnData[colKey.join()] = await this.readColumnChunk(schema, colChunk);
543
+ const columnData = await this.readColumnChunkRange(schema, columnChunk, rowRange, pages, signal, rowGroupOrdinal, columnOrdinal, metadata);
544
+ return [columnKey, columnData];
545
+ }));
546
+ return {
547
+ rowCount: rowRange.end - rowRange.start,
548
+ columnData: Object.fromEntries(columnEntries)
549
+ };
550
+ }
551
+ /**
552
+ * Each row group contains column chunks for all the columns.
553
+ */
554
+ readUncompressedColumnChunkFromMemory(schema, columnChunk, metadata) {
555
+ if (!(this.file.handle instanceof ArrayBuffer)) {
556
+ throw new Error('Synchronous Parquet column reads require an in-memory ArrayBuffer');
143
557
  }
144
- return buffer;
558
+ const field = schema.findField(metadata.path_in_schema);
559
+ const type = getThriftEnum(Type, metadata.type);
560
+ if (type !== field.primitiveType) {
561
+ throw new Error(`chunk type not matching schema: ${type}`);
562
+ }
563
+ const pagesOffset = Number(metadata.data_page_offset);
564
+ const dictionaryPageOffset = metadata.dictionary_page_offset;
565
+ const validDictionaryPageOffset = dictionaryPageOffset !== undefined && Number(dictionaryPageOffset) > 0
566
+ ? Number(dictionaryPageOffset)
567
+ : undefined;
568
+ const chunkOffset = Math.min(pagesOffset, validDictionaryPageOffset ?? pagesOffset);
569
+ const chunkEnd = chunkOffset + Number(metadata.total_compressed_size);
570
+ const chunkSize = Math.min(this.file.size - chunkOffset, Math.max(0, chunkEnd - chunkOffset));
571
+ const chunkBuffer = new Uint8Array(this.file.handle, chunkOffset, chunkSize);
572
+ const pagesRelativeOffset = pagesOffset - chunkOffset;
573
+ const pagesSize = Math.min(chunkBuffer.length - pagesRelativeOffset, Math.max(0, chunkEnd - pagesOffset));
574
+ const context = {
575
+ type,
576
+ rLevelMax: field.rLevelMax,
577
+ dLevelMax: field.dLevelMax,
578
+ compression: 'UNCOMPRESSED',
579
+ column: field,
580
+ numValues: metadata.num_values,
581
+ dictionary: [],
582
+ decompressPage: this.getPageDecompressor('UNCOMPRESSED'),
583
+ preserveBinary: this.props.preserveBinary,
584
+ retainByteArrayViews: this.props.retainByteArrayViews,
585
+ useTypedValueBuffers: this.props.useTypedValueBuffers,
586
+ useTypedLevelBuffers: this.props.useTypedLevelBuffers,
587
+ useArrowByteArrayBuffers: this.props.useArrowByteArrayBuffers,
588
+ // Metadata proves whether the decoder may skip its otherwise duplicated page-header scan.
589
+ // Keep the scan for mixed/unknown encodings: it is both a correctness guard and fallback.
590
+ hasOnlyArrowByteArrayDataPages: hasOnlyArrowByteArrayDataPageEncodings(metadata.encodings, validDictionaryPageOffset),
591
+ verifyPageChecksums: this.props.verifyPageChecksums,
592
+ int96AsTimestamp: this.props.int96AsTimestamp
593
+ };
594
+ let dictionary;
595
+ if (validDictionaryPageOffset !== undefined) {
596
+ const dictionaryRelativeOffset = validDictionaryPageOffset - chunkOffset;
597
+ const dictionarySize = Math.min(Math.max(0, pagesOffset - validDictionaryPageOffset), chunkBuffer.length - dictionaryRelativeOffset, this.props.defaultDictionarySize);
598
+ dictionary = decodeUncompressedDictionaryBuffer(chunkBuffer.subarray(dictionaryRelativeOffset, dictionaryRelativeOffset + dictionarySize), context);
599
+ }
600
+ return decodeUncompressedDataPages(chunkBuffer.subarray(pagesRelativeOffset, pagesRelativeOffset + pagesSize), { ...context, dictionary });
145
601
  }
146
602
  /**
147
603
  * Each row group contains column chunks for all the columns.
148
604
  */
149
- async readColumnChunk(schema, colChunk) {
605
+ async readColumnChunk(schema, colChunk, signal, rowGroupOrdinal = 0, columnOrdinal = 0, resolvedMetadata) {
150
606
  if (colChunk.file_path !== undefined && colChunk.file_path !== null) {
151
607
  throw new Error('external references are not supported');
152
608
  }
153
- const field = schema.findField(colChunk.meta_data?.path_in_schema);
154
- const type = getThriftEnum(Type, colChunk.meta_data?.type);
609
+ const metadata = resolvedMetadata || colChunk.meta_data;
610
+ if (!metadata) {
611
+ throw new Error('Parquet column metadata is missing');
612
+ }
613
+ const field = schema.findField(metadata.path_in_schema);
614
+ const type = getThriftEnum(Type, metadata.type);
155
615
  if (type !== field.primitiveType) {
156
616
  throw new Error(`chunk type not matching schema: ${type}`);
157
617
  }
158
- const compression = getThriftEnum(CompressionCodec, colChunk.meta_data?.codec);
159
- const pagesOffset = Number(colChunk.meta_data?.data_page_offset);
160
- let pagesSize = Number(colChunk.meta_data?.total_compressed_size);
161
- if (!colChunk.file_path) {
162
- pagesSize = Math.min(this.file.size - pagesOffset, Number(colChunk.meta_data?.total_compressed_size));
163
- }
618
+ const compression = getThriftEnum(CompressionCodec, metadata.codec);
619
+ const pagesOffset = Number(metadata.data_page_offset);
620
+ const dictionaryPageOffset = metadata.dictionary_page_offset;
621
+ const validDictionaryPageOffset = dictionaryPageOffset !== undefined && Number(dictionaryPageOffset) > 0
622
+ ? Number(dictionaryPageOffset)
623
+ : undefined;
624
+ const chunkOffset = Math.min(pagesOffset, validDictionaryPageOffset ?? pagesOffset);
625
+ const chunkEnd = chunkOffset + Number(metadata.total_compressed_size);
626
+ const chunkSize = Math.min(this.file.size - chunkOffset, Math.max(0, chunkEnd - chunkOffset));
627
+ const chunkBuffer = await this.readBytes(chunkOffset, chunkSize, signal);
628
+ const pagesRelativeOffset = pagesOffset - chunkOffset;
629
+ const pagesSize = Math.min(chunkBuffer.length - pagesRelativeOffset, Math.max(0, chunkEnd - pagesOffset));
164
630
  const context = {
165
631
  type,
166
632
  rLevelMax: field.rLevelMax,
167
633
  dLevelMax: field.dLevelMax,
168
634
  compression,
169
635
  column: field,
170
- numValues: colChunk.meta_data?.num_values,
636
+ numValues: metadata.num_values,
171
637
  dictionary: [],
638
+ decompressPage: this.getPageDecompressor(compression),
172
639
  // Options - TBD is this the right place for these?
173
- preserveBinary: this.props.preserveBinary
640
+ preserveBinary: this.props.preserveBinary,
641
+ retainByteArrayViews: this.props.retainByteArrayViews,
642
+ useTypedValueBuffers: this.props.useTypedValueBuffers,
643
+ useTypedLevelBuffers: this.props.useTypedLevelBuffers,
644
+ useArrowByteArrayBuffers: this.props.useArrowByteArrayBuffers,
645
+ // Avoid parsing every page header twice when trusted column metadata already establishes the
646
+ // direct Arrow byte-array invariant. Unknown/mixed encodings retain the defensive scan.
647
+ hasOnlyArrowByteArrayDataPages: hasOnlyArrowByteArrayDataPageEncodings(metadata.encodings, validDictionaryPageOffset),
648
+ verifyPageChecksums: this.props.verifyPageChecksums,
649
+ int96AsTimestamp: this.props.int96AsTimestamp
174
650
  };
175
651
  let dictionary;
176
- const dictionaryPageOffset = colChunk?.meta_data?.dictionary_page_offset;
177
- if (dictionaryPageOffset) {
178
- const dictionaryOffset = Number(dictionaryPageOffset);
179
- // Getting dictionary from column chunk to iterate all over indexes to get dataPage values.
180
- dictionary = await this.getDictionary(dictionaryOffset, context, pagesOffset);
652
+ if (validDictionaryPageOffset !== undefined) {
653
+ const dictionaryRelativeOffset = validDictionaryPageOffset - chunkOffset;
654
+ const dictionarySize = Math.min(Math.max(0, pagesOffset - validDictionaryPageOffset), chunkBuffer.length - dictionaryRelativeOffset, this.props.defaultDictionarySize);
655
+ const dictionaryBuffer = chunkBuffer.subarray(dictionaryRelativeOffset, dictionaryRelativeOffset + dictionarySize);
656
+ const decodedDictionaryBuffer = colChunk.crypto_metadata
657
+ ? await this.decryptColumnPages(dictionaryBuffer, context, rowGroupOrdinal, columnOrdinal, this.getColumnKeyMetadata(colChunk), true)
658
+ : dictionaryBuffer;
659
+ dictionary = await decodeDictionaryBuffer(decodedDictionaryBuffer, context);
181
660
  }
182
661
  dictionary = context.dictionary?.length ? context.dictionary : dictionary;
183
- const arrayBuffer = await this.file.read(pagesOffset, pagesSize);
184
- const pagesBuf = Buffer.from(arrayBuffer);
662
+ const pagesBuf = colChunk.crypto_metadata
663
+ ? await this.decryptColumnPages(chunkBuffer.subarray(pagesRelativeOffset, pagesRelativeOffset + pagesSize), context, rowGroupOrdinal, columnOrdinal, this.getColumnKeyMetadata(colChunk))
664
+ : chunkBuffer.subarray(pagesRelativeOffset, pagesRelativeOffset + pagesSize);
185
665
  return await decodeDataPages(pagesBuf, { ...context, dictionary });
186
666
  }
667
+ /** Reads one column chunk as encoded dictionaries, levels, and values for deferred decoding. */
668
+ async readColumnChunkEncodedPages(schema, columnChunk, preserveCompression, signal, rowGroupOrdinal = 0, columnOrdinal = 0, resolvedMetadata) {
669
+ if (columnChunk.file_path !== undefined && columnChunk.file_path !== null) {
670
+ throw new Error('external references are not supported');
671
+ }
672
+ const metadata = resolvedMetadata || columnChunk.meta_data;
673
+ if (!metadata)
674
+ throw new Error('Parquet column metadata is missing');
675
+ const field = schema.findField(metadata.path_in_schema);
676
+ const physicalType = getThriftEnum(Type, metadata.type);
677
+ if (physicalType !== field.primitiveType) {
678
+ throw new Error(`chunk type not matching schema: ${physicalType}`);
679
+ }
680
+ const compression = getThriftEnum(CompressionCodec, metadata.codec);
681
+ const dataPageOffset = Number(metadata.data_page_offset);
682
+ const dictionaryPageOffset = metadata.dictionary_page_offset;
683
+ const validDictionaryPageOffset = dictionaryPageOffset !== undefined && Number(dictionaryPageOffset) > 0
684
+ ? Number(dictionaryPageOffset)
685
+ : undefined;
686
+ const chunkOffset = Math.min(dataPageOffset, validDictionaryPageOffset ?? dataPageOffset);
687
+ const chunkEnd = chunkOffset + Number(metadata.total_compressed_size);
688
+ const chunkByteLength = Math.min(this.file.size - chunkOffset, Math.max(0, chunkEnd - chunkOffset));
689
+ const chunkBuffer = await this.readBytes(chunkOffset, chunkByteLength, signal);
690
+ const dataPageRelativeOffset = dataPageOffset - chunkOffset;
691
+ const dataPageByteLength = Math.min(chunkBuffer.byteLength - dataPageRelativeOffset, Math.max(0, chunkEnd - dataPageOffset));
692
+ const context = {
693
+ column: field,
694
+ compression,
695
+ decompressPage: this.getPageDecompressor(compression),
696
+ preserveCompression,
697
+ verifyPageChecksums: this.props.verifyPageChecksums
698
+ };
699
+ let dictionary;
700
+ if (validDictionaryPageOffset !== undefined) {
701
+ const dictionaryRelativeOffset = validDictionaryPageOffset - chunkOffset;
702
+ const dictionaryByteLength = Math.min(Math.max(0, dataPageOffset - validDictionaryPageOffset), chunkBuffer.byteLength - dictionaryRelativeOffset, this.props.defaultDictionarySize);
703
+ const dictionaryBuffer = chunkBuffer.subarray(dictionaryRelativeOffset, dictionaryRelativeOffset + dictionaryByteLength);
704
+ const plaintextDictionaryBuffer = columnChunk.crypto_metadata
705
+ ? await this.decryptColumnPages(dictionaryBuffer, {
706
+ type: physicalType,
707
+ rLevelMax: field.rLevelMax,
708
+ dLevelMax: field.dLevelMax,
709
+ compression,
710
+ column: field
711
+ }, rowGroupOrdinal, columnOrdinal, this.getColumnKeyMetadata(columnChunk), true)
712
+ : dictionaryBuffer;
713
+ dictionary = (await scanParquetEncodedPages(plaintextDictionaryBuffer, context))[0];
714
+ }
715
+ const dataPageBuffer = chunkBuffer.subarray(dataPageRelativeOffset, dataPageRelativeOffset + dataPageByteLength);
716
+ const plaintextDataPageBuffer = columnChunk.crypto_metadata
717
+ ? await this.decryptColumnPages(dataPageBuffer, {
718
+ type: physicalType,
719
+ rLevelMax: field.rLevelMax,
720
+ dLevelMax: field.dLevelMax,
721
+ compression,
722
+ column: field
723
+ }, rowGroupOrdinal, columnOrdinal, this.getColumnKeyMetadata(columnChunk))
724
+ : dataPageBuffer;
725
+ const pages = await scanParquetEncodedPages(plaintextDataPageBuffer, context);
726
+ return Object.freeze({
727
+ path: Object.freeze([...metadata.path_in_schema]),
728
+ physicalType,
729
+ typeLength: field.typeLength,
730
+ maxRepetitionLevel: field.rLevelMax,
731
+ maxDefinitionLevel: field.dLevelMax,
732
+ compression,
733
+ valueCount: Number(metadata.num_values),
734
+ dictionary,
735
+ pages: Object.freeze(pages)
736
+ });
737
+ }
738
+ /** Decrypts the length-prefixed page header and data modules in one column chunk. */
739
+ async decryptColumnPages(encryptedPages, context, rowGroupOrdinal, columnOrdinal, keyMetadata, includesDictionary = false, dataPageOrdinalStart = 0) {
740
+ if (!this.encryptionContext || !this.props.keyRetriever) {
741
+ throw new Error('Encrypted Parquet pages require parquet.keyRetriever');
742
+ }
743
+ const plaintextPages = [];
744
+ let offset = 0;
745
+ let dataPageOrdinal = dataPageOrdinalStart;
746
+ let pageIndex = 0;
747
+ while (offset < encryptedPages.length) {
748
+ const headerModule = readParquetEncryptedModule(encryptedPages, offset);
749
+ offset = headerModule.nextOffset;
750
+ const dictionaryPage = includesDictionary && pageIndex === 0;
751
+ const headerModuleType = dictionaryPage
752
+ ? 'dictionary-page-header'
753
+ : 'data-page-header';
754
+ const headerAad = createParquetModuleAad(this.encryptionContext.aadPrefix, this.encryptionContext.fileUnique, headerModuleType, rowGroupOrdinal, columnOrdinal, dictionaryPage ? undefined : dataPageOrdinal);
755
+ const headerBytes = await decryptParquetModule(headerModule.bytes, {
756
+ algorithm: this.encryptionContext.algorithm,
757
+ aad: headerAad,
758
+ keyMetadata,
759
+ keyRetriever: this.getCachedKeyRetriever()
760
+ });
761
+ const { pageHeader } = decodePageHeader(headerBytes);
762
+ const pageType = getThriftEnum(PageType, pageHeader.type);
763
+ const dataModule = readParquetEncryptedModule(encryptedPages, offset);
764
+ offset = dataModule.nextOffset;
765
+ const dataAad = createParquetModuleAad(this.encryptionContext.aadPrefix, this.encryptionContext.fileUnique, dictionaryPage ? 'dictionary-page' : 'data-page', rowGroupOrdinal, columnOrdinal, dictionaryPage ? undefined : dataPageOrdinal);
766
+ const dataBytes = await decryptParquetModule(dataModule.bytes, {
767
+ algorithm: this.encryptionContext.algorithm,
768
+ aad: dataAad,
769
+ keyMetadata,
770
+ keyRetriever: this.getCachedKeyRetriever(),
771
+ page: true
772
+ });
773
+ plaintextPages.push(serializeThrift(pageHeader), dataBytes);
774
+ if (pageType !== 'DICTIONARY_PAGE')
775
+ dataPageOrdinal++;
776
+ pageIndex++;
777
+ }
778
+ const plaintextLength = plaintextPages.reduce((total, page) => total + page.length, 0);
779
+ const plaintext = new Uint8Array(plaintextLength);
780
+ let plaintextOffset = 0;
781
+ for (const page of plaintextPages) {
782
+ plaintext.set(page, plaintextOffset);
783
+ plaintextOffset += page.length;
784
+ }
785
+ return plaintext;
786
+ }
787
+ /** Resolves the key metadata reference for an encrypted column. */
788
+ getColumnKeyMetadata(columnChunk) {
789
+ return (columnChunk.crypto_metadata?.ENCRYPTION_WITH_COLUMN_KEY?.key_metadata ??
790
+ this.encryptionContext?.footerKeyMetadata ??
791
+ this.encryptionContext?.footerSigningKeyMetadata);
792
+ }
793
+ /** Reads and decodes contiguous data pages that begin and end on complete row boundaries. */
794
+ async readColumnChunkRange(schema, columnChunk, rowRange, pages, signal, rowGroupOrdinal = 0, columnOrdinal = 0, resolvedMetadata) {
795
+ if (columnChunk.file_path !== undefined && columnChunk.file_path !== null) {
796
+ throw new Error('external references are not supported');
797
+ }
798
+ const columnMetadata = resolvedMetadata || columnChunk.meta_data;
799
+ if (!columnMetadata) {
800
+ throw new Error('Parquet column metadata is missing');
801
+ }
802
+ const encrypted = Boolean(columnChunk.crypto_metadata);
803
+ const field = schema.findField(columnMetadata.path_in_schema);
804
+ const type = getThriftEnum(Type, columnMetadata.type);
805
+ if (type !== field.primitiveType) {
806
+ throw new Error(`chunk type not matching schema: ${type}`);
807
+ }
808
+ const compression = getThriftEnum(CompressionCodec, columnMetadata.codec);
809
+ const overlappingPages = pages.filter(page => page.endRowIndex > rowRange.start && page.firstRowIndex < rowRange.end);
810
+ if (!overlappingPages.length) {
811
+ throw new Error('Parquet page plan does not overlap the requested row range');
812
+ }
813
+ let firstPageIndex = pages.indexOf(overlappingPages[0]);
814
+ const lastPage = overlappingPages[overlappingPages.length - 1];
815
+ let firstPage = pages[firstPageIndex];
816
+ const context = {
817
+ type,
818
+ rLevelMax: field.rLevelMax,
819
+ dLevelMax: field.dLevelMax,
820
+ compression,
821
+ column: field,
822
+ // Repeated leaves have one level entry per physical value, not one per logical row. Let the
823
+ // page decoder consume the selected page range and preserve all repetition levels.
824
+ numValues: field.rLevelMax === 0
825
+ ? new CompactInt64(lastPage.endRowIndex - firstPage.firstRowIndex)
826
+ : undefined,
827
+ dictionary: [],
828
+ decompressPage: this.getPageDecompressor(compression),
829
+ preserveBinary: this.props.preserveBinary,
830
+ retainByteArrayViews: this.props.retainByteArrayViews,
831
+ useTypedValueBuffers: this.props.useTypedValueBuffers,
832
+ useArrowByteArrayBuffers: this.props.useArrowByteArrayBuffers,
833
+ verifyPageChecksums: this.props.verifyPageChecksums,
834
+ int96AsTimestamp: this.props.int96AsTimestamp
835
+ };
836
+ let dictionary;
837
+ const dictionaryPageOffset = Number(columnMetadata.dictionary_page_offset);
838
+ if (Number.isSafeInteger(dictionaryPageOffset) && dictionaryPageOffset > 0) {
839
+ const dictionaryLength = Math.max(0, pages[0].offset - dictionaryPageOffset);
840
+ const dictionaryBuffer = await this.readBytes(dictionaryPageOffset, dictionaryLength, signal);
841
+ const decodedDictionaryBuffer = encrypted
842
+ ? await this.decryptColumnPages(dictionaryBuffer, context, rowGroupOrdinal, columnOrdinal, this.getColumnKeyMetadata(columnChunk), true)
843
+ : dictionaryBuffer;
844
+ dictionary = await decodeDictionaryBuffer(decodedDictionaryBuffer, context);
845
+ }
846
+ if (field.rLevelMax !== 0) {
847
+ // Probe predecessor pages independently, then decode the final range once. This avoids
848
+ // quadratic re-decoding when a large repeated row spans many pages.
849
+ while (firstPageIndex > 0) {
850
+ const probeBuffer = await this.readBytes(firstPage.offset, firstPage.compressedByteLength, signal);
851
+ const decodedProbeBuffer = encrypted
852
+ ? await this.decryptColumnPages(probeBuffer, context, rowGroupOrdinal, columnOrdinal, this.getColumnKeyMetadata(columnChunk), false, firstPageIndex)
853
+ : probeBuffer;
854
+ const probe = await decodeDataPages(decodedProbeBuffer, { ...context, dictionary });
855
+ if (probe.rlevels[0] === 0) {
856
+ break;
857
+ }
858
+ firstPage = pages[--firstPageIndex];
859
+ }
860
+ }
861
+ const dataLength = lastPage.offset + lastPage.compressedByteLength - firstPage.offset;
862
+ const dataBuffer = await this.readBytes(firstPage.offset, dataLength, signal);
863
+ const decodedDataBuffer = encrypted
864
+ ? await this.decryptColumnPages(dataBuffer, context, rowGroupOrdinal, columnOrdinal, this.getColumnKeyMetadata(columnChunk), false, firstPageIndex)
865
+ : dataBuffer;
866
+ const decoded = await decodeDataPages(decodedDataBuffer, { ...context, dictionary });
867
+ if (field.rLevelMax !== 0) {
868
+ const rowStart = rowRange.start - firstPage.firstRowIndex;
869
+ return sliceRepeatedColumnChunk(decoded, Math.max(0, rowStart), rowRange.end - rowRange.start, field.dLevelMax);
870
+ }
871
+ const relativeStart = rowRange.start - firstPage.firstRowIndex;
872
+ const relativeEnd = relativeStart + rowRange.end - rowRange.start;
873
+ return sliceNonRepeatedColumnChunk(decoded, field.dLevelMax, relativeStart, relativeEnd);
874
+ }
187
875
  /**
188
876
  * Getting dictionary for allows to flatten values by indices.
189
877
  * @param dictionaryPageOffset
@@ -191,7 +879,7 @@ export class ParquetReader {
191
879
  * @param pagesOffset
192
880
  * @returns
193
881
  */
194
- async getDictionary(dictionaryPageOffset, context, pagesOffset) {
882
+ async getDictionary(dictionaryPageOffset, context, pagesOffset, signal) {
195
883
  if (dictionaryPageOffset === 0) {
196
884
  // dictionarySize = Math.min(this.fileSize - pagesOffset, this.defaultDictionarySize);
197
885
  // pagesBuf = await this.read(pagesOffset, dictionarySize);
@@ -201,12 +889,91 @@ export class ParquetReader {
201
889
  // Now if we use code commented above we don't get DICTIONARY_PAGE we get DATA_PAGE instead.
202
890
  return [];
203
891
  }
204
- const dictionarySize = Math.min(this.file.size - dictionaryPageOffset, this.props.defaultDictionarySize);
205
- const arrayBuffer = await this.file.read(dictionaryPageOffset, dictionarySize);
206
- const pagesBuf = Buffer.from(arrayBuffer);
207
- const cursor = { buffer: pagesBuf, offset: 0, size: pagesBuf.length };
208
- const decodedPage = await decodePage(cursor, context);
209
- return decodedPage.dictionary;
892
+ const dictionarySize = Math.min(Math.max(0, pagesOffset - dictionaryPageOffset), this.file.size - dictionaryPageOffset, this.props.defaultDictionarySize);
893
+ const pagesBuf = await this.readBytes(dictionaryPageOffset, dictionarySize, signal);
894
+ return await decodeDictionaryBuffer(pagesBuf, context);
895
+ }
896
+ }
897
+ /** Returns a column path available without decrypting column metadata when possible. */
898
+ function getColumnChunkPath(columnChunk) {
899
+ return (columnChunk.meta_data?.path_in_schema ??
900
+ columnChunk.crypto_metadata?.ENCRYPTION_WITH_COLUMN_KEY?.path_in_schema);
901
+ }
902
+ /** Builds a stable cache key while preserving module scope for context-dependent key providers. */
903
+ function createEncryptionKeyCacheKey(algorithm, keyMetadata, aad, aadPrefixByteLength, fileUniqueByteLength) {
904
+ const metadataKey = keyMetadata ? Array.from(keyMetadata).join(',') : 'footer';
905
+ if (fileUniqueByteLength === undefined) {
906
+ return `${algorithm}:${metadataKey}:aad:${Array.from(aad).join(',')}`;
907
+ }
908
+ const moduleOffset = (aadPrefixByteLength ?? 0) + fileUniqueByteLength;
909
+ if (moduleOffset + 5 > aad.byteLength) {
910
+ return `${algorithm}:${metadataKey}:aad:${Array.from(aad).join(',')}`;
911
+ }
912
+ const moduleType = aad[moduleOffset];
913
+ if (moduleType === 0) {
914
+ return `${algorithm}:${metadataKey}:footer`;
915
+ }
916
+ const view = new DataView(aad.buffer, aad.byteOffset + moduleOffset, aad.byteLength - moduleOffset);
917
+ const rowGroupOrdinal = view.getInt16(1, true);
918
+ const columnOrdinal = view.getInt16(3, true);
919
+ return `${algorithm}:${metadataKey}:module:${moduleType}:row-group:${rowGroupOrdinal}:column:${columnOrdinal}`;
920
+ }
921
+ /** Returns the original row-group ordinal for a worker-reduced column list. */
922
+ function getPhysicalColumnOrdinal(columnChunk, fallbackOrdinal) {
923
+ return (columnChunk.parquetColumnOrdinal ??
924
+ fallbackOrdinal);
925
+ }
926
+ /** Decodes one dictionary page from an already-read column-chunk range. */
927
+ async function decodeDictionaryBuffer(dictionaryBuffer, context) {
928
+ const cursor = { buffer: dictionaryBuffer, offset: 0, size: dictionaryBuffer.length };
929
+ const decodedPage = await decodePage(cursor, context);
930
+ return decodedPage.dictionary;
931
+ }
932
+ /** Slices one decoded non-repeated column chunk while preserving optional-value alignment. */
933
+ function sliceNonRepeatedColumnChunk(columnChunk, definitionLevelMaximum, start, end) {
934
+ const valueStart = countDefinedValues(columnChunk.dlevels, definitionLevelMaximum, 0, start);
935
+ const valueEnd = valueStart + countDefinedValues(columnChunk.dlevels, definitionLevelMaximum, start, end);
936
+ return {
937
+ rlevels: columnChunk.rlevels.slice(start, end),
938
+ dlevels: columnChunk.dlevels.slice(start, end),
939
+ values: columnChunk.values.slice(valueStart, valueEnd),
940
+ count: end - start,
941
+ pageHeaders: columnChunk.pageHeaders
942
+ };
943
+ }
944
+ /** Slices a repeated column by logical rows while preserving its level/value alignment. */
945
+ function sliceRepeatedColumnChunk(columnChunk, rowStart, rowCount, definitionLevelMaximum) {
946
+ const rowStarts = [];
947
+ for (let levelIndex = 0; levelIndex < columnChunk.rlevels.length; levelIndex++) {
948
+ if (columnChunk.rlevels[levelIndex] === 0) {
949
+ rowStarts.push(levelIndex);
950
+ }
951
+ }
952
+ const levelStart = rowStarts[rowStart];
953
+ const endRow = rowStart + rowCount;
954
+ const levelEnd = rowStarts[endRow] ?? columnChunk.rlevels.length;
955
+ if (levelStart === undefined || endRow > rowStarts.length || levelEnd < levelStart) {
956
+ throw new Error('Parquet repeated page range does not contain the requested rows');
957
+ }
958
+ const valueStart = countDefinedValues(columnChunk.dlevels, definitionLevelMaximum, 0, levelStart);
959
+ const valueEnd = valueStart +
960
+ countDefinedValues(columnChunk.dlevels, definitionLevelMaximum, levelStart, levelEnd);
961
+ return {
962
+ rlevels: columnChunk.rlevels.slice(levelStart, levelEnd),
963
+ dlevels: columnChunk.dlevels.slice(levelStart, levelEnd),
964
+ values: columnChunk.values.slice(valueStart, valueEnd),
965
+ count: levelEnd - levelStart,
966
+ pageHeaders: columnChunk.pageHeaders
967
+ };
968
+ }
969
+ /** Counts defined primitive values represented by one non-repeated level interval. */
970
+ function countDefinedValues(definitionLevels, definitionLevelMaximum, start, end) {
971
+ let count = 0;
972
+ for (let index = start; index < Math.min(end, definitionLevels.length); index++) {
973
+ if (definitionLevels[index] === definitionLevelMaximum) {
974
+ count++;
975
+ }
210
976
  }
977
+ return count;
211
978
  }
212
979
  //# sourceMappingURL=parquet-reader.js.map