diff --git a/README.md b/README.md index 91aef71..ab8ac5c 100644 --- a/README.md +++ b/README.md @@ -70,49 +70,35 @@ ssbSingleton.setup("/.ssb-example", config, extraModules) ## API -The `SSB` object one gets from the [`singleton`](#ssb-singleton) has -the following: +The `SSB` object one gets from the [`singleton`](#ssb-singleton) is a +[secret-stack] with some extra plugins loadings by default. A few +helper functions are included under helpers: -### db +### connectAndRemember(addr, data) -This is the [ssb-db2] module. - -### net - -This is the [secret-stack] module with a few extra modules -loaded. - -#### id - -The public key of the current user - -#### rpc:connect event +Will connect and store as to automatically reconnect on +reload. Options are as described in [ssb-conn]. -Example: +### getPeer() -``` -SSB.net.on('rpc:connect', (rpc) => { - console.log("connected") - rpc.on('closed', () => console.log("bye")) -}) -``` +Gets one of the connected peers that is not a room server. -#### connectAndRemember(addr, data) +### getGraphForFeed(feed, cb) -Will connect and store as to automatically reconnect on -reload. Options are as described in [ssb-conn]. +Returns an object of: following, blocking and extended given the feed. -#### directConnect(addr, cb) +### box -Connect to addr only once. Cb is (err, rpc) +The +[box](https://github.com/ssbc/ssb-keys#boxcontent-recipients--boxed) +method from ssb-keys. Useful for private messages. -#### blobs +### blobs -This is where the `blobs` api can be found. The module implements the -blobs protocol and so can exchange blobs with connection peers. It +The blobs module is a little special compared to default ssb-blobs. It also contains with the the following extra methods: -##### hash(data, cb) +#### hash(data, cb) Hashes data and returns the digest or err @@ -128,24 +114,24 @@ onFileSelect: function(ev) { } ``` -##### add(blobId, file, cb) +#### add(blobId, file, cb) Adds the `file` (such as one obtained from ev.target.files when using a file select) to the blob store using the blobId name. BlobId is & + hash. -##### remoteURL(blobId) +#### remoteURL(blobId) Returns a http URL string for the current connection. This is useful in a browser for images that you don't want to store directly on the device. -##### privateGet(blobId, unbox, cb) +#### privateGet(blobId, unbox, cb) Callback with err or a url that works for e.g images that was received in a private message. -##### localGet(blobId, unbox, cb) +#### localGet(blobId, unbox, cb) If blob already exists will callback with err or a url that can be used for images for a blob. Otherwise the blob will get requested and @@ -153,39 +139,6 @@ if size is smaller than the maximum size, the blob will be stored locally and used for callback, otherwise the callback will return a `remoteURL` link. -#### ooo - -The [ssb-ooo] module - -#### Browser specific methods on net - -*** Warning: This will be removed in the future *** - -For partial replication a special plugin has been created and -implemented in browser core, other clients such as a pub needs to have -the [ssb-partial-replication] plugin installed. - -Once a rpc connection has been established, a few extra methods are -available under SSB.net.partialReplication. See plugin for -documentation. - -### dir - -The path to where the database and blobs are stored. - -### getPeer() - -Gets one of the connected peers that is not a room server. - -### getGraphForFeed(feed, cb) - -Returns an object of: following, blocking and extended given the feed. - -### box - -[box](https://github.com/ssbc/ssb-keys#boxcontent-recipients--boxed) -method from ssb-keys. Useful for private messages. - ## SSB Singleton Several of the libraries we use (such as db2 and diff --git a/core-helpers.js b/core-helpers.js index 3414ade..78411de 100644 --- a/core-helpers.js +++ b/core-helpers.js @@ -4,13 +4,18 @@ const pull = require('pull-stream') const raf = require('polyraf') const path = require('path') -exports.getPeer = function() -{ - let connPeers = Array.from(SSB.net.conn.hub().entries()) +exports.connectAndRemember = function (addr, data) { + SSB.conn.connect(addr, data, (err, rpc) => { + SSB.conn.remember(addr, Object.assign(data, { autoconnect: true })) + }) +} + +exports.getPeer = function() { + let connPeers = Array.from(SSB.conn.hub().entries()) connPeers = connPeers.filter(([, x]) => !!x.key).map(([address, data]) => ({ address, data })) var goodPeer = connPeers.find(cp => cp.data.type != 'room') - let peers = Object.values(SSB.net.peers).flat() + let peers = Object.values(SSB.peers).flat() if (goodPeer) return peers.find(p => p.id == goodPeer.data.key) else if (peers.length > 0) return peers[0] @@ -18,8 +23,7 @@ exports.getPeer = function() } function deleteDatabaseFile(filename) { - const path = require('path') - const file = raf(path.join(SSB.dir, filename)) + const file = raf(path.join(SSB.config.path, filename)) file.open((err, done) => { if (err) return console.error(err) file.destroy() @@ -79,7 +83,7 @@ exports.convertHopsIntoGraph = function(hops) { const feed = feeds[i] if (hops[feed] == 1) following.push(feed) - else if (hops[feed] > 0 && hops[feed] <= SSB.net.config.friends.hops) + else if (hops[feed] > 0 && hops[feed] <= SSB.config.friends.hops) extended.push(feed) else if (hops[feed] == -1) blocking.push(feed) @@ -89,8 +93,8 @@ exports.convertHopsIntoGraph = function(hops) { } exports.getGraphForFeed = function(feedId, cb) { - SSB.net.friends.hops({ start: feedId }, (err, hops) => { + SSB.friends.hops({ start: feedId }, (err, hops) => { if (err) return cb(err) - else cb(null, exports.convertHopsIntoGraph(hops, feedId == SSB.net.id)) + else cb(null, exports.convertHopsIntoGraph(hops, feedId == SSB.id)) }) } diff --git a/core.js b/core.js index 22e7a7d..010d2ee 100644 --- a/core.js +++ b/core.js @@ -1,47 +1,38 @@ exports.init = function (dir, config, extraModules) { const EventEmitter = require('events') - SSB = { - events: new EventEmitter(), - dbOperators: require('ssb-db2/operators') - } - SSB.dbOperators.mentions = require('ssb-db2/operators/full-mentions') + SSBLOADER = new EventEmitter() + // init secret stack const s = require('sodium-browserify') - s.events.on('sodium-browserify:wasm loaded', function() { - + s.events.on('sodium-browserify:wasm loaded', () => { console.log("wasm loaded") - var net = require('./net').init(dir, config, extraModules) - - console.log("my id: ", net.id) + SSB = require('./net').init(dir, config, extraModules) + console.log("my id: ", SSB.id) - var helpers = require('./core-helpers') + const helpers = require('./core-helpers') - SSB = Object.assign(SSB, { - db: net.db, - net, - dir, + SSB.helpers = { + box: require('ssb-keys').box, + connectAndRemember: helpers.connectAndRemember, getPeer: helpers.getPeer, - - removeDB: helpers.removeDB, - removeIndexes: helpers.removeIndexes, - removeBlobs: helpers.removeBlobs, - convertHopsIntoGraph: helpers.convertHopsIntoGraph, getGraphForFeed: helpers.getGraphForFeed, - box: require('ssb-keys').box - }) + removeDB: helpers.removeDB, + removeIndexes: helpers.removeIndexes, + removeBlobs: helpers.removeBlobs + } // delay startup a bit const startOffline = config && config.core && config.core.startOffline if (!startOffline) { setTimeout(() => { - SSB.net.conn.start() + SSB.conn.start() }, 2500) } - SSB.events.emit("SSB: loaded") + SSBLOADER.emit("ready") }) } diff --git a/feed-replication.js b/feed-replication.js deleted file mode 100644 index 9ce5f03..0000000 --- a/feed-replication.js +++ /dev/null @@ -1,277 +0,0 @@ -const pull = require('pull-stream') -const validate = require('ssb-validate') -const FastPriorityQueue = require('fastpriorityqueue') -const Partial = require('./partial') - -exports.name = 'feedReplication' -exports.version = '1.0.0' -exports.manifest = { - request: 'sync', - updatePartialState: 'async', - partialStatus: 'sync', - inSync: 'sync' -} -exports.permissions = { - anonymous: {allow: []} -} - -exports.init = function (sbot, config) { - console.log("loading feed replication!") - - const partial = Partial(config.path) - - let partialState = null - - partial.get((err, state) => { - partialState = state - - runQueue() - }) - - function syncMessages(feed, key, rpcCall, cb) { - if (!partialState[feed] || !partialState[feed][key]) { - pull( - rpcCall(), - pull.collect((err, msgs) => { - if (err) { - console.error(err.message) - return cb(err) - } - - if (key === 'syncedMessages') { - const lastMsgValue = msgs[msgs.length - 1] - msgs = msgs.filter(m => m.content.type !== 'contact' && - m.content.type !== 'about') - const kvt = validate.toKeyValueTimestamp(lastMsgValue) - sbot.db.setPost(kvt) - } - - sbot.db.addOOOBatch(msgs, (err) => { - if (err) return cb(err) - var newState = {} - newState[key] = true - partial.updateState(feed, newState, (err) => { cb(err, feed) }) - }) - }) - ) - } else - cb(null, feed) - } - - let synced = {} - - function getLatestSequence(feed, cb) { - sbot.db.getLatest(feed, (err, latest) => { - if (err) return cb(err) - - cb(null, latest ? latest.sequence + 1 : 0) - }) - } - - function syncFeed(rpc, feed, hops, cb) { - // idempotent - if (synced[feed]) return cb() - - synced[feed] = 1 - - if (hops === 0) { - cb() // move along selfie - } else if (hops === 1) { - if (!partialState[feed] || !partialState[feed]['full']) { - console.log("full replication of", feed) - getLatestSequence(feed, (err, latestSeq) => { - pull( - rpc.partialReplication.getFeed({ id: feed, seq: latestSeq, keys: false }), - pull.collect((err, messages) => { - if (err) return cb(err) - - sbot.db.addBatch(messages, () => { - waitingEBTRequests.set(feed, true) - partial.updateState(feed, { full: true }, cb) - }) - }) - ) - }) - } else - cb() - } else { - //console.log("partial replication of", feed) - pull( - pull.values([feed]), - pull.asyncMap((feed, cb) => { - syncMessages(feed, 'syncedProfile', - () => rpc.partialReplication.getMessagesOfType({ id: feed, type: 'about' }), cb) - }), - pull.asyncMap((feed, cb) => { - syncMessages(feed, 'syncedContacts', - () => rpc.partialReplication.getMessagesOfType({ id: feed, type: 'contact' }), cb) - }), - pull.asyncMap((feed, cb) => { - syncMessages(feed, 'syncedMessages', - () => rpc.partialReplication.getFeedReverse({ id: feed, keys: false, limit: 25 }), cb) - }), - pull.collect((err) => { - if (err) return cb(err) - - waitingEBTRequests.set(feed, true) - cb() - }) - ) - } - } - - pull( - sbot.conn.hub().listen(), - pull.filter(event => { - const okType = event.type === 'connected' || event.type === 'disconnected' - if (okType && event.details) { - let connPeers = Array.from(sbot.conn.hub().entries()) - connPeers = connPeers.filter(([, x]) => !!x.key).map(([address, data]) => ({ address, data })) - const peer = connPeers.find(x => x.data.key == event.details.rpc.id) - return peer && peer.data.type !== 'room' - } else - return false - }), - pull.drain(event => { - if (event.type === 'connected') - remotes.set(event.details.rpc, 0) - else - remotes.delete(event.details.rpc) - runQueue() - }) - ) - - // queue of { feed, hops, validFrom } - var queue = new FastPriorityQueue(function(lhs, rhs) { - return rhs.hops > lhs.hops - }) - - let currentHops = {} - - // wrapper around EBT - function request(destination, hops, replicating) { - currentHops[destination] = hops - - if (replicating) - queue.add({ feed: destination, hops, validFrom: (+new Date()) + 200 }) - else { - waitingEBTRequests.delete(destination) - queue.removeMany((e) => e.feed === destination) - sbot.ebt.request(destination, false) - } - - runQueue() - } - - let remotes = new Map() // rpc -> concurrent requests - let waitingQueue = false - let waitingEBTRequests = new Map() - - function endWaitingQueue() { - waitingQueue = false - runQueue() - } - - function runQueue() { - // prerequisites - if (queue.isEmpty()) { - //console.log(new Date()) - - sbot.db.onDrain('ebt', () => { - for (let feed of waitingEBTRequests.keys()) - sbot.ebt.request(feed, true) - waitingEBTRequests.clear() - }) - - return - } - if (partialState === null) return - if (remotes.size == 0) return - - let lowest = null - let concurrentRequests = 0 - for (let [rpc, concurrent] of remotes) { - if (lowest === null) - lowest = { rpc, concurrent } - else if (lowest.concurrent < concurrent) - lowest = { rpc, concurrent } - concurrentRequests += concurrent - } - - if (concurrentRequests === 7) return - - let el = queue.peek() - - if (el.validFrom < +new Date()) { - queue.poll() - - remotes.set(lowest.rpc, lowest.concurrent + 1) - syncFeed(lowest.rpc, el.feed, el.hops, () => { - remotes.set(lowest.rpc, remotes.get(lowest.rpc) - 1) - setImmediate(runQueue) // don't blow up the stack - }) - - runQueue() - } else if (!waitingQueue) { - waitingQueue = true - setTimeout(endWaitingQueue, 100) - } - } - - function updatePartialState(feed, changes, cb) { - partial.updateState(feed, changes, cb) - } - - function partialStatus() { - let partialState = partial.getSync() - let currentGraph = SSB.convertHopsIntoGraph(currentHops) - - // full - let totalFull = currentGraph.following.length - let fullSynced = 0 - - // partial - let totalPartial = currentGraph.extended.length - let profilesSynced = 0 - let contactsSynced = 0 - let messagesSynced = 0 - - for (var relation in partialState) { - const status = partialState[relation] - if (status.full) - fullSynced += 1 - - if (status.syncedProfile) - profilesSynced += 1 - if (status.syncedContacts) - contactsSynced += 1 - if (status.syncedMessages) - messagesSynced += 1 - } - - return { - totalPartial, - profilesSynced, - contactsSynced, - messagesSynced, - totalFull, - fullSynced, - } - } - - function getGraph() { - return SSB.convertHopsIntoGraph(currentHops) - } - - function inSync() { - return queue.isEmpty() - } - - return { - request, - updatePartialState, - partialStatus, - inSync, - getGraph - } -} diff --git a/net.js b/net.js index 675acf9..ce35e6d 100644 --- a/net.js +++ b/net.js @@ -12,8 +12,7 @@ exports.init = function(dir, overwriteConfig, extraModules) { caps: { shs: Buffer.from(caps.shs, 'base64') }, keys, friends: { - hops: 2, - hookReplicate: false + hops: 2 }, connections: { incoming: { @@ -50,9 +49,8 @@ exports.init = function(dir, overwriteConfig, extraModules) { .use(require('ssb-conn')) .use(require('ssb-friends')) .use(require('ssb-ebt')) - .use(require('./feed-replication')) .use(require('ssb-replication-scheduler')) - .use(require('./ssb-partial-replication')) + .use(require('./ssb-partial-replication')) // tangles .use(require('./simple-ooo')) .use(require('ssb-ws')) .use(require('ssb-room-client')) @@ -87,15 +85,5 @@ exports.init = function(dir, overwriteConfig, extraModules) { ping() }) - r.connectAndRemember = function(addr, data) { - r.conn.connect(addr, data, (err, rpc) => { - r.conn.remember(addr, Object.assign(data, { autoconnect: true })) - }) - } - - r.directConnect = function(addr, cb) { - r.conn.connect(addr, cb) - } - return r } diff --git a/package-lock.json b/package-lock.json index 9d0f2a9..15e5ae2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,38 +1,34 @@ { "name": "ssb-browser-core", - "version": "11.3.0", + "version": "12.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "11.3.0", + "version": "12.0.0", "license": "Beerware", "dependencies": { "atomic-file-rw": "^0.2.2", - "fastpriorityqueue": "^0.7.1", "gossip-query": "^2.0.2", - "obz": "^1.0.3", "polyraf": "^1.1.0", - "promisify-4loc": "^1.0.0", "pull-cont": "^0.1.1", "pull-defer": "^0.2.3", "pull-notify": "^0.1.1", - "pull-paramap": "^1.2.2", "pull-stream": "^3.6.14", "push-stream": "^11.0.0", "push-stream-to-pull-stream": "^1.0.3", "sanitize-filename": "^1.6.3", "secret-stack": "^6.3.2", "ssb-caps": "^1.1.0", - "ssb-conn": "^5.1.0", - "ssb-db2": "^2.6.5", - "ssb-ebt": "^8.0.0", - "ssb-friends": "^5.0.0", + "ssb-conn": "^6.0.0", + "ssb-db2": "^2.7.0", + "ssb-ebt": "^8.1.0", + "ssb-friends": "^5.1.0", "ssb-keys": "^8.0.2", "ssb-no-auth": "^1.0.0", "ssb-ref": "^2.14.3", - "ssb-replication-scheduler": "github:arj03/ssb-replication-scheduler", - "ssb-room-client": "^1.0.0", + "ssb-replication-scheduler": "^1.0.1", + "ssb-room-client": "^2.0.0", "ssb-sort": "^1.1.3", "ssb-validate": "^4.1.4", "ssb-ws": "^6.2.3" @@ -40,7 +36,7 @@ "devDependencies": { "browserify": "^17.0.0", "rimraf": "^3.0.2", - "tape": "^5.2.2", + "tape": "^5.3.1", "uglifyify": "^5.0.2" } }, @@ -1265,10 +1261,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1279,6 +1284,9 @@ }, "engines": { "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/gossip-query": { @@ -1309,6 +1317,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-dynamic-import": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.0.0.tgz", + "integrity": "sha512-GYPi/aZmACJVrVfEhP1rNUFmtCuK+SQ96mn8Bs7mXiGZRAJiI4VjaMmjj4uuvW8qaF085uWJvyJk9UNYUIYn0A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-network2": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/has-network2/-/has-network2-0.0.3.tgz", @@ -1325,6 +1345,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -1600,12 +1634,12 @@ "integrity": "sha512-2Xj8sA0zDrAcaoWfBiNmc6VPWAgKDpim0T3J9Djq7vbm1UjwbUWzeuLu/FwC46g3cBbAn0E5R0xwVtOobM6Xxg==" }, "node_modules/is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dependencies": { "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -1679,9 +1713,9 @@ "dev": true }, "node_modules/jitdb": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jitdb/-/jitdb-3.4.0.tgz", - "integrity": "sha512-TQUrWpifF3trL4Xk2e1DJn/Wk/FYPZE9QP+0yNzvo3KNDHlBtOYdufnH+otZh13kn1Nh0nt+ZWK8ENB2F34q8Q==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jitdb/-/jitdb-3.5.0.tgz", + "integrity": "sha512-VWaJoWOxQ9mNL+YIHJdlgNiGoADh91McAls+AjRbZeG0Ul0/0CVddVNqJpW4WLAFThqgLeFroMyZNIwqOsoUnQ==", "dependencies": { "atomic-file-rw": "^0.2.1", "binary-search-bounds": "^2.0.4", @@ -1748,6 +1782,14 @@ "node": "*" } }, + "node_modules/key-value-file-store": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/key-value-file-store/-/key-value-file-store-1.0.1.tgz", + "integrity": "sha512-XIK4dTc+X4wQjPM0j5khmyLLh7jUYCq2tV7TeUBOxAUb/9xT11tpUTAgNIlXL2sdTe1p+7Vgjtgnz9orTf9DSQ==", + "dependencies": { + "atomic-file-rw": "^0.2.2" + } + }, "node_modules/labeled-stream-splicer": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", @@ -1951,15 +1993,6 @@ "resolved": "https://registry.npmjs.org/looper/-/looper-4.0.0.tgz", "integrity": "sha1-dwat7VmpntygbmtUu4bI7BnJUVU=" }, - "node_modules/lossy-store": { - "version": "1.2.4", - "resolved": "git+ssh://git@github.com/arj03/lossy-store.git#789b4dd719b811e5adb28163e4aa9c4c055550d3", - "license": "MIT", - "dependencies": { - "atomic-file-rw": "^0.2.2", - "mkdirp": "^1.0.4" - } - }, "node_modules/ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", @@ -2222,9 +2255,12 @@ } }, "node_modules/object-inspect": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/object-is": { "version": "1.1.5", @@ -2632,9 +2668,9 @@ } }, "node_modules/pull-notify": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pull-notify/-/pull-notify-0.1.1.tgz", - "integrity": "sha1-b4b/ldJwuJw+vyVbYDG3Ay3JnMo=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/pull-notify/-/pull-notify-0.1.2.tgz", + "integrity": "sha512-oooAxYEUGNbOVsUrmqqTWWsAUMRIs4sYglnxgleiVcWyvrWgOuk/WUoZDajPTsYix2/rd+z5xSclzHLA7QygcQ==", "dependencies": { "pull-pushable": "^2.0.0" } @@ -3260,9 +3296,9 @@ "integrity": "sha512-qe3qpvchJ+gnH8M/ge4rpL+7eRbSmsEAzNwHkDdrW06OBcziQ6/KuAdmcR6joxCbNeoAXAZF+inkefgE16okXA==" }, "node_modules/ssb-conn": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ssb-conn/-/ssb-conn-5.2.0.tgz", - "integrity": "sha512-hBiM3iZ1fszbghPDYOhpvuopJ7uBZlsRPHMrms77XBBJ8VhnlEzzL+ap+dE1fTmKby26P+7yrVRpS/YNDrPyOA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ssb-conn/-/ssb-conn-6.0.0.tgz", + "integrity": "sha512-RqtKM9NsF/nUjTcoT/Ir+J+UpU+0fjapbux6xXob2Ff58jg7GxrjmfKRbZGZ1D3cz+olFxP3wiAtMaloGYs4Mg==", "dependencies": { "debug": "^4.3.1", "has-network2": ">=0.0.3", @@ -3338,9 +3374,9 @@ } }, "node_modules/ssb-db2": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/ssb-db2/-/ssb-db2-2.6.6.tgz", - "integrity": "sha512-c6cNjhrsKJ/WdKO/t0FTdlR7ee+j/cNN5iPqatk8mGXx+pdWE/9Ft1IbVhgS3TTp3z7ZrhAk3eoWgI3M+roY+A==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/ssb-db2/-/ssb-db2-2.7.0.tgz", + "integrity": "sha512-uC9PfvwISpR4VUDs4vUaR0GdhAsYRlay4pEYf501hmI9XUPcga6jtp7I+JgS5B1ZA5WDshC0uQjgBr67hHmwEA==", "dependencies": { "async-append-only-log": "^3.1.0", "atomic-file-rw": "^0.2.1", @@ -3351,12 +3387,13 @@ "flumecodec": "0.0.1", "flumelog-offset": "3.4.4", "hoox": "0.0.1", - "jitdb": "^3.4.0", + "jitdb": "^3.5.0", "level": "^6.0.1", "level-codec": "^9.0.2", "lodash.debounce": "^4.0.8", "mkdirp": "^1.0.4", "multicb": "1.2.2", + "mutexify": "^1.3.1", "obz": "^1.0.3", "p-defer": "^3.0.0", "promisify-4loc": "1.0.0", @@ -3414,13 +3451,13 @@ } }, "node_modules/ssb-ebt": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssb-ebt/-/ssb-ebt-8.0.1.tgz", - "integrity": "sha512-IoA4AZvnnvcjkmLZvhv9+x0K9ngsNhpYBD8iq0ghkRD/tbHbsvhwWhG49P9qV9lG1guWqrFgdFykyMn2uhNN3w==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ssb-ebt/-/ssb-ebt-8.1.0.tgz", + "integrity": "sha512-/pukYxf0Hnp5Xtxz9IqNBZMRX4Hh7dEBqT9F4y9iYc1zU4zoSx9r8G1pklXzRNgzHsQRoJlTxfCr9UScnGnuTg==", "dependencies": { "base64-url": "^2.2.0", "epidemic-broadcast-trees": "^9.0.0", - "lossy-store": "^1.2.3", + "key-value-file-store": "^1.0.0", "promisify-4loc": "^1.0.0", "pull-defer": "^0.2.3", "pull-stream": "^3.6.0", @@ -3436,9 +3473,9 @@ } }, "node_modules/ssb-friends": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ssb-friends/-/ssb-friends-5.0.0.tgz", - "integrity": "sha512-ZZVk0LPOBUh8TaIBLXVioC8BWyJqxhxUmJ2gQQVmbmYGtqALzTD92SD+AKFFqEkH+jbtq4xmAywnReF9WDy/QA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ssb-friends/-/ssb-friends-5.1.0.tgz", + "integrity": "sha512-N+1Ohh93KB4pA/7hGYG2rlcISa/DMFS2/vO7arwNd4+oCmRmDBvNG15HekFrAlXUcPBEhSuPCy5hEPmw76lZPQ==", "dependencies": { "bipf": "^1.5.1", "flumecodec": "0.0.1", @@ -3506,9 +3543,9 @@ } }, "node_modules/ssb-replication-scheduler": { - "version": "1.0.0", - "resolved": "git+ssh://git@github.com/arj03/ssb-replication-scheduler.git#d381105d12f24198483aecf239639ac8b5993dc4", - "license": "LGPL-3.0", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ssb-replication-scheduler/-/ssb-replication-scheduler-1.0.1.tgz", + "integrity": "sha512-hkYAEK4oZ6w/GdBuctQjg2qNAVrAyYX5qTNpqbEVe6VxHphxMoeT0JuAPoJ8BHVoxhNNLK0uRoVxsTIyuOYooQ==", "dependencies": { "pull-stream": "^3.6.0" }, @@ -3517,14 +3554,15 @@ } }, "node_modules/ssb-room-client": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ssb-room-client/-/ssb-room-client-1.0.0.tgz", - "integrity": "sha512-0rX2uDcgn8gGj5kn7Vo6FT0kSHcznF8XyPQpamLqyS9epj9JcQtsVghP70xrXlaGrVheS1j7oHIbq9rqCrIEEA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ssb-room-client/-/ssb-room-client-2.0.0.tgz", + "integrity": "sha512-HX3JLpMizcPJMlcu0BSlIjLyu87kJDUfjGgl3YgviqH9d7A28bOtR/n2Jl9+wS9tb5m4OeyjQBQ2fO99dPRWjQ==", "dependencies": { "@minireq/browser": "^2.0.0", "@minireq/node": "^2.0.0", "debug": "^4.3.2", "promisify-tuple": "^1.2.0", + "pull-notify": "^0.1.2", "pull-pair": "^1.1.0", "pull-stream": "^3.6.14", "ssb-conn-db": ">=0.2.0", @@ -3783,9 +3821,9 @@ } }, "node_modules/tape": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/tape/-/tape-5.2.2.tgz", - "integrity": "sha512-grXrzPC1ly2kyTMKdqxh5GiLpb0BpNctCuecTB0psHX4Gu0nc+uxWR4xKjTh/4CfQlH4zhvTM2/EXmHXp6v/uA==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-5.3.1.tgz", + "integrity": "sha512-Mj3h+/dgfI2xct4kTpzqZaRxhhglXcMg//xGTbB0AQisfiOYa6ZBNQIgv46xi1MqbgthuNLSS1SAySDZsb7MMA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", @@ -3793,12 +3831,14 @@ "defined": "^1.0.0", "dotignore": "^0.1.2", "for-each": "^0.3.3", - "glob": "^7.1.6", + "get-package-type": "^0.1.0", + "glob": "^7.1.7", "has": "^1.0.3", + "has-dynamic-import": "^2.0.0", "inherits": "^2.0.4", - "is-regex": "^1.1.2", + "is-regex": "^1.1.4", "minimist": "^1.2.5", - "object-inspect": "^1.9.0", + "object-inspect": "^1.11.0", "object-is": "^1.1.5", "object.assign": "^4.1.2", "resolve": "^2.0.0-next.3", @@ -5312,10 +5352,16 @@ "has-symbols": "^1.0.1" } }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5347,6 +5393,15 @@ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" }, + "has-dynamic-import": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.0.0.tgz", + "integrity": "sha512-GYPi/aZmACJVrVfEhP1rNUFmtCuK+SQ96mn8Bs7mXiGZRAJiI4VjaMmjj4uuvW8qaF085uWJvyJk9UNYUIYn0A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "has-network2": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/has-network2/-/has-network2-0.0.3.tgz", @@ -5357,6 +5412,14 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -5597,12 +5660,12 @@ "integrity": "sha512-2Xj8sA0zDrAcaoWfBiNmc6VPWAgKDpim0T3J9Djq7vbm1UjwbUWzeuLu/FwC46g3cBbAn0E5R0xwVtOobM6Xxg==" }, "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "requires": { "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" + "has-tostringtag": "^1.0.0" } }, "is-set": { @@ -5661,9 +5724,9 @@ "dev": true }, "jitdb": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jitdb/-/jitdb-3.4.0.tgz", - "integrity": "sha512-TQUrWpifF3trL4Xk2e1DJn/Wk/FYPZE9QP+0yNzvo3KNDHlBtOYdufnH+otZh13kn1Nh0nt+ZWK8ENB2F34q8Q==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/jitdb/-/jitdb-3.5.0.tgz", + "integrity": "sha512-VWaJoWOxQ9mNL+YIHJdlgNiGoADh91McAls+AjRbZeG0Ul0/0CVddVNqJpW4WLAFThqgLeFroMyZNIwqOsoUnQ==", "requires": { "atomic-file-rw": "^0.2.1", "binary-search-bounds": "^2.0.4", @@ -5715,6 +5778,14 @@ "through": ">=2.2.7 <3" } }, + "key-value-file-store": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/key-value-file-store/-/key-value-file-store-1.0.1.tgz", + "integrity": "sha512-XIK4dTc+X4wQjPM0j5khmyLLh7jUYCq2tV7TeUBOxAUb/9xT11tpUTAgNIlXL2sdTe1p+7Vgjtgnz9orTf9DSQ==", + "requires": { + "atomic-file-rw": "^0.2.2" + } + }, "labeled-stream-splicer": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", @@ -5891,14 +5962,6 @@ "resolved": "https://registry.npmjs.org/looper/-/looper-4.0.0.tgz", "integrity": "sha1-dwat7VmpntygbmtUu4bI7BnJUVU=" }, - "lossy-store": { - "version": "git+ssh://git@github.com/arj03/lossy-store.git#789b4dd719b811e5adb28163e4aa9c4c055550d3", - "from": "lossy-store@^1.2.3", - "requires": { - "atomic-file-rw": "^0.2.2", - "mkdirp": "^1.0.4" - } - }, "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", @@ -6128,9 +6191,9 @@ "dev": true }, "object-inspect": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" }, "object-is": { "version": "1.1.5", @@ -6502,9 +6565,9 @@ } }, "pull-notify": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pull-notify/-/pull-notify-0.1.1.tgz", - "integrity": "sha1-b4b/ldJwuJw+vyVbYDG3Ay3JnMo=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/pull-notify/-/pull-notify-0.1.2.tgz", + "integrity": "sha512-oooAxYEUGNbOVsUrmqqTWWsAUMRIs4sYglnxgleiVcWyvrWgOuk/WUoZDajPTsYix2/rd+z5xSclzHLA7QygcQ==", "requires": { "pull-pushable": "^2.0.0" } @@ -7100,9 +7163,9 @@ "integrity": "sha512-qe3qpvchJ+gnH8M/ge4rpL+7eRbSmsEAzNwHkDdrW06OBcziQ6/KuAdmcR6joxCbNeoAXAZF+inkefgE16okXA==" }, "ssb-conn": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ssb-conn/-/ssb-conn-5.2.0.tgz", - "integrity": "sha512-hBiM3iZ1fszbghPDYOhpvuopJ7uBZlsRPHMrms77XBBJ8VhnlEzzL+ap+dE1fTmKby26P+7yrVRpS/YNDrPyOA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ssb-conn/-/ssb-conn-6.0.0.tgz", + "integrity": "sha512-RqtKM9NsF/nUjTcoT/Ir+J+UpU+0fjapbux6xXob2Ff58jg7GxrjmfKRbZGZ1D3cz+olFxP3wiAtMaloGYs4Mg==", "requires": { "debug": "^4.3.1", "has-network2": ">=0.0.3", @@ -7175,9 +7238,9 @@ } }, "ssb-db2": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/ssb-db2/-/ssb-db2-2.6.6.tgz", - "integrity": "sha512-c6cNjhrsKJ/WdKO/t0FTdlR7ee+j/cNN5iPqatk8mGXx+pdWE/9Ft1IbVhgS3TTp3z7ZrhAk3eoWgI3M+roY+A==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/ssb-db2/-/ssb-db2-2.7.0.tgz", + "integrity": "sha512-uC9PfvwISpR4VUDs4vUaR0GdhAsYRlay4pEYf501hmI9XUPcga6jtp7I+JgS5B1ZA5WDshC0uQjgBr67hHmwEA==", "requires": { "async-append-only-log": "^3.1.0", "atomic-file-rw": "^0.2.1", @@ -7188,12 +7251,13 @@ "flumecodec": "0.0.1", "flumelog-offset": "3.4.4", "hoox": "0.0.1", - "jitdb": "^3.4.0", + "jitdb": "^3.5.0", "level": "^6.0.1", "level-codec": "^9.0.2", "lodash.debounce": "^4.0.8", "mkdirp": "^1.0.4", "multicb": "1.2.2", + "mutexify": "^1.3.1", "obz": "^1.0.3", "p-defer": "^3.0.0", "promisify-4loc": "1.0.0", @@ -7236,13 +7300,13 @@ } }, "ssb-ebt": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssb-ebt/-/ssb-ebt-8.0.1.tgz", - "integrity": "sha512-IoA4AZvnnvcjkmLZvhv9+x0K9ngsNhpYBD8iq0ghkRD/tbHbsvhwWhG49P9qV9lG1guWqrFgdFykyMn2uhNN3w==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ssb-ebt/-/ssb-ebt-8.1.0.tgz", + "integrity": "sha512-/pukYxf0Hnp5Xtxz9IqNBZMRX4Hh7dEBqT9F4y9iYc1zU4zoSx9r8G1pklXzRNgzHsQRoJlTxfCr9UScnGnuTg==", "requires": { "base64-url": "^2.2.0", "epidemic-broadcast-trees": "^9.0.0", - "lossy-store": "^1.2.3", + "key-value-file-store": "^1.0.0", "promisify-4loc": "^1.0.0", "pull-defer": "^0.2.3", "pull-stream": "^3.6.0", @@ -7255,9 +7319,9 @@ } }, "ssb-friends": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ssb-friends/-/ssb-friends-5.0.0.tgz", - "integrity": "sha512-ZZVk0LPOBUh8TaIBLXVioC8BWyJqxhxUmJ2gQQVmbmYGtqALzTD92SD+AKFFqEkH+jbtq4xmAywnReF9WDy/QA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ssb-friends/-/ssb-friends-5.1.0.tgz", + "integrity": "sha512-N+1Ohh93KB4pA/7hGYG2rlcISa/DMFS2/vO7arwNd4+oCmRmDBvNG15HekFrAlXUcPBEhSuPCy5hEPmw76lZPQ==", "requires": { "bipf": "^1.5.1", "flumecodec": "0.0.1", @@ -7318,21 +7382,23 @@ } }, "ssb-replication-scheduler": { - "version": "git+ssh://git@github.com/arj03/ssb-replication-scheduler.git#d381105d12f24198483aecf239639ac8b5993dc4", - "from": "ssb-replication-scheduler@github:arj03/ssb-replication-scheduler", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ssb-replication-scheduler/-/ssb-replication-scheduler-1.0.1.tgz", + "integrity": "sha512-hkYAEK4oZ6w/GdBuctQjg2qNAVrAyYX5qTNpqbEVe6VxHphxMoeT0JuAPoJ8BHVoxhNNLK0uRoVxsTIyuOYooQ==", "requires": { "pull-stream": "^3.6.0" } }, "ssb-room-client": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ssb-room-client/-/ssb-room-client-1.0.0.tgz", - "integrity": "sha512-0rX2uDcgn8gGj5kn7Vo6FT0kSHcznF8XyPQpamLqyS9epj9JcQtsVghP70xrXlaGrVheS1j7oHIbq9rqCrIEEA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ssb-room-client/-/ssb-room-client-2.0.0.tgz", + "integrity": "sha512-HX3JLpMizcPJMlcu0BSlIjLyu87kJDUfjGgl3YgviqH9d7A28bOtR/n2Jl9+wS9tb5m4OeyjQBQ2fO99dPRWjQ==", "requires": { "@minireq/browser": "^2.0.0", "@minireq/node": "^2.0.0", "debug": "^4.3.2", "promisify-tuple": "^1.2.0", + "pull-notify": "^0.1.2", "pull-pair": "^1.1.0", "pull-stream": "^3.6.14", "ssb-conn-db": ">=0.2.0", @@ -7574,9 +7640,9 @@ } }, "tape": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/tape/-/tape-5.2.2.tgz", - "integrity": "sha512-grXrzPC1ly2kyTMKdqxh5GiLpb0BpNctCuecTB0psHX4Gu0nc+uxWR4xKjTh/4CfQlH4zhvTM2/EXmHXp6v/uA==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-5.3.1.tgz", + "integrity": "sha512-Mj3h+/dgfI2xct4kTpzqZaRxhhglXcMg//xGTbB0AQisfiOYa6ZBNQIgv46xi1MqbgthuNLSS1SAySDZsb7MMA==", "dev": true, "requires": { "call-bind": "^1.0.2", @@ -7584,12 +7650,14 @@ "defined": "^1.0.0", "dotignore": "^0.1.2", "for-each": "^0.3.3", - "glob": "^7.1.6", + "get-package-type": "^0.1.0", + "glob": "^7.1.7", "has": "^1.0.3", + "has-dynamic-import": "^2.0.0", "inherits": "^2.0.4", - "is-regex": "^1.1.2", + "is-regex": "^1.1.4", "minimist": "^1.2.5", - "object-inspect": "^1.9.0", + "object-inspect": "^1.11.0", "object-is": "^1.1.5", "object.assign": "^4.1.2", "resolve": "^2.0.0-next.3", diff --git a/package.json b/package.json index 7f8c0ec..a2be938 100644 --- a/package.json +++ b/package.json @@ -9,30 +9,26 @@ }, "dependencies": { "atomic-file-rw": "^0.2.2", - "fastpriorityqueue": "^0.7.1", "gossip-query": "^2.0.2", - "obz": "^1.0.3", "polyraf": "^1.1.0", - "promisify-4loc": "^1.0.0", "pull-cont": "^0.1.1", "pull-defer": "^0.2.3", "pull-notify": "^0.1.1", - "pull-paramap": "^1.2.2", "pull-stream": "^3.6.14", "push-stream": "^11.0.0", "push-stream-to-pull-stream": "^1.0.3", "sanitize-filename": "^1.6.3", "secret-stack": "^6.3.2", "ssb-caps": "^1.1.0", - "ssb-conn": "^5.1.0", - "ssb-db2": "^2.6.5", - "ssb-ebt": "^8.0.0", - "ssb-friends": "^5.0.0", + "ssb-conn": "^6.0.0", + "ssb-db2": "^2.7.0", + "ssb-ebt": "^8.1.0", + "ssb-friends": "^5.1.0", "ssb-keys": "^8.0.2", "ssb-no-auth": "^1.0.0", "ssb-ref": "^2.14.3", - "ssb-replication-scheduler": "github:arj03/ssb-replication-scheduler", - "ssb-room-client": "^1.0.0", + "ssb-replication-scheduler": "^1.0.1", + "ssb-room-client": "^2.0.0", "ssb-sort": "^1.1.3", "ssb-validate": "^4.1.4", "ssb-ws": "^6.2.3" @@ -40,7 +36,7 @@ "devDependencies": { "browserify": "^17.0.0", "rimraf": "^3.0.2", - "tape": "^5.2.2", + "tape": "^5.3.1", "uglifyify": "^5.0.2" }, "scripts": { diff --git a/scripts/full-sync.js b/scripts/full-sync.js index df87938..3d6d28c 100644 --- a/scripts/full-sync.js +++ b/scripts/full-sync.js @@ -11,7 +11,7 @@ fs.copyFileSync("scripts/secret", dir + "/secret") require('../core.js').init(dir) -SSB.events.on('SSB: loaded', function() { +SSBLOADER.on('ready', function() { process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0 // wtf // var remoteAddress = 'wss://between-two-worlds.dk:8990~noauth:lbocEWqF2Fg6WMYLgmfYvqJlMfL7hiqVAV6ANjHWNw8=' @@ -23,7 +23,7 @@ SSB.events.on('SSB: loaded', function() { console.log(new Date()) //SSB.net.id = '@VIOn+8a/vaQvv/Ew3+KriCngyUXHxHbjXkj4GafBAY0=.ed25519' - SSB.net.conn.connect(remoteAddress, (err, rpc) => { + SSB.conn.connect(remoteAddress, (err, rpc) => { console.time("downloading main profile") if (err) console.error(err) @@ -33,7 +33,6 @@ SSB.events.on('SSB: loaded', function() { function updateDB() { setTimeout(() => { console.log("db", SSB.db.getStatus().value) - console.log("replication", SSB.net.feedReplication.partialStatus()) updateDB() //console.log("feed", SSB.feedSyncer.status()) }, 5 * 1000) diff --git a/simple-blobs.js b/simple-blobs.js index 2b4cfcb..3095d60 100644 --- a/simple-blobs.js +++ b/simple-blobs.js @@ -172,7 +172,7 @@ exports.init = function (sbot, config) { function remoteURL(id) { if (!id) return "" - const peer = SSB.getPeer() + const peer = SSB.helpers.getPeer() if (!peer) return '' let remoteAddress = peer.stream.address diff --git a/ssb-partial-replication.js b/ssb-partial-replication.js index e36d379..be56b18 100644 --- a/ssb-partial-replication.js +++ b/ssb-partial-replication.js @@ -14,10 +14,7 @@ const { } = require('ssb-db2/operators') exports.manifest = { - getFeed: 'source', - getFeedReverse: 'source', - getTangle: 'async', - getMessagesOfType: 'source' + getTangle: 'async' } exports.permissions = { anonymous: {allow: Object.keys(exports.manifest)} @@ -27,33 +24,6 @@ exports.name = 'partial-replication' exports.init = function (sbot, config) { return { - getFeed: function (opts) { - return pull( - sbot.createHistoryStream(opts) - ) - }, - - getFeedReverse: function (opts) { - return pull( - pullCont(function(cb) { - SSB.db.getLatest(opts.id, (err, latest) => { - if (err) { - console.error("Got error on feed reverse", err) - return cb(null, pull.empty()) - } - - var seqStart = latest ? latest.sequence - (opts.limit - 1) : 0 - if (seqStart < 0) - seqStart = 0 - - opts.seq = seqStart - - cb(null, sbot.createHistoryStream(opts)) - }) - }) - ) - }, - getTangle: function(msgId, cb) { if (!msgId) return cb("msg not found:" + msgId) @@ -69,37 +39,6 @@ exports.init = function (sbot, config) { }) ) }) - }, - - // opts: { id: feedId, type: string, seq: int?, limit: int? } - getMessagesOfType: function(opts) - { - if (!opts.id) throw new Error("id is required!") - if (!opts.type) throw new Error("type is required!") - - const seq = opts.sequence || opts.seq || 0 - const limit = opts.limit || 1e10 - - return pull( - pullCont(function(cb) { - let q = SSB.db.query( - where(and(author(opts.id), type(opts.type))) - ) - - if (seq) // sequences starts with 1, offset starts with 0 ;-) - q = SSB.db.query(q, (startFrom(seq-1))) - - SSB.db.query( - q, - paginate(limit), - toCallback((err, answer) => { - if (err) return cb(err) - let results = answer.results.map(x => reEncrypt(x).value) - cb(null, pull.values(results)) - }) - ) - }) - ) } } } diff --git a/ssb-singleton.js b/ssb-singleton.js index 3d83ecb..3dab898 100644 --- a/ssb-singleton.js +++ b/ssb-singleton.js @@ -7,7 +7,9 @@ module.exports.setup = function (dir, config, extraModules) { window.windowList = (window.opener && window.opener.windowList ? window.opener.windowList : [ window ]) module.exports.initSSB = function() { - // Before we start up ssb-browser-core, let's check to see if we do not yet have an id, since this would mean that we need to display the onboarding screen. + // Before we start up ssb-browser-core, let's check to see if we + // do not yet have an id, since this would mean that we need to + // display the onboarding screen. const ssbKeys = require('ssb-keys') window.firstTimeLoading = false try { @@ -20,8 +22,16 @@ module.exports.setup = function (dir, config, extraModules) { window.updateFirstTimeLoading() require('./core').init(dir, config, extraModules) - SSB.uniqueID = (new Date()).getTime() - window.singletonSSB = SSB // Using a different name so that anything trying to use the non-singleton global will fail so we can find them. + + // Using a different name so that anything trying to use the + // non-singleton global will fail so we can find them. + window.singletonSSB = { + uniqueID: (new Date()).getTime() + } + + SSBLOADER.on('ready', () => { + window.singletonSSB.SSB = SSB + }) } } @@ -48,7 +58,9 @@ function runOnSuccess() { onSuccessCallbacks[f]() } -// Allows for registering callbacks which run any time the active SSB is switched, including if we initialize or we have to register with a new SSB in another window. +// Allows for registering callbacks which run any time the active SSB +// is switched, including if we initialize or we have to register with +// a new SSB in another window. module.exports.onChangeSSB = function(cb) { ssbChangedCallbacks.push(cb) } @@ -62,38 +74,51 @@ module.exports.onSuccess = function(cb) { } module.exports.getSSB = function() { + const r = module.exports.getSSBInternal() + if (r[1]) + return [r[0], r[1].SSB] + else + return r +} + +module.exports.getSSBInternal = function() { if (window.singletonSSB) { if (windowController.isMaster) { - // We're already holding an SSB object, so we can return it right away. runOnChangeIfNeeded(window.singletonSSB) runOnSuccess() return [ null, window.singletonSSB ] } else { - // We have an initialized SSB but lost our WindowController status, which means we probably froze up for long enough that another window gave up on listening for our heatbeat pings. - // We need to get rid of our SSB object as soon as possible and then fall back to trying to get it from another window. + // We have an initialized SSB but lost our WindowController + // status, which means we probably froze up for long enough that + // another window gave up on listening for our heatbeat pings. + // + // We need to get rid of our SSB object as soon as possible and + // then fall back to trying to get it from another window. delete window.singletonSSB } } var err = "Acquiring database lock - Only one instance of ssb-browser is allowed to run at a time." if (windowController.isMaster) { - // We've been elected as the SSB holder window but have no SSB yet. Initialize an SSB object. + // We've been elected as the SSB holder window but have no SSB + // yet. Initialize an SSB object. module.exports.initSSB() runOnChangeIfNeeded(window.singletonSSB) runOnSuccess() - return [ null, window.singletonSSB ] + return [null, window.singletonSSB] } else { - // We're not supposed to be running an SSB. But there might be another window with one. + // We're not supposed to be running an SSB. But there might be + // another window with one. for (w in window.windowList) { var otherWindow = window.windowList[w] if (otherWindow != window && otherWindow.windowController && otherWindow.getSSBSingleton) { if (window.windowController.others && window.windowController.others[otherWindow.windowController.id]) { // They're still responding to pings. - let [ err, otherSSB ] = otherWindow.getSSBSingleton().getSSB() - if (otherSSB) { - runOnChangeIfNeeded(otherSSB) + let [ err, otherSingleton ] = otherWindow.getSSBSingleton().getSSBInternal() + if (otherSingleton) { + runOnChangeIfNeeded(otherSingleton) runOnSuccess() - return [ null, otherSSB ] + return [null, otherSingleton] } } } @@ -165,7 +190,12 @@ module.exports.getSimpleSSBEventually = function(isRelevant, cb) { isRelevant = () => { return true } } - module.exports.getSSBEventually(-1, isRelevant, (SSB) => { return SSB && SSB.db }, cb) + module.exports.getSSBEventually( + -1, + isRelevant, + (SSB) => { return SSB && SSB.db }, + cb + ) } module.exports.openWindow = function(href) { diff --git a/test/test-contacts.js b/test/contacts.js similarity index 86% rename from test/test-contacts.js rename to test/contacts.js index 6530b25..fc93134 100644 --- a/test/test-contacts.js +++ b/test/contacts.js @@ -7,7 +7,7 @@ require('rimraf').sync(dir) require('../core.js').init(dir) -SSB.events.on('SSB: loaded', function() { +SSB.on('SSB: loaded', function() { test('Base', t => { const contactMsg = { type: 'contact', contact: '@6CAxOI3f+LUOVrbAl0IemqiS7ATpQvr9Mdw9LC4+Uv0=.ed25519', @@ -18,7 +18,7 @@ SSB.events.on('SSB: loaded', function() { t.equal(graph.following[0], contactMsg.contact) t.end() } - SSB.getGraphForFeed(SSB.net.id, onGraph) + SSB.helpers.getGraphForFeed(SSB.id, onGraph) }) }) }) diff --git a/test/test-partial.js b/test/partial.js similarity index 61% rename from test/test-partial.js rename to test/partial.js index fbff5e5..52ca73e 100644 --- a/test/test-partial.js +++ b/test/partial.js @@ -7,14 +7,14 @@ require('rimraf').sync(dir) require('../core.js').init(dir) -SSB.events.on('SSB: loaded', function() { +SSB.on('SSB: loaded', function() { test('Base', t => { const post = { type: 'post', text: 'Testing!' } SSB.db.publish(post, (err, postMsg) => { SSB.db.onDrain('ebt', () => { pull( - SSB.net.createHistoryStream({ id: SSB.net.id, keys: false }), + SSB.createHistoryStream({ id: SSB.id, keys: false }), pull.collect((err, results) => { t.equal(results.length, 1) // values directly @@ -28,7 +28,7 @@ SSB.events.on('SSB: loaded', function() { test('Keys', t => { pull( - SSB.net.createHistoryStream({ id: SSB.net.id }), + SSB.createHistoryStream({ id: SSB.id }), pull.collect((err, results) => { t.equal(results.length, 1) t.equal(typeof results[0].key, 'string') @@ -39,7 +39,7 @@ SSB.events.on('SSB: loaded', function() { test('No values', t => { pull( - SSB.net.createHistoryStream({ id: SSB.net.id, values: false }), + SSB.createHistoryStream({ id: SSB.id, values: false }), pull.collect((err, results) => { t.equal(results.length, 1) t.equal(typeof results[0], 'string') @@ -50,12 +50,12 @@ SSB.events.on('SSB: loaded', function() { test('Seq', t => { pull( - SSB.net.createHistoryStream({ id: SSB.net.id, keys: false, seq: 1 }), + SSB.createHistoryStream({ id: SSB.id, keys: false, seq: 1 }), pull.collect((err, results) => { t.equal(results.length, 1) pull( - SSB.net.createHistoryStream({ id: SSB.net.id, keys: false, seq: 0 }), + SSB.createHistoryStream({ id: SSB.id, keys: false, seq: 0 }), pull.collect((err, results) => { t.equal(results.length, 1) @@ -63,13 +63,13 @@ SSB.events.on('SSB: loaded', function() { SSB.db.publish(post, (err, postMsg) => { SSB.db.onDrain(() => { pull( - SSB.net.createHistoryStream({ id: SSB.net.id, keys: false, seq: 2 }), + SSB.createHistoryStream({ id: SSB.id, keys: false, seq: 2 }), pull.collect((err, results) => { t.equal(results.length, 1) t.equal(results[0].content.text, post.text) pull( - SSB.net.createHistoryStream({ id: SSB.net.id, keys: false, seq: 1, limit: 1 }), + SSB.createHistoryStream({ id: SSB.id, keys: false, seq: 1, limit: 1 }), pull.collect((err, results) => { t.equal(results.length, 1) t.equal(results[0].content.text, 'Testing!') @@ -88,13 +88,13 @@ SSB.events.on('SSB: loaded', function() { }) test('Encrypted', t => { - var content = { type: 'post', text: 'super secret', recps: [SSB.net.id] } - content = SSB.box(content, content.recps.map(x => x.substr(1))) + var content = { type: 'post', text: 'super secret', recps: [SSB.id] } + content = SSB.helpers.box(content, content.recps.map(x => x.substr(1))) SSB.db.publish(content, (err, privateMsg) => { SSB.db.onDrain(() => { pull( - SSB.net.createHistoryStream({ id: SSB.net.id, keys: false }), + SSB.createHistoryStream({ id: SSB.id, keys: false }), pull.collect((err, results) => { t.equal(results.length, 3) t.equal(typeof results[2].content, 'string') @@ -105,27 +105,6 @@ SSB.events.on('SSB: loaded', function() { }) }) - test('getFeed', t => { - pull( - SSB.net.partialReplication.getFeed({ id: SSB.net.id, keys: false }), - pull.collect((err, results) => { - t.equal(results.length, 3) - t.end() - }) - ) - }) - - test('getFeedReverse', t => { - pull( - SSB.net.partialReplication.getFeedReverse({ id: SSB.net.id, limit: 1, keys: false }), - pull.collect((err, results) => { - t.equal(results.length, 1) - t.equal(typeof results[0].content, 'string') - t.end() - }) - ) - }) - test('getTangle', t => { var content = { type: 'post', text: 'Thread' } @@ -133,7 +112,7 @@ SSB.events.on('SSB: loaded', function() { var reply = { type: 'post', text: 'Thread msg', root: threadMsg.key, branch: threadMsg.key } SSB.db.publish(reply, (err, replyMsg) => { SSB.db.onDrain(() => { - SSB.net.partialReplication.getTangle(threadMsg.key, (err, results) => { + SSB.partialReplication.getTangle(threadMsg.key, (err, results) => { t.error(err, 'no err') t.equal(results.length, 2) t.equal(results[0].content.text, content.text) @@ -146,16 +125,16 @@ SSB.events.on('SSB: loaded', function() { }) test('getTangle private', t => { - var content = { type: 'post', text: 'Private thread', recps: [SSB.net.id] } - content = SSB.box(content, content.recps.map(x => x.substr(1))) + var content = { type: 'post', text: 'Private thread', recps: [SSB.id] } + content = SSB.helpers.box(content, content.recps.map(x => x.substr(1))) SSB.db.publish(content, (err, threadMsg) => { var reply = { type: 'post', text: 'Thread msg', root: threadMsg.key, branch: threadMsg.key, - recps: [SSB.net.id] } - reply = SSB.box(reply, reply.recps.map(x => x.substr(1))) + recps: [SSB.id] } + reply = SSB.helpers.box(reply, reply.recps.map(x => x.substr(1))) SSB.db.publish(reply, (err, replyMsg) => { SSB.db.onDrain(() => { - SSB.net.partialReplication.getTangle(threadMsg.key, (err, results) => { + SSB.partialReplication.getTangle(threadMsg.key, (err, results) => { t.equal(results.length, 1, "only the original message") t.equal(results[0].text, content.text) t.end() @@ -164,21 +143,4 @@ SSB.events.on('SSB: loaded', function() { }) }) }) - - test('getMessagesOfType', t => { - var content = { type: 'about', name: 'Monty' } - - SSB.db.publish(content, (err, content) => { - SSB.db.onDrain(() => { - pull( - SSB.net.partialReplication.getMessagesOfType({ id: SSB.net.id, type: 'post', keys: false }), - pull.collect((err, results) => { - t.equal(results.length, 7) - t.equal(results.filter(x => typeof x.content !== 'string').length, 4) - t.end() - }) - ) - }) - }) - }) })