3
3
// SPDX-License-Identifier: LGPL-3.0-only
4
4
5
5
const { promisify : p } = require ( 'util' )
6
- const { fromMessageSigil } = require ( 'ssb-uri2' )
6
+ const { fromMessageSigil, toMessageSigil } = require ( 'ssb-uri2' )
7
7
const pull = require ( 'pull-stream' )
8
8
const pullDefer = require ( 'pull-defer' )
9
9
const pullFlatMerge = require ( 'pull-flat-merge' )
@@ -12,7 +12,15 @@ const OverwriteFields = require('@tangle/overwrite-fields')
12
12
const clarify = require ( 'clarify-error' )
13
13
const Butt64 = require ( 'butt64' )
14
14
const isCanonicalBase64 = require ( 'is-canonical-base64' )
15
- const { where, and, type, live, toPullStream } = require ( 'ssb-db2/operators' )
15
+ const {
16
+ where,
17
+ and,
18
+ type,
19
+ live,
20
+ key,
21
+ isDecrypted,
22
+ toPullStream,
23
+ } = require ( 'ssb-db2/operators' )
16
24
const {
17
25
validator : {
18
26
group : {
@@ -28,6 +36,7 @@ const isSubsetOf = require('set.prototype.issubsetof')
28
36
29
37
const { groupRecp } = require ( './operators' )
30
38
const getTangleUpdates = require ( './tangles/get-tangle-updates' )
39
+ const pullMany = require ( 'pull-many' )
31
40
32
41
const msgPattern = toPattern ( new Butt64 ( 'ssb:message/[a-zA-Z0-9-]+/' , null , 32 ) )
33
42
const feedPattern = toPattern ( new Butt64 ( 'ssb:feed/[a-zA-Z0-9-]+/' , null , 32 ) )
@@ -268,14 +277,16 @@ function Epochs(ssb) {
268
277
// then skip all the preferrentEpochs until we get up to the current
269
278
// This is important for listMembers to not send confusing results
270
279
getPreferredEpoch ( groupId , ( err , preferredEpoch ) => {
271
- if ( err ) return deferredSource . abort ( clarify ( err , 'failed to get initial preferred epoch' ) )
272
-
280
+ // if we're live and this fails we don't really mind, just go straight to live
273
281
if ( ! live ) {
274
- deferredSource . resolve ( pull . once ( preferredEpoch ) )
282
+ if ( err ) deferredSource . abort ( clarify ( err , 'failed to get initial preferred epoch' ) )
283
+ else deferredSource . resolve ( pull . once ( preferredEpoch ) )
284
+
275
285
return
276
286
}
277
287
278
- var sync = false
288
+ // if we couldn't get current preferred, we'll just go live
289
+ var sync = ! ! err
279
290
const source = pull (
280
291
epochsReduce . stream ( groupId , { getters : allGetters , live } ) ,
281
292
pull . asyncMap ( buildPreferredEpoch ) ,
@@ -509,24 +520,58 @@ function epochNodeStream(ssb, groupId, opts = {}) {
509
520
510
521
return deferredSource
511
522
}
512
- function getGroupInit ( ssb , groupId , cb ) {
513
- ssb . box2 . getGroupInfo ( groupId , ( err , info ) => {
514
- // prettier-ignore
515
- if ( err ) return cb ( clarify ( err , 'Failed to get group info for ' + groupId ) )
516
- if ( ! info ) return cb ( new Error ( 'Unknown group' ) )
517
523
518
- // Fetch the tangle root
519
- ssb . db . get ( info . root , ( err , rootVal ) => {
520
- // prettier-ignore
521
- if ( err ) return cb ( clarify ( err , 'Failed to load group root with id ' + info . root ) )
524
+ function getRootVal ( ssb , msgId , cb ) {
525
+ pull (
526
+ pullMany ( [
527
+ ssb . db . query (
528
+ where ( and ( isDecrypted ( 'box2' ) , key ( toMessageSigil ( msgId ) ) ) ) ,
529
+ live ( { old : true } ) ,
530
+ toPullStream ( )
531
+ ) ,
532
+ pull (
533
+ ssb . db . reindexed ( ) ,
534
+ pull . filter ( ( msg ) => fromMessageSigil ( msg . key ) === msgId )
535
+ ) ,
536
+ ] ) ,
537
+ pull . take ( 1 ) ,
538
+ pull . drain (
539
+ ( msg ) => cb ( null , msg . value ) ,
540
+ ( err ) => {
541
+ if ( err ) cb ( Error ( 'Failed getting root msg async' , { cause : err } ) )
542
+ }
543
+ )
544
+ )
545
+ }
522
546
523
- if ( ! isInitRoot ( rootVal ) )
547
+ function getGroupInit ( ssb , groupId , cb ) {
548
+ pull (
549
+ ssb . box2 . getGroupInfoUpdates ( groupId ) ,
550
+ pull . take ( 1 ) ,
551
+ pull . drain (
552
+ ( info ) => {
553
+ if ( ! info ) return cb ( new Error ( 'Unknown group' ) )
554
+
555
+ // Fetch the tangle root
556
+ // This is based on a live stream since sometimes the group info comes in very quick, before the root msg has had time to get put into the db
557
+ // and sometimes it might take ages (we haven't gotten that feed yet)
558
+ getRootVal ( ssb , info . root , ( err , rootVal ) => {
559
+ // prettier-ignore
560
+ if ( err ) return cb ( clarify ( err , 'Failed to load group root with id ' + info . root ) )
561
+
562
+ if ( ! isInitRoot ( rootVal ) )
563
+ // prettier-ignore
564
+ return cb ( clarify ( new Error ( isInitRoot . string ) , 'Malformed group/init root message' ) )
565
+
566
+ cb ( null , { key : info . root , value : rootVal } )
567
+ } )
568
+ } ,
569
+ ( err ) => {
524
570
// prettier-ignore
525
- return cb ( clarify ( new Error ( isInitRoot . string ) , 'Malformed group/init root message' ) )
526
-
527
- cb ( null , { key : info . root , value : rootVal } )
528
- } )
529
- } )
571
+ if ( err ) return cb ( clarify ( err , 'Failed to get group info for ' + groupId ) )
572
+ }
573
+ )
574
+ )
530
575
}
531
576
532
577
/* HELPERS */
0 commit comments