@slonik/driver 48.12.2 → 48.13.0
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 +1 -1
- package/dist/Logger.js +2 -2
- package/dist/factories/createDriverFactory.d.ts +17 -17
- package/dist/factories/createDriverFactory.d.ts.map +1 -1
- package/dist/factories/createDriverFactory.js +59 -59
- package/dist/factories/createDriverFactory.js.map +1 -1
- package/dist/factories/createDriverFactory.test.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +37 -41
- package/src/Logger.ts +2 -2
- package/src/factories/createDriverFactory.test.ts +2 -2
- package/src/factories/createDriverFactory.ts +83 -90
- package/src/index.ts +1 -1
package/README.md
CHANGED
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
Slonik driver is an abstraction layer that provides a consistent API for interacting using different PostgreSQL clients.
|
|
4
4
|
|
|
5
|
-
This package is made available for developers who wish to create their own Slonik driver.
|
|
5
|
+
This package is made available for developers who wish to create their own Slonik driver.
|
package/dist/Logger.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Field } from
|
|
2
|
-
import EventEmitter from
|
|
3
|
-
import type { Readable } from
|
|
4
|
-
import type { ConnectionOptions as TlsConnectionOptions } from
|
|
5
|
-
import type { StrictEventEmitter } from
|
|
1
|
+
import type { Field } from "@slonik/types";
|
|
2
|
+
import EventEmitter from "node:events";
|
|
3
|
+
import type { Readable } from "node:stream";
|
|
4
|
+
import type { ConnectionOptions as TlsConnectionOptions } from "node:tls";
|
|
5
|
+
import type { StrictEventEmitter } from "strict-event-emitter-types";
|
|
6
6
|
export type Driver = {
|
|
7
7
|
createClient: () => Promise<DriverClient>;
|
|
8
8
|
};
|
|
@@ -10,11 +10,11 @@ export type DriverClient = {
|
|
|
10
10
|
acquire: () => void;
|
|
11
11
|
destroy: () => Promise<void>;
|
|
12
12
|
id: () => string;
|
|
13
|
-
off: DriverClientEventEmitter[
|
|
14
|
-
on: DriverClientEventEmitter[
|
|
13
|
+
off: DriverClientEventEmitter["off"];
|
|
14
|
+
on: DriverClientEventEmitter["on"];
|
|
15
15
|
query: (query: string, values?: unknown[], queryOptions?: DriverQueryOptions) => Promise<DriverQueryResult>;
|
|
16
16
|
release: () => Promise<void>;
|
|
17
|
-
removeListener: DriverClientEventEmitter[
|
|
17
|
+
removeListener: DriverClientEventEmitter["removeListener"];
|
|
18
18
|
state: () => DriverClientState;
|
|
19
19
|
stream: (query: string, values?: unknown[]) => DriverStream<DriverStreamResult>;
|
|
20
20
|
};
|
|
@@ -25,20 +25,20 @@ export type DriverClientEventEmitter = StrictEventEmitter<EventEmitter, {
|
|
|
25
25
|
notice: (event: DriverNotice) => void;
|
|
26
26
|
release: () => void;
|
|
27
27
|
}>;
|
|
28
|
-
export type DriverClientState =
|
|
29
|
-
export type DriverCommand =
|
|
28
|
+
export type DriverClientState = "ACQUIRED" | "DESTROYED" | "IDLE" | "PENDING_DESTROY" | "PENDING_RELEASE";
|
|
29
|
+
export type DriverCommand = "COPY" | "DELETE" | "INSERT" | "SELECT" | "UPDATE";
|
|
30
30
|
export type DriverConfiguration = {
|
|
31
|
-
readonly connectionTimeout:
|
|
31
|
+
readonly connectionTimeout: "DISABLE_TIMEOUT" | number;
|
|
32
32
|
readonly connectionUri: string;
|
|
33
33
|
readonly gracefulTerminationTimeout?: number;
|
|
34
|
-
readonly idleInTransactionSessionTimeout:
|
|
35
|
-
readonly idleTimeout?:
|
|
36
|
-
readonly maximumConnectionAge?: number;
|
|
34
|
+
readonly idleInTransactionSessionTimeout: "DISABLE_TIMEOUT" | number;
|
|
35
|
+
readonly idleTimeout?: "DISABLE_TIMEOUT" | number;
|
|
36
|
+
readonly maximumConnectionAge?: "DISABLE_TIMEOUT" | number;
|
|
37
37
|
readonly maximumPoolSize?: number;
|
|
38
38
|
readonly minimumPoolSize?: number;
|
|
39
39
|
readonly resetConnection?: (connection: BasicConnection) => Promise<void>;
|
|
40
40
|
readonly ssl?: TlsConnectionOptions;
|
|
41
|
-
readonly statementTimeout:
|
|
41
|
+
readonly statementTimeout: "DISABLE_TIMEOUT" | number;
|
|
42
42
|
readonly typeParsers: readonly DriverTypeParser[];
|
|
43
43
|
};
|
|
44
44
|
export type DriverEventEmitter = StrictEventEmitter<EventEmitter, {
|
|
@@ -64,9 +64,9 @@ export type DriverQueryResult = {
|
|
|
64
64
|
readonly rowCount: null | number;
|
|
65
65
|
readonly rows: Array<Record<string, unknown>>;
|
|
66
66
|
};
|
|
67
|
-
export interface DriverStream<T> extends Omit<Readable,
|
|
67
|
+
export interface DriverStream<T> extends Omit<Readable, "on" | typeof Symbol.asyncIterator> {
|
|
68
68
|
[Symbol.asyncIterator]: () => AsyncIterableIterator<StreamDataEvent<T>>;
|
|
69
|
-
on: ((event:
|
|
69
|
+
on: ((event: "data", listener: (chunk: StreamDataEvent<T>) => void) => this) & ((event: string | symbol, listener: (...args: any[]) => void) => this);
|
|
70
70
|
}
|
|
71
71
|
export type DriverStreamResult = {
|
|
72
72
|
readonly fields: DriverField[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDriverFactory.d.ts","sourceRoot":"","sources":["../../src/factories/createDriverFactory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,YAAY,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"createDriverFactory.d.ts","sourceRoot":"","sources":["../../src/factories/createDriverFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/consistent-type-definitions */
|
|
2
|
-
import { Logger } from
|
|
3
|
-
import { generateUid } from
|
|
4
|
-
import EventEmitter from
|
|
5
|
-
import {
|
|
6
|
-
|
|
2
|
+
import { Logger } from "../Logger.js";
|
|
3
|
+
import { generateUid } from "@slonik/utilities";
|
|
4
|
+
import EventEmitter from "node:events";
|
|
5
|
+
import { serializeError } from "serialize-error";
|
|
6
|
+
const delay = (ms) => new Promise((resolve) => {
|
|
7
|
+
const timer = setTimeout(resolve, ms);
|
|
8
|
+
timer.unref();
|
|
9
|
+
});
|
|
7
10
|
export const createDriverFactory = (setup) => {
|
|
8
11
|
return async ({ driverConfiguration }) => {
|
|
9
12
|
const { resetConnection } = driverConfiguration;
|
|
@@ -27,10 +30,10 @@ export const createDriverFactory = (setup) => {
|
|
|
27
30
|
}
|
|
28
31
|
Logger.warn({
|
|
29
32
|
error: serializeError(error),
|
|
30
|
-
namespace:
|
|
31
|
-
},
|
|
33
|
+
namespace: "driverClient",
|
|
34
|
+
}, "unhandled driver client error");
|
|
32
35
|
};
|
|
33
|
-
clientEventEmitter.on(
|
|
36
|
+
clientEventEmitter.on("error", onError);
|
|
34
37
|
const { connect, end, query, stream } = await createPoolClient({
|
|
35
38
|
clientEventEmitter,
|
|
36
39
|
});
|
|
@@ -49,26 +52,26 @@ export const createDriverFactory = (setup) => {
|
|
|
49
52
|
};
|
|
50
53
|
const state = () => {
|
|
51
54
|
if (destroyPromise) {
|
|
52
|
-
return
|
|
55
|
+
return "PENDING_DESTROY";
|
|
53
56
|
}
|
|
54
57
|
if (releasePromise) {
|
|
55
|
-
return
|
|
58
|
+
return "PENDING_RELEASE";
|
|
56
59
|
}
|
|
57
60
|
if (isDestroyed) {
|
|
58
|
-
return
|
|
61
|
+
return "DESTROYED";
|
|
59
62
|
}
|
|
60
63
|
if (isAcquired) {
|
|
61
|
-
return
|
|
64
|
+
return "ACQUIRED";
|
|
62
65
|
}
|
|
63
|
-
return
|
|
66
|
+
return "IDLE";
|
|
64
67
|
};
|
|
65
68
|
const internalDestroy = async () => {
|
|
66
69
|
const currentState = state();
|
|
67
|
-
if (currentState ===
|
|
68
|
-
throw new Error(
|
|
70
|
+
if (currentState === "PENDING_DESTROY") {
|
|
71
|
+
throw new Error("Client is pending destroy.");
|
|
69
72
|
}
|
|
70
|
-
if (currentState ===
|
|
71
|
-
throw new Error(
|
|
73
|
+
if (currentState === "DESTROYED") {
|
|
74
|
+
throw new Error("Client is destroyed.");
|
|
72
75
|
}
|
|
73
76
|
clearIdleTimeout();
|
|
74
77
|
// activeQueryPromise and releasePromise are mutually exclusive
|
|
@@ -84,17 +87,14 @@ export const createDriverFactory = (setup) => {
|
|
|
84
87
|
]);
|
|
85
88
|
}
|
|
86
89
|
isDestroyed = true;
|
|
87
|
-
clientEventEmitter.emit(
|
|
90
|
+
clientEventEmitter.emit("destroy");
|
|
88
91
|
// end() calls pg client.end() which sends a termination message and
|
|
89
92
|
// waits for the TCP connection to close. On broken connections (half-open
|
|
90
93
|
// TCP, network partition) this can hang indefinitely. Apply the same
|
|
91
94
|
// graceful termination timeout to prevent leaked promises that block
|
|
92
95
|
// pool.end() and callers awaiting connection.destroy().
|
|
93
|
-
await Promise.race([
|
|
94
|
-
|
|
95
|
-
delay(driverConfiguration.gracefulTerminationTimeout),
|
|
96
|
-
]);
|
|
97
|
-
clientEventEmitter.off('error', onError);
|
|
96
|
+
await Promise.race([end(), delay(driverConfiguration.gracefulTerminationTimeout)]);
|
|
97
|
+
clientEventEmitter.off("error", onError);
|
|
98
98
|
};
|
|
99
99
|
destroy = async () => {
|
|
100
100
|
if (destroyPromise) {
|
|
@@ -105,17 +105,17 @@ export const createDriverFactory = (setup) => {
|
|
|
105
105
|
};
|
|
106
106
|
const internalRelease = async () => {
|
|
107
107
|
const currentState = state();
|
|
108
|
-
if (currentState ===
|
|
109
|
-
throw new Error(
|
|
108
|
+
if (currentState === "PENDING_DESTROY") {
|
|
109
|
+
throw new Error("Client is pending destroy.");
|
|
110
110
|
}
|
|
111
|
-
if (currentState ===
|
|
112
|
-
throw new Error(
|
|
111
|
+
if (currentState === "DESTROYED") {
|
|
112
|
+
throw new Error("Client is destroyed.");
|
|
113
113
|
}
|
|
114
|
-
if (currentState !==
|
|
115
|
-
throw new Error(
|
|
114
|
+
if (currentState !== "ACQUIRED") {
|
|
115
|
+
throw new Error("Client is not acquired.");
|
|
116
116
|
}
|
|
117
117
|
if (activeQueryPromise) {
|
|
118
|
-
throw new Error(
|
|
118
|
+
throw new Error("Client has an active query.");
|
|
119
119
|
}
|
|
120
120
|
if (resetConnection) {
|
|
121
121
|
await resetConnection({
|
|
@@ -124,7 +124,7 @@ export const createDriverFactory = (setup) => {
|
|
|
124
124
|
},
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
|
-
if (driverConfiguration.idleTimeout !==
|
|
127
|
+
if (driverConfiguration.idleTimeout !== "DISABLE_TIMEOUT") {
|
|
128
128
|
clearIdleTimeout();
|
|
129
129
|
idleTimeout = setTimeout(() => {
|
|
130
130
|
void destroy();
|
|
@@ -133,7 +133,7 @@ export const createDriverFactory = (setup) => {
|
|
|
133
133
|
}
|
|
134
134
|
isAcquired = false;
|
|
135
135
|
releasePromise = null;
|
|
136
|
-
clientEventEmitter.emit(
|
|
136
|
+
clientEventEmitter.emit("release");
|
|
137
137
|
};
|
|
138
138
|
const release = () => {
|
|
139
139
|
if (destroyPromise) {
|
|
@@ -148,21 +148,21 @@ export const createDriverFactory = (setup) => {
|
|
|
148
148
|
const client = {
|
|
149
149
|
acquire: () => {
|
|
150
150
|
const currentState = state();
|
|
151
|
-
if (currentState ===
|
|
152
|
-
throw new Error(
|
|
151
|
+
if (currentState === "PENDING_DESTROY") {
|
|
152
|
+
throw new Error("Client is pending destroy.");
|
|
153
153
|
}
|
|
154
|
-
if (currentState ===
|
|
155
|
-
throw new Error(
|
|
154
|
+
if (currentState === "PENDING_RELEASE") {
|
|
155
|
+
throw new Error("Client is pending release.");
|
|
156
156
|
}
|
|
157
|
-
if (currentState ===
|
|
158
|
-
throw new Error(
|
|
157
|
+
if (currentState === "DESTROYED") {
|
|
158
|
+
throw new Error("Client is destroyed.");
|
|
159
159
|
}
|
|
160
|
-
if (currentState ===
|
|
161
|
-
throw new Error(
|
|
160
|
+
if (currentState === "ACQUIRED") {
|
|
161
|
+
throw new Error("Client is already acquired.");
|
|
162
162
|
}
|
|
163
163
|
clearIdleTimeout();
|
|
164
164
|
isAcquired = true;
|
|
165
|
-
clientEventEmitter.emit(
|
|
165
|
+
clientEventEmitter.emit("acquire");
|
|
166
166
|
},
|
|
167
167
|
destroy,
|
|
168
168
|
id: () => id,
|
|
@@ -174,23 +174,23 @@ export const createDriverFactory = (setup) => {
|
|
|
174
174
|
},
|
|
175
175
|
query: async (sql, values, queryOptions) => {
|
|
176
176
|
const currentState = state();
|
|
177
|
-
if (currentState ===
|
|
178
|
-
throw new Error(
|
|
177
|
+
if (currentState === "PENDING_DESTROY") {
|
|
178
|
+
throw new Error("Client is pending destroy.");
|
|
179
179
|
}
|
|
180
|
-
if (currentState ===
|
|
181
|
-
throw new Error(
|
|
180
|
+
if (currentState === "PENDING_RELEASE") {
|
|
181
|
+
throw new Error("Client is pending release.");
|
|
182
182
|
}
|
|
183
|
-
if (currentState ===
|
|
184
|
-
throw new Error(
|
|
183
|
+
if (currentState === "DESTROYED") {
|
|
184
|
+
throw new Error("Client is destroyed.");
|
|
185
185
|
}
|
|
186
|
-
if (currentState !==
|
|
187
|
-
throw new Error(
|
|
186
|
+
if (currentState !== "ACQUIRED") {
|
|
187
|
+
throw new Error("Client is not acquired.");
|
|
188
188
|
}
|
|
189
189
|
try {
|
|
190
190
|
activeQueryPromise = query(sql, values, queryOptions);
|
|
191
191
|
const result = await activeQueryPromise;
|
|
192
192
|
if (!activeQueryPromise) {
|
|
193
|
-
throw new Error(
|
|
193
|
+
throw new Error("Expected `activeQueryPromise` to be set.");
|
|
194
194
|
}
|
|
195
195
|
return result;
|
|
196
196
|
}
|
|
@@ -205,17 +205,17 @@ export const createDriverFactory = (setup) => {
|
|
|
205
205
|
state,
|
|
206
206
|
stream: (sql, values) => {
|
|
207
207
|
const currentState = state();
|
|
208
|
-
if (currentState ===
|
|
209
|
-
throw new Error(
|
|
208
|
+
if (currentState === "PENDING_DESTROY") {
|
|
209
|
+
throw new Error("Client is pending destroy.");
|
|
210
210
|
}
|
|
211
|
-
if (currentState ===
|
|
212
|
-
throw new Error(
|
|
211
|
+
if (currentState === "PENDING_RELEASE") {
|
|
212
|
+
throw new Error("Client is pending release.");
|
|
213
213
|
}
|
|
214
|
-
if (currentState ===
|
|
215
|
-
throw new Error(
|
|
214
|
+
if (currentState === "DESTROYED") {
|
|
215
|
+
throw new Error("Client is destroyed.");
|
|
216
216
|
}
|
|
217
|
-
if (currentState !==
|
|
218
|
-
throw new Error(
|
|
217
|
+
if (currentState !== "ACQUIRED") {
|
|
218
|
+
throw new Error("Client is not acquired.");
|
|
219
219
|
}
|
|
220
220
|
// Note: Stream lifecycle management should be handled by the caller.
|
|
221
221
|
// The client can be released while streaming, but the stream will continue to work.
|
|
@@ -226,7 +226,7 @@ export const createDriverFactory = (setup) => {
|
|
|
226
226
|
await connect();
|
|
227
227
|
}
|
|
228
228
|
catch (error) {
|
|
229
|
-
clientEventEmitter.off(
|
|
229
|
+
clientEventEmitter.off("error", onError);
|
|
230
230
|
throw error;
|
|
231
231
|
}
|
|
232
232
|
return client;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDriverFactory.js","sourceRoot":"","sources":["../../src/factories/createDriverFactory.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,YAAY,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"createDriverFactory.js","sourceRoot":"","sources":["../../src/factories/createDriverFactory.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,YAAY,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,KAAK,GAAG,CAAC,EAAsB,EAAE,EAAE,CACvC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;IAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACtC,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC,CAAC,CAAC;AAyJL,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAkB,EAAiB,EAAE;IACvE,OAAO,KAAK,EAAE,EAAE,mBAAmB,EAAE,EAAmB,EAAE;QACxD,MAAM,EAAE,eAAe,EAAE,GAAG,mBAAmB,CAAC;QAEhD,MAAM,kBAAkB,GAAuB,IAAI,YAAY,EAAE,CAAC;QAElE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,KAAK,CAAC;YACvC,mBAAmB;YACnB,kBAAkB;SACnB,CAAC,CAAC;QAEH,OAAO;YACL,YAAY,EAAE,KAAK,IAAI,EAAE;gBACvB,MAAM,kBAAkB,GAA6B,IAAI,YAAY,EAAE,CAAC;gBAExE,wCAAwC;gBACxC,IAAI,OAA4B,CAAC;gBAEjC,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,EAAE;oBAC/B,IAAI,OAAO,EAAE,CAAC;wBACZ,wDAAwD;wBACxD,KAAK,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;4BACxB,kDAAkD;4BAClD,qDAAqD;wBACvD,CAAC,CAAC,CAAC;oBACL,CAAC;oBAED,MAAM,CAAC,IAAI,CACT;wBACE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC;wBAC5B,SAAS,EAAE,cAAc;qBAC1B,EACD,+BAA+B,CAChC,CAAC;gBACJ,CAAC,CAAC;gBAEF,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAExC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC;oBAC7D,kBAAkB;iBACnB,CAAC,CAAC;gBAEH,IAAI,UAAU,GAAG,KAAK,CAAC;gBACvB,IAAI,WAAW,GAAG,KAAK,CAAC;gBACxB,IAAI,WAAW,GAA0B,IAAI,CAAC;gBAE9C,IAAI,kBAAkB,GAAsC,IAAI,CAAC;gBACjE,IAAI,cAAc,GAAyB,IAAI,CAAC;gBAChD,IAAI,cAAc,GAAyB,IAAI,CAAC;gBAEhD,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;gBAEzB,MAAM,gBAAgB,GAAG,GAAG,EAAE;oBAC5B,IAAI,WAAW,EAAE,CAAC;wBAChB,YAAY,CAAC,WAAW,CAAC,CAAC;wBAE1B,WAAW,GAAG,IAAI,CAAC;oBACrB,CAAC;gBACH,CAAC,CAAC;gBAEF,MAAM,KAAK,GAAG,GAAG,EAAE;oBACjB,IAAI,cAAc,EAAE,CAAC;wBACnB,OAAO,iBAAiB,CAAC;oBAC3B,CAAC;oBAED,IAAI,cAAc,EAAE,CAAC;wBACnB,OAAO,iBAAiB,CAAC;oBAC3B,CAAC;oBAED,IAAI,WAAW,EAAE,CAAC;wBAChB,OAAO,WAAW,CAAC;oBACrB,CAAC;oBAED,IAAI,UAAU,EAAE,CAAC;wBACf,OAAO,UAAU,CAAC;oBACpB,CAAC;oBAED,OAAO,MAAM,CAAC;gBAChB,CAAC,CAAC;gBAEF,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;oBACjC,MAAM,YAAY,GAAG,KAAK,EAAE,CAAC;oBAE7B,IAAI,YAAY,KAAK,iBAAiB,EAAE,CAAC;wBACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;oBAChD,CAAC;oBAED,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;wBACjC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;oBAC1C,CAAC;oBAED,gBAAgB,EAAE,CAAC;oBAEnB,+DAA+D;oBAC/D,oEAAoE;oBACpE,qEAAqE;oBACrE,6DAA6D;oBAC7D,wEAAwE;oBACxE,MAAM,gBAAgB,GAAG,kBAAkB,IAAI,cAAc,CAAC;oBAE9D,IAAI,gBAAgB,EAAE,CAAC;wBACrB,MAAM,OAAO,CAAC,IAAI,CAAC;4BACjB,KAAK,CAAC,mBAAmB,CAAC,0BAA0B,CAAC;4BACrD,gBAAgB;yBACjB,CAAC,CAAC;oBACL,CAAC;oBAED,WAAW,GAAG,IAAI,CAAC;oBAEnB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAEnC,oEAAoE;oBACpE,0EAA0E;oBAC1E,qEAAqE;oBACrE,qEAAqE;oBACrE,wDAAwD;oBACxD,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,mBAAmB,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC;oBAEnF,kBAAkB,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC3C,CAAC,CAAC;gBAEF,OAAO,GAAG,KAAK,IAAI,EAAE;oBACnB,IAAI,cAAc,EAAE,CAAC;wBACnB,OAAO,cAAc,CAAC;oBACxB,CAAC;oBAED,cAAc,GAAG,eAAe,EAAE,CAAC;oBAEnC,OAAO,cAAc,CAAC;gBACxB,CAAC,CAAC;gBAEF,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;oBACjC,MAAM,YAAY,GAAG,KAAK,EAAE,CAAC;oBAE7B,IAAI,YAAY,KAAK,iBAAiB,EAAE,CAAC;wBACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;oBAChD,CAAC;oBAED,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;wBACjC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;oBAC1C,CAAC;oBAED,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;wBAChC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;oBAC7C,CAAC;oBAED,IAAI,kBAAkB,EAAE,CAAC;wBACvB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;oBACjD,CAAC;oBAED,IAAI,eAAe,EAAE,CAAC;wBACpB,MAAM,eAAe,CAAC;4BACpB,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gCACnB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;4BACnB,CAAC;yBACF,CAAC,CAAC;oBACL,CAAC;oBAED,IAAI,mBAAmB,CAAC,WAAW,KAAK,iBAAiB,EAAE,CAAC;wBAC1D,gBAAgB,EAAE,CAAC;wBAEnB,WAAW,GAAG,UAAU,CAAC,GAAG,EAAE;4BAC5B,KAAK,OAAO,EAAE,CAAC;4BAEf,WAAW,GAAG,IAAI,CAAC;wBACrB,CAAC,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;oBAChD,CAAC;oBAED,UAAU,GAAG,KAAK,CAAC;oBAEnB,cAAc,GAAG,IAAI,CAAC;oBAEtB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACrC,CAAC,CAAC;gBAEF,MAAM,OAAO,GAAG,GAAG,EAAE;oBACnB,IAAI,cAAc,EAAE,CAAC;wBACnB,OAAO,cAAc,CAAC;oBACxB,CAAC;oBAED,IAAI,cAAc,EAAE,CAAC;wBACnB,OAAO,cAAc,CAAC;oBACxB,CAAC;oBAED,cAAc,GAAG,eAAe,EAAE,CAAC;oBAEnC,OAAO,cAAc,CAAC;gBACxB,CAAC,CAAC;gBAEF,MAAM,MAAM,GAAG;oBACb,OAAO,EAAE,GAAG,EAAE;wBACZ,MAAM,YAAY,GAAG,KAAK,EAAE,CAAC;wBAE7B,IAAI,YAAY,KAAK,iBAAiB,EAAE,CAAC;4BACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;wBAChD,CAAC;wBAED,IAAI,YAAY,KAAK,iBAAiB,EAAE,CAAC;4BACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;wBAChD,CAAC;wBAED,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;4BACjC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;wBAC1C,CAAC;wBAED,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;4BAChC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;wBACjD,CAAC;wBAED,gBAAgB,EAAE,CAAC;wBAEnB,UAAU,GAAG,IAAI,CAAC;wBAElB,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACrC,CAAC;oBACD,OAAO;oBACP,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;oBACZ,GAAG,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;wBACvB,OAAO,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;oBACjD,CAAC;oBACD,EAAE,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;wBACtB,OAAO,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;oBAChD,CAAC;oBACD,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE;wBACzC,MAAM,YAAY,GAAG,KAAK,EAAE,CAAC;wBAE7B,IAAI,YAAY,KAAK,iBAAiB,EAAE,CAAC;4BACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;wBAChD,CAAC;wBAED,IAAI,YAAY,KAAK,iBAAiB,EAAE,CAAC;4BACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;wBAChD,CAAC;wBAED,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;4BACjC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;wBAC1C,CAAC;wBAED,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;4BAChC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;wBAC7C,CAAC;wBAED,IAAI,CAAC;4BACH,kBAAkB,GAAG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;4BAEtD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;4BAExC,IAAI,CAAC,kBAAkB,EAAE,CAAC;gCACxB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;4BAC9D,CAAC;4BAED,OAAO,MAAM,CAAC;wBAChB,CAAC;gCAAS,CAAC;4BACT,kBAAkB,GAAG,IAAI,CAAC;wBAC5B,CAAC;oBACH,CAAC;oBACD,OAAO;oBACP,cAAc,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;wBAClC,OAAO,kBAAkB,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;oBAC5D,CAAC;oBACD,KAAK;oBACL,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;wBACtB,MAAM,YAAY,GAAG,KAAK,EAAE,CAAC;wBAE7B,IAAI,YAAY,KAAK,iBAAiB,EAAE,CAAC;4BACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;wBAChD,CAAC;wBAED,IAAI,YAAY,KAAK,iBAAiB,EAAE,CAAC;4BACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;wBAChD,CAAC;wBAED,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;4BACjC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;wBAC1C,CAAC;wBAED,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;4BAChC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;wBAC7C,CAAC;wBAED,qEAAqE;wBACrE,oFAAoF;wBAEpF,OAAO,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;oBAC7B,CAAC;iBACF,CAAC;gBAEF,IAAI,CAAC;oBACH,MAAM,OAAO,EAAE,CAAC;gBAClB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,kBAAkB,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBAEzC,MAAM,KAAK,CAAC;gBACd,CAAC;gBAED,OAAO,MAAM,CAAC;YAChB,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { createDriverFactory, type Driver, type DriverClient, type DriverClientEventEmitter, type DriverClientState, type DriverCommand, type DriverConfiguration, type DriverEventEmitter, type DriverFactory, type DriverNotice, type DriverQueryOptions, type DriverQueryResult, type DriverStream, type DriverStreamResult, type DriverTypeParser, } from
|
|
1
|
+
export { createDriverFactory, type Driver, type DriverClient, type DriverClientEventEmitter, type DriverClientState, type DriverCommand, type DriverConfiguration, type DriverEventEmitter, type DriverFactory, type DriverNotice, type DriverQueryOptions, type DriverQueryResult, type DriverStream, type DriverStreamResult, type DriverTypeParser, } from "./factories/createDriverFactory.js";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { createDriverFactory, } from
|
|
1
|
+
export { createDriverFactory, } from "./factories/createDriverFactory.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,68 +1,64 @@
|
|
|
1
1
|
{
|
|
2
|
+
"name": "@slonik/driver",
|
|
3
|
+
"version": "48.13.0",
|
|
4
|
+
"description": "A Node.js PostgreSQL client with strict types, detailed logging and assertions.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"postgresql",
|
|
7
|
+
"promise",
|
|
8
|
+
"types"
|
|
9
|
+
],
|
|
10
|
+
"license": "BSD-3-Clause",
|
|
2
11
|
"author": {
|
|
3
|
-
"email": "gajus@gajus.com",
|
|
4
12
|
"name": "Gajus Kuizinas",
|
|
13
|
+
"email": "gajus@gajus.com",
|
|
5
14
|
"url": "http://gajus.com"
|
|
6
15
|
},
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
],
|
|
11
|
-
"files": [
|
|
12
|
-
"src/**/*.test.ts"
|
|
13
|
-
],
|
|
14
|
-
"nodeArguments": [
|
|
15
|
-
"--import=tsimp"
|
|
16
|
-
]
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/gajus/slonik"
|
|
17
19
|
},
|
|
20
|
+
"files": [
|
|
21
|
+
"./src",
|
|
22
|
+
"./dist"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
18
27
|
"dependencies": {
|
|
19
|
-
"@slonik/types": "^48.
|
|
20
|
-
"@slonik/utilities": "^48.
|
|
28
|
+
"@slonik/types": "^48.13.0",
|
|
29
|
+
"@slonik/utilities": "^48.13.0",
|
|
21
30
|
"roarr": "^7.21.4",
|
|
22
31
|
"serialize-error": "^12.0.0",
|
|
23
32
|
"strict-event-emitter-types": "^2.0.0"
|
|
24
33
|
},
|
|
25
|
-
"description": "A Node.js PostgreSQL client with strict types, detailed logging and assertions.",
|
|
26
34
|
"devDependencies": {
|
|
27
35
|
"@types/node": "^24.10.13",
|
|
28
36
|
"ava": "^6.4.1",
|
|
29
37
|
"cspell": "^9.6.4",
|
|
30
|
-
"eslint": "9.39.2",
|
|
31
38
|
"tsimp": "^2.0.12",
|
|
32
|
-
"typescript": "^5.9.3"
|
|
33
|
-
"typescript-eslint": "^8.55.0",
|
|
34
|
-
"@slonik/eslint-config": "^48.12.2"
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=24"
|
|
39
|
+
"typescript": "^5.9.3"
|
|
38
40
|
},
|
|
39
|
-
"files": [
|
|
40
|
-
"./src",
|
|
41
|
-
"./dist"
|
|
42
|
-
],
|
|
43
|
-
"keywords": [
|
|
44
|
-
"postgresql",
|
|
45
|
-
"promise",
|
|
46
|
-
"types"
|
|
47
|
-
],
|
|
48
|
-
"license": "BSD-3-Clause",
|
|
49
|
-
"main": "./dist/index.js",
|
|
50
|
-
"name": "@slonik/driver",
|
|
51
41
|
"peerDependencies": {
|
|
52
42
|
"zod": "^3.25 || ^4"
|
|
53
43
|
},
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
|
|
44
|
+
"ava": {
|
|
45
|
+
"extensions": [
|
|
46
|
+
"ts"
|
|
47
|
+
],
|
|
48
|
+
"files": [
|
|
49
|
+
"src/**/*.test.ts"
|
|
50
|
+
],
|
|
51
|
+
"nodeArguments": [
|
|
52
|
+
"--import=tsimp"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=24"
|
|
57
57
|
},
|
|
58
|
-
"type": "module",
|
|
59
|
-
"types": "./dist/index.d.ts",
|
|
60
|
-
"version": "48.12.2",
|
|
61
58
|
"scripts": {
|
|
62
59
|
"build": "rm -fr ./dist && tsc --project ./tsconfig.json",
|
|
63
|
-
"lint": "npm run lint:cspell && npm run lint:
|
|
60
|
+
"lint": "npm run lint:cspell && npm run lint:tsc",
|
|
64
61
|
"lint:cspell": "cspell . --no-progress --gitignore",
|
|
65
|
-
"lint:eslint": "eslint --cache ./src",
|
|
66
62
|
"lint:tsc": "tsc --noEmit",
|
|
67
63
|
"test": "ava --verbose --serial"
|
|
68
64
|
}
|
package/src/Logger.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/consistent-type-definitions */
|
|
2
|
-
import { Logger } from
|
|
3
|
-
import type { Field } from
|
|
4
|
-
import { generateUid } from
|
|
5
|
-
import EventEmitter from
|
|
6
|
-
import type { Readable } from
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
|
|
2
|
+
import { Logger } from "../Logger.js";
|
|
3
|
+
import type { Field } from "@slonik/types";
|
|
4
|
+
import { generateUid } from "@slonik/utilities";
|
|
5
|
+
import EventEmitter from "node:events";
|
|
6
|
+
import type { Readable } from "node:stream";
|
|
7
|
+
import type { ConnectionOptions as TlsConnectionOptions } from "node:tls";
|
|
8
|
+
import { serializeError } from "serialize-error";
|
|
9
|
+
import type { StrictEventEmitter } from "strict-event-emitter-types";
|
|
10
|
+
|
|
11
|
+
const delay = (ms: number | undefined) =>
|
|
12
|
+
new Promise<void>((resolve) => {
|
|
13
|
+
const timer = setTimeout(resolve, ms);
|
|
14
|
+
timer.unref();
|
|
15
|
+
});
|
|
11
16
|
|
|
12
17
|
export type Driver = {
|
|
13
18
|
createClient: () => Promise<DriverClient>;
|
|
@@ -17,20 +22,17 @@ export type DriverClient = {
|
|
|
17
22
|
acquire: () => void;
|
|
18
23
|
destroy: () => Promise<void>;
|
|
19
24
|
id: () => string;
|
|
20
|
-
off: DriverClientEventEmitter[
|
|
21
|
-
on: DriverClientEventEmitter[
|
|
25
|
+
off: DriverClientEventEmitter["off"];
|
|
26
|
+
on: DriverClientEventEmitter["on"];
|
|
22
27
|
query: (
|
|
23
28
|
query: string,
|
|
24
29
|
values?: unknown[],
|
|
25
30
|
queryOptions?: DriverQueryOptions,
|
|
26
31
|
) => Promise<DriverQueryResult>;
|
|
27
32
|
release: () => Promise<void>;
|
|
28
|
-
removeListener: DriverClientEventEmitter[
|
|
33
|
+
removeListener: DriverClientEventEmitter["removeListener"];
|
|
29
34
|
state: () => DriverClientState;
|
|
30
|
-
stream: (
|
|
31
|
-
query: string,
|
|
32
|
-
values?: unknown[],
|
|
33
|
-
) => DriverStream<DriverStreamResult>;
|
|
35
|
+
stream: (query: string, values?: unknown[]) => DriverStream<DriverStreamResult>;
|
|
34
36
|
};
|
|
35
37
|
|
|
36
38
|
export type DriverClientEventEmitter = StrictEventEmitter<
|
|
@@ -45,26 +47,26 @@ export type DriverClientEventEmitter = StrictEventEmitter<
|
|
|
45
47
|
>;
|
|
46
48
|
|
|
47
49
|
export type DriverClientState =
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
50
|
+
| "ACQUIRED"
|
|
51
|
+
| "DESTROYED"
|
|
52
|
+
| "IDLE"
|
|
53
|
+
| "PENDING_DESTROY"
|
|
54
|
+
| "PENDING_RELEASE";
|
|
53
55
|
|
|
54
|
-
export type DriverCommand =
|
|
56
|
+
export type DriverCommand = "COPY" | "DELETE" | "INSERT" | "SELECT" | "UPDATE";
|
|
55
57
|
|
|
56
58
|
export type DriverConfiguration = {
|
|
57
|
-
readonly connectionTimeout:
|
|
59
|
+
readonly connectionTimeout: "DISABLE_TIMEOUT" | number;
|
|
58
60
|
readonly connectionUri: string;
|
|
59
61
|
readonly gracefulTerminationTimeout?: number;
|
|
60
|
-
readonly idleInTransactionSessionTimeout:
|
|
61
|
-
readonly idleTimeout?:
|
|
62
|
-
readonly maximumConnectionAge?: number;
|
|
62
|
+
readonly idleInTransactionSessionTimeout: "DISABLE_TIMEOUT" | number;
|
|
63
|
+
readonly idleTimeout?: "DISABLE_TIMEOUT" | number;
|
|
64
|
+
readonly maximumConnectionAge?: "DISABLE_TIMEOUT" | number;
|
|
63
65
|
readonly maximumPoolSize?: number;
|
|
64
66
|
readonly minimumPoolSize?: number;
|
|
65
67
|
readonly resetConnection?: (connection: BasicConnection) => Promise<void>;
|
|
66
68
|
readonly ssl?: TlsConnectionOptions;
|
|
67
|
-
readonly statementTimeout:
|
|
69
|
+
readonly statementTimeout: "DISABLE_TIMEOUT" | number;
|
|
68
70
|
readonly typeParsers: readonly DriverTypeParser[];
|
|
69
71
|
};
|
|
70
72
|
|
|
@@ -101,12 +103,9 @@ export type DriverQueryResult = {
|
|
|
101
103
|
readonly rows: Array<Record<string, unknown>>;
|
|
102
104
|
};
|
|
103
105
|
|
|
104
|
-
export interface DriverStream<T> extends Omit<
|
|
105
|
-
Readable,
|
|
106
|
-
'on' | typeof Symbol.asyncIterator
|
|
107
|
-
> {
|
|
106
|
+
export interface DriverStream<T> extends Omit<Readable, "on" | typeof Symbol.asyncIterator> {
|
|
108
107
|
[Symbol.asyncIterator]: () => AsyncIterableIterator<StreamDataEvent<T>>;
|
|
109
|
-
on: ((event:
|
|
108
|
+
on: ((event: "data", listener: (chunk: StreamDataEvent<T>) => void) => this) &
|
|
110
109
|
((event: string | symbol, listener: (...args: any[]) => void) => this);
|
|
111
110
|
}
|
|
112
111
|
|
|
@@ -153,10 +152,7 @@ type InternalPoolClient = {
|
|
|
153
152
|
values?: unknown[],
|
|
154
153
|
queryOptions?: DriverQueryOptions,
|
|
155
154
|
) => Promise<DriverQueryResult>;
|
|
156
|
-
stream: (
|
|
157
|
-
query: string,
|
|
158
|
-
values?: unknown[],
|
|
159
|
-
) => DriverStream<DriverStreamResult>;
|
|
155
|
+
stream: (query: string, values?: unknown[]) => DriverStream<DriverStreamResult>;
|
|
160
156
|
};
|
|
161
157
|
|
|
162
158
|
type InternalPoolClientFactory = {
|
|
@@ -199,13 +195,13 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
199
195
|
Logger.warn(
|
|
200
196
|
{
|
|
201
197
|
error: serializeError(error),
|
|
202
|
-
namespace:
|
|
198
|
+
namespace: "driverClient",
|
|
203
199
|
},
|
|
204
|
-
|
|
200
|
+
"unhandled driver client error",
|
|
205
201
|
);
|
|
206
202
|
};
|
|
207
203
|
|
|
208
|
-
clientEventEmitter.on(
|
|
204
|
+
clientEventEmitter.on("error", onError);
|
|
209
205
|
|
|
210
206
|
const { connect, end, query, stream } = await createPoolClient({
|
|
211
207
|
clientEventEmitter,
|
|
@@ -231,33 +227,33 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
231
227
|
|
|
232
228
|
const state = () => {
|
|
233
229
|
if (destroyPromise) {
|
|
234
|
-
return
|
|
230
|
+
return "PENDING_DESTROY";
|
|
235
231
|
}
|
|
236
232
|
|
|
237
233
|
if (releasePromise) {
|
|
238
|
-
return
|
|
234
|
+
return "PENDING_RELEASE";
|
|
239
235
|
}
|
|
240
236
|
|
|
241
237
|
if (isDestroyed) {
|
|
242
|
-
return
|
|
238
|
+
return "DESTROYED";
|
|
243
239
|
}
|
|
244
240
|
|
|
245
241
|
if (isAcquired) {
|
|
246
|
-
return
|
|
242
|
+
return "ACQUIRED";
|
|
247
243
|
}
|
|
248
244
|
|
|
249
|
-
return
|
|
245
|
+
return "IDLE";
|
|
250
246
|
};
|
|
251
247
|
|
|
252
248
|
const internalDestroy = async () => {
|
|
253
249
|
const currentState = state();
|
|
254
250
|
|
|
255
|
-
if (currentState ===
|
|
256
|
-
throw new Error(
|
|
251
|
+
if (currentState === "PENDING_DESTROY") {
|
|
252
|
+
throw new Error("Client is pending destroy.");
|
|
257
253
|
}
|
|
258
254
|
|
|
259
|
-
if (currentState ===
|
|
260
|
-
throw new Error(
|
|
255
|
+
if (currentState === "DESTROYED") {
|
|
256
|
+
throw new Error("Client is destroyed.");
|
|
261
257
|
}
|
|
262
258
|
|
|
263
259
|
clearIdleTimeout();
|
|
@@ -278,19 +274,16 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
278
274
|
|
|
279
275
|
isDestroyed = true;
|
|
280
276
|
|
|
281
|
-
clientEventEmitter.emit(
|
|
277
|
+
clientEventEmitter.emit("destroy");
|
|
282
278
|
|
|
283
279
|
// end() calls pg client.end() which sends a termination message and
|
|
284
280
|
// waits for the TCP connection to close. On broken connections (half-open
|
|
285
281
|
// TCP, network partition) this can hang indefinitely. Apply the same
|
|
286
282
|
// graceful termination timeout to prevent leaked promises that block
|
|
287
283
|
// pool.end() and callers awaiting connection.destroy().
|
|
288
|
-
await Promise.race([
|
|
289
|
-
end(),
|
|
290
|
-
delay(driverConfiguration.gracefulTerminationTimeout),
|
|
291
|
-
]);
|
|
284
|
+
await Promise.race([end(), delay(driverConfiguration.gracefulTerminationTimeout)]);
|
|
292
285
|
|
|
293
|
-
clientEventEmitter.off(
|
|
286
|
+
clientEventEmitter.off("error", onError);
|
|
294
287
|
};
|
|
295
288
|
|
|
296
289
|
destroy = async () => {
|
|
@@ -306,20 +299,20 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
306
299
|
const internalRelease = async () => {
|
|
307
300
|
const currentState = state();
|
|
308
301
|
|
|
309
|
-
if (currentState ===
|
|
310
|
-
throw new Error(
|
|
302
|
+
if (currentState === "PENDING_DESTROY") {
|
|
303
|
+
throw new Error("Client is pending destroy.");
|
|
311
304
|
}
|
|
312
305
|
|
|
313
|
-
if (currentState ===
|
|
314
|
-
throw new Error(
|
|
306
|
+
if (currentState === "DESTROYED") {
|
|
307
|
+
throw new Error("Client is destroyed.");
|
|
315
308
|
}
|
|
316
309
|
|
|
317
|
-
if (currentState !==
|
|
318
|
-
throw new Error(
|
|
310
|
+
if (currentState !== "ACQUIRED") {
|
|
311
|
+
throw new Error("Client is not acquired.");
|
|
319
312
|
}
|
|
320
313
|
|
|
321
314
|
if (activeQueryPromise) {
|
|
322
|
-
throw new Error(
|
|
315
|
+
throw new Error("Client has an active query.");
|
|
323
316
|
}
|
|
324
317
|
|
|
325
318
|
if (resetConnection) {
|
|
@@ -330,7 +323,7 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
330
323
|
});
|
|
331
324
|
}
|
|
332
325
|
|
|
333
|
-
if (driverConfiguration.idleTimeout !==
|
|
326
|
+
if (driverConfiguration.idleTimeout !== "DISABLE_TIMEOUT") {
|
|
334
327
|
clearIdleTimeout();
|
|
335
328
|
|
|
336
329
|
idleTimeout = setTimeout(() => {
|
|
@@ -344,7 +337,7 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
344
337
|
|
|
345
338
|
releasePromise = null;
|
|
346
339
|
|
|
347
|
-
clientEventEmitter.emit(
|
|
340
|
+
clientEventEmitter.emit("release");
|
|
348
341
|
};
|
|
349
342
|
|
|
350
343
|
const release = () => {
|
|
@@ -365,27 +358,27 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
365
358
|
acquire: () => {
|
|
366
359
|
const currentState = state();
|
|
367
360
|
|
|
368
|
-
if (currentState ===
|
|
369
|
-
throw new Error(
|
|
361
|
+
if (currentState === "PENDING_DESTROY") {
|
|
362
|
+
throw new Error("Client is pending destroy.");
|
|
370
363
|
}
|
|
371
364
|
|
|
372
|
-
if (currentState ===
|
|
373
|
-
throw new Error(
|
|
365
|
+
if (currentState === "PENDING_RELEASE") {
|
|
366
|
+
throw new Error("Client is pending release.");
|
|
374
367
|
}
|
|
375
368
|
|
|
376
|
-
if (currentState ===
|
|
377
|
-
throw new Error(
|
|
369
|
+
if (currentState === "DESTROYED") {
|
|
370
|
+
throw new Error("Client is destroyed.");
|
|
378
371
|
}
|
|
379
372
|
|
|
380
|
-
if (currentState ===
|
|
381
|
-
throw new Error(
|
|
373
|
+
if (currentState === "ACQUIRED") {
|
|
374
|
+
throw new Error("Client is already acquired.");
|
|
382
375
|
}
|
|
383
376
|
|
|
384
377
|
clearIdleTimeout();
|
|
385
378
|
|
|
386
379
|
isAcquired = true;
|
|
387
380
|
|
|
388
|
-
clientEventEmitter.emit(
|
|
381
|
+
clientEventEmitter.emit("acquire");
|
|
389
382
|
},
|
|
390
383
|
destroy,
|
|
391
384
|
id: () => id,
|
|
@@ -398,20 +391,20 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
398
391
|
query: async (sql, values, queryOptions) => {
|
|
399
392
|
const currentState = state();
|
|
400
393
|
|
|
401
|
-
if (currentState ===
|
|
402
|
-
throw new Error(
|
|
394
|
+
if (currentState === "PENDING_DESTROY") {
|
|
395
|
+
throw new Error("Client is pending destroy.");
|
|
403
396
|
}
|
|
404
397
|
|
|
405
|
-
if (currentState ===
|
|
406
|
-
throw new Error(
|
|
398
|
+
if (currentState === "PENDING_RELEASE") {
|
|
399
|
+
throw new Error("Client is pending release.");
|
|
407
400
|
}
|
|
408
401
|
|
|
409
|
-
if (currentState ===
|
|
410
|
-
throw new Error(
|
|
402
|
+
if (currentState === "DESTROYED") {
|
|
403
|
+
throw new Error("Client is destroyed.");
|
|
411
404
|
}
|
|
412
405
|
|
|
413
|
-
if (currentState !==
|
|
414
|
-
throw new Error(
|
|
406
|
+
if (currentState !== "ACQUIRED") {
|
|
407
|
+
throw new Error("Client is not acquired.");
|
|
415
408
|
}
|
|
416
409
|
|
|
417
410
|
try {
|
|
@@ -420,7 +413,7 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
420
413
|
const result = await activeQueryPromise;
|
|
421
414
|
|
|
422
415
|
if (!activeQueryPromise) {
|
|
423
|
-
throw new Error(
|
|
416
|
+
throw new Error("Expected `activeQueryPromise` to be set.");
|
|
424
417
|
}
|
|
425
418
|
|
|
426
419
|
return result;
|
|
@@ -436,20 +429,20 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
436
429
|
stream: (sql, values) => {
|
|
437
430
|
const currentState = state();
|
|
438
431
|
|
|
439
|
-
if (currentState ===
|
|
440
|
-
throw new Error(
|
|
432
|
+
if (currentState === "PENDING_DESTROY") {
|
|
433
|
+
throw new Error("Client is pending destroy.");
|
|
441
434
|
}
|
|
442
435
|
|
|
443
|
-
if (currentState ===
|
|
444
|
-
throw new Error(
|
|
436
|
+
if (currentState === "PENDING_RELEASE") {
|
|
437
|
+
throw new Error("Client is pending release.");
|
|
445
438
|
}
|
|
446
439
|
|
|
447
|
-
if (currentState ===
|
|
448
|
-
throw new Error(
|
|
440
|
+
if (currentState === "DESTROYED") {
|
|
441
|
+
throw new Error("Client is destroyed.");
|
|
449
442
|
}
|
|
450
443
|
|
|
451
|
-
if (currentState !==
|
|
452
|
-
throw new Error(
|
|
444
|
+
if (currentState !== "ACQUIRED") {
|
|
445
|
+
throw new Error("Client is not acquired.");
|
|
453
446
|
}
|
|
454
447
|
|
|
455
448
|
// Note: Stream lifecycle management should be handled by the caller.
|
|
@@ -462,7 +455,7 @@ export const createDriverFactory = (setup: DriverSetup): DriverFactory => {
|
|
|
462
455
|
try {
|
|
463
456
|
await connect();
|
|
464
457
|
} catch (error) {
|
|
465
|
-
clientEventEmitter.off(
|
|
458
|
+
clientEventEmitter.off("error", onError);
|
|
466
459
|
|
|
467
460
|
throw error;
|
|
468
461
|
}
|
package/src/index.ts
CHANGED