##// END OF EJS Templates
Fixed scheduleRender context restoration
Fixed scheduleRender context restoration

File last commit:

r120:bc1b4dd8ca1a v1.6.2 default
r122:fb2ea4d6aaba v1.6.3 default
Show More
store.ts
58 lines | 2.1 KiB | video/mp2t | TypeScriptLexer
import { PromiseOrValue } from "@implab/core-amd/interfaces";
import { isPromise } from "@implab/core-amd/safe";
import { observe, Observable } from "./observable";
export interface OrderedUpdate<T> {
/** The item is being updated */
readonly item: T;
/** The previous index of the item, -1 in case it is inserted */
readonly prevIndex: number;
/** The new index of the item, -1 in case it is deleted */
readonly newIndex: number;
}
export type QueryResults<T> = Observable<OrderedUpdate<T>>;
interface DjObservableResults<T> {
/**
* Allows observation of results
*/
observe(listener: (object: T, previousIndex: number, newIndex: number) => void, includeUpdates?: boolean): {
remove(): void;
};
}
interface Queryable<T, Q, O> {
query(query?: Q, options?: O): PromiseOrValue<T[]>;
}
export const isDjObservableResults = <T>(v: object): v is DjObservableResults<T> =>
v && (typeof (v as { observe?: unknown; }).observe === "function");
export const query = <T, Q, O>(store: Queryable<T, Q, O>, includeUpdates = true) =>
(query?: Q, options?: O & { observe?: boolean }) => {
return observe<OrderedUpdate<T>>(({ next, complete, error, isClosed }) => {
try {
const results = store.query(query, options);
if (isPromise(results)) {
results.then(items => items.forEach((item, newIndex) => next({ item, newIndex, prevIndex: -1 })))
.then(undefined, error);
} else {
results.forEach((item, newIndex) => next({ item, newIndex, prevIndex: -1 }));
}
if (!isClosed() && (options?.observe !== false) && isDjObservableResults<T>(results)) {
const h = results.observe((item, prevIndex, newIndex) => next({ item, prevIndex, newIndex }), includeUpdates);
return () => h.remove();
} else {
complete();
}
} catch (err) {
error(err);
}
});
};