UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

52 lines (51 loc) 2.02 kB
import { AVOID_REFRESH } from "../../store/FetchStore.js"; import { awaitDispose } from "../../util/dispose.js"; import { setMapItem } from "../../util/map.js"; import { EndpointCache } from "./EndpointCache.js"; /** * Cache of `EndpointCache` objects for multiple endpoints. * - Use `get(endpoint)` to retrieve or create the `EndpointCache` for a given endpoint, then `get(payload)` on that to get a specific `EndpointStore`. */ export class APICache { _endpoints = new Map(); provider; constructor(provider) { this.provider = provider; } _get(endpoint) { return this._endpoints.get(endpoint); } get(endpoint) { return this._get(endpoint) || setMapItem(this._endpoints, endpoint, new EndpointCache(endpoint, this.provider)); } /** * Fetch (or return a cached result) for the given endpoint and payload. * - Returns the cached value immediately if one exists. * - Waits for the in-flight fetch if the store is loading. * - Throws if the fetch fails, matching `APIProvider.call` behaviour. */ async call(endpoint, payload, maxAge = AVOID_REFRESH, caller = this.call) { return this.get(endpoint).call(payload, maxAge, caller); } /** Invalidate a specific store for an endpoint. */ invalidate(endpoint, payload) { this._get(endpoint)?.invalidate(payload); } /** Invalidate all stores for an endpoint. */ invalidateAll(endpoint) { this._get(endpoint)?.invalidateAll(); } /** Trigger a refetch on a specific store for an endpoint. */ refresh(endpoint, payload, maxAge) { this._get(endpoint)?.refresh(payload, maxAge); } /** Trigger a refetch on all stores for an endpoint. */ refreshAll(endpoint, maxAge) { this._get(endpoint)?.refreshAll(maxAge); } // Implement `AsyncDisposable` [Symbol.asyncDispose]() { return awaitDispose(...this._endpoints.values(), // Dispose all endpoints. () => this._endpoints.clear()); } }