1 | var LazyWatcher = require('./lib/lazy-watcher')
|
2 | var resolve = require('./resolve')
|
3 | var isObservable = require('./is-observable')
|
4 |
|
5 | module.exports = ProxyCollection
|
6 |
|
7 | function 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 |
|
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 | }
|