Skip to content

Commit

Permalink
Bump dependencies, move result metadata into main storage, store curr…
Browse files Browse the repository at this point in the history
…ent page in localstorage (#41)

* Upgrade for xmldom fixes

* Fix for axios

* Move oracle to optional

* Store results directly in panel

* Move results into regular storage since values are stored separately on disk

* Add current page to localstorage, fixes for when resultMeta isnt present
  • Loading branch information
eatonphil authored Sep 9, 2021
1 parent a59599a commit 32b84a1
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 162 deletions.
13 changes: 8 additions & 5 deletions desktop/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import fs from 'fs';
import fsPromises from 'fs/promises';
import path from 'path';
import log from '../shared/log';
import { IDDict, ProjectState } from '../shared/state';
import { ProjectState } from '../shared/state';
import { DISK_ROOT, PROJECT_EXTENSION, SYNC_PERIOD } from './constants';

const buffers: IDDict<{
contents: string;
timeout: ReturnType<typeof setTimeout>;
}> = {};
const buffers: Record<
string,
{
contents: string;
timeout: ReturnType<typeof setTimeout>;
}
> = {};
export function writeFileBuffered(name: string, contents: string) {
if (buffers[name]) {
clearTimeout(buffers[name].timeout);
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"mssql": "^7.2.1",
"mysql2": "^2.2.5",
"node-fetch": "^2.6.1",
"oracledb": "^5.2.0",
"pako": "^2.0.3",
"papaparse": "^5.3.1",
"parquetjs-lite": "^0.8.7",
Expand All @@ -49,6 +48,9 @@
"uuid": "^8.3.2",
"xlsx": "^0.17.0"
},
"optionalDependencies": {
"oracledb": "^5.2.0"
},
"devDependencies": {
"@types/electron": "^1.6.10",
"@types/jsesc": "^3.0.1",
Expand Down Expand Up @@ -80,6 +82,8 @@
"resolutions": {
"node-gyp": "^5.0.2",
"plist": "^3.0.4",
"tar": "^4.4.18"
"tar": "^4.4.18",
"adal-node": "^0.2.3",
"axios": "^0.21.4"
}
}
149 changes: 78 additions & 71 deletions shared/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Shape } from 'shape';
import * as uuid from 'uuid';
import { VERSION } from './constants';
import { SupportedLanguages } from './languages';
import log from './log';
import { mergeDeep } from './object';

export class PanelResult {
Expand Down Expand Up @@ -32,10 +31,19 @@ export class PanelResultMeta extends PanelResult {
this.lastRun = null;
this.loading = false;
}
}

export type IDDict<T> = { [k: string]: T };
export type PanelResults = IDDict<Array<PanelResultMeta>>;
static fromJSON(raw: any): PanelResultMeta {
const prm = mergeDeep(new PanelResultMeta(), raw);
if (!raw) {
return prm;
}
prm.lastRun =
typeof raw.lastRun === 'string'
? new Date(raw.lastRun)
: raw.lastRun || prm.lastRun;
return prm;
}
}

export type ServerInfoType = 'ssh-agent' | 'password' | 'private-key';

Expand Down Expand Up @@ -70,6 +78,10 @@ export class ServerInfo {
this.passphrase = passphrase || '';
this.id = uuid.v4();
}

static fromJSON(raw: any): ServerInfo {
return mergeDeep(new ServerInfo(), raw);
}
}

export type Proxy<T, S> = T & {
Expand All @@ -91,6 +103,18 @@ export class ConnectorInfo {
this.serverId = serverId;
this.id = uuid.v4();
}

static fromJSON(raw: any): ConnectorInfo {
const ci = mergeDeep(new ConnectorInfo(), raw);

switch (raw.type) {
case 'sql':
return mergeDeep(new SQLConnectorInfo(), ci);
case 'http':
return mergeDeep(new HTTPConnectorInfo(), ci);
}
return ci;
}
}

export type HTTPConnectorInfoMethod =
Expand All @@ -108,6 +132,10 @@ export class ContentTypeInfo {
this.type = type || '';
this.customLineRegexp = customLineRegexp || '';
}

static fromJSON(raw: any): ContentTypeInfo {
return mergeDeep(new ContentTypeInfo(), raw);
}
}

export class HTTPConnectorInfo extends ConnectorInfo {
Expand Down Expand Up @@ -185,12 +213,38 @@ export class PanelInfo {
name: string;
id: string;
serverId: string;
resultMeta: PanelResultMeta;

constructor(type: PanelInfoType, name?: string, content?: string) {
this.content = content || '';
this.type = type;
this.name = name || '';
this.id = uuid.v4();
this.resultMeta = new PanelResultMeta();
}

static fromJSON(raw: any): PanelInfo {
let pit: PanelInfo = mergeDeep(new PanelInfo(raw.type || 'literal'), raw);

switch (pit.type) {
case 'table':
pit = mergeDeep(new TablePanelInfo(), pit);
case 'http':
pit = mergeDeep(new HTTPPanelInfo(), pit);
case 'graph':
pit = mergeDeep(new GraphPanelInfo(), pit);
case 'program':
pit = mergeDeep(new ProgramPanelInfo(), pit);
case 'literal':
pit = mergeDeep(new LiteralPanelInfo(), pit);
case 'sql':
pit = mergeDeep(new SQLPanelInfo(), pit);
case 'file':
pit = mergeDeep(new FilePanelInfo(), pit);
}

pit.resultMeta = PanelResultMeta.fromJSON(raw.resultMeta);
return pit;
}
}

Expand Down Expand Up @@ -345,6 +399,14 @@ export class ProjectPage {
this.panels = panels || [];
this.id = uuid.v4();
}

static fromJSON(raw: any): ProjectPage {
const pp = new ProjectPage();
pp.panels = (raw.panels || []).map(PanelInfo.fromJSON);
pp.name = raw.name;
pp.id = raw.id || uuid.v4();
return pp;
}
}

export class ProjectState {
Expand Down Expand Up @@ -372,6 +434,18 @@ export class ProjectState {
this.lastVersion = lastVersion || VERSION;
this.id = uuid.v4();
}

static fromJSON(raw: any): ProjectState {
const ps = new ProjectState();
ps.projectName = raw.projectName || '';
ps.pages = (raw.pages || []).map(ProjectPage.fromJSON);
ps.connectors = (raw.connectors || []).map(ConnectorInfo.fromJSON);
ps.servers = (raw.servers || []).map(ServerInfo.fromJSON);
ps.id = raw.id || uuid.v4();
ps.originalVersion = raw.originalVersion || VERSION;
ps.lastVersion = raw.lastVersion || VERSION;
return ps;
}
}

export const DEFAULT_PROJECT: ProjectState = new ProjectState(
Expand All @@ -398,70 +472,3 @@ export const DEFAULT_PROJECT: ProjectState = new ProjectState(
]),
]
);

// The point of this is to make sure that (new) defaults get set on
// existing data.
//
export function rawStateToObjects(raw: ProjectState): ProjectState {
// Make a deep copy
const object = mergeDeep(new ProjectState(), JSON.parse(JSON.stringify(raw)));

object.pages.forEach((_: ProjectPage, pageI: number) => {
const page = (object.pages[pageI] = mergeDeep(
new ProjectPage(),
object.pages[pageI]
));

page.panels.forEach((panel: PanelInfo, i: number) => {
switch (panel.type) {
case 'table':
page.panels[i] = mergeDeep(new TablePanelInfo(), panel);
break;
case 'http':
page.panels[i] = mergeDeep(new HTTPPanelInfo(), panel);
break;
case 'graph':
const graphPanel = panel as GraphPanelInfo;
if ((graphPanel.graph as any).y && !graphPanel.graph.ys) {
graphPanel.graph.ys = [(graphPanel.graph as any).y];
delete (graphPanel.graph as any).y;
}
page.panels[i] = mergeDeep(new GraphPanelInfo(), panel);
break;
case 'program':
page.panels[i] = mergeDeep(new ProgramPanelInfo(), panel);
break;
case 'literal':
page.panels[i] = mergeDeep(new LiteralPanelInfo(), panel);
break;
case 'sql':
page.panels[i] = mergeDeep(new SQLPanelInfo(), panel);
break;
case 'file':
page.panels[i] = mergeDeep(new FilePanelInfo(), panel);
break;
default:
log.info(`Unknown panel type: ${panel.type}`);
}
});
});

object.servers.forEach((s: ServerInfo, i: number) => {
object.servers[i] = mergeDeep(new ServerInfo(), s);
});

object.connectors.forEach((c: ConnectorInfo, i: number) => {
switch (c.type) {
case 'sql':
object.connectors[i] = mergeDeep(new SQLConnectorInfo(), c);
break;
case 'http':
object.connectors[i] = mergeDeep(new HTTPConnectorInfo(), c);
break;
default:
log.info(`Unknown connector type: ${c.type}`);
}
});

return object;
}
58 changes: 21 additions & 37 deletions ui/Pages.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import * as React from 'react';
import { EVAL_ERRORS } from '../shared/errors';
import {
PanelResultMeta,
PanelResults,
ProjectPage,
ProjectState,
} from '../shared/state';
import { PanelResultMeta, ProjectPage, ProjectState } from '../shared/state';
import { Button } from './component-library/Button';
import { Confirm } from './component-library/Confirm';
import { Input } from './component-library/Input';
Expand All @@ -29,20 +24,6 @@ export function Pages({
currentPage: number;
}) {
const page: ProjectPage | null = state.pages[currentPage] || null;
const [panelResultsByPage, setPanelResultsByPage] =
React.useState<PanelResults>({});

// Make sure panelResults are initialized when page changes.
React.useEffect(() => {
if (page && !panelResultsByPage[page.id]) {
setPanelResultsByPage({ ...panelResultsByPage, [page.id]: [] });
}
}, [page && page.id]);

function setPanelResults(panelIndex: number, result: PanelResultMeta) {
panelResultsByPage[page.id][panelIndex] = result;
setPanelResultsByPage({ ...panelResultsByPage });
}

if (!page) {
return (
Expand All @@ -64,21 +45,22 @@ export function Pages({
);
}

// Guard against effect that initializes this per page
if (!panelResultsByPage || !panelResultsByPage[page.id]) {
return null;
}

const panelResults = panelResultsByPage[page.id];
const panelResults = page.panels.map((p) => p.resultMeta);

async function reevalPanel(panelIndex: number, reset?: boolean) {
async function reevalPanel(panelId: string, reset?: boolean) {
const { connectors, servers } = state;

let panel = panelResults[panelIndex] || new PanelResultMeta();
panel.lastRun = null;
panel.loading = !reset;
const panelIndex = page.panels.findIndex((p) => p.id === panelId);
if (panelIndex === -1) {
return;
}
const panel = page.panels[panelIndex];
let resultMeta = panel.resultMeta || new PanelResultMeta();
resultMeta.lastRun = null;
resultMeta.loading = !reset;

setPanelResults(panelIndex, panel);
panel.resultMeta = resultMeta;
updatePage(page);
if (reset) {
return;
}
Expand All @@ -94,7 +76,7 @@ export function Pages({
connectors,
servers
);
setPanelResults(panelIndex, {
panel.resultMeta = {
lastRun: new Date(),
value,
preview,
Expand All @@ -103,13 +85,14 @@ export function Pages({
contentType,
size,
loading: false,
});
};
updatePage(page);
} catch (e) {
if (EVAL_ERRORS.map((cls) => new (cls as any)().name).includes(e.name)) {
e = new PanelPlayWarning(e.message);
}

setPanelResults(panelIndex, {
panel.resultMeta = {
loading: false,
lastRun: new Date(),
exception: e,
Expand All @@ -118,13 +101,14 @@ export function Pages({
contentType: 'unknown',
size: 0,
shape: { kind: 'unknown' },
});
};
updatePage(page);
}
}

async function evalAll() {
for (let i = 0; i < page.panels.length; i++) {
await reevalPanel(i);
for (let panel of page.panels) {
await reevalPanel(panel.id);
await new Promise((resolve) => setTimeout(resolve, 1500));
}
}
Expand Down
Loading

0 comments on commit 32b84a1

Please sign in to comment.