@steadybrew/postgresjs 4.2.0 → 4.4.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 +70 -2
- package/cf/src/connection.js +63 -21
- package/cf/src/errors.js +8 -0
- package/cf/src/index.js +100 -33
- package/cf/src/subscribe.js +122 -47
- package/cjs/src/connection.js +63 -21
- package/cjs/src/errors.js +8 -0
- package/cjs/src/index.js +100 -33
- package/cjs/src/subscribe.js +122 -47
- package/package.json +1 -1
- package/src/connection.js +63 -21
- package/src/errors.js +8 -0
- package/src/index.js +100 -33
- package/src/subscribe.js +122 -47
- package/types/index.d.ts +41 -9
package/cf/src/subscribe.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer'
|
|
2
|
+
import { callback } from './errors.js'
|
|
3
|
+
import { defaultBackoff, backoffSeconds } from './connection.js'
|
|
4
|
+
|
|
2
5
|
const noop = () => { /* noop */ }
|
|
6
|
+
, commands = { 68: 'delete', 73: 'insert', 85: 'update' }
|
|
3
7
|
|
|
4
8
|
export default function Subscribe(postgres, options) {
|
|
5
9
|
const subscribers = new Map()
|
|
@@ -8,6 +12,9 @@ export default function Subscribe(postgres, options) {
|
|
|
8
12
|
|
|
9
13
|
let connection
|
|
10
14
|
, stream
|
|
15
|
+
, timer
|
|
16
|
+
, inflight = false
|
|
17
|
+
, retries = 0
|
|
11
18
|
, ended = false
|
|
12
19
|
|
|
13
20
|
const sql = subscribe.sql = postgres({
|
|
@@ -22,13 +29,12 @@ export default function Subscribe(postgres, options) {
|
|
|
22
29
|
...options.connection,
|
|
23
30
|
replication: 'database'
|
|
24
31
|
},
|
|
25
|
-
onclose:
|
|
32
|
+
onclose: function() {
|
|
26
33
|
if (ended)
|
|
27
34
|
return
|
|
28
35
|
stream = null
|
|
29
36
|
state.pid = state.secret = undefined
|
|
30
|
-
|
|
31
|
-
subscribers.forEach(event => event.forEach(({ onsubscribe }) => onsubscribe()))
|
|
37
|
+
inflight || timer || !connection || connect().catch(noop)
|
|
32
38
|
},
|
|
33
39
|
no_subscribe: true
|
|
34
40
|
})
|
|
@@ -38,6 +44,9 @@ export default function Subscribe(postgres, options) {
|
|
|
38
44
|
|
|
39
45
|
sql.end = async() => {
|
|
40
46
|
ended = true
|
|
47
|
+
clearTimeout(timer)
|
|
48
|
+
timer = null
|
|
49
|
+
connection && await connection.catch(noop)
|
|
41
50
|
stream && (await new Promise(r => (stream.once('close', r), stream.end())))
|
|
42
51
|
return end()
|
|
43
52
|
}
|
|
@@ -49,34 +58,74 @@ export default function Subscribe(postgres, options) {
|
|
|
49
58
|
|
|
50
59
|
return subscribe
|
|
51
60
|
|
|
52
|
-
async function subscribe(event, fn, onsubscribe = noop, onerror
|
|
61
|
+
async function subscribe(event, fn, onsubscribe = noop, onerror) {
|
|
53
62
|
event = parseEvent(event)
|
|
54
63
|
|
|
55
|
-
|
|
56
|
-
connection = init(sql, slot, options.publications)
|
|
64
|
+
const subscriber = { fn, onsubscribe, onerror }
|
|
57
65
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
return (connection || connect()).then(() => {
|
|
67
|
+
const fns = subscribers.has(event)
|
|
68
|
+
? subscribers.get(event).add(subscriber)
|
|
69
|
+
: subscribers.set(event, new Set([subscriber])).get(event)
|
|
62
70
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
71
|
+
const unsubscribe = () => {
|
|
72
|
+
fns.delete(subscriber)
|
|
73
|
+
fns.size === 0 && subscribers.delete(event)
|
|
74
|
+
subscribers.size === 0 && (clearTimeout(timer), timer = null)
|
|
75
|
+
}
|
|
67
76
|
|
|
68
|
-
|
|
69
|
-
connected(x)
|
|
70
|
-
onsubscribe()
|
|
71
|
-
stream && stream.on('error', onerror)
|
|
77
|
+
callback(onsubscribe)
|
|
72
78
|
return { unsubscribe, state, sql }
|
|
73
79
|
})
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
function
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
function connect() {
|
|
83
|
+
clearTimeout(timer)
|
|
84
|
+
timer = null
|
|
85
|
+
inflight = true
|
|
86
|
+
const resume = subscribers.size > 0
|
|
87
|
+
const current = connection = init(sql, slot, options.publications).then(x => {
|
|
88
|
+
stream = x.stream
|
|
89
|
+
state.pid = x.state.pid
|
|
90
|
+
state.secret = x.state.secret
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
current.then(
|
|
94
|
+
() => {
|
|
95
|
+
inflight = false
|
|
96
|
+
retries = 0
|
|
97
|
+
resume && !ended && subscribers.forEach(event => event.forEach(({ onsubscribe }) => callback(onsubscribe)))
|
|
98
|
+
},
|
|
99
|
+
error => {
|
|
100
|
+
inflight = false
|
|
101
|
+
connection === current && (connection = null)
|
|
102
|
+
if (ended || subscribers.size === 0)
|
|
103
|
+
return
|
|
104
|
+
reportConnection(error)
|
|
105
|
+
timer = setTimeout(() => connect().catch(noop), retryDelay(retries++))
|
|
106
|
+
}
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
return current
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function retryDelay(n) {
|
|
113
|
+
let seconds = backoffSeconds(sql.options.backoff, n)
|
|
114
|
+
seconds = Number.isFinite(seconds) ? seconds : defaultBackoff(n)
|
|
115
|
+
return Math.min(Math.max(seconds * 1000, 100), 2 ** 31 - 1)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function reportConnection(error) {
|
|
119
|
+
console.error('Unexpected error during logical streaming - reconnecting', error) // eslint-disable-line
|
|
120
|
+
subscribers.forEach(fns => fns.forEach(({ onerror }) => callback(onerror, error)))
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function report(error, match) {
|
|
124
|
+
let uncaught = false
|
|
125
|
+
subscribers.forEach((fns, event) => match(event) && fns.forEach(({ onerror }) =>
|
|
126
|
+
onerror ? callback(onerror, error) : uncaught = true
|
|
127
|
+
))
|
|
128
|
+
uncaught && callback(() => { throw error })
|
|
80
129
|
}
|
|
81
130
|
|
|
82
131
|
async function init(sql, slot, publications) {
|
|
@@ -100,18 +149,18 @@ export default function Subscribe(postgres, options) {
|
|
|
100
149
|
}
|
|
101
150
|
|
|
102
151
|
stream.on('data', data)
|
|
103
|
-
stream.on('error',
|
|
152
|
+
stream.on('error', reportConnection)
|
|
104
153
|
stream.on('close', sql.close)
|
|
105
154
|
|
|
106
155
|
return { stream, state: xs.state }
|
|
107
156
|
|
|
108
|
-
function error(e) {
|
|
109
|
-
console.error('Unexpected error during logical streaming - reconnecting', e) // eslint-disable-line
|
|
110
|
-
}
|
|
111
|
-
|
|
112
157
|
function data(x) {
|
|
113
158
|
if (x[0] === 0x77) {
|
|
114
|
-
|
|
159
|
+
try {
|
|
160
|
+
parse(x.subarray(25), state, sql.options.parsers, handle, options.transform)
|
|
161
|
+
} catch (error) {
|
|
162
|
+
skip(x.subarray(25), error)
|
|
163
|
+
}
|
|
115
164
|
} else if (x[0] === 0x6b && x[17]) {
|
|
116
165
|
state.lsn = x.subarray(1, 9)
|
|
117
166
|
pong()
|
|
@@ -120,12 +169,26 @@ export default function Subscribe(postgres, options) {
|
|
|
120
169
|
|
|
121
170
|
function handle(a, b) {
|
|
122
171
|
const path = b.relation.schema + '.' + b.relation.table
|
|
172
|
+
, key = b.relation.keys.length && '=' + b.relation.keys.map(x => a[x.name])
|
|
123
173
|
call('*', a, b)
|
|
124
174
|
call('*:' + path, a, b)
|
|
125
|
-
|
|
175
|
+
key && call('*:' + path + key, a, b)
|
|
126
176
|
call(b.command, a, b)
|
|
127
177
|
call(b.command + ':' + path, a, b)
|
|
128
|
-
|
|
178
|
+
key && call(b.command + ':' + path + key, a, b)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function skip(x, error) {
|
|
182
|
+
const command = commands[x[0]]
|
|
183
|
+
, relation = command && state[x.readUInt32BE(1)]
|
|
184
|
+
|
|
185
|
+
if (!relation)
|
|
186
|
+
throw error
|
|
187
|
+
|
|
188
|
+
const path = relation.schema + '.' + relation.table
|
|
189
|
+
, events = ['*', '*:' + path, command, command + ':' + path]
|
|
190
|
+
|
|
191
|
+
report(error, event => events.includes(event.split('=')[0]))
|
|
129
192
|
}
|
|
130
193
|
|
|
131
194
|
function pong() {
|
|
@@ -138,7 +201,7 @@ export default function Subscribe(postgres, options) {
|
|
|
138
201
|
}
|
|
139
202
|
|
|
140
203
|
function call(x, a, b) {
|
|
141
|
-
subscribers.has(x) && subscribers.get(x).forEach(({ fn }) => fn
|
|
204
|
+
subscribers.has(x) && subscribers.get(x).forEach(({ fn }) => callback(fn, a, b, x))
|
|
142
205
|
}
|
|
143
206
|
}
|
|
144
207
|
|
|
@@ -163,19 +226,24 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
163
226
|
let columnIndex = 0
|
|
164
227
|
, column
|
|
165
228
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
229
|
+
try {
|
|
230
|
+
while (i < x.length) {
|
|
231
|
+
column = r.columns[columnIndex++] = {
|
|
232
|
+
key: x[i++],
|
|
233
|
+
name: transform.column.from
|
|
234
|
+
? transform.column.from(x.toString('utf8', i, i = x.indexOf(0, i)))
|
|
235
|
+
: x.toString('utf8', i, i = x.indexOf(0, i)),
|
|
236
|
+
type: x.readUInt32BE(i += 1),
|
|
237
|
+
parser: parsers[x.readUInt32BE(i)],
|
|
238
|
+
atttypmod: x.readUInt32BE(i += 4)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
column.key && r.keys.push(column)
|
|
242
|
+
i += 4
|
|
175
243
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
244
|
+
} catch (error) {
|
|
245
|
+
r.error = error
|
|
246
|
+
r.failed = true
|
|
179
247
|
}
|
|
180
248
|
},
|
|
181
249
|
Y: () => { /* noop */ }, // Type
|
|
@@ -186,7 +254,7 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
186
254
|
},
|
|
187
255
|
I: x => { // Insert
|
|
188
256
|
let i = 1
|
|
189
|
-
const relation = state[x.readUInt32BE(i)]
|
|
257
|
+
const relation = decodable(state[x.readUInt32BE(i)])
|
|
190
258
|
const { row } = tuples(x, relation.columns, i += 7, transform)
|
|
191
259
|
|
|
192
260
|
handle(row, {
|
|
@@ -196,7 +264,7 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
196
264
|
},
|
|
197
265
|
D: x => { // Delete
|
|
198
266
|
let i = 1
|
|
199
|
-
const relation = state[x.readUInt32BE(i)]
|
|
267
|
+
const relation = decodable(state[x.readUInt32BE(i)])
|
|
200
268
|
i += 4
|
|
201
269
|
const key = x[i] === 75
|
|
202
270
|
handle(key || x[i] === 79
|
|
@@ -210,7 +278,7 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
210
278
|
},
|
|
211
279
|
U: x => { // Update
|
|
212
280
|
let i = 1
|
|
213
|
-
const relation = state[x.readUInt32BE(i)]
|
|
281
|
+
const relation = decodable(state[x.readUInt32BE(i)])
|
|
214
282
|
i += 4
|
|
215
283
|
const key = x[i] === 75
|
|
216
284
|
const xs = key || x[i] === 79
|
|
@@ -233,6 +301,13 @@ function parse(x, state, parsers, handle, transform) {
|
|
|
233
301
|
}).reduce(char, {})[x[0]](x)
|
|
234
302
|
}
|
|
235
303
|
|
|
304
|
+
function decodable(relation) {
|
|
305
|
+
if (relation.failed)
|
|
306
|
+
throw relation.error
|
|
307
|
+
|
|
308
|
+
return relation
|
|
309
|
+
}
|
|
310
|
+
|
|
236
311
|
function tuples(x, columns, xi, transform) {
|
|
237
312
|
let type
|
|
238
313
|
, column
|
|
@@ -266,7 +341,7 @@ function tuples(x, columns, xi, transform) {
|
|
|
266
341
|
}
|
|
267
342
|
|
|
268
343
|
function parseEvent(x) {
|
|
269
|
-
const xs = x.match(/^(\*|insert|update|delete)?:?([
|
|
344
|
+
const xs = x.match(/^(\*|insert|update|delete)?:?([^.=]+(?:\.[^=]+)?)?=?(.+)?/i) || []
|
|
270
345
|
|
|
271
346
|
if (!xs)
|
|
272
347
|
throw new Error('Malformed subscribe pattern: ' + x)
|
package/cjs/src/connection.js
CHANGED
|
@@ -5,7 +5,7 @@ const Stream = require('stream')
|
|
|
5
5
|
const { performance } = require('perf_hooks')
|
|
6
6
|
|
|
7
7
|
const { stringify, handleValue, addArrayType } = require('./types.js')
|
|
8
|
-
const { Errors } = require('./errors.js')
|
|
8
|
+
const { Errors, callback } = require('./errors.js')
|
|
9
9
|
const Result = require('./result.js')
|
|
10
10
|
const Queue = require('./queue.js')
|
|
11
11
|
const clampedTimeout = require('./timeout.js')
|
|
@@ -13,7 +13,7 @@ const { SSLRequest, tlsConfig, cancelRequest } = require('./transport.js')
|
|
|
13
13
|
const { Query, CLOSE } = require('./query.js')
|
|
14
14
|
const b = require('./bytes.js')
|
|
15
15
|
|
|
16
|
-
module.exports = Connection
|
|
16
|
+
module.exports = { Connection }
|
|
17
17
|
|
|
18
18
|
let uid = 1
|
|
19
19
|
|
|
@@ -26,6 +26,8 @@ const Sync = b().S().end()
|
|
|
26
26
|
const Phase = { Closed: 0, Backoff: 1, Connecting: 2, Initializing: 3, Ready: 4, Draining: 5, Closing: 6 }
|
|
27
27
|
const phaseNames = Object.keys(Phase)
|
|
28
28
|
|
|
29
|
+
const endsAbortedState = /^\s*(rollback|abort)\b/i
|
|
30
|
+
|
|
29
31
|
const retryRoutines = new Set([
|
|
30
32
|
'FetchPreparedStatement',
|
|
31
33
|
'RevalidateCachedQuery',
|
|
@@ -110,6 +112,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
110
112
|
, chunk = null
|
|
111
113
|
, nonce = null
|
|
112
114
|
, query = null
|
|
115
|
+
, barrier = null
|
|
113
116
|
, final = null
|
|
114
117
|
|
|
115
118
|
const check = globalThis[Symbol.for('postgres.js:check')]
|
|
@@ -222,6 +225,11 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
222
225
|
},
|
|
223
226
|
expired: () => idleTimer.expired() || lifeTimer.expired(),
|
|
224
227
|
owner: null,
|
|
228
|
+
get active() { return query ? 1 : 0 },
|
|
229
|
+
get pipelined() { return sent.length },
|
|
230
|
+
get accepting() { return accepting() },
|
|
231
|
+
get copying() { return stream !== null },
|
|
232
|
+
get acquiring() { return acquisition && !acquisition.owner.cancelled ? 1 : 0 },
|
|
225
233
|
count: 0,
|
|
226
234
|
id
|
|
227
235
|
}
|
|
@@ -265,8 +273,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
265
273
|
return !query && sent.length === 0
|
|
266
274
|
}
|
|
267
275
|
|
|
276
|
+
function accepting() {
|
|
277
|
+
return !query || (!barrier && sent.length < max_pipeline)
|
|
278
|
+
}
|
|
279
|
+
|
|
268
280
|
function backoffMs() {
|
|
269
|
-
return (
|
|
281
|
+
return backoffSeconds(backoff, options.shared.retries) * 1000
|
|
270
282
|
}
|
|
271
283
|
|
|
272
284
|
function standbyPass() {
|
|
@@ -443,7 +455,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
443
455
|
queryError(pending, err)
|
|
444
456
|
pending.cancelled && pending.cancelled.resolve()
|
|
445
457
|
}
|
|
446
|
-
query = results = errorResponse = chunk = nextWriteTimer = null
|
|
458
|
+
query = results = errorResponse = chunk = nextWriteTimer = barrier = null
|
|
447
459
|
result = new Result()
|
|
448
460
|
rows = 0
|
|
449
461
|
nonce = serverSignature = null
|
|
@@ -507,8 +519,10 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
507
519
|
}
|
|
508
520
|
|
|
509
521
|
function submit(q) {
|
|
510
|
-
if (stream)
|
|
511
|
-
|
|
522
|
+
if (stream) {
|
|
523
|
+
queryError(q, Errors.generic('COPY_IN_PROGRESS', 'You cannot execute queries during copy'))
|
|
524
|
+
return true
|
|
525
|
+
}
|
|
512
526
|
|
|
513
527
|
if (q.cancelled)
|
|
514
528
|
return true
|
|
@@ -522,17 +536,21 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
522
536
|
: (query = q, query.active = true)
|
|
523
537
|
|
|
524
538
|
build(q)
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
539
|
+
const written = write(toBuffer(q))
|
|
540
|
+
if (q.describeFirst || q.cursorFn || mayCopy(q))
|
|
541
|
+
barrier = q
|
|
542
|
+
return written && accepting()
|
|
529
543
|
} catch (error) {
|
|
530
|
-
sent.
|
|
531
|
-
|
|
532
|
-
return
|
|
544
|
+
sent.remove(q) || write(Sync)
|
|
545
|
+
queryError(q, error)
|
|
546
|
+
return accepting()
|
|
533
547
|
}
|
|
534
548
|
}
|
|
535
549
|
|
|
550
|
+
function mayCopy(q) {
|
|
551
|
+
return q.options.simple && /\bcopy\b/i.test(q.string)
|
|
552
|
+
}
|
|
553
|
+
|
|
536
554
|
function toBuffer(q) {
|
|
537
555
|
if (q.parameters.length >= 65534)
|
|
538
556
|
throw Errors.generic('MAX_PARAMETERS_EXCEEDED', 'Max number of parameters (65534) exceeded')
|
|
@@ -591,7 +609,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
591
609
|
? statements[q.signature]
|
|
592
610
|
: { string, types, name: q.prepare ? statementId + statementCount++ : '' }
|
|
593
611
|
|
|
594
|
-
typeof options.debug === 'function' && options.debug
|
|
612
|
+
typeof options.debug === 'function' && callback(options.debug, id, string, parameters, types)
|
|
595
613
|
}
|
|
596
614
|
|
|
597
615
|
function write(x, fn) {
|
|
@@ -762,18 +780,21 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
762
780
|
backendParameters[k] = v
|
|
763
781
|
if (options.parameters[k] !== v) {
|
|
764
782
|
options.parameters[k] = v
|
|
765
|
-
onparameter
|
|
783
|
+
callback(onparameter, k, v)
|
|
766
784
|
}
|
|
767
785
|
}
|
|
768
786
|
|
|
769
|
-
function ReadyForQuery() {
|
|
787
|
+
function ReadyForQuery(x) {
|
|
788
|
+
query === barrier && (barrier = null)
|
|
770
789
|
if (query) {
|
|
771
790
|
if (errorResponse) {
|
|
772
791
|
if (query.initialization)
|
|
773
792
|
return dispatch('initFailed', errorResponse)
|
|
793
|
+
query.prepared && retryRoutines.has(errorResponse.routine) && delete statements[query.signature]
|
|
774
794
|
query.retried
|
|
775
795
|
? errored(query.retried)
|
|
776
|
-
: query.prepared && retryRoutines.has(errorResponse.routine) && query.owner === connection.owner
|
|
796
|
+
: query.prepared && retryRoutines.has(errorResponse.routine) && query.owner === connection.owner && !barrier
|
|
797
|
+
&& (x[5] !== 69 || endsAbortedState.test(query.string))
|
|
777
798
|
? retry(query, errorResponse)
|
|
778
799
|
: errored(errorResponse)
|
|
779
800
|
} else {
|
|
@@ -1056,7 +1077,6 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1056
1077
|
}
|
|
1057
1078
|
|
|
1058
1079
|
function retry(q, error) {
|
|
1059
|
-
delete statements[q.signature]
|
|
1060
1080
|
q.retried = error
|
|
1061
1081
|
execute(q)
|
|
1062
1082
|
}
|
|
@@ -1067,7 +1087,8 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1067
1087
|
|
|
1068
1088
|
let index = 9
|
|
1069
1089
|
while (x[index++] !== 0);
|
|
1070
|
-
|
|
1090
|
+
callback(
|
|
1091
|
+
onnotify,
|
|
1071
1092
|
x.toString('utf8', 9, index - 1),
|
|
1072
1093
|
x.toString('utf8', index, x.length - 1)
|
|
1073
1094
|
)
|
|
@@ -1113,6 +1134,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1113
1134
|
}
|
|
1114
1135
|
})
|
|
1115
1136
|
query.resolve(stream)
|
|
1137
|
+
connection.owner && connection.owner.next()
|
|
1116
1138
|
}
|
|
1117
1139
|
|
|
1118
1140
|
function CopyOutResponse() {
|
|
@@ -1120,6 +1142,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1120
1142
|
read() { socket.resume() }
|
|
1121
1143
|
})
|
|
1122
1144
|
query.resolve(stream)
|
|
1145
|
+
connection.owner && connection.owner.next()
|
|
1123
1146
|
}
|
|
1124
1147
|
|
|
1125
1148
|
/* c8 ignore next 3 */
|
|
@@ -1142,6 +1165,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1142
1165
|
}
|
|
1143
1166
|
})
|
|
1144
1167
|
query.resolve(stream)
|
|
1168
|
+
connection.owner && connection.owner.next()
|
|
1145
1169
|
}
|
|
1146
1170
|
|
|
1147
1171
|
function CopyData(x) {
|
|
@@ -1154,10 +1178,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1154
1178
|
}
|
|
1155
1179
|
|
|
1156
1180
|
function NoticeResponse(x) {
|
|
1181
|
+
if (onnotice === false)
|
|
1182
|
+
return
|
|
1183
|
+
|
|
1157
1184
|
onnotice
|
|
1158
|
-
? onnotice
|
|
1185
|
+
? callback(onnotice, parseError(x))
|
|
1159
1186
|
: console.log(parseError(x)) // eslint-disable-line
|
|
1160
|
-
|
|
1161
1187
|
}
|
|
1162
1188
|
|
|
1163
1189
|
/* c8 ignore next 3 */
|
|
@@ -1308,3 +1334,19 @@ function timer(fn, seconds) {
|
|
|
1308
1334
|
fn.apply(null, args)
|
|
1309
1335
|
}
|
|
1310
1336
|
}
|
|
1337
|
+
|
|
1338
|
+
module.exports.defaultBackoff = defaultBackoff;function defaultBackoff(retries) {
|
|
1339
|
+
return (0.5 + Math.random() / 2) * Math.min(3 ** retries / 100, 20)
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
module.exports.backoffSeconds = backoffSeconds;function backoffSeconds(backoff, retries) {
|
|
1343
|
+
if (typeof backoff !== 'function')
|
|
1344
|
+
return backoff
|
|
1345
|
+
|
|
1346
|
+
try {
|
|
1347
|
+
return backoff(retries)
|
|
1348
|
+
} catch (e) {
|
|
1349
|
+
callback(() => { throw e })
|
|
1350
|
+
return defaultBackoff(retries)
|
|
1351
|
+
}
|
|
1352
|
+
}
|
package/cjs/src/errors.js
CHANGED
|
@@ -6,6 +6,14 @@ const PostgresError = module.exports.PostgresError = class PostgresError extends
|
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
module.exports.callback = callback;function callback(fn, ...args) {
|
|
10
|
+
try {
|
|
11
|
+
fn && fn(...args)
|
|
12
|
+
} catch (e) {
|
|
13
|
+
queueMicrotask(() => { throw e })
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
const Errors = module.exports.Errors = {
|
|
10
18
|
connection,
|
|
11
19
|
postgres,
|