hypercore 11.30.1 → 11.31.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/index.js CHANGED
@@ -270,6 +270,11 @@ class Hypercore extends EventEmitter {
270
270
  this.encryption = encryption
271
271
  }
272
272
 
273
+ async setGroup(topic) {
274
+ if (!this.opened) await this.opening
275
+ return this.core.setGroup(topic)
276
+ }
277
+
273
278
  setKeyPair(keyPair) {
274
279
  this.keyPair = keyPair
275
280
  }
@@ -1363,6 +1368,7 @@ function initOnce(session, storage, key, opts) {
1363
1368
  keyPair: opts.keyPair,
1364
1369
  legacy: opts.legacy,
1365
1370
  manifest: opts.manifest,
1371
+ group: opts.group,
1366
1372
  globalCache: opts.globalCache || null // session is a temp option, not to be relied on unless you know what you are doing (no semver guarantees)
1367
1373
  })
1368
1374
  }
package/lib/core.js CHANGED
@@ -214,8 +214,10 @@ module.exports = class Core {
214
214
  fork: 0,
215
215
  length: 0,
216
216
  rootHash: null,
217
- signature: null
217
+ signature: null,
218
+ timestamp: 0
218
219
  },
220
+ group: null,
219
221
  hints: {
220
222
  reorgs: [],
221
223
  contiguousLength: 0,
@@ -296,6 +298,19 @@ module.exports = class Core {
296
298
  this.replicator.setPushOnly(true)
297
299
  }
298
300
 
301
+ if (opts.group) {
302
+ if (!header.group) header.group = await this.db.createGroup(opts.group)
303
+ else if (!b4a.equals(header.group.key, opts.group)) {
304
+ throw STORAGE_CONFLICT(
305
+ 'Core is already register to group: ' + b4a.toString(header.group.key, 'hex')
306
+ )
307
+ }
308
+
309
+ const tx = storage.write()
310
+ tx.setGroup(header.group)
311
+ await tx.flush()
312
+ }
313
+
299
314
  if (overwrite) {
300
315
  const tx = storage.write()
301
316
  tx.deleteTreeNodeRange(0, -1)
@@ -354,6 +369,24 @@ module.exports = class Core {
354
369
  }
355
370
  }
356
371
 
372
+ async setGroup(group) {
373
+ await this.state.mutex.lock()
374
+ try {
375
+ if (!this.header.group) this.header.group = await this.db.createGroup(group)
376
+ else if (!b4a.equals(this.header.group.key, group)) {
377
+ throw STORAGE_CONFLICT(
378
+ 'Core is already register to group: ' + b4a.toString(this.header.group.key, 'hex')
379
+ )
380
+ }
381
+
382
+ const tx = this.storage.write()
383
+ tx.setGroup(this.header.group)
384
+ await tx.flush()
385
+ } finally {
386
+ this.state.mutex.unlock()
387
+ }
388
+ }
389
+
357
390
  async setManifest(manifest) {
358
391
  await this.state.mutex.lock()
359
392
 
@@ -965,7 +998,8 @@ function getDefaultTree() {
965
998
  fork: 0,
966
999
  length: 0,
967
1000
  rootHash: null,
968
- signature: null
1001
+ signature: null,
1002
+ timestamp: 0
969
1003
  }
970
1004
  }
971
1005
 
@@ -978,6 +1012,7 @@ function parseHeader(info) {
978
1012
  external: null,
979
1013
  keyPair: info.keyPair,
980
1014
  tree: info.head || getDefaultTree(),
1015
+ group: info.group,
981
1016
  hints: {
982
1017
  reorgs: [],
983
1018
  contiguousLength: info.hints ? info.hints.contiguousLength : 0,
@@ -1005,13 +1040,15 @@ async function getCoreInfo(storage) {
1005
1040
  const auth = r.getAuth()
1006
1041
  const head = r.getHead()
1007
1042
  const hints = r.getHints()
1043
+ const group = r.getGroup()
1008
1044
 
1009
1045
  r.tryFlush()
1010
1046
 
1011
- const [authInfo, headInfo, hintsInfo] = await Promise.all([auth, head, hints])
1047
+ const [authInfo, headInfo, hintsInfo, groupInfo] = await Promise.all([auth, head, hints, group])
1012
1048
  return {
1013
1049
  ...authInfo,
1014
1050
  head: headInfo,
1015
- hints: hintsInfo
1051
+ hints: hintsInfo,
1052
+ group: groupInfo
1016
1053
  }
1017
1054
  }
package/lib/replicator.js CHANGED
@@ -2451,14 +2451,16 @@ module.exports = class Replicator {
2451
2451
 
2452
2452
  if (this._manifestPeer === peer) this._manifestPeer = null
2453
2453
 
2454
+ let inflight = false
2454
2455
  for (const req of this._inflight) {
2455
2456
  if (req.peer !== peer) continue
2457
+ inflight = true
2456
2458
  this._inflight.remove(req.id, true)
2457
2459
  this._clearRequest(peer, req)
2458
2460
  }
2459
2461
 
2460
2462
  this._onpeerupdate(false, peer)
2461
- this.updateAll()
2463
+ if (inflight) this.updateAll()
2462
2464
  }
2463
2465
 
2464
2466
  _queueBlock(b) {
@@ -219,6 +219,13 @@ class SessionState {
219
219
  return dependency
220
220
  }
221
221
 
222
+ updateGroupIndex(tx, tree) {
223
+ const { pointer } = this.core.header.group
224
+
225
+ tx.deleteGroupUpdate(pointer, this.core.header.tree.timestamp)
226
+ tx.putGroupUpdate(pointer, tree.timestamp, this.core.header.key)
227
+ }
228
+
222
229
  _clearActiveBatch() {
223
230
  this._activeTx = null
224
231
  }
@@ -294,7 +301,16 @@ class SessionState {
294
301
  fork: this.fork,
295
302
  length: this.length,
296
303
  rootHash: this.hash(),
297
- signature: this.signature
304
+ signature: this.signature,
305
+ timestamp: Date.now()
306
+ }
307
+
308
+ if (this.isDefault() && this.core.header.group) {
309
+ const { pointer } = this.core.header.group
310
+
311
+ const tx = await this.createWriteBatch()
312
+ this.updateGroupIndex(tx, tree)
313
+ await tx.flush()
298
314
  }
299
315
 
300
316
  if (dependency) this.storage.setDependencyHead(dependency)
@@ -364,10 +380,17 @@ class SessionState {
364
380
  fork: batch.fork,
365
381
  length: batch.length,
366
382
  rootHash: batch.hash(),
367
- signature: batch.signature
383
+ signature: batch.signature,
384
+ timestamp: Date.now()
368
385
  }
369
386
 
370
- if (batch.upgraded) tx.setHead(head)
387
+ if (batch.upgraded) {
388
+ tx.setHead(head)
389
+
390
+ if (this.core.header.group) {
391
+ this.updateGroupIndex(tx, head)
392
+ }
393
+ }
371
394
 
372
395
  const flushed = await this.flush()
373
396
 
@@ -487,7 +510,12 @@ class SessionState {
487
510
  fork: batch.fork,
488
511
  length: batch.length,
489
512
  rootHash: batch.hash(),
490
- signature: batch.signature
513
+ signature: batch.signature,
514
+ timestamp: Date.now()
515
+ }
516
+
517
+ if (this.isDefault() && this.core.header.group) {
518
+ this.updateGroupIndex(storage, tree)
491
519
  }
492
520
 
493
521
  storage.setHead(tree)
@@ -663,7 +691,8 @@ class SessionState {
663
691
  fork: batch.fork,
664
692
  length: batch.length,
665
693
  rootHash: batch.hash(),
666
- signature: batch.signature
694
+ signature: batch.signature,
695
+ timestamp: Date.now()
667
696
  }
668
697
 
669
698
  tx.setHead(tree)
@@ -676,6 +705,10 @@ class SessionState {
676
705
  remoteContiguousLength: this.core.header.hints.remoteContiguousLength
677
706
  })
678
707
  }
708
+
709
+ if (this.core.header.group) {
710
+ this.updateGroupIndex(tx, tree)
711
+ }
679
712
  }
680
713
 
681
714
  for (let i = 0; i < values.length; i++) {
@@ -829,9 +862,11 @@ class SessionState {
829
862
  fork,
830
863
  length,
831
864
  rootHash: crypto.tree(roots),
832
- signature: null
865
+ signature: null,
866
+ timestamp: Date.now()
833
867
  }
834
868
 
869
+ // never default state so do not update group index
835
870
  tx.setHead(tree)
836
871
 
837
872
  // prop a better way to do this
@@ -957,7 +992,12 @@ class SessionState {
957
992
  fork,
958
993
  length,
959
994
  rootHash: crypto.tree(roots),
960
- signature
995
+ signature,
996
+ timestamp: Date.now()
997
+ }
998
+
999
+ if (this.isDefault() && this.core.header.group) {
1000
+ this.updateGroupIndex(tx, tree)
961
1001
  }
962
1002
 
963
1003
  const upgraded = treeLength < this.length || this.length < length || tree.fork !== this.fork
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore",
3
- "version": "11.30.1",
3
+ "version": "11.31.0",
4
4
  "description": "Hypercore is a secure, distributed append-only log",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -54,7 +54,7 @@
54
54
  "hypercore-crypto": "^3.2.1",
55
55
  "hypercore-errors": "^1.5.0",
56
56
  "hypercore-id-encoding": "^1.2.0",
57
- "hypercore-storage": "^2.8.0",
57
+ "hypercore-storage": "^3.0.0",
58
58
  "is-options": "^1.0.1",
59
59
  "nanoassert": "^2.0.0",
60
60
  "protomux": "^3.5.0",