|
| 1 | +Lineage |
| 2 | +======= |
| 3 | + |
| 4 | +A data versioning library. |
| 5 | + |
| 6 | +## Introduction |
| 7 | + |
| 8 | +Lineage is a JavaScript library for managing versions of data, especially |
| 9 | +helpful when reasoning about state in distributed systems. It provides several |
| 10 | +data types that can act as versions and also provide |
| 11 | + |
| 12 | +Lineage: |
| 13 | + |
| 14 | +- Defines a [protocol](https://github.com/codeparty/protocoljs) for |
| 15 | + incrementing, comparing, and merging versions. |
| 16 | +- Provides several data types that can act as versions. |
| 17 | +- Enables you to add your own data types that can act as versions. |
| 18 | + |
| 19 | +## Installation |
| 20 | + |
| 21 | +``` |
| 22 | +$ npm install lineage |
| 23 | +``` |
| 24 | + |
| 25 | +## Basics |
| 26 | + |
| 27 | +The most basic version data type you can use is a Number or Date. |
| 28 | + |
| 29 | +## Numbers as versions |
| 30 | + |
| 31 | +```javascript |
| 32 | +var lineage = require('lineage') |
| 33 | + , protocol = lineage.protocol; |
| 34 | + |
| 35 | +// Require this to extend Number with the version protocol provided by lineage. |
| 36 | +require('lineage/lib/types/number'); |
| 37 | + |
| 38 | +var oldVersion = 1; |
| 39 | +var newVersion = protocol.incr(oldVersion); // => 2 |
| 40 | + |
| 41 | +var comparison = protocol.compare(oldVersion, newVersion); |
| 42 | +console.log(comparison === protocol.consts.LT); // true |
| 43 | + |
| 44 | +comparison = protocol.compare(oldVersion, oldVersion); |
| 45 | +console.log(comparison === protocol.consts.EQ); // true |
| 46 | + |
| 47 | +comparison = protocol.compare(newVersion, oldVersion); |
| 48 | +console.log(comparison === protocol.consts.GT); // true |
| 49 | +``` |
| 50 | + |
| 51 | +## Dates as versions |
| 52 | + |
| 53 | +Dates act similarly to numbers except version incrementing a Date just means |
| 54 | +returning the Date right now. |
| 55 | + |
| 56 | +```javascript |
| 57 | +var lineage = require('lineage') |
| 58 | + , protocol = lineage.protocol; |
| 59 | + |
| 60 | +// Require this to extend Date with the version protocol provided by lineage |
| 61 | +require('lineage/lib/types/number'); |
| 62 | + |
| 63 | +var oldVersion = new Date(); |
| 64 | + |
| 65 | +setTimeout( function () { |
| 66 | + var newVersion = protocol.incr(oldVersion); // => <Date> |
| 67 | + var comparison = protocol.compare(oldVersion, newVersion); |
| 68 | + console.log(comparison ==== protocol.consts.LT); // true |
| 69 | + |
| 70 | + comparison = protocol.compare(oldVersion, oldVersion); |
| 71 | + console.log(comparison, protocol.consts.EQ); // true |
| 72 | + |
| 73 | + comparison = protocol.compare(newVersion, oldVersion); |
| 74 | + console.log(comparison === protocol.consts.GT); // true |
| 75 | +}, 1); |
| 76 | +``` |
| 77 | + |
| 78 | +## Vector Clocks |
| 79 | + |
| 80 | +For distributed systems, the ideal data structure to use is a vector clock, |
| 81 | +also known as a [Lamport Clock](http://en.wikipedia.org/wiki/Lamport_timestamps). |
| 82 | + |
| 83 | +Lineage provides vector clocks out of the box. |
| 84 | + |
| 85 | +Why vector clocks are critical when you want to version data in a distributed |
| 86 | +system is more involved, and this README will point the reader instead to the |
| 87 | +[canonical paper on Lamport |
| 88 | +clocks](http://research.microsoft.com/en-us/um/people/lamport/pubs/time-clocks.pdf). |
| 89 | + |
| 90 | +What a vector clock does behind the scenes is more straightforward. Vector |
| 91 | +clocks extend the concept of the Number as a counter that represents the |
| 92 | +version. Vector clocks are a set of counters, where each counter is associated |
| 93 | +with the actor/client/node that updated the vector clock. Every time a |
| 94 | +particular actor updates a vector clock, the counter it is associated with is |
| 95 | +incremented. |
| 96 | + |
| 97 | +```JavaScript |
| 98 | +var lineage = require('lineage') |
| 99 | + , protocol = lineage.protocol |
| 100 | + , Clock = require('lineage/lib/types/clock'); |
| 101 | + |
| 102 | +var oldVersion = new Clock(); // => <Clock> |
| 103 | + |
| 104 | +// Compared to Number as a version, Clocks as versions must associate every |
| 105 | +// update to a version with an actor id. Here that actor id is 'actor-A' |
| 106 | +var newVersion = protocol.incr(oldVersion, 'actor-A'); |
| 107 | + |
| 108 | +// Vectors updated by an actor compare to other vectors just how you would |
| 109 | +// expect them to. |
| 110 | +var comparison = protocol.compare(oldVersion, newVersion); |
| 111 | +console.log(comparison === protocol.consts.LT); // true |
| 112 | + |
| 113 | +comparison = protocol.compare(oldVersion, oldVersion); |
| 114 | +console.log(comparison === protocol.consts.EQ); // true |
| 115 | + |
| 116 | +comparison = protocol.compare(newVersion, oldVersion); |
| 117 | +console.log(comparison === protocol.consts.GT); // true |
| 118 | +``` |
| 119 | + |
| 120 | +Up until this point, it would appear as though Clock versions compare to each |
| 121 | +other in the same way that Number versions compare to each other. So why even |
| 122 | +have a different data structure to use for versions? |
| 123 | + |
| 124 | +Things become more interesting when we involve another actor updating the |
| 125 | +version -- in this case, we have a distributed system. |
| 126 | + |
| 127 | +TODO - finish the README |
| 128 | + |
| 129 | +Suppose 1 person in the US and 1 person in China both receive an identical calendar. |
| 130 | + |
| 131 | +### MIT License |
| 132 | +Copyright (c) 2012 by Brian Noguchi and Nate Smith |
| 133 | + |
| 134 | +Permission is hereby granted, free of charge, to any person obtaining a copy |
| 135 | +of this software and associated documentation files (the "Software"), to deal |
| 136 | +in the Software without restriction, including without limitation the rights |
| 137 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 138 | +copies of the Software, and to permit persons to whom the Software is |
| 139 | +furnished to do so, subject to the following conditions: |
| 140 | + |
| 141 | +The above copyright notice and this permission notice shall be included in |
| 142 | +all copies or substantial portions of the Software. |
| 143 | + |
| 144 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 145 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 146 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 147 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 148 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 149 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 150 | +THE SOFTWARE. |
0 commit comments