@steadybrew/postgresjs 4.3.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 +18 -2
- package/cf/src/connection.js +58 -19
- package/cf/src/errors.js +8 -0
- package/cf/src/index.js +47 -32
- package/cf/src/subscribe.js +122 -47
- package/cjs/src/connection.js +58 -19
- package/cjs/src/errors.js +8 -0
- package/cjs/src/index.js +47 -32
- package/cjs/src/subscribe.js +122 -47
- package/package.json +1 -1
- package/src/connection.js +58 -19
- package/src/errors.js +8 -0
- package/src/index.js +47 -32
- package/src/subscribe.js +122 -47
- package/types/index.d.ts +9 -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')]
|
|
@@ -224,6 +227,8 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
224
227
|
owner: null,
|
|
225
228
|
get active() { return query ? 1 : 0 },
|
|
226
229
|
get pipelined() { return sent.length },
|
|
230
|
+
get accepting() { return accepting() },
|
|
231
|
+
get copying() { return stream !== null },
|
|
227
232
|
get acquiring() { return acquisition && !acquisition.owner.cancelled ? 1 : 0 },
|
|
228
233
|
count: 0,
|
|
229
234
|
id
|
|
@@ -268,8 +273,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
268
273
|
return !query && sent.length === 0
|
|
269
274
|
}
|
|
270
275
|
|
|
276
|
+
function accepting() {
|
|
277
|
+
return !query || (!barrier && sent.length < max_pipeline)
|
|
278
|
+
}
|
|
279
|
+
|
|
271
280
|
function backoffMs() {
|
|
272
|
-
return (
|
|
281
|
+
return backoffSeconds(backoff, options.shared.retries) * 1000
|
|
273
282
|
}
|
|
274
283
|
|
|
275
284
|
function standbyPass() {
|
|
@@ -446,7 +455,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
446
455
|
queryError(pending, err)
|
|
447
456
|
pending.cancelled && pending.cancelled.resolve()
|
|
448
457
|
}
|
|
449
|
-
query = results = errorResponse = chunk = nextWriteTimer = null
|
|
458
|
+
query = results = errorResponse = chunk = nextWriteTimer = barrier = null
|
|
450
459
|
result = new Result()
|
|
451
460
|
rows = 0
|
|
452
461
|
nonce = serverSignature = null
|
|
@@ -510,8 +519,10 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
510
519
|
}
|
|
511
520
|
|
|
512
521
|
function submit(q) {
|
|
513
|
-
if (stream)
|
|
514
|
-
|
|
522
|
+
if (stream) {
|
|
523
|
+
queryError(q, Errors.generic('COPY_IN_PROGRESS', 'You cannot execute queries during copy'))
|
|
524
|
+
return true
|
|
525
|
+
}
|
|
515
526
|
|
|
516
527
|
if (q.cancelled)
|
|
517
528
|
return true
|
|
@@ -525,17 +536,21 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
525
536
|
: (query = q, query.active = true)
|
|
526
537
|
|
|
527
538
|
build(q)
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
539
|
+
const written = write(toBuffer(q))
|
|
540
|
+
if (q.describeFirst || q.cursorFn || mayCopy(q))
|
|
541
|
+
barrier = q
|
|
542
|
+
return written && accepting()
|
|
532
543
|
} catch (error) {
|
|
533
544
|
sent.remove(q) || write(Sync)
|
|
534
545
|
queryError(q, error)
|
|
535
|
-
return
|
|
546
|
+
return accepting()
|
|
536
547
|
}
|
|
537
548
|
}
|
|
538
549
|
|
|
550
|
+
function mayCopy(q) {
|
|
551
|
+
return q.options.simple && /\bcopy\b/i.test(q.string)
|
|
552
|
+
}
|
|
553
|
+
|
|
539
554
|
function toBuffer(q) {
|
|
540
555
|
if (q.parameters.length >= 65534)
|
|
541
556
|
throw Errors.generic('MAX_PARAMETERS_EXCEEDED', 'Max number of parameters (65534) exceeded')
|
|
@@ -594,7 +609,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
594
609
|
? statements[q.signature]
|
|
595
610
|
: { string, types, name: q.prepare ? statementId + statementCount++ : '' }
|
|
596
611
|
|
|
597
|
-
typeof options.debug === 'function' && options.debug
|
|
612
|
+
typeof options.debug === 'function' && callback(options.debug, id, string, parameters, types)
|
|
598
613
|
}
|
|
599
614
|
|
|
600
615
|
function write(x, fn) {
|
|
@@ -765,18 +780,21 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
765
780
|
backendParameters[k] = v
|
|
766
781
|
if (options.parameters[k] !== v) {
|
|
767
782
|
options.parameters[k] = v
|
|
768
|
-
onparameter
|
|
783
|
+
callback(onparameter, k, v)
|
|
769
784
|
}
|
|
770
785
|
}
|
|
771
786
|
|
|
772
|
-
function ReadyForQuery() {
|
|
787
|
+
function ReadyForQuery(x) {
|
|
788
|
+
query === barrier && (barrier = null)
|
|
773
789
|
if (query) {
|
|
774
790
|
if (errorResponse) {
|
|
775
791
|
if (query.initialization)
|
|
776
792
|
return dispatch('initFailed', errorResponse)
|
|
793
|
+
query.prepared && retryRoutines.has(errorResponse.routine) && delete statements[query.signature]
|
|
777
794
|
query.retried
|
|
778
795
|
? errored(query.retried)
|
|
779
|
-
: 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))
|
|
780
798
|
? retry(query, errorResponse)
|
|
781
799
|
: errored(errorResponse)
|
|
782
800
|
} else {
|
|
@@ -1059,7 +1077,6 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1059
1077
|
}
|
|
1060
1078
|
|
|
1061
1079
|
function retry(q, error) {
|
|
1062
|
-
delete statements[q.signature]
|
|
1063
1080
|
q.retried = error
|
|
1064
1081
|
execute(q)
|
|
1065
1082
|
}
|
|
@@ -1070,7 +1087,8 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1070
1087
|
|
|
1071
1088
|
let index = 9
|
|
1072
1089
|
while (x[index++] !== 0);
|
|
1073
|
-
|
|
1090
|
+
callback(
|
|
1091
|
+
onnotify,
|
|
1074
1092
|
x.toString('utf8', 9, index - 1),
|
|
1075
1093
|
x.toString('utf8', index, x.length - 1)
|
|
1076
1094
|
)
|
|
@@ -1116,6 +1134,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1116
1134
|
}
|
|
1117
1135
|
})
|
|
1118
1136
|
query.resolve(stream)
|
|
1137
|
+
connection.owner && connection.owner.next()
|
|
1119
1138
|
}
|
|
1120
1139
|
|
|
1121
1140
|
function CopyOutResponse() {
|
|
@@ -1123,6 +1142,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1123
1142
|
read() { socket.resume() }
|
|
1124
1143
|
})
|
|
1125
1144
|
query.resolve(stream)
|
|
1145
|
+
connection.owner && connection.owner.next()
|
|
1126
1146
|
}
|
|
1127
1147
|
|
|
1128
1148
|
/* c8 ignore next 3 */
|
|
@@ -1145,6 +1165,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1145
1165
|
}
|
|
1146
1166
|
})
|
|
1147
1167
|
query.resolve(stream)
|
|
1168
|
+
connection.owner && connection.owner.next()
|
|
1148
1169
|
}
|
|
1149
1170
|
|
|
1150
1171
|
function CopyData(x) {
|
|
@@ -1157,10 +1178,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1157
1178
|
}
|
|
1158
1179
|
|
|
1159
1180
|
function NoticeResponse(x) {
|
|
1181
|
+
if (onnotice === false)
|
|
1182
|
+
return
|
|
1183
|
+
|
|
1160
1184
|
onnotice
|
|
1161
|
-
? onnotice
|
|
1185
|
+
? callback(onnotice, parseError(x))
|
|
1162
1186
|
: console.log(parseError(x)) // eslint-disable-line
|
|
1163
|
-
|
|
1164
1187
|
}
|
|
1165
1188
|
|
|
1166
1189
|
/* c8 ignore next 3 */
|
|
@@ -1311,3 +1334,19 @@ function timer(fn, seconds) {
|
|
|
1311
1334
|
fn.apply(null, args)
|
|
1312
1335
|
}
|
|
1313
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,
|