Skip to content
Merged

Dev #63

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
78118b9
dev: Changed import extension for `env.js` in init-pg.ts
erayhanoglu Aug 13, 2026
9d401d6
chore: Updated dependencies
erayhanoglu Aug 13, 2026
87adb5d
dev: Removed unused `init-pg.ts`, adjusted imports, and updated path …
erayhanoglu Aug 13, 2026
99f4802
dev: Updated test matrix to include Node 26 and Postgres 18
erayhanoglu Aug 13, 2026
b1f8f1c
fix: TLS downgrade, credential decoding, and data-corruption bugs fou…
erayhanoglu Sep 3, 2026
5c80923
dev: Added CLAUDE.md with graphify usage rules
erayhanoglu Sep 3, 2026
8b5aa9d
fix: float4 precision loss and sslmode=prefer incorrectly requiring SSL
erayhanoglu Sep 3, 2026
a0a0580
doc: correct grammar in connection.ts method comments
erayhanoglu Sep 3, 2026
e2b392c
dev: Updated gitignore to include claude and graphify
erayhanoglu Sep 3, 2026
af9b312
doc: Remove outdated and unused badges from README.md
erayhanoglu Sep 3, 2026
9fd6d9a
fix: array literal parser treats apostrophe as a quote character
erayhanoglu Sep 3, 2026
18e63bd
fix: int4 OID auto-detection accepts values outside the 32-bit range
erayhanoglu Sep 3, 2026
7609bff
fix: char OID auto-detection matches multi-byte characters, crashing …
erayhanoglu Sep 3, 2026
e449395
fix: midnight timestamps mis-detected as date instead of timestamp
erayhanoglu Sep 3, 2026
4670fa4
fix: numeric NaN/Infinity/-Infinity decode as 0 in binary format
erayhanoglu Sep 3, 2026
c85d76e
fix: prototype pollution via a query result column named "__proto__"
erayhanoglu Sep 3, 2026
ffade2b
fix: escapeLiteral silently passes through embedded NUL bytes
erayhanoglu Sep 3, 2026
b83349a
fix: PreparedStatement.close() not idempotent, re-sends CLOSE+SYNC
erayhanoglu Sep 3, 2026
0c74ae4
chore: ignore benchmark output and correct the CI path filter
erayhanoglu Sep 5, 2026
a65bfeb
docs: record class member order and loop-hoisting conventions
erayhanoglu Sep 5, 2026
25465c8
perf: reassemble backend messages in one allocation instead of concat…
erayhanoglu Sep 5, 2026
299d8d4
fix: ParameterDescription parameter count read as Int32 instead of Int16
erayhanoglu Sep 5, 2026
fabbe36
perf: rewrite the request/response pipeline and decode rows without p…
erayhanoglu Sep 5, 2026
41d98ff
feat: opt-in query pipelining for Pool.query() and Pool.execute()
erayhanoglu Sep 5, 2026
affab97
chore: add a benchmark suite comparing postgrejs, pg and postgres.js
erayhanoglu Sep 5, 2026
ce611d2
fix: CopyInResponse message code is 'g' rather than 'G'
erayhanoglu Sep 5, 2026
89cd28a
feat: bulk import and export with COPY TO STDOUT / COPY FROM STDIN
erayhanoglu Sep 5, 2026
c0d65a3
refactor: name data type methods decode* to pair with encode*
erayhanoglu Sep 6, 2026
12e84f1
feat: cancel queries and time them out with an AbortSignal
erayhanoglu Sep 6, 2026
1c6dfb4
feat: build statements with the sql tag
erayhanoglu Sep 6, 2026
983255f
style: sort imports and align a comment left over from the decode* re…
erayhanoglu Sep 6, 2026
1bb3919
docs: add a feature comparison table and correct stale claims
erayhanoglu Sep 6, 2026
1aa7095
feat: two-phase commit with prepareTransaction and commitPrepared
erayhanoglu Sep 6, 2026
ccf9a0a
docs: record two-phase commit and drop the callback API row
erayhanoglu Sep 6, 2026
3ec07fe
feat: try several hosts and pick one by role
erayhanoglu Sep 6, 2026
1106831
docs: record multi-host connections in the comparison
erayhanoglu Sep 6, 2026
0068377
docs: correct two names in the comparison table
erayhanoglu Sep 6, 2026
a3b6544
feat: direct TLS negotiation, and only negotiate TLS when asked
erayhanoglu Sep 6, 2026
a41046c
docs: record direct TLS negotiation, and drop the example section
erayhanoglu Sep 6, 2026
90e4c31
docs: count encoder and decoder coverage per wire format
erayhanoglu Sep 6, 2026
c99af41
fix: jsonb text encoder wrote the binary version header, and add the …
erayhanoglu Sep 6, 2026
af1f672
fix: oidvector was registered as a second array type of oid
erayhanoglu Sep 6, 2026
fb69574
feat: SCRAM channel binding, and report what the server says when aut…
erayhanoglu Sep 6, 2026
2146275
feat: stream row changes with LogicalReplication
erayhanoglu Sep 6, 2026
94fc89b
feat: large object API
erayhanoglu Sep 6, 2026
eaae3f7
docs: native bindings are partial, not a plain yes
erayhanoglu Sep 6, 2026
ed2fc63
fix: hang instead of an error when the server asks for GSSAPI or SSPI
erayhanoglu Sep 6, 2026
a97b02f
doc: Rebuild BENCHMARKS.md
erayhanoglu Sep 6, 2026
de2ea31
doc: Updated README.md
erayhanoglu Sep 6, 2026
95ef02e
fix: preserve caller stack traces in async error handling
erayhanoglu Sep 6, 2026
4175ff2
3.0.0
erayhanoglu Sep 6, 2026
c046941
fix: cancel() ignored multi-host failover and direct TLS negotiation
erayhanoglu Sep 6, 2026
040d503
docs: capitalize PostgreJS consistently, rebuild BENCHMARKS.md for 3.0.0
erayhanoglu Sep 6, 2026
4c6ca23
perf: skip the instanceof check on plain string SQL in execute()
erayhanoglu Sep 6, 2026
6ac84ea
chore: default the benchmark run config to the simple-query scenario
erayhanoglu Sep 6, 2026
930de06
fix: benchmark console summary leaked every scenario ever run
erayhanoglu Sep 6, 2026
5e2b453
chore: relicense from MIT to BSD 3-Clause
erayhanoglu Sep 6, 2026
82e8c6d
chore: strip explanatory comments from the row-buffer decode change
erayhanoglu Sep 6, 2026
c1fc39f
docs: rewrite benchmark scenario descriptions as readable paragraphs
erayhanoglu Sep 6, 2026
c35a53c
feat: exact-match --scenario/--lib by default, glob with a leading/tr…
erayhanoglu Sep 6, 2026
8d92283
fix: restore execute()'s timing, and switch it to performance.now()
erayhanoglu Sep 6, 2026
85036c4
feat: make async caller-stack capture an opt-out, per-call overridabl…
erayhanoglu Sep 6, 2026
9515a88
chore: use the new glob syntax in the benchmark run config
erayhanoglu Sep 6, 2026
721cd04
fix: default omitted day-of-month to 1, not 0, when parsing dates
erayhanoglu Sep 6, 2026
ed10a84
fix: LISTEN dropped for extra channels, lost after Pool reconnect, do…
erayhanoglu Sep 6, 2026
6b65637
refactor: remove dead Portal/PgSocket message-send methods
erayhanoglu Sep 6, 2026
3b2ec4c
chore: fix istanbul-ignore comments this project's c8 doesn't honor
erayhanoglu Sep 6, 2026
23ee21b
test: cover pure utility functions, wire-protocol messages, and SASL/…
erayhanoglu Sep 6, 2026
086ec90
docs: document local SCRAM/MD5 test setup in CONTRIBUTING.md
erayhanoglu Sep 6, 2026
aa82756
refactor: remove dead BufferReader.moveBy()/moveTo(), add full coverage
erayhanoglu Sep 6, 2026
72984b8
test: raise sql-tag.ts branch coverage, mark one path unreachable
erayhanoglu Sep 6, 2026
603aa92
test: add full coverage for SafeEventEmitter
erayhanoglu Sep 6, 2026
1bc9e6c
test: add full coverage for the pgoutput logical-replication decoder
erayhanoglu Sep 6, 2026
f3db0ec
test: add full coverage for Int2VectorType
erayhanoglu Sep 6, 2026
0835b57
test: add full coverage for OidVectorType
erayhanoglu Sep 6, 2026
8ccfa19
test: add full coverage for LsegType
erayhanoglu Sep 6, 2026
069ecf1
test: add full coverage for CharType
erayhanoglu Sep 6, 2026
c56310f
test: raise connection-config.ts branch coverage
erayhanoglu Sep 6, 2026
aea3be9
test: raise prepared-statement.ts coverage
erayhanoglu Sep 6, 2026
f414562
test: add full coverage for get-parsers.ts
erayhanoglu Sep 6, 2026
6335e50
chore: mark stringifyArrayLiteral's leaf-level array branch unreachable
erayhanoglu Sep 6, 2026
723a050
test: add full coverage for CircleType
erayhanoglu Sep 6, 2026
bfef8a8
fix: JsonType.encodeText() throws on a bigint value
erayhanoglu Sep 6, 2026
a78120f
test: add full coverage for the remaining small scalar data types
erayhanoglu Sep 6, 2026
87abad3
fix: avoid a rare race in the cancel() test's own cleanup
erayhanoglu Sep 6, 2026
021e400
test: add coverage for the encodeText() pass-throughs on temporal types
erayhanoglu Sep 6, 2026
20a9c22
fix: numeric encodeBinary() silently corrupts magnitudes >= 1e21
erayhanoglu Sep 6, 2026
1dbf82d
test: add full coverage for parse-row.ts
erayhanoglu Sep 6, 2026
18c78a6
test: raise large-object.ts coverage
erayhanoglu Sep 6, 2026
e1a097b
test: add full coverage for frontend.ts wire-message builders
erayhanoglu Sep 6, 2026
a6c38cf
refactor: remove dead SmartBuffer.fill(), add full coverage
erayhanoglu Sep 6, 2026
63caed8
test: raise cursor.ts coverage
erayhanoglu Sep 6, 2026
91868a7
test: add full coverage for BoolType.encodeText()
erayhanoglu Sep 6, 2026
91070bc
test: add full coverage for copy-stream.ts
erayhanoglu Sep 6, 2026
90955eb
fix: LogicalReplication.close() never actually drops a permanent slot…
erayhanoglu Sep 6, 2026
473d582
test: add direct unit coverage for LogicalReplication's pure logic
erayhanoglu Sep 6, 2026
da41a91
chore: remove docker-compose setup, update benchmark paths and regene…
erayhanoglu Sep 6, 2026
35c83dc
docs: expand CONTRIBUTING.md with a full contributor workflow
erayhanoglu Sep 6, 2026
48adbd7
docs: tailor issue templates to a PostgreSQL driver
erayhanoglu Sep 6, 2026
ce32dac
docs: add a v2-to-v3 migration guide
erayhanoglu Sep 6, 2026
0c6866f
docs: rewrite README intro to lead with speed, memory, and features
erayhanoglu Sep 6, 2026
dc8d480
fix: header link/image attributes in README
erayhanoglu Sep 6, 2026
500f1b5
fix: correct stale contact and copyright holder in project docs
erayhanoglu Sep 6, 2026
a7058e4
fix: skip direct-negotiation SSL test on PostgreSQL < 17
erayhanoglu Sep 7, 2026
1a80bdc
fix: skip numeric Infinity/-Infinity tests on PostgreSQL < 14
erayhanoglu Sep 7, 2026
99e2be3
docs: expand CLAUDE.md with project orientation and testing techniques
erayhanoglu Sep 7, 2026
f88c6cc
Merge remote-tracking branch 'origin/main' into dev
erayhanoglu Sep 7, 2026
63f4017
3.0.1
erayhanoglu Sep 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 22 additions & 20 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: Bug report
about: Create a report to help us improve
about: Report unexpected or incorrect behavior
title: ''
labels: ''
assignees: ''
Expand All @@ -11,28 +11,30 @@ assignees: ''
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
A minimal, self-contained code snippet that reproduces the issue - the
connection options used (redact any password/host you don't want public)
and the query or API calls involved.

**Expected behavior**
A clear and concise description of what you expected to happen.
```ts
// e.g.
const connection = new Connection({ host: 'localhost', database: 'test' });
await connection.connect();
const result = await connection.query('select 1');
```

**Screenshots**
If applicable, add screenshots to help explain your problem.
**Expected behavior**
What you expected to happen.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Actual behavior**
What actually happened - include the full error message and stack trace,
or the incorrect value returned, if applicable.

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Environment**
- PostgreJS version: [e.g. 3.0.0]
- Node.js version: [e.g. 22.1.0]
- PostgreSQL version and provider: [e.g. PostgreSQL 16, self-hosted / RDS / Supabase / ...]
- OS: [e.g. Ubuntu 22.04]

**Additional context**
Add any other context about the problem here.
Anything else relevant - connection pooling, SSL/TLS settings, whether it
reproduces consistently or intermittently, etc.
17 changes: 13 additions & 4 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@ assignees: ''
---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
A clear and concise description of what the problem is. Ex. I'm always
frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.
A clear and concise description of what you want to happen - what would
the API look like (a new option, method, or type), and how would it be
used?

```ts
// e.g. a sketch of the API you have in mind
```

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
Other ways to solve the same problem, including workarounds you're using
today, and why they fall short.

**Additional context**
Add any other context or screenshots about the feature request here.
Anything else relevant - links to the PostgreSQL protocol/feature docs
this depends on, or how other drivers handle it, for instance.
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ on:
- support/**/*.*
- .mocharc.cjs
- .c8rc.json
- tsconfig*.json
- /tsconfig*.json

# Only one run per branch at a time
concurrency:
Expand All @@ -43,8 +43,8 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [ '20', '22', '23', '24' ]
postgres: [ '12', '14', '16', '17' ]
node: [ '20', '22', '24', '26' ]
postgres: [ '12', '16', '18' ]
runs-on: ubuntu-latest
timeout-minutes: 15
services:
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ node_modules
/build
/examples/*/package-lock.json
*.tsbuildinfo
.claude
graphify-out
/test-*

# environment variables
.env
Expand All @@ -23,6 +26,9 @@ lerna-debug.log*
/reports
/.nyc_output

# Benchmarks
/benchmark/results

# IDEs and editors
/.idea
.project
Expand Down
5 changes: 5 additions & 0 deletions .run/cli.ts.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="cli.ts" type="NodeJSConfigurationType" application-parameters="-s simple-query-execute*" nameIsGenerated="true" node-parameters="--import @swc-node/register/esm-register" path-to-js-file="cli.ts" working-dir="$PROJECT_DIR$/benchmark">
<method v="2" />
</configuration>
</component>
153 changes: 152 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,157 @@
## Changelog

### [v2.23.1](https://github.com/panates/postgrejs/compare/v2.23.0...v2.23.1) -
### [v3.0.1](https://github.com/panates/postgrejs/compare/v3.0.0...v3.0.1) -

- Dev
- Dev
- Dev
- Dev
- dev: Removed path filter
- Dev
- Dev
- fix missing quotes in exception
- Don't fail if husky is not present
- Dev
- Dev

#### 🚀 New Features

- feat: make async caller-stack capture an opt-out, per-call overridable option @Eray Hanoğlu
- feat: exact-match --scenario/--lib by default, glob with a leading/trailing * @Eray Hanoğlu

#### 🪲 Fixes

- fix: LISTEN dropped for extra channels, lost after Pool reconnect, double 'close' emit @Eray Hanoğlu
- fix: cancel() ignored multi-host failover and direct TLS negotiation @Eray Hanoğlu
- fix: default omitted day-of-month to 1, not 0, when parsing dates @Eray Hanoğlu
- fix: numeric encodeBinary() silently corrupts magnitudes &gt;= 1e21 @Eray Hanoğlu
- fix: benchmark console summary leaked every scenario ever run @Eray Hanoğlu
- fix: LogicalReplication.close() never actually drops a permanent slot it created @Eray Hanoğlu
- fix: JsonType.encodeText() throws on a bigint value @Eray Hanoğlu
- fix: restore execute()'s timing, and switch it to performance.now() @Eray Hanoğlu
- fix: skip numeric Infinity/-Infinity tests on PostgreSQL &lt; 14 @Eray Hanoğlu
- fix: skip direct-negotiation SSL test on PostgreSQL &lt; 17 @Eray Hanoğlu
- fix: avoid a rare race in the cancel() test's own cleanup @Eray Hanoğlu
- fix: correct stale contact and copyright holder in project docs @Eray Hanoğlu
- fix: header link/image attributes in README @Eray Hanoğlu

#### 📖 Documentation Changes

- docs: rewrite benchmark scenario descriptions as readable paragraphs @Eray Hanoğlu
- docs: capitalize PostgreJS consistently, rebuild BENCHMARKS.md for 3.0.0 @Eray Hanoğlu
- docs: add a v2-to-v3 migration guide @Eray Hanoğlu
- docs: expand CONTRIBUTING.md with a full contributor workflow @Eray Hanoğlu
- docs: rewrite README intro to lead with speed, memory, and features @Eray Hanoğlu
- docs: expand CLAUDE.md with project orientation and testing techniques @Eray Hanoğlu
- docs: tailor issue templates to a PostgreSQL driver @Eray Hanoğlu
- docs: document local SCRAM/MD5 test setup in CONTRIBUTING.md @Eray Hanoğlu

#### 🛠 Refactoring and Updates

- refactor: remove dead Portal/PgSocket message-send methods @Eray Hanoğlu
- refactor: remove dead SmartBuffer.fill(), add full coverage @Eray Hanoğlu
- refactor: remove dead BufferReader.moveBy()/moveTo(), add full coverage @Eray Hanoğlu

#### 🧪 Changes to Test Assests

- test: cover pure utility functions, wire-protocol messages, and SASL/cert parsing @Eray Hanoğlu
- test: add full coverage for copy-stream.ts @Eray Hanoğlu
- test: add full coverage for the pgoutput logical-replication decoder @Eray Hanoğlu
- test: add direct unit coverage for LogicalReplication's pure logic @Eray Hanoğlu
- test: add full coverage for the remaining small scalar data types @Eray Hanoğlu
- test: add full coverage for frontend.ts wire-message builders @Eray Hanoğlu
- test: add full coverage for parse-row.ts @Eray Hanoğlu
- test: add full coverage for get-parsers.ts @Eray Hanoğlu
- test: add full coverage for LsegType @Eray Hanoğlu
- test: add full coverage for CircleType @Eray Hanoğlu
- test: raise connection-config.ts branch coverage @Eray Hanoğlu
- test: raise sql-tag.ts branch coverage, mark one path unreachable @Eray Hanoğlu
- test: raise cursor.ts coverage @Eray Hanoğlu
- test: add full coverage for OidVectorType @Eray Hanoğlu
- test: add full coverage for Int2VectorType @Eray Hanoğlu
- test: add coverage for the encodeText() pass-throughs on temporal types @Eray Hanoğlu
- test: raise large-object.ts coverage @Eray Hanoğlu
- test: raise prepared-statement.ts coverage @Eray Hanoğlu
- test: add full coverage for SafeEventEmitter @Eray Hanoğlu
- test: add full coverage for CharType @Eray Hanoğlu
- test: add full coverage for BoolType.encodeText() @Eray Hanoğlu

#### ⚡️ Performance Improvments

- perf: skip the instanceof check on plain string SQL in execute() @Eray Hanoğlu

## [v3.0.0](https://github.com/panates/postgrejs/compare/v2.23.1...v3.0.0) - 6 September 2026

#### Breaking Changes :warning:

- refactor: name data type methods decode* to pair with encode* @Eray Hanoğlu

#### 🚀 New Features

- feat: bulk import and export with COPY TO STDOUT / COPY FROM STDIN @Eray Hanoğlu
- feat: stream row changes with LogicalReplication @Eray Hanoğlu
- feat: build statements with the sql tag @Eray Hanoğlu
- feat: opt-in query pipelining for Pool.query() and Pool.execute() @Eray Hanoğlu
- feat: cancel queries and time them out with an AbortSignal @Eray Hanoğlu
- feat: large object API @Eray Hanoğlu
- feat: try several hosts and pick one by role @Eray Hanoğlu
- feat: SCRAM channel binding, and report what the server says when auth fails @Eray Hanoğlu
- feat: direct TLS negotiation, and only negotiate TLS when asked @Eray Hanoğlu
- feat: two-phase commit with prepareTransaction and commitPrepared @Eray Hanoğlu

#### 🪲 Fixes

- fix: jsonb text encoder wrote the binary version header, and add the last binary encoders @Eray Hanoğlu
- fix: oidvector was registered as a second array type of oid @Eray Hanoğlu
- fix: prototype pollution via a query result column named "__proto__" @Eray Hanoğlu
- fix: float4 precision loss and sslmode=prefer incorrectly requiring SSL @Eray Hanoğlu
- fix: numeric NaN/Infinity/-Infinity decode as 0 in binary format @Eray Hanoğlu
- fix: int4 OID auto-detection accepts values outside the 32-bit range @Eray Hanoğlu
- fix: preserve caller stack traces in async error handling @Eray Hanoğlu
- fix: PreparedStatement.close() not idempotent, re-sends CLOSE+SYNC @Eray Hanoğlu
- fix: midnight timestamps mis-detected as date instead of timestamp @Eray Hanoğlu
- fix: array literal parser treats apostrophe as a quote character @Eray Hanoğlu
- fix: TLS downgrade, credential decoding, and data-corruption bugs found in audit @Eray Hanoğlu
- fix: ParameterDescription parameter count read as Int32 instead of Int16 @Eray Hanoğlu
- fix: hang instead of an error when the server asks for GSSAPI or SSPI @Eray Hanoğlu
- fix: escapeLiteral silently passes through embedded NUL bytes @Eray Hanoğlu
- fix: char OID auto-detection matches multi-byte characters, crashing bind @Eray Hanoğlu
- fix: CopyInResponse message code is 'g' rather than 'G' @Eray Hanoğlu

#### 📖 Documentation Changes

- docs: record multi-host connections in the comparison @Eray Hanoğlu
- docs: count encoder and decoder coverage per wire format @Eray Hanoğlu
- docs: add a feature comparison table and correct stale claims @Eray Hanoğlu
- docs: record direct TLS negotiation, and drop the example section @Eray Hanoğlu
- docs: record class member order and loop-hoisting conventions @Eray Hanoğlu
- docs: native bindings are partial, not a plain yes @Eray Hanoğlu
- docs: correct two names in the comparison table @Eray Hanoğlu
- docs: record two-phase commit and drop the callback API row @Eray Hanoğlu

#### 🌸 Tidying of Code eg Whitespace

- style: sort imports and align a comment left over from the decode* rename @Eray Hanoğlu

#### ⚡️ Performance Improvments

- perf: rewrite the request/response pipeline and decode rows without per-column slices @Eray Hanoğlu
- perf: reassemble backend messages in one allocation instead of concatenating every chunk @Eray Hanoğlu

#### 💬 General Changes

- doc: Rebuild BENCHMARKS.md @Eray Hanoğlu
- doc: Updated README.md @Eray Hanoğlu
- dev: Removed unused `init-pg.ts`, adjusted imports, and updated path in tsconfig @Eray Hanoğlu
- doc: Remove outdated and unused badges from README.md @Eray Hanoğlu
- doc: correct grammar in connection.ts method comments @Eray Hanoğlu
- dev: Added CLAUDE.md with graphify usage rules @Eray Hanoğlu
- dev: Updated test matrix to include Node 26 and Postgres 18 @Eray Hanoğlu
- dev: Changed import extension for `env.js` in init-pg.ts @Eray Hanoğlu
- dev: Updated gitignore to include claude and graphify @Eray Hanoğlu
- dev: Broadened eslint disable rule in bigint-methods.ts @Eray Hanoğlu

### [v2.23.1](https://github.com/panates/postgrejs/compare/v2.23.0...v2.23.1) - 7 July 2026

#### 💬 General Changes

Expand Down
97 changes: 97 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
## Project Orientation

`postgrejs` is a from-scratch PostgreSQL wire-protocol client for Node.js/TypeScript - no `libpq`, no native
bindings. See README.md's "Why PostgreJS?" section for the pitch and `doc/BENCHMARKS.md` for performance data
against `pg` and `postgres.js`.

Directory layout:

- `src/protocol/` - the wire protocol itself: `Backend`/`Frontend` message codecs, `PgSocket` (the connected
socket plus auth/TLS negotiation), `SmartBuffer`/`BufferReader`.
- `src/connection/` - the public-facing layer: `Connection`, `Pool`, `IntlConnection` (the shared internals
`Connection`/`Pool` both wrap), `Cursor`, `PreparedStatement`, `Portal`, `CopyToStream`/`CopyFromStream`,
`LogicalReplication`, `LargeObject`.
- `src/data-types/` - one file per PostgreSQL type, each exporting a scalar `DataType` and its array counterpart
(`encodeBinary`/`decodeBinary`/`encodeText`/`decodeText`/`isType`, registered in `data-type-map.ts`).
- `src/util/` - parsing/encoding helpers used across the above (array literals, dates, buffers, etc).

Tests mirror this in `test/`:

- `test/A-common/` - pure unit tests, no live connection. Prefer this whenever the code under test doesn't
actually need a socket: build the wire bytes/fake dependency by hand rather than reaching for a live server.
- `test/B-connection/` - integration tests against a real local PostgreSQL (`docker/docker-compose.yml`; see
CONTRIBUTING.md for the SCRAM/MD5 setup needed for full coverage locally).
- `test/C-data-types/` - one file per data type, round-tripping values through a live connection via
`_testers.ts`'s `testParse`/`testEncode`.

Every change must come with a test, and the code it touches must be covered - see CONTRIBUTING.md for the full
contributor workflow (lint/compile/test commands, commit message convention, PR checklist).

## Testing Techniques

- **Coverage tool is `c8`, not istanbul.** Use `/* c8 ignore next */` or `/* c8 ignore start */` ... `/* c8 ignore
stop */` - `/* istanbul ignore next */` is silently not honored here. Even correctly-placed `c8 ignore` comments
have occasionally been observed not to suppress branch-level reporting on a single line with a ternary/`&&`
chain; if the coverage number doesn't move after adding one, don't fight it further - just leave a plain
explanatory comment instead of an ignore directive that isn't doing anything.
- **Classes that wrap a socket/connection** (`CopyToStream`, `CopyFromStream`, `LogicalReplication`, `PgSocket`)
are best unit-tested directly against a fake stub object (`pause`/`resume`/`sendCopyData`/`execute`/etc. as
plain functions recording calls) rather than racing real server timing to hit backpressure, mid-stream errors,
or a dead socket - those are reproducible instantly with a fake and flaky against a real one.
- **PostgreSQL version-gated behavior** must self-skip in CI's matrix (PostgreSQL 12/16/18 - see
`.github/workflows/test.yml`): check `connection.sessionParameters.server_version` and call `this.skip()` from
a `function () {}` test callback (not an arrow function - `this` binding is required). Known gates already hit:
`numeric` Infinity/-Infinity needs PG 14+, direct TLS negotiation needs PG 17+.
- **Before assuming a branch is unreachable**, reason through the actual call sites rather than guessing - it's
easy to be wrong in both directions (a branch that looks defensive can be reachable through a caller you
haven't checked yet, and vice versa).
- Dead code (an exported method with zero callers anywhere in `src/`) should be confirmed via
`grep -rn '\.methodName(' src/` and removed rather than tested, unless it's plausibly part of the public API
surface a consumer could rely on.

## Working in this repo

- Run `git status` before staging/committing. The user works concurrently in their own terminal on this same
repo sometimes (e.g. local docker setup files) - `git add <specific files>` still commits whatever else is
already sitting in the index, so an unrelated in-progress change can end up folded into your commit if you
don't check first.
- Don't run the full benchmark suite (`npm run bench`) unless asked.

## Code style

### Class member order

Declare members in this order, with non-public ones always at the bottom rather than next to the code that uses them:

1. Properties (private, protected, public order)
2. Constructor
3. Getters / setters
4. Public methods
5. Protected methods
6. Private methods

Prefer `protected` over `private`. Use `private` only when a member genuinely must not be reachable by a subclass — `Connection`, `Pool` and `IntlConnection` extend and wrap each other, so sealing a member closes off a real extension point.

### Loops

Hoist loop-invariant work out of the loop condition and body — `for (let i = 0; i < obj.length; i++)` re-reads the property on every iteration. V8 can only hoist it when the value is a plain array field and the body calls nothing opaque; anything behind a getter (`BufferReader.length`, `SmartBuffer.length`) or any body that calls a parser/decoder blocks that, which is most of this codebase's hot loops. Read it once into a local first:

```ts
const l = arr.length;
let i: number;
for (i = 0; i < l; i++) { ... }
```

The same applies to conditions that don't depend on the loop variable (`level < dim.length - 1`) — lift the whole comparison, not just the property read.

Declaring `let x` inside the loop body costs nothing when no closure captures it, so keep it scoped there; hoisting it only matters when a closure does capture it, and then hoisting would change behaviour anyway.

## graphify

This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.

Rules:
- For codebase questions, first run `graphify query "<question>"` when graphify-out/graph.json exists. Use `graphify path "<A>" "<B>"` for relationships and `graphify explain "<concept>"` for focused concepts. These return a scoped subgraph, usually much smaller than GRAPH_REPORT.md or raw grep output.
- If graphify-out/wiki/index.md exists, use it for broad navigation instead of raw source browsing.
- Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context.
- After modifying code, run `graphify update .` to keep the graph current (AST-only, no API cost).
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ representative at an online or offline event.

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
colinmcd94@gmail.com or scott@scotttrinh.com.
info@panates.com.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
Expand Down
Loading