git ssb

1+

Matt McKegg / mutant



Commit 4c817e4a9ce3c28a60cc7547029ee43eb9d9f909

fix bugs and cleanup array, concat, dict

Matt McKegg committed on 9/10/2016, 6:20:37 AM
Parent: 9ddfe1a36b770dd913a4f5649543b64785ffd4cc

Files changed

array.jschanged
concat.jschanged
dict.jschanged
array.jsView
@@ -1,15 +1,21 @@
1+var Value = require('./value')
12 var LazyWatcher = require('./lib/lazy-watcher')
2-var isReferenceType = require('./lib/is-reference-type')
3+var isSame = require('./lib/is-same')
4+var isObservable = require('./is-observable')
35 var resolve = require('./resolve')
6+var addCollectionMethods = require('./lib/add-collection-methods')
47
58 module.exports = Array
69
7-function Array (defaultValues) {
10+function Array (defaultValues, opts) {
811 var object = []
912 var sources = []
1013 var releases = []
14+ var fixedIndexing = opts && opts.fixedIndexing || false
1115
16+ var comparer = opts && opts.comparer || null
17+
1218 var binder = LazyWatcher(update, listen, unlisten)
1319 binder.value = object
1420
1521 if (defaultValues && defaultValues.length) {
@@ -22,46 +28,48 @@
2228 }
2329 return binder.addListener(listener)
2430 }
2531
26- observable.push = function (args) {
27- for (var i = 0; i < arguments.length; i++) {
28- add(arguments[i])
32+ // getLength, get, indexOf, etc
33+ addCollectionMethods(observable, sources)
34+
35+ observable.push = function (item) {
36+ var result = null
37+ if (arguments.length === 1) {
38+ result = add(item)
39+ } else {
40+ result = []
41+ for (var i = 0; i < arguments.length; i++) {
42+ result.push(add(arguments[i]))
43+ }
2944 }
3045 binder.broadcast()
46+ return result
3147 }
3248
49+ observable.put = function (index, valueOrObs) {
50+ valueOrObs = getObsValue(valueOrObs)
51+ sources[index] = valueOrObs
52+ object[index] = resolve(valueOrObs)
53+ if (binder.live) {
54+ tryInvoke(releases[index])
55+ releases[index] = bind(valueOrObs)
56+ }
57+ binder.broadcast()
58+ return valueOrObs
59+ }
60+
3361 observable.insert = function (valueOrObs, at) {
62+ valueOrObs = getObsValue(valueOrObs)
3463 sources.splice(at, 0, valueOrObs)
3564 if (binder.live) releases.splice(at, 0, bind(valueOrObs))
3665 object.splice(at, 0, resolve(valueOrObs))
3766 binder.broadcast()
67+ return valueOrObs
3868 }
3969
40- observable.get = function (index) {
41- return sources[index]
42- }
4370
44- observable.getLength = function (index) {
45- return sources.length
46- }
4771
48- observable.includes = function (valueOrObs) {
49- return !!~sources.indexOf(valueOrObs)
50- }
51-
52- observable.indexOf = function (valueOrObs) {
53- return sources.indexOf(valueOrObs)
54- }
55-
56- observable.forEach = function (fn, context) {
57- sources.slice().forEach(fn, context)
58- }
59-
60- observable.find = function (fn) {
61- return sources.find(fn)
62- }
63-
6472 observable.indexOf
6573
6674 observable.pop = function () {
6775 var result = sources.pop()
@@ -87,39 +95,74 @@
8795 binder.broadcast()
8896 }
8997
9098 observable.delete = function (valueOrObs) {
91- var index = sources.indexOf(valueOrObs)
92- if (~index) {
99+ observable.deleteAt(sources.indexOf(valueOrObs))
100+ }
101+
102+ observable.deleteAt = function (index) {
103+ if (index >= 0 && index < sources.length) {
93104 sources.splice(index, 1)
94105 if (binder.live) releases.splice(index, 1).forEach(tryInvoke)
95106 object.splice(index, 1)
96107 binder.broadcast()
97108 }
98109 }
99110
100111 observable.set = function (values) {
101- unlisten()
102- sources.length = 0
103- releases.length = 0
104- object.length = 0
105- values.forEach(add)
106- if (binder.live) {
107- listen()
112+ if (fixedIndexing) {
113+ var length = values && values.length || 0
114+ for (var i = 0; i < length; i++) {
115+ if (!sources[i]) {
116+ var valueOrObs = getObsValue(values[i])
117+ sources[i] = valueOrObs
118+ object[i] = resolve(valueOrObs)
119+ if (binder.live) {
120+ releases[i] = bind(valueOrObs)
121+ }
122+ } else {
123+ sources[i].set(values[i])
124+ }
125+ }
126+ for (var index = length; index < sources.length; index++) {
127+ tryInvoke(releases[index])
128+ }
129+ releases.length = length
130+ sources.length = length
131+ object.length = length
108132 binder.broadcast()
133+ } else {
134+ unlisten()
135+ sources.length = 0
136+ releases.length = 0
137+ object.length = 0
138+ values.forEach(add)
139+ if (binder.live) {
140+ listen()
141+ binder.broadcast()
142+ }
109143 }
110144 }
111145
112146 return observable
113147
114148 // scoped
115149
150+ function getObsValue (valueOrObs) {
151+ if (fixedIndexing && !isObservable(valueOrObs)) {
152+ valueOrObs = Value(valueOrObs)
153+ }
154+ return valueOrObs
155+ }
156+
116157 function add (valueOrObs) {
158+ valueOrObs = getObsValue(valueOrObs)
117159 sources.push(valueOrObs)
160+ object.push(resolve(valueOrObs))
118161 if (binder.live) {
119162 releases.push(bind(valueOrObs))
120163 }
121- object.push(resolve(valueOrObs))
164+ return valueOrObs
122165 }
123166
124167 function bind (valueOrObs) {
125168 return typeof valueOrObs === 'function' ? valueOrObs(binder.onUpdate) : null
@@ -137,11 +180,11 @@
137180 }
138181
139182 function update () {
140183 var changed = false
141- sources.forEach(function (key, i) {
142- var newValue = resolve(observable[key])
143- if (newValue !== object[i] || isReferenceType(newValue)) {
184+ sources.forEach(function (source, i) {
185+ var newValue = resolve(source)
186+ if (!isSame(newValue, object[i], comparer)) {
144187 object[i] = newValue
145188 changed = true
146189 }
147190 })
concat.jsView
@@ -1,52 +1,44 @@
1+var resolve = require('./resolve')
2+var addCollectionMethods = require('./lib/add-collection-methods')
13 var computed = require('./computed')
24
35 module.exports = function Concat (observables) {
46 var values = []
57 var rawValues = []
68
7- var result = computed(observables, function (args) {
9+ var instance = computed.extended(observables, function () {
810 var index = 0
9- for (var i = 0; i < arguments.length; i++) {
10- for (var x = 0; x < arguments[i].length; x++) {
11- var value = arguments[i][x]
12- var raw = get(observables[i], x)
11+
12+ forEach(observables, function (collection) {
13+ forEach(collection, function (item) {
14+ var value = resolve(item)
1315 values[index] = value
14- rawValues[index] = raw
16+ rawValues[index] = item
1517 index += 1
16- }
17- }
18+ })
19+ })
20+
1821 values.length = index
1922 rawValues.length = index
2023 return values
2124 })
2225
23- result.get = function (index) {
24- return rawValues[index]
26+ var result = function MutantConcat (listener) {
27+ return instance(listener)
2528 }
2629
27- result.getLength = function (index) {
28- return rawValues.length
29- }
30+ // getLength, get, indexOf, etc
31+ addCollectionMethods(result, rawValues, instance.checkUpdated)
3032
31- result.includes = function (valueOrObs) {
32- return !!~rawValues.indexOf(valueOrObs)
33- }
34-
35- result.indexOf = function (valueOrObs) {
36- return rawValues.indexOf(valueOrObs)
37- }
38-
3933 return result
4034 }
4135
42-function get (target, index) {
43- if (typeof target === 'function' && !target.get) {
44- target = target()
36+function forEach (sources, fn) {
37+ if (sources && !sources.forEach) {
38+ sources = resolve(sources)
4539 }
4640
47- if (Array.isArray(target)) {
48- return target[index]
49- } else if (target && target.get) {
50- return target.get(index)
41+ if (sources && sources.forEach) {
42+ sources.forEach(fn)
5143 }
5244 }
dict.jsView
@@ -1,17 +1,22 @@
1+var Value = require('./value')
12 var LazyWatcher = require('./lib/lazy-watcher')
2-var isReferenceType = require('./lib/is-reference-type')
3+var isSame = require('./lib/is-same')
34 var resolve = require('./resolve')
5+var isObservable = require('./is-observable')
46
57 // TODO: reimplement using LazyWatcher
68
79 module.exports = Dict
810
9-function Dict (defaultValues) {
11+function Dict (defaultValues, opts) {
1012 var object = Object.create({})
1113 var sources = []
1214 var releases = []
15+ var fixedIndexing = opts && opts.fixedIndexing || false
1316
17+ var comparer = opts && opts.comparer || null
18+
1419 var binder = LazyWatcher(update, listen, unlisten)
1520 binder.value = object
1621
1722 if (defaultValues) {
@@ -27,10 +32,12 @@
2732 return binder.addListener(listener)
2833 }
2934
3035 observable.put = function (key, valueOrObs) {
36+ valueOrObs = getObsValue(valueOrObs)
3137 put(key, valueOrObs)
3238 binder.broadcast()
39+ return valueOrObs
3340 }
3441
3542 observable.get = function (key) {
3643 return sources[key]
@@ -62,26 +69,53 @@
6269 return !!~object.indexOf(valueOrObs)
6370 }
6471
6572 observable.set = function (values) {
66- Object.keys(sources).forEach(function (key) {
67- tryInvoke(releases[key])
68- delete sources[key]
69- delete releases[key]
70- delete object[key]
71- })
73+ var keys = values && Object.keys(values) || []
74+ if (fixedIndexing) {
75+ keys.forEach(function (key) {
76+ if (sources[key]) {
77+ sources[key].set(values[key])
78+ } else {
79+ put(key, getObsValue(values[key]))
80+ }
81+ })
7282
73- Object.keys(values).forEach(function (key) {
74- put(key, values[key])
75- })
83+ Object.keys(sources).forEach(function (key) {
84+ if (!keys.includes(key)) {
85+ tryInvoke(releases[key])
86+ delete sources[key]
87+ delete releases[key]
88+ delete object[key]
89+ }
90+ })
91+ } else {
92+ Object.keys(sources).forEach(function (key) {
93+ tryInvoke(releases[key])
94+ delete sources[key]
95+ delete releases[key]
96+ delete object[key]
97+ })
7698
77- binder.broadcast()
99+ keys.forEach(function (key) {
100+ put(key, values[key])
101+ })
102+
103+ binder.broadcast()
104+ }
78105 }
79106
80107 return observable
81108
82109 // scoped
83110
111+ function getObsValue (valueOrObs) {
112+ if (fixedIndexing && !isObservable(valueOrObs)) {
113+ valueOrObs = Value(valueOrObs)
114+ }
115+ return valueOrObs
116+ }
117+
84118 function put (key, valueOrObs) {
85119 tryInvoke(releases[key])
86120 sources[key] = valueOrObs
87121 if (binder.live) {
@@ -115,9 +149,9 @@
115149 function update () {
116150 var changed = false
117151 Object.keys(sources).forEach(function (key) {
118152 var newValue = resolve(sources[key])
119- if (newValue !== object[key] || isReferenceType(newValue)) {
153+ if (!isSame(newValue, object[key], comparer)) {
120154 object[key] = newValue
121155 changed = true
122156 }
123157 })

Built with git-ssb-web