Add type annotations to AsyncMappedList

This commit is contained in:
Danila Fedorin 2021-09-29 19:13:38 -07:00
parent 0e6c59983f
commit 8466a910da

View File

@ -15,15 +15,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import {BaseMappedList, runAdd, runUpdate, runRemove, runMove, runReset} from "./BaseMappedList";
import {IListObserver} from "./BaseObservableList";
import {BaseMappedList, Mapper, Updater, runAdd, runUpdate, runRemove, runMove, runReset} from "./BaseMappedList";
export class AsyncMappedList extends BaseMappedList {
constructor(sourceList, mapper, updater, removeCallback) {
super(sourceList, mapper, updater, removeCallback);
this._eventQueue = null;
}
export class AsyncMappedList<F,T> extends BaseMappedList<F,T,Promise<T>> implements IListObserver<F> {
private _eventQueue: AsyncEvent<F>[] | null = null;
private _flushing: boolean = false;
onSubscribeFirst() {
onSubscribeFirst(): void {
this._sourceUnsubscribe = this._sourceList.subscribe(this);
this._eventQueue = [];
this._mappedValues = [];
@ -35,110 +34,100 @@ export class AsyncMappedList extends BaseMappedList {
this._flush();
}
async _flush() {
async _flush(): Promise<void> {
if (this._flushing) {
return;
}
this._flushing = true;
try {
while (this._eventQueue.length) {
const event = this._eventQueue.shift();
await event.run(this);
while (this._eventQueue!.length) {
const event = this._eventQueue!.shift();
await event!.run(this);
}
} finally {
this._flushing = false;
}
}
onReset() {
onReset(): void {
if (this._eventQueue) {
this._eventQueue.push(new ResetEvent());
this._flush();
}
}
onAdd(index, value) {
onAdd(index: number, value: F): void {
if (this._eventQueue) {
this._eventQueue.push(new AddEvent(index, value));
this._flush();
}
}
onUpdate(index, value, params) {
onUpdate(index: number, value: F, params: any): void {
if (this._eventQueue) {
this._eventQueue.push(new UpdateEvent(index, value, params));
this._flush();
}
}
onRemove(index) {
onRemove(index: number): void {
if (this._eventQueue) {
this._eventQueue.push(new RemoveEvent(index));
this._flush();
}
}
onMove(fromIdx, toIdx) {
onMove(fromIdx: number, toIdx: number): void {
if (this._eventQueue) {
this._eventQueue.push(new MoveEvent(fromIdx, toIdx));
this._flush();
}
}
onUnsubscribeLast() {
this._sourceUnsubscribe();
onUnsubscribeLast(): void {
this._sourceUnsubscribe!();
this._eventQueue = null;
this._mappedValues = null;
}
}
class AddEvent {
constructor(index, value) {
this.index = index;
this.value = value;
}
type AsyncEvent<F> = AddEvent<F> | UpdateEvent<F> | RemoveEvent<F> | MoveEvent<F> | ResetEvent<F>
async run(list) {
class AddEvent<F> {
constructor(public index: number, public value: F) {}
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
const mappedValue = await list._mapper(this.value);
runAdd(list, this.index, mappedValue);
}
}
class UpdateEvent {
constructor(index, value, params) {
this.index = index;
this.value = value;
this.params = params;
}
class UpdateEvent<F> {
constructor(public index: number, public value: F, public params: any) {}
async run(list) {
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
runUpdate(list, this.index, this.value, this.params);
}
}
class RemoveEvent {
constructor(index) {
this.index = index;
}
class RemoveEvent<F> {
constructor(public index: number) {}
async run(list) {
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
runRemove(list, this.index);
}
}
class MoveEvent {
constructor(fromIdx, toIdx) {
this.fromIdx = fromIdx;
this.toIdx = toIdx;
}
class MoveEvent<F> {
constructor(public fromIdx: number, public toIdx: number) {}
async run(list) {
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
runMove(list, this.fromIdx, this.toIdx);
}
}
class ResetEvent {
async run(list) {
class ResetEvent<F> {
async run<T>(list: AsyncMappedList<F,T>): Promise<void> {
runReset(list);
}
}
@ -150,7 +139,7 @@ export function tests() {
return {
"events are emitted in order": async assert => {
const double = n => n * n;
const source = new ObservableArray();
const source = new ObservableArray<number>();
const mapper = new AsyncMappedList(source, async n => {
await new Promise(r => setTimeout(r, n));
return {n: double(n)};