git ssb

1+

Matt McKegg / mutant



Tree: bc685ac97855accf26bcdf7168da942ffcdccd1a

Files: bc685ac97855accf26bcdf7168da942ffcdccd1a / lib / lazy-watcher.js

2296 bytesRaw
1module.exports = function (update, onBind, onUnbind) {
2 var lazy = false
3 var context = this
4 var updating = false
5
6 var obj = {
7 live: false,
8 nextTick: false,
9 suspended: false,
10 update: update,
11 value: null,
12 listeners: [],
13
14 broadcast: function () {
15 if (obj.nextTick) {
16 if (!updating) {
17 updating = true
18 setImmediate(broadcast)
19 }
20 } else {
21 broadcast()
22 }
23 },
24
25 transaction: function (value, cb) {
26 var originalValue = obj.suspended
27 obj.suspended = true
28 cb(value)
29 obj.suspended = originalValue
30 obj.broadcast()
31 },
32
33 onUpdate: function () {
34 if (obj.nextTick) {
35 if (!updating) {
36 updating = true
37 setImmediate(obj.updateAndBroadcast)
38 }
39 } else {
40 obj.updateAndBroadcast()
41 }
42 },
43
44 updateAndBroadcast: function () {
45 updating = false
46 if (update.call(context)) {
47 broadcast()
48 }
49 },
50
51 checkUpdated: function () {
52 if (!obj.live || lazy || updating) {
53 lazy = false
54 if (obj.nextTick && obj.live && lazy) {
55 obj.onUpdate() // use cached value to make more responsive
56 } else {
57 update.apply(context)
58 }
59 }
60 },
61
62 getValue: function () {
63 obj.checkUpdated.apply(context)
64 return obj.value
65 },
66
67 addListener: function (listener) {
68 if (typeof listener !== 'function') {
69 throw new Error('Listeners must be functions.')
70 }
71
72 obj.listeners.push(listener)
73
74 if (!obj.live) {
75 obj.live = true
76 lazy = true
77 onBind.apply(context)
78 }
79
80 return function release () {
81 for (var i = 0, len = obj.listeners.length; i < len; i++) {
82 if (obj.listeners[i] === listener) {
83 obj.listeners.splice(i, 1)
84 break
85 }
86 }
87 if (!obj.listeners.length && obj.live) {
88 obj.live = false
89 onUnbind.apply(context)
90 }
91 }
92 }
93 }
94
95 return obj
96
97 // scoped
98
99 function broadcast () {
100 if (!obj.suspended) {
101 var cachedListeners = obj.listeners.slice(0)
102 for (var i = 0, len = cachedListeners.length; i < len; i++) {
103 cachedListeners[i](obj.value)
104 }
105 }
106 }
107}
108

Built with git-ssb-web