@loaders.gl/parquet 5.0.0-alpha.2 → 5.0.0-alpha.3

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 (326) hide show
  1. package/LICENSE +1 -1
  2. package/dist/bundled.d.ts +1 -1
  3. package/dist/bundled.d.ts.map +1 -1
  4. package/dist/bundled.js.map +1 -1
  5. package/dist/delta-format.d.ts +9 -0
  6. package/dist/delta-format.d.ts.map +1 -0
  7. package/dist/delta-format.js +12 -0
  8. package/dist/delta-format.js.map +1 -0
  9. package/dist/delta-source-loader-types.d.ts +27 -0
  10. package/dist/delta-source-loader-types.d.ts.map +1 -0
  11. package/dist/delta-source-loader-types.js +28 -0
  12. package/dist/delta-source-loader-types.js.map +1 -0
  13. package/dist/delta-source.d.ts +48 -0
  14. package/dist/delta-source.d.ts.map +1 -0
  15. package/dist/delta-source.js +222 -0
  16. package/dist/delta-source.js.map +1 -0
  17. package/dist/delta-types.d.ts +38 -0
  18. package/dist/delta-types.d.ts.map +1 -0
  19. package/dist/delta-types.js +5 -0
  20. package/dist/delta-types.js.map +1 -0
  21. package/dist/geoparquet-loader.js +1 -1
  22. package/dist/iceberg-rest-catalog.d.ts +49 -0
  23. package/dist/iceberg-rest-catalog.d.ts.map +1 -0
  24. package/dist/iceberg-rest-catalog.js +78 -0
  25. package/dist/iceberg-rest-catalog.js.map +1 -0
  26. package/dist/iceberg-table-source.d.ts +63 -0
  27. package/dist/iceberg-table-source.d.ts.map +1 -0
  28. package/dist/iceberg-table-source.js +797 -0
  29. package/dist/iceberg-table-source.js.map +1 -0
  30. package/dist/iceberg-types.d.ts +150 -0
  31. package/dist/iceberg-types.d.ts.map +1 -0
  32. package/dist/iceberg-types.js +5 -0
  33. package/dist/iceberg-types.js.map +1 -0
  34. package/dist/index.cjs +15005 -3143
  35. package/dist/index.cjs.map +3 -3
  36. package/dist/index.d.ts +7 -3
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +5 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/lib/arrow/convert-schema-from-parquet.d.ts +3 -1
  41. package/dist/lib/arrow/convert-schema-from-parquet.d.ts.map +1 -1
  42. package/dist/lib/arrow/convert-schema-from-parquet.js +94 -19
  43. package/dist/lib/arrow/convert-schema-from-parquet.js.map +1 -1
  44. package/dist/lib/arrow/create-nested-arrow-vector.js +89 -0
  45. package/dist/lib/arrow/create-nested-arrow-vector.js.map +1 -1
  46. package/dist/lib/constants.js +1 -1
  47. package/dist/lib/encoders/encode-table-to-parquet-js.d.ts.map +1 -1
  48. package/dist/lib/encoders/encode-table-to-parquet-js.js +202 -7
  49. package/dist/lib/encoders/encode-table-to-parquet-js.js.map +1 -1
  50. package/dist/lib/geo/geoparquet-covering.d.ts +19 -0
  51. package/dist/lib/geo/geoparquet-covering.d.ts.map +1 -0
  52. package/dist/lib/geo/geoparquet-covering.js +137 -0
  53. package/dist/lib/geo/geoparquet-covering.js.map +1 -0
  54. package/dist/lib/geo/geospatial-metadata.d.ts.map +1 -1
  55. package/dist/lib/geo/geospatial-metadata.js +39 -13
  56. package/dist/lib/geo/geospatial-metadata.js.map +1 -1
  57. package/dist/lib/parquet-bloom-filter-planner.d.ts +16 -0
  58. package/dist/lib/parquet-bloom-filter-planner.d.ts.map +1 -0
  59. package/dist/lib/parquet-bloom-filter-planner.js +57 -0
  60. package/dist/lib/parquet-bloom-filter-planner.js.map +1 -0
  61. package/dist/lib/parquet-bloom-filter.d.ts +30 -0
  62. package/dist/lib/parquet-bloom-filter.d.ts.map +1 -0
  63. package/dist/lib/parquet-bloom-filter.js +289 -0
  64. package/dist/lib/parquet-bloom-filter.js.map +1 -0
  65. package/dist/lib/parquet-encryption.d.ts +80 -0
  66. package/dist/lib/parquet-encryption.d.ts.map +1 -0
  67. package/dist/lib/parquet-encryption.js +190 -0
  68. package/dist/lib/parquet-encryption.js.map +1 -0
  69. package/dist/lib/parquet-page-index.d.ts +34 -5
  70. package/dist/lib/parquet-page-index.d.ts.map +1 -1
  71. package/dist/lib/parquet-page-index.js +114 -28
  72. package/dist/lib/parquet-page-index.js.map +1 -1
  73. package/dist/lib/parquet-predicate.d.ts +5 -1
  74. package/dist/lib/parquet-predicate.d.ts.map +1 -1
  75. package/dist/lib/parquet-predicate.js +42 -14
  76. package/dist/lib/parquet-predicate.js.map +1 -1
  77. package/dist/lib/parquet-source-worker-decoder.d.ts +4 -1
  78. package/dist/lib/parquet-source-worker-decoder.d.ts.map +1 -1
  79. package/dist/lib/parquet-source-worker-decoder.js +83 -17
  80. package/dist/lib/parquet-source-worker-decoder.js.map +1 -1
  81. package/dist/lib/parquet-source-worker-types.d.ts +24 -0
  82. package/dist/lib/parquet-source-worker-types.d.ts.map +1 -1
  83. package/dist/lib/parsers/get-parquet-schema.d.ts.map +1 -1
  84. package/dist/lib/parsers/get-parquet-schema.js +3 -1
  85. package/dist/lib/parsers/get-parquet-schema.js.map +1 -1
  86. package/dist/lib/parsers/parse-parquet-to-arrow-js.d.ts.map +1 -1
  87. package/dist/lib/parsers/parse-parquet-to-arrow-js.js +327 -18
  88. package/dist/lib/parsers/parse-parquet-to-arrow-js.js.map +1 -1
  89. package/dist/lib/parsers/parse-parquet-to-arrow.d.ts.map +1 -1
  90. package/dist/lib/parsers/parse-parquet-to-arrow.js +5 -5
  91. package/dist/lib/parsers/parse-parquet-to-arrow.js.map +1 -1
  92. package/dist/lib/parsers/parse-parquet-to-columns.d.ts.map +1 -1
  93. package/dist/lib/parsers/parse-parquet-to-columns.js +3 -1
  94. package/dist/lib/parsers/parse-parquet-to-columns.js.map +1 -1
  95. package/dist/lib/parsers/parse-parquet-to-json.d.ts.map +1 -1
  96. package/dist/lib/parsers/parse-parquet-to-json.js +18 -2
  97. package/dist/lib/parsers/parse-parquet-to-json.js.map +1 -1
  98. package/dist/lib/slice-parquet-batch.d.ts +9 -0
  99. package/dist/lib/slice-parquet-batch.d.ts.map +1 -0
  100. package/dist/lib/slice-parquet-batch.js +28 -0
  101. package/dist/lib/slice-parquet-batch.js.map +1 -0
  102. package/dist/lib/sources/parquet-range-file.d.ts +1 -1
  103. package/dist/lib/sources/parquet-range-file.d.ts.map +1 -1
  104. package/dist/lib/sources/parquet-range-file.js +28 -22
  105. package/dist/lib/sources/parquet-range-file.js.map +1 -1
  106. package/dist/lib/utils/normalize-parquet-options.d.ts.map +1 -1
  107. package/dist/lib/utils/normalize-parquet-options.js +15 -1
  108. package/dist/lib/utils/normalize-parquet-options.js.map +1 -1
  109. package/dist/parquet-dataset-source.cjs +15766 -4896
  110. package/dist/parquet-dataset-source.cjs.map +3 -3
  111. package/dist/parquet-dataset-source.d.ts +31 -4
  112. package/dist/parquet-dataset-source.d.ts.map +1 -1
  113. package/dist/parquet-dataset-source.js +296 -74
  114. package/dist/parquet-dataset-source.js.map +1 -1
  115. package/dist/parquet-js-loader-types.d.ts +2 -0
  116. package/dist/parquet-js-loader-types.d.ts.map +1 -1
  117. package/dist/parquet-js-loader-types.js +2 -1
  118. package/dist/parquet-js-loader-types.js.map +1 -1
  119. package/dist/parquet-js-loader.d.ts +1 -0
  120. package/dist/parquet-js-loader.d.ts.map +1 -1
  121. package/dist/parquet-js-loader.js +2 -1
  122. package/dist/parquet-js-loader.js.map +1 -1
  123. package/dist/parquet-js-writer.d.ts +23 -2
  124. package/dist/parquet-js-writer.d.ts.map +1 -1
  125. package/dist/parquet-js-writer.js +1 -1
  126. package/dist/parquet-js-writer.js.map +1 -1
  127. package/dist/parquet-loader-base.js +1 -1
  128. package/dist/parquet-loader-options.d.ts +11 -0
  129. package/dist/parquet-loader-options.d.ts.map +1 -1
  130. package/dist/parquet-loader-options.js.map +1 -1
  131. package/dist/parquet-source-capabilities.d.ts +8 -1
  132. package/dist/parquet-source-capabilities.d.ts.map +1 -1
  133. package/dist/parquet-source-capabilities.js +10 -0
  134. package/dist/parquet-source-capabilities.js.map +1 -1
  135. package/dist/parquet-source-loader-types.d.ts +10 -0
  136. package/dist/parquet-source-loader-types.d.ts.map +1 -1
  137. package/dist/parquet-source-loader-types.js +11 -1
  138. package/dist/parquet-source-loader-types.js.map +1 -1
  139. package/dist/parquet-source-loader.cjs +14911 -4316
  140. package/dist/parquet-source-loader.cjs.map +3 -3
  141. package/dist/parquet-source-loader.d.ts +42 -4
  142. package/dist/parquet-source-loader.d.ts.map +1 -1
  143. package/dist/parquet-source-loader.js +585 -38
  144. package/dist/parquet-source-loader.js.map +1 -1
  145. package/dist/parquet-source-types.d.ts +180 -30
  146. package/dist/parquet-source-types.d.ts.map +1 -1
  147. package/dist/parquet-source-worker.js +7055 -6989
  148. package/dist/parquet-source-worker.js.map +4 -4
  149. package/dist/parquet-worker-node.cjs +8505 -1041
  150. package/dist/parquet-worker-node.cjs.map +4 -4
  151. package/dist/parquet-worker-url.js +5 -1
  152. package/dist/parquet-worker-url.js.map +1 -1
  153. package/dist/parquet-worker.js +289 -218
  154. package/dist/parquet-worker.js.map +4 -4
  155. package/dist/parquetjs/codecs/declare.d.ts +15 -0
  156. package/dist/parquetjs/codecs/declare.d.ts.map +1 -1
  157. package/dist/parquetjs/codecs/declare.js +10 -0
  158. package/dist/parquetjs/codecs/declare.js.map +1 -1
  159. package/dist/parquetjs/codecs/delta.d.ts.map +1 -1
  160. package/dist/parquetjs/codecs/delta.js +356 -7
  161. package/dist/parquetjs/codecs/delta.js.map +1 -1
  162. package/dist/parquetjs/codecs/index.d.ts.map +1 -1
  163. package/dist/parquetjs/codecs/index.js +4 -0
  164. package/dist/parquetjs/codecs/index.js.map +1 -1
  165. package/dist/parquetjs/codecs/plain.d.ts +1 -1
  166. package/dist/parquetjs/codecs/plain.d.ts.map +1 -1
  167. package/dist/parquetjs/codecs/plain.js +153 -12
  168. package/dist/parquetjs/codecs/plain.js.map +1 -1
  169. package/dist/parquetjs/codecs/rle.d.ts +4 -0
  170. package/dist/parquetjs/codecs/rle.d.ts.map +1 -1
  171. package/dist/parquetjs/codecs/rle.js +406 -3
  172. package/dist/parquetjs/codecs/rle.js.map +1 -1
  173. package/dist/parquetjs/compression.d.ts +9 -0
  174. package/dist/parquetjs/compression.d.ts.map +1 -1
  175. package/dist/parquetjs/compression.js +86 -67
  176. package/dist/parquetjs/compression.js.map +1 -1
  177. package/dist/parquetjs/encoder/dictionary-planner.d.ts.map +1 -1
  178. package/dist/parquetjs/encoder/dictionary-planner.js +5 -2
  179. package/dist/parquetjs/encoder/dictionary-planner.js.map +1 -1
  180. package/dist/parquetjs/encoder/parquet-encoder.d.ts +43 -1
  181. package/dist/parquetjs/encoder/parquet-encoder.d.ts.map +1 -1
  182. package/dist/parquetjs/encoder/parquet-encoder.js +691 -34
  183. package/dist/parquetjs/encoder/parquet-encoder.js.map +1 -1
  184. package/dist/parquetjs/parquet-thrift/BoundingBox.d.ts +29 -0
  185. package/dist/parquetjs/parquet-thrift/BoundingBox.d.ts.map +1 -0
  186. package/dist/parquetjs/parquet-thrift/BoundingBox.js +85 -0
  187. package/dist/parquetjs/parquet-thrift/BoundingBox.js.map +1 -0
  188. package/dist/parquetjs/parquet-thrift/ColumnChunk.d.ts +5 -0
  189. package/dist/parquetjs/parquet-thrift/ColumnChunk.d.ts.map +1 -1
  190. package/dist/parquetjs/parquet-thrift/ColumnChunk.js +35 -0
  191. package/dist/parquetjs/parquet-thrift/ColumnChunk.js.map +1 -1
  192. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.d.ts +35 -0
  193. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.d.ts.map +1 -0
  194. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.js +135 -0
  195. package/dist/parquetjs/parquet-thrift/ColumnCryptoMetaData.js.map +1 -0
  196. package/dist/parquetjs/parquet-thrift/ColumnMetaData.d.ts +10 -0
  197. package/dist/parquetjs/parquet-thrift/ColumnMetaData.d.ts.map +1 -1
  198. package/dist/parquetjs/parquet-thrift/ColumnMetaData.js +73 -0
  199. package/dist/parquetjs/parquet-thrift/ColumnMetaData.js.map +1 -1
  200. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.d.ts +22 -0
  201. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.d.ts.map +1 -0
  202. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.js +111 -0
  203. package/dist/parquetjs/parquet-thrift/EncryptionAlgorithm.js.map +1 -0
  204. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.d.ts +16 -0
  205. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.d.ts.map +1 -0
  206. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.js +57 -0
  207. package/dist/parquetjs/parquet-thrift/FileCryptoMetaData.js.map +1 -0
  208. package/dist/parquetjs/parquet-thrift/FileMetaData.d.ts +5 -0
  209. package/dist/parquetjs/parquet-thrift/FileMetaData.d.ts.map +1 -1
  210. package/dist/parquetjs/parquet-thrift/FileMetaData.js +35 -0
  211. package/dist/parquetjs/parquet-thrift/FileMetaData.js.map +1 -1
  212. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.d.ts +18 -0
  213. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.d.ts.map +1 -0
  214. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.js +62 -0
  215. package/dist/parquetjs/parquet-thrift/GeospatialStatistics.js.map +1 -0
  216. package/dist/parquetjs/parquet-thrift/SizeStatistics.d.ts +26 -0
  217. package/dist/parquetjs/parquet-thrift/SizeStatistics.d.ts.map +1 -0
  218. package/dist/parquetjs/parquet-thrift/SizeStatistics.js +85 -0
  219. package/dist/parquetjs/parquet-thrift/SizeStatistics.js.map +1 -0
  220. package/dist/parquetjs/parquet-thrift/index.d.ts +6 -0
  221. package/dist/parquetjs/parquet-thrift/index.d.ts.map +1 -1
  222. package/dist/parquetjs/parquet-thrift/index.js +6 -0
  223. package/dist/parquetjs/parquet-thrift/index.js.map +1 -1
  224. package/dist/parquetjs/parser/decoders.d.ts +10 -1
  225. package/dist/parquetjs/parser/decoders.d.ts.map +1 -1
  226. package/dist/parquetjs/parser/decoders.js +318 -14
  227. package/dist/parquetjs/parser/decoders.js.map +1 -1
  228. package/dist/parquetjs/parser/parquet-reader.d.ts +78 -12
  229. package/dist/parquetjs/parser/parquet-reader.d.ts.map +1 -1
  230. package/dist/parquetjs/parser/parquet-reader.js +605 -66
  231. package/dist/parquetjs/parser/parquet-reader.js.map +1 -1
  232. package/dist/parquetjs/schema/declare.d.ts +22 -3
  233. package/dist/parquetjs/schema/declare.d.ts.map +1 -1
  234. package/dist/parquetjs/schema/declare.js.map +1 -1
  235. package/dist/parquetjs/schema/schema.d.ts.map +1 -1
  236. package/dist/parquetjs/schema/schema.js +10 -0
  237. package/dist/parquetjs/schema/schema.js.map +1 -1
  238. package/dist/parquetjs/schema/shred.d.ts.map +1 -1
  239. package/dist/parquetjs/schema/shred.js +219 -11
  240. package/dist/parquetjs/schema/shred.js.map +1 -1
  241. package/dist/parquetjs/schema/types.js +19 -21
  242. package/dist/parquetjs/schema/types.js.map +1 -1
  243. package/dist/parquetjs/schema/variant.d.ts +3 -0
  244. package/dist/parquetjs/schema/variant.d.ts.map +1 -0
  245. package/dist/parquetjs/schema/variant.js +248 -0
  246. package/dist/parquetjs/schema/variant.js.map +1 -0
  247. package/dist/parquetjs/utils/crc32.d.ts +3 -0
  248. package/dist/parquetjs/utils/crc32.d.ts.map +1 -0
  249. package/dist/parquetjs/utils/crc32.js +15 -0
  250. package/dist/parquetjs/utils/crc32.js.map +1 -0
  251. package/dist/parquetjs/utils/read-utils.d.ts +11 -1
  252. package/dist/parquetjs/utils/read-utils.d.ts.map +1 -1
  253. package/dist/parquetjs/utils/read-utils.js +21 -1
  254. package/dist/parquetjs/utils/read-utils.js.map +1 -1
  255. package/dist/unbundled.d.ts +2 -1
  256. package/dist/unbundled.d.ts.map +1 -1
  257. package/dist/unbundled.js +1 -0
  258. package/dist/unbundled.js.map +1 -1
  259. package/package.json +36 -11
  260. package/src/bundled.ts +3 -0
  261. package/src/delta-format.ts +12 -0
  262. package/src/delta-source-loader-types.ts +40 -0
  263. package/src/delta-source.ts +305 -0
  264. package/src/delta-types.ts +40 -0
  265. package/src/iceberg-rest-catalog.ts +122 -0
  266. package/src/iceberg-table-source.ts +1037 -0
  267. package/src/iceberg-types.ts +165 -0
  268. package/src/index.ts +50 -1
  269. package/src/lib/arrow/convert-schema-from-parquet.ts +113 -19
  270. package/src/lib/arrow/create-nested-arrow-vector.ts +116 -0
  271. package/src/lib/encoders/encode-table-to-parquet-js.ts +268 -7
  272. package/src/lib/geo/geoparquet-covering.ts +201 -0
  273. package/src/lib/geo/geospatial-metadata.ts +42 -15
  274. package/src/lib/parquet-bloom-filter-planner.ts +86 -0
  275. package/src/lib/parquet-bloom-filter.ts +345 -0
  276. package/src/lib/parquet-encryption.ts +344 -0
  277. package/src/lib/parquet-page-index.ts +180 -34
  278. package/src/lib/parquet-predicate.ts +52 -16
  279. package/src/lib/parquet-source-worker-decoder.ts +116 -20
  280. package/src/lib/parquet-source-worker-types.ts +25 -0
  281. package/src/lib/parsers/get-parquet-schema.ts +3 -1
  282. package/src/lib/parsers/parse-parquet-to-arrow-js.ts +397 -17
  283. package/src/lib/parsers/parse-parquet-to-arrow.ts +4 -5
  284. package/src/lib/parsers/parse-parquet-to-columns.ts +3 -1
  285. package/src/lib/parsers/parse-parquet-to-json.ts +18 -2
  286. package/src/lib/slice-parquet-batch.ts +32 -0
  287. package/src/lib/sources/parquet-range-file.ts +35 -29
  288. package/src/lib/utils/normalize-parquet-options.ts +17 -1
  289. package/src/parquet-dataset-source.ts +397 -85
  290. package/src/parquet-js-loader-types.ts +1 -0
  291. package/src/parquet-js-loader.ts +2 -1
  292. package/src/parquet-js-writer.ts +30 -0
  293. package/src/parquet-loader-options.ts +11 -0
  294. package/src/parquet-source-capabilities.ts +18 -1
  295. package/src/parquet-source-loader-types.ts +10 -0
  296. package/src/parquet-source-loader.ts +929 -52
  297. package/src/parquet-source-types.ts +197 -28
  298. package/src/parquet-worker-url.ts +6 -1
  299. package/src/parquetjs/codecs/declare.ts +27 -0
  300. package/src/parquetjs/codecs/delta.ts +466 -6
  301. package/src/parquetjs/codecs/index.ts +4 -0
  302. package/src/parquetjs/codecs/plain.ts +177 -11
  303. package/src/parquetjs/codecs/rle.ts +573 -3
  304. package/src/parquetjs/compression.ts +102 -76
  305. package/src/parquetjs/encoder/dictionary-planner.ts +7 -2
  306. package/src/parquetjs/encoder/parquet-encoder.ts +1016 -38
  307. package/src/parquetjs/parquet-thrift/BoundingBox.ts +108 -0
  308. package/src/parquetjs/parquet-thrift/ColumnChunk.ts +35 -0
  309. package/src/parquetjs/parquet-thrift/ColumnCryptoMetaData.ts +139 -0
  310. package/src/parquetjs/parquet-thrift/ColumnMetaData.ts +73 -0
  311. package/src/parquetjs/parquet-thrift/EncryptionAlgorithm.ts +127 -0
  312. package/src/parquetjs/parquet-thrift/FileCryptoMetaData.ts +60 -0
  313. package/src/parquetjs/parquet-thrift/FileMetaData.ts +35 -0
  314. package/src/parquetjs/parquet-thrift/GeospatialStatistics.ts +68 -0
  315. package/src/parquetjs/parquet-thrift/SizeStatistics.ts +98 -0
  316. package/src/parquetjs/parquet-thrift/index.ts +6 -0
  317. package/src/parquetjs/parser/decoders.ts +451 -26
  318. package/src/parquetjs/parser/parquet-reader.ts +935 -87
  319. package/src/parquetjs/schema/declare.ts +22 -2
  320. package/src/parquetjs/schema/schema.ts +10 -0
  321. package/src/parquetjs/schema/shred.ts +238 -11
  322. package/src/parquetjs/schema/types.ts +16 -25
  323. package/src/parquetjs/schema/variant.ts +313 -0
  324. package/src/parquetjs/utils/crc32.ts +15 -0
  325. package/src/parquetjs/utils/read-utils.ts +26 -1
  326. package/src/unbundled.ts +14 -0
@@ -8,6 +8,7 @@
8
8
  import type {PrimitiveType} from '../schema/declare';
9
9
  import {
10
10
  getParquetValueOutput,
11
+ reserveParquetByteArrayOutput,
11
12
  type CursorBuffer,
12
13
  type ParquetCodecOptions,
13
14
  type ParquetValueBuffer
@@ -24,10 +25,18 @@ import {
24
25
  writeUInt32LE
25
26
  } from '../utils/binary-utils';
26
27
 
28
+ const JULIAN_DAY_UNIX_EPOCH = 2440588n;
29
+ const NANOSECONDS_PER_DAY = 86_400_000_000_000n;
30
+ const INT64_MIN = -(1n << 63n);
31
+ const INT64_MAX = (1n << 63n) - 1n;
32
+ const IS_LITTLE_ENDIAN = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
33
+ /** Largest byte value copied inline to avoid a temporary TypedArray view. */
34
+ const MAXIMUM_INLINE_BYTE_COPY_LENGTH = 7;
35
+
27
36
  export function encodeValues(
28
37
  type: PrimitiveType,
29
38
  values: any[],
30
- opts: ParquetCodecOptions
39
+ opts: ParquetCodecOptions = {}
31
40
  ): Uint8Array {
32
41
  switch (type) {
33
42
  case 'BOOLEAN':
@@ -37,7 +46,7 @@ export function encodeValues(
37
46
  case 'INT64':
38
47
  return encodeValues_INT64(values);
39
48
  case 'INT96':
40
- return encodeValues_INT96(values);
49
+ return encodeValues_INT96(values, opts.int96AsTimestamp);
41
50
  case 'FLOAT':
42
51
  return encodeValues_FLOAT(values);
43
52
  case 'DOUBLE':
@@ -118,6 +127,9 @@ function decodeValues_INT32(
118
127
  options: ParquetCodecOptions
119
128
  ): ParquetValueBuffer {
120
129
  const {output, outputOffset} = getParquetValueOutput(options, count);
130
+ if (output instanceof Int32Array && copyPlainTypedValues(cursor, output, outputOffset, count)) {
131
+ return output;
132
+ }
121
133
  const dataView = getCursorDataView(cursor);
122
134
  for (let i = 0; i < count; i++) {
123
135
  output[outputOffset + i] = dataView.getInt32(cursor.offset, true);
@@ -140,6 +152,13 @@ function decodeValues_INT64(
140
152
  options: ParquetCodecOptions
141
153
  ): ParquetValueBuffer {
142
154
  const {output, outputOffset} = getParquetValueOutput(options, count);
155
+ if (
156
+ options.int64AsBigInt &&
157
+ output instanceof BigInt64Array &&
158
+ copyPlainTypedValues(cursor, output, outputOffset, count)
159
+ ) {
160
+ return output;
161
+ }
143
162
  const dataView = getCursorDataView(cursor);
144
163
  for (let i = 0; i < count; i++) {
145
164
  const value = dataView.getBigInt64(cursor.offset, true);
@@ -149,15 +168,36 @@ function decodeValues_INT64(
149
168
  return output;
150
169
  }
151
170
 
152
- function encodeValues_INT96(values: number[]): Uint8Array {
171
+ function encodeValues_INT96(values: Array<number | bigint>, asTimestamp = false): Uint8Array {
153
172
  const buf = new Uint8Array(12 * values.length);
154
173
  for (let i = 0; i < values.length; i++) {
155
- writeInt64LE(buf, values[i], i * 12);
156
- writeUInt32LE(buf, values[i] >= 0 ? 0 : 0xffffffff, i * 12 + 8);
174
+ if (!asTimestamp) {
175
+ writeInt64LE(buf, values[i], i * 12);
176
+ writeUInt32LE(buf, values[i] >= 0 ? 0 : 0xffffffff, i * 12 + 8);
177
+ continue;
178
+ }
179
+ const epochNanoseconds = BigInt(values[i]);
180
+ if (epochNanoseconds < INT64_MIN || epochNanoseconds > INT64_MAX) {
181
+ throw new Error(`INT96 timestamp is outside the signed 64-bit range: ${epochNanoseconds}`);
182
+ }
183
+ const julianDayOffset = floorDivide(epochNanoseconds, NANOSECONDS_PER_DAY);
184
+ const nanosecondsOfDay = epochNanoseconds - julianDayOffset * NANOSECONDS_PER_DAY;
185
+ const julianDay = JULIAN_DAY_UNIX_EPOCH + julianDayOffset;
186
+ if (julianDay < -2147483648n || julianDay > 2147483647n) {
187
+ throw new Error(`INT96 timestamp has an unsupported Julian day: ${julianDay}`);
188
+ }
189
+ writeInt64LE(buf, nanosecondsOfDay, i * 12);
190
+ writeInt32LE(buf, Number(julianDay), i * 12 + 8);
157
191
  }
158
192
  return buf;
159
193
  }
160
194
 
195
+ function floorDivide(value: bigint, divisor: bigint): bigint {
196
+ const quotient = value / divisor;
197
+ const remainder = value % divisor;
198
+ return remainder < 0n ? quotient - 1n : quotient;
199
+ }
200
+
161
201
  function decodeValues_INT96(
162
202
  cursor: CursorBuffer,
163
203
  count: number,
@@ -166,12 +206,26 @@ function decodeValues_INT96(
166
206
  const {output, outputOffset} = getParquetValueOutput(options, count);
167
207
  const dataView = getCursorDataView(cursor);
168
208
  for (let i = 0; i < count; i++) {
169
- const low = Number(dataView.getBigInt64(cursor.offset, true));
170
- const high = dataView.getUint32(cursor.offset + 8, true);
171
- if (high === 0xffffffff) {
172
- output[outputOffset + i] = ~-low + 1; // truncate to 64 actual precision
209
+ if (options.int96AsTimestamp) {
210
+ const nanosecondsOfDay = dataView.getBigUint64(cursor.offset, true);
211
+ if (nanosecondsOfDay >= NANOSECONDS_PER_DAY) {
212
+ throw new Error(`Invalid INT96 nanoseconds of day: ${nanosecondsOfDay}`);
213
+ }
214
+ const julianDay = BigInt(dataView.getInt32(cursor.offset + 8, true));
215
+ const epochNanoseconds =
216
+ (julianDay - JULIAN_DAY_UNIX_EPOCH) * NANOSECONDS_PER_DAY + nanosecondsOfDay;
217
+ if (epochNanoseconds < INT64_MIN || epochNanoseconds > INT64_MAX) {
218
+ throw new Error(`INT96 timestamp is outside the signed 64-bit range: ${epochNanoseconds}`);
219
+ }
220
+ output[outputOffset + i] = epochNanoseconds;
173
221
  } else {
174
- output[outputOffset + i] = low; // truncate to 64 actual precision
222
+ const low = Number(dataView.getBigInt64(cursor.offset, true));
223
+ const high = dataView.getUint32(cursor.offset + 8, true);
224
+ if (high === 0xffffffff) {
225
+ output[outputOffset + i] = ~-low + 1; // truncate to 64 actual precision
226
+ } else {
227
+ output[outputOffset + i] = low; // truncate to 64 actual precision
228
+ }
175
229
  }
176
230
  cursor.offset += 12;
177
231
  }
@@ -192,6 +246,9 @@ function decodeValues_FLOAT(
192
246
  options: ParquetCodecOptions
193
247
  ): ParquetValueBuffer {
194
248
  const {output, outputOffset} = getParquetValueOutput(options, count);
249
+ if (output instanceof Float32Array && copyPlainTypedValues(cursor, output, outputOffset, count)) {
250
+ return output;
251
+ }
195
252
  const dataView = getCursorDataView(cursor);
196
253
  for (let i = 0; i < count; i++) {
197
254
  output[outputOffset + i] = dataView.getFloat32(cursor.offset, true);
@@ -214,6 +271,9 @@ function decodeValues_DOUBLE(
214
271
  options: ParquetCodecOptions
215
272
  ): ParquetValueBuffer {
216
273
  const {output, outputOffset} = getParquetValueOutput(options, count);
274
+ if (output instanceof Float64Array && copyPlainTypedValues(cursor, output, outputOffset, count)) {
275
+ return output;
276
+ }
217
277
  const dataView = getCursorDataView(cursor);
218
278
  for (let i = 0; i < count; i++) {
219
279
  output[outputOffset + i] = dataView.getFloat64(cursor.offset, true);
@@ -245,6 +305,9 @@ function decodeValues_BYTE_ARRAY(
245
305
  count: number,
246
306
  options: ParquetCodecOptions
247
307
  ): ParquetValueBuffer {
308
+ if (options.byteArrayOutput) {
309
+ return decodeByteArraysToContiguousOutput(cursor, count, options);
310
+ }
248
311
  const {output, outputOffset} = getParquetValueOutput(options, count);
249
312
  const dataView = getCursorDataView(cursor);
250
313
  for (let i = 0; i < count; i++) {
@@ -255,6 +318,47 @@ function decodeValues_BYTE_ARRAY(
255
318
  return output;
256
319
  }
257
320
 
321
+ /** Decodes length-prefixed PLAIN values directly into one Arrow-compatible byte buffer. */
322
+ function decodeByteArraysToContiguousOutput(
323
+ cursor: CursorBuffer,
324
+ count: number,
325
+ options: ParquetCodecOptions
326
+ ): ParquetValueBuffer {
327
+ const byteArrayOutput = options.byteArrayOutput!;
328
+ const outputOffset = options.outputOffset || 0;
329
+ const dataView = getCursorDataView(cursor);
330
+ let byteOffset = byteArrayOutput.byteLength;
331
+ byteArrayOutput.valueOffsets[outputOffset] = byteOffset;
332
+ const remainingByteLength = (cursor.size ?? cursor.buffer.byteLength) - cursor.offset;
333
+ if (remainingByteLength < 0) {
334
+ throw new Error('PLAIN BYTE_ARRAY cursor exceeds the page buffer');
335
+ }
336
+ // PLAIN's remaining encoded bytes are an upper bound for its decoded payload because each value
337
+ // drops a four-byte length prefix. Reserve once per page instead of checking capacity per value.
338
+ reserveParquetByteArrayOutput(byteArrayOutput, remainingByteLength);
339
+ for (let valueIndex = 0; valueIndex < count; valueIndex++) {
340
+ const byteLength = dataView.getUint32(cursor.offset, true);
341
+ cursor.offset += 4;
342
+ const sourceEnd = cursor.offset + byteLength;
343
+ const destinationEnd = byteOffset + byteLength;
344
+ if (sourceEnd > (cursor.size ?? cursor.buffer.byteLength)) {
345
+ throw new Error('PLAIN BYTE_ARRAY value exceeds the page buffer');
346
+ }
347
+ if (byteLength <= MAXIMUM_INLINE_BYTE_COPY_LENGTH) {
348
+ for (let byteIndex = 0; byteIndex < byteLength; byteIndex++) {
349
+ byteArrayOutput.data[byteOffset + byteIndex] = cursor.buffer[cursor.offset + byteIndex];
350
+ }
351
+ } else {
352
+ byteArrayOutput.data.set(cursor.buffer.subarray(cursor.offset, sourceEnd), byteOffset);
353
+ }
354
+ cursor.offset = sourceEnd;
355
+ byteOffset = destinationEnd;
356
+ byteArrayOutput.valueOffsets[outputOffset + valueIndex + 1] = byteOffset;
357
+ }
358
+ byteArrayOutput.byteLength = byteOffset;
359
+ return options.output || [];
360
+ }
361
+
258
362
  function encodeValues_FIXED_LEN_BYTE_ARRAY(values: any[], opts: ParquetCodecOptions): Uint8Array {
259
363
  if (!opts.typeLength) {
260
364
  throw new Error('missing option: typeLength (required for FIXED_LEN_BYTE_ARRAY)');
@@ -273,16 +377,53 @@ function decodeValues_FIXED_LEN_BYTE_ARRAY(
273
377
  count: number,
274
378
  opts: ParquetCodecOptions
275
379
  ): ParquetValueBuffer {
276
- const {output, outputOffset} = getParquetValueOutput(opts, count);
277
380
  if (!opts.typeLength) {
278
381
  throw new Error('missing option: typeLength (required for FIXED_LEN_BYTE_ARRAY)');
279
382
  }
383
+ if (opts.byteArrayOutput) {
384
+ return decodeFixedLengthByteArraysToContiguousOutput(cursor, count, opts.typeLength, opts);
385
+ }
386
+ const {output, outputOffset} = getParquetValueOutput(opts, count);
280
387
  for (let i = 0; i < count; i++) {
281
388
  output[outputOffset + i] = readByteArray(cursor, opts.typeLength, opts.retainByteArrayViews);
282
389
  }
283
390
  return output;
284
391
  }
285
392
 
393
+ /** Exposes one fixed-width PLAIN payload directly as Arrow-compatible bytes and offsets. */
394
+ function decodeFixedLengthByteArraysToContiguousOutput(
395
+ cursor: CursorBuffer,
396
+ count: number,
397
+ typeLength: number,
398
+ options: ParquetCodecOptions
399
+ ): ParquetValueBuffer {
400
+ const byteArrayOutput = options.byteArrayOutput!;
401
+ const outputOffset = options.outputOffset || 0;
402
+ const payloadByteLength = count * typeLength;
403
+ const inputEnd = cursor.offset + payloadByteLength;
404
+ if (inputEnd > (cursor.size ?? cursor.buffer.byteLength)) {
405
+ throw new Error('PLAIN FIXED_LEN_BYTE_ARRAY values exceed the page buffer');
406
+ }
407
+
408
+ let byteOffset = byteArrayOutput.byteLength;
409
+ byteArrayOutput.valueOffsets[outputOffset] = byteOffset;
410
+ if (byteOffset === 0) {
411
+ // The common single-page case can retain the original Parquet bytes without allocating either
412
+ // one view per value or a second payload buffer. A later page falls back to append-and-copy.
413
+ byteArrayOutput.data = cursor.buffer.subarray(cursor.offset, inputEnd);
414
+ } else {
415
+ reserveParquetByteArrayOutput(byteArrayOutput, payloadByteLength);
416
+ byteArrayOutput.data.set(cursor.buffer.subarray(cursor.offset, inputEnd), byteOffset);
417
+ }
418
+ cursor.offset = inputEnd;
419
+ for (let valueIndex = 0; valueIndex < count; valueIndex++) {
420
+ byteOffset += typeLength;
421
+ byteArrayOutput.valueOffsets[outputOffset + valueIndex + 1] = byteOffset;
422
+ }
423
+ byteArrayOutput.byteLength = byteOffset;
424
+ return options.output || [];
425
+ }
426
+
286
427
  /** Reads one byte-array value, optionally retaining a view into the decoded page buffer. */
287
428
  function readByteArray(
288
429
  cursor: CursorBuffer,
@@ -299,6 +440,31 @@ function getCursorDataView(cursor: CursorBuffer): DataView {
299
440
  return new DataView(cursor.buffer.buffer, cursor.buffer.byteOffset, cursor.buffer.byteLength);
300
441
  }
301
442
 
443
+ /** Copies little-endian PLAIN values directly into an identical typed destination. */
444
+ function copyPlainTypedValues(
445
+ cursor: CursorBuffer,
446
+ output: Int32Array | BigInt64Array | Float32Array | Float64Array,
447
+ outputOffset: number,
448
+ count: number
449
+ ): boolean {
450
+ if (!IS_LITTLE_ENDIAN) {
451
+ return false;
452
+ }
453
+ const byteLength = count * output.BYTES_PER_ELEMENT;
454
+ const inputEnd = cursor.offset + byteLength;
455
+ if (inputEnd > (cursor.size ?? cursor.buffer.length) || outputOffset + count > output.length) {
456
+ throw new Error('Unexpected end of Parquet PLAIN values');
457
+ }
458
+ const outputBytes = new Uint8Array(
459
+ output.buffer,
460
+ output.byteOffset + outputOffset * output.BYTES_PER_ELEMENT,
461
+ byteLength
462
+ );
463
+ outputBytes.set(cursor.buffer.subarray(cursor.offset, inputEnd));
464
+ cursor.offset = inputEnd;
465
+ return true;
466
+ }
467
+
302
468
  function toPrimitiveBytes(value: any): Uint8Array {
303
469
  return typeof value === 'string' ? encodeUtf8(value) : toUint8Array(value);
304
470
  }