gristlabs_grist-core/app/common/ActionDispatcher.ts
Paul Fitzpatrick 5ef889addd (core) move home server into core
Summary: This moves enough server material into core to run a home server.  The data engine is not yet incorporated (though in manual testing it works when ported).

Test Plan: existing tests pass

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2552
2020-07-21 20:39:10 -04:00

72 lines
4.1 KiB
TypeScript

import mapValues = require('lodash/mapValues');
import {BulkColValues, ColInfo, ColInfoWithId, ColValues, DocAction} from "./DocActions";
// TODO this replaces modelUtil's ActionDispatcher and bulkActionExpand. Those should be removed.
/**
* Helper class which provides a `dispatchAction` method that dispatches DocActions received from
* the server to methods `this.on{ActionType}`, e.g. `this.onUpdateRecord`.
*
* Implementation methods `on*` are called with the action as the first argument, and with
* the action arguments as additional method arguments, for convenience.
*
* Methods for bulk actions may be implemented directly, or will iterate through each record in
* the action, and call the single-record methods for each one.
*/
export abstract class ActionDispatcher {
public dispatchAction(action: DocAction): void {
// In node 6 testing, this switch is 5+ times faster than looking up "on"+action[0].
const a: any[] = action;
switch (action[0]) {
case "AddRecord": return this.onAddRecord (action, a[1], a[2], a[3]);
case "UpdateRecord": return this.onUpdateRecord (action, a[1], a[2], a[3]);
case "RemoveRecord": return this.onRemoveRecord (action, a[1], a[2]);
case "BulkAddRecord": return this.onBulkAddRecord (action, a[1], a[2], a[3]);
case "BulkUpdateRecord": return this.onBulkUpdateRecord(action, a[1], a[2], a[3]);
case "BulkRemoveRecord": return this.onBulkRemoveRecord(action, a[1], a[2]);
case "ReplaceTableData": return this.onReplaceTableData(action, a[1], a[2], a[3]);
case "AddColumn": return this.onAddColumn (action, a[1], a[2], a[3]);
case "RemoveColumn": return this.onRemoveColumn (action, a[1], a[2]);
case "RenameColumn": return this.onRenameColumn (action, a[1], a[2], a[3]);
case "ModifyColumn": return this.onModifyColumn (action, a[1], a[2], a[3]);
case "AddTable": return this.onAddTable (action, a[1], a[2]);
case "RemoveTable": return this.onRemoveTable (action, a[1]);
case "RenameTable": return this.onRenameTable (action, a[1], a[2]);
default: throw new Error(`Received unknown action ${action[0]}`);
}
}
protected abstract onAddRecord(action: DocAction, tableId: string, rowId: number, colValues: ColValues): void;
protected abstract onUpdateRecord(action: DocAction, tableId: string, rowId: number, colValues: ColValues): void;
protected abstract onRemoveRecord(action: DocAction, tableId: string, rowId: number): void;
// If not overridden, these will make multiple calls to single-record action methods.
protected onBulkAddRecord(action: DocAction, tableId: string, rowIds: number[], colValues: BulkColValues): void {
for (let i = 0; i < rowIds.length; i++) {
this.onAddRecord(action, tableId, rowIds[i], mapValues(colValues, (values) => values[i]));
}
}
protected onBulkUpdateRecord(action: DocAction, tableId: string, rowIds: number[], colValues: BulkColValues): void {
for (let i = 0; i < rowIds.length; i++) {
this.onUpdateRecord(action, tableId, rowIds[i], mapValues(colValues, (values) => values[i]));
}
}
protected onBulkRemoveRecord(action: DocAction, tableId: string, rowIds: number[]) {
for (const r of rowIds) {
this.onRemoveRecord(action, tableId, r);
}
}
protected abstract onReplaceTableData(
action: DocAction, tableId: string, rowIds: number[], colValues: BulkColValues): void;
protected abstract onAddColumn(action: DocAction, tableId: string, colId: string, colInfo: ColInfo): void;
protected abstract onRemoveColumn(action: DocAction, tableId: string, colId: string): void;
protected abstract onRenameColumn(action: DocAction, tableId: string, oldColId: string, newColId: string): void;
protected abstract onModifyColumn(action: DocAction, tableId: string, colId: string, colInfo: ColInfo): void;
protected abstract onAddTable(action: DocAction, tableId: string, columns: ColInfoWithId[]): void;
protected abstract onRemoveTable(action: DocAction, tableId: string): void;
protected abstract onRenameTable(action: DocAction, oldTableId: string, newTableId: string): void;
}