@m2k-5f/pgtx 2.5.0 → 2.5.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.
package/README.md CHANGED
@@ -179,6 +179,9 @@ In the `mitata` benchmark, Pgtx also demonstrated approximately **3× lower memo
179
179
  > 🚀 Pgtx automatically groups concurrent queries into pipeline batches, reducing network overhead by up to 5x compared to sequential queries.
180
180
 
181
181
 
182
+ ---
183
+
184
+
182
185
  ### High-Performance Data Streaming (`pool.stream`)
183
186
 
184
187
  For heavy database lookups (exporting millions of rows, bulk reports, or large analytical dumps), memory accumulation is the ultimate killer of backend stability. Storing rows in a standard JavaScript array causes massive heap pollution and triggers blocking Garbage Collection spikes.
@@ -232,6 +235,7 @@ In the `mitata` benchmark, Pgtx also demonstrated approximately **3× lower memo
232
235
  };
233
236
  ```
234
237
 
238
+ ---
235
239
 
236
240
  ### Transactions & Savepoints
237
241
 
@@ -247,6 +251,7 @@ In the `mitata` benchmark, Pgtx also demonstrated approximately **3× lower memo
247
251
  })
248
252
  ```
249
253
 
254
+ ---
250
255
 
251
256
  ### Async Notifications (LISTEN / NOTIFY)
252
257
 
@@ -300,6 +305,7 @@ In the `mitata` benchmark, Pgtx also demonstrated approximately **3× lower memo
300
305
 
301
306
  > ⚠️ **Architecture Note:** While `pool.notify` is a fire-and-forget atomic command, subscription states (`LISTEN`/`UNLISTEN`) are strictly tied to specific PostgreSQL backend processes. Using the high-level `pool.listen()` is strongly recommended for application code, as it encapsulates socket management into an elegant, leak-proof callback boundary.
302
307
 
308
+ ---
303
309
 
304
310
  ### Bulk Inserts
305
311
 
@@ -315,6 +321,8 @@ In the `mitata` benchmark, Pgtx also demonstrated approximately **3× lower memo
315
321
  // INSERT INTO users (name, email) VALUES ($1, $2), ($3, $4)
316
322
  ```
317
323
 
324
+ ---
325
+
318
326
  ### Dynamic Updates
319
327
 
320
328
  ```typescript
@@ -326,6 +334,8 @@ In the `mitata` benchmark, Pgtx also demonstrated approximately **3× lower memo
326
334
  // UPDATE users SET status = $1, last_login = $2 WHERE id = $3
327
335
  ```
328
336
 
337
+ ---
338
+
329
339
  ### Recursive Fragments
330
340
 
331
341
  ```typescript
@@ -338,6 +348,8 @@ In the `mitata` benchmark, Pgtx also demonstrated approximately **3× lower memo
338
348
  `
339
349
  ```
340
350
 
351
+ ---
352
+
341
353
  ### Smart Lists
342
354
 
343
355
  ```typescript
@@ -356,6 +368,8 @@ In the `mitata` benchmark, Pgtx also demonstrated approximately **3× lower memo
356
368
  `
357
369
  ```
358
370
 
371
+ ---
372
+
359
373
  ### Clean WHERE Clauses
360
374
 
361
375
  ```typescript
@@ -366,6 +380,8 @@ In the `mitata` benchmark, Pgtx also demonstrated approximately **3× lower memo
366
380
  // SELECT * FROM users WHERE role = $1 AND active = $2
367
381
  ```
368
382
 
383
+ ---
384
+
369
385
  ### Conditional Logic
370
386
 
371
387
  ```typescript
@@ -129,7 +129,7 @@ export declare class Connection {
129
129
  * })
130
130
  * ```
131
131
  */
132
- begin<T>(txCallback: (transaction: Transaction) => Promise<T>): Future<T, Error>;
132
+ begin<T>(txCallback: (transaction: Transaction) => Promise<T>): Future<T, unknown>;
133
133
  /**
134
134
  * Sends an asynchronous notification to a channel via `pg_notify`.
135
135
  *
@@ -153,7 +153,7 @@ export declare class Connection {
153
153
  * await conn.listen('events', data => console.log(data))
154
154
  * ```
155
155
  */
156
- listen(channelName: string, callback: (payload: string) => void): Future<Record<string, any>[], PostgresError>;
156
+ listen(channelName: string, callback: (payload: string) => void): Future<void, PostgresError>;
157
157
  /**
158
158
  * Unsubscribes a callback. Sends `UNLISTEN` if no callbacks remain for the channel.
159
159
  *
@@ -165,7 +165,7 @@ export declare class Connection {
165
165
  * await conn.unlisten('events', callback)
166
166
  * ```
167
167
  */
168
- unlisten(channelName: string, callback: (payload: string) => void): Future<[], PostgresError>;
168
+ unlisten(channelName: string, callback: (payload: string) => void): Future<void, PostgresError>;
169
169
  /**
170
170
  * Executes an SQL query in streaming mode.
171
171
  *
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import { SocketConnector } from "./protocol/socket-connector";
7
7
  import { Queue } from "./queue";
8
8
  import { Query, QueryState, StreamQuery } from "./query";
9
9
  import { sql } from ".";
10
- import { Begin, Future, Resolve } from 'fluent-future';
10
+ import { Begin, Future, Ok } from 'fluent-future';
11
11
  import { PostgresError } from "./error";
12
12
  const ErrConnectionClosed = new PostgresError("Connection is closed", 'connection_closed', "", "ERROR");
13
13
  const ErrConnectionReconnecring = new PostgresError("Connection are reconnecting", "connection_reconnecting", "", "ERROR");
@@ -86,7 +86,7 @@ export class Connection {
86
86
  static new(params) {
87
87
  const writer = ConnectionRequestWriter.new();
88
88
  return createAuthorizedSocket(writer, params)
89
- .andThen(socket => Resolve(new Connection(socket, writer, params.logLevel || 'error', params)));
89
+ .andThen(socket => Ok(new Connection(socket, writer, params.logLevel || 'error', params)));
90
90
  }
91
91
  /**
92
92
  * Executes a query using tagged template literals.
@@ -193,7 +193,7 @@ export class Connection {
193
193
  }
194
194
  const callbackSet = this._listeningCallbacks.get(channelName);
195
195
  callbackSet.add(callback);
196
- return this.query `listen ${sql.ident(channelName)};`;
196
+ return this.query `listen ${sql.ident(channelName)};`.map(() => { });
197
197
  }
198
198
  /**
199
199
  * Unsubscribes a callback. Sends `UNLISTEN` if no callbacks remain for the channel.
@@ -209,15 +209,15 @@ export class Connection {
209
209
  unlisten(channelName, callback) {
210
210
  this._checkOpened();
211
211
  if (!this._listeningCallbacks.has(channelName)) {
212
- return Resolve([]);
212
+ return Ok();
213
213
  }
214
214
  const callbackSet = this._listeningCallbacks.get(channelName);
215
215
  callbackSet.delete(callback);
216
216
  if (callbackSet.size === 0) {
217
217
  this._listeningCallbacks.delete(channelName);
218
- return this.query `unlisten ${sql.ident(channelName)};`;
218
+ return this.query `unlisten ${sql.ident(channelName)};`.map(() => { });
219
219
  }
220
- return Resolve([]);
220
+ return Ok();
221
221
  }
222
222
  /**
223
223
  * Executes an SQL query in streaming mode.
package/dist/pool.d.ts CHANGED
@@ -86,7 +86,7 @@ export declare class Pool {
86
86
  * return await conn.query`SELECT pg_is_in_recovery()`;
87
87
  * });
88
88
  */
89
- withAcquire<T>(fn: (conn: Connection) => Promise<T>): Future<T, Error>;
89
+ withAcquire<T>(fn: (conn: Connection) => Promise<T>): Future<T, unknown>;
90
90
  /**
91
91
  * Releases the connection back to the pool.
92
92
  *
@@ -124,7 +124,7 @@ export declare class Pool {
124
124
  * })
125
125
  * ```
126
126
  */
127
- begin<T>(txCallback: (transaction: Transaction) => Promise<T>): Future<T, Error>;
127
+ begin<T>(txCallback: (transaction: Transaction) => Promise<T>): Future<T, unknown>;
128
128
  /**
129
129
  * Executes a one-off query using pipeline.
130
130
  *
@@ -1 +1 @@
1
- {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAG3C,OAAO,EAAS,MAAM,EAAW,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,KAAK,UAAU,GAAG,gBAAgB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,IAAI;IACb,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,YAAY;gBAIR,MAAM,EAAE,UAAU;IAM9B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO;IA2BP;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC;IAUnD;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU;IAiBxB;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC;IAY7D;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;IAuBpF;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC;IAoCzG;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GACuB,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC;IAIhG;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;IAY3D;;OAEG;IACH,IAAI,IAAI,WAEP;IAGD;;;OAGG;IACH,IAAI,KAAK,WAER;IAGD;;;;;;;;;;OAUG;IACH,KAAK;CAWR"}
1
+ {"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../src/pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAG3C,OAAO,EAAS,MAAM,EAAM,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,KAAK,UAAU,GAAG,gBAAgB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,IAAI;IACb,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,IAAI,CAAQ;IACpB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,SAAS,CAAQ;IAEzB,OAAO,CAAC,YAAY;gBAIR,MAAM,EAAE,UAAU;IAM9B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO;IA2BP;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC;IAUnD;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU;IAiBxB;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC;IAY7D;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;IAuBpF;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC;IAoCzG;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GACuB,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC;IAIhG;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;IAY3D;;OAEG;IACH,IAAI,IAAI,WAEP;IAGD;;;OAGG;IACH,IAAI,KAAK,WAER;IAGD;;;;;;;;;;OAUG;IACH,KAAK;CAWR"}
package/dist/pool.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Connection } from "./connection";
2
2
  import { Queue } from "./queue";
3
- import { Begin, Future, Resolve } from "fluent-future";
3
+ import { Begin, Future, Ok } from "fluent-future";
4
4
  import { PostgresError } from "./error";
5
5
  const ErrPoolClosed = new PostgresError('Pool closed');
6
6
  /**
@@ -74,7 +74,7 @@ export class Pool {
74
74
  while (this._available.hasMore) {
75
75
  const conn = this._available.shift;
76
76
  if (conn.isOpened) {
77
- return Resolve(conn);
77
+ return Ok(conn);
78
78
  }
79
79
  this._total--;
80
80
  }
@@ -11,5 +11,6 @@ export type AuthorizationParams = {
11
11
  };
12
12
  export declare const ErrNonceMismatch: PostgresError;
13
13
  export declare const ErrPasswordRequired: PostgresError;
14
+ export declare const ErrSocketFailedDuringAuth: PostgresError;
14
15
  export declare const createAuthorizedSocket: (writer: ConnectionRequestWriter, params: AuthorizationParams) => Future<Socket, PostgresError>;
15
16
  //# sourceMappingURL=socket-authorization.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"socket-authorization.d.ts","sourceRoot":"","sources":["../../src/protocol/socket-authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAKrE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAGtC,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAGD,eAAO,MAAM,gBAAgB,eAAmF,CAAA;AAChH,eAAO,MAAM,mBAAmB,eAAqE,CAAA;AAIrG,eAAO,MAAM,sBAAsB,GAAI,QAAQ,uBAAuB,EAAE,QAAQ,mBAAmB,kCAyHlG,CAAA"}
1
+ {"version":3,"file":"socket-authorization.d.ts","sourceRoot":"","sources":["../../src/protocol/socket-authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,MAAM,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAKrE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAGtC,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAGD,eAAO,MAAM,gBAAgB,eAAmF,CAAA;AAChH,eAAO,MAAM,mBAAmB,eAAqE,CAAA;AACrG,eAAO,MAAM,yBAAyB,eAAiD,CAAA;AAIvF,eAAO,MAAM,sBAAsB,GAAI,QAAQ,uBAAuB,EAAE,QAAQ,mBAAmB,kCAoHlG,CAAA"}
@@ -7,93 +7,90 @@ import { PostgresError } from "../error";
7
7
  import { Future } from "fluent-future";
8
8
  export const ErrNonceMismatch = new PostgresError("Protocol violation: server nonce doesn't match client nonce");
9
9
  export const ErrPasswordRequired = new PostgresError('The authorization method requires a password.');
10
+ export const ErrSocketFailedDuringAuth = new PostgresError("Socket failed during auth");
10
11
  export const createAuthorizedSocket = (writer, params) => {
11
- return Future.of(new Promise((resolve, reject) => {
12
- const nonce = generateNonce();
13
- let clientMessage = '';
14
- let serverMessage = '';
15
- const socket = createConnection({ host: params.host, port: params.port });
16
- const connector = new SocketConnector(socket, (type, length, reader) => {
17
- writer.clear();
18
- switch (type) {
19
- case ResponseTypes.Authentication: {
20
- switch (reader.readAuthentication()) {
21
- case AuthenticationCodes.Ok: break;
22
- case AuthenticationCodes.CleartextPassword: {
23
- if (!params.password)
24
- throw ErrPasswordRequired;
25
- connector.write(writer.writePassword(params.password));
26
- break;
27
- }
28
- case AuthenticationCodes.MD5Password: {
29
- const salt = reader.readMD5Salt();
30
- if (!params.password)
31
- throw ErrPasswordRequired;
32
- const password = encryptMd5(params.password, params.user, salt);
33
- connector.write(writer.writePassword(password));
34
- break;
35
- }
36
- case AuthenticationCodes.SASL: {
37
- reader.readSaslMechanisms();
38
- if (!params.password)
39
- throw ErrPasswordRequired;
40
- clientMessage = `n=${params.user},r=${nonce}`;
41
- connector.write(writer.writeSaslInitial('SCRAM-SHA-256', `n,,${clientMessage}`));
42
- break;
43
- }
44
- case AuthenticationCodes.SASLContinue: {
45
- serverMessage = reader.readSaslMessage(length);
46
- if (!params.password)
47
- throw ErrPasswordRequired;
48
- const parts = Object.fromEntries(serverMessage.split(',').map(x => x.split('=')));
49
- const serverNonce = parts.r;
50
- const saltBase64 = parts.s;
51
- const iterations = parseInt(parts.i, 10);
52
- if (!serverNonce.startsWith(nonce)) {
53
- connector.destroy();
54
- return reject(ErrNonceMismatch);
55
- }
56
- const clientFinalMessageWithoutProof = `c=biws,r=${serverNonce}`;
57
- const authMessage = `${clientMessage},${serverMessage},${clientFinalMessageWithoutProof}`;
58
- const { clientProof } = calculateScramAuth(params.password, saltBase64, iterations, authMessage);
59
- const clientFinalMessage = `${clientFinalMessageWithoutProof},p=${clientProof}`;
60
- connector.write(writer.writeSaslResponse(clientFinalMessage));
61
- break;
62
- }
63
- case AuthenticationCodes.SASLFinal: {
64
- reader.readSaslMessage(length);
65
- break;
12
+ const { future, reject, resolve } = Future.withResolvers();
13
+ const nonce = generateNonce();
14
+ let clientMessage = '';
15
+ let serverMessage = '';
16
+ const socket = createConnection({ host: params.host, port: params.port });
17
+ const connector = new SocketConnector(socket, (type, length, reader) => {
18
+ writer.clear();
19
+ switch (type) {
20
+ case ResponseTypes.Authentication: {
21
+ switch (reader.readAuthentication()) {
22
+ case AuthenticationCodes.Ok: break;
23
+ case AuthenticationCodes.CleartextPassword: {
24
+ if (!params.password)
25
+ throw ErrPasswordRequired;
26
+ connector.write(writer.writePassword(params.password));
27
+ break;
28
+ }
29
+ case AuthenticationCodes.MD5Password: {
30
+ const salt = reader.readMD5Salt();
31
+ if (!params.password)
32
+ throw ErrPasswordRequired;
33
+ const password = encryptMd5(params.password, params.user, salt);
34
+ connector.write(writer.writePassword(password));
35
+ break;
36
+ }
37
+ case AuthenticationCodes.SASL: {
38
+ reader.readSaslMechanisms();
39
+ if (!params.password)
40
+ throw ErrPasswordRequired;
41
+ clientMessage = `n=${params.user},r=${nonce}`;
42
+ connector.write(writer.writeSaslInitial('SCRAM-SHA-256', `n,,${clientMessage}`));
43
+ break;
44
+ }
45
+ case AuthenticationCodes.SASLContinue: {
46
+ serverMessage = reader.readSaslMessage(length);
47
+ if (!params.password)
48
+ throw ErrPasswordRequired;
49
+ const parts = Object.fromEntries(serverMessage.split(',').map(x => x.split('=')));
50
+ const serverNonce = parts.r;
51
+ const saltBase64 = parts.s;
52
+ const iterations = parseInt(parts.i, 10);
53
+ if (!serverNonce.startsWith(nonce)) {
54
+ connector.destroy();
55
+ return reject(ErrNonceMismatch);
66
56
  }
57
+ const clientFinalMessageWithoutProof = `c=biws,r=${serverNonce}`;
58
+ const authMessage = `${clientMessage},${serverMessage},${clientFinalMessageWithoutProof}`;
59
+ const { clientProof } = calculateScramAuth(params.password, saltBase64, iterations, authMessage);
60
+ const clientFinalMessage = `${clientFinalMessageWithoutProof},p=${clientProof}`;
61
+ connector.write(writer.writeSaslResponse(clientFinalMessage));
62
+ break;
63
+ }
64
+ case AuthenticationCodes.SASLFinal: {
65
+ reader.readSaslMessage(length);
66
+ break;
67
67
  }
68
- break;
69
- }
70
- case ResponseTypes.ParamaterStatus: {
71
- reader.readParameterStatus();
72
- break;
73
- }
74
- case ResponseTypes.ErrorResponse: {
75
- const error = reader.readErrorResponse();
76
- connector.destroy();
77
- reject(error);
78
- return;
79
- }
80
- case ResponseTypes.BackendKeyData: {
81
- reader.readBackendKeyData();
82
- }
83
- case ResponseTypes.ReadyForQuery: {
84
- reader.readReadyForQuery();
85
- resolve(connector.unwrapSocket());
86
- return;
87
68
  }
69
+ break;
88
70
  }
89
- }, error => {
90
- reject(error);
91
- });
92
- connector.write(writer.writeStartup(params.user, params.database));
93
- writer.clear();
94
- }), error => {
95
- if (error instanceof PostgresError)
96
- return error;
97
- return new PostgresError(error.message);
71
+ case ResponseTypes.ParamaterStatus: {
72
+ reader.readParameterStatus();
73
+ break;
74
+ }
75
+ case ResponseTypes.ErrorResponse: {
76
+ const error = reader.readErrorResponse();
77
+ connector.destroy();
78
+ reject(error);
79
+ return;
80
+ }
81
+ case ResponseTypes.BackendKeyData: {
82
+ reader.readBackendKeyData();
83
+ }
84
+ case ResponseTypes.ReadyForQuery: {
85
+ reader.readReadyForQuery();
86
+ resolve(connector.unwrapSocket());
87
+ return;
88
+ }
89
+ }
90
+ }, error => {
91
+ reject(ErrSocketFailedDuringAuth);
98
92
  });
93
+ connector.write(writer.writeStartup(params.user, params.database));
94
+ writer.clear();
95
+ return future;
99
96
  };
@@ -17,11 +17,11 @@ export declare class Transaction {
17
17
  /**
18
18
  * Commits the current transaction.
19
19
  */
20
- commit(): Future<[], PostgresError>;
20
+ commit(): Future<void, any>;
21
21
  /**
22
22
  * Rolls back the current transaction.
23
23
  */
24
- rollback(): Future<[], PostgresError>;
24
+ rollback(): Future<void, any>;
25
25
  /**
26
26
  * Executes a query within the current transaction.
27
27
  */
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAEvC;;;GAGG;AACH,qBAAa,WAAW;IAIhB,QAAQ,CAAC,IAAI,EAAE,UAAU;IAH7B,OAAO,CAAC,UAAU,CAAiB;gBAGtB,IAAI,EAAE,UAAU;IAG7B;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACI,MAAM,IAIiC,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC;IAGvE;;OAEG;IACI,QAAQ,IAI+B,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC;IAGvE;;OAEG;IACI,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE;IAK3F;;;;;;;;;OASG;IACI,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC;CAWjG"}
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAEvC;;;GAGG;AACH,qBAAa,WAAW;IAIhB,QAAQ,CAAC,IAAI,EAAE,UAAU;IAH7B,OAAO,CAAC,UAAU,CAAiB;gBAGtB,IAAI,EAAE,UAAU;IAG7B;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACI,MAAM;IAQb;;OAEG;IACI,QAAQ;IAQf;;OAEG;IACI,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE;IAK3F;;;;;;;;;OASG;IACI,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC;CAWjG"}
@@ -26,7 +26,8 @@ export class Transaction {
26
26
  commit() {
27
27
  this.checkActive();
28
28
  return this.conn.query `COMMIT`
29
- .tap(() => this.isFinished = true);
29
+ .tap(() => { this.isFinished = true; })
30
+ .map(() => { });
30
31
  }
31
32
  /**
32
33
  * Rolls back the current transaction.
@@ -34,7 +35,8 @@ export class Transaction {
34
35
  rollback() {
35
36
  this.checkActive();
36
37
  return this.conn.query `ROLLBACK`
37
- .tap(() => this.isFinished = true);
38
+ .tap(() => { this.isFinished = true; })
39
+ .map(() => { });
38
40
  }
39
41
  /**
40
42
  * Executes a query within the current transaction.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m2k-5f/pgtx",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "type": "module",
5
5
  "description": "Blazing-fast PostgreSQL driver with pipeline support.",
6
6
  "files": [
@@ -42,14 +42,13 @@
42
42
  }
43
43
  },
44
44
  "devDependencies": {
45
- "@types/node": "^26.1.2",
45
+ "@types/node": "^26.2.0",
46
46
  "mitata": "^1.0.34",
47
- "pg": "^8.22.0",
48
47
  "postgres": "^3.4.9",
49
- "tsx": "^4.23.5",
48
+ "tsx": "^4.23.11",
50
49
  "typescript": "^5.9.3"
51
50
  },
52
51
  "dependencies": {
53
- "fluent-future": "^1.3.3"
52
+ "fluent-future": "^1.4.1"
54
53
  }
55
54
  }