git ssb

1+

Matt McKegg / mutant



Tree: f69a37d1862b7bc2b9590d1514f049129243de67

Files: f69a37d1862b7bc2b9590d1514f049129243de67 / set.js

2612 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 }
98}
99
100function get (value) {
101 return value
102}
103
104function resolve (source) {
105 return typeof source === 'function' ? source() : source
106}
107
108function notIncluded (value) {
109 return !~this.indexOf(value)
110}
111
112function removeFrom (item) {
113 var index = this.indexOf(item)
114 if (~index) {
115 this.splice(index, 1)
116 }
117}
118
119function addTo (item) {
120 this.push(item)
121}
122
123function tryInvoke (func) {
124 if (typeof func === 'function') {
125 func()
126 }
127}
128

Built with git-ssb-web