@nxtedition/lib 18.0.1 → 18.0.3
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/couch.js +103 -63
- package/package.json +1 -1
package/couch.js
CHANGED
|
@@ -5,7 +5,6 @@ import { defaultDelay as delay } from './http.js'
|
|
|
5
5
|
import querystring from 'querystring'
|
|
6
6
|
import urljoin from 'url-join'
|
|
7
7
|
import undici from 'undici'
|
|
8
|
-
import assert from 'node:assert'
|
|
9
8
|
|
|
10
9
|
// https://github.com/fastify/fastify/blob/main/lib/reqIdGenFactory.js
|
|
11
10
|
// 2,147,483,647 (2^31 − 1) stands for max SMI value (an internal optimization of V8).
|
|
@@ -226,21 +225,16 @@ export function makeCouch(opts) {
|
|
|
226
225
|
}
|
|
227
226
|
}
|
|
228
227
|
|
|
229
|
-
async function*
|
|
230
|
-
let remaining = Number(options.limit) || Infinity
|
|
231
|
-
|
|
232
|
-
const params2 = {
|
|
233
|
-
...params,
|
|
234
|
-
...options.query,
|
|
235
|
-
feed: live ? 'continuous' : 'normal',
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (Number.isFinite(remaining)) {
|
|
239
|
-
params.limit = remaining
|
|
240
|
-
}
|
|
241
|
-
|
|
228
|
+
async function* continuous() {
|
|
242
229
|
const req = {
|
|
243
|
-
path:
|
|
230
|
+
path:
|
|
231
|
+
dbPathname +
|
|
232
|
+
'/_changes' +
|
|
233
|
+
`?${new URLSearchParams({
|
|
234
|
+
...params,
|
|
235
|
+
...options.query,
|
|
236
|
+
feed: 'continuous',
|
|
237
|
+
})}`,
|
|
244
238
|
idempotent: false,
|
|
245
239
|
blocking: true,
|
|
246
240
|
method,
|
|
@@ -256,66 +250,34 @@ export function makeCouch(opts) {
|
|
|
256
250
|
bodyTimeout: 2 * (params.heartbeat || 60e3),
|
|
257
251
|
}
|
|
258
252
|
|
|
259
|
-
const HEAD = '{"results":['
|
|
260
|
-
const TAIL = '],'
|
|
261
|
-
|
|
262
253
|
try {
|
|
263
254
|
const res = await client.request(req)
|
|
264
255
|
|
|
265
256
|
retryCount = 0
|
|
266
257
|
|
|
267
258
|
let str = ''
|
|
268
|
-
let state = 0
|
|
269
259
|
for await (const chunk of res.body) {
|
|
270
260
|
const lines = (str + chunk).split('\n')
|
|
271
261
|
str = lines.pop() ?? ''
|
|
272
262
|
|
|
273
|
-
const
|
|
263
|
+
const results = batched ? [] : null
|
|
274
264
|
for (const line of lines) {
|
|
275
|
-
if (line
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
const data = JSON.parse(line)
|
|
280
|
-
if (data.last_seq) {
|
|
281
|
-
params.since = data.last_seq
|
|
282
|
-
assert(params.since, 'invalid last_seq: ' + params.since)
|
|
283
|
-
} else {
|
|
284
|
-
params.since = data.seq || params.since
|
|
285
|
-
changes.push(data)
|
|
265
|
+
if (line) {
|
|
266
|
+
const change = JSON.parse(line)
|
|
267
|
+
if (change.seq) {
|
|
268
|
+
params.since = change.seq
|
|
286
269
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (state === 0) {
|
|
290
|
-
if (line === HEAD) {
|
|
291
|
-
state = 1
|
|
292
|
-
} else {
|
|
293
|
-
assert(line.length < HEAD.length, 'invalid line: ' + line)
|
|
294
|
-
}
|
|
295
|
-
} else if (state === 1) {
|
|
296
|
-
if (line === TAIL) {
|
|
297
|
-
state = 2
|
|
298
|
-
} else {
|
|
299
|
-
const idx = line.lastIndexOf('}') + 1
|
|
300
|
-
assert(idx > 0, 'invalid line; ' + line)
|
|
301
|
-
const data = JSON.parse(line.slice(0, idx))
|
|
302
|
-
params.since = data.seq || params.since
|
|
303
|
-
changes.push(data)
|
|
304
|
-
}
|
|
305
|
-
} else if (state === 2) {
|
|
306
|
-
state = 3
|
|
307
|
-
params.since = JSON.parse('{' + line).last_seq
|
|
308
|
-
assert(params.since, 'invalid last_seq: ' + params.since)
|
|
270
|
+
if (results) {
|
|
271
|
+
results.push(change)
|
|
309
272
|
} else {
|
|
310
|
-
|
|
273
|
+
yield change
|
|
311
274
|
}
|
|
312
275
|
}
|
|
313
276
|
}
|
|
314
277
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
assert(remaining >= 0, 'invalid remaining: ' + remaining)
|
|
278
|
+
if (results?.length) {
|
|
279
|
+
yield results
|
|
280
|
+
}
|
|
319
281
|
}
|
|
320
282
|
} catch (err) {
|
|
321
283
|
Object.assign(err, { data: req })
|
|
@@ -323,15 +285,93 @@ export function makeCouch(opts) {
|
|
|
323
285
|
}
|
|
324
286
|
}
|
|
325
287
|
|
|
288
|
+
async function* normal() {
|
|
289
|
+
const batchSize =
|
|
290
|
+
options.batch_size ?? options.batchSize ?? (params.include_docs ? 512 : 4096)
|
|
291
|
+
let remaining = parseInt(options.limit) || Infinity
|
|
292
|
+
|
|
293
|
+
const next = async () => {
|
|
294
|
+
const req = {
|
|
295
|
+
path:
|
|
296
|
+
dbPathname +
|
|
297
|
+
'/_changes' +
|
|
298
|
+
`?${new URLSearchParams({
|
|
299
|
+
...params,
|
|
300
|
+
...options.query,
|
|
301
|
+
limit: Math.min(remaining, batchSize),
|
|
302
|
+
feed: live ? 'longpoll' : 'normal',
|
|
303
|
+
})}`,
|
|
304
|
+
idempotent: true,
|
|
305
|
+
blocking: live,
|
|
306
|
+
method,
|
|
307
|
+
body: JSON.stringify(body),
|
|
308
|
+
signal: ac.signal,
|
|
309
|
+
headers: {
|
|
310
|
+
'user-agent': userAgent,
|
|
311
|
+
'request-id': genReqId(),
|
|
312
|
+
...(body ? { 'content-type': 'application/json' } : {}),
|
|
313
|
+
},
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
try {
|
|
317
|
+
const res = await client.request(req)
|
|
318
|
+
|
|
319
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
320
|
+
throw makeError(req, {
|
|
321
|
+
status: res.statusCode,
|
|
322
|
+
headers: res.headers,
|
|
323
|
+
data: await res.body.text(),
|
|
324
|
+
})
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return await res.body.json()
|
|
328
|
+
} catch (err) {
|
|
329
|
+
Object.assign(err, { data: req })
|
|
330
|
+
return { err }
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
let promise
|
|
335
|
+
while (remaining) {
|
|
336
|
+
const { last_seq: seq, results, err } = await (promise ?? next())
|
|
337
|
+
promise = null
|
|
338
|
+
|
|
339
|
+
if (err) {
|
|
340
|
+
throw err
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
retryCount = 0
|
|
344
|
+
|
|
345
|
+
if (seq) {
|
|
346
|
+
params.since = seq
|
|
347
|
+
if (results.length > 0 && !results.at(-1)?.seq) {
|
|
348
|
+
results.at(-1).seq = seq
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
remaining -= results.length
|
|
353
|
+
|
|
354
|
+
if (!live && results.length === 0) {
|
|
355
|
+
return
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
promise = next()
|
|
359
|
+
|
|
360
|
+
if (batched) {
|
|
361
|
+
yield results
|
|
362
|
+
} else {
|
|
363
|
+
yield* results
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
326
368
|
try {
|
|
327
369
|
while (true) {
|
|
328
370
|
try {
|
|
329
|
-
if (
|
|
330
|
-
yield*
|
|
371
|
+
if (live && !options.batchSize && !options.batch_size) {
|
|
372
|
+
yield* continuous()
|
|
331
373
|
} else {
|
|
332
|
-
|
|
333
|
-
yield* changes
|
|
334
|
-
}
|
|
374
|
+
yield* normal()
|
|
335
375
|
}
|
|
336
376
|
return
|
|
337
377
|
} catch (err) {
|