Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

ssb-crut

Package Overview
Dependencies
Maintainers
3
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ssb-crut - npm Package Compare versions

Comparing version 4.6.3 to 5.0.0

6

CHANGELOG.md
# Changelog
## v5.0.0
Breaking:
- `crut.list` now supports more options for `opts.orderBy`, but to support this needed to
change the API of `opts.read` for that method
## v4.0.0

@@ -4,0 +10,0 @@

24

index.js

@@ -69,2 +69,3 @@ const Strategy = require('@tangle/strategy')

this.createStream = CreateStream(ssb, this.spec)
this.getRecordId = GetRecordId(this.spec)
}

@@ -228,12 +229,15 @@

opts.groupId
? pull.filter(msg => (
msg.value.content.recps &&
msg.value.content.recps[0] === opts.groupId
))
? pull.filter(msg => {
if (!msg.value.content.recps) return false
return msg.value.content.recps[0] === opts.groupId
})
: null,
pull.map(this.getRecordId),
pull.unique(),
// map rootMsg => record (and filter out the ones which were junk)
paraMap(
opts.read || ((msg, cb) => {
this.read(msg.key, (err, record) => {
opts.read || ((id, cb) => {
this.read(id, (err, record) => {
if (err) cb(null, false)

@@ -373,1 +377,9 @@ else cb(null, record)

}
function GetRecordId (spec) {
return function getRecordId (msg) {
return msg.value.content.tangles[spec.tangle].root === null
? msg.key
: msg.value.content.tangles[spec.tangle].root
}
}

@@ -0,48 +1,101 @@

/* eslint brace-style: ["error", "stroustrup", { "allowSingleLine": true }] */
const RECEIVE_TIME = 'receiveTime'
const UPDATE_TIME = 'updateTime'
const CREATE_TIME = 'createTime'
// creates a stream of potential recordIds
module.exports = function CreateStream (ssb, spec) {
if (ssb.db) {
const { where, and, slowEqual, type, descending, sortByArrival, toPullStream } = require('ssb-db2/operators')
if (ssb.db) return CreateDB2Stream(ssb, spec)
else return CreateDB1Stream(ssb, spec)
}
return function createStreamDB2 (opts) {
return ssb.db.query(
where(
and(
type(spec.type),
slowEqual(`value.content.tangles.${spec.tangle}.root`, null)
)
),
opts.descending === false ? null : descending(),
(opts.orderBy || opts.sortBy) === CREATE_TIME ? null : sortByArrival(),
toPullStream()
)
function CreateDB1Stream (ssb, spec) {
return function createDB1Stream (opts) {
const orderBy = opts.orderBy || opts.sortBy
let $filter
if (orderBy === RECEIVE_TIME || orderBy === undefined) {
$filter = {
timestamp: { $gt: 0 }, // stimulates orderBy received time
value: {
content: {
type: spec.type,
tangles: {
[spec.tangle]: { root: null } // root messages
}
}
}
}
}
} // eslint-disable-line
else {
return function createStreamDB1 (opts) {
const query = [{
$filter: {
value: {
content: {
type: spec.type,
tangles: {
[spec.tangle]: { root: null }
}
else if (orderBy === CREATE_TIME) {
$filter = {
value: {
timestamp: { $gt: 0 }, // stimulates orderBy (asserted) create time
content: {
type: spec.type,
tangles: {
[spec.tangle]: { root: null } // root messages
}
}
}
}]
if ((opts.orderBy || opts.sortBy) === CREATE_TIME) {
query[0].$filter.value.timestamp = { $gt: 0 }
// this is a common ssb-query hack to stimulate the tya index to be used
// tya = "type, asserted timestamp" (otherwise tyr = "type, received timestamp" is used)
}
}
else if (orderBy === UPDATE_TIME) {
$filter = {
timestamp: { $gt: 0 }, // stimulates orderBy received time
value: {
content: {
type: spec.type,
tangles: {
[spec.tangle]: { $is: 'object' } // either root/update!
}
}
}
}
}
else throw new Error(`unknown opts.orderBy ${orderBy}`)
// these are a common ssb-query hack to stimulate the the right time-ordering index
// tya = "type, asserted timestamp"
// tyr = "type, received timestamp"
return ssb.query.read({
query,
// ...opts,
reverse: opts.descending !== false
})
}
return ssb.query.read({
query: [{ $filter }],
// ...opts,
reverse: opts.descending !== false
})
}
}
function CreateDB2Stream (ssb, spec) {
const {
where, and,
slowPredicate, slowEqual, type,
descending, sortByArrival,
toPullStream
} = require('ssb-db2/operators')
return function createDB2Stream (opts) {
return ssb.db.query(
where(
and(
type(spec.type),
(opts.orderBy === UPDATE_TIME)
? slowPredicate(`value.content.tangles.${spec.tangle}.root`, isAny)
: slowEqual(`value.content.tangles.${spec.tangle}.root`, null)
// NOTE this could be better written, can look at it later
)
),
opts.descending === false ? null : descending(),
(opts.orderBy || opts.sortBy) === CREATE_TIME ? null : sortByArrival(),
toPullStream()
)
}
}
function isAny (root) {
return (
root === null ||
typeof root === 'string'
)
}
{
"name": "ssb-crut",
"version": "4.6.3",
"version": "5.0.0",
"description": "easy CRUT methods for secure scuttlebutt",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -328,4 +328,6 @@ # ssb-crut

- define what order to pull the records in by, looks at the times recorded on the **initial message** of the record.
- options: `receiveTime|createTime`
- default: `receiveTime`
- options:
- `receiveTime` = order by when the record was first received/ written (default)
- `updateTime` = order by how recently writes (create/update) to the record were received
- `createTime` = order by when the record was created (as asserted by the author)
- `opts.descending` *Boolean*

@@ -342,4 +344,4 @@ - sets whether the receiveTime/createTime/updateTime is _descending_ throughour the results

```js
(msg, cb) => {
crut.read(msg.key, (err, record) => {
(id, cb) => {
crut.read(id, (err, record) => {
if (err) cb(null, null) // prevents one failed read from causing whole like to fail

@@ -350,2 +352,3 @@ else cb(null, record)

```
- where `recordId` is the id of the root message of the record tangle
- `opts.width` *Integer*

@@ -352,0 +355,0 @@ - how many `read` functions to run in parallel

@@ -83,3 +83,3 @@ const test = require('tape')

t.true(profile.tombstone, 'isTombstoned')
t.deepEqual(profile.states.length, 1, 'forceTombstone merges the branched states')
t.equal(profile.states.length, 1, 'forceTombstone merges the branched states')

@@ -86,0 +86,0 @@ server1.close()

@@ -8,11 +8,12 @@ const test = require('tape')

test('list', async t => {
const spec = {
type: 'profile/test',
tangle: 'profile',
props: {
name: Overwrite()
}
const spec = {
type: 'profile/test',
tangle: 'profile',
props: {
name: Overwrite()
}
}
test('list', async t => {
/* setup */
// make a friend who has made a record first

@@ -25,12 +26,20 @@ const friend = SSB()

const crut = new CRUT(me, spec)
const create = (name, recps) => crut.create({ name, recps })
const create = async (name, recps) => {
const id = await crut.create({ name, recps })
if (process.env.DB2) {
await promisify(setTimeout)(50)
// HACK db2 gets orderBy=createTime wrong sometimes without this
}
return id
}
await create(1)
const recordId = await create(2)
await crut.update(recordId, { name: 2.0 })
const secondId = await create(2)
await create(3)
await crut.update(secondId, { name: 2.0 })
// order of creation: 3, 2, 1, 0 (descending)
// order of update: 2, 3, 1, 0 (descending)
let list
list = await crut.list()
/* opts = {} */
let list = await crut.list()
t.deepEqual(

@@ -42,3 +51,3 @@ list.map(record => record.name),

// limit
/* opts.limit */
list = await crut.list({ limit: 2 })

@@ -51,2 +60,3 @@ t.deepEqual(

/* opts.descending */
// limit fail

@@ -67,4 +77,4 @@ try {

// startFrom
list = await crut.list({ startFrom: recordId })
/* opts.startFrom */
list = await crut.list({ startFrom: secondId })
t.deepEqual(

@@ -76,12 +86,19 @@ list.map(record => record.name),

// orderBy
/* opts.orderBy */
await replicate({ from: friend, to: me })
list = await crut.list()
list = await crut.list() // orderBy: receiveTime
t.deepEqual(
list.map(record => record.name),
[0, 3, 2.0, 1],
'opts.orderBy = receivedTime (after replicate))'
'opts.orderBy = receiveTime (after replicate))'
)
list = await crut.list({ orderBy: 'updateTime' })
t.deepEqual(
list.map(record => record.name),
[0, 2.0, 3, 1],
'opts.orderBy = updateTime (after replicate))'
)
list = await crut.list({ orderBy: 'createTime' })

@@ -91,3 +108,3 @@ t.deepEqual(

[3, 2.0, 1, 0],
'opts.orderBy = createdTime (after replicate))'
'opts.orderBy = createTime (after replicate))'
)

@@ -97,4 +114,6 @@

list = await crut.list({
filter: record => Math.floor(record.name % 2 === 0)
})
filter: record => {
return Math.floor(record.name) % 2 === 0
}
}).catch(t.error)
t.deepEqual(

@@ -108,4 +127,4 @@ list.map(record => record.name),

list = await crut.list({
read: (msg, cb) => {
crut.read(msg.key, (err, record) => {
read: (id, cb) => {
crut.read(id, (err, record) => {
if (err) return cb(null, null)

@@ -120,3 +139,4 @@

// but could also check a cache etc
})
}).catch(t.error)
t.deepEqual(

@@ -129,3 +149,3 @@ list.map(record => record.fancyName),

// tombstone
await crut.tombstone(recordId, {})
await crut.tombstone(secondId, {})
list = await crut.list()

@@ -132,0 +152,0 @@ t.deepEqual(

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc