@clickhouse/client 1.23.0-head.dbc2960.1 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +1342 -0
  2. package/README.md +18 -6
  3. package/dist/version.d.ts +1 -1
  4. package/dist/version.js +1 -1
  5. package/dist/version.js.map +1 -1
  6. package/package.json +7 -6
  7. package/skills/AGENTS.md +8 -0
  8. package/skills/clickhouse-js-node-rowbinary/AGENTS.md +44 -0
  9. package/skills/clickhouse-js-node-rowbinary/CHANGELOG.md +49 -0
  10. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/README.md +78 -14
  11. package/skills/clickhouse-js-node-rowbinary/SKILL.md +111 -0
  12. package/skills/{clickhouse-js-node-rowbinary-parser/SKILL.md → clickhouse-js-node-rowbinary/reader.md} +51 -131
  13. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/src/examples/carts.ts +9 -5
  14. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/src/examples/events.ts +5 -5
  15. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/src/examples/iot.ts +4 -4
  16. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/src/examples/ledger.ts +3 -3
  17. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/src/examples/logs.ts +4 -4
  18. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/src/examples/observability.ts +9 -10
  19. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/src/examples/orders.ts +10 -9
  20. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/src/examples/profiles.ts +5 -5
  21. package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/src/examples/telemetry.ts +6 -6
  22. package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/compile.ts +18 -8
  23. package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/dynamic.ts +12 -8
  24. package/skills/clickhouse-js-node-rowbinary/src/readers/enums.ts +40 -0
  25. package/skills/clickhouse-js-node-rowbinary/src/writers/aggregateFunction.ts +18 -0
  26. package/skills/clickhouse-js-node-rowbinary/src/writers/bool.ts +10 -0
  27. package/skills/clickhouse-js-node-rowbinary/src/writers/composite.ts +140 -0
  28. package/skills/clickhouse-js-node-rowbinary/src/writers/core.ts +92 -0
  29. package/skills/clickhouse-js-node-rowbinary/src/writers/datetime.ts +123 -0
  30. package/skills/clickhouse-js-node-rowbinary/src/writers/decimals.ts +51 -0
  31. package/skills/clickhouse-js-node-rowbinary/src/writers/enums.ts +18 -0
  32. package/skills/clickhouse-js-node-rowbinary/src/writers/floats.ts +40 -0
  33. package/skills/clickhouse-js-node-rowbinary/src/writers/geo.ts +125 -0
  34. package/skills/clickhouse-js-node-rowbinary/src/writers/integers.ts +90 -0
  35. package/skills/clickhouse-js-node-rowbinary/src/writers/interval.ts +11 -0
  36. package/skills/clickhouse-js-node-rowbinary/src/writers/ip.ts +121 -0
  37. package/skills/clickhouse-js-node-rowbinary/src/writers/lowCardinality.ts +12 -0
  38. package/skills/clickhouse-js-node-rowbinary/src/writers/nested.ts +17 -0
  39. package/skills/clickhouse-js-node-rowbinary/src/writers/nothing.ts +21 -0
  40. package/skills/clickhouse-js-node-rowbinary/src/writers/rows.ts +144 -0
  41. package/skills/clickhouse-js-node-rowbinary/src/writers/simpleAggregateFunction.ts +12 -0
  42. package/skills/clickhouse-js-node-rowbinary/src/writers/strings.ts +77 -0
  43. package/skills/clickhouse-js-node-rowbinary/src/writers/time.ts +54 -0
  44. package/skills/clickhouse-js-node-rowbinary/src/writers/uuid.ts +60 -0
  45. package/skills/clickhouse-js-node-rowbinary/src/writers/varint.ts +64 -0
  46. package/skills/clickhouse-js-node-rowbinary/src/writers/writer.ts +101 -0
  47. package/skills/clickhouse-js-node-rowbinary/writer.md +96 -0
  48. package/skills/clickhouse-js-node-rowbinary-parser/src/enums.ts +0 -28
  49. /package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/EXAMPLES.md +0 -0
  50. /package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/case-studies/iot-rowbinary-vs-json.md +0 -0
  51. /package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/case-studies/ledger-rowbinary-vs-json.md +0 -0
  52. /package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/case-studies/logs-json-wins.md +0 -0
  53. /package/skills/{clickhouse-js-node-rowbinary-parser → clickhouse-js-node-rowbinary}/case-studies/wasm-vs-js.md +0 -0
  54. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/aggregateFunction.ts +0 -0
  55. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/bool.ts +0 -0
  56. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/columnar.ts +0 -0
  57. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/composite.ts +0 -0
  58. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/core.ts +0 -0
  59. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/datetime.ts +0 -0
  60. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/decimals.ts +0 -0
  61. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/floats.ts +0 -0
  62. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/geo.ts +0 -0
  63. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/header.ts +0 -0
  64. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/integers.ts +0 -0
  65. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/interval.ts +0 -0
  66. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/ip.ts +0 -0
  67. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/json.ts +0 -0
  68. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/lowCardinality.ts +0 -0
  69. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/nested.ts +0 -0
  70. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/nothing.ts +0 -0
  71. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/reader.ts +0 -0
  72. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/rowBinaryWithNamesAndTypes.ts +0 -0
  73. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/rows.ts +0 -0
  74. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/simpleAggregateFunction.ts +0 -0
  75. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/stream.ts +0 -0
  76. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/strings.ts +0 -0
  77. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/time.ts +0 -0
  78. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/uuid.ts +0 -0
  79. /package/skills/{clickhouse-js-node-rowbinary-parser/src → clickhouse-js-node-rowbinary/src/readers}/varint.ts +0 -0
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Barrel re-export of the RowBinary WRITER — the encode mirror of `reader.ts`,
3
+ * split by type family across parallel `*.ts` modules (the readers stay in
4
+ * their own files untouched). Import from here for everything in one place, or
5
+ * from a specific module (e.g. `./integers.js`, `./strings.js`) to
6
+ * pull in only the sub-writers a given result needs — the latter is what a
7
+ * generated encoder should do, copying just the modules its column types require.
8
+ *
9
+ * Each `writeX` is the inverse of the matching `readX`: it appends the value's
10
+ * RowBinary bytes to a {@link Sink} (the write-side mirror of the reader's
11
+ * `Cursor`). Leaf writers are `Writer<T>`s directly; combinators (e.g.
12
+ * `writeArray`) take sub-writers and return a `Writer`, so types compose with no
13
+ * per-element closures — exactly like the reader combinators.
14
+ *
15
+ * const sink = new Sink(Buffer.allocUnsafe(64));
16
+ * writeUInt8(sink, 255);
17
+ * sink.bytes(); // the encoded RowBinary
18
+ *
19
+ * - core — Sink, Writer<T>, reserve (mirror of Cursor, Reader<T>, advance)
20
+ * - varint — writeUVarint
21
+ *
22
+ * The dynamic AST-based encode path (the inverse of `compile.ts` /
23
+ * `rowBinaryWithNamesAndTypes.ts` / `dynamic.ts`) is intentionally NOT part of
24
+ * this barrel yet.
25
+ */
26
+ export { Sink, reserve, BufferFull, type Writer } from "./core.js";
27
+ export { writeUVarint } from "./varint.js";
28
+ export {
29
+ writeUInt8,
30
+ writeInt8,
31
+ writeUInt16,
32
+ writeInt16,
33
+ writeUInt32,
34
+ writeInt32,
35
+ writeUInt64,
36
+ writeInt64,
37
+ writeUInt128,
38
+ writeInt128,
39
+ writeUInt256,
40
+ writeInt256,
41
+ } from "./integers.js";
42
+ export { writeBool } from "./bool.js";
43
+ export { writeEnum8, writeEnum16 } from "./enums.js";
44
+ export { writeFloat32, writeFloat64, writeBFloat16 } from "./floats.js";
45
+ export {
46
+ writeDecimal32,
47
+ writeDecimal64,
48
+ writeDecimal128,
49
+ writeDecimal256,
50
+ parseDecimal,
51
+ } from "./decimals.js";
52
+ export {
53
+ writeString,
54
+ writeStringBytes,
55
+ writeFixedString,
56
+ writeFixedStringBytes,
57
+ } from "./strings.js";
58
+ export {
59
+ writeUUID,
60
+ writeUUIDBigInt,
61
+ writeUUIDHiLo,
62
+ parseUUID,
63
+ } from "./uuid.js";
64
+ export { writeIPv4, writeIPv6, parseIPv4, parseIPv6 } from "./ip.js";
65
+ export {
66
+ writeDate,
67
+ writeDate32,
68
+ writeDateTime,
69
+ writeDateTime64,
70
+ writeDateTime64P3,
71
+ writeDateTime64P6,
72
+ writeDateTime64P9,
73
+ } from "./datetime.js";
74
+ export { writeTime, writeTime64, parseTime, parseTime64 } from "./time.js";
75
+ export { writeInterval } from "./interval.js";
76
+ export {
77
+ writeNullable,
78
+ writeArray,
79
+ writeQBit,
80
+ writeTuple,
81
+ writeTupleNamed,
82
+ writeMap,
83
+ writeVariant,
84
+ type VariantValue,
85
+ } from "./composite.js";
86
+ export { writeRows, FLUSH_CHANNEL_NAME, type WriteRowsFlush } from "./rows.js";
87
+ export {
88
+ writePoint,
89
+ writeRing,
90
+ writeLineString,
91
+ writePolygon,
92
+ writeMultiLineString,
93
+ writeMultiPolygon,
94
+ writeGeometry,
95
+ type GeometryValue,
96
+ } from "./geo.js";
97
+ export { writeLowCardinality } from "./lowCardinality.js";
98
+ export { writeSimpleAggregateFunction } from "./simpleAggregateFunction.js";
99
+ export { writeNested } from "./nested.js";
100
+ export { writeNothing } from "./nothing.js";
101
+ export { writeAggregateFunction } from "./aggregateFunction.js";
@@ -0,0 +1,96 @@
1
+ # RowBinary writer (encode) for Node.js
2
+
3
+ Encoding JS values into a `RowBinary` payload to send to ClickHouse. Read
4
+ [SKILL.md](SKILL.md) first for the format gate ("is RowBinary even the right
5
+ format?") and the principles that apply to **both** directions; this file covers
6
+ what's specific to **writing**. Reading? See [reader.md](reader.md).
7
+
8
+ Each `writeX` encodes one value, appending its RowBinary bytes to a `Sink` (a
9
+ caller-supplied byte buffer plus the current write offset — state only, no write
10
+ methods). Leaf writers (`writeUInt8`, `writeString`, …) encode directly;
11
+ combinators (`writeArray`, `writeTuple`, …) take sub-writers and return a writer,
12
+ so composite types compose with no per-element closures. For the `Sink`/`Writer<T>`
13
+ types and how to drain the encoded bytes, see `src/writers/core.ts`. Import the
14
+ barrel as `@clickhouse/rowbinary/writer`, or a per-type module for just what you
15
+ need. (Structurally this is the mirror of the decode side in
16
+ [reader.md](reader.md), but you don't need the read side to write.)
17
+
18
+ ## Writer guidance
19
+
20
+ On top of the shared principles in [SKILL.md](SKILL.md), the write path has its own:
21
+
22
+ - **Reserve before you write.** Every fixed-width write goes through `reserve()`,
23
+ which bounds-checks against the fixed-length buffer and throws the `BufferFull`
24
+ sentinel when the chunk is full — your cue to flush what's written and continue
25
+ into a fresh buffer. Exact signature, return value, and throw contract are in
26
+ `src/writers/core.ts`.
27
+
28
+ - **Coalesce `reserve()` across a run of adjacent fixed-width columns.** Their
29
+ combined size is statically known, so reserve ONCE for the whole run and write
30
+ each value at a constant offset off the returned base — one bounds-check instead
31
+ of one per column. Only applies where every column in the run is fixed-width (a
32
+ variable-width writer like `writeString` reserves on its own).
33
+
34
+ - **Hoist sink state into locals in the generated writer.** `Sink.buf`/`Sink.view`
35
+ are `readonly`, so bind them to locals once at the top and address them directly
36
+ instead of through `sink.` on every write. Keep the write position (`sink.pos`)
37
+ in a local too — but sync it back to `sink.pos` before any `reserve()` or
38
+ `BufferFull` throw, since those read and mutate it to decide capacity and where a
39
+ flushed buffer resumes.
40
+
41
+ - **Stream the whole result with `writeRows`, not a one-shot writer.** When you
42
+ need to encode a large or unbounded row source, reach for `writeRows` rather than
43
+ a `Writer<readonly T[]>`: it owns a fixed buffer and yields it as a generator,
44
+ streaming the result out chunk by chunk instead of demanding it all fit at once.
45
+ It never leaks a half-written row (it rewinds to the last whole-row boundary
46
+ before flushing) and never fails on a single big row (it grows the buffer to fit).
47
+ It also publishes a per-flush diagnostics-channel event for buffer-utilization
48
+ metrics. Signature, default buffer size, channel name and payload type, the
49
+ growth/rewind details, and a usage example are all in `src/writers/rows.ts`.
50
+
51
+ - **No defensive validation on the hot path.** Don't add `isFinite`/`NaN`/range
52
+ checks to `writeX`; document the precondition in JSDoc instead. Two narrow
53
+ exceptions — framing-keeping checks and zero-cost parse-time helpers — are
54
+ spelled out in [AGENTS.md](AGENTS.md); `src/writers/ip.ts` is the worked
55
+ example (`writeIPv6`, `parseIPv6`).
56
+
57
+ - **Lossy time conversions floor, never round.** Every date/time writer in
58
+ `src/writers/datetime.ts` drops the sub-unit it can't encode by flooring toward
59
+ −∞, so a caller's value is never silently shifted _up_ to the wrong
60
+ day/second/tick and pre-1970 instants stay correct (not rounded toward the
61
+ epoch). See its JSDoc for the per-function specifics.
62
+
63
+ ## Writer type family references
64
+
65
+ The writers live as real code under `src/writers/`, one file per type family
66
+ (same basenames as the readers, under the `writers/` directory).
67
+
68
+ | Value to encode (trigger) | Open |
69
+ | --------------------------------------------------------------------------------------- | ---------------------------------------- |
70
+ | **Always** — sink state, `reserve()`, `BufferFull`, `Writer<T>` | `src/writers/core.ts` |
71
+ | LEB128 length/count prefixes for `String`/`Array`/`Map` (`writeUVarint`) | `src/writers/varint.ts` |
72
+ | `Int8`–`Int256`, `UInt8`–`UInt256` | `src/writers/integers.ts` |
73
+ | `Bool` (`writeBool`) | `src/writers/bool.ts` |
74
+ | `Enum8`, `Enum16` (`writeEnum8`/`writeEnum16`; pass the raw int) | `src/writers/enums.ts` |
75
+ | `Float32`, `Float64`, `BFloat16` | `src/writers/floats.ts` |
76
+ | `Decimal32/64/128/256`, `Decimal(P, S)` (`parseDecimal`) | `src/writers/decimals.ts` |
77
+ | `String`, `FixedString(N)` (`writeString`/`writeStringBytes`/`writeFixedString`) | `src/writers/strings.ts` |
78
+ | `UUID` (`writeUUID`, `parseUUID`) | `src/writers/uuid.ts` |
79
+ | `IPv4`, `IPv6` (`writeIPv4`/`writeIPv6`, `parseIPv4`/`parseIPv6`) | `src/writers/ip.ts` |
80
+ | `Date`, `Date32`, `DateTime`, `DateTime(tz)`, `DateTime64(P[, tz])` | `src/writers/datetime.ts` |
81
+ | `Time`, `Time64(P)` (`parseTime`/`parseTime64`) | `src/writers/time.ts` |
82
+ | `IntervalNanosecond` … `IntervalYear` | `src/writers/interval.ts` |
83
+ | `Array(T)`, `Map(K, V)`, `Tuple(...)`, `Nullable(T)`, `Variant(...)`, `QBit(...)` | `src/writers/composite.ts` |
84
+ | `Point`, `Ring`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`, `Geometry` | `src/writers/geo.ts` |
85
+ | The whole result — write rows from a value source (`writeRows`) | `src/writers/rows.ts` |
86
+ | `LowCardinality(T)` — transparent, encode as `T` | `src/writers/lowCardinality.ts` |
87
+ | `SimpleAggregateFunction(f, T)` — transparent, encode as `T` | `src/writers/simpleAggregateFunction.ts` |
88
+ | `Nested(...)` — no wire of its own; `Array(Tuple(...))` | `src/writers/nested.ts` |
89
+ | `Nothing` — zero-width, never encoded (only wrapped) | `src/writers/nothing.ts` |
90
+ | `AggregateFunction(...)` — opaque state; produce server-side | `src/writers/aggregateFunction.ts` |
91
+
92
+ **No writer counterpart yet** — these reader paths are decode-only for now:
93
+ `dynamic.ts`, `json.ts`, `stream.ts`, the `RowBinaryWithNamesAndTypes`
94
+ header/compile/runtime path (`header.ts`, `compile.ts`,
95
+ `rowBinaryWithNamesAndTypes.ts`), and the columnar typed-array path
96
+ (`columnar.ts`). The AST-based dynamic encode path is intentionally not built.
@@ -1,28 +0,0 @@
1
- import { Cursor, advance } from "./core.js";
2
-
3
- /**
4
- * Read an `Enum8`: the value's underlying signed `Int8`. The name<->value map
5
- * lives in the column's type, not the bytes. Two strategies, both better than one
6
- * shared name-resolving reader:
7
- *
8
- * - Keep the number: carry the raw Int8 and map to a name only where needed —
9
- * most hot loops never need it.
10
- * - Or generate a per-enum reader with a baked-in constant map, so the JIT can
11
- * monomorphize each enum's decode:
12
- *
13
- * const STATUS = { 1: "active", 2: "closed" } as const;
14
- * const readStatusEnum = (s) => STATUS[readInt8(s) as keyof typeof STATUS];
15
- */
16
- export function readEnum8(state: Cursor): number {
17
- return state.view.getInt8(advance(state, 1));
18
- }
19
-
20
- /**
21
- * Read an `Enum16`: the value's underlying signed `Int16` (2 bytes). The
22
- * name<->value map lives in the column's type definition, not the bytes. Prefer
23
- * keeping the number, or a generated per-enum reader with a baked-in constant
24
- * map so the JIT can optimize each enum's decode independently.
25
- */
26
- export function readEnum16(state: Cursor): number {
27
- return state.view.getInt16(advance(state, 2), true);
28
- }