(core) Speed up and upgrade build.

Summary:
- Upgrades to build-related packages:
  - Upgrade typescript, related libraries and typings.
  - Upgrade webpack, eslint; add tsc-watch, node-dev, eslint_d.

- Build organization changes:
  - Build webpack from original typescript, transpiling only; with errors still
    reported by a background tsc watching process.

- Typescript-related changes:
  - Reduce imports of AWS dependencies (very noticeable speedup)
  - Avoid auto-loading global @types
  - Client code is now built with isolatedModules flag (for safe transpilation)
  - Use allowJs to avoid copying JS files manually.

- Linting changes
  - Enhance Arcanist ESLintLinter to run before/after commands, and set up to use eslint_d
  - Update eslint config, and include .eslintignore to avoid linting generated files.
  - Include a bunch of eslint-prompted and eslint-generated fixes
  - Add no-unused-expression rule to eslint, and fix a few warnings about it

- Other items:
  - Refactor cssInput to avoid circular dependency
  - Remove a bit of unused code, libraries, dependencies

Test Plan: No behavior changes, all existing tests pass. There are 30 tests fewer reported because `test_gpath.py` was removed (it's been unused for years)

Reviewers: paulfitz

Reviewed By: paulfitz

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D3498
This commit is contained in:
Dmitry S
2022-06-27 16:09:41 -04:00
parent 64ff9ccd0a
commit dd2eadc86e
45 changed files with 948 additions and 2442 deletions

View File

@@ -18,33 +18,6 @@ declare module "bluebird" {
class Disposer<T> {}
}
// TODO This is a module by Grist Labs; we should add index.d.ts to it.
declare module "@gristlabs/basket-api" {
interface Item { [colId: string]: any; }
interface ColValues { [colId: string]: any[]; }
interface AuthToken { [authProvider: string]: string; }
class Basket {
public static addBasket(login: AuthToken): Promise<string>;
public static getBaskets(login: AuthToken): Promise<string[]>;
public basketId: Readonly<string>;
public apiKey: Readonly<string|undefined>;
constructor(basketId: string, apiKey?: string);
public addTable(optTableId: string): Promise<string>;
public getTable(tableId: string): Promise<Item[]>;
public renameTable(oldTableId: string, newTableId: string): Promise<void>;
public replaceTableData(tableId: string, columnValues: ColValues): Promise<void>;
public deleteTable(tableId: string): Promise<void>;
public getTables(): Promise<string[]>;
public uploadAttachment(attachmentId: string, attachment: Buffer): Promise<void>;
public delete(login: AuthToken): Promise<void>;
}
namespace Basket {}
export = Basket;
}
// Used in one place, and the typings are almost entirely unhelpful.
declare module "multiparty";

View File

@@ -49,7 +49,7 @@ import {
adaptServerUrl, addOrgToPath, addPermit, getOrgUrl, getOriginUrl, getScope, optStringParam,
RequestWithGristInfo, stringParam, TEST_HTTPS_OFFSET, trustOrigin} from 'app/server/lib/requestUtils';
import {ISendAppPageOptions, makeGristConfig, makeMessagePage, makeSendAppPage} from 'app/server/lib/sendAppPage';
import {getDatabaseUrl} from 'app/server/lib/serverUtils';
import {getDatabaseUrl, listenPromise} from 'app/server/lib/serverUtils';
import {Sessions} from 'app/server/lib/Sessions';
import * as shutdown from 'app/server/lib/shutdown';
import {TagChecker} from 'app/server/lib/TagChecker';
@@ -1666,14 +1666,11 @@ export class FlexServer implements GristServer {
private async _startServers(server: http.Server, httpsServer: https.Server|undefined,
name: string, port: number, verbose: boolean) {
await new Promise((resolve, reject) => server.listen(port, this.host, resolve).on('error', reject));
await listenPromise(server.listen(port, this.host));
if (verbose) { log.info(`${name} available at ${this.host}:${port}`); }
if (TEST_HTTPS_OFFSET && httpsServer) {
const httpsPort = port + TEST_HTTPS_OFFSET;
await new Promise((resolve, reject) => {
httpsServer.listen(httpsPort, this.host, resolve)
.on('error', reject);
});
await listenPromise(httpsServer.listen(httpsPort, this.host));
if (verbose) { log.info(`${name} available at https://${this.host}:${httpsPort}`); }
}
}

View File

@@ -1,5 +1,6 @@
export interface INotifier {
deleteUser(userId: number): Promise<void>;
// for test purposes, check if any notifications are in progress
readonly testPending: boolean;
deleteUser(userId: number): Promise<void>;
}

View File

@@ -125,16 +125,16 @@ export class NSandbox implements ISandbox {
if (options.minimalPipeMode) {
log.rawDebug("3-pipe Sandbox started", this._logMeta);
this._streamToSandbox = this.childProc.stdin;
this._streamFromSandbox = this.childProc.stdout;
this._streamToSandbox = this.childProc.stdin!;
this._streamFromSandbox = this.childProc.stdout!;
} else {
log.rawDebug("5-pipe Sandbox started", this._logMeta);
this._streamToSandbox = (this.childProc.stdio as Stream[])[3] as Writable;
this._streamFromSandbox = (this.childProc.stdio as Stream[])[4];
this.childProc.stdout.on('data', sandboxUtil.makeLinePrefixer('Sandbox stdout: ', this._logMeta));
this.childProc.stdout!.on('data', sandboxUtil.makeLinePrefixer('Sandbox stdout: ', this._logMeta));
}
const sandboxStderrLogger = sandboxUtil.makeLinePrefixer('Sandbox stderr: ', this._logMeta);
this.childProc.stderr.on('data', data => {
this.childProc.stderr!.on('data', data => {
this._lastStderr = data;
sandboxStderrLogger(data);
});

View File

@@ -16,7 +16,7 @@ import {IMsgCustom, IMsgRpcCall} from 'grain-rpc';
*/
export class SafePythonComponent extends BaseComponent {
private _sandbox: ISandbox;
private _sandbox?: ISandbox;
private _logMeta: log.ILogMeta;
// safe python component does not need pluginInstance.rpc because it is not possible to forward

View File

@@ -118,7 +118,7 @@ export class DocTriggers {
public shutdown() {
this._shuttingDown = true;
if (!this._sending) {
this._redisClientField?.quitAsync();
void(this._redisClientField?.quitAsync());
}
}

View File

@@ -121,8 +121,8 @@ export class UnsafeNodeComponent extends BaseComponent {
.catch(err => log.warn("unsafeNode[%s] failed with %s", child.pid, err))
.then(() => { this._child = undefined; });
child.stdout.on('data', makeLinePrefixer('PLUGIN stdout: '));
child.stderr.on('data', makeLinePrefixer('PLUGIN stderr: '));
child.stdout!.on('data', makeLinePrefixer('PLUGIN stdout: '));
child.stderr!.on('data', makeLinePrefixer('PLUGIN stderr: '));
warnIfNotReady(this._rpc, 3000, "Plugin isn't ready; be sure to call grist.ready() from plugin");
child.on('message', this._rpc.receiveMessage.bind(this._rpc));

View File

@@ -63,6 +63,13 @@ export function connect(arg: any, ...moreArgs: any[]): Promise<net.Socket> {
});
}
/**
* Promisified version of net.Server.listen().
*/
export function listenPromise<T extends net.Server>(server: T): Promise<void> {
return new Promise<void>((resolve, reject) => server.once('listening', resolve).once('error', reject));
}
/**
* Returns whether the path `inner` is contained within the directory `outer`.
*/