Files: aacf3bddbfecb924c25697a24bafc3bb0b1b86ad / array.js
2615 bytesRaw
1 | var Value = require('./value') |
2 | |
3 | module.exports = Array |
4 | |
5 | function Array (defaultValues) { |
6 | var object = [] |
7 | var sources = [] |
8 | var releases = [] |
9 | |
10 | if (defaultValues && defaultValues.length) { |
11 | defaultValues.forEach(add) |
12 | } |
13 | |
14 | var observable = Value(object) |
15 | var broadcast = observable.set |
16 | |
17 | observable.push = function (args) { |
18 | for (var i = 0; i < arguments.length; i++) { |
19 | add(arguments[i]) |
20 | } |
21 | broadcast(object) |
22 | } |
23 | |
24 | observable.insert = function (valueOrObs, at) { |
25 | sources.splice(at, 0, valueOrObs) |
26 | releases.splice(at, 0, bind(valueOrObs)) |
27 | object.splice(at, 0, resolve(valueOrObs)) |
28 | broadcast(object) |
29 | } |
30 | |
31 | observable.get = function (index) { |
32 | return sources[index] |
33 | } |
34 | |
35 | observable.getLength = function (index) { |
36 | return sources.length |
37 | } |
38 | |
39 | observable.includes = function (valueOrObs) { |
40 | return !!~sources.indexOf(valueOrObs) |
41 | } |
42 | |
43 | observable.indexOf = function (valueOrObs) { |
44 | return sources.indexOf(valueOrObs) |
45 | } |
46 | |
47 | observable.indexOf |
48 | |
49 | observable.pop = function () { |
50 | var result = sources.pop() |
51 | tryInvoke(releases.pop()) |
52 | object.pop() |
53 | broadcast(object) |
54 | return result |
55 | } |
56 | |
57 | observable.shift = function () { |
58 | var result = sources.shift() |
59 | tryInvoke(releases.shift()) |
60 | object.shift() |
61 | broadcast(object) |
62 | return result |
63 | } |
64 | |
65 | observable.clear = function () { |
66 | releases.forEach(tryInvoke) |
67 | sources.length = 0 |
68 | releases.length = 0 |
69 | object.length = 0 |
70 | broadcast(object) |
71 | } |
72 | |
73 | observable.delete = function (valueOrObs) { |
74 | var index = sources.indexOf(valueOrObs) |
75 | if (~index) { |
76 | sources.splice(index, 1) |
77 | releases.splice(index, 1).forEach(tryInvoke) |
78 | object.splice(index, 1) |
79 | broadcast(object) |
80 | } |
81 | } |
82 | |
83 | observable.set = function (values) { |
84 | releases.forEach(tryInvoke) |
85 | sources.length = 0 |
86 | releases.length = 0 |
87 | object.length = 0 |
88 | values.forEach(add) |
89 | broadcast(object) |
90 | } |
91 | |
92 | observable.destroy = observable.clear |
93 | |
94 | return observable |
95 | |
96 | // scoped |
97 | |
98 | function add (valueOrObs) { |
99 | sources.push(valueOrObs) |
100 | releases.push(bind(valueOrObs)) |
101 | object.push(resolve(valueOrObs)) |
102 | } |
103 | |
104 | function bind (valueOrObs) { |
105 | return typeof valueOrObs === 'function' ? valueOrObs(update.bind(this, valueOrObs)) : null |
106 | } |
107 | |
108 | function update (obs, value) { |
109 | sources.forEach(function (source, i) { |
110 | if (source === obs) { |
111 | object[i] = value |
112 | } |
113 | }) |
114 | broadcast(object) |
115 | } |
116 | } |
117 | |
118 | function resolve (source) { |
119 | return typeof source === 'function' ? source() : source |
120 | } |
121 | |
122 | function tryInvoke (func) { |
123 | if (typeof func === 'function') { |
124 | func() |
125 | } |
126 | } |
127 |
Built with git-ssb-web