aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-12-06 20:02:36 -0500
committerbobzel <zzzman@gmail.com>2023-12-06 20:02:36 -0500
commitc30a5b644458a7ab03a4dabe93face035aa0a21b (patch)
tree2fed8f18909ad185757ae96eb93eb85482ac3a6c
parent6d38096db5f0d550866d82d954436447d0c36a65 (diff)
more error/warning fixes
-rw-r--r--src/client/util/SerializationHelper.ts1
-rw-r--r--src/client/views/EditableView.tsx2
-rw-r--r--src/client/views/GestureOverlay.tsx1
-rw-r--r--src/client/views/MainView.tsx1
-rw-r--r--src/client/views/MetadataEntryMenu.tsx1
-rw-r--r--src/client/views/collections/CollectionMenu.tsx1
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx4
-rw-r--r--src/client/views/global/globalScripts.ts6
-rw-r--r--src/client/views/search/IconButton.tsx76
-rw-r--r--src/server/DashSession/Session/agents/monitor.ts151
-rw-r--r--src/server/DashSession/Session/agents/promisified_ipc_manager.ts96
-rw-r--r--src/server/DashUploadUtils.ts8
-rw-r--r--src/typings/index.d.ts8
13 files changed, 183 insertions, 173 deletions
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index 76037a7e9..8daa69890 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -1,6 +1,5 @@
import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema } from 'serializr';
import { Field } from '../../fields/Doc';
-import { ClientUtils } from './ClientUtils';
let serializing = 0;
export function afterDocDeserialize(cb: (err: any, val: any) => void, err: any, newValue: any) {
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index edc35047f..6bc0e5424 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -222,12 +222,14 @@ export class EditableView extends React.Component<EditableProps> {
className: 'editableView-input',
onKeyDown: this.onKeyDown,
autoFocus: true,
+ // @ts-ignore
onBlur: e => this.finalizeEdit(e.currentTarget.value, false, true, false),
onPointerDown: this.stopPropagation,
onClick: this.stopPropagation,
onPointerUp: this.stopPropagation,
onKeyPress: this.stopPropagation,
value: this.props.autosuggestProps.value,
+ // @ts-ignore
onChange: this.props.autosuggestProps.onChange,
}}
/>
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 5f0df3c5f..214da5541 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -14,7 +14,6 @@ import { InteractionUtils } from '../util/InteractionUtils';
import { ScriptingGlobals } from '../util/ScriptingGlobals';
import { Transform } from '../util/Transform';
import './GestureOverlay.scss';
-import { InkTranscription } from './InkTranscription';
import {
ActiveArrowEnd,
ActiveArrowScale,
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 1408e3124..50feccce2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -44,7 +44,6 @@ import { DictationOverlay } from './DictationOverlay';
import { DocumentDecorations } from './DocumentDecorations';
import { GestureOverlay } from './GestureOverlay';
import { KeyManager } from './GlobalKeyHandler';
-import { InkTranscription } from './InkTranscription';
import { LightboxView } from './LightboxView';
import { LinkMenu } from './linking/LinkMenu';
import './MainView.scss';
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx
index bcbdd3ccb..5c6912121 100644
--- a/src/client/views/MetadataEntryMenu.tsx
+++ b/src/client/views/MetadataEntryMenu.tsx
@@ -156,6 +156,7 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps> {
<span>Key:</span>
<div className="metadataEntry-autoSuggester" onClick={e => this.autosuggestRef.current!.input?.focus()}>
<Autosuggest
+ // @ts-ignore
inputProps={{ value: this._currentKey, onChange: this.onKeyChange }}
getSuggestionValue={this.getSuggestionValue}
suggestions={emptyPath}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 268879bd4..3edf4135f 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -541,6 +541,7 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi
autosuggestProps: {
inputProps: {
value: this._currentKey,
+ // @ts-ignore
onChange: this.onKeyChange,
},
getSuggestionValue: this.getSuggestionValue,
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
index 1118c6a72..45e24bbb2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
@@ -10,7 +10,7 @@ import { Cast } from '../../../../fields/Types';
import { CollectionViewProps } from '../CollectionView';
import './CollectionFreeFormView.scss';
import * as React from 'react';
-import v5 = require('uuid/v5');
+import * as uuid from 'uuid';
@observer
export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> {
@@ -42,7 +42,7 @@ export class CollectionFreeFormRemoteCursors extends React.Component<CollectionV
if (el) {
const ctx = el.getContext('2d');
if (ctx) {
- ctx.fillStyle = '#' + v5(metadata.id, v5.URL).substring(0, 6).toUpperCase() + '22';
+ ctx.fillStyle = '#' + uuid.v5(metadata.id, uuid.v5.URL).substring(0, 6).toUpperCase() + '22';
ctx.fillRect(0, 0, 20, 20);
ctx.fillStyle = 'black';
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 0ad76db35..de29d8602 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -14,7 +14,7 @@ import { undoable, UndoManager } from '../../util/UndoManager';
import { CollectionFreeFormView } from '../collections/collectionFreeForm';
import { GestureOverlay } from '../GestureOverlay';
import { ActiveFillColor, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth, SetActiveIsInkMask } from '../InkingStroke';
-import { InkTranscription } from '../InkTranscription';
+// import { InkTranscription } from '../InkTranscription';
import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
import { DocumentView } from '../nodes/DocumentView';
import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
@@ -293,14 +293,14 @@ export function createInkGroup(inksToGroup?: Doc[], isSubGroup?: boolean) {
// TODO: nda - will probably need to go through and only remove the unprocessed selected docs
ffView.unprocessedDocs = [];
- InkTranscription.Instance.transcribeInk(newCollection, selected, false);
+ // InkTranscription.Instance.transcribeInk(newCollection, selected, false);
});
}
CollectionFreeFormView.collectionsWithUnprocessedInk.clear();
}
function setActiveTool(tool: InkTool | GestureUtils.Gestures, keepPrim: boolean, checkResult?: boolean) {
- InkTranscription.Instance?.createInkGroup();
+ // InkTranscription.Instance?.createInkGroup();
if (checkResult) {
return (Doc.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool
? GestureOverlay.Instance?.KeepPrimitiveMode || ![GestureUtils.Gestures.Circle, GestureUtils.Gestures.Line, GestureUtils.Gestures.Rectangle].includes(tool as GestureUtils.Gestures)
diff --git a/src/client/views/search/IconButton.tsx b/src/client/views/search/IconButton.tsx
index 6cf3a5f72..9aae347e7 100644
--- a/src/client/views/search/IconButton.tsx
+++ b/src/client/views/search/IconButton.tsx
@@ -1,29 +1,28 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import * as _ from "lodash";
+import * as _ from 'lodash';
import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { DocumentType } from "../../documents/DocumentTypes";
+import { DocumentType } from '../../documents/DocumentTypes';
import '../global/globalCssVariables.scss';
import { IconBar } from './IconBar';
-import "./IconButton.scss";
-import "./SearchBox.scss";
+import './IconButton.scss';
+import './SearchBox.scss';
import { Font } from '@react-pdf/renderer';
-interface IconButtonProps {
+interface iconButtonProps {
type: string;
}
@observer
-export class IconButton extends React.Component<IconButtonProps>{
-
+export class IconButton extends React.Component<iconButtonProps> {
@observable private _isSelected: boolean = IconBar.Instance.getIcons().indexOf(this.props.type) !== -1;
@observable private _hover = false;
private _resetReaction?: IReactionDisposer;
private _selectAllReaction?: IReactionDisposer;
static Instance: IconButton;
- constructor(props: IconButtonProps) {
+ constructor(props: iconButtonProps) {
super(props);
IconButton.Instance = this;
}
@@ -40,7 +39,7 @@ export class IconButton extends React.Component<IconButtonProps>{
IconBar.Instance._resetClicked = false;
}
}
- }),
+ })
);
this._selectAllReaction = reaction(
@@ -54,24 +53,35 @@ export class IconButton extends React.Component<IconButtonProps>{
IconBar.Instance._selectAllClicked = false;
}
}
- }),
+ })
);
- }
+ };
@action.bound
getIcon() {
switch (this.props.type) {
- case (DocumentType.NONE): return "ban";
- case (DocumentType.AUDIO): return "music";
- case (DocumentType.COL): return "object-group";
- case (DocumentType.IMG): return "image";
- case (DocumentType.LINK): return "link";
- case (DocumentType.PDF): return "file-pdf";
- case (DocumentType.RTF): return "sticky-note";
- case (DocumentType.VID): return "video";
- case (DocumentType.WEB): return "globe-asia";
- case (DocumentType.MAP): return "map-marker-alt";
- default: return "caret-down";
+ case DocumentType.NONE:
+ return 'ban';
+ case DocumentType.AUDIO:
+ return 'music';
+ case DocumentType.COL:
+ return 'object-group';
+ case DocumentType.IMG:
+ return 'image';
+ case DocumentType.LINK:
+ return 'link';
+ case DocumentType.PDF:
+ return 'file-pdf';
+ case DocumentType.RTF:
+ return 'sticky-note';
+ case DocumentType.VID:
+ return 'video';
+ case DocumentType.WEB:
+ return 'globe-asia';
+ case DocumentType.MAP:
+ return 'map-marker-alt';
+ default:
+ return 'caret-down';
}
}
@@ -82,45 +92,39 @@ export class IconButton extends React.Component<IconButtonProps>{
if (!this._isSelected) {
this._isSelected = true;
newList.push(this.props.type);
- }
- else {
+ } else {
this._isSelected = false;
_.pull(newList, this.props.type);
}
IconBar.Instance.updateIcon(newList);
- }
+ };
selected = {
opacity: 1,
- backgroundColor: "#121721",
+ backgroundColor: '#121721',
//backgroundColor: "rgb(128, 128, 128)"
};
notSelected = {
opacity: 0.2,
- backgroundColor: "#121721",
+ backgroundColor: '#121721',
};
hoverStyle = {
opacity: 1,
- backgroundColor: "rgb(128, 128, 128)"
+ backgroundColor: 'rgb(128, 128, 128)',
//backgroundColor: "rgb(178, 206, 248)" //$medium-blue
};
render() {
return (
- <div className="type-outer" id={this.props.type + "-filter"}
- onMouseEnter={() => this._hover = true}
- onMouseLeave={() => this._hover = false}
- onClick={this.onClick}>
- <div className="type-icon" id={this.props.type + "-icon"}
- style={this._hover ? this.hoverStyle : this._isSelected ? this.selected : this.notSelected}
- >
+ <div className="type-outer" id={this.props.type + '-filter'} onMouseEnter={() => (this._hover = true)} onMouseLeave={() => (this._hover = false)} onClick={this.onClick}>
+ <div className="type-icon" id={this.props.type + '-icon'} style={this._hover ? this.hoverStyle : this._isSelected ? this.selected : this.notSelected}>
<FontAwesomeIcon className="fontawesome-icon" icon={this.getIcon()} />
</div>
{/* <div className="filter-description">{this.props.type}</div> */}
</div>
);
}
-} \ No newline at end of file
+}
diff --git a/src/server/DashSession/Session/agents/monitor.ts b/src/server/DashSession/Session/agents/monitor.ts
index 0f469285e..a6fde4356 100644
--- a/src/server/DashSession/Session/agents/monitor.ts
+++ b/src/server/DashSession/Session/agents/monitor.ts
@@ -1,16 +1,16 @@
-import { ExitHandler } from "./applied_session_agent";
-import { Configuration, configurationSchema, defaultConfig, Identifiers, colorMapping } from "../utilities/session_config";
-import Repl, { ReplAction } from "../utilities/repl";
-import * as _cluster from "cluster";
-import { Worker } from "cluster";
-import { manage, MessageHandler, ErrorLike } from "./promisified_ipc_manager";
-import { red, cyan, white, yellow, blue } from "colors";
-import { exec, ExecOptions } from "child_process";
-import { validate, ValidationError } from "jsonschema";
-import { Utilities } from "../utilities/utilities";
-import { readFileSync } from "fs";
-import IPCMessageReceiver from "./process_message_router";
-import { ServerWorker } from "./server_worker";
+import { ExitHandler } from './applied_session_agent';
+import { Configuration, configurationSchema, defaultConfig, Identifiers, colorMapping } from '../utilities/session_config';
+import Repl, { ReplAction } from '../utilities/repl';
+import * as _cluster from 'cluster';
+import { Worker } from 'cluster';
+import { manage, MessageHandler, ErrorLike } from './promisified_ipc_manager';
+import { red, cyan, white, yellow, blue } from 'colors';
+import { exec, ExecOptions } from 'child_process';
+import { validate, ValidationError } from 'jsonschema';
+import { Utilities } from '../utilities/utilities';
+import { readFileSync } from 'fs';
+import IPCMessageReceiver from './process_message_router';
+import { ServerWorker } from './server_worker';
const cluster = _cluster as any;
const isWorker = cluster.isWorker;
const setupMaster = cluster.setupPrimary;
@@ -26,20 +26,20 @@ export class Monitor extends IPCMessageReceiver {
private finalized = false;
private exitHandlers: ExitHandler[] = [];
private readonly config: Configuration;
- private activeWorker: Worker| undefined;
+ private activeWorker: Worker | undefined;
private key: string | undefined;
private repl: Repl;
public static Create() {
if (isWorker) {
- ServerWorker.IPCManager.emit("kill", {
- reason: "cannot create a monitor on the worker process.",
+ ServerWorker.IPCManager.emit('kill', {
+ reason: 'cannot create a monitor on the worker process.',
graceful: false,
- errorCode: 1
+ errorCode: 1,
});
process.exit(1);
} else if (++Monitor.count > 1) {
- console.error(red("cannot create more than one monitor."));
+ console.error(red('cannot create more than one monitor.'));
process.exit(1);
} else {
return new Monitor();
@@ -48,7 +48,7 @@ export class Monitor extends IPCMessageReceiver {
private constructor() {
super();
- console.log(this.timestamp(), cyan("initializing session..."));
+ console.log(this.timestamp(), cyan('initializing session...'));
this.configureInternalHandlers();
this.config = this.loadAndValidateConfiguration();
this.initializeClusterFunctions();
@@ -59,8 +59,8 @@ export class Monitor extends IPCMessageReceiver {
// handle exceptions in the master thread - there shouldn't be many of these
// the IPC (inter process communication) channel closed exception can't seem
// to be caught in a try catch, and is inconsequential, so it is ignored
- process.on("uncaughtException", ({ message, stack }): void => {
- if (message !== "Channel closed") {
+ process.on('uncaughtException', ({ message, stack }): void => {
+ if (message !== 'Channel closed') {
this.mainLog(red(message));
if (stack) {
this.mainLog(`uncaught exception\n${red(stack)}`);
@@ -68,36 +68,36 @@ export class Monitor extends IPCMessageReceiver {
}
});
- this.on("kill", ({ reason, graceful, errorCode }) => this.killSession(reason, graceful, errorCode));
- this.on("lifecycle", ({ event }) => console.log(this.timestamp(), `${this.config.identifiers.worker.text} lifecycle phase (${event})`));
- }
+ this.on('kill', ({ reason, graceful, errorCode }) => this.killSession(reason, graceful, errorCode));
+ this.on('lifecycle', ({ event }) => console.log(this.timestamp(), `${this.config.identifiers.worker.text} lifecycle phase (${event})`));
+ };
private initializeClusterFunctions = () => {
// determines whether or not we see the compilation / initialization / runtime output of each child server process
- const output = this.config.showServerOutput ? "inherit" : "ignore";
- setupMaster({ stdio: ["ignore", output, output, "ipc"] });
+ const output = this.config.showServerOutput ? 'inherit' : 'ignore';
+ setupMaster({ stdio: ['ignore', output, output, 'ipc'] });
// a helpful cluster event called on the master thread each time a child process exits
- on("exit", ({ process: { pid } }, code, signal) => {
- const prompt = `server worker with process id ${pid} has exited with code ${code}${signal === null ? "" : `, having encountered signal ${signal}`}.`;
+ on('exit', ({ process: { pid } }: { process: { pid: any } }, code: any, signal: any) => {
+ const prompt = `server worker with process id ${pid} has exited with code ${code}${signal === null ? '' : `, having encountered signal ${signal}`}.`;
this.mainLog(cyan(prompt));
// to make this a robust, continuous session, every time a child process dies, we immediately spawn a new one
this.spawn();
});
- }
+ };
public finalize = (sessionKey: string): void => {
if (this.finalized) {
- throw new Error("Session monitor is already finalized");
+ throw new Error('Session monitor is already finalized');
}
this.finalized = true;
this.key = sessionKey;
this.spawn();
- }
+ };
public readonly coreHooks = Object.freeze({
onCrashDetected: (listener: MessageHandler<{ error: ErrorLike }>) => this.on(Monitor.IntrinsicEvents.CrashDetected, listener),
- onServerRunning: (listener: MessageHandler<{ isFirstTime: boolean }>) => this.on(Monitor.IntrinsicEvents.ServerRunning, listener)
+ onServerRunning: (listener: MessageHandler<{ isFirstTime: boolean }>) => this.on(Monitor.IntrinsicEvents.ServerRunning, listener),
});
/**
@@ -107,12 +107,12 @@ export class Monitor extends IPCMessageReceiver {
* requests to complete) or immediately.
*/
public killSession = async (reason: string, graceful = true, errorCode = 0) => {
- this.mainLog(cyan(`exiting session ${graceful ? "clean" : "immediate"}ly`));
- this.mainLog(`session exit reason: ${(red(reason))}`);
+ this.mainLog(cyan(`exiting session ${graceful ? 'clean' : 'immediate'}ly`));
+ this.mainLog(`session exit reason: ${red(reason)}`);
await this.executeExitHandlers(true);
await this.killActiveWorker(graceful, true);
process.exit(errorCode);
- }
+ };
/**
* Execute the list of functions registered to be called
@@ -126,27 +126,27 @@ export class Monitor extends IPCMessageReceiver {
*/
public addReplCommand = (basename: string, argPatterns: (RegExp | string)[], action: ReplAction) => {
this.repl.registerCommand(basename, argPatterns, action);
- }
+ };
public exec = (command: string, options?: ExecOptions) => {
return new Promise<void>(resolve => {
- exec(command, { ...options, encoding: "utf8" }, (error, stdout, stderr) => {
+ exec(command, { ...options, encoding: 'utf8' }, (error, stdout, stderr) => {
if (error) {
this.execLog(red(`unable to execute ${white(command)}`));
- error.message.split("\n").forEach(line => line.length && this.execLog(red(`(error) ${line}`)));
+ error.message.split('\n').forEach(line => line.length && this.execLog(red(`(error) ${line}`)));
} else {
let outLines: string[], errorLines: string[];
- if ((outLines = stdout.split("\n").filter(line => line.length)).length) {
+ if ((outLines = stdout.split('\n').filter(line => line.length)).length) {
outLines.forEach(line => line.length && this.execLog(cyan(`(stdout) ${line}`)));
}
- if ((errorLines = stderr.split("\n").filter(line => line.length)).length) {
+ if ((errorLines = stderr.split('\n').filter(line => line.length)).length) {
errorLines.forEach(line => line.length && this.execLog(yellow(`(stderr) ${line}`)));
}
}
resolve();
});
});
- }
+ };
/**
* Generates a blue UTC string associated with the time
@@ -159,14 +159,14 @@ export class Monitor extends IPCMessageReceiver {
*/
public mainLog = (...optionalParams: any[]) => {
console.log(this.timestamp(), this.config.identifiers.master.text, ...optionalParams);
- }
+ };
/**
* A formatted, identified and timestamped log in color for non-
*/
private execLog = (...optionalParams: any[]) => {
console.log(this.timestamp(), this.config.identifiers.exec.text, ...optionalParams);
- }
+ };
/**
* Reads in configuration .json file only once, in the master thread
@@ -175,28 +175,28 @@ export class Monitor extends IPCMessageReceiver {
private loadAndValidateConfiguration = (): Configuration => {
let config: Configuration | undefined;
try {
- console.log(this.timestamp(), cyan("validating configuration..."));
+ console.log(this.timestamp(), cyan('validating configuration...'));
config = JSON.parse(readFileSync('./session.config.json', 'utf8'));
const options = {
throwError: true,
- allowUnknownAttributes: false
+ allowUnknownAttributes: false,
};
// ensure all necessary and no excess information is specified by the configuration file
validate(config, configurationSchema, options);
config = Utilities.preciseAssign({}, defaultConfig, config);
} catch (error: any) {
if (error instanceof ValidationError) {
- console.log(red("\nSession configuration failed."));
- console.log("The given session.config.json configuration file is invalid.");
+ console.log(red('\nSession configuration failed.'));
+ console.log('The given session.config.json configuration file is invalid.');
console.log(`${error.instance}: ${error.stack}`);
process.exit(0);
- } else if (error.code === "ENOENT" && error.path === "./session.config.json") {
- console.log(cyan("Loading default session parameters..."));
- console.log("Consider including a session.config.json configuration file in your project root for customization.");
+ } else if (error.code === 'ENOENT' && error.path === './session.config.json') {
+ console.log(cyan('Loading default session parameters...'));
+ console.log('Consider including a session.config.json configuration file in your project root for customization.');
config = Utilities.preciseAssign({}, defaultConfig);
} else {
- console.log(red("\nSession configuration failed."));
- console.log("The following unknown error occurred during configuration.");
+ console.log(red('\nSession configuration failed.'));
+ console.log('The following unknown error occurred during configuration.');
console.log(error.stack);
process.exit(0);
}
@@ -209,7 +209,7 @@ export class Monitor extends IPCMessageReceiver {
});
return config!;
}
- }
+ };
/**
* Builds the repl that allows the following commands to be typed into stdin of the master thread.
@@ -219,24 +219,24 @@ export class Monitor extends IPCMessageReceiver {
const boolean = /true|false/;
const number = /\d+/;
const letters = /[a-zA-Z]+/;
- repl.registerCommand("exit", [/clean|force/], args => this.killSession("manual exit requested by repl", args[0] === "clean", 0));
- repl.registerCommand("restart", [/clean|force/], args => this.killActiveWorker(args[0] === "clean"));
- repl.registerCommand("set", [letters, "port", number, boolean], args => this.setPort(args[0], Number(args[2]), args[3] === "true"));
- repl.registerCommand("set", [/polling/, number, boolean], args => {
+ repl.registerCommand('exit', [/clean|force/], args => this.killSession('manual exit requested by repl', args[0] === 'clean', 0));
+ repl.registerCommand('restart', [/clean|force/], args => this.killActiveWorker(args[0] === 'clean'));
+ repl.registerCommand('set', [letters, 'port', number, boolean], args => this.setPort(args[0], Number(args[2]), args[3] === 'true'));
+ repl.registerCommand('set', [/polling/, number, boolean], args => {
const newPollingIntervalSeconds = Math.floor(Number(args[1]));
if (newPollingIntervalSeconds < 0) {
- this.mainLog(red("the polling interval must be a non-negative integer"));
+ this.mainLog(red('the polling interval must be a non-negative integer'));
} else {
if (newPollingIntervalSeconds !== this.config.polling.intervalSeconds) {
this.config.polling.intervalSeconds = newPollingIntervalSeconds;
- if (args[2] === "true") {
- Monitor.IPCManager.emit("updatePollingInterval", { newPollingIntervalSeconds });
+ if (args[2] === 'true') {
+ Monitor.IPCManager.emit('updatePollingInterval', { newPollingIntervalSeconds });
}
}
}
});
return repl;
- }
+ };
private executeExitHandlers = async (reason: Error | boolean) => Promise.all(this.exitHandlers.map(handler => handler(reason)));
@@ -246,13 +246,13 @@ export class Monitor extends IPCMessageReceiver {
private killActiveWorker = async (graceful = true, isSessionEnd = false): Promise<void> => {
if (this.activeWorker && !this.activeWorker.isDead()) {
if (graceful) {
- Monitor.IPCManager.emit("manualExit", { isSessionEnd });
+ Monitor.IPCManager.emit('manualExit', { isSessionEnd });
} else {
await ServerWorker.IPCManager.destroy();
this.activeWorker.process.kill();
}
}
- }
+ };
/**
* Allows the caller to set the port at which the target (be it the server,
@@ -261,7 +261,7 @@ export class Monitor extends IPCMessageReceiver {
* at the port. Otherwise, the updated port won't be used until / unless the child
* dies on its own and triggers a restart.
*/
- private setPort = (port: "server" | "socket" | string, value: number, immediateRestart: boolean): void => {
+ private setPort = (port: 'server' | 'socket' | string, value: number, immediateRestart: boolean): void => {
if (value > 1023 && value < 65536) {
this.config.ports[port] = value;
if (immediateRestart) {
@@ -270,7 +270,7 @@ export class Monitor extends IPCMessageReceiver {
} else {
this.mainLog(red(`${port} is an invalid port number`));
}
- }
+ };
/**
* Kills the current active worker and proceeds to spawn a new worker,
@@ -278,30 +278,29 @@ export class Monitor extends IPCMessageReceiver {
*/
private spawn = async (): Promise<void> => {
await this.killActiveWorker();
- const { config: { polling, ports }, key } = this;
+ const {
+ config: { polling, ports },
+ key,
+ } = this;
this.activeWorker = fork({
pollingRoute: polling.route,
pollingFailureTolerance: polling.failureTolerance,
serverPort: ports.server,
socketPort: ports.socket,
pollingIntervalSeconds: polling.intervalSeconds,
- session_key: key
+ session_key: key,
});
if (this.activeWorker) {
Monitor.IPCManager = manage(this.activeWorker.process, this.handlers);
}
this.mainLog(cyan(`spawned new server worker with process id ${this.activeWorker?.process.pid}`));
-
- }
-
+ };
}
export namespace Monitor {
-
export enum IntrinsicEvents {
- KeyGenerated = "key_generated",
- CrashDetected = "crash_detected",
- ServerRunning = "server_running"
+ KeyGenerated = 'key_generated',
+ CrashDetected = 'crash_detected',
+ ServerRunning = 'server_running',
}
-
-} \ No newline at end of file
+}
diff --git a/src/server/DashSession/Session/agents/promisified_ipc_manager.ts b/src/server/DashSession/Session/agents/promisified_ipc_manager.ts
index f6c8de521..76e218977 100644
--- a/src/server/DashSession/Session/agents/promisified_ipc_manager.ts
+++ b/src/server/DashSession/Session/agents/promisified_ipc_manager.ts
@@ -1,9 +1,9 @@
-import { Utilities } from "../utilities/utilities";
-import { ChildProcess } from "child_process";
+import { Utilities } from '../utilities/utilities';
+import { ChildProcess } from 'child_process';
/**
* Convenience constructor
- * @param target the process / worker to which to attach the specialized listeners
+ * @param target the process / worker to which to attach the specialized listeners
*/
export function manage(target: IPCTarget, handlers?: HandlerMap) {
return new PromisifiedIPCManager(target, handlers);
@@ -18,26 +18,30 @@ export type HandlerMap = { [name: string]: MessageHandler[] };
/**
* This will always literally be a child process. But, though setting
* up a manager in the parent will indeed see the target as the ChildProcess,
- * setting up a manager in the child will just see itself as a regular NodeJS.Process.
+ * setting up a manager in the child will just see itself as a regular NodeJS.Process.
*/
export type IPCTarget = NodeJS.Process | ChildProcess;
/**
- * Specifies a general message format for this API
+ * Specifies a general message format for this API
*/
export type Message<T = any> = {
name: string;
args?: T;
};
-export type MessageHandler<T = any> = (args: T) => (any | Promise<any>);
+export type MessageHandler<T = any> = (args: T) => any | Promise<any>;
/**
* When a message is emitted, it is embedded with private metadata
* to facilitate the resolution of promises, etc.
*/
-interface InternalMessage extends Message { metadata: Metadata; }
-interface Metadata { isResponse: boolean; id: string; }
-type InternalMessageHandler = (message: InternalMessage) => (any | Promise<any>);
+interface InternalMessage extends Message {
+ metadata: Metadata;
+}
+interface Metadata {
+ isResponse: boolean;
+ id: string;
+}
/**
* Allows for the transmission of the error's key features over IPC.
@@ -56,12 +60,12 @@ export interface Response<T = any> {
error?: ErrorLike;
}
-const destroyEvent = "__destroy__";
+const destroyEvent = '__destroy__';
/**
* This is a wrapper utility class that allows the caller process
* to emit an event and return a promise that resolves when it and all
- * other processes listening to its emission of this event have completed.
+ * other processes listening to its emission of this event have completed.
*/
export class PromisifiedIPCManager {
private readonly target: IPCTarget;
@@ -75,7 +79,7 @@ export class PromisifiedIPCManager {
this.target = target;
if (handlers) {
handlers[destroyEvent] = [this.destroyHelper];
- this.target.addListener("message", this.generateInternalHandler(handlers));
+ this.target.addListener('message', this.generateInternalHandler(handlers));
}
}
@@ -86,26 +90,27 @@ export class PromisifiedIPCManager {
*/
public emit = async <T = any>(name: string, args?: any): Promise<Response<T>> => {
if (this.isDestroyed) {
- const error = { name: "FailedDispatch", message: "Cannot use a destroyed IPC manager to emit a message." };
+ const error = { name: 'FailedDispatch', message: 'Cannot use a destroyed IPC manager to emit a message.' };
return { error };
}
return new Promise<Response<T>>(resolve => {
const messageId = Utilities.guid();
+ type InternalMessageHandler = (message: any /* MessageListener*/) => any | Promise<any>;
const responseHandler: InternalMessageHandler = ({ metadata: { id, isResponse }, args }) => {
if (isResponse && id === messageId) {
- this.target.removeListener("message", responseHandler);
+ this.target.removeListener('message', responseHandler);
resolve(args);
}
};
- this.target.addListener("message", responseHandler);
+ this.target.addListener('message', responseHandler);
const message = { name, args, metadata: { id: messageId, isResponse: false } };
if (!(this.target.send && this.target.send(message))) {
- const error: ErrorLike = { name: "FailedDispatch", message: "Either the target's send method was undefined or the act of sending failed." };
+ const error: ErrorLike = { name: 'FailedDispatch', message: "Either the target's send method was undefined or the act of sending failed." };
resolve({ error });
- this.target.removeListener("message", responseHandler);
+ this.target.removeListener('message', responseHandler);
}
});
- }
+ };
/**
* Invoked from either the parent or the child process, this allows
@@ -122,7 +127,7 @@ export class PromisifiedIPCManager {
}
resolve();
});
- }
+ };
/**
* Dispatches the dummy responses and sets the isDestroyed flag to true.
@@ -131,12 +136,12 @@ export class PromisifiedIPCManager {
const { pendingMessages } = this;
this.isDestroyed = true;
Object.keys(pendingMessages).forEach(id => {
- const error: ErrorLike = { name: "ManagerDestroyed", message: "The IPC manager was destroyed before the response could be returned." };
+ const error: ErrorLike = { name: 'ManagerDestroyed', message: 'The IPC manager was destroyed before the response could be returned.' };
const message: InternalMessage = { name: pendingMessages[id], args: { error }, metadata: { id, isResponse: true } };
this.target.send?.(message);
});
this.pendingMessages = {};
- }
+ };
/**
* This routine receives a uniquely identified message. If the message is itself a response,
@@ -145,29 +150,30 @@ export class PromisifiedIPCManager {
* which will ultimately invoke the responseHandler of the original emission and resolve the
* sender's promise.
*/
- private generateInternalHandler = (handlers: HandlerMap): MessageHandler => async (message: InternalMessage) => {
- const { name, args, metadata } = message;
- if (name && metadata && !metadata.isResponse) {
- const { id } = metadata;
- this.pendingMessages[id] = name;
- let error: Error | undefined;
- let results: any[] | undefined;
- try {
- const registered = handlers[name];
- if (registered) {
- results = await Promise.all(registered.map(handler => handler(args)));
+ private generateInternalHandler =
+ (handlers: HandlerMap): MessageHandler =>
+ async (message: InternalMessage) => {
+ const { name, args, metadata } = message;
+ if (name && metadata && !metadata.isResponse) {
+ const { id } = metadata;
+ this.pendingMessages[id] = name;
+ let error: Error | undefined;
+ let results: any[] | undefined;
+ try {
+ const registered = handlers[name];
+ if (registered) {
+ results = await Promise.all(registered.map(handler => handler(args)));
+ }
+ } catch (e: any) {
+ error = e;
+ }
+ if (!this.isDestroyed && this.target.send) {
+ const metadata = { id, isResponse: true };
+ const response: Response = { results, error };
+ const message = { name, args: response, metadata };
+ delete this.pendingMessages[id];
+ this.target.send(message);
}
- } catch (e: any) {
- error = e;
- }
- if (!this.isDestroyed && this.target.send) {
- const metadata = { id, isResponse: true };
- const response: Response = { results, error };
- const message = { name, args: response, metadata };
- delete this.pendingMessages[id];
- this.target.send(message);
}
- }
- }
-
-} \ No newline at end of file
+ };
+}
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 2bea15915..7765349ff 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -170,10 +170,12 @@ export namespace DashUploadUtils {
res({
source: {
size: 0,
- path: filepath,
+ filepath: name,
+ originalFilename: name,
newFilename: name,
- type: '',
- toJSON: () => ({ newFilename: name, filepath }),
+ mimetype: 'video',
+ hashAlgorithm: 'md5',
+ toJSON: () => ({ newFilename: name, filepath, mimetype: 'video', mtime: new Date(), size: 0, length: 0, originalFilename: name }),
},
result: { name: 'failed youtube query', message: `Could not archive video. ${code ? errors : uploadProgress.get(videoId)}` },
});
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts
index fb2ae7a02..284aae338 100644
--- a/src/typings/index.d.ts
+++ b/src/typings/index.d.ts
@@ -14,13 +14,11 @@ declare module 'react-reveal';
declare module 'react-reveal/makeCarousel';
declare module '@hig/flyout';
declare module 'express-flash';
-declare module 'connect-flash';
+declare module 'connect-flash' {
+ interface flash {}
+}
declare module 'connect-mongo';
declare module '@mui/material';
-declare module 'socket.io-parser' {
- type Encoder = any;
- type Decoder = any;
-}
declare module '@react-pdf/renderer' {
import * as React from 'react';