@drakkar.software/starfish-events 3.0.0-alpha.40

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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/plugin.ts", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/bytewriter.js", "../../../../node_modules/.pnpm/hyparquet@1.26.1/node_modules/hyparquet/src/schema.js", "../../../../node_modules/.pnpm/hyparquet@1.26.1/node_modules/hyparquet/src/xxhash.js", "../../../../node_modules/.pnpm/hyparquet@1.26.1/node_modules/hyparquet/src/bloom.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/thrift.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/bloom.js", "../../../../node_modules/.pnpm/hyparquet@1.26.1/node_modules/hyparquet/src/constants.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/delta.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/encoding.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/plain.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/variant.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/schema.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/splitstream.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/datapage.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/dictionary.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/geospatial.js", "../../../../node_modules/.pnpm/hyparquet@1.26.1/node_modules/hyparquet/src/utils.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/wkb.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/unconvert.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/column.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/dremel.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/indexes.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/metadata.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/snappy.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/parquet-writer.js", "../../../../node_modules/.pnpm/hyparquet-writer@0.16.1/node_modules/hyparquet-writer/src/write.js", "../src/encode.ts"],
4
+ "sourcesContent": ["/**\n * Starfish server plugin: intercepts JSON event-batch pushes and encodes them\n * as Parquet files written directly to the object store (typically S3).\n *\n * ## How it works\n *\n * 1. Register a JSON-typed collection (allowedMimeTypes: [\"application/json\"])\n * with public write access.\n * 2. Attach this plugin to the sync router.\n * 3. Each push to that collection is intercepted here; the JSON event batch is\n * encoded as Parquet and stored via `store.putBytes`, short-circuiting the\n * default JSON document write so no JSON is persisted alongside the Parquet.\n *\n * ## Collection requirement\n *\n * The intercepted collection **must** be JSON-typed \u2014 `interceptPush` only\n * receives a populated `rawBody` for JSON collections. A binary (parquet-typed)\n * collection would yield an empty body.\n *\n * ## One file per batch\n *\n * Parquet's column-footer format makes in-place append impractical. Each\n * `send()` call from the SunGlasses adapter writes a unique path (batchId in\n * the storagePath template). DuckDB's `read_parquet('s3://\u2026/**\u200C/*.parquet')`\n * glob treats all files under the prefix as one logical dataset.\n *\n * ## Privacy\n *\n * Never log `distinct_id`, `properties`, or `context`. Log counts only.\n * These values ride as opaque strings into Parquet.\n */\n\nimport type {\n ServerPlugin,\n PushHookContext,\n PushHookResult,\n} from \"@drakkar.software/starfish-protocol\"\nimport { getCrypto, bytesToHex, PARQUET_MIME_TYPE } from \"@drakkar.software/starfish-protocol\"\nimport type { ObjectStore } from \"@drakkar.software/starfish-server\"\nimport { resolveDocumentKey } from \"@drakkar.software/starfish-server\"\nimport { encodeParquet } from \"./encode.js\"\n\n/** Options for {@link createEventsServerPlugin}. */\nexport interface EventsPluginOptions {\n /**\n * Object store the plugin writes Parquet files to.\n * Must implement `putBytes` (e.g. `S3ObjectStore` from `starfish-server/s3`).\n * Pass the **same** store instance that you pass to `createSyncRouter`.\n */\n store: ObjectStore\n\n /**\n * Name of the collection to intercept.\n * Must match the `name` field in the `SyncConfig.collections` entry.\n * Example: `\"events\"`\n */\n collection: string\n\n /**\n * Storage-path template for the output Parquet key.\n * Supports `{param}` placeholders resolved from the push URL's path params.\n * Example: `\"events/{app}/{batchId}\"` \u2192 `\"events/myapp/<uuid>\"`\n *\n * The plugin appends `.parquet` when the resolved key doesn't already end\n * with it, so you can omit the extension from the template.\n */\n storagePath: string\n}\n\n/**\n * Create a Starfish server plugin that encodes SunGlasses event batches as\n * Parquet and writes them to the object store.\n *\n * @example\n * ```ts\n * import { S3ObjectStore } from \"@drakkar.software/starfish-server/s3\"\n * import { createEventsServerPlugin } from \"@drakkar.software/starfish-events\"\n *\n * const store = new S3ObjectStore({ bucket: \"my-bucket\", ... })\n * const eventsPlugin = createEventsServerPlugin({\n * store,\n * collection: \"events\",\n * storagePath: \"events/{app}/{batchId}\",\n * })\n *\n * const sync = createSyncRouter({\n * store,\n * config: {\n * version: 1,\n * collections: [{\n * name: \"events\",\n * storagePath: \"events/{app}/{batchId}\",\n * readRoles: [\"public\"],\n * writeRoles: [\"public\"],\n * encryption: \"none\",\n * allowedMimeTypes: [\"application/json\"], // \u2190 JSON-typed, not parquet\n * maxBodyBytes: 8_000_000,\n * }],\n * },\n * plugins: [eventsPlugin],\n * })\n * ```\n */\nexport function createEventsServerPlugin(opts: EventsPluginOptions): ServerPlugin {\n const { store, collection, storagePath } = opts\n\n if (!store.putBytes) {\n throw new Error(\n \"[starfish-events] the provided ObjectStore does not implement putBytes. \" +\n \"Use S3ObjectStore or another store that supports binary writes.\",\n )\n }\n\n return {\n name: \"starfish-events\",\n\n interceptPush: async (ctx: PushHookContext): Promise<PushHookResult> => {\n // Only intercept the configured collection; let everything else proceed.\n if (ctx.collection !== collection) return { action: \"proceed\" }\n\n // Parse the client push envelope: { data: { events: [...] }, baseHash }\n let events: Record<string, unknown>[]\n try {\n const envelope = JSON.parse(ctx.rawBody) as {\n data?: { events?: unknown[] }\n baseHash?: string | null\n }\n const raw = envelope?.data?.events\n events = Array.isArray(raw) ? (raw as Record<string, unknown>[]) : []\n } catch {\n return {\n action: \"reject\",\n status: 400,\n error: \"Invalid JSON body \u2014 expected { data: { events: [...] }, baseHash }\",\n }\n }\n\n // Stamp ingest time server-side (never log events contents).\n const receivedAt = new Date().toISOString()\n const rows = events.map((e) => ({ ...e, received_at: receivedAt }))\n\n // Encode to Parquet.\n let parquetBytes: Uint8Array\n try {\n parquetBytes = encodeParquet(rows)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`[starfish-events] Parquet encoding failed: ${msg}`)\n return { action: \"reject\", status: 500, error: \"Parquet encoding failed\" }\n }\n\n // Resolve the output key from the storagePath template + URL params.\n let key = resolveDocumentKey(storagePath, ctx.params)\n if (!key.endsWith(\".parquet\")) key += \".parquet\"\n\n // Write to the object store. Failure propagates as 500 so the client\n // retries (SunGlasses adapter throws on non-2xx \u2192 SDK requeues the batch).\n await store.putBytes!(key, parquetBytes, { contentType: PARQUET_MIME_TYPE })\n\n // Compute SHA-256 of the stored bytes to match the binary push response format.\n const cr = getCrypto()\n // Cast: hyparquet-writer always returns a plain ArrayBuffer (never SharedArrayBuffer).\n const hashBuf = await cr.subtle.digest(\"SHA-256\", parquetBytes.buffer as ArrayBuffer)\n const hash = bytesToHex(new Uint8Array(hashBuf))\n\n // Privacy: log only counts, never event contents.\n console.log(\n `[starfish-events] wrote ${events.length} event(s) \u2192 ${key} (${parquetBytes.byteLength} bytes)`,\n )\n\n return { action: \"respond\", status: 200, body: { hash } }\n },\n }\n}\n", "/**\n * @import {Writer} from '../src/types.js'\n */\n\n/**\n * Writes data to an auto-expanding ArrayBuffer.\n *\n * @param {number} [initalSize]\n * @returns {Writer}\n */\nexport function ByteWriter(initalSize = 1024) {\n this.buffer = new ArrayBuffer(initalSize)\n this.view = new DataView(this.buffer)\n this.offset = 0 // total bytes written\n this.index = 0 // index in buffer (may be reset when flushing to file)\n return this\n}\n\n/**\n * @param {number} size\n */\nByteWriter.prototype.ensure = function(size) {\n // auto-expanding buffer\n if (this.index + size > this.buffer.byteLength) {\n const newSize = Math.max(this.buffer.byteLength * 2, this.index + size)\n const newBuffer = new ArrayBuffer(newSize)\n // TODO: save buffers until later and merge once?\n new Uint8Array(newBuffer).set(new Uint8Array(this.buffer))\n this.buffer = newBuffer\n this.view = new DataView(this.buffer)\n }\n}\n\nByteWriter.prototype.finish = function() {\n}\n\nByteWriter.prototype.getBuffer = function() {\n return this.buffer.slice(0, this.index)\n}\n\nByteWriter.prototype.getBytes = function() {\n return new Uint8Array(this.buffer, 0, this.index)\n}\n\n/**\n * @param {number} value\n */\nByteWriter.prototype.appendUint8 = function(value) {\n this.ensure(this.index + 1)\n this.view.setUint8(this.index, value)\n this.offset++\n this.index++\n}\n\n/**\n * @param {number} value\n */\nByteWriter.prototype.appendUint32 = function(value) {\n this.ensure(this.index + 4)\n this.view.setUint32(this.index, value, true)\n this.offset += 4\n this.index += 4\n}\n\n/**\n * @param {number} value\n */\nByteWriter.prototype.appendInt32 = function(value) {\n this.ensure(this.index + 4)\n this.view.setInt32(this.index, value, true)\n this.offset += 4\n this.index += 4\n}\n\n/**\n * @param {bigint} value\n */\nByteWriter.prototype.appendInt64 = function(value) {\n this.ensure(this.index + 8)\n this.view.setBigInt64(this.index, BigInt(value), true)\n this.offset += 8\n this.index += 8\n}\n\n/**\n * @param {number} value\n */\nByteWriter.prototype.appendFloat32 = function(value) {\n this.ensure(this.index + 8)\n this.view.setFloat32(this.index, value, true)\n this.offset += 4\n this.index += 4\n}\n\n/**\n * @param {number} value\n */\nByteWriter.prototype.appendFloat64 = function(value) {\n this.ensure(this.index + 8)\n this.view.setFloat64(this.index, value, true)\n this.offset += 8\n this.index += 8\n}\n\n/**\n * @param {ArrayBuffer} value\n */\nByteWriter.prototype.appendBuffer = function(value) {\n this.appendBytes(new Uint8Array(value))\n}\n\n/**\n * @param {Uint8Array} value\n */\nByteWriter.prototype.appendBytes = function(value) {\n this.ensure(this.index + value.length)\n new Uint8Array(this.buffer, this.index, value.length).set(value)\n this.offset += value.length\n this.index += value.length\n}\n\n/**\n * Convert a 32-bit signed integer to varint (1-5 bytes).\n * Writes out groups of 7 bits at a time, setting high bit if more to come.\n *\n * @param {number} value\n */\nByteWriter.prototype.appendVarInt = function(value) {\n while (true) {\n if ((value & ~0x7f) === 0) {\n // fits in 7 bits\n this.appendUint8(value)\n return\n } else {\n // write 7 bits and set high bit\n this.appendUint8(value & 0x7f | 0x80)\n value >>>= 7\n }\n }\n}\n\n/**\n * Convert a bigint to varint (1-10 bytes for 64-bit range).\n *\n * @param {bigint} value\n */\nByteWriter.prototype.appendVarBigInt = function(value) {\n while (true) {\n if ((value & ~0x7fn) === 0n) {\n // fits in 7 bits\n this.appendUint8(Number(value))\n return\n } else {\n // write 7 bits and set high bit\n this.appendUint8(Number(value & 0x7fn | 0x80n))\n value >>= 7n\n }\n }\n}\n\n/**\n * Convert number to zigzag encoding and write as varint.\n *\n * @param {number | bigint} value\n */\nByteWriter.prototype.appendZigZag = function(value) {\n if (typeof value === 'number') {\n this.appendVarInt(value << 1 ^ value >> 31)\n } else {\n this.appendVarBigInt(value << 1n ^ value >> 63n)\n }\n}\n", "/**\n * Build a tree from the schema elements.\n *\n * @param {SchemaElement[]} schema\n * @param {number} rootIndex index of the root element\n * @param {string[]} path path to the element\n * @returns {SchemaTree} tree of schema elements\n */\nfunction schemaTree(schema, rootIndex, path) {\n const element = schema[rootIndex]\n const children = []\n let count = 1\n\n // Read the specified number of children\n if (element.num_children) {\n while (children.length < element.num_children) {\n const childElement = schema[rootIndex + count]\n const child = schemaTree(schema, rootIndex + count, [...path, childElement.name])\n count += child.count\n children.push(child)\n }\n }\n\n return { count, element, children, path }\n}\n\n/**\n * Get schema elements from the root to the given element name.\n *\n * @param {SchemaElement[]} schema\n * @param {string[]} name path to the element\n * @returns {SchemaTree[]} list of schema elements\n */\nexport function getSchemaPath(schema, name) {\n let tree = schemaTree(schema, 0, [])\n const path = [tree]\n for (const part of name) {\n const child = tree.children.find(child => child.element.name === part)\n if (!child) throw new Error(`parquet schema element not found: ${name}`)\n path.push(child)\n tree = child\n }\n return path\n}\n\n/**\n * Get all physical (leaf) column names.\n *\n * @param {SchemaTree} schemaTree\n * @returns {string[]} list of physical column names\n */\nexport function getPhysicalColumns(schemaTree) {\n /** @type {string[]} */\n const columns = []\n /** @param {SchemaTree} node */\n function traverse(node) {\n if (node.children.length) {\n for (const child of node.children) {\n traverse(child)\n }\n } else {\n columns.push(node.path.join('.'))\n }\n }\n traverse(schemaTree)\n return columns\n}\n\n/**\n * Get the max repetition level for a given schema path.\n *\n * @param {SchemaTree[]} schemaPath\n * @returns {number} max repetition level\n */\nexport function getMaxRepetitionLevel(schemaPath) {\n let maxLevel = 0\n for (const { element } of schemaPath) {\n if (element.repetition_type === 'REPEATED') {\n maxLevel++\n }\n }\n return maxLevel\n}\n\n/**\n * Get the max definition level for a given schema path.\n *\n * @param {SchemaTree[]} schemaPath\n * @returns {number} max definition level\n */\nexport function getMaxDefinitionLevel(schemaPath) {\n let maxLevel = 0\n for (const { element } of schemaPath.slice(1)) {\n if (element.repetition_type !== 'REQUIRED') {\n maxLevel++\n }\n }\n return maxLevel\n}\n\n/**\n * Check if a column is list-like.\n *\n * @param {SchemaTree} schema\n * @returns {boolean} true if list-like\n */\nexport function isListLike(schema) {\n if (!schema) return false\n if (schema.element.converted_type !== 'LIST') return false\n if (schema.children.length > 1) return false\n\n const firstChild = schema.children[0]\n if (firstChild.children.length > 1) return false\n if (firstChild.element.repetition_type !== 'REPEATED') return false\n\n return true\n}\n\n/**\n * Check if a column is map-like.\n *\n * @param {SchemaTree} schema\n * @returns {boolean} true if map-like\n */\nexport function isMapLike(schema) {\n if (!schema) return false\n if (schema.element.converted_type !== 'MAP') return false\n if (schema.children.length > 1) return false\n\n const firstChild = schema.children[0]\n if (firstChild.children.length !== 2) return false\n if (firstChild.element.repetition_type !== 'REPEATED') return false\n\n const keyChild = firstChild.children.find(child => child.element.name === 'key')\n if (keyChild?.element.repetition_type === 'REPEATED') return false\n\n const valueChild = firstChild.children.find(child => child.element.name === 'value')\n if (valueChild?.element.repetition_type === 'REPEATED') return false\n\n return true\n}\n\n/**\n * Returns true if a column is non-nested.\n *\n * @param {SchemaTree[]} schemaPath\n * @returns {boolean}\n */\nexport function isFlatColumn(schemaPath) {\n if (schemaPath.length !== 2) return false\n const [, column] = schemaPath\n if (column.element.repetition_type === 'REPEATED') return false\n if (column.children.length) return false\n return true\n}\n\n/**\n * @import {SchemaElement, SchemaTree} from '../src/types.js'\n */\n", "// XxHash64 (https://github.com/Cyan4973/xxHash/blob/dev/doc/xxhash_spec.md)\n// Used by parquet bloom filters: hashes the PLAIN encoding of column values with seed 0.\n\nconst MASK = 0xffffffffffffffffn\nconst PRIME1 = 0x9e3779b185ebca87n\nconst PRIME2 = 0xc2b2ae3d27d4eb4fn\nconst PRIME3 = 0x165667b19e3779f9n\nconst PRIME4 = 0x85ebca77c2b2ae63n\nconst PRIME5 = 0x27d4eb2f165667c5n\n\n/**\n * @param {bigint} x\n * @param {bigint} r rotation amount in bits (1..63)\n * @returns {bigint}\n */\nfunction rotl64(x, r) {\n return (x << r | x >> 64n - r) & MASK\n}\n\n/**\n * @param {bigint} acc\n * @param {bigint} val\n * @returns {bigint}\n */\nfunction round(acc, val) {\n acc = acc + val * PRIME2 & MASK\n acc = rotl64(acc, 31n)\n return acc * PRIME1 & MASK\n}\n\n/**\n * @param {bigint} acc\n * @param {bigint} val\n * @returns {bigint}\n */\nfunction mergeRound(acc, val) {\n acc ^= round(0n, val)\n return acc * PRIME1 + PRIME4 & MASK\n}\n\n/**\n * Compute the 64-bit xxHash of a byte buffer.\n *\n * @param {Uint8Array} input\n * @param {bigint} [seed]\n * @returns {bigint} 64-bit hash\n */\nexport function xxhash64(input, seed = 0n) {\n const view = new DataView(input.buffer, input.byteOffset, input.byteLength)\n const len = input.byteLength\n let offset = 0\n let h64\n\n if (len >= 32) {\n let v1 = seed + PRIME1 + PRIME2 & MASK\n let v2 = seed + PRIME2 & MASK\n let v3 = seed\n let v4 = seed - PRIME1 & MASK\n\n while (offset + 32 <= len) {\n v1 = round(v1, view.getBigUint64(offset, true)); offset += 8\n v2 = round(v2, view.getBigUint64(offset, true)); offset += 8\n v3 = round(v3, view.getBigUint64(offset, true)); offset += 8\n v4 = round(v4, view.getBigUint64(offset, true)); offset += 8\n }\n\n h64 = rotl64(v1, 1n) + rotl64(v2, 7n) + rotl64(v3, 12n) + rotl64(v4, 18n) & MASK\n h64 = mergeRound(h64, v1)\n h64 = mergeRound(h64, v2)\n h64 = mergeRound(h64, v3)\n h64 = mergeRound(h64, v4)\n } else {\n h64 = seed + PRIME5 & MASK\n }\n\n h64 = h64 + BigInt(len) & MASK\n\n while (offset + 8 <= len) {\n h64 ^= round(0n, view.getBigUint64(offset, true))\n h64 = rotl64(h64, 27n) * PRIME1 + PRIME4 & MASK\n offset += 8\n }\n\n if (offset + 4 <= len) {\n h64 ^= BigInt(view.getUint32(offset, true)) * PRIME1 & MASK\n h64 = rotl64(h64, 23n) * PRIME2 + PRIME3 & MASK\n offset += 4\n }\n\n while (offset < len) {\n h64 ^= BigInt(view.getUint8(offset)) * PRIME5 & MASK\n h64 = rotl64(h64, 11n) * PRIME1 & MASK\n offset += 1\n }\n\n h64 ^= h64 >> 33n\n h64 = h64 * PRIME2 & MASK\n h64 ^= h64 >> 29n\n h64 = h64 * PRIME3 & MASK\n h64 ^= h64 >> 32n\n return h64\n}\n", "// Split Block Bloom Filter (https://github.com/apache/parquet-format/blob/master/BloomFilter.md)\n// A bloom filter is a sequence of 32-byte blocks. Each block holds 8 little-endian uint32 words.\n// Insertion sets one bit per word, chosen by salting the low 32 bits of an xxhash64.\n// Membership requires all 8 bits to be set; misses are exact, hits are probabilistic.\n\nimport { deserializeTCompactProtocol } from './thrift.js'\nimport { xxhash64 } from './xxhash.js'\n\n/**\n * @import {BloomFilter, DataReader, ParquetQueryFilter, SchemaElement} from '../src/types.js'\n */\n\nconst textEncoder = new TextEncoder()\n\nconst SALT = new Uint32Array([\n 0x47b6137b, 0x44974d91, 0x8824ad5b, 0xa2b7289d,\n 0x705495c7, 0x2df1424b, 0x9efc4947, 0x5c6bfb31,\n])\n\n/**\n * Map the high 32 bits of a hash to a block index in [0, numBlocks).\n *\n * @param {bigint} hash\n * @param {number} numBlocks\n * @returns {number}\n */\nfunction blockIndex(hash, numBlocks) {\n return Number((hash >> 32n) * BigInt(numBlocks) >> 32n)\n}\n\n/**\n * Per-block mask: 8 uint32 words, each with a single bit set at position `(low32 * SALT[i]) >> 27`.\n *\n * @param {bigint} hash\n * @returns {Uint32Array}\n */\nfunction blockMask(hash) {\n const m = new Uint32Array(8)\n const low = Number(hash & 0xffffffffn) | 0\n for (let i = 0; i < 8; i++) {\n m[i] = 1 << (Math.imul(low, SALT[i]) >>> 27)\n }\n return m\n}\n\n/**\n * Insert a hash into a Split Block Bloom Filter.\n *\n * @param {Uint32Array} blocks bloom filter words (8 * numBlocks long)\n * @param {bigint} hash 64-bit xxhash of the parquet-plain-encoded value\n */\nexport function sbbfInsert(blocks, hash) {\n const offset = blockIndex(hash, blocks.length >> 3) << 3\n const m = blockMask(hash)\n for (let i = 0; i < 8; i++) {\n blocks[offset + i] |= m[i]\n }\n}\n\n/**\n * Test whether a hash might be present in a Split Block Bloom Filter.\n * False positives are possible; false negatives are not.\n *\n * @param {Uint32Array} blocks bloom filter words (8 * numBlocks long)\n * @param {bigint} hash 64-bit xxhash of the parquet-plain-encoded value\n * @returns {boolean}\n */\nexport function sbbfContains(blocks, hash) {\n const offset = blockIndex(hash, blocks.length >> 3) << 3\n const m = blockMask(hash)\n for (let i = 0; i < 8; i++) {\n if ((blocks[offset + i] & m[i]) === 0) return false\n }\n return true\n}\n\n/**\n * Parse a Split Block Bloom Filter from a reader positioned at the BloomFilterHeader.\n * Returns undefined when the header advertises an unsupported algorithm, hash, or\n * compression \u2014 callers should treat that as \"cannot use this bloom filter.\"\n *\n * @param {DataReader} reader\n * @returns {BloomFilter | undefined}\n */\nexport function readBloomFilter(reader) {\n const header = deserializeTCompactProtocol(reader)\n const numBytes = header.field_1\n if (typeof numBytes !== 'number' || numBytes <= 0 || numBytes % 32 !== 0) return undefined\n // BloomFilterAlgorithm / Hash / Compression are unions with a single supported variant each.\n if (!header.field_2?.field_1) return undefined // algorithm must be BLOCK\n if (!header.field_3?.field_1) return undefined // hash must be XXHASH\n if (!header.field_4?.field_1) return undefined // compression must be UNCOMPRESSED\n\n const { view, offset } = reader\n if (offset + numBytes > view.byteLength) {\n throw new Error(`parquet bloom filter truncated: need ${numBytes} bytes, have ${view.byteLength - offset}`)\n }\n // Reader offset is not 4-aligned in general, and we want endian-portable reads.\n const blocks = new Uint32Array(numBytes >> 2)\n for (let i = 0; i < blocks.length; i++) {\n blocks[i] = view.getUint32(offset + i * 4, true)\n }\n reader.offset = offset + numBytes\n return { numBytes, blocks }\n}\n\n/**\n * Hash a JS filter value as its parquet PLAIN-encoded bytes, suitable for a\n * bloom filter lookup. Returns undefined when the column's parser is lossy or\n * ambiguous (DATE, TIMESTAMP_*, DECIMAL, JSON, BSON, INT96, FLOAT16, UUID,\n * GEOMETRY, GEOGRAPHY, INTERVAL) or when the JS value type doesn't match the\n * column. Callers must treat undefined as \"bloom filter cannot help.\"\n *\n * @param {any} value\n * @param {SchemaElement} element\n * @returns {bigint | undefined}\n */\nexport function hashParquetValue(value, element) {\n if (value === null || value === undefined) return undefined\n const { type, converted_type, logical_type } = element\n\n if (type === 'BOOLEAN') {\n if (typeof value !== 'boolean') return undefined\n return xxhash64(new Uint8Array([value ? 1 : 0]))\n }\n\n if (type === 'FLOAT') {\n if (typeof value !== 'number') return undefined\n const buf = new ArrayBuffer(4)\n new DataView(buf).setFloat32(0, value, true)\n return xxhash64(new Uint8Array(buf))\n }\n\n if (type === 'DOUBLE') {\n if (typeof value !== 'number') return undefined\n const buf = new ArrayBuffer(8)\n new DataView(buf).setFloat64(0, value, true)\n return xxhash64(new Uint8Array(buf))\n }\n\n if (type === 'INT32') {\n if (converted_type === 'DATE' || converted_type === 'DECIMAL' || converted_type === 'TIME_MILLIS') return undefined\n if (logical_type?.type === 'DATE' || logical_type?.type === 'TIME' || logical_type?.type === 'DECIMAL') return undefined\n if (typeof value !== 'number' || !Number.isInteger(value)) return undefined\n const buf = new ArrayBuffer(4)\n new DataView(buf).setInt32(0, value | 0, true)\n return xxhash64(new Uint8Array(buf))\n }\n\n if (type === 'INT64') {\n if (converted_type === 'TIMESTAMP_MILLIS' || converted_type === 'TIMESTAMP_MICROS') return undefined\n if (converted_type === 'TIME_MICROS' || converted_type === 'DECIMAL') return undefined\n if (logical_type?.type === 'TIMESTAMP' || logical_type?.type === 'TIME' || logical_type?.type === 'DECIMAL') return undefined\n let bigValue\n if (typeof value === 'bigint') bigValue = value\n else if (typeof value === 'number' && Number.isSafeInteger(value)) bigValue = BigInt(value)\n else return undefined\n const buf = new ArrayBuffer(8)\n new DataView(buf).setBigUint64(0, BigInt.asUintN(64, bigValue), true)\n return xxhash64(new Uint8Array(buf))\n }\n\n if (type === 'BYTE_ARRAY') {\n if (converted_type === 'JSON' || converted_type === 'BSON' || converted_type === 'DECIMAL') return undefined\n if (logical_type?.type === 'JSON' || logical_type?.type === 'BSON' || logical_type?.type === 'VARIANT') return undefined\n if (logical_type?.type === 'GEOMETRY' || logical_type?.type === 'GEOGRAPHY') return undefined\n if (typeof value === 'string') return xxhash64(textEncoder.encode(value))\n if (value instanceof Uint8Array) return xxhash64(value)\n return undefined\n }\n\n if (type === 'FIXED_LEN_BYTE_ARRAY') {\n if (converted_type === 'DECIMAL' || converted_type === 'INTERVAL') return undefined\n if (logical_type?.type === 'DECIMAL' || logical_type?.type === 'UUID' || logical_type?.type === 'FLOAT16') return undefined\n if (logical_type?.type === 'GEOMETRY' || logical_type?.type === 'GEOGRAPHY') return undefined\n if (value instanceof Uint8Array) return xxhash64(value)\n return undefined\n }\n\n // INT96 deprecated, or type missing on group columns\n return undefined\n}\n\n/**\n * Top-level column names that appear in $eq or $in predicates within a filter.\n * These are the only columns where a bloom filter can prove a value's absence\n * and let us skip a row group; any other operator can't be helped by a bloom.\n *\n * @param {ParquetQueryFilter | undefined} filter\n * @returns {Set<string>}\n */\nexport function bloomEligibleColumns(filter) {\n /** @type {Set<string>} */\n const out = new Set()\n walkBloomEligible(filter, out)\n return out\n}\n\n/**\n * @param {ParquetQueryFilter | undefined} filter\n * @param {Set<string>} out\n */\nfunction walkBloomEligible(filter, out) {\n if (!filter) return\n if ('$and' in filter && Array.isArray(filter.$and)) {\n for (const sub of filter.$and) walkBloomEligible(sub, out)\n return\n }\n if ('$or' in filter && Array.isArray(filter.$or)) {\n for (const sub of filter.$or) walkBloomEligible(sub, out)\n return\n }\n // $nor would need to prove presence, not absence \u2014 bloom can't help.\n if ('$nor' in filter) return\n for (const [field, condition] of Object.entries(filter)) {\n if (field.startsWith('$')) continue\n if (typeof condition === 'object' && condition !== null && !Array.isArray(condition)) {\n if ('$eq' in condition || '$in' in condition) out.add(field)\n } else {\n // primitive / null / array condition is an implicit $eq\n out.add(field)\n }\n }\n}\n", "/**\n * @import {ThriftType} from 'hyparquet/src/types.js'\n * @import {Writer} from '../src/types.js'\n */\n\n// TCompactProtocol types\nconst STOP = 0\nconst TRUE = 1\nconst FALSE = 2\nconst BYTE = 3\nconst I32 = 5\nconst I64 = 6\nconst DOUBLE = 7\nconst BINARY = 8\nconst LIST = 9\nconst STRUCT = 12\n\n/**\n * Serialize a JS object in TCompactProtocol format.\n *\n * Expects keys named like \"field_1\", \"field_2\", etc. in ascending order.\n *\n * @param {Writer} writer\n * @param {{ [key: `field_${number}`]: any }} data\n */\nexport function serializeTCompactProtocol(writer, data) {\n writeElement(writer, STRUCT, data)\n}\n\n/**\n * Write a single value of a given compact type.\n *\n * @param {Writer} writer\n * @param {number} type\n * @param {ThriftType} value\n */\nfunction writeElement(writer, type, value) {\n // true/false is stored in the type\n if (type === TRUE) return\n if (type === FALSE) return\n if (type === BYTE && typeof value === 'number') {\n writer.appendUint8(value)\n } else if (type === I32 && typeof value === 'number') {\n writer.appendZigZag(value)\n } else if (type === I64 && typeof value === 'bigint') {\n writer.appendZigZag(value)\n } else if (type === DOUBLE && typeof value === 'number') {\n writer.appendFloat64(value)\n } else if (type === BINARY && typeof value === 'string') {\n // store length as a varint, then raw bytes\n const bytes = new TextEncoder().encode(value)\n writer.appendVarInt(bytes.length)\n writer.appendBytes(bytes)\n } else if (type === BINARY && value instanceof Uint8Array) {\n // store length as a varint, then raw bytes\n writer.appendVarInt(value.byteLength)\n writer.appendBytes(value)\n } else if (type === LIST && Array.isArray(value)) {\n // Guess the element type from the first element\n const elemType = getCompactTypeForList(value)\n\n // Header: size << 4 | elementType\n if (value.length > 14) {\n writer.appendUint8(15 << 4 | elemType)\n writer.appendVarInt(value.length)\n } else {\n writer.appendUint8(value.length << 4 | elemType)\n }\n\n if (elemType === FALSE) {\n // Special case for boolean list\n for (const v of value) {\n writer.appendUint8(v ? 1 : 0)\n }\n } else {\n for (const v of value) {\n writeElement(writer, elemType, v)\n }\n }\n } else if (type === STRUCT && typeof value === 'object') {\n // write struct fields\n let lastFid = 0\n for (const [k, v] of Object.entries(value)) {\n if (v === undefined) continue\n\n const fid = parseInt(k.replace(/^field_/, ''), 10)\n if (Number.isNaN(fid)) {\n throw new Error(`thrift invalid field name: ${k}. Expected \"field_###\"`)\n }\n const t = getCompactTypeForValue(v)\n const delta = fid - lastFid\n if (delta <= 0) {\n throw new Error(`thrift non-monotonic field id: fid=${fid}, lastFid=${lastFid}`)\n }\n if (delta > 15) {\n writer.appendUint8(t)\n writer.appendZigZag(fid)\n } else {\n writer.appendUint8(delta << 4 | t)\n }\n writeElement(writer, t, v)\n lastFid = fid\n }\n // end struct\n writer.appendUint8(STOP)\n } else {\n throw new Error(`thrift invalid type ${type} for value ${value}`)\n }\n}\n\n/**\n * Infer type from JS value\n *\n * @param {any} value\n * @returns {number} CompactType\n */\nfunction getCompactTypeForValue(value) {\n if (value === true) return TRUE\n if (value === false) return FALSE\n if (Number.isInteger(value)) return I32\n if (typeof value === 'number') return DOUBLE\n if (typeof value === 'bigint') return I64\n if (typeof value === 'string') return BINARY\n if (value instanceof Uint8Array) return BINARY\n if (Array.isArray(value)) return LIST\n if (value && typeof value === 'object') return STRUCT\n throw new Error(`Cannot determine thrift compact type for: ${value}`)\n}\n\n/**\n * Infer type for list elements, expand types as needed\n *\n * @param {any[]} value\n * @returns {number} CompactType\n */\nfunction getCompactTypeForList(value) {\n let elemType = 0\n for (const v of value) {\n let t = getCompactTypeForValue(v)\n if (t === TRUE) t = FALSE // booleans map to FALSE\n if (!elemType) elemType = t // first element\n if (elemType === DOUBLE && t === I32) t = DOUBLE // expand int to float\n if (elemType === I32 && t === DOUBLE) elemType = DOUBLE // expand int to float\n if (t !== elemType) {\n throw new Error(`thrift invalid type for list element: ${v} (expected type ${elemType})`)\n }\n }\n return elemType ?? BYTE // BYTE for empty list\n}\n", "// Split Block Bloom Filter (https://github.com/apache/parquet-format/blob/master/BloomFilter.md)\n// A bloom filter is a sequence of 32-byte blocks. Each block holds 8 little-endian uint32 words.\n// Insertion sets one bit per word, chosen by salting the low 32 bits of an xxhash64.\n// Membership requires all 8 bits to be set; misses are exact, hits are probabilistic.\n\nimport { hashParquetValue } from 'hyparquet/src/bloom.js'\nimport { serializeTCompactProtocol } from './thrift.js'\n\n/**\n * @import {SchemaElement} from 'hyparquet'\n * @import {PageIndexes, Writer} from '../src/types.js'\n */\n\nconst SALT = new Uint32Array([\n 0x47b6137b, 0x44974d91, 0x8824ad5b, 0xa2b7289d,\n 0x705495c7, 0x2df1424b, 0x9efc4947, 0x5c6bfb31,\n])\n\nconst BYTES_PER_BLOCK = 32\nconst MIN_BYTES = 32 // one block\nconst MAX_BYTES = 128 * 1024 * 1024 // parquet-mr default cap\n\n/**\n * Map the high 32 bits of a hash to a block index in [0, numBlocks).\n *\n * @param {bigint} hash\n * @param {number} numBlocks\n * @returns {number}\n */\nfunction blockIndex(hash, numBlocks) {\n return Number((hash >> 32n) * BigInt(numBlocks) >> 32n)\n}\n\n/**\n * Per-block mask: 8 uint32 words, each with a single bit set at position `(low32 * SALT[i]) >> 27`.\n *\n * @param {bigint} hash\n * @returns {Uint32Array}\n */\nfunction blockMask(hash) {\n const m = new Uint32Array(8)\n const low = Number(hash & 0xffffffffn) | 0\n for (let i = 0; i < 8; i++) {\n m[i] = 1 << (Math.imul(low, SALT[i]) >>> 27)\n }\n return m\n}\n\n/**\n * Insert a hash into a Split Block Bloom Filter.\n *\n * @param {Uint32Array} blocks bloom filter words (8 * numBlocks long)\n * @param {bigint} hash 64-bit xxhash of the parquet-plain-encoded value\n */\nexport function sbbfInsert(blocks, hash) {\n const offset = blockIndex(hash, blocks.length >> 3) << 3\n const m = blockMask(hash)\n for (let i = 0; i < 8; i++) {\n blocks[offset + i] |= m[i]\n }\n}\n\n/**\n * Test whether a hash might be present in a Split Block Bloom Filter.\n * False positives are possible; false negatives are not.\n *\n * @param {Uint32Array} blocks bloom filter words (8 * numBlocks long)\n * @param {bigint} hash 64-bit xxhash of the parquet-plain-encoded value\n * @returns {boolean}\n */\nexport function sbbfContains(blocks, hash) {\n const offset = blockIndex(hash, blocks.length >> 3) << 3\n const m = blockMask(hash)\n for (let i = 0; i < 8; i++) {\n if ((blocks[offset + i] & m[i]) === 0) return false\n }\n return true\n}\n\n/**\n * Round up to the next power of two (32-bit).\n *\n * @param {number} n\n * @returns {number}\n */\nfunction nextPowerOfTwo(n) {\n let p = 1\n while (p < n) p <<= 1\n return p\n}\n\n/**\n * Optimal SBBF size in bytes for a given number of distinct values and\n * target false-positive probability. Matches parquet-mr's BlockSplitBloomFilter:\n * derives bits from m = -8 * ndv / ln(1 - p^(1/8)), rounds up to a whole block,\n * and snaps to the next power of two below 1024 bits.\n *\n * @param {number} ndv expected number of distinct values\n * @param {number} fpp target false positive probability, in (0, 1)\n * @returns {number} bloom filter size in bytes (multiple of 32)\n */\nexport function optimalNumBytes(ndv, fpp) {\n if (!(fpp > 0 && fpp < 1)) throw new Error(`bloom filter fpp must be in (0, 1), got ${fpp}`)\n if (!(ndv >= 0)) throw new Error(`bloom filter ndv must be >= 0, got ${ndv}`)\n const m = -8 * ndv / Math.log(1 - fpp ** (1 / 8))\n let numBits = Math.ceil(m)\n if (!isFinite(numBits) || numBits > MAX_BYTES << 3) numBits = MAX_BYTES << 3\n // Round up to whole 32-byte blocks\n const blockBits = BYTES_PER_BLOCK << 3\n numBits = Math.ceil(numBits / blockBits) * blockBits\n let numBytes = numBits >> 3\n if (numBytes < MIN_BYTES) numBytes = MIN_BYTES\n // Power-of-two snap below 1024 bytes (matches parquet-mr behavior)\n if (numBytes < 1024) numBytes = nextPowerOfTwo(numBytes)\n return numBytes\n}\n\n/**\n * Allocate a zeroed Split Block Bloom Filter sized for the given NDV and FPP.\n *\n * @param {number} ndv expected number of distinct values\n * @param {number} [fpp] target false positive probability, default 0.01\n * @returns {Uint32Array} blocks (numBytes / 4 uint32 words)\n */\nexport function createBloomFilter(ndv, fpp = 0.01) {\n const numBytes = optimalNumBytes(ndv, fpp)\n return new Uint32Array(numBytes >> 2)\n}\n\n/**\n * Collects distinct hashes of column values and finalizes them into an SBBF\n * sized for the actual distinct count. `finalize` returns `undefined` if any\n * non-null value was unhashable (the filter would have false negatives), if\n * no values were seen, or if the optimal size exceeds `maxBytes`.\n */\nexport class BloomBuilder {\n /**\n * @param {SchemaElement} element\n * @param {{ fpp?: number, maxBytes?: number }} [options]\n */\n constructor(element, { fpp = 0.01, maxBytes = 1024 * 1024 } = {}) {\n this.element = element\n this.fpp = fpp\n this.maxBytes = maxBytes\n /** @type {Set<bigint>} */\n this.hashes = new Set()\n this.skipped = 0\n }\n\n /** @param {any} value */\n insert(value) {\n if (value === null || value === undefined) return\n const h = hashParquetValue(value, this.element)\n if (h === undefined) {\n this.skipped++\n return\n }\n this.hashes.add(h)\n }\n\n /** @returns {Uint32Array | undefined} */\n finalize() {\n if (this.skipped > 0 || this.hashes.size === 0) return undefined\n const numBytes = optimalNumBytes(this.hashes.size, this.fpp)\n if (numBytes > this.maxBytes) return undefined\n const blocks = new Uint32Array(numBytes >> 2)\n for (const h of this.hashes) sbbfInsert(blocks, h)\n return blocks\n }\n}\n\n/**\n * Write a parquet bloom filter: BloomFilterHeader thrift struct followed by\n * the raw little-endian bytes of the SBBF blocks. Always uses BLOCK / XXHASH /\n * UNCOMPRESSED, the only variants parquet currently defines.\n *\n * @param {Writer} writer\n * @param {Uint32Array} blocks bloom filter words (8 * numBlocks long)\n */\nexport function writeBloomFilter(writer, blocks) {\n if (blocks.length % 8 !== 0) {\n throw new Error(`bloom filter block count must be a multiple of 8 uint32 words, got ${blocks.length}`)\n }\n serializeTCompactProtocol(writer, {\n field_1: blocks.byteLength, // numBytes\n field_2: { field_1: {} }, // algorithm: SplitBlockAlgorithm\n field_3: { field_1: {} }, // hash: XxHash\n field_4: { field_1: {} }, // compression: Uncompressed\n })\n for (let i = 0; i < blocks.length; i++) {\n writer.appendUint32(blocks[i])\n }\n}\n\n/**\n * Write all pending bloom filters in a contiguous block and patch each chunk's\n * meta_data.bloom_filter_offset / bloom_filter_length so readers can find them.\n * Clustering matches parquet-mr's tail placement: a reader fetching the footer\n * region can pull every bloom in one range request.\n *\n * @param {Writer} writer\n * @param {PageIndexes[]} pageIndexes\n */\nexport function writeBlooms(writer, pageIndexes) {\n for (const { chunk, bloomFilter } of pageIndexes) {\n if (!bloomFilter || !chunk.meta_data) continue\n const offset = writer.offset\n writeBloomFilter(writer, bloomFilter)\n chunk.meta_data.bloom_filter_offset = BigInt(offset)\n chunk.meta_data.bloom_filter_length = writer.offset - offset\n }\n}\n", "\n/** @type {import('../src/types.d.ts').ParquetType[]} */\nexport const ParquetTypes = [\n 'BOOLEAN',\n 'INT32',\n 'INT64',\n 'INT96', // deprecated\n 'FLOAT',\n 'DOUBLE',\n 'BYTE_ARRAY',\n 'FIXED_LEN_BYTE_ARRAY',\n]\n\n/** @type {import('../src/types.d.ts').Encoding[]} */\nexport const Encodings = [\n 'PLAIN',\n 'GROUP_VAR_INT', // deprecated\n 'PLAIN_DICTIONARY',\n 'RLE',\n 'BIT_PACKED', // deprecated\n 'DELTA_BINARY_PACKED',\n 'DELTA_LENGTH_BYTE_ARRAY',\n 'DELTA_BYTE_ARRAY',\n 'RLE_DICTIONARY',\n 'BYTE_STREAM_SPLIT',\n]\n\n/** @type {import('../src/types.d.ts').FieldRepetitionType[]} */\nexport const FieldRepetitionTypes = [\n 'REQUIRED',\n 'OPTIONAL',\n 'REPEATED',\n]\n\n/** @type {import('../src/types.d.ts').ConvertedType[]} */\nexport const ConvertedTypes = [\n 'UTF8',\n 'MAP',\n 'MAP_KEY_VALUE',\n 'LIST',\n 'ENUM',\n 'DECIMAL',\n 'DATE',\n 'TIME_MILLIS',\n 'TIME_MICROS',\n 'TIMESTAMP_MILLIS',\n 'TIMESTAMP_MICROS',\n 'UINT_8',\n 'UINT_16',\n 'UINT_32',\n 'UINT_64',\n 'INT_8',\n 'INT_16',\n 'INT_32',\n 'INT_64',\n 'JSON',\n 'BSON',\n 'INTERVAL',\n]\n\n/** @type {import('../src/types.d.ts').CompressionCodec[]} */\nexport const CompressionCodecs = [\n 'UNCOMPRESSED',\n 'SNAPPY',\n 'GZIP',\n 'LZO',\n 'BROTLI',\n 'LZ4',\n 'ZSTD',\n 'LZ4_RAW',\n]\n\n/** @type {import('../src/types.d.ts').PageType[]} */\nexport const PageTypes = [\n 'DATA_PAGE',\n 'INDEX_PAGE',\n 'DICTIONARY_PAGE',\n 'DATA_PAGE_V2',\n]\n\n/** @type {import('../src/types.d.ts').BoundaryOrder[]} */\nexport const BoundaryOrders = [\n 'UNORDERED',\n 'ASCENDING',\n 'DESCENDING',\n]\n\n/** @type {import('../src/types.d.ts').EdgeInterpolationAlgorithm[]} */\nexport const EdgeInterpolationAlgorithms = [\n 'SPHERICAL',\n 'VINCENTY',\n 'THOMAS',\n 'ANDOYER',\n 'KARNEY',\n]\n", "/**\n * Delta Binary Packed encoding for parquet.\n * Encodes integers as deltas with variable bit-width packing.\n *\n * @import {DecodedArray} from 'hyparquet'\n * @import {Writer} from '../src/types.js'\n */\n\nconst BLOCK_SIZE = 128\nconst MINIBLOCKS_PER_BLOCK = 4\nconst VALUES_PER_MINIBLOCK = BLOCK_SIZE / MINIBLOCKS_PER_BLOCK // 32\n\n/**\n * Write values using delta binary packed encoding.\n *\n * @param {Writer} writer\n * @param {DecodedArray} values\n */\nexport function deltaBinaryPack(writer, values) {\n const count = values.length\n if (count === 0) {\n // Write header with zero count\n writer.appendVarInt(BLOCK_SIZE)\n writer.appendVarInt(MINIBLOCKS_PER_BLOCK)\n writer.appendVarInt(0)\n writer.appendVarInt(0)\n return\n }\n if (typeof values[0] !== 'number' && typeof values[0] !== 'bigint') {\n throw new Error('deltaBinaryPack only supports number or bigint arrays')\n }\n\n // Write header\n writer.appendVarInt(BLOCK_SIZE)\n writer.appendVarInt(MINIBLOCKS_PER_BLOCK)\n writer.appendVarInt(count)\n writer.appendZigZag(values[0])\n\n // Process blocks\n let index = 1\n while (index < count) {\n const blockEnd = Math.min(index + BLOCK_SIZE, count)\n const blockSize = blockEnd - index\n\n // Compute deltas for this block\n const blockDeltas = new BigInt64Array(blockSize)\n let minDelta = BigInt(values[index]) - BigInt(values[index - 1])\n blockDeltas[0] = minDelta\n for (let i = 1; i < blockSize; i++) {\n const delta = BigInt(values[index + i]) - BigInt(values[index + i - 1])\n blockDeltas[i] = delta\n if (delta < minDelta) minDelta = delta\n }\n writer.appendZigZag(minDelta)\n\n // Calculate bit widths for each miniblock\n const bitWidths = new Uint8Array(MINIBLOCKS_PER_BLOCK)\n for (let mb = 0; mb < MINIBLOCKS_PER_BLOCK; mb++) {\n const mbStart = mb * VALUES_PER_MINIBLOCK\n const mbEnd = Math.min(mbStart + VALUES_PER_MINIBLOCK, blockSize)\n\n let maxAdjusted = 0n\n for (let i = mbStart; i < mbEnd; i++) {\n const adjusted = blockDeltas[i] - minDelta\n if (adjusted > maxAdjusted) maxAdjusted = adjusted\n }\n bitWidths[mb] = bitWidth(maxAdjusted)\n }\n\n // Write bit widths\n writer.appendBytes(bitWidths)\n\n // Write packed miniblocks\n for (let mb = 0; mb < MINIBLOCKS_PER_BLOCK; mb++) {\n const bitWidth = bitWidths[mb]\n if (bitWidth === 0) continue // No data needed for zero bit width\n\n const mbStart = mb * VALUES_PER_MINIBLOCK\n const mbEnd = Math.min(mbStart + VALUES_PER_MINIBLOCK, blockSize)\n\n // Bit pack the adjusted deltas\n let buffer = 0n\n let bitsUsed = 0\n\n for (let i = 0; i < VALUES_PER_MINIBLOCK; i++) {\n const adjusted = mbStart + i < mbEnd ? blockDeltas[mbStart + i] - minDelta : 0n\n buffer |= adjusted << BigInt(bitsUsed)\n bitsUsed += bitWidth\n\n // Flush complete bytes\n while (bitsUsed >= 8) {\n writer.appendUint8(Number(buffer & 0xffn))\n buffer >>= 8n\n bitsUsed -= 8\n }\n }\n // assert(bitsUsed === 0) // because multiple of 8\n }\n\n index = blockEnd\n }\n}\n\n/**\n * Write byte arrays using delta length encoding.\n * Encodes lengths using delta binary packed, then writes raw bytes.\n *\n * @param {Writer} writer\n * @param {DecodedArray} values\n */\nexport function deltaLengthByteArray(writer, values) {\n // Extract lengths\n const lengths = new Int32Array(values.length)\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n if (!(value instanceof Uint8Array)) {\n throw new Error('deltaLengthByteArray expects Uint8Array values')\n }\n lengths[i] = value.length\n }\n\n // Write delta-packed lengths\n deltaBinaryPack(writer, lengths)\n\n // Write raw byte data\n for (const value of values) {\n writer.appendBytes(value)\n }\n}\n\n/**\n * Write byte arrays using delta encoding with prefix compression.\n * Stores common prefixes with previous value to improve compression.\n *\n * @param {Writer} writer\n * @param {DecodedArray} values\n */\nexport function deltaByteArray(writer, values) {\n if (values.length === 0) {\n deltaBinaryPack(writer, [])\n deltaBinaryPack(writer, [])\n return\n }\n\n // Calculate prefix lengths and suffixes\n const prefixLengths = new Int32Array(values.length)\n const suffixLengths = new Int32Array(values.length)\n /** @type {Uint8Array[]} */\n const suffixes = new Array(values.length)\n\n // First value has no prefix\n const value = values[0]\n if (!(value instanceof Uint8Array)) {\n throw new Error('deltaByteArray expects Uint8Array values')\n }\n prefixLengths[0] = 0\n suffixLengths[0] = values[0].length\n suffixes[0] = values[0]\n\n for (let i = 1; i < values.length; i++) {\n const prev = values[i - 1]\n const curr = values[i]\n if (!(curr instanceof Uint8Array)) {\n throw new Error('deltaByteArray expects Uint8Array values')\n }\n\n // Find common prefix length\n let prefixLen = 0\n const maxPrefix = Math.min(prev.length, curr.length)\n while (prefixLen < maxPrefix && prev[prefixLen] === curr[prefixLen]) {\n prefixLen++\n }\n\n prefixLengths[i] = prefixLen\n suffixLengths[i] = curr.length - prefixLen\n suffixes[i] = curr.subarray(prefixLen)\n }\n\n // Write delta-packed prefix lengths\n deltaBinaryPack(writer, prefixLengths)\n\n // Write delta-packed suffix lengths\n deltaBinaryPack(writer, suffixLengths)\n\n // Write suffix bytes\n for (const suffix of suffixes) {\n writer.appendBytes(suffix)\n }\n}\n\n/**\n * Minimum bits needed to store value.\n *\n * @param {bigint} value\n * @returns {number}\n */\nfunction bitWidth(value) {\n if (value === 0n) return 0\n let bits = 0\n while (value > 0n) {\n bits++\n value >>= 1n\n }\n return bits\n}\n", "/**\n * @import {DecodedArray} from 'hyparquet'\n * @import {Writer} from '../src/types.js'\n */\n\n/**\n * @param {Writer} writer\n * @param {DecodedArray} values\n * @param {number} bitWidth\n * @returns {number} bytes written\n */\nexport function writeRleBitPackedHybrid(writer, values, bitWidth) {\n const offsetStart = writer.offset\n let pendingBitPackedGroups = 0\n let bitPackedStart = 0\n let i = 0\n\n while (i < values.length) {\n // Try to write RLE runs of 8+ values\n let rleCount = 1\n const firstVal = values[i]\n while (i + rleCount < values.length && values[i + rleCount] === firstVal) {\n rleCount++\n }\n if (rleCount >= 8) {\n // Flush pending bit-packed groups\n if (pendingBitPackedGroups) {\n writeBitPackedGroups(writer, values, bitPackedStart, pendingBitPackedGroups, bitWidth)\n pendingBitPackedGroups = 0\n }\n\n // Write RLE run\n writeRleRun(writer, firstVal, rleCount, bitWidth)\n i += rleCount\n } else {\n // Add to pending bit-packed groups\n if (pendingBitPackedGroups === 0) {\n bitPackedStart = i\n }\n pendingBitPackedGroups++\n i += 8\n }\n }\n\n // Flush remaining\n if (pendingBitPackedGroups) {\n writeBitPackedGroups(writer, values, bitPackedStart, pendingBitPackedGroups, bitWidth)\n }\n\n return writer.offset - offsetStart\n}\n\n/**\n * Write a single RLE run: a repeated value and its count.\n *\n * @param {Writer} writer\n * @param {number} value\n * @param {number} count\n * @param {number} bitWidth\n */\nfunction writeRleRun(writer, value, count, bitWidth) {\n writer.appendVarInt(count << 1) // rle header\n const width = bitWidth + 7 >> 3\n for (let j = 0; j < width; j++) {\n writer.appendUint8(value >> (j << 3) & 0xff)\n }\n}\n\n/**\n * Write consecutive bit-packed groups of 8 values each.\n *\n * @param {Writer} writer\n * @param {DecodedArray} values\n * @param {number} start index of first value\n * @param {number} numGroups number of 8-value groups\n * @param {number} bitWidth\n */\nfunction writeBitPackedGroups(writer, values, start, numGroups, bitWidth) {\n writer.appendVarInt(numGroups << 1 | 1) // bp header\n\n if (bitWidth === 0) return\n\n const mask = (1 << bitWidth) - 1\n let buffer = 0\n let bitsUsed = 0\n const totalValues = numGroups * 8\n\n for (let i = 0; i < totalValues; i++) {\n const idx = start + i\n const v = idx < values.length ? values[idx] & mask : 0\n buffer |= v << bitsUsed\n bitsUsed += bitWidth\n\n // Flush full bytes\n while (bitsUsed >= 8) {\n writer.appendUint8(buffer & 0xff)\n buffer >>>= 8\n bitsUsed -= 8\n }\n }\n\n // Flush any remaining bits\n if (bitsUsed > 0) {\n writer.appendUint8(buffer & 0xff)\n }\n}\n", "\n/**\n * @import {DecodedArray, ParquetType} from 'hyparquet'\n * @import {Writer} from '../src/types.js'\n * @param {Writer} writer\n * @param {DecodedArray} values\n * @param {ParquetType} type\n * @param {number | undefined} fixedLength\n */\nexport function writePlain(writer, values, type, fixedLength) {\n if (type === 'BOOLEAN') {\n writePlainBoolean(writer, values)\n } else if (type === 'INT32') {\n writePlainInt32(writer, values)\n } else if (type === 'INT64') {\n writePlainInt64(writer, values)\n } else if (type === 'FLOAT') {\n writePlainFloat(writer, values)\n } else if (type === 'DOUBLE') {\n writePlainDouble(writer, values)\n } else if (type === 'BYTE_ARRAY') {\n writePlainByteArray(writer, values)\n } else if (type === 'FIXED_LEN_BYTE_ARRAY') {\n if (!fixedLength) throw new Error('parquet FIXED_LEN_BYTE_ARRAY expected type_length')\n writePlainByteArrayFixed(writer, values, fixedLength)\n } else {\n throw new Error(`parquet unsupported type: ${type}`)\n }\n}\n\n/**\n * @param {Writer} writer\n * @param {DecodedArray} values\n */\nfunction writePlainBoolean(writer, values) {\n let currentByte = 0\n\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n if (typeof value !== 'boolean') throw new Error('parquet expected boolean value, got ' + value)\n const bitOffset = i % 8\n\n if (value) {\n currentByte |= 1 << bitOffset\n }\n\n // once we've packed 8 bits or are at a multiple of 8, we write out the byte\n if (bitOffset === 7) {\n writer.appendUint8(currentByte)\n currentByte = 0\n }\n }\n\n // if the array length is not a multiple of 8, write the leftover bits\n if (values.length % 8) {\n writer.appendUint8(currentByte)\n }\n}\n\n/**\n * @param {Writer} writer\n * @param {DecodedArray} values\n */\nfunction writePlainInt32(writer, values) {\n for (const value of values) {\n if (!Number.isSafeInteger(value)) throw new Error('parquet expected integer value, got ' + value)\n if (value < -2147483648 || value > 2147483647) throw new Error('parquet expected int32 value, got ' + value)\n writer.appendInt32(value)\n }\n}\n\n/**\n * @param {Writer} writer\n * @param {DecodedArray} values\n */\nfunction writePlainInt64(writer, values) {\n for (const value of values) {\n if (typeof value !== 'bigint') throw new Error('parquet expected bigint value, got ' + value)\n writer.appendInt64(value)\n }\n}\n\n/**\n * @param {Writer} writer\n * @param {DecodedArray} values\n */\nfunction writePlainFloat(writer, values) {\n for (const value of values) {\n if (typeof value !== 'number') throw new Error('parquet expected number value, got ' + value)\n writer.appendFloat32(value)\n }\n}\n\n/**\n * @param {Writer} writer\n * @param {DecodedArray} values\n */\nfunction writePlainDouble(writer, values) {\n for (const value of values) {\n if (typeof value !== 'number') throw new Error('parquet expected number value, got ' + value)\n writer.appendFloat64(value)\n }\n}\n\n/**\n * @param {Writer} writer\n * @param {DecodedArray} values\n */\nfunction writePlainByteArray(writer, values) {\n for (const value of values) {\n let bytes = value\n if (typeof bytes === 'string') {\n // convert string to Uint8Array\n bytes = new TextEncoder().encode(value)\n }\n if (!(bytes instanceof Uint8Array)) {\n throw new Error('parquet expected Uint8Array value, got ' + typeof bytes)\n }\n writer.appendUint32(bytes.length)\n writer.appendBytes(bytes)\n }\n}\n\n/**\n * @param {Writer} writer\n * @param {DecodedArray} values\n * @param {number} fixedLength\n */\nfunction writePlainByteArrayFixed(writer, values, fixedLength) {\n for (const value of values) {\n if (!(value instanceof Uint8Array)) throw new Error('parquet expected Uint8Array value, got ' + typeof value)\n if (value.length !== fixedLength) throw new Error(`parquet expected Uint8Array of length ${fixedLength}`)\n writer.appendBytes(value)\n }\n}\n", "import { ByteWriter } from './bytewriter.js'\n\nconst encoder = new TextEncoder()\nconst INT64_MIN = -(2n ** 63n)\nconst INT64_MAX = 2n ** 63n - 1n\nconst VARIANT_NULL = new Uint8Array([0x00])\nconst RESERVED_SHREDDING_FIELDS = new Set(['value', 'typed_value'])\n/** @type {Map<string, number>} */\nconst EMPTY_KEY_INDEX = new Map()\nconst EMPTY_METADATA = writeVariantMetadata([])\n\n/**\n * Encode an array of arbitrary JS values into variant binary format.\n * Each row becomes { metadata, value } (or null for missing values).\n * When shredding is provided, produces { metadata, value, typed_value } per row.\n *\n * @import {BasicType, ShredType} from '../src/types.js'\n * @param {any[]} values\n * @param {ShredType | undefined} shredding\n * @param {{ name: string, required: boolean }} [column]\n * @returns {Array<Record<string, any> | null>}\n */\nexport function encodeVariantColumn(values, shredding, column) {\n if (column?.required) {\n for (let i = 0; i < values.length; i++) {\n if (values[i] === undefined) {\n throw new Error(`required variant column ${column.name} has undefined value at index ${i}`)\n }\n }\n }\n const shreddingConfig = shredding && normalizeShreddingConfig(shredding)\n if (shreddingConfig) {\n // Cache (metadata, keyIndex) by sorted-dictionary signature so rows with\n // the same set of keys share a single Uint8Array + Map.\n /** @type {Map<string, { metadata: Uint8Array, keyIndex: Map<string, number> }>} */\n const metadataCache = new Map()\n return values.map(value => {\n // undefined is a missing row; null is a present Variant null.\n if (value === undefined) return null\n // Build the metadata dictionary from every nested key in the row. The\n // reader uses dictionary membership to decide which object fields are\n // present, so all present keys (shredded or not) must be in the dictionary.\n /** @type {Set<string>} */\n const keys = new Set()\n collectKeys(value, keys)\n const { metadata, keyIndex } = getVariantRowMetadata(keys, metadataCache)\n return { metadata, ...encodeShredded(value, shreddingConfig, keyIndex, true) }\n })\n }\n\n const dictionary = buildVariantDictionary(values)\n const metadata = writeVariantMetadata(dictionary)\n /** @type {Map<string, number>} */\n const keyIndex = new Map()\n for (let i = 0; i < dictionary.length; i++) {\n keyIndex.set(dictionary[i], i)\n }\n return values.map(value => {\n // Keep top-level null as a present Variant null (0x00). Only undefined is missing.\n if (value === undefined) return null\n return { metadata, value: writeVariantValue(value, keyIndex) }\n })\n}\n\n/**\n * Recursively encode a value against a shred type into a { value, typed_value }\n * shredded group (the metadata wrapper is added by the caller at the top level).\n *\n * Shape rules (per the Variant shredding spec):\n * - scalar: matches the type -> typed_value holds the value, value is null;\n * otherwise fall back to a binary variant in value.\n * - object: shredded fields go into the typed_value struct (absent fields are\n * omitted), remaining fields are packed into a binary value.\n * - array: each element is recursively shredded into the typed_value LIST, value\n * is null. A non-array value falls back to a binary value.\n *\n * @param {any} value\n * @param {ShredType} shredType\n * @param {Map<string, number>} keyIndex\n * @param {boolean} allowPartialObjects\n * @returns {{ value: Uint8Array | null, typed_value: any }}\n */\nfunction encodeShredded(value, shredType, keyIndex, allowPartialObjects) {\n // Present Variant null: value holds variant null, typed_value is null.\n if (value === null || value === undefined) {\n return { value: VARIANT_NULL, typed_value: null }\n }\n\n // Array shred type\n if (Array.isArray(shredType)) {\n if (!Array.isArray(value)) {\n // Not an array: typed_value must be null, store the value as binary.\n return { value: writeVariantValue(value, keyIndex), typed_value: null }\n }\n const elemShred = shredType[0]\n return { value: null, typed_value: value.map(el => encodeShredded(el, elemShred, keyIndex, false)) }\n }\n\n // Object shred type\n if (typeof shredType === 'object') {\n // Not a plain object: fall back to a binary value.\n if (typeof value !== 'object' || Array.isArray(value) || value instanceof Date || value instanceof Uint8Array) {\n return { value: writeVariantValue(value, keyIndex), typed_value: null }\n }\n\n // Remaining (non-shredded) fields are packed into a binary value.\n /** @type {Record<string, any>} */\n const remaining = {}\n let hasRemaining = false\n for (const k of Object.keys(value)) {\n if (k in shredType || value[k] === undefined) continue\n remaining[k] = value[k]\n hasRemaining = true\n }\n if (hasRemaining && !allowPartialObjects) {\n return { value: writeVariantValue(value, keyIndex), typed_value: null }\n }\n\n const fieldNames = Object.keys(shredType)\n const hasMissingFieldConflict = fieldNames.some(fieldName =>\n (!Object.prototype.hasOwnProperty.call(value, fieldName) || value[fieldName] === undefined) &&\n keyIndex.has(fieldName)\n )\n if (hasMissingFieldConflict) {\n return { value: writeVariantValue(value, keyIndex), typed_value: null }\n }\n\n /** @type {Record<string, any>} */\n const typedValue = {}\n for (const fieldName of fieldNames) {\n if (!Object.prototype.hasOwnProperty.call(value, fieldName) || value[fieldName] === undefined) {\n // missing field: omit the optional field wrapper entirely\n continue\n }\n typedValue[fieldName] = encodeShredded(value[fieldName], shredType[fieldName], keyIndex, false)\n }\n const binaryValue = hasRemaining ? writeVariantValue(remaining, keyIndex) : null\n\n return { value: binaryValue, typed_value: typedValue }\n }\n\n // Scalar shred type\n if (matchesType(value, shredType)) {\n return { value: null, typed_value: value }\n }\n return { value: writeVariantValue(value, keyIndex), typed_value: null }\n}\n\n/**\n * Build metadata and keyIndex, sharing across rows with the same dictionary.\n *\n * @param {Set<string>} keys\n * @param {Map<string, { metadata: Uint8Array, keyIndex: Map<string, number> }>} metadataCache\n * @returns {{ metadata: Uint8Array, keyIndex: Map<string, number> }}\n */\nfunction getVariantRowMetadata(keys, metadataCache) {\n if (keys.size === 0) {\n return { metadata: EMPTY_METADATA, keyIndex: EMPTY_KEY_INDEX }\n }\n\n const dictionary = [...keys].sort()\n const cacheKey = dictionary.join('\\0')\n const cached = metadataCache.get(cacheKey)\n if (cached) {\n return cached\n }\n\n const metadata = writeVariantMetadata(dictionary)\n const keyIndex = new Map()\n for (let i = 0; i < dictionary.length; i++) keyIndex.set(dictionary[i], i)\n const rowMetadata = { metadata, keyIndex }\n metadataCache.set(cacheKey, rowMetadata)\n return rowMetadata\n}\n\n/**\n * Check if a JS value matches a BasicType for shredding.\n *\n * @param {any} value\n * @param {BasicType} type\n * @returns {boolean}\n */\nfunction matchesType(value, type) {\n if (value === null || value === undefined) return false\n switch (type) {\n case 'BOOLEAN': return typeof value === 'boolean'\n case 'INT32': return typeof value === 'number' && Number.isInteger(value) && value >= -2147483648 && value <= 2147483647\n case 'INT64': return typeof value === 'bigint' && value >= INT64_MIN && value <= INT64_MAX\n case 'FLOAT': return typeof value === 'number'\n case 'DOUBLE': return typeof value === 'number'\n case 'STRING': return typeof value === 'string'\n case 'TIMESTAMP': return value instanceof Date\n default: return false\n }\n}\n\n// Conservative defaults for auto-detected shredding. Shredding is a query\n// optimization, not a compression one: each shredded leaf is a full column\n// (page headers, dictionary page, offset index), so deep/wide structures\n// auto-shred into hundreds of columns and bloat the file. Auto-detect only\n// descends a couple of container levels and bails on very wide schemas,\n// leaving the rest in the binary value fallback. Explicit configs are unbounded.\nconst MAX_SHRED_DEPTH = 3\nconst MAX_SHRED_LEAVES = 256\n\n/**\n * Auto-detect a shredding config by recursively analyzing values for consistent\n * structure. Detects scalar fields, nested objects, and arrays. Only structured\n * top-level values (objects/arrays) are shredded; a column of bare scalars is\n * left unshredded. Descent is bounded (see MAX_SHRED_DEPTH/MAX_SHRED_LEAVES) to\n * avoid exploding deeply nested variants into a column per leaf.\n *\n * @param {any[]} values\n * @returns {ShredType | undefined}\n */\nexport function autoDetectShredding(values) {\n const detected = detectShred(values, 0)\n // Top level: only shred structured values (objects/arrays), not bare scalars.\n if (detected === undefined || typeof detected !== 'object') return undefined\n const normalized = normalizeShreddingConfig(detected)\n // Leave pathologically wide schemas as a single binary value.\n if (normalized === undefined || countShredLeaves(normalized) > MAX_SHRED_LEAVES) return undefined\n return normalized\n}\n\n/**\n * Count the typed leaf columns a shred type expands into (per array element).\n *\n * @param {ShredType} shredType\n * @returns {number}\n */\nfunction countShredLeaves(shredType) {\n if (Array.isArray(shredType)) return shredType.length ? countShredLeaves(shredType[0]) : 0\n if (shredType && typeof shredType === 'object') {\n let leaves = 0\n for (const key of Object.keys(shredType)) leaves += countShredLeaves(shredType[key])\n return leaves\n }\n return 1 // scalar leaf\n}\n\n/**\n * Recursively detect a shred type from a pool of sample values at one position.\n * Returns undefined when the values are not consistently shreddable, or when a\n * container is nested deeper than MAX_SHRED_DEPTH (left as binary fallback).\n *\n * @param {any[]} values\n * @param {number} depth container nesting levels already descended\n * @returns {ShredType | undefined}\n */\nfunction detectShred(values, depth) {\n /** @type {any[]} */\n const nonNull = []\n for (const v of values) {\n if (v !== null && v !== undefined) nonNull.push(v)\n }\n if (!nonNull.length) return undefined\n\n // Object shred: any plain object present. Non-objects are ignored here and\n // fall back to binary at encode time.\n if (nonNull.some(isPlainObject)) {\n if (depth >= MAX_SHRED_DEPTH) return undefined\n /** @type {Map<string, any[]>} field name -> its present values */\n const fieldValues = new Map()\n for (const v of nonNull) {\n if (!isPlainObject(v)) continue\n for (const [key, fieldValue] of Object.entries(v)) {\n if (fieldValue === undefined) continue\n const arr = fieldValues.get(key)\n if (arr) arr.push(fieldValue)\n else fieldValues.set(key, [fieldValue])\n }\n }\n /** @type {Record<string, ShredType>} */\n const shredding = {}\n for (const [key, vals] of fieldValues) {\n const fieldShred = detectShred(vals, depth + 1)\n if (fieldShred !== undefined) shredding[key] = fieldShred\n }\n return Object.keys(shredding).length > 0 ? shredding : undefined\n }\n\n // Array shred: every value is an array. Pool all elements and recurse.\n if (nonNull.every(Array.isArray)) {\n if (depth >= MAX_SHRED_DEPTH) return undefined\n /** @type {any[]} */\n const elements = []\n for (const arr of nonNull) for (const el of arr) elements.push(el)\n const elemShred = detectShred(elements, depth + 1)\n return elemShred === undefined ? undefined : [elemShred]\n }\n\n // Scalar shred: every value is the same basic JS type.\n /** @type {string | undefined} */\n let jsType\n for (const v of nonNull) {\n if (Array.isArray(v)) return undefined // mixed array + scalar\n const t = v instanceof Date ? 'date' : typeof v\n if (jsType === undefined) jsType = t\n else if (jsType !== t) return undefined\n }\n return jsType ? jsTypeToBasicType(jsType) : undefined\n}\n\n/**\n * True for plain objects (not null, array, Date, or Uint8Array).\n *\n * @param {any} v\n * @returns {boolean}\n */\nfunction isPlainObject(v) {\n return typeof v === 'object' && v !== null &&\n !Array.isArray(v) && !(v instanceof Date) && !(v instanceof Uint8Array)\n}\n\n/**\n * Recursively strip field names reserved by the shredded variant wrapper layout\n * (`value`, `typed_value`). Returns undefined when an object level empties out.\n *\n * @param {ShredType} shredding\n * @returns {ShredType | undefined}\n */\nexport function normalizeShreddingConfig(shredding) {\n if (Array.isArray(shredding)) {\n const elem = shredding.length ? normalizeShreddingConfig(shredding[0]) : undefined\n return elem === undefined ? undefined : [elem]\n }\n if (typeof shredding === 'object') {\n /** @type {Record<string, ShredType>} */\n const normalized = {}\n for (const [key, type] of Object.entries(shredding)) {\n if (RESERVED_SHREDDING_FIELDS.has(key)) continue\n const norm = normalizeShreddingConfig(type)\n if (norm !== undefined) normalized[key] = norm\n }\n return Object.keys(normalized).length > 0 ? normalized : undefined\n }\n // scalar\n return shredding\n}\n\n/**\n * Map a JS typeof string to a BasicType for shredding.\n *\n * @param {string} jsType\n * @returns {BasicType | undefined}\n */\nfunction jsTypeToBasicType(jsType) {\n switch (jsType) {\n case 'boolean': return 'BOOLEAN'\n case 'string': return 'STRING'\n case 'number': return 'DOUBLE'\n case 'bigint': return 'INT64'\n case 'date': return 'TIMESTAMP'\n default: return undefined\n }\n}\n\n/**\n * Recursively collect all unique object keys from the column values.\n * Returns a sorted string array.\n *\n * @param {any[]} values\n * @returns {string[]}\n */\nfunction buildVariantDictionary(values) {\n /** @type {Set<string>} */\n const keys = new Set()\n collectKeys(values, keys)\n return [...keys].sort()\n}\n\n/**\n * @param {any} value\n * @param {Set<string>} keys\n */\nfunction collectKeys(value, keys) {\n if (value === null || value === undefined) return\n if (Array.isArray(value)) {\n for (const item of value) {\n collectKeys(item, keys)\n }\n return\n }\n if (value instanceof Date || value instanceof Uint8Array) return\n if (typeof value === 'object') {\n for (const key of Object.keys(value)) {\n keys.add(key)\n collectKeys(value[key], keys)\n }\n }\n}\n\n/**\n * Encode variant metadata binary.\n * Format: header byte, dictionary size, offsets, UTF-8 string data.\n *\n * @param {string[]} dictionary sorted array of unique keys\n * @returns {Uint8Array}\n */\nfunction writeVariantMetadata(dictionary) {\n // Encode strings and compute total byte length in one pass\n const n = dictionary.length\n /** @type {Uint8Array[]} */\n const encoded = new Array(n)\n let totalStringBytes = 0\n for (let i = 0; i < n; i++) {\n const e = encoder.encode(dictionary[i])\n encoded[i] = e\n totalStringBytes += e.length\n }\n\n // Determine offset size: max offset is totalStringBytes\n const offsetSize = byteWidth(totalStringBytes)\n\n // Header: version=1, sorted=1, offsetSize\n const header = 1 | 1 << 4 | offsetSize - 1 << 6\n\n // Total size: 1 (header) + offsetSize (dict size) + (n + 1) * offsetSize (offsets) + totalStringBytes\n const totalSize = 1 + offsetSize + (n + 1) * offsetSize + totalStringBytes\n const bytes = new Uint8Array(totalSize)\n let offset = 0\n\n bytes[offset++] = header\n\n // Dictionary size\n for (let j = 0; j < offsetSize; j++) bytes[offset++] = n >> j * 8 & 0xff\n\n // String offsets\n let strOffset = 0\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < offsetSize; j++) bytes[offset++] = strOffset >> j * 8 & 0xff\n strOffset += encoded[i].length\n }\n // Final offset\n for (let j = 0; j < offsetSize; j++) bytes[offset++] = strOffset >> j * 8 & 0xff\n\n // String data\n for (let i = 0; i < n; i++) {\n bytes.set(encoded[i], offset)\n offset += encoded[i].length\n }\n\n return bytes\n}\n\n/**\n * Encode a single JS value to variant binary format.\n *\n * @param {any} value\n * @param {Map<string, number>} keyIndex map from key string to dictionary index\n * @returns {Uint8Array}\n */\nfunction writeVariantValue(value, keyIndex) {\n const writer = new ByteWriter(8)\n writeValue(value, writer, keyIndex)\n return writer.getBytes()\n}\n\n/**\n * @param {any} val\n * @param {ByteWriter} writer\n * @param {Map<string, number>} keyIndex\n */\nfunction writeValue(val, writer, keyIndex) {\n if (val === null || val === undefined) {\n writer.appendUint8(0x00) // basicType=0, typeId=0\n return\n }\n if (val === true) {\n writer.appendUint8(0x04) // typeId=1\n return\n }\n if (val === false) {\n writer.appendUint8(0x08) // typeId=2\n return\n }\n if (typeof val === 'bigint') {\n if (val < INT64_MIN || val > INT64_MAX) {\n throw new RangeError(`variant bigint out of int64 range: ${val}`)\n }\n writer.appendUint8(6 << 2) // int64\n writer.appendInt64(val)\n return\n }\n if (typeof val === 'number') {\n if (Number.isInteger(val)) {\n if (val >= -128 && val <= 127) {\n writer.appendUint8(3 << 2) // int8\n writer.appendUint8(val & 0xff)\n return\n }\n if (val >= -32768 && val <= 32767) {\n writer.appendUint8(4 << 2) // int16\n appendUnsignedLE(writer, val, 2)\n return\n }\n if (val >= -2147483648 && val <= 2147483647) {\n writer.appendUint8(5 << 2) // int32\n writer.appendInt32(val)\n return\n }\n }\n writer.appendUint8(7 << 2) // double\n writer.appendFloat64(val)\n return\n }\n if (typeof val === 'string') {\n const strBytes = encoder.encode(val)\n if (strBytes.length <= 63) {\n // short string: basicType=1, length in header\n writer.appendUint8(strBytes.length << 2 | 1)\n writer.appendBytes(strBytes)\n } else {\n // long string: primitive typeId=16\n writer.appendUint8(16 << 2)\n writer.appendUint32(strBytes.length)\n writer.appendBytes(strBytes)\n }\n return\n }\n if (val instanceof Date) {\n writer.appendUint8(13 << 2) // timestamp_micros_ntz\n writer.appendInt64(BigInt(val.getTime()) * 1000n)\n return\n }\n if (val instanceof Uint8Array) {\n writer.appendUint8(15 << 2) // binary\n writer.appendUint32(val.length)\n writer.appendBytes(val)\n return\n }\n if (Array.isArray(val)) {\n writeVariantArray(val, writer, keyIndex)\n return\n }\n if (typeof val === 'object') {\n writeVariantObject(val, writer, keyIndex)\n return\n }\n\n throw new Error(`variant cannot encode value: ${val}`)\n}\n\n/**\n * @param {Record<string, any>} obj\n * @param {ByteWriter} writer\n * @param {Map<string, number>} keyIndex\n */\nfunction writeVariantObject(obj, writer, keyIndex) {\n const entries = Object.keys(obj).filter(key => obj[key] !== undefined).map(key => {\n const id = keyIndex.get(key)\n if (id === undefined) throw new Error(`variant key not in dictionary: ${key}`)\n return { id, key }\n })\n // Sort by field ID for spec compliance\n entries.sort((a, b) => a.id - b.id)\n\n const numElements = entries.length\n const maxFieldId = numElements > 0 ? entries[numElements - 1].id : 0\n const idWidth = byteWidth(maxFieldId)\n\n // Encode child values into a scratch writer so we can compute offsets\n const scratch = new ByteWriter(8)\n const offsets = new Array(numElements + 1)\n offsets[0] = 0\n for (let i = 0; i < numElements; i++) {\n writeValue(obj[entries[i].key], scratch, keyIndex)\n offsets[i + 1] = scratch.index\n }\n const offsetWidth = byteWidth(offsets[numElements])\n const isLarge = numElements > 255 ? 1 : 0\n\n // Header: basicType=2, header encodes offsetWidth, idWidth, isLarge\n writer.appendUint8((offsetWidth - 1 | idWidth - 1 << 2 | isLarge << 4) << 2 | 2)\n if (isLarge) writer.appendUint32(numElements)\n else writer.appendUint8(numElements)\n for (const { id } of entries) appendUnsignedLE(writer, id, idWidth)\n for (const off of offsets) appendUnsignedLE(writer, off, offsetWidth)\n writer.appendBytes(scratch.getBytes())\n}\n\n/**\n * @param {any[]} arr\n * @param {ByteWriter} writer\n * @param {Map<string, number>} keyIndex\n */\nfunction writeVariantArray(arr, writer, keyIndex) {\n const numElements = arr.length\n\n const scratch = new ByteWriter(8)\n const offsets = new Array(numElements + 1)\n offsets[0] = 0\n for (let i = 0; i < numElements; i++) {\n writeValue(arr[i], scratch, keyIndex)\n offsets[i + 1] = scratch.index\n }\n const offsetWidth = byteWidth(offsets[numElements])\n const isLarge = numElements > 255 ? 1 : 0\n\n // Header: basicType=3, header encodes fieldOffsetSize, isLarge\n writer.appendUint8((offsetWidth - 1 | isLarge << 2) << 2 | 3)\n if (isLarge) writer.appendUint32(numElements)\n else writer.appendUint8(numElements)\n for (const off of offsets) appendUnsignedLE(writer, off, offsetWidth)\n writer.appendBytes(scratch.getBytes())\n}\n\n/**\n * Determine the minimum byte width needed to represent a value.\n *\n * @param {number} maxValue\n * @returns {number} 1, 2, 3, or 4\n */\nfunction byteWidth(maxValue) {\n if (maxValue <= 0xff) return 1\n if (maxValue <= 0xffff) return 2\n if (maxValue <= 0xffffff) return 3\n return 4\n}\n\n/**\n * Write an unsigned integer in little-endian format into a ByteWriter.\n *\n * @param {ByteWriter} writer\n * @param {number} value\n * @param {number} width byte width (1-4)\n */\nfunction appendUnsignedLE(writer, value, width) {\n for (let i = 0; i < width; i++) {\n writer.appendUint8(value >> i * 8 & 0xff)\n }\n}\n", "import { normalizeShreddingConfig } from './variant.js'\n\n/**\n * @import {ConvertedType, DecodedArray, FieldRepetitionType, ParquetType, SchemaElement} from 'hyparquet'\n * @import {BasicType, ColumnSource, ShredType} from '../src/types.js'\n */\n\n/**\n * Infer a schema from column data.\n * Accepts optional schemaOverrides to override the type of columns by name.\n *\n * @param {object} options\n * @param {ColumnSource[]} options.columnData\n * @param {Record<string, SchemaElement>} [options.schemaOverrides]\n * @returns {SchemaElement[]}\n */\nexport function schemaFromColumnData({ columnData, schemaOverrides }) {\n /** @type {SchemaElement[]} */\n const schema = [{\n name: 'root',\n num_children: columnData.length,\n }]\n\n for (const { name, data, type, nullable, shredding } of columnData) {\n if (schemaOverrides?.[name]) {\n // use schema override\n const override = schemaOverrides[name]\n if (type || nullable !== undefined) {\n throw new Error(`cannot provide both type and schema override for column ${name}`)\n }\n if (override.name !== name) {\n throw new Error(`schema override for column ${name} must have matching name, got ${override.name}`)\n }\n if (override.type === 'FIXED_LEN_BYTE_ARRAY' && !override.type_length) {\n throw new Error('schema override for FIXED_LEN_BYTE_ARRAY must include type_length')\n }\n // TODO: support nested schema overrides\n if (override.num_children) {\n throw new Error('schema override does not support nested types')\n }\n schema.push(override)\n } else if (type === 'VARIANT') {\n // variant group with metadata and value children\n const repetition_type = nullable === false ? 'REQUIRED' : 'OPTIONAL'\n const shreddingConfig = shredding && shredding !== true ? normalizeShreddingConfig(shredding) : undefined\n if (shreddingConfig) {\n schema.push(\n { name, repetition_type, num_children: 3, logical_type: { type: 'VARIANT' } },\n { name: 'metadata', type: 'BYTE_ARRAY', repetition_type: 'REQUIRED' },\n { name: 'value', type: 'BYTE_ARRAY', repetition_type: 'OPTIONAL' },\n ...buildVariantTypedValue(shreddingConfig)\n )\n } else {\n schema.push(\n { name, repetition_type, num_children: 2, logical_type: { type: 'VARIANT' } },\n { name: 'metadata', type: 'BYTE_ARRAY', repetition_type: 'REQUIRED' },\n { name: 'value', type: 'BYTE_ARRAY', repetition_type: 'OPTIONAL' }\n )\n }\n } else if (type) {\n // use provided type\n schema.push(basicTypeToSchemaElement(name, type, nullable))\n } else {\n // auto-detect type from first 1000 values\n schema.push(autoSchemaElement(name, data.slice(0, 1000)))\n }\n }\n\n return schema\n}\n\n/**\n * Build the flat preorder SchemaElement subtree for a shredded variant\n * `typed_value` node, recursively, from a shred type. The first returned element\n * is always named `typed_value`. Supports scalars, object structs, and LIST arrays.\n *\n * @param {ShredType} shredType\n * @returns {SchemaElement[]}\n */\nfunction buildVariantTypedValue(shredType) {\n // Array shred type: single-element array template -> 3-level LIST\n if (Array.isArray(shredType)) {\n return [\n { name: 'typed_value', repetition_type: 'OPTIONAL', converted_type: 'LIST', num_children: 1 },\n { name: 'list', repetition_type: 'REPEATED', num_children: 1 },\n { name: 'element', repetition_type: 'REQUIRED', num_children: 2 },\n { name: 'value', type: 'BYTE_ARRAY', repetition_type: 'OPTIONAL' },\n ...buildVariantTypedValue(shredType[0]),\n ]\n }\n\n // Object shred type: struct with one optional group per field\n if (typeof shredType === 'object') {\n const fieldNames = Object.keys(shredType)\n /** @type {SchemaElement[]} */\n const elements = [\n { name: 'typed_value', repetition_type: 'OPTIONAL', num_children: fieldNames.length },\n ]\n for (const fieldName of fieldNames) {\n elements.push(\n { name: fieldName, repetition_type: 'OPTIONAL', num_children: 2 },\n { name: 'value', type: 'BYTE_ARRAY', repetition_type: 'OPTIONAL' },\n ...buildVariantTypedValue(shredType[fieldName])\n )\n }\n return elements\n }\n\n // Scalar shred type: typed leaf\n return [shreddedLeafElement(shredType)]\n}\n\n/**\n * Map a BasicType to the typed_value leaf SchemaElement for shredded scalars.\n *\n * @param {BasicType} type\n * @returns {SchemaElement}\n */\nfunction shreddedLeafElement(type) {\n switch (type) {\n case 'STRING':\n return { name: 'typed_value', type: 'BYTE_ARRAY', converted_type: 'UTF8', repetition_type: 'OPTIONAL' }\n case 'INT32':\n return { name: 'typed_value', type: 'INT32', repetition_type: 'OPTIONAL' }\n case 'INT64':\n return { name: 'typed_value', type: 'INT64', repetition_type: 'OPTIONAL' }\n case 'DOUBLE':\n return { name: 'typed_value', type: 'DOUBLE', repetition_type: 'OPTIONAL' }\n case 'FLOAT':\n return { name: 'typed_value', type: 'FLOAT', repetition_type: 'OPTIONAL' }\n case 'BOOLEAN':\n return { name: 'typed_value', type: 'BOOLEAN', repetition_type: 'OPTIONAL' }\n case 'TIMESTAMP':\n return { name: 'typed_value', type: 'INT64', converted_type: 'TIMESTAMP_MICROS', repetition_type: 'OPTIONAL' }\n default:\n throw new Error(`unsupported shredded field type: ${type}`)\n }\n}\n\n/**\n * @param {string} name\n * @param {Exclude<BasicType, 'VARIANT'>} type\n * @param {boolean} [nullable]\n * @returns {SchemaElement}\n */\nfunction basicTypeToSchemaElement(name, type, nullable) {\n const repetition_type = nullable === false ? 'REQUIRED' : 'OPTIONAL'\n if (type === 'STRING') {\n return { name, type: 'BYTE_ARRAY', converted_type: 'UTF8', repetition_type }\n }\n if (type === 'JSON') {\n return { name, type: 'BYTE_ARRAY', converted_type: 'JSON', repetition_type }\n }\n if (type === 'TIMESTAMP') {\n return { name, type: 'INT64', converted_type: 'TIMESTAMP_MILLIS', repetition_type }\n }\n if (type === 'UUID') {\n return { name, type: 'FIXED_LEN_BYTE_ARRAY', type_length: 16, logical_type: { type: 'UUID' }, repetition_type }\n }\n if (type === 'FLOAT16') {\n return { name, type: 'FIXED_LEN_BYTE_ARRAY', type_length: 2, logical_type: { type: 'FLOAT16' }, repetition_type }\n }\n if (type === 'GEOMETRY') {\n return { name, type: 'BYTE_ARRAY', logical_type: { type: 'GEOMETRY' }, repetition_type }\n }\n if (type === 'GEOGRAPHY') {\n return { name, type: 'BYTE_ARRAY', logical_type: { type: 'GEOGRAPHY' }, repetition_type }\n }\n return { name, type, repetition_type }\n}\n\n/**\n * Automatically determine a SchemaElement from an array of values.\n *\n * @param {string} name the column name\n * @param {DecodedArray} values the column values\n * @returns {SchemaElement}\n */\nexport function autoSchemaElement(name, values) {\n /** @type {ParquetType | undefined} */\n let type\n /** @type {FieldRepetitionType} */\n let repetition_type = 'REQUIRED'\n /** @type {ConvertedType | undefined} */\n let converted_type\n\n if (values instanceof Int32Array) return { name, type: 'INT32', repetition_type }\n if (values instanceof BigInt64Array) return { name, type: 'INT64', repetition_type }\n if (values instanceof Float32Array) return { name, type: 'FLOAT', repetition_type }\n if (values instanceof Float64Array) return { name, type: 'DOUBLE', repetition_type }\n\n for (const value of values) {\n if (value === null || value === undefined) {\n repetition_type = 'OPTIONAL'\n } else {\n // value is defined, infer type\n /** @type {ParquetType} */\n let valueType\n /** @type {ConvertedType | undefined} */\n let valueConvertedType\n if (typeof value === 'boolean') valueType = 'BOOLEAN'\n else if (typeof value === 'bigint') valueType = 'INT64'\n else if (Number.isInteger(value)) valueType = 'INT32'\n else if (typeof value === 'number') valueType = 'DOUBLE'\n else if (value instanceof Uint8Array) valueType = 'BYTE_ARRAY'\n else if (typeof value === 'string') {\n valueType = 'BYTE_ARRAY'\n valueConvertedType = 'UTF8'\n }\n else if (value instanceof Date) {\n valueType = 'INT64'\n valueConvertedType = 'TIMESTAMP_MILLIS'\n }\n else if (typeof value === 'object') {\n // use json (TODO: native list and object types)\n valueType = 'BYTE_ARRAY'\n valueConvertedType = 'JSON'\n }\n else throw new Error(`cannot determine parquet type for: ${value}`)\n\n // expand type if necessary\n if (type === undefined) {\n type = valueType\n converted_type = valueConvertedType\n } else if (type === 'INT32' && valueType === 'DOUBLE') {\n type = 'DOUBLE'\n } else if (type === 'DOUBLE' && valueType === 'INT32') {\n valueType = 'DOUBLE'\n } else if (type !== valueType || converted_type !== valueConvertedType) {\n throw new Error(`parquet cannot write mixed types: ${converted_type ?? type} and ${valueConvertedType ?? valueType}`)\n }\n }\n }\n if (!type) {\n // fallback to nullable BYTE_ARRAY\n // TODO: logical_type: 'NULL'\n type = 'BYTE_ARRAY'\n repetition_type = 'OPTIONAL'\n }\n return { name, type, repetition_type, converted_type }\n}\n\n/**\n * Get the max repetition level for a given schema path.\n *\n * @param {SchemaElement[]} schemaPath\n * @returns {number} max repetition level\n */\nexport function getMaxRepetitionLevel(schemaPath) {\n let maxLevel = 0\n for (const element of schemaPath) {\n if (element.repetition_type === 'REPEATED') {\n maxLevel++\n }\n }\n return maxLevel\n}\n", "/**\n * Write values using BYTE_STREAM_SPLIT encoding.\n * This encoding writes all first bytes of values, then all second bytes, etc.\n * Can improve compression for floating-point and fixed-width numeric data.\n *\n * @import {DecodedArray, ParquetType} from 'hyparquet'\n * @import {Writer} from '../src/types.js'\n * @param {Writer} writer\n * @param {DecodedArray} values\n * @param {ParquetType} type\n * @param {number | undefined} typeLength\n */\nexport function writeByteStreamSplit(writer, values, type, typeLength) {\n const count = values.length\n\n // Get bytes from values based on type\n /** @type {Uint8Array} */\n let bytes\n /** @type {number} */\n let width\n if (type === 'FLOAT') {\n const typed = values instanceof Float32Array ? values : new Float32Array(numberArray(values))\n bytes = new Uint8Array(typed.buffer, typed.byteOffset, typed.byteLength)\n width = 4\n } else if (type === 'DOUBLE') {\n const typed = values instanceof Float64Array ? values : new Float64Array(numberArray(values))\n bytes = new Uint8Array(typed.buffer, typed.byteOffset, typed.byteLength)\n width = 8\n } else if (type === 'INT32') {\n const typed = values instanceof Int32Array ? values : new Int32Array(numberArray(values))\n bytes = new Uint8Array(typed.buffer, typed.byteOffset, typed.byteLength)\n width = 4\n } else if (type === 'INT64') {\n const typed = bigIntArray(values)\n bytes = new Uint8Array(typed.buffer, typed.byteOffset, typed.byteLength)\n width = 8\n } else if (type === 'FIXED_LEN_BYTE_ARRAY') {\n if (!typeLength) throw new Error('parquet byte_stream_split missing type_length')\n width = typeLength\n bytes = new Uint8Array(count * width)\n for (let i = 0; i < count; i++) {\n bytes.set(values[i], i * width)\n }\n } else {\n throw new Error(`parquet byte_stream_split unsupported type: ${type}`)\n }\n\n // Write bytes in column format (all byte 0 from all values, then byte 1, etc.)\n for (let b = 0; b < width; b++) {\n for (let i = 0; i < count; i++) {\n writer.appendUint8(bytes[i * width + b])\n }\n }\n}\n\n/**\n * @param {DecodedArray} values\n * @returns {number[]}\n */\nfunction numberArray(values) {\n if (Array.isArray(values) && values.every(v => typeof v === 'number')) {\n return values\n }\n throw new Error('Expected number array for BYTE_STREAM_SPLIT encoding')\n}\n\n/**\n * @param {DecodedArray} values\n * @returns {BigInt64Array}\n */\nfunction bigIntArray(values) {\n if (values instanceof BigInt64Array) return values\n if (Array.isArray(values) && values.every(v => typeof v === 'bigint')) {\n return new BigInt64Array(values)\n }\n throw new Error('Expected bigint array for BYTE_STREAM_SPLIT encoding')\n}\n\n", "import { Encodings, PageTypes } from 'hyparquet/src/constants.js'\nimport { ByteWriter } from './bytewriter.js'\nimport { deltaBinaryPack, deltaByteArray, deltaLengthByteArray } from './delta.js'\nimport { writeRleBitPackedHybrid } from './encoding.js'\nimport { writePlain } from './plain.js'\nimport { getMaxRepetitionLevel } from './schema.js'\nimport { writeByteStreamSplit } from './splitstream.js'\nimport { serializeTCompactProtocol } from './thrift.js'\n\n/**\n * @param {Object} options\n * @param {Writer} options.writer\n * @param {ColumnEncoder} options.column\n * @param {Encoding} options.encoding\n * @param {PageData} options.pageData\n */\nexport function writeDataPageV2({ writer, column, encoding, pageData }) {\n const { columnName, element, codec, compressors } = column\n const { type, type_length, repetition_type } = element\n\n if (!type) throw new Error(`column ${columnName} cannot determine type`)\n if (repetition_type === 'REPEATED') throw new Error(`column ${columnName} repeated types not supported`)\n\n // write levels to temp buffer\n const levelWriter = new ByteWriter()\n const {\n definition_levels_byte_length,\n repetition_levels_byte_length,\n num_nulls,\n num_values,\n num_rows,\n } = writeLevels(levelWriter, column, pageData)\n\n // TODO: skip nulls while writing instead of filtering\n const nonnull = num_nulls ? pageData.values.filter(v => v !== null && v !== undefined) : pageData.values\n\n // write page data to temp buffer\n const page = new ByteWriter()\n if (encoding === 'PLAIN') {\n writePlain(page, nonnull, type, type_length)\n } else if (encoding === 'RLE') {\n if (type !== 'BOOLEAN') throw new Error('RLE encoding only supported for BOOLEAN type')\n const rleData = new ByteWriter()\n writeRleBitPackedHybrid(rleData, nonnull, 1)\n page.appendUint32(rleData.offset) // prepend byte length\n page.appendBytes(rleData.getBytes())\n } else if (encoding === 'PLAIN_DICTIONARY' || encoding === 'RLE_DICTIONARY') {\n // find max bitwidth\n let maxValue = 0\n for (const v of nonnull) if (v > maxValue) maxValue = v\n const bitWidth = Math.ceil(Math.log2(maxValue + 1))\n page.appendUint8(bitWidth) // prepend bitWidth\n writeRleBitPackedHybrid(page, nonnull, bitWidth)\n } else if (encoding === 'DELTA_BINARY_PACKED') {\n if (type !== 'INT32' && type !== 'INT64') {\n throw new Error('DELTA_BINARY_PACKED encoding only supported for INT32 and INT64 types')\n }\n deltaBinaryPack(page, nonnull)\n } else if (encoding === 'DELTA_LENGTH_BYTE_ARRAY') {\n if (type !== 'BYTE_ARRAY') {\n throw new Error('DELTA_LENGTH_BYTE_ARRAY encoding only supported for BYTE_ARRAY type')\n }\n deltaLengthByteArray(page, nonnull)\n } else if (encoding === 'DELTA_BYTE_ARRAY') {\n if (type !== 'BYTE_ARRAY') {\n throw new Error('DELTA_BYTE_ARRAY encoding only supported for BYTE_ARRAY type')\n }\n deltaByteArray(page, nonnull)\n } else if (encoding === 'BYTE_STREAM_SPLIT') {\n writeByteStreamSplit(page, nonnull, type, type_length)\n } else {\n throw new Error(`parquet unsupported encoding: ${encoding}`)\n }\n\n // compress page data\n const pageBytes = page.getBytes()\n const compressedBytes = compressors[codec]?.(pageBytes) ?? pageBytes\n\n // write page header\n writePageHeader(writer, {\n type: 'DATA_PAGE_V2',\n uncompressed_page_size: levelWriter.offset + page.offset,\n compressed_page_size: levelWriter.offset + compressedBytes.length,\n data_page_header_v2: {\n num_values,\n num_nulls,\n num_rows,\n encoding,\n definition_levels_byte_length,\n repetition_levels_byte_length,\n is_compressed: !!codec,\n // is there benefit to page statistics here?\n },\n })\n\n // write levels\n writer.appendBytes(levelWriter.getBytes())\n\n // write page data\n writer.appendBytes(compressedBytes)\n}\n\n/**\n * @param {Writer} writer\n * @param {PageHeader} header\n */\nexport function writePageHeader(writer, header) {\n /** @type {ThriftObject} */\n const compact = {\n field_1: PageTypes.indexOf(header.type),\n field_2: header.uncompressed_page_size,\n field_3: header.compressed_page_size,\n field_4: header.crc,\n field_5: header.data_page_header && {\n field_1: header.data_page_header.num_values,\n field_2: Encodings.indexOf(header.data_page_header.encoding),\n field_3: Encodings.indexOf(header.data_page_header.definition_level_encoding),\n field_4: Encodings.indexOf(header.data_page_header.repetition_level_encoding),\n // field_5: header.data_page_header.statistics,\n },\n field_7: header.dictionary_page_header && {\n field_1: header.dictionary_page_header.num_values,\n field_2: Encodings.indexOf(header.dictionary_page_header.encoding),\n },\n field_8: header.data_page_header_v2 && {\n field_1: header.data_page_header_v2.num_values,\n field_2: header.data_page_header_v2.num_nulls,\n field_3: header.data_page_header_v2.num_rows,\n field_4: Encodings.indexOf(header.data_page_header_v2.encoding),\n field_5: header.data_page_header_v2.definition_levels_byte_length,\n field_6: header.data_page_header_v2.repetition_levels_byte_length,\n field_7: header.data_page_header_v2.is_compressed ? undefined : false, // default true\n },\n }\n serializeTCompactProtocol(writer, compact)\n}\n\n/**\n * @import {DecodedArray, Encoding, PageHeader} from 'hyparquet'\n * @import {ColumnEncoder, PageData, ThriftObject, Writer} from '../src/types.js'\n * @param {Writer} writer\n * @param {ColumnEncoder} column\n * @param {PageData} dataPage\n * @returns {{\n * definition_levels_byte_length: number\n * repetition_levels_byte_length: number\n * num_values: number\n * num_nulls: number\n * num_rows: number\n * }}\n */\nfunction writeLevels(writer, column, dataPage) {\n const { schemaPath } = column\n const { values, definitionLevels, repetitionLevels, maxDefinitionLevel } = dataPage\n const num_values = definitionLevels.length || values.length\n let num_nulls = 0\n let num_rows = 0\n if (repetitionLevels.length) {\n for (let i = 0; i < repetitionLevels.length; i++) {\n if (repetitionLevels[i] === 0) num_rows++\n }\n } else {\n num_rows = values.length\n }\n if (definitionLevels.length) {\n for (let i = 0; i < definitionLevels.length; i++) {\n if (definitionLevels[i] < maxDefinitionLevel) num_nulls++\n }\n }\n\n const maxRepetitionLevel = getMaxRepetitionLevel(schemaPath)\n let repetition_levels_byte_length = 0\n if (maxRepetitionLevel) {\n const bitWidth = Math.ceil(Math.log2(maxRepetitionLevel + 1))\n repetition_levels_byte_length = writeRleBitPackedHybrid(writer, repetitionLevels, bitWidth)\n }\n\n let definition_levels_byte_length = 0\n if (maxDefinitionLevel) {\n const bitWidth = Math.ceil(Math.log2(maxDefinitionLevel + 1))\n definition_levels_byte_length = writeRleBitPackedHybrid(writer, definitionLevels, bitWidth)\n }\n return { definition_levels_byte_length, repetition_levels_byte_length, num_values, num_nulls, num_rows }\n}\n", "import { ByteWriter } from './bytewriter.js'\nimport { writePageHeader } from './datapage.js'\nimport { writePlain } from './plain.js'\n\n/**\n * @import {DecodedArray, Encoding, ParquetType} from 'hyparquet'\n * @import {ColumnEncoder, Writer} from './types.js'\n */\n\n/**\n * Estimate the byte size of a value for page size calculation.\n *\n * @param {any} value\n * @param {ParquetType} type\n * @param {number} [type_length]\n * @returns {number}\n */\nexport function estimateValueSize(value, type, type_length) {\n if (value === null || value === undefined) return 0\n if (type === 'BOOLEAN') return 0.125\n if (type === 'INT32' || type === 'FLOAT') return 4\n if (type === 'INT64' || type === 'DOUBLE') return 8\n if (type === 'INT96') return 12\n if (type === 'FIXED_LEN_BYTE_ARRAY') return type_length ?? 0\n if (type === 'BYTE_ARRAY') {\n if (value instanceof Uint8Array) return value.byteLength\n if (typeof value === 'string') return value.length\n }\n return 0\n}\n\n/**\n * FNV-1a hash of a byte array, used to bucket byte-array dictionary values\n * without allocating a string key per value.\n *\n * @param {Uint8Array} bytes\n * @returns {number}\n */\nfunction hashBytes(bytes) {\n let h = 0x811c9dc5\n for (let i = 0; i < bytes.length; i++) {\n h ^= bytes[i]\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n}\n\n/**\n * @param {Uint8Array} a\n * @param {Uint8Array} b\n * @returns {boolean}\n */\nfunction bytesEqual(a, b) {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false\n }\n return true\n}\n\n/**\n * Decide whether to dictionary-encode a column, and if so build the dictionary\n * and per-row indexes. Returns {} to fall back to plain encoding.\n *\n * @param {DecodedArray} values\n * @param {ParquetType} type\n * @param {number | undefined} type_length\n * @param {Encoding | undefined} encoding\n * @param {number} pageSize\n * @returns {{ dictionary?: any[], indexes?: number[] }}\n */\nexport function useDictionary(values, type, type_length, encoding, pageSize) {\n if (encoding && encoding !== 'RLE_DICTIONARY') return {}\n if (type === 'BOOLEAN') return {}\n\n // uniqueness on a sample. Byte arrays are keyed by hash so distinct\n // Uint8Array objects with identical bytes count as one (a plain Set would key\n // them by object identity); null/undefined count as values, matching the\n // plain-encoding fallback that validates required/missing values.\n const sample = values.slice(0, 1000)\n const sampleKeys = new Set()\n for (const value of sample) {\n sampleKeys.add(value instanceof Uint8Array ? hashBytes(value) : value)\n }\n if (sampleKeys.size === 0 || sampleKeys.size / sample.length > 0.5) return {}\n\n // build dictionary and indexes. Primitives (string/number/bigint) dedupe by\n // value; byte arrays dedupe by content via hash buckets with an exact\n // byte-equality check (hashes can collide).\n /** @type {any[]} */\n const dictionary = []\n /** @type {number[]} */\n const indexes = new Array(values.length)\n /** @type {Map<any, number>} */\n const valueIndex = new Map()\n /** @type {Map<number, number[]>} */\n const hashBuckets = new Map()\n let dictSize = 0\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n if (value === null || value === undefined) continue\n\n let index\n if (value instanceof Uint8Array) {\n const hash = hashBytes(value)\n const bucket = hashBuckets.get(hash)\n if (bucket) {\n for (const j of bucket) {\n if (bytesEqual(dictionary[j], value)) { index = j; break }\n }\n }\n if (index === undefined) {\n dictSize += value.byteLength\n if (pageSize && dictSize > pageSize) return {}\n index = dictionary.length\n dictionary.push(value)\n if (bucket) bucket.push(index)\n else hashBuckets.set(hash, [index])\n }\n } else {\n index = valueIndex.get(value)\n if (index === undefined) {\n dictSize += estimateValueSize(value, type, type_length)\n if (pageSize && dictSize > pageSize) return {}\n index = dictionary.length\n dictionary.push(value)\n valueIndex.set(value, index)\n }\n }\n indexes[i] = index\n }\n\n // TODO: sort by frequency?\n return { dictionary, indexes }\n}\n\n/**\n * @param {Writer} writer\n * @param {ColumnEncoder} column\n * @param {DecodedArray} dictionary\n */\nexport function writeDictionaryPage(writer, column, dictionary) {\n const { element, codec, compressors } = column\n const { type, type_length } = element\n if (!type) throw new Error(`column ${column.columnName} cannot determine type`)\n\n // write values to temp buffer\n const dictionaryPage = new ByteWriter()\n writePlain(dictionaryPage, dictionary, type, type_length)\n const dictionaryBytes = dictionaryPage.getBytes()\n\n // compress dictionary page data\n const compressedBytes = compressors[codec]?.(dictionaryBytes) ?? dictionaryBytes\n\n // write dictionary page header\n writePageHeader(writer, {\n type: 'DICTIONARY_PAGE',\n uncompressed_page_size: dictionaryBytes.byteLength,\n compressed_page_size: compressedBytes.byteLength,\n dictionary_page_header: {\n num_values: dictionary.length,\n encoding: 'PLAIN',\n },\n })\n writer.appendBytes(compressedBytes)\n}\n", "/**\n * Compute geospatial statistics for GEOMETRY and GEOGRAPHY columns.\n *\n * @import {BoundingBox, DecodedArray, Geometry, GeospatialStatistics} from 'hyparquet/src/types.js'\n * @param {DecodedArray} values\n * @returns {GeospatialStatistics | undefined}\n */\nexport function geospatialStatistics(values) {\n /** @type {Set<number>} */\n const typeCodes = new Set()\n /** @type {Partial<BoundingBox> | undefined} */\n let partial\n\n for (const value of values) {\n if (value === null || value === undefined) continue\n if (typeof value !== 'object') {\n throw new Error('geospatial column expects GeoJSON geometries')\n }\n partial = extendBoundsFromGeometry(partial, value)\n typeCodes.add(geometryTypeCodeWithDimension(value))\n }\n\n // If either the X or Y dimension has no finite values, the bounding box itself is not produced\n /** @type {BoundingBox | undefined} */\n let bbox\n const { xmin, ymin, xmax, ymax } = partial ?? {}\n if (xmin !== undefined && ymin !== undefined && xmax !== undefined && ymax !== undefined) {\n bbox = { ...partial, xmin, ymin, xmax, ymax }\n }\n\n if (typeCodes.size || bbox) {\n return {\n bbox,\n // Geospatial type codes of all instances, or an empty list if not known\n geospatial_types: typeCodes.size ? Array.from(typeCodes).sort((a, b) => a - b) : [],\n }\n }\n}\n\n/**\n * @param {Partial<BoundingBox> | undefined} bbox\n * @param {Geometry} geometry\n * @returns {Partial<BoundingBox> | undefined}\n */\nfunction extendBoundsFromGeometry(bbox, geometry) {\n if (geometry.type === 'GeometryCollection') {\n for (const child of geometry.geometries || []) {\n bbox = extendBoundsFromGeometry(bbox, child)\n }\n return bbox\n }\n return extendBoundsFromCoordinates(bbox, geometry.coordinates)\n}\n\n/**\n * Recurse through nested coordinate arrays. At a leaf position [x,y,(z),(m)],\n * each dimension is filtered independently. NaN/non-finite values in one\n * dimension does not skip the others.\n * @param {Partial<BoundingBox> | undefined} bbox\n * @param {any[]} coordinates\n * @returns {Partial<BoundingBox> | undefined}\n */\nfunction extendBoundsFromCoordinates(bbox, coordinates) {\n if (typeof coordinates[0] === 'number') {\n // Expand bbox\n bbox = updateAxis(bbox, 'xmin', 'xmax', coordinates[0])\n bbox = updateAxis(bbox, 'ymin', 'ymax', coordinates[1])\n if (coordinates.length > 2) bbox = updateAxis(bbox, 'zmin', 'zmax', coordinates[2])\n if (coordinates.length > 3) bbox = updateAxis(bbox, 'mmin', 'mmax', coordinates[3])\n return bbox\n }\n for (const child of coordinates) {\n bbox = extendBoundsFromCoordinates(bbox, child)\n }\n return bbox\n}\n\n/**\n * @param {Partial<BoundingBox> | undefined} bbox\n * @param {'xmin' | 'ymin' | 'zmin' | 'mmin'} minKey\n * @param {'xmax' | 'ymax' | 'zmax' | 'mmax'} maxKey\n * @param {number | undefined} value\n * @returns {Partial<BoundingBox> | undefined}\n */\nfunction updateAxis(bbox, minKey, maxKey, value) {\n if (value === undefined || !Number.isFinite(value)) return bbox\n if (!bbox) bbox = {}\n const min = bbox[minKey]\n const max = bbox[maxKey]\n if (min === undefined || value < min) bbox[minKey] = value\n if (max === undefined || value > max) bbox[maxKey] = value\n return bbox\n}\n\n/**\n * @param {Geometry} geometry\n * @returns {number}\n */\nfunction geometryTypeCodeWithDimension(geometry) {\n const base = geometryTypeCodes[geometry.type]\n if (base === undefined) throw new Error(`unknown geometry type: ${geometry.type}`)\n const dim = inferGeometryDimensions(geometry)\n if (dim === 2) return base\n if (dim === 3) return base + 1000\n if (dim === 4) return base + 3000\n throw new Error(`unsupported geometry dimensions: ${dim}`)\n}\n\nconst geometryTypeCodes = {\n Point: 1,\n LineString: 2,\n Polygon: 3,\n MultiPoint: 4,\n MultiLineString: 5,\n MultiPolygon: 6,\n GeometryCollection: 7,\n}\n\n/**\n * Determine the maximum coordinate dimensions for the geometry.\n * @param {Geometry} geometry\n * @returns {number}\n */\nfunction inferGeometryDimensions(geometry) {\n if (geometry.type === 'GeometryCollection') {\n let maxDim = 0\n for (const child of geometry.geometries || []) {\n maxDim = Math.max(maxDim, inferGeometryDimensions(child))\n }\n return maxDim || 2\n }\n return inferCoordinateDimensions(geometry.coordinates)\n}\n\n/**\n * @param {any[]} value\n * @returns {number}\n */\nfunction inferCoordinateDimensions(value) {\n if (!value.length) return 2\n if (typeof value[0] === 'number') return value.length\n let maxDim = 0\n for (const item of value) {\n maxDim = Math.max(maxDim, inferCoordinateDimensions(item))\n }\n return maxDim || 2\n}\n", "/**\n * @import {AsyncBuffer, Awaitable, DecodedArray} from '../src/types.js'\n */\n\nimport { defaultInitialFetchSize } from './metadata.js'\n\n/**\n * Replace bigint, date, etc with legal JSON types.\n *\n * @param {any} obj object to convert\n * @returns {unknown} converted object\n */\nexport function toJson(obj) {\n if (obj === undefined) return null\n if (typeof obj === 'bigint') return Number(obj)\n if (Object.is(obj, -0)) return 0\n if (Array.isArray(obj)) return obj.map(toJson)\n if (obj instanceof Uint8Array) return Array.from(obj)\n if (obj instanceof Date) return obj.toISOString()\n if (obj instanceof Object) {\n /** @type {Record<string, unknown>} */\n const newObj = {}\n for (const key of Object.keys(obj)) {\n if (obj[key] === undefined) continue\n newObj[key] = toJson(obj[key])\n }\n return newObj\n }\n return obj\n}\n\n/**\n * Concatenate two arrays fast.\n *\n * @param {any[]} aaa\n * @param {DecodedArray} bbb\n */\nexport function concat(aaa, bbb) {\n const chunk = 10000\n for (let i = 0; i < bbb.length; i += chunk) {\n aaa.push(...bbb.slice(i, i + chunk))\n }\n}\n\n/**\n * Deep equality.\n *\n * @param {any} a\n * @param {any} b\n * @param {boolean} [strict]\n * @returns {boolean}\n */\nexport function equals(a, b, strict = true) {\n // eslint-disable-next-line eqeqeq\n if (strict ? a === b : a == b) return true\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') return false\n\n if (a instanceof Uint8Array && b instanceof Uint8Array) {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false\n }\n return true\n }\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!equals(a[i], b[i], strict)) return false\n }\n return true\n }\n\n const aKeys = Object.keys(a)\n if (aKeys.length !== Object.keys(b).length) return false\n for (const k of aKeys) {\n if (!equals(a[k], b[k], strict)) return false\n }\n return true\n}\n\n/**\n * Get the byte length using fetch with a ranged GET request.\n * Aborts the request if server returns 200 instead of 206.\n *\n * @param {string} url\n * @param {RequestInit} [requestInit] fetch options\n * @param {typeof globalThis.fetch} [fetchFn] fetch function to use\n * @returns {Promise<number>}\n */\nasync function byteLengthFromUrlUsingGet(url, requestInit = {}, fetchFn = globalThis.fetch) {\n const controller = new AbortController()\n const headers = new Headers(requestInit.headers)\n headers.set('Range', 'bytes=0-0')\n\n const res = await fetchFn(url, {\n ...requestInit,\n headers,\n signal: controller.signal,\n })\n\n if (!res.ok) throw new Error(`fetch with range failed ${res.status}`)\n\n // Server supports Range requests (206 Partial Content)\n if (res.status === 206) {\n const contentRange = res.headers.get('Content-Range')\n if (!contentRange) throw new Error('missing content-range header')\n\n // Parse \"bytes 0-0/9446073\" to get total length\n const match = contentRange.match(/bytes \\d+-\\d+\\/(\\d+)/)\n if (!match) throw new Error(`invalid content-range header: ${contentRange}`)\n\n return parseInt(match[1])\n }\n\n // Server ignored Range and returned 200 - get Content-Length and abort request\n if (res.status === 200) {\n const contentLength = res.headers.get('Content-Length')\n\n // Abort the request to stop any ongoing download\n controller.abort()\n\n if (contentLength) return parseInt(contentLength)\n }\n\n throw new Error('server does not support range requests and missing content-length')\n}\n\n/**\n * Get the byte length of a URL using a HEAD request.\n * If HEAD fails with 403 (e.g., with signed S3 URLs), falls back to a ranged GET request.\n * If HEAD succeeds but Content-Length is missing, falls back to GET with range.\n * If requestInit is provided, it will be passed to fetch.\n *\n * @param {string} url\n * @param {RequestInit} [requestInit] fetch options\n * @param {typeof globalThis.fetch} [customFetch] fetch function to use\n * @returns {Promise<number>}\n */\nexport async function byteLengthFromUrl(url, requestInit, customFetch) {\n const fetch = customFetch ?? globalThis.fetch\n const res = await fetch(url, { ...requestInit, method: 'HEAD' })\n\n // If HEAD request is forbidden (common with signed S3 URLs), try GET with range\n if (res.status === 403) {\n return byteLengthFromUrlUsingGet(url, requestInit, fetch)\n }\n\n if (!res.ok) throw new Error(`fetch head failed ${res.status}`)\n const length = res.headers.get('Content-Length')\n // If Content-Length is missing from HEAD, fallback to GET with range\n if (!length) {\n return byteLengthFromUrlUsingGet(url, requestInit, fetch)\n }\n return parseInt(length)\n}\n\n/**\n * Construct an AsyncBuffer for a URL.\n * If byteLength is not provided, will make a HEAD request to get the file size.\n * If fetch is provided, it will be used instead of the global fetch.\n * If requestInit is provided, it will be passed to fetch.\n *\n * @param {object} options\n * @param {string} options.url\n * @param {number} [options.byteLength]\n * @param {typeof globalThis.fetch} [options.fetch] fetch function to use\n * @param {RequestInit} [options.requestInit]\n * @returns {Promise<AsyncBuffer>}\n */\nexport async function asyncBufferFromUrl({ url, byteLength, requestInit, fetch: customFetch }) {\n if (!url) throw new Error('missing url')\n const fetch = customFetch ?? globalThis.fetch\n // byte length from HEAD request\n byteLength ??= await byteLengthFromUrl(url, requestInit, fetch)\n\n /**\n * A promise for the whole buffer, if range requests are not supported.\n * @type {Promise<ArrayBuffer>|undefined}\n */\n let buffer = undefined\n const init = requestInit || {}\n\n return {\n byteLength,\n async slice(start, end) {\n if (buffer) {\n return buffer.then(buffer => buffer.slice(start, end))\n }\n\n const headers = new Headers(init.headers)\n const endStr = end === undefined ? '' : end - 1\n headers.set('Range', `bytes=${start}-${endStr}`)\n\n const res = await fetch(url, { ...init, headers })\n if (!res.ok || !res.body) throw new Error(`fetch failed ${res.status}`)\n\n if (res.status === 200) {\n // Endpoint does not support range requests and returned the whole object\n buffer = res.arrayBuffer()\n return buffer.then(buffer => buffer.slice(start, end))\n } else if (res.status === 206) {\n // The endpoint supports range requests and sent us the requested range\n return res.arrayBuffer()\n } else {\n throw new Error(`fetch received unexpected status code ${res.status}`)\n }\n },\n }\n}\n\n/**\n * Returns a cached layer on top of an AsyncBuffer. For caching slices of a file\n * that are read multiple times, possibly over a network.\n *\n * @param {AsyncBuffer} file file-like object to cache\n * @param {{ minSize?: number }} [options]\n * @returns {AsyncBuffer} cached file-like object\n */\nexport function cachedAsyncBuffer({ byteLength, slice }, { minSize = defaultInitialFetchSize } = {}) {\n if (byteLength < minSize) {\n // Cache whole file if it's small\n const buffer = slice(0, byteLength)\n return {\n byteLength,\n async slice(start, end) {\n return (await buffer).slice(start, end)\n },\n }\n }\n const cache = new Map()\n return {\n byteLength,\n /**\n * @param {number} start\n * @param {number} [end]\n * @returns {Awaitable<ArrayBuffer>}\n */\n slice(start, end) {\n const key = cacheKey(start, end, byteLength)\n const cached = cache.get(key)\n if (cached) return cached\n // cache miss, read from file\n const promise = slice(start, end)\n cache.set(key, promise)\n return promise\n },\n }\n}\n\n\n/**\n * Returns canonical cache key for a byte range 'start,end'.\n * Normalize int-range and suffix-range requests to the same key.\n *\n * @param {number} start start byte of range\n * @param {number} [end] end byte of range, or undefined for suffix range\n * @param {number} [size] size of file, or undefined for suffix range\n * @returns {string}\n */\nfunction cacheKey(start, end, size) {\n if (start < 0) {\n if (end !== undefined) throw new Error(`invalid suffix range [${start}, ${end}]`)\n if (size === undefined) return `${start},`\n return `${size + start},${size}`\n } else if (end !== undefined) {\n if (start > end) throw new Error(`invalid empty range [${start}, ${end}]`)\n return `${start},${end}`\n } else if (size === undefined) {\n return `${start},`\n } else {\n return `${start},${size}`\n }\n}\n\n/**\n * Flatten a list of lists into a single list.\n *\n * @param {DecodedArray[]} [chunks]\n * @returns {DecodedArray}\n */\nexport function flatten(chunks) {\n if (!chunks) return []\n if (chunks.length === 1) return chunks[0]\n /** @type {any[]} */\n const output = []\n for (const chunk of chunks) {\n concat(output, chunk)\n }\n return output\n}\n", "import { ByteWriter } from './bytewriter.js'\n\n/**\n * @import {Geometry, Position} from 'hyparquet/src/types.js'\n */\n\n/**\n * Serialize a GeoJSON geometry into ISO WKB.\n *\n * @param {Geometry} geometry\n * @returns {Uint8Array}\n */\nexport function geojsonToWkb(geometry) {\n const writer = new ByteWriter()\n writeGeometry(writer, geometry)\n return writer.getBytes()\n}\n\n/**\n * @param {ByteWriter} writer\n * @param {Geometry} geometry\n */\nfunction writeGeometry(writer, geometry) {\n if (typeof geometry !== 'object') {\n throw new Error('geometry values must be GeoJSON geometries')\n }\n const typeCode = geometryTypeCode(geometry.type)\n\n // infer dimensions\n const dim = inferGeometryDimensions(geometry)\n let flag = 0\n if (dim === 3) flag = 1\n else if (dim === 4) flag = 3\n else if (dim > 4) throw new Error(`unsupported geometry dimensions: ${dim}`)\n\n writer.appendUint8(1) // little endian\n writer.appendUint32(typeCode + flag * 1000)\n\n if (geometry.type === 'Point') {\n writePosition(writer, geometry.coordinates, dim)\n } else if (geometry.type === 'LineString') {\n writeLine(writer, geometry.coordinates, dim)\n } else if (geometry.type === 'Polygon') {\n writer.appendUint32(geometry.coordinates.length)\n for (const ring of geometry.coordinates) {\n writeLine(writer, ring, dim)\n }\n } else if (geometry.type === 'MultiPoint') {\n writer.appendUint32(geometry.coordinates.length)\n for (const coordinates of geometry.coordinates) {\n writeGeometry(writer, { type: 'Point', coordinates })\n }\n } else if (geometry.type === 'MultiLineString') {\n writer.appendUint32(geometry.coordinates.length)\n for (const coordinates of geometry.coordinates) {\n writeGeometry(writer, { type: 'LineString', coordinates })\n }\n } else if (geometry.type === 'MultiPolygon') {\n writer.appendUint32(geometry.coordinates.length)\n for (const coordinates of geometry.coordinates) {\n writeGeometry(writer, { type: 'Polygon', coordinates })\n }\n } else if (geometry.type === 'GeometryCollection') {\n writer.appendUint32(geometry.geometries.length)\n for (const child of geometry.geometries) {\n writeGeometry(writer, child)\n }\n } else {\n throw new Error('unsupported geometry type')\n }\n}\n\n/**\n * @param {ByteWriter} writer\n * @param {Position} position\n * @param {number} dim\n */\nfunction writePosition(writer, position, dim) {\n if (position.length < dim) {\n throw new Error('geometry position dimensions mismatch')\n }\n for (let i = 0; i < dim; i++) {\n writer.appendFloat64(position[i])\n }\n}\n\n/**\n * @param {ByteWriter} writer\n * @param {Position[]} coordinates\n * @param {number} dim\n */\nfunction writeLine(writer, coordinates, dim) {\n writer.appendUint32(coordinates.length)\n for (const position of coordinates) {\n writePosition(writer, position, dim)\n }\n}\n\n/**\n * @param {Geometry['type']} type\n * @returns {number}\n */\nfunction geometryTypeCode(type) {\n if (type === 'Point') return 1\n if (type === 'LineString') return 2\n if (type === 'Polygon') return 3\n if (type === 'MultiPoint') return 4\n if (type === 'MultiLineString') return 5\n if (type === 'MultiPolygon') return 6\n if (type === 'GeometryCollection') return 7\n throw new Error(`unknown geometry type: ${type}`)\n}\n\n/**\n * Determine the maximum coordinate dimensions for the geometry.\n *\n * @param {Geometry} geometry\n * @returns {number}\n */\nfunction inferGeometryDimensions(geometry) {\n if (geometry.type === 'GeometryCollection') {\n let maxDim = 0\n for (const child of geometry.geometries) {\n maxDim = Math.max(maxDim, inferGeometryDimensions(child))\n }\n return maxDim || 2\n }\n return inferCoordinateDimensions(geometry.coordinates)\n}\n\n/**\n * @param {any} value\n * @returns {number}\n */\nfunction inferCoordinateDimensions(value) {\n if (!Array.isArray(value)) return 2\n if (!value.length) return 2\n if (typeof value[0] === 'number') return value.length\n let maxDim = 0\n for (const item of value) {\n maxDim = Math.max(maxDim, inferCoordinateDimensions(item))\n }\n return maxDim || 2\n}\n", "import { toJson } from 'hyparquet'\nimport { geojsonToWkb } from './wkb.js'\n\n/**\n * @import {DecodedArray, SchemaElement, Statistics} from 'hyparquet'\n * @import {MinMaxType} from 'hyparquet/src/types.js'\n * @import {ThriftObject} from '../src/types.js'\n */\n\nconst dayMillis = 86400000 // 1 day in milliseconds\n\n/**\n * Convert from rich to primitive types.\n *\n * @param {SchemaElement} element\n * @param {DecodedArray} values\n * @returns {DecodedArray}\n */\nexport function unconvert(element, values) {\n const { type, converted_type: ctype, logical_type: ltype } = element\n if (ctype === 'DECIMAL') {\n const factor = 10 ** (element.scale || 0)\n return values.map(v => {\n if (v === null || v === undefined) return v\n if (typeof v !== 'number') throw new Error('DECIMAL must be a number')\n return unconvertDecimal(element, BigInt(Math.round(v * factor)))\n })\n }\n if (ctype === 'DATE') {\n return Array.from(values).map(v => {\n if (v instanceof Date) return Math.floor(v.getTime() / dayMillis)\n return v\n })\n }\n if (ctype === 'TIMESTAMP_MILLIS') {\n return Array.from(values).map(v => {\n if (v === null || v === undefined) return v\n if (v instanceof Date) return BigInt(v.getTime())\n return BigInt(v)\n })\n }\n if (ctype === 'TIMESTAMP_MICROS') {\n return Array.from(values).map(v => {\n if (v === null || v === undefined) return v\n if (v instanceof Date) return BigInt(v.getTime() * 1000)\n return BigInt(v)\n })\n }\n if (ctype === 'JSON') {\n if (!Array.isArray(values)) throw new Error('JSON must be an array')\n const encoder = new TextEncoder()\n return values.map(v => v === undefined ? undefined : encoder.encode(JSON.stringify(toJson(v))))\n }\n if (ctype === 'UTF8') {\n if (!Array.isArray(values)) throw new Error('strings must be an array')\n const encoder = new TextEncoder()\n return values.map(v => typeof v === 'string' ? encoder.encode(v) : v)\n }\n if (ctype === 'UINT_32' || ltype?.type === 'INTEGER' && ltype.bitWidth === 32 && !ltype.isSigned) {\n if (values instanceof Uint32Array) return values\n if (values instanceof Int32Array) return new Uint32Array(values.buffer, values.byteOffset, values.length)\n return Array.from(values).map(v => {\n if (v === null || v === undefined) return v\n if (!Number.isSafeInteger(v)) throw new Error('expected integer value, got ' + v)\n if (v < 0 || v > 4294967295) throw new Error('expected uint32 value, got ' + v)\n if (v > 2147483647) return v - 4294967296 // convert to signed range\n return v\n })\n }\n if (ltype?.type === 'FLOAT16') {\n if (type !== 'FIXED_LEN_BYTE_ARRAY') throw new Error('FLOAT16 must be FIXED_LEN_BYTE_ARRAY type')\n if (element.type_length !== 2) throw new Error('FLOAT16 expected type_length to be 2 bytes')\n return Array.from(values).map(unconvertFloat16)\n }\n if (ltype?.type === 'UUID') {\n if (!Array.isArray(values)) throw new Error('UUID must be an array')\n if (type !== 'FIXED_LEN_BYTE_ARRAY') throw new Error('UUID must be FIXED_LEN_BYTE_ARRAY type')\n if (element.type_length !== 16) throw new Error('UUID expected type_length to be 16 bytes')\n return values.map(unconvertUuid)\n }\n if (ltype?.type === 'TIMESTAMP') {\n return Array.from(values).map(v => {\n if (v === null || v === undefined) return v\n if (v instanceof Date) {\n const millis = BigInt(v.getTime())\n if (ltype.unit === 'NANOS') return millis * 1_000_000n\n if (ltype.unit === 'MICROS') return millis * 1_000n\n return millis // MILLIS (default)\n }\n return BigInt(v)\n })\n }\n if (ltype?.type === 'GEOMETRY' || ltype?.type === 'GEOGRAPHY') {\n if (!Array.isArray(values)) throw new Error('geometry must be an array')\n return values.map(v => {\n if (v === null || v === undefined) return v\n return geojsonToWkb(v)\n })\n }\n return values\n}\n\n/**\n * @param {Uint8Array | string | undefined} value\n * @returns {Uint8Array | undefined}\n */\nfunction unconvertUuid(value) {\n if (value === undefined || value === null) return\n if (value instanceof Uint8Array) return value\n if (typeof value === 'string') {\n const uuidRegex = /^[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}$/i\n if (!uuidRegex.test(value)) {\n throw new Error('UUID must be a valid UUID string')\n }\n value = value.replace(/-/g, '').toLowerCase()\n const bytes = new Uint8Array(16)\n for (let i = 0; i < 16; i++) {\n bytes[i] = parseInt(value.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n }\n throw new Error('UUID must be a string or Uint8Array')\n}\n\n// Statistics min/max values are truncated to this many bytes to bound footer size.\nconst STATS_TRUNCATE_LENGTH = 16\n\n/**\n * Truncate a byte-array statistic to STATS_TRUNCATE_LENGTH bytes.\n *\n * A truncated prefix is a valid lower bound (min) but not a valid upper bound:\n * for a max we must round the prefix up to the smallest byte string that is\n * still >= the original. We do that by incrementing the last byte that is\n * < 0xFF, dropping any trailing 0xFF bytes first. If every prefix byte is 0xFF\n * there is no shorter upper bound, so the max is omitted (returns undefined).\n *\n * @param {Uint8Array} bytes\n * @param {boolean} isMax\n * @returns {Uint8Array | undefined}\n */\nfunction truncateStatistic(bytes, isMax) {\n if (bytes.length <= STATS_TRUNCATE_LENGTH) return bytes\n const prefix = bytes.slice(0, STATS_TRUNCATE_LENGTH)\n if (!isMax) return prefix // a prefix is a valid lower bound\n let i = prefix.length - 1\n while (i >= 0 && prefix[i] === 0xff) i-- // drop trailing 0xFF\n if (i < 0) return undefined // all 0xFF: no valid shorter upper bound\n const rounded = prefix.slice(0, i + 1)\n rounded[i] += 1\n return rounded\n}\n\n/**\n * Returns false when a min/max value had to be truncated, otherwise undefined.\n *\n * We only emit the (optional) exactness flag when it is false; an absent flag\n * means the value is exact, which keeps the footer small for untruncated columns.\n *\n * @param {MinMaxType | undefined} value\n * @param {SchemaElement} element\n * @returns {boolean | undefined}\n */\nfunction minMaxIsExact(value, element) {\n if (value === undefined || value === null) return undefined\n const { type } = element\n // only byte-array statistics are ever truncated\n if (type !== 'BYTE_ARRAY' && type !== 'FIXED_LEN_BYTE_ARRAY') return undefined\n if (element.logical_type?.type === 'UUID') return undefined // exactly 16 bytes, never truncated\n const bytes = value instanceof Uint8Array ? value : new TextEncoder().encode(value.toString())\n return bytes.length > STATS_TRUNCATE_LENGTH ? false : undefined\n}\n\n/**\n * Uncovert from rich type to byte array for metadata statistics.\n *\n * @param {MinMaxType | undefined} value\n * @param {SchemaElement} element\n * @param {boolean} isMax whether this is a max value (rounds truncation up)\n * @returns {Uint8Array | undefined}\n */\nexport function unconvertMinMax(value, element, isMax) {\n if (value === undefined || value === null) return undefined\n const { type, converted_type } = element\n if (type === 'BOOLEAN') return new Uint8Array([value ? 1 : 0])\n if (element.logical_type?.type === 'UUID' && (typeof value === 'string' || value instanceof Uint8Array)) {\n return unconvertUuid(value)\n }\n if (converted_type === 'DECIMAL') {\n if (typeof value !== 'number') throw new Error('DECIMAL must be a number')\n const factor = 10 ** (element.scale || 0)\n const out = unconvertDecimal(element, BigInt(Math.round(value * factor)))\n if (out instanceof Uint8Array) return out\n if (typeof out === 'number') {\n const buffer = new ArrayBuffer(4)\n new DataView(buffer).setFloat32(0, out, true)\n return new Uint8Array(buffer)\n }\n if (typeof out === 'bigint') {\n const buffer = new ArrayBuffer(8)\n new DataView(buffer).setBigInt64(0, out, true)\n return new Uint8Array(buffer)\n }\n }\n if (type === 'BYTE_ARRAY' || type === 'FIXED_LEN_BYTE_ARRAY') {\n const bytes = value instanceof Uint8Array ? value : new TextEncoder().encode(value.toString())\n return truncateStatistic(bytes, isMax)\n }\n if (type === 'FLOAT' && typeof value === 'number') {\n const buffer = new ArrayBuffer(4)\n new DataView(buffer).setFloat32(0, value, true)\n return new Uint8Array(buffer)\n }\n if (type === 'DOUBLE' && typeof value === 'number') {\n const buffer = new ArrayBuffer(8)\n new DataView(buffer).setFloat64(0, value, true)\n return new Uint8Array(buffer)\n }\n if (type === 'INT32' && typeof value === 'number') {\n const buffer = new ArrayBuffer(4)\n new DataView(buffer).setInt32(0, value, true)\n return new Uint8Array(buffer)\n }\n if (type === 'INT64' && typeof value === 'bigint') {\n const buffer = new ArrayBuffer(8)\n new DataView(buffer).setBigInt64(0, value, true)\n return new Uint8Array(buffer)\n }\n if (type === 'INT32' && converted_type === 'DATE' && value instanceof Date) {\n const buffer = new ArrayBuffer(4)\n new DataView(buffer).setInt32(0, Math.floor(value.getTime() / dayMillis), true)\n return new Uint8Array(buffer)\n }\n if (type === 'INT64' && converted_type === 'TIMESTAMP_MILLIS' && value instanceof Date) {\n const buffer = new ArrayBuffer(8)\n new DataView(buffer).setBigInt64(0, BigInt(value.getTime()), true)\n return new Uint8Array(buffer)\n }\n if (type === 'INT64' && converted_type === 'TIMESTAMP_MICROS' && value instanceof Date) {\n const buffer = new ArrayBuffer(8)\n new DataView(buffer).setBigInt64(0, BigInt(value.getTime() * 1000), true)\n return new Uint8Array(buffer)\n }\n if (type === 'INT64' && element.logical_type?.type === 'TIMESTAMP' && value instanceof Date) {\n const millis = BigInt(value.getTime())\n const { unit } = element.logical_type\n let bigintValue = millis\n if (unit === 'NANOS') bigintValue = millis * 1_000_000n\n else if (unit === 'MICROS') bigintValue = millis * 1_000n\n const buffer = new ArrayBuffer(8)\n new DataView(buffer).setBigInt64(0, bigintValue, true)\n return new Uint8Array(buffer)\n }\n throw new Error(`unsupported type for statistics: ${type} with value ${value}`)\n}\n\n/**\n * @param {Statistics} stats\n * @param {SchemaElement} element\n * @returns {ThriftObject}\n */\nexport function unconvertStatistics(stats, element) {\n return {\n field_1: unconvertMinMax(stats.max, element, true),\n field_2: unconvertMinMax(stats.min, element, false),\n field_3: stats.null_count,\n field_4: stats.distinct_count,\n field_5: unconvertMinMax(stats.max_value, element, true),\n field_6: unconvertMinMax(stats.min_value, element, false),\n field_7: stats.is_max_value_exact ?? minMaxIsExact(stats.max_value ?? stats.max, element),\n field_8: stats.is_min_value_exact ?? minMaxIsExact(stats.min_value ?? stats.min, element),\n }\n}\n\n/**\n * @param {SchemaElement} element\n * @param {bigint} value\n * @returns {number | bigint | Uint8Array}\n */\nexport function unconvertDecimal({ type, type_length }, value) {\n if (type === 'INT32') return Number(value)\n if (type === 'INT64') return value\n if (type === 'FIXED_LEN_BYTE_ARRAY' && !type_length) {\n throw new Error('fixed length byte array type_length is required')\n }\n if (!type_length && !value) return new Uint8Array()\n\n const bytes = []\n while (true) {\n // extract the lowest 8 bits\n const byte = Number(value & 0xffn)\n bytes.unshift(byte)\n value >>= 8n\n\n if (type_length) {\n if (bytes.length >= type_length) break // fixed length\n } else {\n // for nonnegative: stop when top byte has signBit = 0 AND shifted value == 0n\n // for negative: stop when top byte has signBit = 1 AND shifted value == -1n\n const sign = byte & 0x80\n if (!sign && value === 0n || sign && value === -1n) {\n break\n }\n }\n }\n\n return new Uint8Array(bytes)\n}\n\n/**\n * @param {number | undefined} value\n * @returns {Uint8Array | undefined}\n */\nexport function unconvertFloat16(value) {\n if (value === undefined || value === null) return\n if (typeof value !== 'number') throw new Error('parquet float16 expected number value')\n if (Number.isNaN(value)) return new Uint8Array([0x00, 0x7e])\n\n const sign = value < 0 || Object.is(value, -0) ? 1 : 0\n const abs = Math.abs(value)\n\n // infinities\n if (!isFinite(abs)) return new Uint8Array([0x00, sign << 7 | 0x7c])\n\n // \u00B10\n if (abs === 0) return new Uint8Array([0x00, sign << 7])\n\n // write as f32 to get raw bits\n const buf = new ArrayBuffer(4)\n new Float32Array(buf)[0] = abs\n const bits32 = new Uint32Array(buf)[0]\n\n let exp32 = bits32 >>> 23 & 0xff\n let mant32 = bits32 & 0x7fffff\n\n // convert 32\u2011bit exponent to unbiased, then to 16\u2011bit\n exp32 -= 127\n\n // handle numbers too small for a normal 16\u2011bit exponent\n if (exp32 < -14) {\n // sub\u2011normal: shift mantissa so that result = mant * 2^-14\n const shift = -14 - exp32\n mant32 = (mant32 | 0x800000) >> shift + 13\n\n // round\u2011to\u2011nearest\u2011even\n if (mant32 & 1) mant32 += 1\n\n const bits16 = sign << 15 | mant32\n return new Uint8Array([bits16 & 0xff, bits16 >> 8])\n }\n\n // overflow\n if (exp32 > 15) return new Uint8Array([0x00, sign << 7 | 0x7c])\n\n // normal number\n let exp16 = exp32 + 15\n mant32 = mant32 + 0x1000 // add rounding bit\n\n // handle mantissa overflow after rounding\n if (mant32 & 0x800000) {\n mant32 = 0\n if (++exp16 === 31) // became infinity\n return new Uint8Array([0x00, sign << 7 | 0x7c])\n }\n\n const bits16 = sign << 15 | exp16 << 10 | mant32 >> 13\n return new Uint8Array([bits16 & 0xff, bits16 >> 8])\n}\n", "import { BloomBuilder } from './bloom.js'\nimport { writeDataPageV2 } from './datapage.js'\nimport { estimateValueSize, useDictionary, writeDictionaryPage } from './dictionary.js'\nimport { geospatialStatistics } from './geospatial.js'\nimport { unconvert, unconvertMinMax } from './unconvert.js'\n\n/**\n * @import {ColumnChunk, ColumnIndex, DecodedArray, Encoding, OffsetIndex, ParquetType, Statistics} from 'hyparquet'\n * @import {PageEncodingStats} from 'hyparquet/src/types.js'\n * @import {ColumnEncoder, PageData, Writer} from '../src/types.js'\n */\n\n/**\n * Write a column chunk to the writer.\n *\n * @param {object} options\n * @param {Writer} options.writer\n * @param {ColumnEncoder} options.column\n * @param {PageData} options.pageData\n * @returns {{ chunk: ColumnChunk, columnIndex?: ColumnIndex, offsetIndex?: OffsetIndex, bloomFilter?: Uint32Array }}\n */\nexport function writeColumn({ writer, column, pageData }) {\n const { columnName, element, schemaPath, stats, pageSize, encoding: userEncoding } = column\n const { type, type_length } = element\n if (!type) throw new Error(`column ${columnName} cannot determine type`)\n const { values, definitionLevels, repetitionLevels, maxDefinitionLevel } = pageData\n const offsetStart = writer.offset\n\n /** @type {Encoding[]} */\n const encodings = []\n\n const isGeospatial = element?.logical_type?.type === 'GEOMETRY' || element?.logical_type?.type === 'GEOGRAPHY'\n\n // Compute statistics\n const statistics = stats ? getStatistics(values) : undefined\n const geospatial_statistics = stats && isGeospatial ? geospatialStatistics(values) : undefined\n\n // Build bloom filter from original values (hashParquetValue reads schema info from element)\n let bloomFilter\n if (column.bloomFilter) {\n const opts = typeof column.bloomFilter === 'object' ? column.bloomFilter : undefined\n const builder = new BloomBuilder(element, opts)\n for (const v of values) builder.insert(v)\n bloomFilter = builder.finalize()\n }\n\n // dictionary encoding\n /** @type {bigint | undefined} */\n let dictionary_page_offset\n const { dictionary, indexes } = useDictionary(values, type, type_length, userEncoding, pageSize)\n\n // Determine encoding and prepare values for writing\n /** @type {Encoding} */\n let encoding\n /** @type {DecodedArray} */\n let writeValues\n let writeType = type\n if (dictionary && indexes) {\n // replace values with dictionary indices\n writeValues = indexes\n writeType = 'INT32'\n encoding = 'RLE_DICTIONARY'\n\n // write dictionary page first\n dictionary_page_offset = BigInt(writer.offset)\n const unconverted = unconvert(element, dictionary)\n writeDictionaryPage(writer, column, unconverted)\n } else {\n // unconvert values from rich types to simple\n writeValues = unconvert(element, values)\n encoding = userEncoding ?? (type === 'BOOLEAN' && values.length > 16 ? 'RLE' : 'PLAIN')\n }\n encodings.push(encoding)\n\n // Split values into pages based on pageSize\n const pageBoundaries = getPageBoundaries(writeValues, writeType, type_length, pageSize)\n\n // Initialize index structures if requested\n /** @type {ColumnIndex | undefined} */\n const columnIndex = column.columnIndex && pageBoundaries.length > 1 ? {\n null_pages: [],\n min_values: [],\n max_values: [],\n boundary_order: 'UNORDERED',\n null_counts: [],\n } : undefined\n /** @type {OffsetIndex | undefined} */\n const offsetIndex = column.offsetIndex && pageBoundaries.length > 1 ? {\n page_locations: [],\n } : undefined\n\n // Write data pages\n const data_page_offset = BigInt(writer.offset)\n let first_row_index = 0n\n let prevStart = 0\n let prevMinValue\n let prevMaxValue\n let ascending = true\n let descending = true\n\n for (const { start, end } of pageBoundaries) {\n const pageOffset = writer.offset\n\n // Slice into subpage and write levels and data\n const pageChunk = {\n values: writeValues.slice(start, end),\n definitionLevels: definitionLevels.slice(start, end),\n repetitionLevels: repetitionLevels.slice(start, end),\n maxDefinitionLevel,\n }\n writeDataPageV2({ writer, column, encoding, pageData: pageChunk })\n\n // ColumnIndex construction\n if (columnIndex) {\n const pageValues = values.slice(start, end) // original values not indexes\n const { min_value, max_value, null_count = 0n } = getStatistics(pageValues)\n\n columnIndex.null_pages.push(null_count === BigInt(end - start)) // all nulls\n // Spec: for all-null pages set \"byte[0]\"\n columnIndex.min_values.push(unconvertMinMax(min_value, element, false) ?? new Uint8Array())\n columnIndex.max_values.push(unconvertMinMax(max_value, element, true) ?? new Uint8Array())\n columnIndex.null_counts?.push(null_count)\n\n // Track boundary order using original JS values\n if (prevMinValue !== undefined && min_value !== undefined) {\n if (prevMinValue > min_value) ascending = false\n if (prevMinValue < min_value) descending = false\n }\n if (prevMaxValue !== undefined && max_value !== undefined) {\n if (prevMaxValue > max_value) ascending = false\n if (prevMaxValue < max_value) descending = false\n }\n prevMinValue = min_value\n prevMaxValue = max_value\n }\n\n // OffsetIndex construction\n if (offsetIndex) {\n if (repetitionLevels.length) {\n // Count row boundaries from previous page\n for (let i = prevStart + 1; i <= start; i++) {\n if (repetitionLevels[i] === 0) first_row_index++\n }\n } else {\n first_row_index = BigInt(start) // Flat column\n }\n\n offsetIndex.page_locations.push({\n offset: BigInt(pageOffset),\n compressed_page_size: writer.offset - pageOffset,\n first_row_index,\n })\n }\n\n prevStart = start\n }\n\n // Set boundary order after all pages are written\n if (columnIndex) {\n if (ascending) columnIndex.boundary_order = 'ASCENDING'\n else if (descending) columnIndex.boundary_order = 'DESCENDING'\n }\n\n // Build encoding stats\n /** @type {PageEncodingStats[] | undefined} */\n let encoding_stats\n if (stats) {\n encoding_stats = []\n if (dictionary_page_offset !== undefined) {\n encoding_stats.push({ page_type: 'DICTIONARY_PAGE', encoding: 'PLAIN', count: 1 })\n }\n encoding_stats.push({ page_type: 'DATA_PAGE_V2', encoding, count: pageBoundaries.length })\n }\n\n return {\n chunk: {\n meta_data: {\n type,\n encodings,\n path_in_schema: schemaPath.slice(1).map(s => s.name),\n codec: column.codec ?? 'UNCOMPRESSED',\n num_values: BigInt(values.length),\n total_compressed_size: BigInt(writer.offset - offsetStart),\n total_uncompressed_size: BigInt(writer.offset - offsetStart), // TODO: uncompressed pages + headers\n data_page_offset,\n dictionary_page_offset,\n statistics,\n encoding_stats,\n geospatial_statistics,\n },\n file_offset: BigInt(offsetStart),\n },\n columnIndex,\n offsetIndex,\n bloomFilter,\n }\n}\n\n/**\n * Get page boundaries based on estimated byte size.\n * TODO: split pages on row boundaries\n *\n * @param {DecodedArray} values\n * @param {ParquetType} type\n * @param {number | undefined} type_length\n * @param {number} pageSize\n * @returns {{start: number, end: number}[]}\n */\nfunction getPageBoundaries(values, type, type_length, pageSize) {\n // If no pageSize limit, return single page with all values\n if (!pageSize) {\n return [{ start: 0, end: values.length }]\n }\n\n const boundaries = []\n let start = 0\n let accumulatedBytes = 0\n\n for (let i = 0; i < values.length; i++) {\n const valueSize = estimateValueSize(values[i], type, type_length)\n accumulatedBytes += valueSize\n\n // Check if we should start a new page\n if (accumulatedBytes >= pageSize && i > start) {\n boundaries.push({ start, end: i })\n start = i\n accumulatedBytes = valueSize\n }\n }\n\n // Final page with remaining values\n if (start < values.length) {\n boundaries.push({ start, end: values.length })\n }\n\n return boundaries\n}\n\n/**\n * @param {DecodedArray} values\n * @returns {Statistics}\n */\nfunction getStatistics(values) {\n let min_value = undefined\n let max_value = undefined\n let null_count = 0n\n for (const value of values) {\n if (value === null || value === undefined) {\n null_count++\n continue\n }\n if (typeof value === 'object') continue // skip objects\n if (typeof value === 'number' && Number.isNaN(value)) continue // skip NaN per parquet spec\n if (min_value === undefined || value < min_value) min_value = value\n if (max_value === undefined || value > max_value) max_value = value\n }\n // Normalize signed zero per parquet spec: min becomes -0, max becomes +0\n if (min_value === 0) min_value = -0\n if (max_value === 0) max_value = 0\n return { min_value, max_value, null_count }\n}\n", "import { getMaxDefinitionLevel, isListLike, isMapLike } from 'hyparquet/src/schema.js'\n\n/**\n * @import {DecodedArray, SchemaElement, SchemaTree} from 'hyparquet'\n * @import {PageData} from '../src/types.js'\n */\n\n/**\n * Encode column values into repetition and definition levels following the\n * Dremel algorithm. Returns page data for one subcolumn (leaf node in the schema).\n *\n * @param {SchemaTree[]} treePath schema tree nodes from root to leaf\n * @param {DecodedArray} rows top-level column data\n * @returns {PageData}\n */\nexport function encodeNestedValues(treePath, rows) {\n const schemaPath = treePath.map(n => n.element)\n if (treePath.length < 2) throw new Error('parquet schema path must include column')\n\n /** @type {number[]} */\n const definitionLevels = []\n /** @type {number[]} */\n const repetitionLevels = []\n const maxDefinitionLevel = getMaxDefinitionLevel(treePath)\n\n // Flat required columns don't need dremel encoding\n if (treePath.length === 2 && maxDefinitionLevel === 0) {\n return { values: rows, definitionLevels, repetitionLevels, maxDefinitionLevel }\n }\n\n // Flat optional columns: just compute definition levels\n if (treePath.length === 2 && maxDefinitionLevel === 1) {\n const definitionLevels = new Array(rows.length)\n for (let i = 0; i < rows.length; i++) {\n definitionLevels[i] = rows[i] === null || rows[i] === undefined ? 0 : 1\n }\n return { values: rows, definitionLevels, repetitionLevels, maxDefinitionLevel }\n }\n\n // Track repetition depth prior to each level\n const repLevelPrior = new Array(treePath.length)\n let repeatedCount = 0\n for (let i = 0; i < treePath.length; i++) {\n repLevelPrior[i] = repeatedCount\n if (schemaPath[i].repetition_type === 'REPEATED') repeatedCount++\n }\n\n /** @type {any[]} */\n const values = []\n\n for (const row of rows) {\n visit(1, row, 0, 0, false)\n }\n\n return { values, definitionLevels, repetitionLevels, maxDefinitionLevel }\n\n /**\n * Recursively walk the schema path, emitting definition/repetition pairs.\n *\n * @param {number} depth index into schemaPath\n * @param {any} value value at the current depth\n * @param {number} defLevel definition level accumulated so far\n * @param {number} repLevel repetition level for the next emitted slot\n * @param {boolean} allowNull whether the current value is allowed to be null\n */\n function visit(depth, value, defLevel, repLevel, allowNull) {\n const element = schemaPath[depth]\n const repetition = element.repetition_type || 'REQUIRED'\n\n // Leaf node\n if (depth === treePath.length - 1) {\n if (value === null || value === undefined) {\n if (repetition === 'REQUIRED' && !allowNull) {\n throw new Error('parquet required value is undefined')\n }\n definitionLevels.push(defLevel)\n } else {\n definitionLevels.push(repetition === 'REQUIRED' ? defLevel : defLevel + 1)\n }\n repetitionLevels.push(repLevel)\n values.push(value)\n return\n }\n\n if (repetition === 'REPEATED') {\n if (value === null || value === undefined) {\n if (!allowNull) throw new Error('parquet required value is undefined')\n visit(depth + 1, undefined, defLevel, repLevel, true)\n return\n }\n if (!Array.isArray(value)) {\n throw new Error(`parquet repeated field ${element.name} must be an array`)\n }\n if (!value.length) {\n visit(depth + 1, undefined, defLevel, repLevel, true)\n return\n }\n // For MAP key_value entries, extract the child field (key or value) from each entry\n const isMapEntry = isMapLike(treePath[depth - 1])\n const childElement = schemaPath[depth + 1]\n for (let i = 0; i < value.length; i++) {\n let childValue = value[i]\n if (isMapEntry && childValue && typeof childValue === 'object' && childElement) {\n childValue = childValue[childElement.name]\n }\n const childRep = i === 0 ? repLevel : repLevelPrior[depth] + 1\n visit(depth + 1, childValue, defLevel + 1, childRep, false)\n }\n return\n }\n\n if (repetition === 'OPTIONAL') {\n if (value === null || value === undefined) {\n visit(depth + 1, undefined, defLevel, repLevel, true)\n } else {\n const childValue = getChildValue(depth, value)\n const childIsNull = childValue === null || childValue === undefined\n // Increment def level if: (1) this is a struct (contributes to def even if child is null),\n // or (2) the child value exists. LIST/MAP wrappers don't increment def level themselves.\n const isLogicalContainer = isListLike(treePath[depth]) || isMapLike(treePath[depth])\n const isStruct = element.num_children && !element.type && !isLogicalContainer\n const nextDef = isStruct || !childIsNull ? defLevel + 1 : defLevel\n visit(depth + 1, childValue, nextDef, repLevel, childIsNull)\n }\n return\n }\n\n // REQUIRED\n if (value === null || value === undefined) {\n if (!allowNull) throw new Error('parquet required value is undefined')\n visit(depth + 1, undefined, defLevel, repLevel, true)\n } else {\n visit(depth + 1, getChildValue(depth, value), defLevel, repLevel, false)\n }\n }\n\n /**\n * Select the child value for the next schema element in the path.\n * Normalizes maps to {key, value} entries.\n *\n * @param {number} depth current schema depth\n * @param {any} currentValue current value at this depth\n * @returns {any}\n */\n function getChildValue(depth, currentValue) {\n if (currentValue === null || currentValue === undefined) return undefined\n const child = schemaPath[depth + 1]\n if (!child) return undefined\n\n // LIST and MAP wrappers\n if (isListLike(treePath[depth])) return currentValue\n if (isMapLike(treePath[depth])) {\n return normalizeMap(currentValue, schemaPath[depth])\n }\n\n if (typeof currentValue === 'object' && !Array.isArray(currentValue)) {\n return currentValue[child.name]\n }\n\n throw new Error(`parquet expected struct, got ${currentValue}`)\n }\n\n}\n\n/**\n * Normalize a map value to an array of {key, value} entries.\n * Accepts Map, plain object, array of [k, v] pairs, or array of {key, value}.\n *\n * @param {any} value\n * @param {SchemaElement} element\n * @returns {{key: any, value: any}[]}\n */\nfunction normalizeMap(value, element) {\n if (value instanceof Map) {\n return Array.from(value.entries(), ([k, v]) => ({ key: k, value: v }))\n }\n if (Array.isArray(value)) {\n return value.map(entry => {\n if (entry && typeof entry === 'object' && 'key' in entry && 'value' in entry) {\n return entry\n }\n if (Array.isArray(entry) && entry.length === 2) {\n return { key: entry[0], value: entry[1] }\n }\n throw new Error('parquet map entry must provide key and value')\n })\n }\n if (typeof value === 'object') {\n return Object.entries(value).map(([k, v]) => ({ key: k, value: v }))\n }\n throw new Error(`parquet map field ${element.name} must be Map, array, or object`)\n}\n", "import { BoundaryOrders } from 'hyparquet/src/constants.js'\nimport { serializeTCompactProtocol } from './thrift.js'\n\n/**\n * @import {ColumnChunk, ColumnIndex, OffsetIndex} from 'hyparquet'\n * @import {PageIndexes, Writer} from '../src/types.js'\n */\n\n/**\n * Write ColumnIndex and OffsetIndex for the given columns.\n *\n * @param {Writer} writer\n * @param {PageIndexes[]} pageIndexes\n */\nexport function writeIndexes(writer, pageIndexes) {\n for (const { chunk, columnIndex } of pageIndexes) {\n writeColumnIndex(writer, chunk, columnIndex)\n }\n for (const { chunk, offsetIndex } of pageIndexes) {\n writeOffsetIndex(writer, chunk, offsetIndex)\n }\n}\n\n/**\n * @param {Writer} writer\n * @param {ColumnChunk} columnChunk\n * @param {ColumnIndex} [columnIndex]\n */\nfunction writeColumnIndex(writer, columnChunk, columnIndex) {\n // Page indexes only help when multiple pages\n if (!columnIndex || columnIndex.min_values.length <= 1) return\n const columnIndexOffset = writer.offset\n serializeTCompactProtocol(writer, {\n field_1: columnIndex.null_pages,\n field_2: columnIndex.min_values,\n field_3: columnIndex.max_values,\n field_4: BoundaryOrders.indexOf(columnIndex.boundary_order),\n field_5: columnIndex.null_counts,\n })\n columnChunk.column_index_offset = BigInt(columnIndexOffset)\n columnChunk.column_index_length = writer.offset - columnIndexOffset\n}\n\n/**\n * @param {Writer} writer\n * @param {ColumnChunk} columnChunk\n * @param {OffsetIndex} [offsetIndex]\n */\nfunction writeOffsetIndex(writer, columnChunk, offsetIndex) {\n // Page indexes only help when multiple pages\n if (!offsetIndex || offsetIndex.page_locations.length <= 1) return\n const offsetIndexOffset = writer.offset\n serializeTCompactProtocol(writer, {\n field_1: offsetIndex.page_locations.map(p => ({\n field_1: p.offset,\n field_2: p.compressed_page_size,\n field_3: p.first_row_index,\n })),\n })\n columnChunk.offset_index_offset = BigInt(offsetIndexOffset)\n columnChunk.offset_index_length = writer.offset - offsetIndexOffset\n}\n", "import { getSchemaPath } from 'hyparquet/src/schema.js'\nimport { CompressionCodecs, ConvertedTypes, EdgeInterpolationAlgorithms, Encodings, FieldRepetitionTypes, PageTypes, ParquetTypes } from 'hyparquet/src/constants.js'\nimport { serializeTCompactProtocol } from './thrift.js'\nimport { unconvertStatistics } from './unconvert.js'\n\n/**\n * @import {FileMetaData, LogicalType, SchemaElement, TimeUnit} from 'hyparquet'\n * @import {ThriftObject, Writer} from '../src/types.js'\n */\n\n/**\n * Write Parquet file metadata as thrift.\n *\n * @param {Writer} writer\n * @param {FileMetaData} metadata\n */\nexport function writeMetadata(writer, metadata) {\n /** @type {ThriftObject} */\n const compact = {\n field_1: metadata.version,\n field_2: metadata.schema.map(element => ({\n field_1: element.type && ParquetTypes.indexOf(element.type),\n field_2: element.type_length,\n field_3: element.repetition_type && FieldRepetitionTypes.indexOf(element.repetition_type),\n field_4: element.name,\n field_5: element.num_children,\n field_6: element.converted_type && ConvertedTypes.indexOf(element.converted_type),\n field_7: element.scale,\n field_8: element.precision,\n field_9: element.field_id,\n field_10: logicalType(element.logical_type),\n })),\n field_3: metadata.num_rows,\n field_4: metadata.row_groups.map(rg => ({\n field_1: rg.columns.map(c => ({\n field_1: c.file_path,\n field_2: c.file_offset,\n field_3: c.meta_data && {\n field_1: ParquetTypes.indexOf(c.meta_data.type),\n field_2: c.meta_data.encodings.map(e => Encodings.indexOf(e)),\n field_3: c.meta_data.path_in_schema,\n field_4: CompressionCodecs.indexOf(c.meta_data.codec),\n field_5: c.meta_data.num_values,\n field_6: c.meta_data.total_uncompressed_size,\n field_7: c.meta_data.total_compressed_size,\n field_8: c.meta_data.key_value_metadata && c.meta_data.key_value_metadata.map(kv => ({\n field_1: kv.key,\n field_2: kv.value,\n })),\n field_9: c.meta_data.data_page_offset,\n field_10: c.meta_data.index_page_offset,\n field_11: c.meta_data.dictionary_page_offset,\n field_12: c.meta_data.statistics && unconvertStatistics(\n c.meta_data.statistics,\n schemaElement(metadata.schema, c.meta_data.path_in_schema)\n ),\n field_13: c.meta_data.encoding_stats && c.meta_data.encoding_stats.map(es => ({\n field_1: PageTypes.indexOf(es.page_type),\n field_2: Encodings.indexOf(es.encoding),\n field_3: es.count,\n })),\n field_14: c.meta_data.bloom_filter_offset,\n field_15: c.meta_data.bloom_filter_length,\n field_16: c.meta_data.size_statistics && {\n field_1: c.meta_data.size_statistics.unencoded_byte_array_data_bytes,\n field_2: c.meta_data.size_statistics.repetition_level_histogram,\n field_3: c.meta_data.size_statistics.definition_level_histogram,\n },\n field_17: c.meta_data.geospatial_statistics && {\n field_1: c.meta_data.geospatial_statistics.bbox && {\n field_1: c.meta_data.geospatial_statistics.bbox.xmin,\n field_2: c.meta_data.geospatial_statistics.bbox.xmax,\n field_3: c.meta_data.geospatial_statistics.bbox.ymin,\n field_4: c.meta_data.geospatial_statistics.bbox.ymax,\n field_5: c.meta_data.geospatial_statistics.bbox.zmin,\n field_6: c.meta_data.geospatial_statistics.bbox.zmax,\n field_7: c.meta_data.geospatial_statistics.bbox.mmin,\n field_8: c.meta_data.geospatial_statistics.bbox.mmax,\n },\n field_2: c.meta_data.geospatial_statistics.geospatial_types,\n },\n },\n field_4: c.offset_index_offset,\n field_5: c.offset_index_length,\n field_6: c.column_index_offset,\n field_7: c.column_index_length,\n // field_8: c.crypto_metadata,\n field_9: c.encrypted_column_metadata,\n })),\n field_2: rg.total_byte_size,\n field_3: rg.num_rows,\n field_4: rg.sorting_columns && rg.sorting_columns.map(sc => ({\n field_1: sc.column_idx,\n field_2: sc.descending,\n field_3: sc.nulls_first,\n })),\n field_5: rg.file_offset,\n field_6: rg.total_compressed_size,\n // field_7: rg.ordinal, // should be int16\n })),\n field_5: metadata.key_value_metadata && metadata.key_value_metadata.map(kv => ({\n field_1: kv.key,\n field_2: kv.value,\n })),\n field_6: metadata.created_by,\n }\n\n // write metadata as thrift\n const metadataStart = writer.offset\n serializeTCompactProtocol(writer, compact)\n // write metadata length\n const metadataLength = writer.offset - metadataStart\n writer.appendUint32(metadataLength)\n}\n\n/**\n * Resolve schema element for statistics using the stored path.\n *\n * @param {SchemaElement[]} schema\n * @param {string[]} path\n * @returns {SchemaElement}\n */\nfunction schemaElement(schema, path) {\n const tree = getSchemaPath(schema, path)\n return tree[tree.length - 1].element\n}\n\n/**\n * @param {LogicalType | undefined} type\n * @returns {ThriftObject | undefined}\n */\nexport function logicalType(type) {\n if (!type) return\n if (type.type === 'STRING') return { field_1: {} }\n if (type.type === 'MAP') return { field_2: {} }\n if (type.type === 'LIST') return { field_3: {} }\n if (type.type === 'ENUM') return { field_4: {} }\n if (type.type === 'DECIMAL') return { field_5: {\n field_1: type.scale,\n field_2: type.precision,\n } }\n if (type.type === 'DATE') return { field_6: {} }\n if (type.type === 'TIME') return { field_7: {\n field_1: type.isAdjustedToUTC,\n field_2: timeUnit(type.unit),\n } }\n if (type.type === 'TIMESTAMP') return { field_8: {\n field_1: type.isAdjustedToUTC,\n field_2: timeUnit(type.unit),\n } }\n if (type.type === 'INTEGER') return { field_10: {\n field_1: type.bitWidth,\n field_2: type.isSigned,\n } }\n if (type.type === 'NULL') return { field_11: {} }\n if (type.type === 'JSON') return { field_12: {} }\n if (type.type === 'BSON') return { field_13: {} }\n if (type.type === 'UUID') return { field_14: {} }\n if (type.type === 'FLOAT16') return { field_15: {} }\n if (type.type === 'VARIANT') return { field_16: {} }\n if (type.type === 'GEOMETRY') return { field_17: {\n field_1: type.crs,\n } }\n if (type.type === 'GEOGRAPHY') return { field_18: {\n field_1: type.crs,\n field_2: type.algorithm && EdgeInterpolationAlgorithms.indexOf(type.algorithm),\n } }\n}\n\n/**\n * @param {TimeUnit} unit\n * @returns {ThriftObject}\n */\nfunction timeUnit(unit) {\n if (unit === 'NANOS') return { field_3: {} }\n if (unit === 'MICROS') return { field_2: {} }\n return { field_1: {} }\n}\n", "/**\n * The MIT License (MIT)\n * Copyright (c) 2016 Zhipeng Jia\n * https://github.com/zhipeng-jia/snappyjs\n */\n\nimport { ByteWriter } from './bytewriter.js'\n\n/**\n * @import {Writer} from '../src/types.js'\n */\n\nconst BLOCK_LOG = 16\nconst BLOCK_SIZE = 1 << BLOCK_LOG\n\nconst MAX_HASH_TABLE_BITS = 14\nconst globalHashTables = new Array(MAX_HASH_TABLE_BITS + 1)\n\n/**\n * Compress snappy data.\n * Returns Snappy-compressed bytes as Uint8Array.\n *\n * @param {Uint8Array} input - uncompressed data\n * @returns {Uint8Array}\n */\nexport function snappyCompress(input) {\n const writer = new ByteWriter()\n writer.appendVarInt(input.length) // uncompressed length\n\n // Process input in 64K blocks\n let pos = 0\n while (pos < input.length) {\n const fragmentSize = Math.min(input.length - pos, BLOCK_SIZE)\n compressFragment(writer, input, pos, fragmentSize)\n pos += fragmentSize\n }\n\n return writer.getBytes()\n}\n\n/**\n * Hash function used in the reference implementation.\n *\n * @param {number} key\n * @param {number} hashFuncShift\n * @returns {number}\n */\nfunction hashFunc(key, hashFuncShift) {\n return key * 0x1e35a7bd >>> hashFuncShift\n}\n\n/**\n * Load a 32-bit little-endian integer from a byte array.\n *\n * @param {Uint8Array} array\n * @param {number} pos\n * @returns {number}\n */\nfunction load32(array, pos) {\n return (\n array[pos] +\n (array[pos + 1] << 8) +\n (array[pos + 2] << 16) +\n (array[pos + 3] << 24)\n )\n}\n\n/**\n * Compare two 32-bit sequences for equality.\n *\n * @param {Uint8Array} array\n * @param {number} pos1\n * @param {number} pos2\n * @returns {boolean}\n */\nfunction equals32(array, pos1, pos2) {\n return (\n array[pos1] === array[pos2] &&\n array[pos1 + 1] === array[pos2 + 1] &&\n array[pos1 + 2] === array[pos2 + 2] &&\n array[pos1 + 3] === array[pos2 + 3]\n )\n}\n\n/**\n * Emit a literal chunk of data.\n * @param {Writer} writer\n * @param {Uint8Array} input\n * @param {number} ip\n * @param {number} len\n */\nfunction emitLiteral(writer, input, ip, len) {\n // The first byte(s) encode the literal length\n if (len <= 60) {\n writer.appendUint8(len - 1 << 2)\n } else if (len < 256) {\n writer.appendUint8(60 << 2)\n writer.appendUint8(len - 1)\n } else {\n writer.appendUint8(61 << 2)\n writer.appendUint8(len - 1 & 0xff)\n writer.appendUint8(len - 1 >>> 8)\n }\n\n // Then copy the literal bytes\n writer.appendBytes(input.subarray(ip, ip + len))\n}\n\n/**\n * Emit a copy of previous data.\n * @param {Writer} writer\n * @param {number} offset\n * @param {number} len\n */\nfunction emitCopyLessThan64(writer, offset, len) {\n if (len < 12 && offset < 2048) {\n // Copy 4..11 bytes, offset < 2048\n // --> [ 1 | (len-4)<<2 | (offset>>8)<<5 ]\n writer.appendUint8(1 + (len - 4 << 2) + (offset >>> 8 << 5))\n writer.appendUint8(offset & 0xff)\n } else {\n // Copy len bytes, offset 1..65535\n // --> [ 2 | (len-1)<<2 ]\n writer.appendUint8(2 + (len - 1 << 2))\n writer.appendUint8(offset & 0xff)\n writer.appendUint8(offset >>> 8)\n }\n}\n\n/**\n * Emit a copy of previous data.\n * @param {Writer} writer\n * @param {number} offset\n * @param {number} len\n */\nfunction emitCopy(writer, offset, len) {\n // Emit 64-byte copies as long as we can\n while (len >= 68) {\n emitCopyLessThan64(writer, offset, 64)\n len -= 64\n }\n // Emit one 60-byte copy if needed\n if (len > 64) {\n emitCopyLessThan64(writer, offset, 60)\n len -= 60\n }\n // Final copy\n emitCopyLessThan64(writer, offset, len)\n}\n\n/**\n * Compress a fragment of data.\n * @param {Writer} writer\n * @param {Uint8Array} input\n * @param {number} ip\n * @param {number} inputSize\n */\nfunction compressFragment(writer, input, ip, inputSize) {\n let hashTableBits = 1\n while (1 << hashTableBits <= inputSize && hashTableBits <= MAX_HASH_TABLE_BITS) {\n hashTableBits++\n }\n hashTableBits--\n const hashFuncShift = 32 - hashTableBits\n\n // Initialize the hash table\n globalHashTables[hashTableBits] ??= new Uint16Array(1 << hashTableBits)\n const hashTable = globalHashTables[hashTableBits]\n hashTable.fill(0)\n\n const ipEnd = ip + inputSize\n let ipLimit\n const baseIp = ip\n let nextEmit = ip\n\n let hash, nextHash\n let nextIp, candidate, skip\n let bytesBetweenHashLookups\n let base, matched, offset\n let prevHash, curHash\n let flag = true\n\n const INPUT_MARGIN = 15\n if (inputSize >= INPUT_MARGIN) {\n ipLimit = ipEnd - INPUT_MARGIN\n ip++\n nextHash = hashFunc(load32(input, ip), hashFuncShift)\n\n while (flag) {\n skip = 32\n nextIp = ip\n do {\n ip = nextIp\n hash = nextHash\n bytesBetweenHashLookups = skip >>> 5\n skip++\n nextIp = ip + bytesBetweenHashLookups\n if (ip > ipLimit) {\n flag = false\n break\n }\n nextHash = hashFunc(load32(input, nextIp), hashFuncShift)\n candidate = baseIp + hashTable[hash]\n hashTable[hash] = ip - baseIp\n } while (!equals32(input, ip, candidate))\n\n if (!flag) {\n break\n }\n\n // Emit the literal from `nextEmit` to `ip`\n emitLiteral(writer, input, nextEmit, ip - nextEmit)\n\n // We found a match. Repeatedly match and emit copies\n do {\n base = ip\n matched = 4\n while (\n ip + matched < ipEnd &&\n input[ip + matched] === input[candidate + matched]\n ) {\n matched++\n }\n ip += matched\n offset = base - candidate\n emitCopy(writer, offset, matched)\n\n nextEmit = ip\n if (ip >= ipLimit) {\n flag = false\n break\n }\n prevHash = hashFunc(load32(input, ip - 1), hashFuncShift)\n hashTable[prevHash] = ip - 1 - baseIp\n curHash = hashFunc(load32(input, ip), hashFuncShift)\n candidate = baseIp + hashTable[curHash]\n hashTable[curHash] = ip - baseIp\n } while (equals32(input, ip, candidate))\n\n if (!flag) {\n break\n }\n\n ip++\n nextHash = hashFunc(load32(input, ip), hashFuncShift)\n }\n }\n\n // Emit the last literal (if any)\n if (nextEmit < ipEnd) {\n emitLiteral(writer, input, nextEmit, ipEnd - nextEmit)\n }\n}\n", "import { getSchemaPath } from 'hyparquet/src/schema.js'\nimport { writeBlooms } from './bloom.js'\nimport { writeColumn } from './column.js'\nimport { encodeNestedValues } from './dremel.js'\nimport { writeIndexes } from './indexes.js'\nimport { writeMetadata } from './metadata.js'\nimport { snappyCompress } from './snappy.js'\nimport { encodeVariantColumn } from './variant.js'\n\n/**\n * @import {ColumnChunk, CompressionCodec, FileMetaData, KeyValue, RowGroup, SchemaElement, SchemaTree} from 'hyparquet'\n * @import {ColumnEncoder, ColumnSource, Compressors, PageIndexes, Writer} from '../src/types.js'\n */\n\n/**\n * ParquetWriter class allows incremental writing of parquet files.\n *\n * @param {object} options\n * @param {Writer} options.writer\n * @param {SchemaElement[]} options.schema\n * @param {CompressionCodec} [options.codec]\n * @param {Compressors} [options.compressors]\n * @param {boolean} [options.statistics]\n * @param {KeyValue[]} [options.kvMetadata]\n */\nexport function ParquetWriter({ writer, schema, codec = 'SNAPPY', compressors, statistics = true, kvMetadata }) {\n this.writer = writer\n this.schema = schema\n this.codec = codec\n // Include built-in snappy as fallback\n this.compressors = { SNAPPY: snappyCompress, ...compressors }\n this.statistics = statistics\n this.kvMetadata = kvMetadata\n\n /** @type {RowGroup[]} */\n this.row_groups = []\n this.num_rows = 0n\n\n /** @type {PageIndexes[]} */\n this.pendingIndexes = []\n\n // write header PAR1\n this.writer.appendUint32(0x31524150)\n}\n\n/**\n * Write data to the file.\n * Will split data into row groups of the specified size.\n * Calls writer.flush() (if defined) after each row group; if it returns a\n * Promise, subsequent row groups await it before encoding more data.\n *\n * @param {object} options\n * @param {ColumnSource[]} options.columnData\n * @param {number | number[]} [options.rowGroupSize]\n * @param {number} [options.pageSize]\n * @returns {void | Promise<void>}\n */\nParquetWriter.prototype.write = function({ columnData, rowGroupSize = [1000, 100000], pageSize = 1048576 }) {\n const columnDataRows = columnData[0]?.data?.length || 0\n /** @type {Promise<void> | undefined} */\n let pending\n for (const { groupStartIndex, groupSize } of groupIterator({ columnDataRows, rowGroupSize })) {\n const writeGroup = () => {\n const groupStartOffset = this.writer.offset\n /** @type {ColumnChunk[]} */\n const columns = []\n\n // write columns\n for (let j = 0; j < columnData.length; j++) {\n const { name, data, encoding, codec = this.codec, columnIndex = false, offsetIndex = true, shredding, bloomFilter } = columnData[j]\n\n // Spec: if ColumnIndex is present, OffsetIndex must also be present\n if (columnIndex && !offsetIndex) {\n throw new Error('parquet ColumnIndex cannot be present without OffsetIndex')\n }\n if (data.length !== columnDataRows) {\n throw new Error('parquet columns must have the same length')\n }\n\n const groupData = data.slice(groupStartIndex, groupStartIndex + groupSize)\n const columnPath = getSchemaPath(this.schema, [name])\n const leafPaths = getLeafSchemaPaths(columnPath)\n\n // For VARIANT logical type, encode JS values into {metadata, value} structs\n const columnElement = columnPath.at(-1)?.element\n const shreddingConfig = shredding && shredding !== true ? shredding : undefined\n const isVariant = columnElement?.logical_type?.type === 'VARIANT'\n const isRequired = columnElement?.repetition_type === 'REQUIRED'\n const rows = isVariant\n ? encodeVariantColumn(Array.from(groupData), shreddingConfig, { name, required: isRequired })\n : groupData\n\n for (const leafPath of leafPaths) {\n const schemaPath = leafPath.map(node => node.element)\n\n /** @type {ColumnEncoder} */\n const column = {\n columnName: schemaPath.slice(1).map(s => s.name).join('.'),\n element: schemaPath[schemaPath.length - 1],\n schemaPath,\n codec,\n compressors: this.compressors,\n stats: this.statistics,\n pageSize,\n columnIndex,\n offsetIndex,\n encoding,\n bloomFilter,\n }\n\n const pageData = encodeNestedValues(leafPath, rows)\n const result = writeColumn({\n writer: this.writer,\n column,\n pageData,\n })\n\n columns.push(result.chunk)\n this.pendingIndexes.push(result)\n }\n }\n\n this.num_rows += BigInt(groupSize)\n this.row_groups.push({\n columns,\n total_byte_size: BigInt(this.writer.offset - groupStartOffset),\n num_rows: BigInt(groupSize),\n })\n return this.writer.flush?.()\n }\n if (pending) {\n pending = pending.then(writeGroup)\n } else {\n const r = writeGroup()\n if (r) pending = Promise.resolve(r)\n }\n }\n return pending\n}\n\n/**\n * Finish writing the file.\n *\n * @returns {void | Promise<void>}\n */\nParquetWriter.prototype.finish = function() {\n // Write all indexes at end of file\n writeIndexes(this.writer, this.pendingIndexes)\n // Bloom filters cluster after indexes so pushdown readers fetch them in one range\n writeBlooms(this.writer, this.pendingIndexes)\n\n // write metadata\n /** @type {FileMetaData} */\n const metadata = {\n version: 2,\n created_by: 'hyparquet',\n schema: this.schema,\n num_rows: this.num_rows,\n row_groups: this.row_groups,\n metadata_length: 0,\n key_value_metadata: this.kvMetadata,\n }\n // @ts-ignore don't want to actually serialize metadata_length\n delete metadata.metadata_length\n writeMetadata(this.writer, metadata)\n\n // write footer PAR1\n this.writer.appendUint32(0x31524150)\n return this.writer.finish()\n}\n\n/**\n * Target row count for the i-th row group. When rowGroupSize is an array, the\n * last entry repeats once the array is exhausted.\n *\n * @param {number | number[]} rowGroupSize - Size of each row group or an array of sizes\n * @param {number} i - zero-based group index\n * @returns {number}\n */\nexport function groupSize(rowGroupSize, i) {\n return Array.isArray(rowGroupSize)\n ? rowGroupSize[Math.min(i, rowGroupSize.length - 1)]\n : rowGroupSize\n}\n\n/**\n * Create an iterator for row groups based on the specified row group size.\n * If rowGroupSize is an array, it will return groups based on the sizes in the array.\n * When the array runs out, it will continue with the last size.\n *\n * @param {object} options\n * @param {number} options.columnDataRows - Total number of rows in the column data\n * @param {number | number[]} options.rowGroupSize - Size of each row group or an array of sizes\n * @returns {Array<{groupStartIndex: number, groupSize: number}>}\n */\nfunction groupIterator({ columnDataRows, rowGroupSize }) {\n if (Array.isArray(rowGroupSize) && !rowGroupSize.length) {\n throw new Error('rowGroupSize array cannot be empty')\n }\n const groups = []\n let groupIndex = 0\n let groupStartIndex = 0\n while (groupStartIndex < columnDataRows) {\n const size = groupSize(rowGroupSize, groupIndex)\n groups.push({ groupStartIndex, groupSize: Math.min(size, columnDataRows - groupStartIndex) })\n groupStartIndex += size\n groupIndex++\n }\n return groups\n}\n\n/**\n * Expand a schema path to all primitive leaf nodes under the column.\n *\n * @param {SchemaTree[]} schemaPath\n * @returns {SchemaTree[][]}\n */\nfunction getLeafSchemaPaths(schemaPath) {\n /** @type {SchemaTree[][]} */\n const leaves = []\n dfs(schemaPath)\n return leaves\n\n /**\n * @param {SchemaTree[]} path\n */\n function dfs(path) {\n const node = path[path.length - 1]\n if (!node.children.length) {\n leaves.push(path)\n return\n }\n for (const child of node.children) {\n dfs([...path, child])\n }\n }\n}\n", "import { ByteWriter } from './bytewriter.js'\nimport { ParquetWriter } from './parquet-writer.js'\nimport { schemaFromColumnData } from './schema.js'\nimport { autoDetectShredding, normalizeShreddingConfig } from './variant.js'\n\n/**\n * @import {ParquetWriteOptions} from '../src/types.js'\n */\n\n/**\n * Write data as parquet to a file or stream.\n *\n * @param {ParquetWriteOptions} options\n * @returns {void | Promise<void>}\n */\nexport function parquetWrite({\n writer,\n columnData,\n schema,\n codec = 'SNAPPY',\n compressors,\n statistics = true,\n rowGroupSize = [1000, 100000],\n kvMetadata,\n pageSize = 1048576,\n}) {\n // Resolve shredding: true -> auto-detected config\n columnData = columnData.map(col => {\n if (col.shredding === true && col.type === 'VARIANT') {\n const detected = autoDetectShredding(Array.from(col.data))\n return detected ? { ...col, shredding: detected } : { ...col, shredding: undefined }\n }\n if (col.shredding !== undefined && col.shredding !== true && col.type === 'VARIANT') {\n const shredding = normalizeShreddingConfig(col.shredding)\n return shredding ? { ...col, shredding } : { ...col, shredding: undefined }\n }\n return col\n })\n if (!schema) {\n schema = schemaFromColumnData({ columnData })\n } else if (columnData.some(({ type }) => type)) {\n throw new Error('cannot provide both schema and columnData type')\n } else {\n // TODO: validate schema\n }\n const pq = new ParquetWriter({\n writer,\n schema,\n codec,\n compressors,\n statistics,\n kvMetadata,\n })\n const w = pq.write({\n columnData,\n rowGroupSize,\n pageSize,\n })\n return w ? w.then(() => pq.finish()) : pq.finish()\n}\n\n/**\n * Write data as parquet to an ArrayBuffer.\n *\n * @param {Omit<ParquetWriteOptions, 'writer'>} options\n * @returns {ArrayBuffer}\n */\nexport function parquetWriteBuffer(options) {\n const writer = new ByteWriter()\n parquetWrite({ ...options, writer })\n return writer.getBuffer()\n}\n", "/**\n * Parquet encoding for SunGlasses event rows.\n *\n * Column schema matches the EventRow produced by `apps/ingest-server/src/schema.ts`\n * so DuckDB queries are identical regardless of which backend delivered the data.\n *\n * All columns are VARCHAR (STRING) \u2014 properties and context are opaque JSON strings.\n * UNCOMPRESSED codec avoids a native/WASM compressor dependency.\n */\nimport { parquetWriteBuffer } from \"hyparquet-writer\"\n\n/** Column names in fixed order \u2014 mirrors apps/ingest-server EventRow. */\nconst COLUMNS = [\n \"event_type\",\n \"event\",\n \"distinct_id\",\n \"anonymous_id\",\n \"ts\",\n \"message_id\",\n \"properties\",\n \"context\",\n \"dt\",\n \"received_at\",\n] as const\n\ntype ColumnName = (typeof COLUMNS)[number]\n\n/**\n * Encode an array of flat event row objects as a Parquet-format `Uint8Array`.\n *\n * Missing fields default to empty string. All values are stored as STRING\n * (VARCHAR-equivalent in Parquet). `received_at` should be an ISO-8601 UTC\n * timestamp stamped by the plugin at ingest time.\n *\n * Privacy: caller is responsible for never passing distinct_id/properties/\n * context to logs; this function stores whatever it receives opaquely.\n */\nexport function encodeParquet(rows: Record<string, unknown>[]): Uint8Array {\n const columnData = COLUMNS.map((name: ColumnName) => ({\n name,\n type: \"STRING\" as const,\n nullable: false,\n data: rows.map((r) => String(r[name] ?? \"\")),\n }))\n\n const buffer = parquetWriteBuffer({ columnData, codec: \"UNCOMPRESSED\" })\n return new Uint8Array(buffer)\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["child", "SALT", "bitWidth", "bitWidth", "metadata", "keyIndex", "bitWidth", "inferGeometryDimensions", "inferCoordinateDimensions", "encoder", "bits16", "definitionLevels", "BLOCK_SIZE", "groupSize"]
7
+ }