shelving
Version:
Toolkit for using data in JavaScript.
62 lines (61 loc) • 2.46 kB
JavaScript
import { awaitValues } from "../../util/async.js";
import { awaitDispose } from "../../util/dispose.js";
import { setMapItem } from "../../util/map.js";
import { ItemStore } from "../store/ItemStore.js";
import { QueryStore } from "../store/QueryStore.js";
/**
* Cache of `ItemStore` and `QueryStore` objects for a single collection.
* - Use `getItem(id)` to retrieve or create the `ItemStore` for a given id.
* - Use `getQuery(query)` to retrieve or create the `QueryStore` for a given query.
*/
export class CollectionCache {
_items = new Map();
_queries = new Map();
collection;
provider;
memory;
constructor(collection, provider, memory) {
this.collection = collection;
this.provider = provider;
this.memory = memory;
}
/** Get (or create) the `ItemStore` for the given id. */
getItem(id) {
return this._items.get(id) || setMapItem(this._items, id, new ItemStore(this.collection, id, this.provider, this.memory));
}
/** Get (or create) the `QueryStore` for the given query. */
getQuery(query) {
const key = this._queryKey(query);
return this._queries.get(key) || setMapItem(this._queries, key, new QueryStore(this.collection, query, this.provider, this.memory));
}
/** Refresh a specific item store. */
async refreshItem(id, maxAge) {
await this._items.get(id)?.refresh(maxAge);
}
/** Refresh every cached item store. */
async refreshItems(maxAge) {
await awaitValues(...this._items.values().map(store => store.refresh(maxAge)));
}
/** Refresh a specific query store. */
async refreshQuery(query, maxAge) {
await this._queries.get(this._queryKey(query))?.refresh(maxAge);
}
/** Refresh every cached query store. */
async refreshQueries(maxAge) {
await awaitValues(...this._queries.values().map(store => store.refresh(maxAge)));
}
/** Refresh every cached store (items and queries). */
async refreshAll(maxAge) {
await awaitValues(this.refreshItems(maxAge), this.refreshQueries(maxAge));
}
_queryKey(query) {
return JSON.stringify(query);
}
// Implement `AsyncDisposable`
[Symbol.asyncDispose]() {
return awaitDispose(...this._items.values(), // Dispose all items.
...this._queries.values(), // Dispose all queries.
() => this._items.clear(), // Clear the items.
() => this._queries.clear());
}
}