hypercore 9.12.0 → 10.0.0-alpha.11

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.
Files changed (86) hide show
  1. package/.github/workflows/test-node.yml +3 -4
  2. package/README.md +131 -404
  3. package/__snapshots__/test/storage.js.snapshot.cjs +15 -0
  4. package/examples/announce.js +19 -0
  5. package/examples/basic.js +10 -0
  6. package/examples/http.js +123 -0
  7. package/examples/lookup.js +20 -0
  8. package/index.js +365 -1600
  9. package/lib/bitfield.js +113 -285
  10. package/lib/block-encryption.js +68 -0
  11. package/lib/block-store.js +58 -0
  12. package/lib/core.js +468 -0
  13. package/lib/extensions.js +76 -0
  14. package/lib/merkle-tree.js +1110 -0
  15. package/lib/messages.js +571 -0
  16. package/lib/mutex.js +39 -0
  17. package/lib/oplog.js +224 -0
  18. package/lib/protocol.js +525 -0
  19. package/lib/random-iterator.js +46 -0
  20. package/lib/remote-bitfield.js +24 -0
  21. package/lib/replicator.js +857 -0
  22. package/lib/streams.js +39 -0
  23. package/package.json +44 -45
  24. package/test/basic.js +59 -471
  25. package/test/bitfield.js +48 -133
  26. package/test/core.js +290 -0
  27. package/test/encodings.js +18 -0
  28. package/test/encryption.js +123 -0
  29. package/test/extension.js +71 -0
  30. package/test/helpers/index.js +23 -0
  31. package/test/merkle-tree.js +518 -0
  32. package/test/mutex.js +137 -0
  33. package/test/oplog.js +399 -0
  34. package/test/preload.js +72 -0
  35. package/test/replicate.js +227 -824
  36. package/test/sessions.js +173 -0
  37. package/test/storage.js +31 -0
  38. package/test/streams.js +39 -146
  39. package/test/user-data.js +47 -0
  40. package/bench/all.sh +0 -65
  41. package/bench/copy-64kb-blocks.js +0 -51
  42. package/bench/helpers/read-throttled.js +0 -27
  43. package/bench/helpers/read.js +0 -47
  44. package/bench/helpers/write.js +0 -29
  45. package/bench/read-16kb-blocks-proof-throttled.js +0 -1
  46. package/bench/read-16kb-blocks-proof.js +0 -1
  47. package/bench/read-16kb-blocks-throttled.js +0 -1
  48. package/bench/read-16kb-blocks.js +0 -1
  49. package/bench/read-512b-blocks.js +0 -1
  50. package/bench/read-64kb-blocks-linear-batch.js +0 -18
  51. package/bench/read-64kb-blocks-linear.js +0 -18
  52. package/bench/read-64kb-blocks-proof.js +0 -1
  53. package/bench/read-64kb-blocks.js +0 -1
  54. package/bench/replicate-16kb-blocks.js +0 -19
  55. package/bench/replicate-64kb-blocks.js +0 -19
  56. package/bench/write-16kb-blocks.js +0 -1
  57. package/bench/write-512b-blocks.js +0 -1
  58. package/bench/write-64kb-blocks-static.js +0 -1
  59. package/bench/write-64kb-blocks.js +0 -1
  60. package/example.js +0 -23
  61. package/lib/cache.js +0 -26
  62. package/lib/crypto.js +0 -5
  63. package/lib/replicate.js +0 -829
  64. package/lib/safe-buffer-equals.js +0 -6
  65. package/lib/storage.js +0 -421
  66. package/lib/tree-index.js +0 -183
  67. package/test/ack.js +0 -306
  68. package/test/audit.js +0 -36
  69. package/test/cache.js +0 -93
  70. package/test/compat.js +0 -209
  71. package/test/copy.js +0 -377
  72. package/test/default-storage.js +0 -51
  73. package/test/extensions.js +0 -137
  74. package/test/get.js +0 -64
  75. package/test/head.js +0 -65
  76. package/test/helpers/create-tracking-ram.js +0 -27
  77. package/test/helpers/create.js +0 -6
  78. package/test/helpers/replicate.js +0 -4
  79. package/test/seek.js +0 -234
  80. package/test/selections.js +0 -95
  81. package/test/set-uploading-downloading.js +0 -91
  82. package/test/stats.js +0 -77
  83. package/test/timeouts.js +0 -22
  84. package/test/tree-index.js +0 -841
  85. package/test/update.js +0 -156
  86. package/test/value-encoding.js +0 -52
@@ -0,0 +1,571 @@
1
+ const c = require('compact-encoding')
2
+
3
+ const node = exports.node = {
4
+ preencode (state, n) {
5
+ c.uint.preencode(state, n.index)
6
+ c.uint.preencode(state, n.size)
7
+ c.fixed32.preencode(state, n.hash)
8
+ },
9
+ encode (state, n) {
10
+ c.uint.encode(state, n.index)
11
+ c.uint.encode(state, n.size)
12
+ c.fixed32.encode(state, n.hash)
13
+ },
14
+ decode (state) {
15
+ return {
16
+ index: c.uint.decode(state),
17
+ size: c.uint.decode(state),
18
+ hash: c.fixed32.decode(state)
19
+ }
20
+ }
21
+ }
22
+
23
+ const nodeArray = c.array(node)
24
+
25
+ const dataUpgrade = {
26
+ preencode (state, u) {
27
+ c.uint.preencode(state, u.start)
28
+ c.uint.preencode(state, u.length)
29
+ nodeArray.preencode(state, u.nodes)
30
+ nodeArray.preencode(state, u.additionalNodes)
31
+ c.buffer.preencode(state, u.signature)
32
+ },
33
+ encode (state, u) {
34
+ c.uint.encode(state, u.start)
35
+ c.uint.encode(state, u.length)
36
+ nodeArray.encode(state, u.nodes)
37
+ nodeArray.encode(state, u.additionalNodes)
38
+ c.buffer.encode(state, u.signature)
39
+ },
40
+ decode (state) {
41
+ return {
42
+ start: c.uint.decode(state),
43
+ length: c.uint.decode(state),
44
+ nodes: nodeArray.decode(state),
45
+ additionalNodes: nodeArray.decode(state),
46
+ signature: c.buffer.decode(state)
47
+ }
48
+ }
49
+ }
50
+
51
+ const dataSeek = {
52
+ preencode (state, s) {
53
+ c.uint.preencode(state, s.bytes)
54
+ nodeArray.preencode(state, s.nodes)
55
+ },
56
+ encode (state, s) {
57
+ c.uint.encode(state, s.bytes)
58
+ nodeArray.encode(state, s.nodes)
59
+ },
60
+ decode (state) {
61
+ return {
62
+ bytes: c.uint.decode(state),
63
+ nodes: nodeArray.decode(state)
64
+ }
65
+ }
66
+ }
67
+
68
+ const dataBlock = {
69
+ preencode (state, b) {
70
+ c.uint.preencode(state, b.index)
71
+ c.buffer.preencode(state, b.value)
72
+ nodeArray.preencode(state, b.nodes)
73
+ },
74
+ encode (state, b) {
75
+ c.uint.encode(state, b.index)
76
+ c.buffer.encode(state, b.value)
77
+ nodeArray.encode(state, b.nodes)
78
+ },
79
+ decode (state) {
80
+ return {
81
+ index: c.uint.decode(state),
82
+ value: c.buffer.decode(state),
83
+ nodes: nodeArray.decode(state)
84
+ }
85
+ }
86
+ }
87
+
88
+ exports.data = {
89
+ preencode (state, d) {
90
+ c.uint.preencode(state, d.fork)
91
+ state.end++ // flags
92
+ if (d.block) dataBlock.preencode(state, d.block)
93
+ if (d.seek) dataSeek.preencode(state, d.seek)
94
+ if (d.upgrade) dataUpgrade.preencode(state, d.upgrade)
95
+ },
96
+ encode (state, d) {
97
+ c.uint.encode(state, d.fork)
98
+
99
+ const s = state.start++
100
+ let flags = 0
101
+
102
+ if (d.block) {
103
+ flags |= 1
104
+ dataBlock.encode(state, d.block)
105
+ }
106
+ if (d.seek) {
107
+ flags |= 2
108
+ dataSeek.encode(state, d.seek)
109
+ }
110
+ if (d.upgrade) {
111
+ flags |= 4
112
+ dataUpgrade.encode(state, d.upgrade)
113
+ }
114
+
115
+ state.buffer[s] = flags
116
+ },
117
+ decode (state) {
118
+ const fork = c.uint.decode(state)
119
+ const flags = c.uint.decode(state)
120
+ return {
121
+ fork,
122
+ block: (flags & 1) === 0 ? null : dataBlock.decode(state),
123
+ seek: (flags & 2) === 0 ? null : dataSeek.decode(state),
124
+ upgrade: (flags & 4) === 0 ? null : dataUpgrade.decode(state)
125
+ }
126
+ }
127
+ }
128
+
129
+ const requestBlock = {
130
+ preencode (state, b) {
131
+ c.uint.preencode(state, b.index)
132
+ c.bool.preencode(state, b.value)
133
+ c.uint.preencode(state, b.nodes)
134
+ },
135
+ encode (state, b) {
136
+ c.uint.encode(state, b.index)
137
+ c.bool.encode(state, b.value)
138
+ c.uint.encode(state, b.nodes)
139
+ },
140
+ decode (state) {
141
+ return {
142
+ index: c.uint.decode(state),
143
+ value: c.bool.decode(state),
144
+ nodes: c.uint.decode(state)
145
+ }
146
+ }
147
+ }
148
+
149
+ const requestSeek = {
150
+ preencode (state, s) {
151
+ c.uint.preencode(state, s.bytes)
152
+ },
153
+ encode (state, s) {
154
+ c.uint.encode(state, s.bytes)
155
+ },
156
+ decode (state) {
157
+ return {
158
+ bytes: c.uint.decode(state)
159
+ }
160
+ }
161
+ }
162
+
163
+ const requestUpgrade = {
164
+ preencode (state, u) {
165
+ c.uint.preencode(state, u.start)
166
+ c.uint.preencode(state, u.length)
167
+ },
168
+ encode (state, u) {
169
+ c.uint.encode(state, u.start)
170
+ c.uint.encode(state, u.length)
171
+ },
172
+ decode (state) {
173
+ return {
174
+ start: c.uint.decode(state),
175
+ length: c.uint.decode(state)
176
+ }
177
+ }
178
+ }
179
+
180
+ exports.request = {
181
+ preencode (state, r) {
182
+ c.uint.preencode(state, r.fork)
183
+ state.end++ // flags
184
+ if (r.block) requestBlock.preencode(state, r.block)
185
+ if (r.seek) requestSeek.preencode(state, r.seek)
186
+ if (r.upgrade) requestUpgrade.preencode(state, r.upgrade)
187
+ },
188
+ encode (state, r) {
189
+ c.uint.encode(state, r.fork)
190
+
191
+ const s = state.start++
192
+ let flags = 0
193
+
194
+ if (r.block) {
195
+ flags |= 1
196
+ requestBlock.encode(state, r.block)
197
+ }
198
+ if (r.seek) {
199
+ flags |= 2
200
+ requestSeek.encode(state, r.seek)
201
+ }
202
+ if (r.upgrade) {
203
+ flags |= 4
204
+ requestUpgrade.encode(state, r.upgrade)
205
+ }
206
+
207
+ state.buffer[s] = flags
208
+ },
209
+ decode (state) {
210
+ const fork = c.uint.decode(state)
211
+ const flags = c.uint.decode(state)
212
+ return {
213
+ fork,
214
+ block: (flags & 1) === 0 ? null : requestBlock.decode(state),
215
+ seek: (flags & 2) === 0 ? null : requestSeek.decode(state),
216
+ upgrade: (flags & 4) === 0 ? null : requestUpgrade.decode(state)
217
+ }
218
+ }
219
+ }
220
+
221
+ exports.have = {
222
+ preencode (state, h) {
223
+ c.uint.preencode(state, h.start)
224
+ if (h.length > 1) c.uint.preencode(state, h.length)
225
+ },
226
+ encode (state, h) {
227
+ c.uint.encode(state, h.start)
228
+ if (h.length > 1) c.uint.encode(state, h.length)
229
+ },
230
+ decode (state) {
231
+ return {
232
+ start: c.uint.decode(state),
233
+ length: state.start < state.end ? c.uint.decode(state) : 1
234
+ }
235
+ }
236
+ }
237
+
238
+ exports.bitfield = {
239
+ preencode (state, b) {
240
+ c.uint.preencode(state, b.start)
241
+ c.uint32array.preencode(state, b.bitfield)
242
+ },
243
+ encode (state, b) {
244
+ c.uint.encode(state, b.start)
245
+ c.uint32array.encode(state, b.bitfield)
246
+ },
247
+ decode (state) {
248
+ return {
249
+ start: c.uint.decode(state),
250
+ bitfield: c.uint32array.decode(state)
251
+ }
252
+ }
253
+ }
254
+
255
+ exports.info = {
256
+ preencode (state, i) {
257
+ c.uint.preencode(state, i.length)
258
+ c.uint.preencode(state, i.fork)
259
+ },
260
+ encode (state, i) {
261
+ c.uint.encode(state, i.length)
262
+ c.uint.encode(state, i.fork)
263
+ },
264
+ decode (state) {
265
+ return {
266
+ length: c.uint.decode(state),
267
+ fork: c.uint.decode(state)
268
+ }
269
+ }
270
+ }
271
+
272
+ exports.handshake = {
273
+ preencode (state, h) {
274
+ c.uint.preencode(state, h.protocolVersion)
275
+ c.string.preencode(state, h.userAgent)
276
+ },
277
+ encode (state, h) {
278
+ c.uint.encode(state, h.protocolVersion)
279
+ c.string.encode(state, h.userAgent)
280
+ },
281
+ decode (state) {
282
+ return {
283
+ protocolVersion: c.uint.decode(state),
284
+ userAgent: c.string.decode(state)
285
+ }
286
+ }
287
+ }
288
+
289
+ exports.extension = {
290
+ preencode (state, a) {
291
+ c.uint.preencode(state, a.alias)
292
+ c.string.preencode(state, a.name)
293
+ },
294
+ encode (state, a) {
295
+ c.uint.encode(state, a.alias)
296
+ c.string.encode(state, a.name)
297
+ },
298
+ decode (state) {
299
+ return {
300
+ alias: c.uint.decode(state),
301
+ name: c.string.decode(state)
302
+ }
303
+ }
304
+ }
305
+
306
+ exports.core = {
307
+ preencode (state, m) {
308
+ c.uint.preencode(state, m.alias)
309
+ c.fixed32.preencode(state, m.discoveryKey)
310
+ c.fixed32.preencode(state, m.capability)
311
+ },
312
+ encode (state, m) {
313
+ c.uint.encode(state, m.alias)
314
+ c.fixed32.encode(state, m.discoveryKey)
315
+ c.fixed32.encode(state, m.capability)
316
+ },
317
+ decode (state) {
318
+ return {
319
+ alias: c.uint.decode(state),
320
+ discoveryKey: c.fixed32.decode(state),
321
+ capability: c.fixed32.decode(state)
322
+ }
323
+ }
324
+ }
325
+
326
+ exports.unknownCore = {
327
+ preencode (state, m) {
328
+ c.fixed32.preencode(state, m.discoveryKey)
329
+ },
330
+ encode (state, m) {
331
+ c.fixed32.encode(state, m.discoveryKey)
332
+ },
333
+ decode (state) {
334
+ return { discoveryKey: c.fixed32.decode(state) }
335
+ }
336
+ }
337
+
338
+ const keyValue = {
339
+ preencode (state, p) {
340
+ c.string.preencode(state, p.key)
341
+ c.buffer.preencode(state, p.value)
342
+ },
343
+ encode (state, p) {
344
+ c.string.encode(state, p.key)
345
+ c.buffer.encode(state, p.value)
346
+ },
347
+ decode (state) {
348
+ return {
349
+ key: c.string.decode(state),
350
+ value: c.buffer.decode(state)
351
+ }
352
+ }
353
+ }
354
+
355
+ const treeUpgrade = {
356
+ preencode (state, u) {
357
+ c.uint.preencode(state, u.fork)
358
+ c.uint.preencode(state, u.ancestors)
359
+ c.uint.preencode(state, u.length)
360
+ c.buffer.preencode(state, u.signature)
361
+ },
362
+ encode (state, u) {
363
+ c.uint.encode(state, u.fork)
364
+ c.uint.encode(state, u.ancestors)
365
+ c.uint.encode(state, u.length)
366
+ c.buffer.encode(state, u.signature)
367
+ },
368
+ decode (state) {
369
+ return {
370
+ fork: c.uint.decode(state),
371
+ ancestors: c.uint.decode(state),
372
+ length: c.uint.decode(state),
373
+ signature: c.buffer.decode(state)
374
+ }
375
+ }
376
+ }
377
+
378
+ const bitfieldUpdate = { // TODO: can maybe be folded into a HAVE later on with the most recent spec
379
+ preencode (state, b) {
380
+ state.end++ // flags
381
+ c.uint.preencode(state, b.start)
382
+ c.uint.preencode(state, b.length)
383
+ },
384
+ encode (state, b) {
385
+ state.buffer[state.start++] = b.drop ? 1 : 0
386
+ c.uint.encode(state, b.start)
387
+ c.uint.encode(state, b.length)
388
+ },
389
+ decode (state) {
390
+ const flags = c.uint.decode(state)
391
+ return {
392
+ drop: (flags & 1) !== 0,
393
+ start: c.uint.decode(state),
394
+ length: c.uint.decode(state)
395
+ }
396
+ }
397
+ }
398
+
399
+ exports.oplogEntry = {
400
+ preencode (state, m) {
401
+ state.end++ // flags
402
+ if (m.userData) keyValue.preencode(state, m.userData)
403
+ if (m.treeNodes) nodeArray.preencode(state, m.treeNodes)
404
+ if (m.treeUpgrade) treeUpgrade.preencode(state, m.treeUpgrade)
405
+ if (m.bitfield) bitfieldUpdate.preencode(state, m.bitfield)
406
+ },
407
+ encode (state, m) {
408
+ const s = state.start++
409
+ let flags = 0
410
+
411
+ if (m.userData) {
412
+ flags |= 1
413
+ keyValue.encode(state, m.userData)
414
+ }
415
+ if (m.treeNodes) {
416
+ flags |= 2
417
+ nodeArray.encode(state, m.treeNodes)
418
+ }
419
+ if (m.treeUpgrade) {
420
+ flags |= 4
421
+ treeUpgrade.encode(state, m.treeUpgrade)
422
+ }
423
+ if (m.bitfield) {
424
+ flags |= 8
425
+ bitfieldUpdate.encode(state, m.bitfield)
426
+ }
427
+
428
+ state.buffer[s] = flags
429
+ },
430
+ decode (state) {
431
+ const flags = c.uint.decode(state)
432
+ return {
433
+ userData: (flags & 1) !== 0 ? keyValue.decode(state) : null,
434
+ treeNodes: (flags & 2) !== 0 ? nodeArray.decode(state) : null,
435
+ treeUpgrade: (flags & 4) !== 0 ? treeUpgrade.decode(state) : null,
436
+ bitfield: (flags & 8) !== 0 ? bitfieldUpdate.decode(state) : null
437
+ }
438
+ }
439
+ }
440
+
441
+ const keyPair = {
442
+ preencode (state, kp) {
443
+ c.buffer.preencode(state, kp.publicKey)
444
+ c.buffer.preencode(state, kp.secretKey)
445
+ },
446
+ encode (state, kp) {
447
+ c.buffer.encode(state, kp.publicKey)
448
+ c.buffer.encode(state, kp.secretKey)
449
+ },
450
+ decode (state) {
451
+ return {
452
+ publicKey: c.buffer.decode(state),
453
+ secretKey: c.buffer.decode(state)
454
+ }
455
+ }
456
+ }
457
+
458
+ const reorgHint = {
459
+ preencode (state, r) {
460
+ c.uint.preencode(state, r.from)
461
+ c.uint.preencode(state, r.to)
462
+ c.uint.preencode(state, r.ancestors)
463
+ },
464
+ encode (state, r) {
465
+ c.uint.encode(state, r.from)
466
+ c.uint.encode(state, r.to)
467
+ c.uint.encode(state, r.ancestors)
468
+ },
469
+ decode (state) {
470
+ return {
471
+ from: c.uint.decode(state),
472
+ to: c.uint.decode(state),
473
+ ancestors: c.uint.decode(state)
474
+ }
475
+ }
476
+ }
477
+
478
+ const reorgHintArray = c.array(reorgHint)
479
+
480
+ const hints = {
481
+ preencode (state, h) {
482
+ reorgHintArray.preencode(state, h.reorgs)
483
+ },
484
+ encode (state, h) {
485
+ reorgHintArray.encode(state, h.reorgs)
486
+ },
487
+ decode (state) {
488
+ return {
489
+ reorgs: reorgHintArray.decode(state)
490
+ }
491
+ }
492
+ }
493
+
494
+ const treeHeader = {
495
+ preencode (state, t) {
496
+ c.uint.preencode(state, t.fork)
497
+ c.uint.preencode(state, t.length)
498
+ c.buffer.preencode(state, t.rootHash)
499
+ c.buffer.preencode(state, t.signature)
500
+ },
501
+ encode (state, t) {
502
+ c.uint.encode(state, t.fork)
503
+ c.uint.encode(state, t.length)
504
+ c.buffer.encode(state, t.rootHash)
505
+ c.buffer.encode(state, t.signature)
506
+ },
507
+ decode (state) {
508
+ return {
509
+ fork: c.uint.decode(state),
510
+ length: c.uint.decode(state),
511
+ rootHash: c.buffer.decode(state),
512
+ signature: c.buffer.decode(state)
513
+ }
514
+ }
515
+ }
516
+
517
+ const types = {
518
+ preencode (state, t) {
519
+ c.string.preencode(state, t.tree)
520
+ c.string.preencode(state, t.bitfield)
521
+ c.string.preencode(state, t.signer)
522
+ },
523
+ encode (state, t) {
524
+ c.string.encode(state, t.tree)
525
+ c.string.encode(state, t.bitfield)
526
+ c.string.encode(state, t.signer)
527
+ },
528
+ decode (state) {
529
+ return {
530
+ tree: c.string.decode(state),
531
+ bitfield: c.string.decode(state),
532
+ signer: c.string.decode(state)
533
+ }
534
+ }
535
+ }
536
+
537
+ const keyValueArray = c.array(keyValue)
538
+
539
+ exports.oplogHeader = {
540
+ preencode (state, h) {
541
+ state.end += 1 // version
542
+ types.preencode(state, h.types)
543
+ keyValueArray.preencode(state, h.userData)
544
+ treeHeader.preencode(state, h.tree)
545
+ keyPair.preencode(state, h.signer)
546
+ hints.preencode(state, h.hints)
547
+ },
548
+ encode (state, h) {
549
+ state.buffer[state.start++] = 0 // version
550
+ types.encode(state, h.types)
551
+ keyValueArray.encode(state, h.userData)
552
+ treeHeader.encode(state, h.tree)
553
+ keyPair.encode(state, h.signer)
554
+ hints.encode(state, h.hints)
555
+ },
556
+ decode (state) {
557
+ const version = c.uint.decode(state)
558
+
559
+ if (version !== 0) {
560
+ throw new Error('Invalid header version. Expected 0, got ' + version)
561
+ }
562
+
563
+ return {
564
+ types: types.decode(state),
565
+ userData: keyValueArray.decode(state),
566
+ tree: treeHeader.decode(state),
567
+ signer: keyPair.decode(state),
568
+ hints: hints.decode(state)
569
+ }
570
+ }
571
+ }
package/lib/mutex.js ADDED
@@ -0,0 +1,39 @@
1
+ module.exports = class Mutex {
2
+ constructor () {
3
+ this.locked = false
4
+ this.destroyed = false
5
+
6
+ this._destroying = null
7
+ this._destroyError = null
8
+ this._queue = []
9
+ this._enqueue = (resolve, reject) => this._queue.push([resolve, reject])
10
+ }
11
+
12
+ lock () {
13
+ if (this.destroyed) return Promise.reject(this._destroyError)
14
+ if (this.locked) return new Promise(this._enqueue)
15
+ this.locked = true
16
+ return Promise.resolve()
17
+ }
18
+
19
+ unlock () {
20
+ if (!this._queue.length) {
21
+ this.locked = false
22
+ return
23
+ }
24
+ this._queue.shift()[0]()
25
+ }
26
+
27
+ destroy (err) {
28
+ if (!this._destroying) this._destroying = this.locked ? this.lock().catch(() => {}) : Promise.resolve()
29
+
30
+ this.destroyed = true
31
+ this._destroyError = err || new Error('Mutex has been destroyed')
32
+
33
+ if (err) {
34
+ while (this._queue.length) this._queue.shift()[1](err)
35
+ }
36
+
37
+ return this._destroying
38
+ }
39
+ }