@m2k-5f/pgtx 2.3.4 → 2.4.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
@@ -7,8 +7,7 @@
7
7
 
8
8
  Pipeline execution, automatic prepared statements, typed SQL, transactions, and zero dependencies.
9
9
 
10
- **Up to 3.4× faster than Postgres.js and 15.6× faster than `pg` in concurrent pipeline workloads.**
11
-
10
+ **Up to 25% faster than `Postgres.js` and 15.6× faster than `pg` in concurrent pipeline workloads.**
12
11
 
13
12
  ---
14
13
 
@@ -21,6 +20,35 @@
21
20
  # bun add @m2k-5f/pgtx
22
21
  ```
23
22
 
23
+ ---
24
+
25
+ ## 🚀 Quick Start
26
+
27
+ ```typescript
28
+ import { sql, Pool } from "@m2k-5f/pgtx";
29
+
30
+ const pool = new Pool({
31
+ host: 'localhost',
32
+ user: 'postgres',
33
+ password: 'postgres',
34
+ database: 'myapp'
35
+ })
36
+
37
+ // Type-safe query
38
+ const [user] = await pool.query<User>`SELECT * FROM users WHERE id = ${1}`
39
+
40
+ // Bulk insert
41
+ await pool.query`
42
+ INSERT INTO users ${sql.insert([{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }])}
43
+ `
44
+
45
+ // Transaction
46
+ await pool.begin(async (tx) => {
47
+ await tx.query`UPDATE accounts SET balance = balance - 100 WHERE id = ${1}`
48
+ await tx.query`UPDATE accounts SET balance = balance + 100 WHERE id = ${2}`
49
+ })
50
+ ```
51
+
24
52
  ---
25
53
 
26
54
  ## ✨ Features
@@ -37,26 +65,26 @@
37
65
 
38
66
  ---
39
67
 
40
- ## ⚡ Performance
68
+ ## ⚡ Performance & Benchmarks
41
69
 
42
- ### Stress test 3000 concurrent `SELECT` queries
70
+ ### 1. In-Engine Pipeline Blast (3000 Parallel Queries)
71
+ *Measured using `mitata` inside GitHub Actions cloud runners (Ubuntu, 2 vCPUs, 10 DB Connections).*
43
72
 
44
- **Environment**
73
+ | Driver | Avg Time per Iteration | Relative Speed | Memory (p75) |
74
+ | :--- | :---: | :---: | :---: |
75
+ | **Pgtx (Pipeline)** | **19.21 ms** | **Baseline (3.6×)** | **874.71 KB** |
76
+ | Postgres.js (Pipeline) | 70.50 ms | 3.6× Slower | 1.29 MB |
77
+ | node-postgres (no pipeline) | 327.07 ms | 17.0× Slower | 4.05 MB |
45
78
 
46
- * PostgreSQL connection pool: **10 connections**
47
- * **3000 concurrent parameterized `SELECT` queries**
48
- * Same SQL and identical workload for all drivers
79
+ > **Stability Note:** Pgtx provides an rock-solid flat latency graph (p99 is strictly bounded to `21.76 ms`), while maintaining a 2.5× smaller memory footprint compared to Postgres.js due to zero-allocation binary parsing.
49
80
 
50
- | Driver | Time |
51
- | ---------------------- | -----------: |
52
- | 🥇 **Pgtx (Pipeline)** | **24.18 ms** |
53
- | Postgres.js (Pipeline) | 83.36 ms |
54
- | node-postgres (`pg`) | 377.95 ms |
81
+ ### 2. Real-World HTTP Throughput (`wrk` Stress Test)
82
+ *HTTP server baseline using a `node:http` instance on GitHub Actions runner, handling 1,000 concurrent network connections (`wrk -t2 -c1000 -d10s`).*
55
83
 
56
- ### Relative performance
84
+ - **Pgtx:** **~14,500 RPS**
85
+ - **Postgres.js:** **~11,500 RPS**
57
86
 
58
- * 🚀 **3.4× faster than Postgres.js**
59
- * 🚀 **15.6× faster than node-postgres (`pg`)**
87
+ On high-concurrency bare metal servers, Pgtx effortlessly maintains a **+25% performance lead** over Postgres.js.
60
88
 
61
89
  Pgtx achieves high throughput by:
62
90
 
@@ -66,9 +94,9 @@
66
94
  * Automatic prepared statement caching
67
95
  * Row description caching
68
96
  * Zero-dependency implementation
97
+ * Binary protocol support
69
98
 
70
- > Benchmark source is available in the repository and can be reproduced locally.
71
-
99
+ > Benchmarks source is available in the repository and can be reproduced locally.
72
100
 
73
101
  ---
74
102
 
@@ -89,37 +117,10 @@
89
117
 
90
118
  ---
91
119
 
92
- ## 🚀 Quick Start
93
-
94
- ```typescript
95
- import { sql, Pool } from "@m2k-5f/pgtx";
96
-
97
- const pool = new Pool({
98
- host: 'localhost',
99
- user: 'postgres',
100
- password: 'postgres',
101
- database: 'myapp'
102
- })
103
-
104
- // Type-safe query
105
- const [user] = await pool.query<User>`SELECT * FROM users WHERE id = ${1}`
106
-
107
- // Bulk insert
108
- await pool.query`
109
- INSERT INTO users ${sql.insert([{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }])}
110
- `
111
-
112
- // Transaction
113
- await pool.begin(async (tx) => {
114
- await tx.query`UPDATE accounts SET balance = balance - 100 WHERE id = ${1}`
115
- await tx.query`UPDATE accounts SET balance = balance + 100 WHERE id = ${2}`
116
- })
117
- ```
118
-
119
- ---
120
120
 
121
+ ## 📖 Features
121
122
 
122
- ## 🎯 Typed Error Handling
123
+ ### 🎯 Typed Error Handling
123
124
 
124
125
  Pgtx queries return `Future<T, PostgresError>` from [fluent-future](https://www.npmjs.com/package/fluent-future) instead of raw `Promise<T>`. This gives you:
125
126
 
@@ -136,10 +137,6 @@
136
137
 
137
138
  ---
138
139
 
139
-
140
- ## 📖 Features
141
-
142
-
143
140
  ### Pipeline by Default
144
141
 
145
142
  `Bind` and `.bind` from [fluent-future](https://www.npmjs.com/package/fluent-future) automatically multiplex independent queries over PostgreSQL pipeline protocol — no manual batching required:
@@ -69,10 +69,8 @@ export declare class Connection {
69
69
  private _isReconnecting;
70
70
  private _socket;
71
71
  private _writer;
72
- private _activeQuery;
73
72
  private _pipelinesQueue;
74
73
  private _described;
75
- private _rowMappers;
76
74
  private _describingPending;
77
75
  private _parsed;
78
76
  private _parsingPending;
@@ -80,7 +78,6 @@ export declare class Connection {
80
78
  private _stmtCounter;
81
79
  private _logLevel;
82
80
  private _nextStatement;
83
- private _getRowMapper;
84
81
  private _checkOpened;
85
82
  private constructor();
86
83
  /**
@@ -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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"}
@@ -45,15 +45,6 @@ export class Connection {
45
45
  _nextStatement() {
46
46
  return `s-${this._stmtCounter++}`;
47
47
  }
48
- _getRowMapper(statementName, descriptions) {
49
- let mapper = this._rowMappers.get(statementName);
50
- if (mapper)
51
- return mapper;
52
- const fields = descriptions.map((desc, i) => `"${desc.name}": values[${i}]`).join(',\n ');
53
- mapper = new Function('values', `return ${fields}`)();
54
- this._rowMappers.set(statementName, mapper);
55
- return mapper;
56
- }
57
48
  _checkOpened() {
58
49
  if (!this.isOpened)
59
50
  throw ErrConnectionClosed;
@@ -62,10 +53,8 @@ export class Connection {
62
53
  this._isFlushing = false;
63
54
  this._isOpened = true;
64
55
  this._isReconnecting = false;
65
- this._activeQuery = null;
66
56
  this._pipelinesQueue = new Queue();
67
57
  this._described = new Map();
68
- this._rowMappers = new Map();
69
58
  this._describingPending = new Set();
70
59
  this._parsed = new Map();
71
60
  this._parsingPending = new Map();
@@ -281,7 +270,7 @@ export class Connection {
281
270
  .writeBind("", query.statementName, query.args)
282
271
  .writeExecute("");
283
272
  }
284
- this._pipelinesQueue.get().push(query);
273
+ this._pipelinesQueue.last.push(query);
285
274
  }
286
275
  _registerFlush() {
287
276
  if (!this._isFlushing) {
@@ -339,15 +328,14 @@ export class Connection {
339
328
  return Promise.all(promises);
340
329
  }
341
330
  _getCurrentQuery() {
342
- return this._pipelinesQueue.get().get();
331
+ return this._pipelinesQueue.current.current;
343
332
  }
344
333
  _rejectPipeline(error) {
345
334
  if (this._pipelinesQueue.isFree)
346
335
  return;
347
- const queue = this._pipelinesQueue.get();
336
+ const queue = this._pipelinesQueue.current;
348
337
  while (queue.hasMore) {
349
- queue.get().reject(error);
350
- queue.next();
338
+ queue.shift.reject(error);
351
339
  }
352
340
  }
353
341
  _handlePacket(type, reader) {
@@ -383,6 +371,7 @@ export class Connection {
383
371
  this._describingPending.delete(query.statementName);
384
372
  this._described.set(query.statementName, []);
385
373
  query.state = QueryState.Executing;
374
+ query.columns = [];
386
375
  }
387
376
  break;
388
377
  case ResponseTypes.RowDescription:
@@ -397,11 +386,7 @@ export class Connection {
397
386
  break;
398
387
  case ResponseTypes.DataRow:
399
388
  {
400
- let query = this._activeQuery;
401
- if (!query) {
402
- query = this._getCurrentQuery();
403
- this._activeQuery = query;
404
- }
389
+ let query = this._getCurrentQuery();
405
390
  if (!query.columns) {
406
391
  query.columns = this._described.get(query.statementName);
407
392
  }
@@ -415,17 +400,13 @@ export class Connection {
415
400
  this.close();
416
401
  break;
417
402
  }
418
- const query = this._activeQuery || this._getCurrentQuery();
403
+ const query = this._getCurrentQuery();
419
404
  if (!query) {
420
405
  this.close();
421
406
  break;
422
407
  }
423
- if (!query.columns) {
424
- query.columns = this._described.get(query.statementName);
425
- }
426
408
  query.state = QueryState.Completed;
427
- this._pipelinesQueue.get().next();
428
- this._activeQuery = null;
409
+ this._pipelinesQueue.current.next();
429
410
  query.resolve();
430
411
  }
431
412
  break;
@@ -451,10 +432,7 @@ export class Connection {
451
432
  case ResponseTypes.ReadyForQuery:
452
433
  {
453
434
  reader.readReadyForQuery();
454
- const pipeline = this._pipelinesQueue.get();
455
- if (!pipeline.hasMore) {
456
- this._pipelinesQueue.next();
457
- }
435
+ this._pipelinesQueue.next();
458
436
  }
459
437
  break;
460
438
  case ResponseTypes.Notice:
@@ -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,EAAE,MAAM,EAAW,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,KAAK,UAAU,GAAG,gBAAgB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;IA0BP;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU;IAoBxB;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC;IAW7D;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;IAiCpF;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GACuB,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC;IAIhG;;OAEG;IACH,IAAI,IAAI,WAEP;IAGD;;;OAGG;IACH,IAAI,KAAK,WAER;IAGD;;;;;;;;;;OAUG;IACH,KAAK;CAeR"}
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,EAAE,MAAM,EAAW,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGxC,KAAK,UAAU,GAAG,gBAAgB,GAAG;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;IAyBP;;;;;;;;;;;;;;;;;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;IAW7D;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;IAuBpF;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,MAAW,GACuB,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC;IAIhG;;OAEG;IACH,IAAI,IAAI,WAEP;IAGD;;;OAGG;IACH,IAAI,KAAK,WAER;IAGD;;;;;;;;;;OAUG;IACH,KAAK;CAWR"}
package/dist/pool.js CHANGED
@@ -70,8 +70,7 @@ export class Pool {
70
70
  acquire() {
71
71
  this._checkClosed();
72
72
  while (this._available.hasMore) {
73
- const conn = this._available.get();
74
- this._available.next();
73
+ const conn = this._available.shift;
75
74
  if (conn.isOpened) {
76
75
  return Resolve(conn);
77
76
  }
@@ -111,9 +110,7 @@ export class Pool {
111
110
  return;
112
111
  }
113
112
  if (this._waiting.hasMore) {
114
- const waiter = this._waiting.get();
115
- this._waiting.next();
116
- waiter.resolve(conn);
113
+ this._waiting.shift.resolve(conn);
117
114
  return;
118
115
  }
119
116
  this._available.push(conn);
@@ -168,8 +165,7 @@ export class Pool {
168
165
  query(templates, ...args) {
169
166
  this._checkClosed();
170
167
  while (this._available.hasMore) {
171
- const conn = this._available.get();
172
- this._available.next();
168
+ const conn = this._available.shift;
173
169
  if (!conn.isOpened) {
174
170
  this._total--;
175
171
  continue;
@@ -177,15 +173,6 @@ export class Pool {
177
173
  this._available.push(conn);
178
174
  return conn.query(templates, ...args);
179
175
  }
180
- if (this._total < this._max) {
181
- this._total++;
182
- return Future.of(Connection.new(this._config))
183
- .tapErr(() => this._total--)
184
- .andThen(conn => {
185
- this.release(conn);
186
- return conn.query(templates, ...args);
187
- });
188
- }
189
176
  return this.acquire()
190
177
  .andThen(conn => {
191
178
  this.release(conn);
@@ -232,14 +219,10 @@ export class Pool {
232
219
  */
233
220
  close() {
234
221
  while (this._available.hasMore) {
235
- const conn = this._available.get();
236
- this._available.next();
237
- conn.close();
222
+ this._available.shift.close();
238
223
  }
239
224
  while (this._waiting.hasMore) {
240
- const waiter = this._waiting.get();
241
- this._waiting.next();
242
- waiter.reject(new Error('Pool closed'));
225
+ this._waiting.shift.reject(new Error('Pool closed'));
243
226
  }
244
227
  this._total = 0;
245
228
  }
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGrD,eAAO,MAAM,UAAU;;;;;;CAMb,CAAA;AAGV,MAAM,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,UAAU,CAAC,CAAA;AAG9C,qBAAa,KAAK,CAAC,CAAC;IAOL,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE;IACvB,KAAK,EAAE,KAAK;IACZ,aAAa,EAAE,aAAa;IAC5B,OAAO,CAAC,EAAE,iBAAiB,EAAE;IAVxC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAA;IACrB,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,KAAK,CAAU;gBAGZ,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EACvB,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,aAAa,EAC5B,OAAO,CAAC,EAAE,iBAAiB,EAAE,YAAA;IAQxC,QAAQ,CAAC,KAAK,EAAE,KAAK;IAKrB,IAAI,CAAC,KAAK,EAAE,CAAC;IAIb,MAAM,CAAC,KAAK,EAAE,KAAK;IAKnB,OAAO;CAGV"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGrD,eAAO,MAAM,UAAU;;;;;;CAMb,CAAA;AAGV,MAAM,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,UAAU,CAAC,CAAA;AAG9C,qBAAa,KAAK,CAAC,CAAC;IAOL,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE;IACvB,KAAK,EAAE,KAAK;IACZ,aAAa,EAAE,aAAa;IAC5B,OAAO,CAAC,EAAE,iBAAiB,EAAE;IAVxC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAA;IACrB,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,KAAK,CAAU;gBAGZ,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EACvB,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,aAAa,EAC5B,OAAO,CAAC,EAAE,iBAAiB,EAAE,YAAA;IASxC,QAAQ,CAAC,KAAK,EAAE,KAAK;IAKrB,IAAI,CAAC,KAAK,EAAE,CAAC;IAKb,MAAM,CAAC,KAAK,EAAE,KAAK;IAKnB,OAAO;CAGV"}
package/dist/queue.d.ts CHANGED
@@ -2,8 +2,9 @@ export declare class Queue<T> {
2
2
  private _queue;
3
3
  private _pointer;
4
4
  next(): void;
5
- get(): T;
6
- shift(): T;
5
+ get current(): T;
6
+ get last(): T;
7
+ get shift(): T;
7
8
  push(item: T): void;
8
9
  get size(): number;
9
10
  get hasMore(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,qBAAa,KAAK,CAAC,CAAC;IAChB,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAI;IAEpB,IAAI;IASJ,GAAG;IAKH,KAAK;IAYL,IAAI,CAAC,IAAI,EAAE,CAAC;IAIZ,IAAI,IAAI,WAEP;IAGD,IAAI,OAAO,YAEV;IAGD,IAAI,MAAM,YAA+C;CAC5D"}
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,qBAAa,KAAK,CAAC,CAAC;IAChB,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAI;IAEpB,IAAI;IAcJ,IAAI,OAAO,MAEV;IAED,IAAI,IAAI,MAA+C;IAGvD,IAAI,KAAK,MAKR;IAGD,IAAI,CAAC,IAAI,EAAE,CAAC;IAIZ,IAAI,IAAI,WAEP;IAGD,IAAI,OAAO,YAEV;IAGD,IAAI,MAAM,YAA+C;CAC5D"}
package/dist/queue.js CHANGED
@@ -5,21 +5,22 @@ export class Queue {
5
5
  }
6
6
  next() {
7
7
  this._pointer++;
8
+ if (this._pointer > 10000) {
9
+ this._queue.splice(0, this._pointer);
10
+ this._pointer = 0;
11
+ }
8
12
  if (this._pointer >= this._queue.length) {
9
- this._queue = [];
13
+ this._queue.length = 0;
10
14
  this._pointer = 0;
11
15
  }
12
16
  }
13
- get() {
17
+ get current() {
14
18
  return this._queue[this._pointer];
15
19
  }
16
- shift() {
20
+ get last() { return this._queue[this._queue.length - 1]; }
21
+ get shift() {
17
22
  const item = this._queue[this._pointer];
18
- this._pointer++;
19
- if (this._pointer >= this._queue.length) {
20
- this._queue.length = 0;
21
- this._pointer = 0;
22
- }
23
+ this.next();
23
24
  return item;
24
25
  }
25
26
  push(item) {
package/package.json CHANGED
@@ -1,55 +1,55 @@
1
- {
2
- "name": "@m2k-5f/pgtx",
3
- "version": "2.3.4",
4
- "type": "module",
5
- "description": "Blazing-fast PostgreSQL driver with pipeline support.",
6
- "files": [
7
- "dist",
8
- "README.md"
9
- ],
10
- "scripts": {
11
- "build": "tsc",
12
- "prepublishOnly": "npm run build",
13
- "testGitHub": "node --import tsx --test $(find tests -name '*.test.ts')",
14
- "test": "node --import tsx --test ./tests/*.test.ts",
15
- "benchmark": "npx tsx benchmark.ts"
16
- },
17
- "repository": {
18
- "type": "git",
19
- "url": "git://github.com/M2K-5F/pgtx.git"
20
- },
21
- "keywords": [
22
- "sql",
23
- "postgres",
24
- "driver",
25
- "pipeline",
26
- "query-builder",
27
- "typescript",
28
- "transactions",
29
- "prepared-statements"
30
- ],
31
- "author": "M2K-5F",
32
- "license": "MIT",
33
- "homepage": "https://github.com/M2K-5F/pgtx",
34
- "bugs": {
35
- "url": "https://github.com/M2K-5F/pgtx/issues"
36
- },
37
- "exports": {
38
- ".": {
39
- "import": "./dist/index.js",
40
- "require": "./dist/index.js",
41
- "types": "./dist/index.d.ts"
42
- }
43
- },
44
- "devDependencies": {
45
- "@types/node": "^26.1.1",
46
- "mitata": "^1.0.34",
47
- "pg": "^8.22.0",
48
- "postgres": "^3.4.9",
49
- "tsx": "^4.21.0",
50
- "typescript": "^5.0.0"
51
- },
52
- "dependencies": {
53
- "fluent-future": "^1.3.2"
54
- }
55
- }
1
+ {
2
+ "name": "@m2k-5f/pgtx",
3
+ "version": "2.4.1",
4
+ "type": "module",
5
+ "description": "Blazing-fast PostgreSQL driver with pipeline support.",
6
+ "files": [
7
+ "dist",
8
+ "README.md"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "prepublishOnly": "npm run build",
13
+ "testGitHub": "node --import tsx --test $(find tests -name '*.test.ts')",
14
+ "test": "node --import tsx --test ./tests/*.test.ts",
15
+ "benchmark": "npx tsx benchmark.ts"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git://github.com/M2K-5F/pgtx.git"
20
+ },
21
+ "keywords": [
22
+ "sql",
23
+ "postgres",
24
+ "driver",
25
+ "pipeline",
26
+ "query-builder",
27
+ "typescript",
28
+ "transactions",
29
+ "prepared-statements"
30
+ ],
31
+ "author": "M2K-5F",
32
+ "license": "MIT",
33
+ "homepage": "https://github.com/M2K-5F/pgtx",
34
+ "bugs": {
35
+ "url": "https://github.com/M2K-5F/pgtx/issues"
36
+ },
37
+ "exports": {
38
+ ".": {
39
+ "import": "./dist/index.js",
40
+ "require": "./dist/index.js",
41
+ "types": "./dist/index.d.ts"
42
+ }
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^26.1.1",
46
+ "mitata": "^1.0.34",
47
+ "pg": "^8.22.0",
48
+ "postgres": "^3.4.9",
49
+ "tsx": "^4.21.0",
50
+ "typescript": "^5.0.0"
51
+ },
52
+ "dependencies": {
53
+ "fluent-future": "^1.3.2"
54
+ }
55
+ }
@@ -1,5 +0,0 @@
1
- import { CompiledSqlQuery } from "./../utils";
2
- export declare abstract class Clause {
3
- abstract map(argCounter: number): CompiledSqlQuery;
4
- }
5
- //# sourceMappingURL=base.clause.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"base.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/base.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,8BAAsB,MAAM;IACxB,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CACrD"}
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Clause = void 0;
4
- class Clause {
5
- }
6
- exports.Clause = Clause;
@@ -1,9 +0,0 @@
1
- import { Clause } from "./base.clause";
2
- import { CompiledSqlQuery } from "../utils";
3
- export declare class StaticClause<T extends string> extends Clause {
4
- readonly value: T;
5
- constructor(value: T);
6
- map(argCounter: number): CompiledSqlQuery;
7
- }
8
- export declare function staticClause<T extends string>(value: T): StaticClause<T>;
9
- //# sourceMappingURL=static.clause.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"static.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/static.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,MAAM;IAElD,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAAR,KAAK,EAAE,CAAC;IAKZ,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CAMrD;AAGD,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAExE"}
@@ -1,21 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StaticClause = void 0;
4
- exports.staticClause = staticClause;
5
- const base_clause_1 = require("./base.clause");
6
- class StaticClause extends base_clause_1.Clause {
7
- constructor(value) {
8
- super();
9
- this.value = value;
10
- }
11
- map(argCounter) {
12
- if (this.value === undefined) {
13
- throw new TypeError(`Query parameter undefined at position ${argCounter}`);
14
- }
15
- return { text: this.value, args: [], argCounter };
16
- }
17
- }
18
- exports.StaticClause = StaticClause;
19
- function staticClause(value) {
20
- return new StaticClause(value);
21
- }
@@ -1,9 +0,0 @@
1
- import { Clause } from "./base.clause";
2
- import { CompiledSqlQuery } from "../utils";
3
- export declare class InsertClause extends Clause {
4
- readonly inserts: Record<string, any>[];
5
- constructor(inserts: Record<string, any>[]);
6
- map(argCounter: number): CompiledSqlQuery;
7
- }
8
- export declare function valueClause<T extends Record<string, any>>(...objects: [T, ...NoInfer<T>[]]): InsertClause;
9
- //# sourceMappingURL=values.clause.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"values.clause.d.ts","sourceRoot":"","sources":["../../src/clauses/values.clause.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,qBAAa,YAAa,SAAQ,MAAM;IAEhC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE;gBAA9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE;IAGlC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;CAgBrD;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,gBAE1F"}
@@ -1,27 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InsertClause = void 0;
4
- exports.valueClause = valueClause;
5
- const base_clause_1 = require("./base.clause");
6
- class InsertClause extends base_clause_1.Clause {
7
- constructor(inserts) {
8
- super();
9
- this.inserts = inserts;
10
- }
11
- map(argCounter) {
12
- const columns = Object.keys(this.inserts[0]);
13
- let text = `(${columns.join(', ')}) VALUES `;
14
- let args = [];
15
- text += `${this.inserts.map(values => {
16
- return `(${Object.values(values).map(value => {
17
- args.push(value);
18
- return `$${argCounter++}`;
19
- }).join(", ")})`;
20
- }).join(", ")}`;
21
- return { text, args, argCounter };
22
- }
23
- }
24
- exports.InsertClause = InsertClause;
25
- function valueClause(...objects) {
26
- return new InsertClause(objects);
27
- }
@@ -1,17 +0,0 @@
1
- import { PoolClient, Pool, QueryResultRow } from "pg";
2
- import { PreparedStatement } from "./types";
3
- export declare class ConnPraparedStatement<Result extends QueryResultRow, Args extends any[]> {
4
- private readonly conn;
5
- readonly text: string;
6
- readonly name: string;
7
- constructor(conn: PoolClient, text: string, name: string);
8
- execute(...params: Args): Promise<Result[]>;
9
- }
10
- export declare class PoolPreparedStatement<Result extends QueryResultRow, Args extends any[]> implements PreparedStatement<Result, Args> {
11
- private readonly pool;
12
- readonly text: string;
13
- readonly name: string;
14
- constructor(pool: Pool, text: string, name: string);
15
- execute(...params: Args): Promise<Result[]>;
16
- }
17
- //# sourceMappingURL=prepared.statement.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prepared.statement.d.ts","sourceRoot":"","sources":["../src/prepared.statement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,qBAAa,qBAAqB,CAAC,MAAM,SAAS,cAAc,EAAE,IAAI,SAAS,GAAG,EAAE;IAE5E,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAFJ,IAAI,EAAE,UAAU,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM;IAGnB,OAAO,CAAC,GAAG,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAQpD;AAED,qBAAa,qBAAqB,CAAC,MAAM,SAAS,cAAc,EAAE,IAAI,SAAS,GAAG,EAAE,CAAE,YAAW,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC;IAExH,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAFJ,IAAI,EAAE,IAAI,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM;IAGnB,OAAO,CAAC,GAAG,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAepD"}
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PoolPreparedStatement = exports.ConnPraparedStatement = void 0;
4
- class ConnPraparedStatement {
5
- constructor(conn, text, name) {
6
- this.conn = conn;
7
- this.text = text;
8
- this.name = name;
9
- }
10
- async execute(...params) {
11
- return this.conn.query({
12
- text: this.text,
13
- name: this.name,
14
- values: params
15
- })
16
- .then(result => result.rows);
17
- }
18
- }
19
- exports.ConnPraparedStatement = ConnPraparedStatement;
20
- class PoolPreparedStatement {
21
- constructor(pool, text, name) {
22
- this.pool = pool;
23
- this.text = text;
24
- this.name = name;
25
- }
26
- async execute(...params) {
27
- const conn = await this.pool.connect();
28
- try {
29
- return await conn.query({
30
- text: this.text,
31
- name: this.name,
32
- values: params
33
- })
34
- .then(result => result.rows);
35
- }
36
- finally {
37
- conn.release();
38
- }
39
- }
40
- }
41
- exports.PoolPreparedStatement = PoolPreparedStatement;
@@ -1,6 +0,0 @@
1
- import { CompiledSqlQuery, CompileSQLParams } from "./types";
2
- export declare class QueryCacher {
3
- private readonly cache;
4
- cachedBuild(params: CompileSQLParams): CompiledSqlQuery;
5
- }
6
- //# sourceMappingURL=query.cacher.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"query.cacher.d.ts","sourceRoot":"","sources":["../src/query.cacher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAI7D,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyE;IAExF,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB;CAgBjE"}
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QueryCacher = void 0;
4
- const abstract_clause_1 = require("./clauses/abstract.clause");
5
- const utils_1 = require("./utils");
6
- class QueryCacher {
7
- constructor() {
8
- this.cache = new WeakMap();
9
- }
10
- cachedBuild(params) {
11
- const cached = this.cache.get(params.templates);
12
- if (cached?.isStatic) {
13
- return { text: cached.text, args: params.args, counter: params.counter };
14
- }
15
- const result = (0, utils_1.compileSqlTemplate)(params);
16
- if (!cached) {
17
- const isStatic = !params.args.some(value => value instanceof abstract_clause_1.Clause);
18
- this.cache.set(params.templates, { text: result.text, isStatic });
19
- }
20
- return result;
21
- }
22
- }
23
- exports.QueryCacher = QueryCacher;
@@ -1,6 +0,0 @@
1
- import { ColumnDescription } from "../types";
2
- declare const Parsers: Record<number, (value: string) => unknown>;
3
- export declare function parseRowValues(columns: ColumnDescription[], rows: (string | null)[][]): Record<string, any>[];
4
- export declare const setTypeParser: (typeOID: keyof typeof Parsers, parser: (value: string) => unknown) => void;
5
- export {};
6
- //# sourceMappingURL=value-parser.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"value-parser.d.ts","sourceRoot":"","sources":["../../src/utils/value-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AA+B5C,QAAA,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAkD9C,CAAA;AAMV,wBAAgB,cAAc,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CA8B7G;AAGD,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,OAAO,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,SAE9F,CAAA"}
@@ -1,96 +0,0 @@
1
- const parsePostgresArray = (v) => {
2
- if (v === '{}')
3
- return [];
4
- const str = v.substring(1, v.length - 1);
5
- const matches = str.match(/"(?:\\.|[^"\\])*"|[^,]+/g);
6
- if (!matches)
7
- return [];
8
- return matches.map(el => {
9
- const trimmed = el.trim();
10
- if (trimmed === 'NULL')
11
- return null;
12
- if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
13
- return trimmed
14
- .substring(1, trimmed.length - 1)
15
- .replace(/\\"/g, '"')
16
- .replace(/\\\\/g, '\\');
17
- }
18
- return trimmed;
19
- });
20
- };
21
- const parsePoint = (v) => {
22
- const [x, y] = v.replace(/[()]/g, '').split(',');
23
- return { x: parseFloat(x), y: parseFloat(y) };
24
- };
25
- const Parsers = {
26
- 16: (v) => v === 't', // BOOL
27
- 21: (v) => parseInt(v, 10), // INT2 (SMALLINT)
28
- 23: (v) => parseInt(v, 10), // INT4 (INTEGER)
29
- 26: (v) => parseInt(v, 10), // OID
30
- 20: (v) => parseInt(v), // INT8 (BIGINT)
31
- 700: (v) => parseFloat(v), // FLOAT4 (REAL)
32
- 701: (v) => parseFloat(v), // FLOAT8 (DOUBLE PRECISION)
33
- 1700: (v) => parseFloat(v), // NUMERIC (DECIMAL)
34
- 18: (v) => v, // CHAR
35
- 19: (v) => v, // NAME
36
- 25: (v) => v, // TEXT
37
- 1042: (v) => v, // BPCHAR (CHAR(N))
38
- 1043: (v) => v, // VARCHAR
39
- 2950: (v) => v, // UUID
40
- 17: (v) => Buffer.from(v.substring(2), 'hex'), // BYTEA
41
- 1082: (v) => new Date(v), // DATE
42
- 1114: (v) => new Date(v + 'Z'), // TIMESTAMP
43
- 1184: (v) => new Date(v), // TIMESTAMPTZ
44
- 1083: (v) => v, // TIME
45
- 1266: (v) => v, // TIMETZ
46
- 1186: (v) => v, // INTERVAL
47
- 114: (v) => JSON.parse(v), // JSON
48
- 3802: (v) => JSON.parse(v), // JSONB
49
- 869: (v) => v, // INET (IP-адреса)
50
- 650: (v) => v, // CIDR
51
- 829: (v) => v, // MACADDR
52
- 600: parsePoint, // POINT
53
- 603: (v) => v.replace(/[()]/g, '') // POLYGON
54
- .split(',')
55
- .map(parsePoint),
56
- 1000: (v) => parsePostgresArray(v).map(el => el === 't'),
57
- 1005: (v) => parsePostgresArray(v).map(el => parseInt(el, 10)),
58
- 1007: (v) => parsePostgresArray(v).map(el => parseInt(el, 10)), // int4[]
59
- 1016: (v) => parsePostgresArray(v).map(el => BigInt(el)), // int8[]
60
- 1021: (v) => parsePostgresArray(v).map(el => parseFloat(el)),
61
- 1022: (v) => parsePostgresArray(v).map(el => parseFloat(el)), // float8[]
62
- 1231: (v) => parsePostgresArray(v).map(el => parseFloat(el)), // numeric[]
63
- 1009: (v) => parsePostgresArray(v), // text[]
64
- 1015: (v) => parsePostgresArray(v), // varchar[]
65
- 199: (v) => parsePostgresArray(v).map(el => JSON.parse(el)), // json[]
66
- 3807: (v) => parsePostgresArray(v).map(el => JSON.parse(el)), // jsonb[]
67
- };
68
- const defaultParser = (v) => v;
69
- export function parseRowValues(columns, rows) {
70
- const result = [];
71
- const columnsLength = columns.length;
72
- const columnParsers = columns.map(col => Parsers[col.typeOID] || defaultParser);
73
- for (let r = 0; r < rows.length; r++) {
74
- const rawRow = rows[r];
75
- const rowObject = {};
76
- for (let c = 0; c < columnsLength; c++) {
77
- const val = rawRow[c];
78
- const colName = columns[c].name;
79
- if (val === null) {
80
- rowObject[colName] = null;
81
- continue;
82
- }
83
- try {
84
- rowObject[colName] = columnParsers[c](val);
85
- }
86
- catch {
87
- rowObject[colName] = val;
88
- }
89
- }
90
- result.push(rowObject);
91
- }
92
- return result;
93
- }
94
- export const setTypeParser = (typeOID, parser) => {
95
- Parsers[typeOID] = parser;
96
- };
package/dist/utils.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { CompiledSqlQuery, CompileSQLParams } from "./types";
2
- export declare function compileSqlTemplate(params: Readonly<CompileSQLParams>): CompiledSqlQuery;
3
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAIlF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAgCvF"}
package/dist/utils.js DELETED
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.compileSqlTemplate = compileSqlTemplate;
4
- const abstract_clause_1 = require("./clauses/abstract.clause");
5
- function compileSqlTemplate(params) {
6
- const templateLength = params.templates.length;
7
- const query = {
8
- text: [],
9
- args: [],
10
- counter: params.counter
11
- };
12
- params.templates.forEach((template, index) => {
13
- query.text.push(template);
14
- if (index === templateLength - 1)
15
- return;
16
- const value = params.args[index];
17
- if (value instanceof abstract_clause_1.Clause) {
18
- value.mapIntoQuery(query);
19
- }
20
- else {
21
- if (value === undefined) {
22
- throw new TypeError(`Query parameter at position ${query.counter} is undefined.
23
- Use null if you want NULL in SQL, or ensure the value is defined.`);
24
- }
25
- query.args.push(value);
26
- query.text.push(`$${query.counter++}`);
27
- }
28
- });
29
- return { ...query, text: query.text.join('') };
30
- }