corestore 7.9.1 → 7.10.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 +72 -8
- package/lib/notify.js +27 -0
- package/package.json +13 -6
package/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const { isAndroid } = require('which-runtime')
|
|
|
8
8
|
const { STORAGE_EMPTY, ASSERTION } = require('hypercore-errors')
|
|
9
9
|
|
|
10
10
|
const auditStore = require('./lib/audit.js')
|
|
11
|
+
const GroupNotifyHandle = require('./lib/notify.js')
|
|
11
12
|
|
|
12
13
|
const [NS] = crypto.namespace('corestore', 1)
|
|
13
14
|
const DEFAULT_NAMESPACE = b4a.alloc(32) // This is meant to be 32 0-bytes
|
|
@@ -204,6 +205,7 @@ class FindingPeers {
|
|
|
204
205
|
constructor() {
|
|
205
206
|
this.count = 0
|
|
206
207
|
this.pending = []
|
|
208
|
+
this.destroyed = false
|
|
207
209
|
}
|
|
208
210
|
|
|
209
211
|
add(core) {
|
|
@@ -212,7 +214,7 @@ class FindingPeers {
|
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
inc(sessions) {
|
|
215
|
-
if (++this.count !== 1) return
|
|
217
|
+
if (this.destroyed || ++this.count !== 1) return
|
|
216
218
|
|
|
217
219
|
for (const core of sessions) {
|
|
218
220
|
this.pending.push(core.findingPeers())
|
|
@@ -220,7 +222,12 @@ class FindingPeers {
|
|
|
220
222
|
}
|
|
221
223
|
|
|
222
224
|
dec(sessions) {
|
|
223
|
-
if (--this.count !== 0) return
|
|
225
|
+
if (this.destroyed || --this.count !== 0) return
|
|
226
|
+
while (this.pending.length > 0) this.pending.pop()()
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
destroy() {
|
|
230
|
+
this.destroyed = true
|
|
224
231
|
while (this.pending.length > 0) this.pending.pop()()
|
|
225
232
|
}
|
|
226
233
|
}
|
|
@@ -253,8 +260,10 @@ class Corestore extends ReadyResource {
|
|
|
253
260
|
this.watchers = null
|
|
254
261
|
this.watchIndex = -1
|
|
255
262
|
|
|
263
|
+
this._groupNotifiers = new Map() // group notifications
|
|
256
264
|
this._findingPeers = null // here for legacy
|
|
257
265
|
this._ongcBound = this._ongc.bind(this)
|
|
266
|
+
this._onGroupActiveBound = this._onGroupActive.bind(this)
|
|
258
267
|
|
|
259
268
|
if (opts.primaryKey && !this.root && !opts.unsafe) {
|
|
260
269
|
throw ASSERTION(
|
|
@@ -262,8 +271,6 @@ class Corestore extends ReadyResource {
|
|
|
262
271
|
)
|
|
263
272
|
}
|
|
264
273
|
|
|
265
|
-
if (this.root) this.corestores.add(this)
|
|
266
|
-
|
|
267
274
|
this.ready().catch(noop)
|
|
268
275
|
}
|
|
269
276
|
|
|
@@ -287,12 +294,50 @@ class Corestore extends ReadyResource {
|
|
|
287
294
|
}
|
|
288
295
|
}
|
|
289
296
|
|
|
297
|
+
_onGroupActive(topic) {
|
|
298
|
+
this.emit('group-active', topic)
|
|
299
|
+
|
|
300
|
+
const topicHex = b4a.toString(topic, 'hex')
|
|
301
|
+
const handles = this._groupNotifiers.get(topicHex)
|
|
302
|
+
if (!handles) return
|
|
303
|
+
for (const handle of handles) handle.emit('update')
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
notifyGroup(topic) {
|
|
307
|
+
const topicHex = b4a.toString(topic, 'hex')
|
|
308
|
+
let handles = this._groupNotifiers.get(topicHex)
|
|
309
|
+
|
|
310
|
+
if (!handles) {
|
|
311
|
+
handles = []
|
|
312
|
+
this._groupNotifiers.set(topicHex, handles)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const handle = new GroupNotifyHandle(this, topic)
|
|
316
|
+
const length = handles.push(handle)
|
|
317
|
+
handle.index = length - 1
|
|
318
|
+
|
|
319
|
+
return handle
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
_removeGroupNotify(handle) {
|
|
323
|
+
if (handle.index === -1) return
|
|
324
|
+
|
|
325
|
+
const topicHex = b4a.toString(handle._topic, 'hex')
|
|
326
|
+
const handles = this._groupNotifiers.get(topicHex)
|
|
327
|
+
if (!handles) return
|
|
328
|
+
|
|
329
|
+
const popped = handles.pop()
|
|
330
|
+
if (popped !== handle) handles[(popped.index = handle.index)] = popped
|
|
331
|
+
if (handles.length === 0) this._groupNotifiers.delete(topicHex)
|
|
332
|
+
handle.index = -1
|
|
333
|
+
}
|
|
334
|
+
|
|
290
335
|
findingPeers() {
|
|
291
336
|
if (this._findingPeers === null) this._findingPeers = new FindingPeers()
|
|
292
337
|
this._findingPeers.inc(this.sessions)
|
|
293
338
|
let done = false
|
|
294
339
|
return () => {
|
|
295
|
-
if (done) return
|
|
340
|
+
if (done || !this._findingPeers) return
|
|
296
341
|
done = true
|
|
297
342
|
this._findingPeers.dec(this.sessions)
|
|
298
343
|
}
|
|
@@ -352,6 +397,7 @@ class Corestore extends ReadyResource {
|
|
|
352
397
|
|
|
353
398
|
async _open() {
|
|
354
399
|
if (this.root !== null) {
|
|
400
|
+
this.corestores.add(this)
|
|
355
401
|
if (this.root.opened === false) await this.root.ready()
|
|
356
402
|
this.primaryKey = this.root.primaryKey
|
|
357
403
|
return
|
|
@@ -374,10 +420,19 @@ class Corestore extends ReadyResource {
|
|
|
374
420
|
const hanging = [...this.sessions]
|
|
375
421
|
for (const sess of hanging) closing.push(sess.close())
|
|
376
422
|
|
|
377
|
-
if (this.watchers !== null)
|
|
423
|
+
if (this.watchers !== null) {
|
|
424
|
+
this.cores.unwatch(this)
|
|
425
|
+
this.watchers = null
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (this._findingPeers !== null) {
|
|
429
|
+
this._findingPeers.destroy()
|
|
430
|
+
this._findingPeers = null
|
|
431
|
+
}
|
|
378
432
|
|
|
379
433
|
if (this.root !== null) {
|
|
380
434
|
await Promise.all(closing)
|
|
435
|
+
this.corestores.delete(this)
|
|
381
436
|
return
|
|
382
437
|
}
|
|
383
438
|
|
|
@@ -554,6 +609,7 @@ class Corestore extends ReadyResource {
|
|
|
554
609
|
|
|
555
610
|
_makeSession(conf) {
|
|
556
611
|
const session = new Hypercore(null, null, conf)
|
|
612
|
+
|
|
557
613
|
if (this._findingPeers !== null) this._findingPeers.add(session)
|
|
558
614
|
return session
|
|
559
615
|
}
|
|
@@ -596,7 +652,8 @@ class Corestore extends ReadyResource {
|
|
|
596
652
|
keyPair: null,
|
|
597
653
|
key: null,
|
|
598
654
|
discoveryKey,
|
|
599
|
-
manifest: null
|
|
655
|
+
manifest: null,
|
|
656
|
+
group: null
|
|
600
657
|
}
|
|
601
658
|
|
|
602
659
|
if (opts.name) {
|
|
@@ -614,6 +671,10 @@ class Corestore extends ReadyResource {
|
|
|
614
671
|
}
|
|
615
672
|
}
|
|
616
673
|
|
|
674
|
+
if (opts.group) {
|
|
675
|
+
result.group = opts.group
|
|
676
|
+
}
|
|
677
|
+
|
|
617
678
|
if (opts.key) result.key = ID.decode(opts.key)
|
|
618
679
|
else if (result.manifest) result.key = Hypercore.key(result.manifest)
|
|
619
680
|
|
|
@@ -630,7 +691,7 @@ class Corestore extends ReadyResource {
|
|
|
630
691
|
const auth = this._auth(discoveryKey, opts)
|
|
631
692
|
|
|
632
693
|
const id = toHex(auth.discoveryKey)
|
|
633
|
-
const existing = this.cores.resume(id)
|
|
694
|
+
const existing = this.cores.resume(id, auth.group)
|
|
634
695
|
if (existing && !existing.closing) return existing
|
|
635
696
|
|
|
636
697
|
const core = Hypercore.createCore(this.storage, {
|
|
@@ -649,6 +710,7 @@ class Corestore extends ReadyResource {
|
|
|
649
710
|
keyPair: auth.keyPair,
|
|
650
711
|
legacy: opts.legacy,
|
|
651
712
|
manifest: auth.manifest,
|
|
713
|
+
group: auth.group,
|
|
652
714
|
globalCache: opts.globalCache || this.globalCache || null,
|
|
653
715
|
alias: opts.name ? { name: opts.name, namespace: this.ns } : null
|
|
654
716
|
})
|
|
@@ -657,6 +719,8 @@ class Corestore extends ReadyResource {
|
|
|
657
719
|
this.cores.gc(core)
|
|
658
720
|
}
|
|
659
721
|
|
|
722
|
+
core.ongroupupdate = this._onGroupActiveBound
|
|
723
|
+
|
|
660
724
|
core.replicator.ondownloading = () => {
|
|
661
725
|
if (this.active) this.streamTracker.attachAll(core)
|
|
662
726
|
}
|
package/lib/notify.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const { EventEmitter } = require('events')
|
|
2
|
+
const { Readable } = require('streamx')
|
|
3
|
+
|
|
4
|
+
class GroupNotifyHandle extends EventEmitter {
|
|
5
|
+
constructor(store, topic) {
|
|
6
|
+
super()
|
|
7
|
+
this._store = store
|
|
8
|
+
this._topic = topic
|
|
9
|
+
this.index = -1
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
updates(opts) {
|
|
13
|
+
return Readable.deferred(async () => {
|
|
14
|
+
const groupId = await this._store.storage.getGroup(this._topic).catch(noop)
|
|
15
|
+
if (groupId === null) return null
|
|
16
|
+
return this._store.storage.createGroupUpdateStream(groupId, opts)
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
destroy() {
|
|
21
|
+
this._store._removeGroupNotify(this)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = GroupNotifyHandle
|
|
26
|
+
|
|
27
|
+
function noop() {}
|
package/package.json
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "corestore",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.10.0",
|
|
4
4
|
"description": "A Hypercore factory that simplifies managing collections of cores.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"index.js",
|
|
8
8
|
"lib/*"
|
|
9
9
|
],
|
|
10
|
+
"imports": {
|
|
11
|
+
"events": {
|
|
12
|
+
"bare": "bare-events",
|
|
13
|
+
"default": "events"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
10
16
|
"dependencies": {
|
|
11
17
|
"b4a": "^1.6.7",
|
|
12
|
-
"
|
|
18
|
+
"bare-events": "^2.8.3",
|
|
19
|
+
"hypercore": "^11.32.0",
|
|
13
20
|
"hypercore-crypto": "^3.4.2",
|
|
14
21
|
"hypercore-errors": "^1.4.0",
|
|
15
22
|
"hypercore-id-encoding": "^1.3.0",
|
|
16
23
|
"ready-resource": "^1.1.1",
|
|
17
24
|
"sodium-universal": "^5.0.1",
|
|
25
|
+
"streamx": "^2.26.0",
|
|
18
26
|
"which-runtime": "^1.2.1"
|
|
19
27
|
},
|
|
20
28
|
"devDependencies": {
|
|
@@ -22,15 +30,14 @@
|
|
|
22
30
|
"lunte": "^1.3.0",
|
|
23
31
|
"prettier": "^3.6.2",
|
|
24
32
|
"prettier-config-holepunch": "^2.0.0",
|
|
25
|
-
"rache": "^1.0.0"
|
|
26
|
-
"test-tmp": "^1.3.0"
|
|
33
|
+
"rache": "^1.0.0"
|
|
27
34
|
},
|
|
28
35
|
"scripts": {
|
|
29
36
|
"format": "prettier --write .",
|
|
30
37
|
"test": "npm run test:node && npm run test:bare",
|
|
31
|
-
"test:bare": "brittle-bare --coverage test
|
|
38
|
+
"test:bare": "brittle-bare --coverage test/all.js",
|
|
32
39
|
"lint": "prettier --check . && lunte",
|
|
33
|
-
"test:node": "brittle-node --coverage test
|
|
40
|
+
"test:node": "brittle-node --coverage test/all.js"
|
|
34
41
|
},
|
|
35
42
|
"repository": {
|
|
36
43
|
"type": "git",
|