ssb-settings

An ssb-server plugin for creating, reading and updating settings records in scuttlebutt

Usage no npm install needed!

<script type="module">
  import ssbSettings from 'https://cdn.skypack.dev/ssb-settings';
</script>

README

ssb-settings

An ssb-server plugin for creating, reading and updating settings records in scuttlebutt

Modules

  • ssb-settings

Settings

Settings is a record to store custom information that can be used to configure settings for an app, group or profile.

   A   (the root message)
   |
   B   (an edit after A)
// settings for the example above
{
  key: A, // settingsId, the MessageId of the root message of the settings
  originalAuthor: FeedId,
  recps: [FeedId],
  states: [
    { head: B, state: stateB }
  ]
}

and the state is an Object which looks like the following:

{
  key: B, // settingsId, the MessageId of the update message of the settings 
  type: String,

  keyBackedUp: Boolean,

  authors: {
    [FeedId]: [
      { start: Integer, end: Integer }
    ]
  }

  tombstone: Tombstone
}

API

server.settings.create(details, cb)

Creates a new settings record and describes details you'd like to set on it

  • details Object - allows you to specify additional fields
  • cb Function - a callback with signature (err, settingsId)

The expected form of details:

{
  recps: [ FeedId, ...],          // can only be set in create

  keyBackedUp: Boolean,

  authors: {
    add: [FeedId, ALL_AUTHORS],
    remove: [FeedId, ALL_AUTHORS] // NOTE: not available on create
  },

  tombstone: Tombstone            // NOTE: don't use - tombstone has a dedicated method
}
  • type Tombstone is either null OR an Object of shape:

    {
      date: UnixTime,  // an Integer indicating microseconds from 1st Jan 1970, can be negative!
      reason: String   // (optional)
    }
    
  • recps is a special scuttlebutt property, short for "recipients". Adding this means the settings will automatically be encrypted so only the FeedId and GroupId listed in the recps Array will be able to read this settings. (to use GroupId see ssb-tribes)

  • authors contains two arrays (add, remove) for adding and removing authors to the set. Authors are of the form feedId or *:

    • FeedId - updates from this author will be valid
    • * - updates by all authors will be valid
    • NOTE: authors are valid until they are removed from the set. When this feedId, it overrides all authors until it is removed
    • Any updates that arent from a valid author are classed as invalid and wont be returned when using the get method

Note: All of these fields are optional


server.settings.get(settingsId, cb)

Gets a settings record by its settingsId

  • settingsId String - the cypherlink for the settings (the msgId of the root message for the settings)
  • cb Function - a callback with signature (err, settings)

All fields will be returned, but if no value has been set/added for that field, the value will be null


server.settings.link.create({ settings }, cb)

Creates a message which links a feed and settings.

Arguments:

  • settings MessageId - the key for settings (the root message of a profile tangle)
  • cb Function - callback with signature (err, linkId)
    • linkId String - the cypherlink for the link (the msgId of the root message for the link)

Note:

  • feed-settings links are always with the feedId of the current scuttlebutt instance, so feed is not an input
  • recps are always set to the same recps of the root message for the settings

server.settings.findByFeedId(feedId, cb)

Takes a feedId and calls back with all settings that feedId has linked to it. Signature of cb is cb(err, settings). See the example at the top for the form of settings

NOTE:

  • Settings which have been tombstoned are not included in results
  • Settings are ordered from oldest to newest in terms of when they were linked to the feedId
  • You can call this with server.settings.findByFeedId(feedId, { getSettings }, cb), useful if you have a getter with a cache

server.settings.update(settingsId, details, cb)

Gets a settings record by its settingsId

  • settingsId String - the cypherlink for the settings (the msgId of the root message for the settings)
  • details Object - same as in settings.create except recps is set for you based on what the first message was
  • cb Function - a callback with signature (err)

All fields will be returned, but if no value has been set/added for that field, the value will be null

server.settings.tombstone(settingsId, opts, cb)

  • settingsId String - the cypherlink for the settings (the msgId of the root message for the settings)
  • opts Object
    • opts.date UnixTime - time since 1970 in ms
    • opts.reason String (optional)
  • cb Function - a callback with signature (err, tombstoneId)

Future

In the future, we might support settings that are shared over multiple devices. That would mean we need to account for potentially divergent states like:

   A   (the root message)
   |
   B   (an edit after A)
  / \
 C   D (two concurrent edits after B)

Because there might be multiple offline edits to settings which didn't know about one-another, it's possible for divergence to happen: C and D wont know about each other.

Settings is an Object which maps the key of each latest edit to the state it perceives the settings record to be in:

// settings for the example above
{
  key: MessageId, // settingsId supplied, the root message of the settings
  states: [
    { head: C, state: stateC },
    { head: D, state: stateD },
  ]
}

and the state is an Object which looks like the following:

{
  type: String,
  keyBackedUp: Boolean,

  authors: {
    [FeedId]: [
      { start: Integer, end: Integer }
    ]
  }

  recps: Recps,
  tombstone: Tombstone
}