2020-08-05 22:08:55 +05:30
|
|
|
/*
|
|
|
|
Copyright 2020 Bruno Windels <bruno@windels.cloud>
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2020-04-21 00:56:39 +05:30
|
|
|
import {BaseObservableMap} from "./BaseObservableMap.js";
|
2019-02-21 04:18:16 +05:30
|
|
|
|
2020-04-21 00:56:39 +05:30
|
|
|
export class ObservableMap extends BaseObservableMap {
|
2019-02-27 01:43:11 +05:30
|
|
|
constructor(initialValues) {
|
2019-02-21 04:18:16 +05:30
|
|
|
super();
|
|
|
|
this._values = new Map(initialValues);
|
|
|
|
}
|
|
|
|
|
|
|
|
update(key, params) {
|
|
|
|
const value = this._values.get(key);
|
|
|
|
if (value !== undefined) {
|
2019-02-24 23:54:28 +05:30
|
|
|
// could be the same value, so it's already updated
|
|
|
|
// but we don't assume this here
|
|
|
|
this._values.set(key, value);
|
|
|
|
this.emitUpdate(key, value, params);
|
2019-02-21 04:18:16 +05:30
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false; // or return existing value?
|
|
|
|
}
|
|
|
|
|
|
|
|
add(key, value) {
|
|
|
|
if (!this._values.has(key)) {
|
2019-02-24 23:54:28 +05:30
|
|
|
this._values.set(key, value);
|
2019-02-21 04:18:16 +05:30
|
|
|
this.emitAdd(key, value);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false; // or return existing value?
|
|
|
|
}
|
|
|
|
|
|
|
|
remove(key) {
|
|
|
|
const value = this._values.get(key);
|
|
|
|
if (value !== undefined) {
|
|
|
|
this._values.delete(key);
|
|
|
|
this.emitRemove(key, value);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-22 13:33:26 +05:30
|
|
|
set(key, value) {
|
|
|
|
if (this._values.has(key)) {
|
|
|
|
// We set the value here because update only supports inline updates
|
|
|
|
this._values.set(key, value);
|
|
|
|
return this.update(key);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return this.add(key, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-21 04:18:16 +05:30
|
|
|
reset() {
|
|
|
|
this._values.clear();
|
|
|
|
this.emitReset();
|
|
|
|
}
|
|
|
|
|
|
|
|
get(key) {
|
|
|
|
return this._values.get(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
get size() {
|
|
|
|
return this._values.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Symbol.iterator]() {
|
2019-02-24 23:54:28 +05:30
|
|
|
return this._values.entries();
|
|
|
|
}
|
2020-08-31 17:41:08 +05:30
|
|
|
|
|
|
|
values() {
|
|
|
|
return this._values.values();
|
|
|
|
}
|
2021-06-03 22:43:13 +05:30
|
|
|
|
|
|
|
keys() {
|
|
|
|
return this._values.keys();
|
|
|
|
}
|
2019-02-24 23:54:28 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
export function tests() {
|
|
|
|
return {
|
2019-02-27 01:43:11 +05:30
|
|
|
test_initial_values(assert) {
|
|
|
|
const map = new ObservableMap([
|
|
|
|
["a", 5],
|
|
|
|
["b", 10]
|
|
|
|
]);
|
|
|
|
assert.equal(map.size, 2);
|
|
|
|
assert.equal(map.get("a"), 5);
|
|
|
|
assert.equal(map.get("b"), 10);
|
|
|
|
},
|
|
|
|
|
2019-02-24 23:54:28 +05:30
|
|
|
test_add(assert) {
|
|
|
|
let fired = 0;
|
|
|
|
const map = new ObservableMap();
|
|
|
|
map.subscribe({
|
|
|
|
onAdd(key, value) {
|
|
|
|
fired += 1;
|
|
|
|
assert.equal(key, 1);
|
|
|
|
assert.deepEqual(value, {value: 5});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
map.add(1, {value: 5});
|
|
|
|
assert.equal(map.size, 1);
|
|
|
|
assert.equal(fired, 1);
|
|
|
|
},
|
|
|
|
|
|
|
|
test_update(assert) {
|
|
|
|
let fired = 0;
|
|
|
|
const map = new ObservableMap();
|
|
|
|
const value = {number: 5};
|
|
|
|
map.add(1, value);
|
|
|
|
map.subscribe({
|
|
|
|
onUpdate(key, value, params) {
|
|
|
|
fired += 1;
|
|
|
|
assert.equal(key, 1);
|
|
|
|
assert.deepEqual(value, {number: 6});
|
|
|
|
assert.equal(params, "test");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
value.number = 6;
|
|
|
|
map.update(1, "test");
|
|
|
|
assert.equal(fired, 1);
|
|
|
|
},
|
|
|
|
|
|
|
|
test_update_unknown(assert) {
|
|
|
|
let fired = 0;
|
2019-02-27 01:43:11 +05:30
|
|
|
const map = new ObservableMap();
|
2019-02-24 23:54:28 +05:30
|
|
|
map.subscribe({
|
|
|
|
onUpdate() { fired += 1; }
|
|
|
|
});
|
|
|
|
const result = map.update(1);
|
|
|
|
assert.equal(fired, 0);
|
|
|
|
assert.equal(result, false);
|
|
|
|
},
|
|
|
|
|
2021-06-22 13:33:26 +05:30
|
|
|
test_set(assert) {
|
|
|
|
let add_fired = 0, update_fired = 0;
|
|
|
|
const map = new ObservableMap();
|
|
|
|
map.subscribe({
|
|
|
|
onAdd(key, value) {
|
|
|
|
add_fired += 1;
|
|
|
|
assert.equal(key, 1);
|
|
|
|
assert.deepEqual(value, {value: 5});
|
|
|
|
},
|
|
|
|
onUpdate(key, value, params) {
|
|
|
|
update_fired += 1;
|
|
|
|
assert.equal(key, 1);
|
|
|
|
assert.deepEqual(value, {value: 7});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// Add
|
|
|
|
map.set(1, {value: 5});
|
|
|
|
assert.equal(map.size, 1);
|
|
|
|
assert.equal(add_fired, 1);
|
|
|
|
// Update
|
|
|
|
map.set(1, {value: 7});
|
|
|
|
assert.equal(map.size, 1);
|
|
|
|
assert.equal(update_fired, 1);
|
|
|
|
},
|
|
|
|
|
2019-02-24 23:54:28 +05:30
|
|
|
test_remove(assert) {
|
|
|
|
let fired = 0;
|
|
|
|
const map = new ObservableMap();
|
|
|
|
const value = {value: 5};
|
|
|
|
map.add(1, value);
|
|
|
|
map.subscribe({
|
|
|
|
onRemove(key, value) {
|
|
|
|
fired += 1;
|
|
|
|
assert.equal(key, 1);
|
|
|
|
assert.deepEqual(value, {value: 5});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
map.remove(1);
|
|
|
|
assert.equal(map.size, 0);
|
|
|
|
assert.equal(fired, 1);
|
|
|
|
},
|
|
|
|
|
|
|
|
test_iterate(assert) {
|
|
|
|
const results = [];
|
|
|
|
const map = new ObservableMap();
|
|
|
|
map.add(1, {number: 5});
|
|
|
|
map.add(2, {number: 6});
|
|
|
|
map.add(3, {number: 7});
|
|
|
|
for (let e of map) {
|
|
|
|
results.push(e);
|
|
|
|
}
|
|
|
|
assert.equal(results.length, 3);
|
|
|
|
assert.equal(results.find(([key]) => key === 1)[1].number, 5);
|
|
|
|
assert.equal(results.find(([key]) => key === 2)[1].number, 6);
|
|
|
|
assert.equal(results.find(([key]) => key === 3)[1].number, 7);
|
|
|
|
},
|
|
|
|
test_size(assert) {
|
|
|
|
const map = new ObservableMap();
|
|
|
|
map.add(1, {number: 5});
|
|
|
|
map.add(2, {number: 6});
|
|
|
|
assert.equal(map.size, 2);
|
|
|
|
},
|
2019-02-21 04:18:16 +05:30
|
|
|
}
|
|
|
|
}
|