git ssb

1+

Matt McKegg / mutant



Tree: 89c147a250091cde1a0a493d7aac2a9e27ac1f3b

Files: 89c147a250091cde1a0a493d7aac2a9e27ac1f3b / set.js

2628 bytesRaw
1var LazyWatcher = require('./lib/lazy-watcher')
2
3module.exports = Set
4
5function Set (defaultValues) {
6 var object = []
7 var sources = []
8 var releases = []
9
10 var binder = LazyWatcher(update, listen, unlisten)
11 binder.value = object
12
13 if (defaultValues && defaultValues.length) {
14 defaultValues.forEach(function (valueOrObs) {
15 if (!~sources.indexOf(valueOrObs)) {
16 sources.push(valueOrObs)
17 }
18 })
19 update()
20 }
21
22 var observable = function MutantSet (listener) {
23 if (!listener) {
24 return binder.getValue()
25 }
26 return binder.addListener(listener)
27 }
28
29 observable.add = function (valueOrObs) {
30 if (!~sources.indexOf(valueOrObs)) {
31 sources.push(valueOrObs)
32 if (binder.live) {
33 releases[sources.length - 1] = bind(valueOrObs)
34 }
35 binder.onUpdate()
36 }
37 }
38
39 observable.clear = function () {
40 releases.forEach(tryInvoke)
41 sources.length = 0
42 releases.length = 0
43 binder.onUpdate()
44 }
45
46 observable.delete = function (valueOrObs) {
47 var index = sources.indexOf(valueOrObs)
48 if (~index) {
49 sources.splice(index, 1)
50 releases.splice(index, 1).forEach(tryInvoke)
51 binder.onUpdate()
52 }
53 }
54
55 observable.has = function (valueOrObs) {
56 return !!~object.indexOf(valueOrObs)
57 }
58
59 observable.set = function (values) {
60 sources.length = 0
61 values.forEach(function (value) {
62 sources.push(value)
63 })
64 binder.onUpdate()
65 }
66
67 observable.get = function (index) {
68 return sources[index]
69 }
70
71 observable.getLength = function () {
72 return sources.length
73 }
74
75 return observable
76
77 function bind (valueOrObs) {
78 return typeof valueOrObs === 'function' ? valueOrObs(binder.onUpdate) : null
79 }
80
81 function listen () {
82 sources.forEach(function (obs, i) {
83 releases[i] = bind(obs)
84 })
85 }
86
87 function unlisten () {
88 releases.forEach(tryInvoke)
89 releases.length = 0
90 }
91
92 function update () {
93 var currentValues = object.map(get)
94 var newValues = sources.map(resolve)
95 currentValues.filter(notIncluded, newValues).forEach(removeFrom, object)
96 newValues.filter(notIncluded, currentValues).forEach(addTo, object)
97 return true
98 }
99}
100
101function get (value) {
102 return value
103}
104
105function resolve (source) {
106 return typeof source === 'function' ? source() : source
107}
108
109function notIncluded (value) {
110 return !~this.indexOf(value)
111}
112
113function removeFrom (item) {
114 var index = this.indexOf(item)
115 if (~index) {
116 this.splice(index, 1)
117 }
118}
119
120function addTo (item) {
121 this.push(item)
122}
123
124function tryInvoke (func) {
125 if (typeof func === 'function') {
126 func()
127 }
128}
129

Built with git-ssb-web