Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
414 commits
Select commit Hold shift + click to select a range
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
9711f7e
fix(qwp): absorb dictionary journal faults and preserve reconnect causes
glasstiger Sep 10, 2026
f4b3ed9
update submodule
glasstiger Sep 14, 2026
8c74abb
fix(qwp)!: resolve remaining review findings
glasstiger Sep 14, 2026
1cdb390
fix(qwp)!: address proven review findings
glasstiger Sep 14, 2026
b2d2495
fix(qwp): share one directory-sync policy across both threads
glasstiger Sep 14, 2026
fbe4cce
refactor(qwp): share transaction frame-flag peeks across replay stores
glasstiger Sep 14, 2026
65d58ed
fix(qwp)!: accept valid RESULT_END, contain observer thenables, honou…
glasstiger Sep 14, 2026
7907e07
fix(qwp): fail over to a larger-cap node during fail-fast store-and-f…
glasstiger Sep 14, 2026
4588383
docs(qwp): document the disabled reconnect deadline and typed UDP pre…
glasstiger Sep 14, 2026
8e74ec0
merge(qwp): cap-aware fail-fast startup failover
glasstiger Sep 14, 2026
b6afeb5
test(qwp): align egress replay terminals with zero-based batch sequences
glasstiger Sep 14, 2026
893ba12
fix(qwp): keep valid decimals, cross-realm bytes and rolled-back rows
glasstiger Sep 15, 2026
3ce8c8b
fix(qwp): keep store-and-forward journals committable and self-cleaning
glasstiger Sep 15, 2026
941cfed
merge(qwp): correct decimal text, cross-realm bytes, array cap, rollb…
glasstiger Sep 15, 2026
9f7e0f3
refactor(qwp): share one array-axis limit and document the corrected …
glasstiger Sep 15, 2026
415d583
merge(qwp): keep store-and-forward journals committable, startable an…
glasstiger Sep 15, 2026
8b91442
test(qwp): end the browser egress stream at its last batch sequence
glasstiger Sep 15, 2026
fd428ba
fix(qwp): stop padding null VARCHAR query binds with an unread offset…
glasstiger Sep 15, 2026
e2daa9e
fix(qwp): validate the QWP sender logger and share one frame-flags of…
glasstiger Sep 15, 2026
d443934
merge(qwp): correct the null VARCHAR query bind encoding
glasstiger Sep 15, 2026
3fcd080
fix(qwp): bound decimal scale and accept ".5"/"5." decimal text
glasstiger Sep 15, 2026
90326b3
merge(qwp): bound decimal scale and widen the decimal-text grammar
glasstiger Sep 15, 2026
27cf88f
docs(qwp): document the decimal-text grammar and the {unscaled, scale…
glasstiger Sep 15, 2026
7437e99
fix(qwp): bound the store-and-forward transaction-close admission
glasstiger Sep 15, 2026
81de591
merge(qwp): bound the store-and-forward transaction-close admission
glasstiger Sep 15, 2026
7683e7b
docs(qwp): state the bounded store-and-forward liveness overshoot
glasstiger Sep 15, 2026
ce57b28
fix(qwp): close remaining review findings
glasstiger Sep 15, 2026
3eda92a
fix(qwp): close final review findings
glasstiger Sep 15, 2026
ebfb6e3
fix(qwp): bound timer options and store-and-forward budgets
glasstiger Sep 15, 2026
21ca4bf
fix(qwp): reject impossible replay batches
glasstiger Sep 15, 2026
0da3b1d
fix(qwp): align replay batch capacity
glasstiger Sep 16, 2026
647be7f
fix(qwp): validate codec and row boundaries
glasstiger Sep 16, 2026
71b46b4
fix release recovery and documentation checks
glasstiger Sep 16, 2026
9bb4212
fix(qwp): stop a reclaimed advisory-lock claim from yielding a second…
glasstiger Sep 16, 2026
5f2dfc8
fix(qwp): send through a session that implements only the required me…
glasstiger Sep 16, 2026
216b492
fix(qwp): keep orphan recovery on the sender's durability contract
glasstiger Sep 16, 2026
67af746
build: ship the Apache-2.0 terms both packages are licensed under
glasstiger Sep 16, 2026
9f8543b
docs: correct the low-level ingress example and the Node.js floor
glasstiger Sep 16, 2026
c62e3a2
docs: regenerate the API reference
glasstiger Sep 16, 2026
e73e629
test(qwp): make the advisory-lock race check filesystem-portable
glasstiger Sep 16, 2026
b153b96
fix(qwp): harden recovery and release safety
glasstiger Sep 16, 2026
f27e484
fix(qwp): close remaining review gaps
glasstiger Sep 16, 2026
ac6de9a
fix(qwp): keep recovery, replay, and option precedence intact
glasstiger Sep 16, 2026
166cdec
fix(qwp): keep slot ownership exclusive and lease return bounded
glasstiger Sep 16, 2026
6e505d7
fix(qwp): unblock replay credit and honor startup overrides
glasstiger Sep 17, 2026
fd7c6ad
fix(qwp): finish reconnect and lifecycle cleanup
glasstiger Sep 17, 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