Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
368 commits
Select commit Hold shift + click to select a range
bd4a224
fix(qwp): cancel a connect still negotiating when close() is called
glasstiger Aug 21, 2026
df1d952
fix(qwp): close the UDP socket when bind fails
glasstiger Aug 21, 2026
0092879
docs(qwp): state the auto-flush defaults and correct auto_flush_bytes
glasstiger Aug 21, 2026
da1132b
refactor(qwp): drop the unreachable resolved-sender constructor branch
glasstiger Aug 21, 2026
2ac6907
fix(qwp): keep compiled-writer row typing across published bundles
glasstiger Aug 21, 2026
822da58
ci: typecheck a consumer against the built declaration files
glasstiger Aug 21, 2026
4756867
test(qwp): pin which published classes can be named in a type position
glasstiger Aug 21, 2026
aabde6e
build(qwp): emit src/qwp/** as shared chunks instead of per-entry copies
glasstiger Aug 21, 2026
2399426
test(qwp): cover failover in a real browser
glasstiger Aug 21, 2026
a543a4f
ci: allow the build workflow to be dispatched manually
glasstiger Aug 21, 2026
5225cdd
refactor(qwp): replace the native slot lock with a pure-JS directory …
glasstiger Aug 21, 2026
68be1cc
fix(tcp): derive the JWK public point from the configured private key
glasstiger Aug 21, 2026
3360f67
test(qwp): drop browser tests that need a live QuestDB
glasstiger Aug 21, 2026
0a11537
ci: type-check test/** and fix what that surfaces
glasstiger Aug 21, 2026
a11f2dd
fix(ci): keep test/dist-types out of the test type-check
glasstiger Aug 21, 2026
3b494f5
fix(ci): make the build-artifact gate runnable
glasstiger Aug 21, 2026
93cbad4
fix(qwp): attach socket listeners before an aborted signal closes them
glasstiger Aug 21, 2026
5f305bf
fix(qwp): prove advisory-lock ownership with an acquisition token
glasstiger Aug 21, 2026
8870a28
fix(qwp): stop writing to a journal whose slot lock was reclaimed
glasstiger Aug 21, 2026
7aaf8df
fix: validate a column call even when its value is nullish
glasstiger Aug 21, 2026
be17047
fix(qwp): accept nullish words in long256Column
glasstiger Aug 21, 2026
1981bf2
fix(qwp): reject symbol IDs and encode options that cannot be honoured
glasstiger Aug 21, 2026
597991c
fix(qwp): bound decoded identifiers in bytes, not code units
glasstiger Aug 21, 2026
c754bfb
fix: make the QWP entry points reachable for docs and node10 consumers
glasstiger Aug 21, 2026
0606437
fix(qwp): stop close() from leaving connects and writes behind
glasstiger Aug 21, 2026
390c1bc
test(qwp): cover store-and-forward exclusion across real processes
glasstiger Aug 22, 2026
ce3ae47
fix(qwp): reject geohash and decimal values that cannot be encoded
glasstiger Aug 23, 2026
d7c90dc
fix(qwp): retry a transient journal fault raised while applying an ACK
glasstiger Aug 23, 2026
6e8951b
fix(qwp): quarantine an orphan slot whose head the server rejects
glasstiger Aug 23, 2026
a9a1948
fix(qwp): bound the grid a RESULT_BATCH declares, not only each dimen…
glasstiger Aug 23, 2026
89f0ee6
fix(qwp): close segment handles when the hot spare cannot be discarded
glasstiger Aug 23, 2026
18b2877
docs: generate the QWP entry points typedoc.json already declares
glasstiger Aug 23, 2026
81bb837
fix: discard a row that cannot be closed instead of wedging the sender
glasstiger Aug 23, 2026
0a1fccf
fix(qwp): keep auto-flush accurate when reset() lands during a flush
glasstiger Aug 23, 2026
5f2f692
fix(qwp): let an explicit connect_timeout bound the WebSocket upgrade
glasstiger Aug 23, 2026
4ea0f38
perf(qwp): decompress a RESULT_BATCH in place, not through a shifting…
glasstiger Aug 23, 2026
6417967
fix(qwp): retry a transient upgrade rejection instead of failing term…
glasstiger Aug 24, 2026
12f32f1
fix(qwp): stop a transient owner-record read from latching the slot lock
glasstiger Aug 24, 2026
6c3de06
fix(qwp): make the ACK watermark durable before the manifest that tri…
glasstiger Aug 24, 2026
6d02085
fix(qwp): keep a reclaimed journal from deleting the new owner's files
glasstiger Aug 24, 2026
ff32123
fix(qwp): retry a recoverable slot before quarantining it
glasstiger Aug 24, 2026
45a380a
perf(qwp): split UDP datagrams without re-encoding the batch each time
glasstiger Aug 24, 2026
68b06b4
fix(qwp): keep a QWP logger supplied without a top-level one
glasstiger Aug 24, 2026
de38f5a
fix(qwp): make the zstd over-run marker impossible to spell by accident
glasstiger Aug 24, 2026
266438f
fix(qwp): validate a column call even when its value is nullish
glasstiger Aug 24, 2026
0843b0e
fix(qwp): apply target and zone to ingress, not only egress
glasstiger Aug 24, 2026
26a190d
fix(qwp): let close() abort a connect that holds a store-and-forward …
glasstiger Aug 24, 2026
a645bf3
test(qwp): stop the auto-flush row trigger racing the interval trigger
glasstiger Aug 24, 2026
8f5a475
docs: name the client after JavaScript, not Node.js
glasstiger Aug 24, 2026
d9e0893
ci: point the Enterprise dispatch at the renamed e2e pipeline
glasstiger Aug 24, 2026
88311dd
fix(qwp): keep an async observability callback from crashing the host
glasstiger Aug 24, 2026
e3f7475
test(qwp): assert wss:// verifies certificates and preserves credentials
glasstiger Aug 24, 2026
c4fc77d
fix(qwp): validate nullish dateColumn and fixed-width decimal calls
glasstiger Aug 24, 2026
5745581
perf(qwp): drop the per-cell column-key rebuild on the ingest path
glasstiger Aug 25, 2026
8d2cf79
fix(qwp): send an all-nullish compiled-writer row instead of rejectin…
glasstiger Aug 25, 2026
fcebb9c
fix(qwp): point the udp-only relocation hint at udp, not http/tcp/udp
glasstiger Aug 25, 2026
e0b3611
fix(qwp): count rows a reset-interrupted flush already published
glasstiger Aug 25, 2026
687913b
fix(qwp): keep a parked append waiting through a self-healing trim fault
glasstiger Aug 25, 2026
c61f26e
test(qwp): count only payload bytes in the sfa-multiprocess marker check
glasstiger Aug 25, 2026
0dfee20
fix(qwp): reject an over-range ingress ACK instead of clamping it
glasstiger Aug 25, 2026
2bf90ff
fix(qwp): stop a stale advisory-lock holder from re-proving itself
glasstiger Aug 25, 2026
ea1bfb0
fix(qwp): stop a caller agent on wss from silently disabling tls_verify
glasstiger Aug 25, 2026
3a0b286
fix(qwp): bound the egress delta dictionary a RESULT_BATCH declares
glasstiger Aug 25, 2026
f2764bd
perf(qwp): drop two quadratic/redundant costs from the encoder hot path
glasstiger Aug 25, 2026
d7b2fdc
fix: validate the timestamp unit even when the value is nullish
glasstiger Aug 25, 2026
afc24fd
fix(qwp): install the default logger for ws::/wss:: connect strings
glasstiger Aug 25, 2026
e7a03e2
fix(qwp): wait out a self-healing trim fault met by a fresh append
glasstiger Aug 25, 2026
3854ca6
perf(qwp): slice a sparse table in ascending order without rescanning
glasstiger Aug 25, 2026
92bda6f
fix(qwp): validate the server decimal scale and drain views before a …
glasstiger Aug 25, 2026
de2c6f6
perf(qwp): lazy-load the QWP Node subsystem from the root entry
glasstiger Aug 25, 2026
73ed15c
fix(qwp): validate compressed delta bounds after decompression
glasstiger Aug 25, 2026
28e499b
fix(qwp): validate identifier limits in UTF-8 bytes
glasstiger Aug 25, 2026
6cec137
fix(qwp): preserve routing for pooled orphan recovery
glasstiger Aug 25, 2026
76e111e
fix(qwp): retry rate-limited browser bootstrap
glasstiger Aug 25, 2026
d5a16e4
test(qwp): settle trimming before lock reclamation
glasstiger Aug 25, 2026
afc4057
fix(qwp): preserve root failover endpoints
glasstiger Aug 25, 2026
ca8d23d
fix(qwp): accept signed packed IPv4 values
glasstiger Aug 25, 2026
0bb1adb
fix(qwp): require PEM TLS roots
glasstiger Aug 25, 2026
8c47a5e
fix(qwp): preserve ESM runtime identity
glasstiger Aug 26, 2026
303a6bb
fix(qwp): accept exponent decimal numbers
glasstiger Aug 26, 2026
818eb96
test(qwp): verify custom PEM root handshake
glasstiger Aug 26, 2026
5284c8f
fix(qwp): preserve typed ingress overrides
glasstiger Aug 26, 2026
de73067
fix(qwp): avoid ACK deadlines for browser polls
glasstiger Aug 26, 2026
f2aca2d
fix(qwp): require durable ACK negotiation for polling
glasstiger Aug 26, 2026
002b81d
fix(qwp): stop terminal replay retry loops
glasstiger Aug 26, 2026
b19302e
perf(qwp): lazy-load root QWP module
glasstiger Aug 26, 2026
d565bec
fix(qwp): warn when ignoring incompatible agents
glasstiger Aug 26, 2026
7c29d3a
fix(qwp): accept trusted certificate PEM roots
glasstiger Aug 26, 2026
6f71c99
fix(qwp): validate programmatic security options
glasstiger Aug 26, 2026
3eb4610
build: verify packed artifacts
glasstiger Aug 26, 2026
6634ca4
fix(qwp): report CRC tail data loss
glasstiger Aug 26, 2026
ac91f90
docs: update Sender transport semantics
glasstiger Aug 26, 2026
a7f9818
fix: statically load QWP node module
glasstiger Aug 27, 2026
0b66d49
fix: reset poison strikes during outages
glasstiger Aug 27, 2026
fb4a8b3
docs: clarify ILP auto-flush failure semantics
glasstiger Aug 27, 2026
425e936
fix: validate unsupported ILP columns consistently
glasstiger Aug 27, 2026
f9961fe
fix: retry transient QWP journal faults
glasstiger Aug 27, 2026
c044adc
docs(qwp): document numeric null sentinels
glasstiger Aug 27, 2026
c8576dd
fix(qwp): reject UDP authentication aliases
glasstiger Aug 27, 2026
38175c6
docs(qwp): document long-array ingestion limit
glasstiger Aug 27, 2026
5c891bf
fix(qwp): cap array dimensions at server limit
glasstiger Aug 27, 2026
a6df999
fix(qwp): keep mixed failover sweeps retryable
glasstiger Aug 27, 2026
c5d56f9
fix(qwp): bound browser session bootstrap
glasstiger Aug 27, 2026
e2d3094
fix(qwp): close direct sessions after NACK
glasstiger Aug 27, 2026
94bbecd
fix(qwp): retry unknown ingress statuses indefinitely
glasstiger Aug 28, 2026
913f8fb
fix(qwp): validate array dimensions before encoding
glasstiger Aug 28, 2026
405daf6
fix(qwp): validate timestamp units on null columns
glasstiger Aug 28, 2026
d347267
fix(qwp): cancel pool connections during shutdown
glasstiger Aug 28, 2026
be03ff0
fix(qwp): accept negative close flush timeouts
glasstiger Aug 28, 2026
5a67016
refactor: split Node.js and browser clients
glasstiger Sep 2, 2026
a85e01a
fix(qwp): absorb store close failures on protocol-error paths
glasstiger Sep 2, 2026
3b9157b
fix(qwp): classify the CANCELLED and LIMIT_EXCEEDED statuses
glasstiger Sep 2, 2026
901daec
fix(qwp): stop transient server faults from latching the poison detector
glasstiger Sep 2, 2026
42ab02c
fix(qwp): reject an over-wide row when it is staged, not at flush
glasstiger Sep 2, 2026
1d4a228
perf(qwp): derive each ingress column's encoding once per frame
glasstiger Sep 2, 2026
8c2fefd
fix(qwp): close two holes in the row-discard contract
glasstiger Sep 2, 2026
db181f3
fix(qwp): release a decimal column's scale lock once its rows are pub…
glasstiger Sep 2, 2026
e662f86
fix(qwp): await the aborted connection's teardown in close()
glasstiger Sep 2, 2026
2f3d6a7
fix(qwp): keep a pooled client usable after a failed connect
glasstiger Sep 2, 2026
cdd8e89
fix(qwp): keep requestDurableAck off the egress upgrade
glasstiger Sep 2, 2026
e1018a1
docs(qwp): correct seven claims that did not match the code
glasstiger Sep 2, 2026
760d0e0
test(qwp): accept Node 26 detached buffer error
glasstiger Sep 2, 2026
302c544
fix(ilp): enforce symbol ordering independently of column values
glasstiger Sep 2, 2026
ea4b141
fix(qwp): keep the close ACK wait observed past its deadline
glasstiger Sep 2, 2026
3fd7905
fix(qwp): serve CommonJS to the browser export condition
glasstiger Sep 2, 2026
ec7b286
fix(qwp): count only written bytes as discarded journal data
glasstiger Sep 2, 2026
236eddd
fix(qwp): report a retired deferred recovery tail
glasstiger Sep 2, 2026
f41630a
docs(qwp): document the cluster-wide terminal auth verdict
glasstiger Sep 2, 2026
198fef1
refactor(qwp): type the capacity waiter's timer as optional
glasstiger Sep 2, 2026
c5bbb00
docs: correct the entry-point count and record the workspace gates
glasstiger Sep 2, 2026
a03d771
fix(qwp): contextually type the capacity waiter literal
glasstiger Sep 2, 2026
782fced
fix(qwp): report a segment whose record framing overshoots EOF
glasstiger Sep 2, 2026
c2cf921
fix(qwp): recover a slot lock from a stall instead of latching it
glasstiger Sep 2, 2026
8309207
fix(qwp): enforce both table caps where the batch can still be split
glasstiger Sep 2, 2026
57684ff
fix(qwp): quarantine an orphan whose dictionary cannot be reconstructed
glasstiger Sep 2, 2026
5740f33
fix(qwp): enforce the egress maxBatchRows request on the answer
glasstiger Sep 2, 2026
d2bc305
fix(ilp): close the symbol section only on a column call that lands
glasstiger Sep 2, 2026
5085e4f
fix(qwp): reconcile the udp and ws/wss connect-string vocabularies
glasstiger Sep 3, 2026
85ec77a
docs: update the review skill for the workspace split
glasstiger Sep 3, 2026
99d659f
docs: carry the upstream pool-startup contract into the review skill
glasstiger Sep 3, 2026
6e022ef
fix(qwp): stop an unref'd drain timer from stranding close()
glasstiger Sep 3, 2026
22acd37
fix(qwp): stop an unsendable datagram size from reporting delivery
glasstiger Sep 3, 2026
8a881ba
fix(qwp): report a tail segment whose records never reached disk
glasstiger Sep 3, 2026
d7595be
fix(qwp): bound a NACK message by its frame, not a fixed ceiling
glasstiger Sep 3, 2026
610c955
fix(ilp): keep a row closable when the buffer, not the row, is at fault
glasstiger Sep 3, 2026
96fdbf0
fix: declare the Node floor undici actually requires
glasstiger Sep 3, 2026
ed6fae2
docs(ilp): document the UDP default port in the addr TSDoc
glasstiger Sep 3, 2026
41da86a
docs: regenerate the typedoc site
glasstiger Sep 3, 2026
95bc1f5
fix(qwp): tune the ingress reconnect defaults instead of replacing them
glasstiger Sep 3, 2026
3f69ded
fix(qwp): stop charging an open transaction's deferred frame for a close
glasstiger Sep 3, 2026
f4bcaa6
fix(qwp): keep a decimal column's scale locked while a row is still open
glasstiger Sep 3, 2026
010d7a9
fix(qwp): reject an array cell whose values do not fill its dimensions
glasstiger Sep 3, 2026
c2d436a
fix(qwp): enforce the ingress row cap with no negotiated byte cap
glasstiger Sep 3, 2026
2c08342
fix(qwp): validate egress connect-string bounds against the egress de…
glasstiger Sep 3, 2026
fd55924
fix(qwp): reject a compression level that cannot reach the wire
glasstiger Sep 3, 2026
daef7b4
fix(ilp): rewind a close that cannot fit instead of dropping the row
glasstiger Sep 3, 2026
cfd9ae8
fix(qwp): observe the eager first connect that an abort leaves behind
glasstiger Sep 4, 2026
3aaa8b5
fix(qwp): keep an orphan drain alive across a keepalive poll it canno…
glasstiger Sep 4, 2026
6444c96
fix(ilp): keep a row open when its designated timestamp value is reje…
glasstiger Sep 4, 2026
720cd9c
fix(qwp): reject a fixed-width cell its column cannot represent
glasstiger Sep 4, 2026
77a56c3
fix(qwp): key the ACK watermark on the durable request, not the serve…
glasstiger Sep 4, 2026
097e9c3
docs(nodejs): state the Node floor the package actually enforces
glasstiger Sep 4, 2026
89e7ff5
fix(qwp): reject the remaining JWK keys on a udp connect string
glasstiger Sep 4, 2026
c2cb03a
fix(qwp): let a terminal keepalive-poll verdict quarantine the orphan…
glasstiger Sep 4, 2026
b9f0ad1
fix(ilp): discard a row no timestamp can close before validating the …
glasstiger Sep 4, 2026
3eb25a4
perf(qwp): range-check timestamps in the pass that already converts them
glasstiger Sep 4, 2026
2537359
docs(qwp): key the documented watermark rule on the durable request
glasstiger Sep 4, 2026
0879571
test(qwp): cover the session-side ACK watermark gate
glasstiger Sep 4, 2026
e3751e2
fix(qwp): keep the ACK watermark when a journal load fails mid-scan
glasstiger Sep 4, 2026
29b6677
fix(ilp): make the row-discard contract match what at()/atNow() imple…
glasstiger Sep 4, 2026
1891920
fix(qwp): validate security options on the programmatic ws/wss sender…
glasstiger Sep 4, 2026
f61b0cd
fix(qwp): absorb the delta dictionary from a discarded egress batch
glasstiger Sep 4, 2026
7c581fd
fix(qwp): correct store-and-forward recovery and lock-adoption diagno…
glasstiger Sep 4, 2026
0c2f38d
build(publish): refuse a dispatch that would release only one package
glasstiger Sep 4, 2026
87e10a0
fix(qwp): fence persistent ingress durability
glasstiger Sep 4, 2026
b752035
fix(qwp): reject invalid encoding options
glasstiger Sep 4, 2026
bfec211
fix(qwp): bound reconnects and serialize result credit
glasstiger Sep 4, 2026
63e9414
fix(types): keep declarations compatible with TypeScript 4.9
glasstiger Sep 4, 2026
0438c95
fix(qwp): harden ingress acknowledgement tracking
glasstiger Sep 4, 2026
8d53cfa
fix(qwp): harden reconnect lifecycle
glasstiger Sep 4, 2026
6e61702
fix(qwp): validate low-level floating-point values
glasstiger Sep 4, 2026
853eb61
fix(qwp): reject ambiguous authentication sources
glasstiger Sep 4, 2026
6c654aa
fix(qwp): harden low-level numeric validation
glasstiger Sep 4, 2026
0dbbe53
fix(ilp): validate decimal scales for nullish columns
glasstiger Sep 4, 2026
110d12f
fix(qwp): harden store-and-forward reliability
glasstiger Sep 4, 2026
61f4566
fix(qwp): validate low-level long values
glasstiger Sep 6, 2026
d6c678e
fix(qwp): address remaining review findings
glasstiger Sep 6, 2026
4f237d8
fix(qwp): harden replay and wire validation
glasstiger Sep 6, 2026
d4d74bd
fix(qwp): reject contradictory acknowledgment options
glasstiger Sep 7, 2026
7e2f3d6
fix(qwp): make view callback completion safe
glasstiger Sep 7, 2026
56c7d06
fix(qwp): split batches at the table count cap
glasstiger Sep 7, 2026
dc6f5b1
fix(qwp): bound reconnect and pool shutdown
glasstiger Sep 7, 2026
2714c02
fix(qwp): retire empty lost replay segments
glasstiger Sep 7, 2026
b9c6b77
fix(qwp): preserve durable ack and orphan quarantine
glasstiger Sep 7, 2026
26affa3
fix(qwp): correct core encoding edge cases
glasstiger Sep 7, 2026
729e6e1
fix(qwp): preserve replay journal integrity
glasstiger Sep 7, 2026
27e8f8b
fix(qwp): keep abandoned frames out of ack state
glasstiger Sep 7, 2026
b638b04
fix(qwp): prevent live replay lease takeover
glasstiger Sep 7, 2026
84d174a
fix(qwp): reclaim an abandoned advisory-lock owner directory
glasstiger Sep 7, 2026
134b1da
fix(qwp): stop a transient journal fault from ending a producer
glasstiger Sep 7, 2026
34c3bc6
fix(qwp): close what a failed startup started, and bound egress shutdown
glasstiger Sep 7, 2026
fe341bb
fix(qwp): keep store-and-forward journals inside the directory they c…
glasstiger Sep 7, 2026
caac293
fix(qwp): measure reconnect budgets and dwell windows on the monotoni…
glasstiger Sep 7, 2026
a214198
fix(qwp): stop dropping programmatically supplied options
glasstiger Sep 7, 2026
806b439
fix(qwp): dispatch egress reconnect events on a bounded inbox
glasstiger Sep 7, 2026
99be589
docs(qwp): correct the store-and-forward reference
glasstiger Sep 7, 2026
2451428
fix(qwp): persist the recovery cursor when a prefix is discarded
glasstiger Sep 8, 2026
33283c3
fix(qwp): stop leaking and silently overriding upgrade credentials
glasstiger Sep 8, 2026
d5ccf91
fix(qwp): observe every promise the observer paths leave in flight
glasstiger Sep 8, 2026
4195dcd
fix(qwp): reject an out-of-range geohash bind instead of masking it
glasstiger Sep 8, 2026
7d103b9
fix(qwp): measure the remaining store-and-forward budgets monotonically
glasstiger Sep 8, 2026
cae4cb8
fix(qwp): say when a Sender ignores a QWP configuration key
glasstiger Sep 8, 2026
66d2b4f
ci(publish): run the complete built-package type gate
glasstiger Sep 8, 2026
99aa3cb
docs(review-pr): keep the submodule check out of argument substitution
glasstiger Sep 8, 2026
38a1b05
perf(qwp): keep ingress metrics off the flush hot path
glasstiger Sep 8, 2026
7c73e45
fix(qwp): stop endpoint credentials reaching QWP error text
glasstiger Sep 8, 2026
6269199
fix(qwp): stop store-and-forward budgets abandoning recoverable data
glasstiger Sep 8, 2026
982db8e
fix(qwp): send the real package version as the default client id
glasstiger Sep 8, 2026
9eb31dd
docs(qwp): correct the authTimeoutMs deadline contract
glasstiger Sep 8, 2026
496fd2b
style: apply Prettier, and gate it in CI
glasstiger Sep 8, 2026
b823991
docs: regenerate the API reference
glasstiger Sep 8, 2026
f57887b
fix(qwp): stop store-and-forward journals losing their exclusion and …
glasstiger Sep 8, 2026
5caf480
fix(qwp): stop the reconnect loop retrying and latching the wrong errors
glasstiger Sep 8, 2026
c9e55b9
fix(qwp): redact endpoint credentials from reconnect notification events
glasstiger Sep 8, 2026
bee2458
fix(qwp): apply the connect string's QWP option rules to the programm…
glasstiger Sep 8, 2026
0a5663d
fix(qwp): retire a store-and-forward segment that outlived its origin
glasstiger Sep 8, 2026
119a12e
fix(qwp): serialize async observers on the ingress notification inboxes
glasstiger Sep 8, 2026
812e0e8
fix(qwp): apply the right configuration scope to a Sender's QWP keys
glasstiger Sep 8, 2026
13c7fc9
fix(qwp): stop the cluster-address parser echoing endpoint credentials
glasstiger Sep 8, 2026
9df61ad
fix(qwp): observe the acknowledgement promise the publication API han…
glasstiger Sep 8, 2026
bca76a0
fix(qwp): give a bigint zero the same QUERY_REQUEST bytes as a number…
glasstiger Sep 8, 2026
148531f
fix(qwp): apply the connect string's transport-scoped key rules to th…
glasstiger Sep 8, 2026
3e2acf4
test(nodejs): cover the symbol-section rollback when a column value o…
glasstiger Sep 8, 2026
9e9aad4
docs(qwp): document every public error class, the defaults the code a…
glasstiger Sep 8, 2026
fed5aae
ci(gitleaks): declare the sample credentials the scanner keeps reporting
glasstiger Sep 8, 2026
bb14ad1
Read durable-ACK support from SERVER_INFO
glasstiger Sep 8, 2026
e8eac15
fix(qwp): stop trimming a segment the manifest still names
glasstiger Sep 9, 2026
8da1c20
test(qwp): advertise durable ACK from the browser e2e mock
glasstiger Sep 9, 2026
7a0dc4b
test: pin the published surface and the ILP side of the QWP members
glasstiger Sep 9, 2026
924b6c4
fix(qwp): fence replay-store manifest mutations
glasstiger Sep 9, 2026
baf6fb9
fix(qwp): request browser ingress negotiation
glasstiger Sep 9, 2026
1c39120
fix(qwp): harden replay-store ownership and recovery
glasstiger Sep 9, 2026
2c67059
fix(qwp): validate egress stream integrity
glasstiger Sep 9, 2026
8f9a0f7
fix(qwp): validate transport routing and agents
glasstiger Sep 9, 2026
6ebcc27
ci: gate publishing on browser bundle tests
glasstiger Sep 9, 2026
d957e66
fix(qwp): address the review's remaining findings
glasstiger Sep 9, 2026
6a4f323
fix(qwp): address the review's follow-up findings
glasstiger Sep 9, 2026
5d6bb6f
fix(qwp): bound decompression, repair binds, and harden journal recovery
glasstiger Sep 10, 2026
f03d051
docs: regenerate the API reference
glasstiger Sep 10, 2026
3ca2ced
fix(qwp): keep a failover sweep on the scheme its credentials were bu…
glasstiger Sep 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
881 changes: 881 additions & 0 deletions .claude/skills/review-pr/SKILL.md

Large diffs are not rendered by default.

129 changes: 127 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ on:
- main
pull_request:
schedule:
- cron: '15 2,10,18 * * *'
- cron: "15 2,10,18 * * *"
# GitHub disables a scheduled workflow after 60 days of repository
# inactivity, which stops it running on pull requests too. Dispatch is
# how to re-run it after that without pushing to a branch.
workflow_dispatch:

jobs:
test:
Expand All @@ -28,14 +32,135 @@ jobs:

- uses: pnpm/action-setup@v4
with:
version: 9
version: 10.12.4
run_install: true

- name: Linting
run: pnpm eslint

# `pnpm format` writes; nothing verified the result, so formatting drifted
# into files no other gate reads.
- name: Formatting
run: pnpm format:check

- name: Type-checking
run: pnpm typecheck

# This contract uses DOM libraries with no @types/node and covers only
# the source graph shipped in @questdb/browser-client.
- name: Type-checking (browser)
run: pnpm typecheck:qwp-browser

# `pnpm typecheck` covers src plus a single contract file, so nothing
# type-checked test/** at all: a test could reference a deleted export
# and still pass, because vitest strips types without checking them.
- name: Type-checking (tests)
run: pnpm typecheck:test

- name: Type-checking (benchmarks)
run: pnpm typecheck:bench

- name: Linting (benchmarks)
run: pnpm lint:bench

- name: Tests
run: pnpm test

# Loads the built bundles through package.json `exports`, the way a
# consumer does, and verifies the two npm package boundaries.
- name: Built package tests
run: pnpm test:dist

# test:dist asserts runtime behaviour only. The compiled writers promise
# per-column row typing, which lives entirely in the emitted .d.ts files
# and is therefore invisible to source-level tests, where the public
# entries share one private-core module instance.
- name: Type-checking (built package consumer)
run: pnpm typecheck:dist

# The same gate publish.yml runs. Keeping it here too means a chunk that
# escapes `files`, or a regression in the check itself, fails a pull
# request instead of first being discovered during a release.
- name: Check for build artifacts
run: node scripts/check-build-artifacts.mjs

# Drives the built browser bundle in real Chromium against a local mock
# server. Tests that need a live QuestDB belong in the server repositories,
# where the topology and authentication fixtures already exist.
qwp-browser:
name: QWP browser bundle
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20

- uses: pnpm/action-setup@v4
with:
version: 10.12.4
run_install: true

- name: Install Chromium
run: pnpm exec playwright install --with-deps chromium

- name: Browser bundle tests
run: pnpm test:qwp-browser

enterprise-qwp-e2e:
name: Dispatch Enterprise QWP E2E
runs-on: ubuntu-latest
# Azure credentials are not exposed to fork PRs. The repository variable
# keeps this dormant until the Enterprise pipeline and PAT are configured.
if: >-
vars.ENTERPRISE_E2E_ENABLED == 'true' &&
(github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository)
steps:
- name: Queue Enterprise TypeScript-client E2E
env:
ENT_DISPATCH_PAT: ${{ secrets.ENT_DISPATCH_PAT }}
CLIENT_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
CLIENT_PR_NUMBER: ${{ github.event.pull_request.number || '' }}
CLIENT_BRANCH: ${{ github.head_ref || github.ref_name }}
run: |
set -euo pipefail

if [ -z "${ENT_DISPATCH_PAT:-}" ]; then
echo "ENT_DISPATCH_PAT is not configured" >&2
exit 1
fi

ORG_URL="https://dev.azure.com/questdb/"
PROJECT="questdb-enterprise"
PIPELINE_NAME="build-and-test-e2e-javascript-client"
PIPELINES=$(curl -fsS -u ":${ENT_DISPATCH_PAT}" \
"${ORG_URL}${PROJECT}/_apis/pipelines?api-version=7.0")
PIPELINE_ID=$(echo "$PIPELINES" | jq -r --arg name "$PIPELINE_NAME" \
'.value[] | select(.name == $name) | .id' | head -1)
if [ -z "$PIPELINE_ID" ] || [ "$PIPELINE_ID" = "null" ]; then
echo "Enterprise pipeline '$PIPELINE_NAME' is not registered" >&2
exit 1
fi

BODY=$(jq -n \
--arg commit "$CLIENT_COMMIT" \
--arg pr "$CLIENT_PR_NUMBER" \
--arg branch "$CLIENT_BRANCH" \
'{
templateParameters: {
javascriptClientCommit: $commit,
javascriptClientPrNumber: $pr,
clientBranch: $branch
}
}')
RESPONSE=$(curl -fsS -u ":${ENT_DISPATCH_PAT}" \
-H "Content-Type: application/json" \
-X POST \
-d "$BODY" \
"${ORG_URL}${PROJECT}/_apis/pipelines/${PIPELINE_ID}/runs?api-version=7.0")
echo "Enterprise E2E queued: $(echo "$RESPONSE" | jq -r '._links.web.href')"
50 changes: 42 additions & 8 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

- uses: pnpm/action-setup@v4
with:
version: 9
version: 10.12.4
run_install: true

- name: Linting
Expand All @@ -29,21 +29,55 @@ jobs:
- name: Type-checking
run: pnpm typecheck

# This contract uses DOM libraries with no @types/node and covers only
# the source graph shipped in @questdb/browser-client.
- name: Type-checking (browser)
run: pnpm typecheck:qwp-browser

- name: Tests
run: pnpm test

- name: Build
run: pnpm build
- name: Install Chromium
run: pnpm exec playwright install --with-deps chromium

- name: Browser bundle tests
run: pnpm test:qwp-browser

- name: Built package tests
run: pnpm exec vitest run --config vitest.dist.config.ts

# Guards the emitted .d.ts row typing, which no runtime suite can see.
# Run the script rather than inlining its commands: hand-copying them
# here dropped the TypeScript 4.9 leg, and publish.yml is
# workflow_dispatch-only with no dependency on build.yml, so a dispatch
# from a branch that never opened a pull request reached npm publish with
# no legacy-consumer gate at all. The script re-runs `pnpm build`, which
# is idempotent.
- name: Type-checking (built package consumer)
run: pnpm typecheck:dist

# Checks both npm tarballs and follows every exported declaration and
# runtime module through its relative dependency graph.
- name: Check for build artifacts
run: |
[ -f dist/cjs/index.js ] || (echo "CJS build missing" && exit 1)
[ -f dist/es/index.mjs ] || (echo "ESM build missing" && exit 1)
run: node scripts/check-build-artifacts.mjs

# Both packages are published from one commit, and npm-publish silently
# skips a version that already exists. Fail here instead of half-releasing.
- name: Check release versions
run: node scripts/check-release-versions.mjs

- name: Publish @questdb/nodejs-client
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.CI_TOKEN }}
access: public
strategy: all
package: packages/nodejs-client/package.json

- name: Publish
- name: Publish @questdb/browser-client
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.CI_TOKEN }}
access: public
strategy: all
package: package.json
package: packages/browser-client/package.json
29 changes: 29 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Gitleaks configuration for the QuestDB JavaScript clients.
#
# The default rule set is kept in full. This file only names the sample
# credentials the repository has to spell out in the clear, so that
# `generic-api-key`, which cannot tell a sample apart from a credential, stops
# reporting them.
#
# Every value below is a placeholder or a published documentation sample. None
# authenticates anything: the tests hand them to mock servers that run inside
# the test process, and the examples point at a local QuestDB.

title = "QuestDB JavaScript clients"

[extend]
useDefault = true

[allowlist]
description = "Sample credentials used by the tests, examples, and README"
regexes = [
# P-256 private scalars for ILP TCP authentication. Signing needs a real
# scalar, so these cannot be shortened to an obvious placeholder.
'''9b9x5WhJywDEuo1KGQWSPNxtX-6X6R2BRCKhYMMY6n8''', # kid "testapp", tests and examples.manifest.yaml
'''zhPiK3BkYMYJvRf5sqyrWNJwjDKHOWHnRbmQggUll6A''', # kid "user1", second key in the TCP auth tests
'''ZRxmCOQBpZoj2fZ-lEtqzVDkCre_ouF3ePpaQNDwoQk''', # kid "admin", the documented example key
# HTTP bearer tokens, which are opaque strings the client never interprets.
'''Xyvd3er6GF87ysaHk''', # README token example
'''abcdefghijkl123''', # mock HTTP server in the transport tests
'''jwkprivkey123''', # connect-string parsing fixture in the options tests
]
39 changes: 30 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,76 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

This is the QuestDB Node.js client library (@questdb/nodejs-client) that provides data ingestion capabilities to QuestDB databases. The client supports multiple transport protocols (HTTP/HTTPS, TCP/TCPS) and authentication methods.
This repository builds the QuestDB JavaScript clients: `@questdb/nodejs-client`
for Node.js and `@questdb/browser-client` for browsers. A private
`@questdb/client-core` workspace package owns their shared implementation.

## Development Commands

### Build

```bash
pnpm build # Build the library using bunchee (produces both ESM and CJS outputs)
pnpm build # Build both public ESM/CJS packages from client-core
```

### Testing

```bash
pnpm test # Run all tests using Vitest
```

### Code Quality

```bash
pnpm eslint # Run ESLint on all source files
pnpm typecheck # Run TypeScript type checking without emitting files
pnpm format # Format code using Prettier
```

### Documentation

```bash
pnpm docs # Build JSDoc documentation
pnpm run docs # Build TypeDoc documentation
pnpm preview:docs # Preview generated documentation locally
```

## Architecture

### Core Components

1. **Sender** (`src/sender.ts`): Main API class that orchestrates data ingestion. Handles auto-flushing, connection management, and provides the builder pattern API for constructing rows.
Runtime-neutral QWP implementation lives under `packages/client-core/src`.
Each public package owns its runtime-specific source, package metadata,
documentation, and single root build.

1. **Sender** (`packages/nodejs-client/src/sender.ts`): Main Node.js API class that orchestrates data ingestion. Handles auto-flushing, connection management, and provides the builder pattern API for constructing rows.

2. **Transport Layer** (`packages/nodejs-client/src/transport/`):

2. **Transport Layer** (`src/transport/`):
- `http/undici.ts`: Default HTTP transport using Undici library for high performance
- `http/stdlib.ts`: Alternative HTTP transport using Node.js built-in modules
- `tcp.ts`: TCP/TCPS transport for persistent connections with JWK authentication
- Protocol negotiation and retry logic for HTTP transports

3. **Buffer System** (`src/buffer/`):
3. **Buffer System** (`packages/nodejs-client/src/buffer/`):

- `bufferv1.ts`: Text-based protocol (version 1) for backward compatibility
- `bufferv2.ts`: Binary protocol (version 2) with double encoding and array support
- `bufferv3.ts`: Extends v2 with DECIMAL columns (`decimalColumn`, `decimalColumnText`)
- All three are public exports (`SenderBufferV1`/`V2`/`V3`), selected by `createBuffer`
- Dynamic buffer resizing and row-level transaction support

4. **Configuration** (`src/options.ts`): Comprehensive options parsing from connection strings with validation and deprecation handling.
4. **Configuration** (`packages/nodejs-client/src/options.ts`): Comprehensive options parsing from connection strings with validation and deprecation handling.

5. **QWP core** (`packages/client-core/src/qwp/` and `packages/client-core/src/_qwp/`): Shared browser-safe protocol/session code.

6. **Runtime adapters**: `packages/nodejs-client/src/qwp.ts` owns Node WebSocket, UDP, TLS, and persistence support; `packages/browser-client/src/index.ts` owns the browser WebSocket and authentication adapter. The browser package must remain free of Node built-ins, Node typings, `undici`, and `ws`.

### Protocol Versions

- **Version 1**: Text-based serialization, compatible with older QuestDB versions
- **Version 2**: Binary encoding for doubles, supports array columns, better performance
- **Auto-negotiation**: HTTP transport can automatically detect and use the best protocol version
- **Version 3**: Adds DECIMAL columns on top of version 2
- **Auto-negotiation**: HTTP transport can automatically detect and use the best protocol version, preferring v3 over v2

### Key Design Patterns

Expand All @@ -66,6 +85,7 @@ pnpm preview:docs # Preview generated documentation locally
## Testing Strategy

Tests are organized by component:

- `sender.config.test.ts`: Configuration parsing and validation
- `sender.buffer.test.ts`: Buffer operations and protocol serialization
- `sender.transport.test.ts`: Transport layer functionality
Expand All @@ -80,4 +100,5 @@ Integration tests use TestContainers to spin up QuestDB instances for realistic
- Buffer automatically resizes up to `max_buf_size` (default 100MB)
- Auto-flush triggers based on row count or time interval
- Each worker thread needs its own Sender instance (buffers cannot be shared)
- Protocol version 2 is recommended for new implementations with array column support
- Protocol version 2 or higher is recommended for new implementations; v2 adds array columns and v3 adds DECIMAL
- Run `pnpm test:dist` after package-boundary changes; it checks both npm tarballs, ESM/CJS loading, browser bundling, and the absence of Node modules from the browser artifact.
Loading
Loading