@tangle/complex-set
v3.0.3
Published
A strategy for tracking a set over time, when it matters when a certain thing was added to a Set, and when it was removed
Downloads
30
Readme
@tangle/complex-set
A strategy for tracking a set over time, when it matters when a certain thing was added to a Set, and when it was removed
Example Usage
const ComplexSet = require('@tangle/complex-set')
const input = {
add: [
{ id: '@ben', seq: 25 },
{ id: '@cherese', seq: 2 }
]
}
strategy.mapFromInput(input, [strategy.identity()])
// => {
// '@ben': { 25: 1 },
// 'cherese: { 2: 1 }
// }
The raw transformations look like this:
{
[id]: {
[seq]: state
}
}
where
id
String - the thing being added / removed from the setseq
Integer - some Integer which is a unique representation of when. (e.g. logical clock or clock wall time). Must be >= 0state
Integer - an Integer representing whether it was an add or remove.state > 0
- addstate <= 0
- remove
However there are convenience methods for making it easier to work with these.
API
ComplexSet(idPattern) => complexSet
Instantiates a strategy, complexSet
.
idPattern
String (optional)- a pattern which is converted into a regexp validating the
id
field - e.g.
'^@\w+$'
would make only ids like@mixmix
valid - default:
'^.+$'
- a pattern which is converted into a regexp validating the
complexSet.isValid(T) => Boolean
complexSet.schema
Access the JSON shcema that isValid
was built with.
complexSet.concat(A, B) => C
complexSet.identity() => I
returns "identity transformation"
complexSet.mapFromInput(input, currentTips) => T
Takes a current transformation state, currentTips
, an array of Ts that are the
tips of the graph, along with a human friendly (descriptive) input
and returns a transformation T
which satisfies the
change requested in `input.
Format of input:
{
add: [{ id: Id, seq: Integer }, ... ]
remove: [{ id: Id, seq: Integer }, ... ]
}
where:
id
is a unique identifier for something being added.Id
must pass theidPattern
validator
seq
is a "sequence", some whole number which represents a position in time- this could be a vector clock, or
- a wall clock (UTC time)
You can provide EITHER add / remove OR both.
complexSet.mapToOutput(T) => t
Takes a transformation T
and returns an output state t
, which is more
"human readable"
Format of output t
:
{
Id: [Interval],
}
A series of Interval
s is computed for each Id
from all the add and remove
events, and these are ordered lowest to highest in terms of sequence.
Intervals will be of form:
{ start: Integer, end: Integer }
- a "closed" interval{ start: Integer, end: null }
- an "open" interval
- this will only ever occur as the last interval in a series
An Example transformation
When users were added / removed as permitted authors for an ssb-record.
// an example of a transformation
T = {
// an example set where each @user was permitted at different intervals
'@cherese': {
200: 1, // seq=200, state=1=add
1000: -1 // seq=1000, state=-1=remove
},
'@ben': {
1000: 1, // seq=1000, state=1=add
1100: 2, // seq=1100, state=2=add
2000: -1 // seq=2000, state=-1=remove
},
'@mix': {
300: -1 // seq=300, state=-1=remove
}
}
// the reified state of that transformation
mapToOutput(T) = {
'@cherese': [{ start: 200, end: 1000 }],
'@ben': [{ start: 1000, end: 2000 }], // note how 1100 wasnt added
// note @mix is not here
// ids with no "add" states are ignored
}
simpleSet.isConflict() => False
simpleSet.isValidMerge() => True
simpleSet.merge(graph, mergeNode, field) => T
where:
graph
is a@tangle/graph
instancemergeNode
is the proposed merge-nodefield
String contains the the data fieldsnode.data[field]