UNPKG

2.43 kBJavaScriptView Raw
1var LazyWatcher = require('./lib/lazy-watcher')
2var resolve = require('./resolve')
3var isObservable = require('./is-observable')
4
5module.exports = ProxyCollection
6
7function ProxyCollection (source, opts) {
8 var releases = []
9
10 var binder = LazyWatcher(update, listen, unlisten)
11 binder.value = resolve(source)
12
13 if (opts && opts.nextTick) binder.nextTick = true
14 if (opts && opts.idle) binder.idle = true
15
16 var observable = function MutantProxyCollection (listener) {
17 if (!listener) {
18 return binder.getValue()
19 }
20 return binder.addListener(listener)
21 }
22
23 observable.get = function (index) {
24 if (isObservable(source) && source.get) {
25 return source.get(index)
26 } else if (Array.isArray(resolve(source))) {
27 return resolve(source)[index]
28 }
29 }
30
31 observable.getLength = function () {
32 if (isObservable(source) && source.getLength) {
33 return source.getLength()
34 } else if (Array.isArray(resolve(source))) {
35 return resolve(source).length
36 }
37 }
38
39 observable.includes = function (value) {
40 if (isObservable(source) && source.includes) {
41 return source.includes(value)
42 } else if (Array.isArray(resolve(source))) {
43 return !!~resolve(source).indexOf(value)
44 }
45 }
46
47 observable.indexOf = function (value) {
48 if (isObservable(source) && source.indexOf) {
49 return source.indexOf(value)
50 } else if (Array.isArray(resolve(source))) {
51 return resolve(source).indexOf(value)
52 }
53 }
54
55 observable.forEach = function (fn, context) {
56 if (isObservable(source) && source.forEach) {
57 return source.forEach(fn, context)
58 } else if (Array.isArray(resolve(source))) {
59 return resolve(source).slice().forEach(fn, context)
60 }
61 }
62
63 observable.find = function (fn) {
64 if (isObservable(source) && source.find) {
65 return source.find(fn)
66 } else if (Array.isArray(resolve(source))) {
67 return resolve(source).find(fn)
68 }
69 }
70
71 observable.set = function (newSource) {
72 unlisten()
73 source = newSource
74 if (binder.live) {
75 listen()
76 }
77 binder.onUpdate()
78 }
79
80 return observable
81
82 // scoped
83
84 function listen () {
85 if (isObservable(source)) {
86 releases.push(
87 source(binder.onUpdate)
88 )
89 }
90 }
91
92 function unlisten () {
93 while (releases.length) {
94 releases.pop()()
95 }
96 }
97
98 function update () {
99 binder.value = resolve(source) || {}
100 return true
101 }
102}