mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
51ff72c15e
Summary: Building: - Builds no longer wait for tsc for either client, server, or test targets. All use esbuild which is very fast. - Build still runs tsc, but only to report errors. This may be turned off with `SKIP_TSC=1` env var. - Grist-core continues to build using tsc. - Esbuild requires ES6 module semantics. Typescript's esModuleInterop is turned on, so that tsc accepts and enforces correct usage. - Client-side code is watched and bundled by webpack as before (using esbuild-loader) Code changes: - Imports must now follow ES6 semantics: `import * as X from ...` produces a module object; to import functions or class instances, use `import X from ...`. - Everything is now built with isolatedModules flag. Some exports were updated for it. Packages: - Upgraded browserify dependency, and related packages (used for the distribution-building step). - Building the distribution now uses esbuild's minification. babel-minify is no longer used. Test Plan: Should have no behavior changes, existing tests should pass, and docker image should build too. Reviewers: georgegevoian Reviewed By: georgegevoian Subscribers: alexmojaki Differential Revision: https://phab.getgrist.com/D3506
97 lines
2.8 KiB
TypeScript
97 lines
2.8 KiB
TypeScript
import {ICustomWidget} from 'app/common/CustomWidget';
|
|
import log from 'app/server/lib/log';
|
|
import fetch from 'node-fetch';
|
|
import {ApiError} from 'app/common/ApiError';
|
|
import LRUCache from 'lru-cache';
|
|
|
|
/**
|
|
* Widget Repository returns list of available Custom Widgets.
|
|
*/
|
|
export interface IWidgetRepository {
|
|
getWidgets(): Promise<ICustomWidget[]>;
|
|
}
|
|
|
|
// Static url for StaticWidgetRepository
|
|
const STATIC_URL = process.env.GRIST_WIDGET_LIST_URL;
|
|
|
|
/**
|
|
* Default repository that gets list of available widgets from a static URL.
|
|
*/
|
|
export class WidgetRepositoryImpl implements IWidgetRepository {
|
|
constructor(protected _staticUrl = STATIC_URL) {}
|
|
|
|
/**
|
|
* Method exposed for testing, overrides widget url.
|
|
*/
|
|
public testOverrideUrl(url: string) {
|
|
this._staticUrl = url;
|
|
}
|
|
|
|
public async getWidgets(): Promise<ICustomWidget[]> {
|
|
if (!this._staticUrl) {
|
|
log.warn(
|
|
'WidgetRepository: Widget repository is not configured.' + !STATIC_URL
|
|
? ' Missing GRIST_WIDGET_LIST_URL environmental variable.'
|
|
: ''
|
|
);
|
|
return [];
|
|
}
|
|
try {
|
|
const response = await fetch(this._staticUrl);
|
|
if (!response.ok) {
|
|
if (response.status === 404) {
|
|
throw new ApiError('WidgetRepository: Remote widget list not found', 404);
|
|
} else {
|
|
const body = await response.text().catch(() => '');
|
|
throw new ApiError(
|
|
`WidgetRepository: Remote server returned an error: ${body || response.statusText}`, response.status
|
|
);
|
|
}
|
|
}
|
|
const widgets = await response.json().catch(() => null);
|
|
if (!widgets || !Array.isArray(widgets)) {
|
|
throw new ApiError('WidgetRepository: Error reading widget list', 500);
|
|
}
|
|
return widgets;
|
|
} catch (err) {
|
|
if (!(err instanceof ApiError)) {
|
|
throw new ApiError(String(err), 500);
|
|
}
|
|
throw err;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Version of WidgetRepository that caches successful result for 2 minutes.
|
|
*/
|
|
class CachedWidgetRepository extends WidgetRepositoryImpl {
|
|
private _cache = new LRUCache<1, ICustomWidget[]>({maxAge : 1000 * 60 /* minute */ * 2});
|
|
public async getWidgets() {
|
|
// Don't cache for localhost
|
|
if (super._staticUrl && super._staticUrl.startsWith("http://localhost")) {
|
|
this._cache.reset();
|
|
}
|
|
if (this._cache.has(1)) {
|
|
log.debug("WidgetRepository: Widget list taken from the cache.");
|
|
return this._cache.get(1)!;
|
|
}
|
|
const list = await super.getWidgets();
|
|
// Cache only if there are some widgets.
|
|
if (list.length) { this._cache.set(1, list); }
|
|
return list;
|
|
}
|
|
|
|
public testOverrideUrl(url: string) {
|
|
super.testOverrideUrl(url);
|
|
this._cache.reset();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns widget repository implementation.
|
|
*/
|
|
export function buildWidgetRepository() {
|
|
return new CachedWidgetRepository();
|
|
}
|