Commit 540184c1 authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Migrate APIRoutesService to TS

parent 15d64695
import type {
IndexResponse,
LinksResponse,
RouteMap,
RouteMetadata,
} from '../../types/api';
import type { SidebarSettings } from '../../types/config';
import { fetchJSON } from '../util/fetch'; import { fetchJSON } from '../util/fetch';
import { retryPromiseOperation } from '../util/retry'; import { retryPromiseOperation } from '../util/retry';
/** /**
* Fetch an API metadata file, retrying the operation if it fails. * Fetch an API metadata file, retrying the operation if it fails.
*
* @param {string} url
*/ */
function getJSON(url) { function getJSON<T>(url: string): Promise<T> {
return retryPromiseOperation(() => return retryPromiseOperation(
() =>
// nb. The `/api/` and `/api/links` routes are fetched without specifying // nb. The `/api/` and `/api/links` routes are fetched without specifying
// any additional headers/config so that we can use `<link rel="preload">` in // any additional headers/config so that we can use `<link rel="preload">` in
// the `/app.html` response to fetch them early, while the client JS app // the `/app.html` response to fetch them early, while the client JS app
// is loading. // is loading.
fetchJSON(url) fetchJSON(url) as Promise<T>
); );
} }
/**
* @typedef {import('../../types/api').IndexResponse} IndexResponse
* @typedef {import('../../types/api').LinksResponse} LinksResponse
* @typedef {import('../../types/api').RouteMap} RouteMap
* @typedef {import('../../types/api').RouteMetadata} RouteMetadata
* @typedef {import('../../types/config').SidebarSettings} SidebarSettings
*/
/** /**
* A service which fetches and caches API route metadata. * A service which fetches and caches API route metadata.
*/ */
// @inject // @inject
export class APIRoutesService { export class APIRoutesService {
/** private _apiURL: SidebarSettings['apiUrl'];
* @param {SidebarSettings} settings private _routeCache: Promise<RouteMap> | null;
*/ private _linkCache: Promise<LinksResponse> | null;
constructor(settings) {
this._apiURL = settings.apiUrl;
/** @type {Promise<RouteMap>|null} */ constructor(settings: SidebarSettings) {
this._apiURL = settings.apiUrl;
this._routeCache = null; this._routeCache = null;
/** @type {Promise<LinksResponse>|null} */
this._linkCache = null; this._linkCache = null;
} }
...@@ -48,29 +43,25 @@ export class APIRoutesService { ...@@ -48,29 +43,25 @@ export class APIRoutesService {
* Routes are fetched without any authentication and therefore assumed to be * Routes are fetched without any authentication and therefore assumed to be
* the same regardless of whether the user is authenticated or not. * the same regardless of whether the user is authenticated or not.
* *
* @return {Promise<RouteMap>} - Map of routes to route metadata. * @return Map of routes to route metadata.
*/ */
routes() { routes(): Promise<RouteMap> {
if (!this._routeCache) { if (!this._routeCache) {
this._routeCache = getJSON(this._apiURL).then(result => { this._routeCache = getJSON<IndexResponse>(this._apiURL).then(
const index = /** @type {IndexResponse} */ (result); result => result.links
return index.links; );
});
} }
return this._routeCache; return this._routeCache;
} }
/** /**
* Fetch and cache service page links from the API. * Fetch and cache service page links from the API.
*
* @return {Promise<LinksResponse>}
*/ */
links() { links(): Promise<LinksResponse> {
if (!this._linkCache) { if (!this._linkCache) {
this._linkCache = this.routes().then(async routes => { this._linkCache = this.routes().then(async routes => {
const linksRoute = /** @type {RouteMetadata} */ (routes.links); const linksRoute = routes.links as RouteMetadata;
const links = await getJSON(linksRoute.url); return getJSON<LinksResponse>(linksRoute.url);
return /** @type {LinksResponse} */ (links);
}); });
} }
return this._linkCache; return this._linkCache;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment