postgrejs 2.23.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/CHANGELOG.md +152 -1
  2. package/LICENSE +26 -17
  3. package/README.md +195 -175
  4. package/connection/connection.d.ts +152 -13
  5. package/connection/connection.js +296 -49
  6. package/connection/copy-stream.d.ts +88 -0
  7. package/connection/copy-stream.js +244 -0
  8. package/connection/cursor.js +20 -13
  9. package/connection/intl-connection.d.ts +68 -3
  10. package/connection/intl-connection.js +414 -57
  11. package/connection/large-object.d.ts +65 -0
  12. package/connection/large-object.js +151 -0
  13. package/connection/logical-replication.d.ts +121 -0
  14. package/connection/logical-replication.js +279 -0
  15. package/connection/pool.d.ts +61 -4
  16. package/connection/pool.js +177 -29
  17. package/connection/portal.d.ts +18 -4
  18. package/connection/portal.js +53 -59
  19. package/connection/prepared-statement.d.ts +22 -1
  20. package/connection/prepared-statement.js +117 -97
  21. package/data-type-map.js +4 -2
  22. package/data-types/bool-type.js +14 -10
  23. package/data-types/box-type.js +15 -8
  24. package/data-types/bytea-type.js +9 -5
  25. package/data-types/char-type.js +11 -5
  26. package/data-types/circle-type.js +15 -7
  27. package/data-types/date-type.js +25 -19
  28. package/data-types/float4-type.js +10 -3
  29. package/data-types/float8-type.js +12 -3
  30. package/data-types/int2-type.js +9 -4
  31. package/data-types/int2-vector-type.js +9 -4
  32. package/data-types/int4-type.js +11 -5
  33. package/data-types/int8-type.js +22 -7
  34. package/data-types/json-type.js +17 -8
  35. package/data-types/jsonb-type.js +20 -14
  36. package/data-types/lseg-type.js +16 -8
  37. package/data-types/numeric-type.d.ts +8 -0
  38. package/data-types/numeric-type.js +112 -8
  39. package/data-types/oid-type.d.ts +0 -1
  40. package/data-types/oid-type.js +9 -10
  41. package/data-types/oid-vector-type.d.ts +9 -0
  42. package/data-types/oid-vector-type.js +51 -0
  43. package/data-types/point-type.js +14 -6
  44. package/data-types/time-type.js +20 -13
  45. package/data-types/timestamp-type.js +32 -25
  46. package/data-types/timestamptz-type.js +33 -21
  47. package/data-types/uuid-type.js +21 -11
  48. package/data-types/varchar-type.js +16 -4
  49. package/index.d.ts +5 -0
  50. package/index.js +5 -0
  51. package/interfaces/data-type.d.ts +5 -3
  52. package/interfaces/database-connection-params.d.ts +95 -0
  53. package/interfaces/query-options.d.ts +17 -0
  54. package/interfaces/script-execute-options.d.ts +17 -0
  55. package/package.json +2 -3
  56. package/protocol/backend.d.ts +6 -1
  57. package/protocol/backend.js +70 -45
  58. package/protocol/buffer-reader.d.ts +0 -2
  59. package/protocol/buffer-reader.js +3 -10
  60. package/protocol/cert-signature.d.ts +12 -0
  61. package/protocol/cert-signature.js +114 -0
  62. package/protocol/frontend.d.ts +16 -0
  63. package/protocol/frontend.js +57 -6
  64. package/protocol/pg-socket.d.ts +220 -9
  65. package/protocol/pg-socket.js +539 -102
  66. package/protocol/pgoutput.d.ts +76 -0
  67. package/protocol/pgoutput.js +155 -0
  68. package/protocol/protocol.d.ts +3 -4
  69. package/protocol/protocol.js +1 -1
  70. package/protocol/sasl.d.ts +11 -1
  71. package/protocol/sasl.js +35 -4
  72. package/protocol/smart-buffer.d.ts +0 -2
  73. package/protocol/smart-buffer.js +11 -16
  74. package/types.d.ts +5 -3
  75. package/util/abort-signal.d.ts +24 -0
  76. package/util/abort-signal.js +63 -0
  77. package/util/array-calculatedim.js +3 -1
  78. package/util/connection-config.js +77 -3
  79. package/util/decode-binaryarray.d.ts +1 -1
  80. package/util/decode-binaryarray.js +15 -6
  81. package/util/encode-binaryarray.js +7 -3
  82. package/util/escape-identifier.d.ts +14 -0
  83. package/util/escape-identifier.js +32 -0
  84. package/util/escape-literal.js +3 -0
  85. package/util/fast-parseint.d.ts +1 -0
  86. package/util/fast-parseint.js +12 -17
  87. package/util/format-datetime.d.ts +10 -0
  88. package/util/format-datetime.js +71 -0
  89. package/util/get-parsers.js +31 -10
  90. package/util/parse-array.js +2 -2
  91. package/util/parse-bytea.d.ts +2 -0
  92. package/util/parse-bytea.js +83 -0
  93. package/util/parse-datetime.d.ts +3 -1
  94. package/util/parse-datetime.js +86 -17
  95. package/util/parse-row.d.ts +3 -1
  96. package/util/parse-row.js +60 -5
  97. package/util/parse-time.js +8 -1
  98. package/util/sql-tag.d.ts +60 -0
  99. package/util/sql-tag.js +202 -0
  100. package/util/starts-transaction.d.ts +38 -0
  101. package/util/starts-transaction.js +148 -0
  102. package/util/stringify-arrayliteral.js +13 -1
  103. package/util/wrap-row-description.js +13 -4
  104. package/util/convert-row-to-object.d.ts +0 -2
  105. package/util/convert-row-to-object.js +0 -9
package/CHANGELOG.md CHANGED
@@ -1,6 +1,157 @@
1
1
  ## Changelog
2
2
 
3
- ### [v2.23.1](https://github.com/panates/postgrejs/compare/v2.23.0...v2.23.1) -
3
+ ### [v3.0.1](https://github.com/panates/postgrejs/compare/v3.0.0...v3.0.1) -
4
+
5
+ - Dev
6
+ - Dev
7
+ - Dev
8
+ - Dev
9
+ - dev: Removed path filter
10
+ - Dev
11
+ - Dev
12
+ - fix missing quotes in exception
13
+ - Don't fail if husky is not present
14
+ - Dev
15
+ - Dev
16
+
17
+ #### 🚀 New Features
18
+
19
+ - feat: make async caller-stack capture an opt-out, per-call overridable option @Eray Hanoğlu
20
+ - feat: exact-match --scenario/--lib by default, glob with a leading/trailing * @Eray Hanoğlu
21
+
22
+ #### 🪲 Fixes
23
+
24
+ - fix: LISTEN dropped for extra channels, lost after Pool reconnect, double 'close' emit @Eray Hanoğlu
25
+ - fix: cancel() ignored multi-host failover and direct TLS negotiation @Eray Hanoğlu
26
+ - fix: default omitted day-of-month to 1, not 0, when parsing dates @Eray Hanoğlu
27
+ - fix: numeric encodeBinary() silently corrupts magnitudes >= 1e21 @Eray Hanoğlu
28
+ - fix: benchmark console summary leaked every scenario ever run @Eray Hanoğlu
29
+ - fix: LogicalReplication.close() never actually drops a permanent slot it created @Eray Hanoğlu
30
+ - fix: JsonType.encodeText() throws on a bigint value @Eray Hanoğlu
31
+ - fix: restore execute()'s timing, and switch it to performance.now() @Eray Hanoğlu
32
+ - fix: skip numeric Infinity/-Infinity tests on PostgreSQL < 14 @Eray Hanoğlu
33
+ - fix: skip direct-negotiation SSL test on PostgreSQL < 17 @Eray Hanoğlu
34
+ - fix: avoid a rare race in the cancel() test's own cleanup @Eray Hanoğlu
35
+ - fix: correct stale contact and copyright holder in project docs @Eray Hanoğlu
36
+ - fix: header link/image attributes in README @Eray Hanoğlu
37
+
38
+ #### 📖 Documentation Changes
39
+
40
+ - docs: rewrite benchmark scenario descriptions as readable paragraphs @Eray Hanoğlu
41
+ - docs: capitalize PostgreJS consistently, rebuild BENCHMARKS.md for 3.0.0 @Eray Hanoğlu
42
+ - docs: add a v2-to-v3 migration guide @Eray Hanoğlu
43
+ - docs: expand CONTRIBUTING.md with a full contributor workflow @Eray Hanoğlu
44
+ - docs: rewrite README intro to lead with speed, memory, and features @Eray Hanoğlu
45
+ - docs: expand CLAUDE.md with project orientation and testing techniques @Eray Hanoğlu
46
+ - docs: tailor issue templates to a PostgreSQL driver @Eray Hanoğlu
47
+ - docs: document local SCRAM/MD5 test setup in CONTRIBUTING.md @Eray Hanoğlu
48
+
49
+ #### 🛠 Refactoring and Updates
50
+
51
+ - refactor: remove dead Portal/PgSocket message-send methods @Eray Hanoğlu
52
+ - refactor: remove dead SmartBuffer.fill(), add full coverage @Eray Hanoğlu
53
+ - refactor: remove dead BufferReader.moveBy()/moveTo(), add full coverage @Eray Hanoğlu
54
+
55
+ #### 🧪 Changes to Test Assests
56
+
57
+ - test: cover pure utility functions, wire-protocol messages, and SASL/cert parsing @Eray Hanoğlu
58
+ - test: add full coverage for copy-stream.ts @Eray Hanoğlu
59
+ - test: add full coverage for the pgoutput logical-replication decoder @Eray Hanoğlu
60
+ - test: add direct unit coverage for LogicalReplication's pure logic @Eray Hanoğlu
61
+ - test: add full coverage for the remaining small scalar data types @Eray Hanoğlu
62
+ - test: add full coverage for frontend.ts wire-message builders @Eray Hanoğlu
63
+ - test: add full coverage for parse-row.ts @Eray Hanoğlu
64
+ - test: add full coverage for get-parsers.ts @Eray Hanoğlu
65
+ - test: add full coverage for LsegType @Eray Hanoğlu
66
+ - test: add full coverage for CircleType @Eray Hanoğlu
67
+ - test: raise connection-config.ts branch coverage @Eray Hanoğlu
68
+ - test: raise sql-tag.ts branch coverage, mark one path unreachable @Eray Hanoğlu
69
+ - test: raise cursor.ts coverage @Eray Hanoğlu
70
+ - test: add full coverage for OidVectorType @Eray Hanoğlu
71
+ - test: add full coverage for Int2VectorType @Eray Hanoğlu
72
+ - test: add coverage for the encodeText() pass-throughs on temporal types @Eray Hanoğlu
73
+ - test: raise large-object.ts coverage @Eray Hanoğlu
74
+ - test: raise prepared-statement.ts coverage @Eray Hanoğlu
75
+ - test: add full coverage for SafeEventEmitter @Eray Hanoğlu
76
+ - test: add full coverage for CharType @Eray Hanoğlu
77
+ - test: add full coverage for BoolType.encodeText() @Eray Hanoğlu
78
+
79
+ #### ⚡️ Performance Improvments
80
+
81
+ - perf: skip the instanceof check on plain string SQL in execute() @Eray Hanoğlu
82
+
83
+ ## [v3.0.0](https://github.com/panates/postgrejs/compare/v2.23.1...v3.0.0) - 6 September 2026
84
+
85
+ #### Breaking Changes :warning:
86
+
87
+ - refactor: name data type methods decode* to pair with encode* @Eray Hanoğlu
88
+
89
+ #### 🚀 New Features
90
+
91
+ - feat: bulk import and export with COPY TO STDOUT / COPY FROM STDIN @Eray Hanoğlu
92
+ - feat: stream row changes with LogicalReplication @Eray Hanoğlu
93
+ - feat: build statements with the sql tag @Eray Hanoğlu
94
+ - feat: opt-in query pipelining for Pool.query() and Pool.execute() @Eray Hanoğlu
95
+ - feat: cancel queries and time them out with an AbortSignal @Eray Hanoğlu
96
+ - feat: large object API @Eray Hanoğlu
97
+ - feat: try several hosts and pick one by role @Eray Hanoğlu
98
+ - feat: SCRAM channel binding, and report what the server says when auth fails @Eray Hanoğlu
99
+ - feat: direct TLS negotiation, and only negotiate TLS when asked @Eray Hanoğlu
100
+ - feat: two-phase commit with prepareTransaction and commitPrepared @Eray Hanoğlu
101
+
102
+ #### 🪲 Fixes
103
+
104
+ - fix: jsonb text encoder wrote the binary version header, and add the last binary encoders @Eray Hanoğlu
105
+ - fix: oidvector was registered as a second array type of oid @Eray Hanoğlu
106
+ - fix: prototype pollution via a query result column named "__proto__" @Eray Hanoğlu
107
+ - fix: float4 precision loss and sslmode=prefer incorrectly requiring SSL @Eray Hanoğlu
108
+ - fix: numeric NaN/Infinity/-Infinity decode as 0 in binary format @Eray Hanoğlu
109
+ - fix: int4 OID auto-detection accepts values outside the 32-bit range @Eray Hanoğlu
110
+ - fix: preserve caller stack traces in async error handling @Eray Hanoğlu
111
+ - fix: PreparedStatement.close() not idempotent, re-sends CLOSE+SYNC @Eray Hanoğlu
112
+ - fix: midnight timestamps mis-detected as date instead of timestamp @Eray Hanoğlu
113
+ - fix: array literal parser treats apostrophe as a quote character @Eray Hanoğlu
114
+ - fix: TLS downgrade, credential decoding, and data-corruption bugs found in audit @Eray Hanoğlu
115
+ - fix: ParameterDescription parameter count read as Int32 instead of Int16 @Eray Hanoğlu
116
+ - fix: hang instead of an error when the server asks for GSSAPI or SSPI @Eray Hanoğlu
117
+ - fix: escapeLiteral silently passes through embedded NUL bytes @Eray Hanoğlu
118
+ - fix: char OID auto-detection matches multi-byte characters, crashing bind @Eray Hanoğlu
119
+ - fix: CopyInResponse message code is 'g' rather than 'G' @Eray Hanoğlu
120
+
121
+ #### 📖 Documentation Changes
122
+
123
+ - docs: record multi-host connections in the comparison @Eray Hanoğlu
124
+ - docs: count encoder and decoder coverage per wire format @Eray Hanoğlu
125
+ - docs: add a feature comparison table and correct stale claims @Eray Hanoğlu
126
+ - docs: record direct TLS negotiation, and drop the example section @Eray Hanoğlu
127
+ - docs: record class member order and loop-hoisting conventions @Eray Hanoğlu
128
+ - docs: native bindings are partial, not a plain yes @Eray Hanoğlu
129
+ - docs: correct two names in the comparison table @Eray Hanoğlu
130
+ - docs: record two-phase commit and drop the callback API row @Eray Hanoğlu
131
+
132
+ #### 🌸 Tidying of Code eg Whitespace
133
+
134
+ - style: sort imports and align a comment left over from the decode* rename @Eray Hanoğlu
135
+
136
+ #### ⚡️ Performance Improvments
137
+
138
+ - perf: rewrite the request/response pipeline and decode rows without per-column slices @Eray Hanoğlu
139
+ - perf: reassemble backend messages in one allocation instead of concatenating every chunk @Eray Hanoğlu
140
+
141
+ #### 💬 General Changes
142
+
143
+ - doc: Rebuild BENCHMARKS.md @Eray Hanoğlu
144
+ - doc: Updated README.md @Eray Hanoğlu
145
+ - dev: Removed unused `init-pg.ts`, adjusted imports, and updated path in tsconfig @Eray Hanoğlu
146
+ - doc: Remove outdated and unused badges from README.md @Eray Hanoğlu
147
+ - doc: correct grammar in connection.ts method comments @Eray Hanoğlu
148
+ - dev: Added CLAUDE.md with graphify usage rules @Eray Hanoğlu
149
+ - dev: Updated test matrix to include Node 26 and Postgres 18 @Eray Hanoğlu
150
+ - dev: Changed import extension for `env.js` in init-pg.ts @Eray Hanoğlu
151
+ - dev: Updated gitignore to include claude and graphify @Eray Hanoğlu
152
+ - dev: Broadened eslint disable rule in bigint-methods.ts @Eray Hanoğlu
153
+
154
+ ### [v2.23.1](https://github.com/panates/postgrejs/compare/v2.23.0...v2.23.1) - 7 July 2026
4
155
 
5
156
  #### 💬 General Changes
6
157
 
package/LICENSE CHANGED
@@ -1,21 +1,30 @@
1
- MIT License
1
+ BSD 3-Clause License
2
2
 
3
- Copyright (c) 2020 Panates, Eray Hanoglu
3
+ Copyright (c) 2020 Panates
4
+ All rights reserved.
4
5
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
11
8
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
9
+ 1. Redistributions of source code must retain the above copyright notice,
10
+ this list of conditions and the following disclaimer.
14
11
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
12
+ 2. Redistributions in binary form must reproduce the above copyright
13
+ notice, this list of conditions and the following disclaimer in the
14
+ documentation and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ POSSIBILITY OF SUCH DAMAGE.
package/README.md CHANGED
@@ -1,53 +1,49 @@
1
1
  <!--suppress HtmlDeprecatedAttribute -->
2
- <p align="center">¨
3
- <a href="https://postgrejs.panates.com/" target="blank">
4
- <img src="https://postgrejs.panates.com/img/postgrejs-header-block.png" width="800" alt="PostgreJS Logo" />
2
+ <p align="center">
3
+ <a href="https://postgrejs.panates.com/" target="_blank" rel="noopener noreferrer">
4
+ <img src="https://postgrejs.panates.com/img/postgrejs-header-block.png" width="800" height="446" alt="PostgreJS Logo" />
5
5
  </a>
6
6
  </p>
7
-
7
+
8
8
  [![NPM Version][npm-image]][npm-url]
9
9
  [![NPM Downloads][downloads-image]][downloads-url]
10
10
  [![CI Tests][ci-test-image]][ci-test-url]
11
11
  [![Test Coverage][coveralls-image]][coveralls-url]
12
12
 
13
+ ## Why PostgreJS?
13
14
 
14
- PostgreJS is an enterprise-level PostgreSQL client for Node.js.
15
- It is designed to provide a robust and efficient interface to PostgreSQL databases,
16
- ensuring high performance and reliability for enterprise applications.
17
- Written entirely in TypeScript, it leverages modern JavaScript features to deliver a seamless development experience.
18
-
15
+ **PostgreJS** is a PostgreSQL driver for Node.js built from the wire protocol up - no `libpq`, no native bindings,
16
+ just TypeScript talking directly to PostgreSQL. That from-scratch design is also what makes it fast and light: every
17
+ byte on the wire is handled by code written for exactly that purpose, with a binary-first protocol, shared buffers,
18
+ and row/column decoding pipelines built to avoid unnecessary allocation, instead of generic string plumbing bolted
19
+ onto a client meant for text.
19
20
 
20
- ## Library Overview
21
+ ### ⚡ Blazing Fast
21
22
 
22
- PostgreJS is a pure JavaScript library, meticulously crafted with TypeScript to offer a strictly typed, well-structured,
23
- and highly maintainable codebase.
24
- Key highlights include:
23
+ The numbers back it up. In PostgreJS's own benchmark suite - run head-to-head against
24
+ [`pg`](https://github.com/brianc/node-postgres) (node-postgres) and [`postgres`](https://github.com/porsager/postgres)
25
+ (postgres.js) on identical workloads - PostgreJS opens a connection up to **3x faster** than postgres.js and
26
+ **2x faster** than pg, pushes pooled queries through up to **6.6x faster** than postgres.js, and fetches large
27
+ result sets nearly **5x faster** than pg. It's also the only one of the three with a complete binary wire protocol
28
+ across every data type, rather than falling back to text for most of them. See
29
+ [`doc/BENCHMARKS.md`](doc/BENCHMARKS.md) for the full methodology and every scenario.
25
30
 
26
- - **Language:** Pure modern JavaScript library.
27
- - **Strictly Typed:** Completely written in TypeScript, offering strong typing and enhanced development experience.
28
- - **Compatibility:** Works seamlessly with both CommonJS and ESM module systems, ensuring flexibility in various project setups.
29
- - **Comprehensive Testing:** Rigorously tested to ensure stability and reliability in production environments.
30
- - **Promise-Based API:** Asynchronous operations are handled with a Promise-based API, promoting clean and efficient asynchronous code.
31
-
32
- ## Features
31
+ ### 🪶 Small Footprint
33
32
 
34
- - **Connection Management:** Supports both single connection and advanced pooling, providing scalability and efficient resource management.
35
- - **Binary Wire Protocol:** Implements the full binary wire protocol for all PostgreSQL data types, ensuring robust and efficient data handling.
36
- - **Prepared Statements:** Named prepared statements for optimized query execution.
37
- - **Cursors:** Features fast double-link cache cursors for efficient data retrieval.
38
- - **Notifications:** High-level implementation for PostgreSQL notifications (LISTEN/NOTIFY), enabling real-time data updates.
39
- - **Extensibility:** Extensible data-types and type mapping to accommodate custom requirements.
40
- - **Parameter Binding:** Bind parameters with OID mappings for precise and efficient query execution.
41
- - **Array Handling:** Supports multidimensional arrays with fast binary encoding/decoding.
42
- - **Performance Optimization:** Low memory utilization and boosted performance through the use of shared buffers.
43
- - **Authorization:** SSupports various password algorithms including Clear text, MD5, and SASL, ensuring secure authentication.
44
- - **Flexible Data Retrieval:** Can return both array and object rows to suit different data processing needs.
45
- - **Resource Management:** Auto disposal of resources with the "using" syntax ([TC30 Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management)), ensuring efficient resource cleanup.
33
+ The same benchmarks show it using a fraction of the memory: peak heap usage typically runs **3-7x lower** than both
34
+ pg and postgres.js - as much as **7x lower** when streaming cursors or fetching large arrays - and it spends a
35
+ fraction of the time either of them does in garbage collection. Shared buffers and decode paths that read values
36
+ straight out of the wire buffer leave far less garbage behind per row, so there's less for the GC to clean up in
37
+ the first place.
46
38
 
47
- Whether you're building a simple application or a complex enterprise system,
48
- PostgreJS provides the features and performance you need to succeed.
49
- Explore the capabilities of the library and elevate your PostgreSQL integration to the next level.
39
+ ### 🔋 Batteries Included
50
40
 
41
+ Speed and memory aside, PostgreJS is also the most complete driver of the three: a dynamic `sql` tag for
42
+ composable, parameterized SQL, per-query type mapping, and TC39 Explicit Resource Management (`using`) support are
43
+ unique to it, alongside a feature set most drivers spread across several add-on packages - connection pooling,
44
+ prepared statements, server-side cursors, LISTEN/NOTIFY, bulk `COPY` streams, logical replication, large objects,
45
+ two-phase commit, multi-host failover, and SCRAM channel binding - all in the one package, written in
46
+ strictly-typed TypeScript from the ground up.
51
47
 
52
48
  ## Installation
53
49
 
@@ -56,161 +52,185 @@ $ npm install postgrejs --save
56
52
  ```
57
53
 
58
54
  ## Documentation
59
- Please read :small_orange_diamond: [DOCUMENTATION](https://postgrejs.panates.com/) :small_orange_diamond: for detailed usage.
60
-
61
- ## Example usage
62
-
63
- ### Establish a single connection, execute a simple query
64
55
 
65
- ```ts
66
- import { Connection } from 'postgrejs';
67
- // Create connection
68
- const connection = new Connection('postgres://localhost');
69
- // Connect to database server
70
- await connection.connect();
56
+ Please read :small_orange_diamond: [DOCUMENTATION](https://postgrejs.panates.com/) :small_orange_diamond: for detailed
57
+ usage.
71
58
 
72
- // Execute query and fetch rows
73
- const result = await connection.query(
74
- 'select * from cities where name like $1',
75
- {params: ['%york%']});
76
- const rows: any[] = result.rows;
77
- // Do what ever you want with rows
78
-
79
- // Disconnect from server
80
- await connection.close();
81
- ```
59
+ ## Library Overview
82
60
 
83
- ### Establish a pooled connection, create a cursor
84
- ```ts
85
- import { Pool } from 'postgrejs';
86
-
87
- // Create connection pool
88
- const db = new Pool({
89
- host: 'postgres://localhost',
90
- pool: {
91
- min: 1,
92
- max: 10,
93
- idleTimeoutMillis: 5000
94
- }
95
- });
96
-
97
- // Execute query and fetch cursor
98
- const result = await db.query(
99
- 'select * from cities where name like $1',
100
- {params: ['%york%'], cursor: true});
101
-
102
- // Walk through the cursor, and do whatever you want with fetched rows
103
- const cursor = result.cursor;
104
- let row;
105
- while ((row = await cursor.next())) {
106
- console.log(row);
107
- }
108
- // Close cursor, (Send connection back to the pool)
109
- await cursor.close();
110
-
111
- // Disconnect all connections and shutdown pool
112
- await db.close();
113
- ```
61
+ - **Language:** Pure JavaScript, with no native/binary dependencies to compile or ship.
62
+ - **Strictly typed:** Written entirely in TypeScript, with types shipped alongside the package.
63
+ - **Modern module format:** Ships as ESM; Node 20.19+/22.12+ can `require()` it from CommonJS code as well.
64
+ - **Promise-based API:** Every asynchronous operation returns a promise - no callbacks to wrangle.
65
+ - **Rigorously tested:** A test suite covering the wire protocol, every data type, and connection-handling edge case,
66
+ run on every push against PostgreSQL 12 through 18.
114
67
 
115
- ### Using prepared statements
116
- ```ts
117
- import { DataTypeOIDs } from 'postgrejs';
68
+ ## Features
118
69
 
119
- // .....
120
- const statement = await connection.prepare(
121
- 'insert into my_table(id, name) values ($1, $2)', {
122
- paramTypes: [DataTypeOIDs.Int4, DataTypeOIDs.Varchar]
123
- });
70
+ - **Connection Management:** Supports both single connection and advanced pooling, providing scalability and efficient
71
+ resource management.
72
+ - **Binary Wire Protocol:** Implements the full binary wire protocol for all PostgreSQL data types, ensuring robust and
73
+ efficient data handling.
74
+ - **Prepared Statements:** Named prepared statements for optimized query execution.
75
+ - **Cursors:** Features fast double-link cache cursors for efficient data retrieval.
76
+ - **Notifications:** High-level implementation for PostgreSQL notifications (LISTEN/NOTIFY), enabling real-time data
77
+ updates.
78
+ - **Extensibility:** Extensible data-types and type mapping to accommodate custom requirements.
79
+ - **Parameter Binding:** Bind parameters with OID mappings for precise and efficient query execution.
80
+ - **Array Handling:** Supports multidimensional arrays with fast binary encoding/decoding.
81
+ - **Performance Optimization:** Low memory utilization and boosted performance through the use of shared buffers.
82
+ - **Authorization:** Supports various password algorithms including Clear text, MD5, and SASL, ensuring secure
83
+ authentication.
84
+ - **Bulk Import/Export:** `COPY TO STDOUT` and `COPY FROM STDIN` as Node streams, with backpressure in both directions.
85
+ - **Query Pipelining:** Pooled queries can share connections so a burst is not capped by pool size - opt-in per call.
86
+ - **Dynamic SQL:** A `sql` tag builds statements from composable fragments - values become parameters, names are quoted,
87
+ and `sql.values()`/`sql.set()` write INSERT and UPDATE clauses from objects.
88
+ - **Multiple Hosts:** A connection can list several servers and pick one by role
89
+ (`target_session_attrs`), so a cluster that has failed over is found on the next connect.
90
+ - **Large Objects:** File-like access to binary data stored outside the row - seek, partial reads, streams - for
91
+ values past what a `bytea` column can hold.
92
+ - **Logical Replication:** `LogicalReplication` streams committed row changes as an async iterable, decoding
93
+ `pgoutput` itself, with client-side filtering and positions confirmed as you consume.
94
+ - **Channel Binding:** SCRAM authentication binds itself to the TLS channel when the server offers it, the way libpq
95
+ does by default, so a relayed login is detected even where the certificate is not verified.
96
+ - **Two-phase commit:** `prepareTransaction()` leaves a transaction waiting under a name for `commitPrepared()`/
97
+ `rollbackPrepared()`, from any connection.
98
+ - **Cancellation:** Any call takes an `AbortSignal`, which also gives per-query timeouts via `AbortSignal.timeout()`.
99
+ - **Flexible Data Retrieval:** Can return both array and object rows to suit different data processing needs.
100
+ - **Resource Management:** Auto disposal of resources with the "using" syntax
101
+ ([TC39 Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management)), ensuring
102
+ efficient resource cleanup.
103
+
104
+ ## Feature Comparison
105
+
106
+ How PostgreJS compares to [`pg`](https://github.com/brianc/node-postgres) (node-postgres) and
107
+ [`postgres`](https://github.com/porsager/postgres) (postgres.js). Every row was checked against the libraries' own
108
+ source rather than their documentation — versions compared: **PostgreJS 2.23.1, pg 8.23.0, postgres.js 3.4.9**. ✅ built
109
+ in · 🟡 partial or needs a separate package · ❌ not supported.
110
+
111
+ | Feature | PostgreJS | pg | postgres.js |
112
+ |:---------------------------------|:----------------------:|:-------------------:|:----------------:|
113
+ | ***Packaging*** | | | |
114
+ | Packages to install | 1 | 4 <sup>1</sup> | 1 |
115
+ | Module system | ESM | ESM/CJS | ESM/CJS |
116
+ | Language | TS | JS <sup>2</sup> | JS <sup>3</sup> |
117
+ | ***Wire protocol*** | | | |
118
+ | Simple Query protocol | ✅ | ✅ | ✅ |
119
+ | Extended Query protocol | ✅ | ✅ | ✅ |
120
+ | Text wire format | ✅ | ✅ | ✅ |
121
+ | Binary wire format | ✅ | 🟡 <sup>4</sup> | ❌ <sup>5</sup> |
122
+ | Per-column format selection | ✅ | ❌ | ❌ |
123
+ | ***High-level API*** | | | |
124
+ | Object and array row modes | ✅ | ✅ | ✅ |
125
+ | Dynamic SQL helpers | ✅ `sql` tag | ❌ | ✅ |
126
+ | Per-query type mapping | ✅ | ❌ <sup>6</sup> | ❌ <sup>6</sup> |
127
+ | Query cancellation | ✅ AbortSignal | ✅ | ✅ |
128
+ | Per-query timeout | ✅ AbortSignal | ✅ | ❌ <sup>7</sup> |
129
+ | Reference counters | Connection · Statement | ❌ | ❌ |
130
+ | Caller kept in async error stacks | ✅ | 🟡 <sup>8</sup> | 🟡 <sup>9</sup> |
131
+ | Error located in the SQL text | ✅ line and mark | 🟡 offset | 🟡 offset |
132
+ | TC39 Explicit Resource Management | ✅ | ❌ | ❌ |
133
+ | ***Querying*** | | | |
134
+ | Query parameters | ✅ | ✅ | ✅ |
135
+ | Parameter type casting | ✅ | 🟡 <sup>10</sup> | ✅ |
136
+ | Prepared statements | ✅ explicit | ✅ | ✅ automatic |
137
+ | Multi-statement scripts | ✅ | ✅ | ✅ |
138
+ | Server-side cursors | ✅ | 🟡 <sup>11</sup> | ✅ |
139
+ | `COPY TO` / `COPY FROM` | ✅ | 🟡 <sup>12</sup> | ✅ |
140
+ | Row count after a COPY | ✅ | ✅ | ❌ |
141
+ | ***Transaction management*** | | | |
142
+ | Transaction API | ✅ | ❌ | ✅ |
143
+ | Savepoints | ✅ | ❌ | ✅ |
144
+ | Two-phase commit API | ✅ | ❌ | 🟡 <sup>13</sup> |
145
+ | ***Session management*** | | | |
146
+ | Built-in connection pool | ✅ | ✅ | ✅ implicit |
147
+ | Pipelining on one connection | ✅ opt-in/call | ✅ opt-in/client | ✅ automatic |
148
+ | Graceful shutdown | ✅ | ❌ <sup>14</sup> | ✅ |
149
+ | Multiple hosts | ✅ | ❌ | ✅ |
150
+ | LISTEN/NOTIFY | ✅ | 🟡 <sup>15</sup> | ✅ |
151
+ | ***Data types*** | | | |
152
+ | Text encoders | 56 | generic <sup>16</sup> | 14 |
153
+ | Text decoders | 56 | 44 | 12 <sup>17</sup> |
154
+ | Binary encoders | 56 | ❌ | ❌ |
155
+ | Binary decoders | 56 | 16 | ❌ |
156
+ | Multidimensional arrays | ✅ binary | 🟡 text <sup>18</sup> | 🟡 text |
157
+ | ***Security*** | | | |
158
+ | SSL/TLS | ✅ | ✅ | ✅ |
159
+ | Direct TLS negotiation (PG17) | ✅ | ✅ | ✅ |
160
+ | Cleartext, MD5, SCRAM-SHA-256 | ✅ | ✅ | ✅ |
161
+ | SCRAM channel binding (`-PLUS`) | ✅ default | ✅ opt-in | ❌ |
162
+ | ***Beyond querying*** | | | |
163
+ | Logical replication | ✅ | 🟡 <sup>19</sup> | ✅ |
164
+ | Large object API | ✅ | ❌ | ✅ |
165
+ | Native libpq bindings | ❌ | 🟡 <sup>20</sup> | ❌ |
166
+
167
+ - <sup>1</sup> What it takes to reach the feature set above. PostgreJS and postgres.js ship everything in the one
168
+ package you import; `pg` needs `pg-cursor` for cursors, `pg-query-stream`
169
+ for row streams and `pg-copy-streams` for COPY, each installed and versioned separately.
170
+ - <sup>2</sup> Types come from the separate `@types/pg`; only the `pg-protocol` and
171
+ `pg-connection-string` sub-packages are written in TypeScript.
172
+ - <sup>3</sup> Ships a hand-maintained `.d.ts`.
173
+ - <sup>4</sup> Results only - parameters are always stringified. Opt-in per query or per client, and all columns at
174
+ once. No binary parser is registered for `bytea`, and binary arrays decode only `int4`, `int8` and `text` elements.
175
+ - <sup>5</sup> Both format-code counts are hardcoded to zero and parameters are stringified, so everything on the wire
176
+ is text.
177
+ - <sup>6</sup> Global or per-client (pg) and per-instance (postgres.js), but not per query.
178
+ - <sup>7</sup> Connection-level timeouts only.
179
+ - <sup>8</sup> Restored by calling `Error.captureStackTrace` from the promise's own rejection handler, where the
180
+ synchronous stack is already gone - the caller's frames come from Node's async stack traces, so they survive an
181
+ awaited chain but not a `.then()`/`.catch()` one, and the callback API gets none at all.
182
+ - <sup>9</sup> Captured at the tagged template, four frames deep; `sql.unsafe()` gets none.
183
+ - <sup>10</sup> A `types` array on the query config does reach the Parse message, but the same field doubles as the
184
+ result parser override, so any row-returning query throws inside pg's own handler. Verified usable only for statements
185
+ that return no rows (pg 8.23.0).
186
+ - <sup>11</sup> Core has the row-limit primitive; the cursor and stream APIs are separate packages.
187
+ - <sup>12</sup> The core `Query` refuses COPY IN; `pg-copy-streams` is required.
188
+ - <sup>13</sup> `sql.prepare(name)` runs `PREPARE TRANSACTION` inside `begin`, but there is no helper for the other
189
+ half - `COMMIT PREPARED` / `ROLLBACK PREPARED` have to be written as raw SQL.
190
+ - <sup>14</sup> `end()` destroys the socket when a query is still in flight, so the query is aborted rather than
191
+ awaited; only a client in pipeline mode waits for drain first.
192
+ - <sup>15</sup> On the client only - the pool does not forward notifications.
193
+ - <sup>16</sup> pg has no per-OID text encoders: a parameter is converted by its
194
+ JavaScript type rather than by the type it is going into, so there is no
195
+ count to give.
196
+ - <sup>17</sup> Plus every array type, whose OIDs are read from the catalog when a
197
+ connection opens rather than registered ahead of time.
198
+ - <sup>18</sup> Its binary array decoder covers only `int4`, `int8` and `text` elements, so everything else falls back to
199
+ text anyway.
200
+ - <sup>19</sup> A connection flag exists, but nothing decodes the stream.
201
+ - <sup>20</sup> `pg-native` swaps the pure JavaScript protocol for libpq, and its own
202
+ documentation lists what stops working with it: `pg-cursor`, `pg-query-stream` and
203
+ `pg-copy-streams` all "operate directly on the binary stream and therefore are
204
+ incompatible" - so server-side cursors, row streaming and COPY are what it costs.
205
+
206
+
207
+ ## Benchmarks
208
+
209
+ PostgreJS implements the full PostgreSQL wire protocol from scratch, with no dependency on `pg`/libpq.
210
+ [`doc/BENCHMARKS.md`](doc/BENCHMARKS.md) compares it against `pg` (node-postgres) and `postgres` (postgres.js)
211
+ across connection setup, simple/prepared queries, mixed-type decoding, bulk fetches, cursor streaming and pool
212
+ concurrency, each library run through its own idiomatic fast path. The numbers there are reproducible on your own
213
+ machine via `npm run bench` against the repo's own
214
+ `docker/docker-compose.yml` Postgres instance; see [`benchmark/README.md`](./benchmark/README.md) for details.
124
215
 
125
- for (let i = 0; i < 100; i++) {
126
- await statement.execute({params: [i, ('name' + i)]});
127
- }
128
- await statement.close(); // When you done, close the statement to relase resources
129
- ```
216
+ ## Support
130
217
 
131
- #### Check [DOCUMENTATION](https://postgrejs.panates.com/) for other examples.
132
-
133
-
134
-
135
- ## Type mappings
136
- The table below lists builtin data type mappings.
137
-
138
- | PosgtreSQL type | JS type | Receive | Send |
139
- |-----------------|:------------|-------------|--------|
140
- | bool | boolean | text,binary | binary |
141
- | int2 | number | text,binary | binary |
142
- | int4 | number | text,binary | binary |
143
- | int8 | BigInt | text,binary | binary |
144
- | float4 | number | text,binary | binary |
145
- | float8 | number | text,binary | binary |
146
- | char | string | text,binary | binary |
147
- | bpchar | string | text,binary | binary |
148
- | varchar | string | text,binary | binary |
149
- | date | Date | text,binary | binary |
150
- | time | Date | text,binary | binary |
151
- | timestamp | Date | text,binary | binary |
152
- | timestamptz | Date | text,binary | binary |
153
- | oid | number | text,binary | binary |
154
- | bytea | Buffer | text,binary | binary |
155
- | uuid | string | text,binary | binary |
156
- | json | object | text,binary | binary |
157
- | jsonb | object | text,binary | binary |
158
- | xml | string | text,binary | binary |
159
- | point | Point | text,binary | binary |
160
- | circle | Circle | text,binary | binary |
161
- | lseg | Rectangle | text,binary | binary |
162
- | box | Rectangle | text,binary | binary |
163
- | int2Vector | number[] | text,binary | binary |
164
- | _bool | boolean[] | text,binary | binary |
165
- | _int2 | number[] | text,binary | binary |
166
- | _int4 | number[] | text,binary | binary |
167
- | _int8 | BigInt[] | text,binary | binary |
168
- | _float4 | number[] | text,binary | binary |
169
- | _float8 | number[] | text,binary | binary |
170
- | _char | string[] | text,binary | binary |
171
- | _bpchar | string[] | text,binary | binary |
172
- | _varchar | string[] | text,binary | binary |
173
- | _date | Date[] | text,binary | binary |
174
- | _time | Date[] | text,binary | binary |
175
- | _timestamp | Date[] | text,binary | binary |
176
- | _timestamptz | Date[] | text,binary | binary |
177
- | _uuid | string[] | text,binary | binary |
178
- | _oid | number[] | text,binary | binary |
179
- | _bytea | Buffer[] | text,binary | binary |
180
- | _json | object[] | text,binary | binary |
181
- | _jsonb | object[] | text,binary | binary |
182
- | _xml | string[] | text,binary | binary |
183
- | _point | Point[] | text,binary | binary |
184
- | _circle | Circle[] | text,binary | binary |
185
- | _lseg | Rectangle[] | text,binary | binary |
186
- | _box | Rectangle[] | text,binary | binary |
187
- | _int2Vector | number[][] | text,binary | binary |
218
+ You can report bugs and discuss features on the [GitHub issues](https://github.com/panates/postgrejs/issues) page When
219
+ you open an issue please provide version of NodeJS and PostgreSQL server.
188
220
 
221
+ ## Node Compatibility
189
222
 
190
- ## Support
191
- You can report bugs and discuss features on the [GitHub issues](https://github.com/panates/postgrejs/issues) page
192
- When you open an issue please provide version of NodeJS and PostgreSQL server.
223
+ - node >= 20.x
193
224
 
194
- ## Node Compatibility
195
- - node >= 16.x
196
-
197
-
198
225
  ## License
199
- PostgreJS is available under [MIT](LICENSE) license.
226
+
227
+ PostgreJS is available under the [BSD 3-Clause](LICENSE) license.
200
228
 
201
229
  [npm-image]: https://img.shields.io/npm/v/postgrejs
202
230
  [npm-url]: https://npmjs.org/package/postgrejs
231
+ [downloads-image]: https://img.shields.io/npm/dm/postgrejs.svg
232
+ [downloads-url]: https://npmjs.org/package/postgrejs
203
233
  [ci-test-image]: https://github.com/panates/postgrejs/actions/workflows/test.yml/badge.svg
204
234
  [ci-test-url]: https://github.com/panates/postgrejs/actions/workflows/test.yml
205
235
  [coveralls-image]: https://img.shields.io/coveralls/panates/postgrejs/master.svg
206
236
  [coveralls-url]: https://coveralls.io/r/panates/postgrejs
207
- [downloads-image]: https://img.shields.io/npm/dm/postgrejs.svg
208
- [downloads-url]: https://npmjs.org/package/postgrejs
209
- [gitter-image]: https://badges.gitter.im/panates/postgrejs.svg
210
- [gitter-url]: https://gitter.im/panates/postgrejs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
211
- [dependencies-image]: https://david-dm.org/panates/postgrejs/status.svg
212
- [dependencies-url]:https://david-dm.org/panates/postgrejs
213
- [devdependencies-image]: https://david-dm.org/panates/postgrejs/dev-status.svg
214
- [devdependencies-url]:https://david-dm.org/panates/postgrejs?type=dev
215
- [quality-image]: http://npm.packagequality.com/shield/postgrejs.png
216
- [quality-url]: http://packagequality.com/#?package=postgrejs