{"version":3,"file":"WireRowData.cjs","names":["createRequire","#rowCount","#payloadBytes","#rowSlices","#chunks","#columns","#rowBase","#readCell","#fields","#cellLength","getBinaryTypeParser","#retained","#compact","#scanOrdinal","#scanOffset","#wire"],"sources":["../../src/drivers/WireRowData.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nimport { type RowData } from \"joist-core\";\nimport pg from \"pg\";\n\nimport { getBinaryTypeParser } from \"./binaryParsers.ts\";\n\nconst runtimeRequire = createRequire(import.meta.url);\n\n// pg's internal-but-exported Query class; subclassing it reuses its extended-protocol\n// submit/bind logic while letting us intercept row handling (the same seam pg-cursor uses).\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst PgQuery: any = runtimeRequire(\"pg/lib/query\");\n\n/** One column's RowDescription-derived metadata, resolved once per query. */\ntype WireColumn = {\n  name: string;\n  ordinal: number;\n  /** Decodes this column's cell bytes to its value; see `setRowDescription`. */\n  decode: (chunk: Buffer, start: number, length: number) => any;\n};\n\n// Each row is three consecutive entries in the `#rowSlices` table: chunk index, start, length\nconst ROW_STRIDE = 3;\n\n/** The row-length sentinel for rows dropped by `finalize` compaction. */\nconst DROPPED = 0xffffffff;\n\n/** Only compact when dropped rows hold more than this fraction of the payload bytes. */\nconst COMPACT_THRESHOLD = 0.2;\n\n/**\n * Only allocate the adaptive scan cursor once a fault targets at least this ordinal: shallower\n * scans cost less than the cursor's bookkeeping, i.e. hydrate-only results (id is ordinal ~0)\n * and narrow reads never pay the 6 bytes/row.\n */\nconst SCAN_CURSOR_MIN_ORDINAL = 8;\n\n/**\n * A lazy wire-row {@link RowData} over raw Postgres `DataRow` payload bytes.\n *\n * Each query produces its own `WireRowData` — one query, one result; results are never combined\n * or appended across queries, and the payload is read-only after the query completes (entity\n * mutations go into `InstanceData.data`, never back into the row bytes).\n *\n * Rows are kept in their row-major wire format (`int16 fieldCount` + length-prefixed cells) as\n * zero-copy views over the parser's own immutable buffers: `addRow` records each DataRow's\n * `(bytes, offset, length)` by reference, deduping the socket chunk that consecutive rows\n * share. (Our pg-protocol patch guarantees message bytes are never rewritten — chunks parse in\n * place and straddling messages get a buffer of their own; see `patchPgProtocol.ts`.) A\n * `row × column` cell is decoded on first field access by scanning the row's length-prefixed\n * cells to the column's ordinal (\"row-lazy\" decode, see JS-ROW-STORE-DESIGN.md §3/C2). This is\n * deferred decoding of row-major data, not a columnar layout.\n *\n * Because chunks are whole socket reads, retaining any row pins its ~64KiB chunk (plus whatever\n * protocol frames share it); `finalize`'s compaction copies retained rows out into an\n * exact-size owned buffer when enough of the payload was dropped.\n *\n * Text-format cells go through the same active text parsers node-postgres would resolve for\n * the query (i.e. honoring pool/client `TypeOverrides`), so they parse identically to classic\n * rows. Binary-format cells decode via `wireBinaryParser`: wire bytes -> value directly for\n * default-parsed scalar types (no intermediate string), else rendered to pg's canonical text\n * and fed through the active text parser for parity. (Classic node-postgres cannot do binary\n * at all — it round-trips cells through a UTF-8 string, corrupting bytes >= 0x80.)\n *\n * Because decoding is deferred, a custom parser that throws will do so on first field access\n * (or `toRow`/`toRows`), not while awaiting the query; `id` and inheritance-discriminator cells\n * still decode during hydration.\n *\n * After hydration, `finalize` trims unused capacity and, when some rows were not retained (i.e.\n * their entities were already in the identity map), compacts the payload down to only the\n * retained rows, so retained memory tracks live entities rather than query history.\n *\n * Small results deliberately stay lazy — there is NO row-count threshold below which we\n * materialize to a `PojoRowData` instead. Measured (benchmark-rowdata-small.ts, 40-col rows):\n * for the typical sparse access pattern (~6 of 40 columns read), keeping the lazy result wins at\n * every size including a single row (n=1: 4.3µs vs 7.6µs; n=1000: 0.76ms vs 3.0ms), because\n * materialization eagerly decodes every column while lazy faults only what is read. Even full\n * column coverage no longer flips the winner: with binary decode and `#readCell`'s adaptive\n * scan cursor, reading all ~36 columns of every row measures ~parity with classic end-to-end\n * (benchmark-lazy-parsing.ts), and small finds (n <= 10) are statistically identical.\n */\nexport class WireRowData implements RowData {\n  #chunks: Buffer[] = [];\n  /** Where each row's bytes live: `(chunk index, start, length)` slices, `ROW_STRIDE` entries per row. */\n  #rowSlices: Uint32Array<ArrayBufferLike> = new Uint32Array(16 * ROW_STRIDE);\n  #rowCount = 0;\n  #payloadBytes = 0;\n  #retained: number[] | undefined = undefined;\n  #columns: Map<string, WireColumn> = new Map();\n  #fields: WireColumn[] = [];\n  /** The adaptive scan cursor: per row, the furthest scanned ordinal + its offset (see #readCell). */\n  #scanOrdinal: Uint16Array | undefined = undefined;\n  #scanOffset: Uint32Array | undefined = undefined;\n\n  get rowCount(): number {\n    return this.#rowCount;\n  }\n\n  /** The DataRow payload bytes currently indexed; drops when compaction discards rows. */\n  get payloadBytes(): number {\n    return this.#payloadBytes;\n  }\n\n  /** The bytes currently held by payload chunks + the row-slice table, i.e. for benchmarks. */\n  get memoryBytes(): number {\n    let bytes = this.#rowSlices.byteLength;\n    for (const chunk of this.#chunks) bytes += chunk.length;\n    return bytes;\n  }\n\n  get(rowIndex: number, columnName: string): any {\n    const column = this.#columns.get(columnName);\n    // Tolerate probes for columns the query didn't select, i.e. `__class` on non-CTI queries\n    if (column === undefined) return undefined;\n    const base = this.#rowBase(rowIndex);\n    const slices = this.#rowSlices;\n    const start = slices[base + 1];\n    return this.#readCell(this.#chunks[slices[base]], start, start + slices[base + 2], column, rowIndex);\n  }\n\n  /** Materializes one row as a POJO, i.e. for debugging and differential tests; values are not cached. */\n  toRow(rowIndex: number): any {\n    const base = this.#rowBase(rowIndex);\n    const slices = this.#rowSlices;\n    const chunk = this.#chunks[slices[base]];\n    const start = slices[base + 1];\n    const end = start + slices[base + 2];\n    const row: Record<string, any> = {};\n    let pos = start + 2;\n    for (const field of this.#fields) {\n      const len = this.#cellLength(chunk, pos, end, rowIndex);\n      pos += 4;\n      if (len === -1) {\n        row[field.name] = null;\n      } else {\n        row[field.name] = field.decode(chunk, pos, len);\n        pos += len;\n      }\n    }\n    return row;\n  }\n\n  /** Materializes classic POJO rows, i.e. for `afterFind` observation or debugging; not cached. */\n  toRows(): any[] {\n    const rows = new Array(this.#rowCount);\n    for (let i = 0; i < this.#rowCount; i++) rows[i] = this.toRow(i);\n    return rows;\n  }\n\n  /**\n   * Resolves each column's decoder from the query's RowDescription.\n   *\n   * Binary-format fields decode through Joist's own binary registry only (see\n   * `setBinaryTypeParser`) — `pg.types`/`TypeOverrides` are never consulted, and a column whose\n   * oid has no registered binary parser fails the query here, before any rows arrive, rather\n   * than guessing at a lossy decoding. Text-format fields (the `binary: false` escape hatch)\n   * decode by utf8-slicing the cell into the active text parser, resolved via `getTypeParser`\n   * (i.e. the pool/client `TypeOverrides` chain) or the global registry.\n   */\n  setRowDescription(\n    fields: Array<{ name: string; dataTypeID: number; format?: string }>,\n    getTypeParser?: (dataTypeID: number) => (value: any) => any,\n  ): void {\n    for (let i = 0; i < fields.length; i++) {\n      const { name, dataTypeID, format } = fields[i];\n      let decode;\n      if (format === \"binary\") {\n        decode = getBinaryTypeParser(dataTypeID);\n        if (decode === undefined) {\n          throw new Error(\n            `joist-orm: no binary type parser registered for oid ${dataTypeID} (column \"${name}\");` +\n              ` register one with setBinaryTypeParser (i.e. binaryTextParser for text-like types)`,\n          );\n        }\n      } else {\n        const parse = getTypeParser?.(dataTypeID) ?? pg.types.getTypeParser(dataTypeID, \"text\");\n        decode = textCellDecoder(parse);\n      }\n      const column = { name, ordinal: i, decode };\n      this.#columns.set(name, column);\n      this.#fields.push(column);\n    }\n  }\n\n  /**\n   * Records one DataRow payload *by reference* (zero-copy); called synchronously from the wire\n   * parser, whose patched buffer management guarantees the bytes are never rewritten.\n   *\n   * Consecutive rows usually share one socket chunk, so `bytes` is deduped against the last\n   * chunk ref; retaining any row of a chunk pins the whole chunk, which `finalize`'s compaction\n   * resolves by copying retained rows out when enough of the payload was dropped.\n   */\n  addRow(bytes: Buffer, offset: number, payloadLength: number): void {\n    if (payloadLength < 2 || offset + payloadLength > bytes.length) {\n      throw new Error(`Malformed DataRow payload (length ${payloadLength})`);\n    }\n    let chunkIndex = this.#chunks.length - 1;\n    if (chunkIndex === -1 || this.#chunks[chunkIndex] !== bytes) {\n      this.#chunks.push(bytes);\n      chunkIndex++;\n    }\n    let slices = this.#rowSlices;\n    const base = this.#rowCount * ROW_STRIDE;\n    if (base === slices.length) {\n      const grown = new Uint32Array(slices.length * 2);\n      grown.set(slices);\n      slices = this.#rowSlices = grown;\n    }\n    slices[base] = chunkIndex;\n    slices[base + 1] = offset;\n    slices[base + 2] = payloadLength;\n    this.#rowCount++;\n    this.#payloadBytes += payloadLength;\n  }\n\n  /** Marks `rowIndex` as retained by a hydrated entity; unmarked rows can be compacted away. */\n  retain(rowIndex: number): void {\n    (this.#retained ??= []).push(rowIndex);\n  }\n\n  /**\n   * Trims unused capacity, and compacts down to only `retain`-ed rows when enough rows were not\n   * retained to be worth the copy.\n   *\n   * Compaction exists to release pinned socket buffers to the GC: rows are zero-copy views into\n   * whole ~64KiB chunks, so keeping any row alive pins its entire chunk — and unretained rows\n   * are typically duplicates whose entities were *already in memory* (identity-map hits that\n   * keep their original `rowData`), making the newly-arrived bytes dead weight. Copying the\n   * retained rows into one exact-size owned buffer lets every chunk reference drop.\n   *\n   * The copy re-copies every retained byte, so it only pays off when it buys back a meaningful\n   * fraction of the payload: we compact when the dropped rows hold more than 20% of the payload\n   * bytes, and otherwise just trim, accepting the (bounded) leftover bytes. Called once after\n   * hydration + sidecar reads (`_tags`, preload aggregates) are complete; retained entities keep\n   * their original `rowIndex`, and un-compacted unretained rows simply remain readable-but-unused.\n   */\n  finalize(): void {\n    const retained = this.#retained ?? [];\n    this.#retained = undefined;\n    if (retained.length < this.#rowCount) {\n      let retainedBytes = 0;\n      for (const i of retained) retainedBytes += this.#rowSlices[i * ROW_STRIDE + 2];\n      const droppedBytes = this.#payloadBytes - retainedBytes;\n      if (droppedBytes > this.#payloadBytes * COMPACT_THRESHOLD) {\n        this.#compact(retained, retainedBytes);\n        return;\n      }\n    }\n    // Just shrink the row-slice table to its used size\n    if (this.#rowCount * ROW_STRIDE < this.#rowSlices.length) {\n      this.#rowSlices = this.#rowSlices.slice(0, this.#rowCount * ROW_STRIDE);\n    }\n  }\n\n  /** Copies retained rows into one owned buffer, releasing the pinned socket chunks to the GC. */\n  #compact(retained: readonly number[], bytes: number): void {\n    const chunks: Buffer[] = bytes > 0 ? [Buffer.allocUnsafe(bytes)] : [];\n    const slices = new Uint32Array(this.#rowCount * ROW_STRIDE);\n    for (let i = 0; i < this.#rowCount; i++) slices[i * ROW_STRIDE + 2] = DROPPED;\n    let used = 0;\n    for (const i of retained) {\n      const base = i * ROW_STRIDE;\n      const source = this.#chunks[this.#rowSlices[base]];\n      const start = this.#rowSlices[base + 1];\n      const len = this.#rowSlices[base + 2];\n      source.copy(chunks[0], used, start, start + len);\n      slices[base] = 0;\n      slices[base + 1] = used;\n      slices[base + 2] = len;\n      used += len;\n    }\n    this.#chunks = chunks;\n    this.#rowSlices = slices;\n    this.#payloadBytes = used;\n    // The scan cursor survives: its cached offsets are relative to each row's (copied) payload\n  }\n\n  /** Validates `rowIndex` and returns its base index into the `#rowSlices` table. */\n  #rowBase(rowIndex: number): number {\n    if (!(rowIndex >= 0 && rowIndex < this.#rowCount)) {\n      throw new Error(`Invalid rowIndex ${rowIndex} (rowCount ${this.#rowCount})`);\n    }\n    const base = rowIndex * ROW_STRIDE;\n    if (this.#rowSlices[base + 2] === DROPPED) {\n      throw new Error(`Row ${rowIndex} was compacted away (its entity was already loaded)`);\n    }\n    return base;\n  }\n\n  /**\n   * Scans a row's cells to `column`'s ordinal and decodes it.\n   *\n   * An adaptive per-row scan cursor caches the furthest cell boundary already scanned — the\n   * ordinal whose row-relative offset is known (`#scanOrdinal`/`#scanOffset`) — so ascending\n   * reads resume instead of re-scanning from the row start: a dense in-order read of all C\n   * columns costs one linear pass rather than O(C^2) length-prefix skips. Out-of-order\n   * (descending) faults simply scan from the start, i.e. never worse than without the cursor.\n   * The arrays are a fixed 6 bytes/row, allocated lazily on the first fault deep enough for\n   * resuming to matter, and — being row-relative — stay valid across compaction.\n   */\n  #readCell(chunk: Buffer, start: number, end: number, column: WireColumn, rowIndex: number): any {\n    const fieldCount = chunk.readInt16BE(start);\n    const { ordinal } = column;\n    if (ordinal >= fieldCount) {\n      throw new Error(`Row ${rowIndex} has ${fieldCount} cells but column ${column.name} is #${column.ordinal}`);\n    }\n    let pos = start + 2;\n    let c = 0;\n    let scanOrdinal = this.#scanOrdinal;\n    if (scanOrdinal === undefined && ordinal >= SCAN_CURSOR_MIN_ORDINAL) {\n      scanOrdinal = this.#scanOrdinal = new Uint16Array(this.#rowCount);\n      this.#scanOffset = new Uint32Array(this.#rowCount);\n    }\n    if (scanOrdinal !== undefined && rowIndex < scanOrdinal.length) {\n      // 0 = unset: caching cell #0 would be pointless (it is always at offset 2), so any real\n      // entry is the ordinal, >= 1, whose row-relative offset is in #scanOffset\n      const known = scanOrdinal[rowIndex];\n      if (known !== 0 && known <= ordinal) {\n        c = known;\n        pos = start + this.#scanOffset![rowIndex];\n      }\n    }\n    for (; c < ordinal; c++) {\n      const len = this.#cellLength(chunk, pos, end, rowIndex);\n      pos += len > 0 ? len + 4 : 4;\n    }\n    const len = this.#cellLength(chunk, pos, end, rowIndex);\n    if (scanOrdinal !== undefined && rowIndex < scanOrdinal.length && ordinal + 1 > scanOrdinal[rowIndex]) {\n      // advance-only: after reading cell #ordinal we know where cell #ordinal+1 starts\n      scanOrdinal[rowIndex] = ordinal + 1;\n      this.#scanOffset![rowIndex] = pos + 4 + (len > 0 ? len : 0) - start;\n    }\n    if (len === -1) return null;\n    return column.decode(chunk, pos + 4, len);\n  }\n\n  /** Reads + validates one cell's length prefix. */\n  #cellLength(chunk: Buffer, pos: number, end: number, rowIndex: number): number {\n    if (pos + 4 > end) throw new Error(`Truncated DataRow payload in row ${rowIndex}`);\n    const len = chunk.readInt32BE(pos);\n    if (len < -1 || (len > 0 && pos + 4 + len > end)) {\n      throw new Error(`Malformed cell length ${len} in row ${rowIndex}`);\n    }\n    return len;\n  }\n}\n\n/**\n * Executes `sql` on an already-checked-out client, returning a {@link RowData} instead of\n * materialized POJO rows.\n *\n * Uses a `pg` Query subclass that records each DataRow's raw payload bytes into the result\n * (via the lazy DataRow message from `patchPgProtocol`) and never materializes per-cell\n * strings or per-row objects. If the client's connection turns out to use an unpatched\n * pg-protocol copy (i.e. the app's pool was built from a different `pg` install than the one\n * joist-orm patched), the query fails with a descriptive error — a misconfiguration any CI\n * build/smoketest will surface immediately, so we fail loudly rather than silently degrade.\n * The rows already streamed are discarded; the connection itself stays usable.\n *\n * By default the query requests *binary* result format (via the extended protocol), so scalar\n * cells decode wire-bytes -> value with no intermediate strings; see `wireBinaryParser` for the\n * parity strategy. Pass `binary: false` for classic text-format results, or set\n * `JOIST_LAZY_BINARY=0` to flip the default while the binary path is a prototype (i.e. for\n * A/B benchmarking or as an escape hatch).\n */\n// The prototype escape hatch for binary results, i.e. for A/B benchmarking; read once at load\nconst BINARY_BY_DEFAULT = process.env.JOIST_LAZY_BINARY !== \"0\";\n\nexport function executeRowDataQuery(\n  client: pg.PoolClient,\n  sql: string,\n  bindings: readonly any[],\n  opts?: { binary?: boolean },\n): Promise<RowData> {\n  const binary = opts?.binary ?? BINARY_BY_DEFAULT;\n  return new Promise((resolve, reject) => {\n    const query = new RowDataQuery(\n      // Binary results require the extended protocol; `queryMode` forces it for bindings-less queries\n      binary\n        ? { text: sql, values: bindings as any[], binary: true, queryMode: \"extended\" }\n        : { text: sql, values: bindings as any[] },\n      (err: unknown) => {\n        if (err) reject(err);\n        else resolve(query.rowData);\n      },\n    );\n    client.query(query as any);\n  });\n}\n\n/** Returns whether `client` supports the lazy row-data query path, before submitting anything. */\nexport function isRowDataCapableClient(client: unknown): client is pg.PoolClient {\n  // Require the pure-JS pg client (pg-native has no `connection` and different query internals)\n  return (\n    typeof client === \"object\" &&\n    client !== null &&\n    typeof (client as any).query === \"function\" &&\n    (client as any).connection !== undefined &&\n    (client as any).native === undefined\n  );\n}\n\n/** A pg Query that diverts DataRows into a {@link WireRowData} instead of a `Result`. */\nclass RowDataQuery extends PgQuery {\n  #wire = new WireRowData();\n\n  constructor(\n    config: { text: string; values: any[]; binary?: boolean; queryMode?: string },\n    callback: (err: unknown) => void,\n  ) {\n    super(config, undefined, callback);\n  }\n\n  /**\n   * The query's result rows, i.e. once our callback has fired.\n   *\n   * If a small-result materialization threshold ever seems attractive, this is where it would\n   * go — but see the \"Small results deliberately stay lazy\" note on {@link WireRowData}: lazy\n   * won the measured comparison at every row count for sparse access, so no threshold exists.\n   */\n  get rowData(): RowData {\n    return this.#wire;\n  }\n\n  handleRowDescription(msg: any): void {\n    if (this._canceledDueToError) return;\n    try {\n      super.handleRowDescription(msg);\n      // Resolve active *text* parsers through the client's TypeOverrides chain (client.js\n      // injects `_types` at submit time); we can't reuse `Result._parsers` because in binary\n      // mode those resolve to pg's (broken) binary registry, while our binary decode path is\n      // built on text-parser parity — see `wireBinaryParser`\n      const types = this._result?._types;\n      this.#wire.setRowDescription(msg.fields, types && ((oid: number) => types.getTypeParser(oid, \"text\")));\n    } catch (err) {\n      // Mirror pg's Query error containment: record + reject at ReadyForQuery, keeping the\n      // connection's protocol state intact\n      this._canceledDueToError = err;\n    }\n  }\n\n  handleDataRow(msg: any): void {\n    if (this._canceledDueToError) return;\n    try {\n      if (msg.bytes === undefined) {\n        // This connection's pg-protocol copy is unpatched (i.e. the pool came from a different\n        // `pg` install than the one joist-orm patched), so lazyRows cannot work — fail loudly\n        // rather than silently degrade; any CI build/smoketest will surface this immediately\n        throw new Error(\n          \"joist-orm: lazyRows is enabled, but this connection's pg-protocol emits classic\" +\n            \" DataRows (likely a duplicate pg install); fix the install or disable lazyRows.\",\n        );\n      }\n      // `msg.length` includes the int32 length field itself, so the payload is `length - 4`;\n      // our patched message carries the real length from `handlePacket`'s argument\n      this.#wire.addRow(msg.bytes, msg.offset, msg.length - 4);\n    } catch (err) {\n      this._canceledDueToError = err;\n    }\n  }\n}\n\n/** Builds a text-format cell decoder: utf8-slice the cell bytes into the active text parser. */\nfunction textCellDecoder(parse: (value: any) => any): (chunk: Buffer, start: number, length: number) => any {\n  return (chunk, start, length) => parse(chunk.toString(\"utf8\", start, start + length));\n}\n"],"mappings":"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"}