MappedList.findAndUpdate

This commit is contained in:
Bruno Windels 2021-05-26 13:08:33 +02:00
parent ce7147e463
commit a5d5c55835

View File

@ -1,5 +1,6 @@
/*
Copyright 2020 Bruno Windels <bruno@windels.cloud>
Copyright 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -17,11 +18,12 @@ limitations under the License.
import {BaseObservableList} from "./BaseObservableList.js";
export class MappedList extends BaseObservableList {
constructor(sourceList, mapper, updater) {
constructor(sourceList, mapper, updater, removeCallback) {
super();
this._sourceList = sourceList;
this._mapper = mapper;
this._updater = updater;
this._removeCallback = removeCallback;
this._sourceUnsubscribe = null;
this._mappedValues = null;
}
@ -56,6 +58,9 @@ export class MappedList extends BaseObservableList {
onRemove(index) {
const mappedValue = this._mappedValues[index];
this._mappedValues.splice(index, 1);
if (this._removeCallback) {
this._removeCallback(mappedValue);
}
this.emitRemove(index, mappedValue);
}
@ -70,6 +75,21 @@ export class MappedList extends BaseObservableList {
this._sourceUnsubscribe();
}
findAndUpdate(predicate, updater) {
const index = this._mappedValues.findIndex(predicate);
if (index !== -1) {
const mappedValue = this._mappedValues[index];
// allow bailing out of sending an emit if updater determined its not needed
const params = updater(mappedValue);
if (params !== false) {
this.emitUpdate(index, mappedValue, params);
}
// found
return true;
}
return false;
}
get length() {
return this._mappedValues.length;
}
@ -79,6 +99,8 @@ export class MappedList extends BaseObservableList {
}
}
import {ObservableArray} from "./ObservableArray.js";
export async function tests() {
class MockList extends BaseObservableList {
get length() {
@ -126,6 +148,59 @@ export async function tests() {
source.emitUpdate(0, 7);
assert(fired);
unsubscribe();
},
"test findAndUpdate not found": assert => {
const source = new ObservableArray([1, 3, 4]);
const mapped = new MappedList(
source,
n => {return n*n;}
);
mapped.subscribe({
onUpdate() { assert.fail(); }
});
assert.equal(mapped.findAndUpdate(
n => n === 100,
() => assert.fail()
), false);
},
"test findAndUpdate found but updater bails out of update": assert => {
const source = new ObservableArray([1, 3, 4]);
const mapped = new MappedList(
source,
n => {return n*n;}
);
mapped.subscribe({
onUpdate() { assert.fail(); }
});
let fired = false;
assert.equal(mapped.findAndUpdate(
n => n === 9,
n => {
assert.equal(n, 9);
fired = true;
return false;
}
), true);
assert.equal(fired, true);
},
"test findAndUpdate emits update": assert => {
const source = new ObservableArray([1, 3, 4]);
const mapped = new MappedList(
source,
n => {return n*n;}
);
let fired = false;
mapped.subscribe({
onUpdate(idx, n, params) {
assert.equal(idx, 1);
assert.equal(n, 9);
assert.equal(params, "param");
fired = true;
}
});
assert.equal(mapped.findAndUpdate(n => n === 9, () => "param"), true);
assert.equal(fired, true);
},
};
}