hypercore 10.24.5 → 10.24.6
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/index.js +2 -6
- package/lib/batch.js +13 -53
- package/lib/core.js +57 -26
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -958,12 +958,8 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
958
958
|
}
|
|
959
959
|
|
|
960
960
|
async append (blocks, opts = {}) {
|
|
961
|
-
if (this._batch && this !== this._batch.session) throw BATCH_UNFLUSHED()
|
|
962
|
-
|
|
963
|
-
// if a batched append, run unlocked as it already locked...
|
|
964
|
-
const lock = !this._batch
|
|
965
|
-
|
|
966
961
|
if (this.opened === false) await this.opening
|
|
962
|
+
if (this._batch) throw BATCH_UNFLUSHED()
|
|
967
963
|
|
|
968
964
|
const { keyPair = this.keyPair, signature = null } = opts
|
|
969
965
|
const writable = !this._readonly && !!(signature || (keyPair && keyPair.secretKey))
|
|
@@ -982,7 +978,7 @@ module.exports = class Hypercore extends EventEmitter {
|
|
|
982
978
|
}
|
|
983
979
|
}
|
|
984
980
|
|
|
985
|
-
return this.core.append(buffers, {
|
|
981
|
+
return this.core.append(buffers, { keyPair, signature, preappend })
|
|
986
982
|
}
|
|
987
983
|
|
|
988
984
|
async treeHash (length) {
|
package/lib/batch.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const { BLOCK_NOT_AVAILABLE, SESSION_CLOSED } = require('hypercore-errors')
|
|
2
2
|
const EventEmitter = require('events')
|
|
3
3
|
const c = require('compact-encoding')
|
|
4
|
-
const b4a = require('b4a')
|
|
5
4
|
|
|
6
5
|
module.exports = class HypercoreBatch extends EventEmitter {
|
|
7
6
|
constructor (session, autoClose) {
|
|
@@ -76,7 +75,6 @@ module.exports = class HypercoreBatch extends EventEmitter {
|
|
|
76
75
|
async update (opts) {
|
|
77
76
|
if (this.opened === false) await this.ready()
|
|
78
77
|
await this.session.update(opts)
|
|
79
|
-
await this._catchup()
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
setUserData (key, value, opts) {
|
|
@@ -253,64 +251,26 @@ module.exports = class HypercoreBatch extends EventEmitter {
|
|
|
253
251
|
return flushed
|
|
254
252
|
}
|
|
255
253
|
|
|
256
|
-
async _catchup () {
|
|
257
|
-
if (this.core.tree.length === this._sessionLength) return true
|
|
258
|
-
|
|
259
|
-
const batchLength = this._sessionLength + this._appends.length
|
|
260
|
-
|
|
261
|
-
if (this.core.tree.length > batchLength) return false
|
|
262
|
-
|
|
263
|
-
const b = this.createTreeBatch()
|
|
264
|
-
|
|
265
|
-
for (const root of this.core.tree.roots) {
|
|
266
|
-
const batchRoot = await b.get(root.index)
|
|
267
|
-
|
|
268
|
-
if (batchRoot === null) continue // in the shared tree
|
|
269
|
-
if (batchRoot.size !== root.size || !b4a.equals(batchRoot.hash, root.hash)) {
|
|
270
|
-
// TODO: type this error
|
|
271
|
-
throw new Error('Batch is uncommitable due to a conflict at ' + root.index)
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
const offset = this.core.tree.length - this._sessionLength
|
|
276
|
-
for (let i = 0; i < offset; i++) this._byteLength -= this._appends[i].byteLength
|
|
277
|
-
|
|
278
|
-
await this.core.insertValuesUnsafe(this._appends.slice(0, offset), this._sessionLength, this._sessionByteLength, b.nodes)
|
|
279
|
-
|
|
280
|
-
this._sessionLength = this.session.length
|
|
281
|
-
this._sessionByteLength = this.session.byteLength
|
|
282
|
-
this._sessionBatch = this.session.createTreeBatch()
|
|
283
|
-
this._appends = this._appends.slice(offset)
|
|
284
|
-
|
|
285
|
-
return true
|
|
286
|
-
}
|
|
287
|
-
|
|
288
254
|
async _flush (length, keyPair, signature) { // TODO: make this safe to interact with a parallel truncate...
|
|
289
|
-
|
|
290
|
-
if (
|
|
255
|
+
const flushingLength = Math.min(length - this._sessionLength, this._appends.length)
|
|
256
|
+
if (flushingLength <= 0) return true
|
|
291
257
|
|
|
292
|
-
|
|
258
|
+
const batch = this.createTreeBatch(this._sessionLength + flushingLength)
|
|
259
|
+
if (batch === null) return false
|
|
293
260
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (flushingLength <= 0) return true
|
|
261
|
+
const info = await this.core.insertBatch(batch, this._appends, { keyPair, signature })
|
|
262
|
+
if (info === null) return false
|
|
297
263
|
|
|
298
|
-
|
|
264
|
+
const delta = info.byteLength - this._sessionByteLength
|
|
299
265
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
this._sessionLength = info.length
|
|
304
|
-
this._sessionByteLength = info.byteLength
|
|
305
|
-
this._sessionBatch = this.session.createTreeBatch()
|
|
266
|
+
this._sessionLength = info.length
|
|
267
|
+
this._sessionByteLength = info.byteLength
|
|
268
|
+
this._sessionBatch = this.session.createTreeBatch()
|
|
306
269
|
|
|
307
|
-
|
|
308
|
-
|
|
270
|
+
this._appends = this._appends.slice(flushingLength)
|
|
271
|
+
this._byteLength -= delta
|
|
309
272
|
|
|
310
|
-
|
|
311
|
-
} finally {
|
|
312
|
-
this.core._mutex.unlock()
|
|
313
|
-
}
|
|
273
|
+
this.emit('flush')
|
|
314
274
|
|
|
315
275
|
return true
|
|
316
276
|
}
|
package/lib/core.js
CHANGED
|
@@ -432,40 +432,71 @@ module.exports = class Core {
|
|
|
432
432
|
})
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
if (!values.length) return
|
|
435
|
+
async insertBatch (batch, values, { signature, keyPair = this.header.keyPair } = {}) {
|
|
436
|
+
await this._mutex.lock()
|
|
438
437
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
end: offset + values.length
|
|
443
|
-
}
|
|
438
|
+
try {
|
|
439
|
+
// upsert compat manifest
|
|
440
|
+
if (this.verifier === null && keyPair) this.setManifest(null, keyPair)
|
|
444
441
|
|
|
445
|
-
|
|
446
|
-
await this.oplog.append({
|
|
447
|
-
userData: null,
|
|
448
|
-
treeNodes,
|
|
449
|
-
treeUpgrade: null,
|
|
450
|
-
bitfield
|
|
451
|
-
}, false)
|
|
442
|
+
if (this.tree.fork !== batch.fork) return null
|
|
452
443
|
|
|
453
|
-
|
|
454
|
-
|
|
444
|
+
if (this.tree.length > batch.treeLength) {
|
|
445
|
+
if (this.tree.length > batch.length) return null // TODO: partial commit in the future if possible
|
|
455
446
|
|
|
456
|
-
|
|
457
|
-
|
|
447
|
+
for (const root of this.tree.roots) {
|
|
448
|
+
const batchRoot = await batch.get(root.index)
|
|
449
|
+
if (batchRoot.size !== root.size || !b4a.equals(batchRoot.hash, root.hash)) {
|
|
450
|
+
return null
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
458
454
|
|
|
459
|
-
|
|
460
|
-
|
|
455
|
+
const offset = batch.treeLength
|
|
456
|
+
const adding = batch.length - batch.treeLength
|
|
461
457
|
|
|
462
|
-
|
|
463
|
-
|
|
458
|
+
batch.upgraded = batch.length > this.tree.length
|
|
459
|
+
batch.treeLength = this.tree.length
|
|
460
|
+
if (batch.upgraded) batch.signature = signature || this.verifier.sign(batch, keyPair)
|
|
464
461
|
|
|
465
|
-
|
|
466
|
-
|
|
462
|
+
let byteOffset = batch.byteLength
|
|
463
|
+
for (let i = 0; i < adding; i++) byteOffset -= values[i].byteLength
|
|
464
|
+
|
|
465
|
+
const entry = {
|
|
466
|
+
userData: null,
|
|
467
|
+
treeNodes: batch.nodes,
|
|
468
|
+
treeUpgrade: batch.upgraded ? batch : null,
|
|
469
|
+
bitfield: {
|
|
470
|
+
drop: false,
|
|
471
|
+
start: offset,
|
|
472
|
+
length: adding
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
await this.blocks.putBatch(offset, adding > values.length ? values.slice(0, adding) : values, byteOffset)
|
|
477
|
+
await this.oplog.append([entry], false)
|
|
478
|
+
|
|
479
|
+
this.bitfield.setRange(entry.bitfield.start, entry.bitfield.length, true)
|
|
480
|
+
batch.commit()
|
|
481
|
+
|
|
482
|
+
const status = (batch.upgraded ? 0b0001 : 0) | updateContig(this.header, entry.bitfield, this.bitfield)
|
|
483
|
+
this.onupdate(status, entry.bitfield, null, null)
|
|
484
|
+
|
|
485
|
+
if (this._shouldFlush()) await this._flushOplog()
|
|
486
|
+
} finally {
|
|
487
|
+
this._mutex.unlock()
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return { length: batch.length, byteLength: batch.byteLength }
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
async append (values, { signature, keyPair = this.header.keyPair, preappend } = {}) {
|
|
494
|
+
await this._mutex.lock()
|
|
467
495
|
|
|
468
496
|
try {
|
|
497
|
+
// upsert compat manifest
|
|
498
|
+
if (this.verifier === null && keyPair) this.setManifest(null, keyPair)
|
|
499
|
+
|
|
469
500
|
if (preappend) await preappend(values)
|
|
470
501
|
|
|
471
502
|
if (!values.length) {
|
|
@@ -506,7 +537,7 @@ module.exports = class Core {
|
|
|
506
537
|
|
|
507
538
|
return { length: batch.length, byteLength }
|
|
508
539
|
} finally {
|
|
509
|
-
|
|
540
|
+
this._mutex.unlock()
|
|
510
541
|
}
|
|
511
542
|
}
|
|
512
543
|
|