Skip to content

Commit

Permalink
Basic support for user input using readline
Browse files Browse the repository at this point in the history
  • Loading branch information
DonJayamanne committed Sep 10, 2021
1 parent 680d68c commit 5e993b7
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 2.0.3 (10 Sept 2021)
* Update samples to use `isomorphic-fetch` instead of `node-fetch` (and pre-requisite `npm` packages).
* Basic support for user input in notebooks using [readline](https://nodejs.org/api/readline.html#readline_readline_createinterface_options)

## 2.0.2 (6 Sept 2021)
* Excellent support for [arquero](https://uwdata.github.io/arquero/) (rich HTML output)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* Excellent support for [arquero](https://uwdata.github.io/arquero/) (rich HTML output)
* Run shell scripts within the notebook cell.
* Quickly prototype and view HTML/JavaScript/CSS output
* Basic support for user input using [readline](https://nodejs.org/api/readline.html#readline_readline_createinterface_options)


Packages such [plotly](https://plotly.com/javascript/), [tfjs-vis](https://www.npmjs.com/package/@tensorflow/tfjs-vis) & [danfo.js](https://danfo.jsdata.org/) support rich visualzation only in the browser,
wowever, this extension leverages the power of Notebooks to provide the same rich visualzations when targetting node.js.
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@
"shell-quote": "^1.7.2",
"source-map": "^0.6.1",
"tmp": "^0.2.1",
"typescript": "^4.4.2",
"typescript": "^4.4.3",
"uuid": "^8.3.2",
"ws": "^7.5.3",
"xterm": "^4.13.0",
Expand Down
8 changes: 7 additions & 1 deletion src/extension/kernel/jsKernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import * as WebSocket from 'ws';
import { CellExecutionState } from './types';
import * as path from 'path';
import { ChildProcess, spawn } from 'child_process';
import { createDeferred, Deferred, generateId } from '../coreUtils';
import { createDeferred, Deferred, generateId, noop } from '../coreUtils';
import { ServerLogger } from '../serverLogger';
import { CellOutput as CellOutput } from './cellOutput';
import { getNotebookCwd } from '../utils';
Expand Down Expand Up @@ -280,6 +280,12 @@ export class JavaScriptKernel implements IDisposable {
void window.showErrorMessage('JavaScript/TypeScript Notebook Kernel was restarted');
break;
}
case 'readlineRequest': {
window.showInputBox({ ignoreFocusOut: true, prompt: message.question }).then((result) => {
void this.sendMessage({ type: 'readlineResponse', answer: result, requestId: message.requestId });
}, noop);
break;
}
case 'tensorFlowVis': {
if (
getConfiguration().inlineTensorflowVisualizations &&
Expand Down
4 changes: 4 additions & 0 deletions src/extension/server/codeExecution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { noop } from '../coreUtils';
import { createConsoleOutputCompletedMarker } from '../const';
import { DanfoNodePlotter } from './extensions/danforPlotter';
import { ArqueroFormatter } from './extensions/arqueroFormatter';
import { ReadLineProxy } from './extensions/readLineProxy';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const Module = require('module');

Expand Down Expand Up @@ -304,6 +305,9 @@ Module._load = function (request: any, parent: any) {

// eslint-disable-next-line prefer-rest-params
const result = originalLoad.apply(this, arguments);
if (request === 'readline') {
ReadLineProxy.initialize(result);
}
if (request === 'danfojs-node') {
DanfoJsFormatter.initialize(result);
}
Expand Down
35 changes: 35 additions & 0 deletions src/extension/server/extensions/readLineProxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { addMessageHandler, removeMessageHandler, sendMessage } from '../comms';
import { v4 as uuid } from 'uuid';
import { ReadLineQuestionResponse } from '../types';

export class ReadLineProxy {
static initialize(readLine: typeof import('readline')) {
const originalCreateInterface = readLine.createInterface;
readLine.createInterface = function () {
const rlInterface = originalCreateInterface.apply(readLine, arguments as any);
const originalQuesttion = rlInterface.question;
rlInterface.question = function (query: string) {
const questionArgs = Array.prototype.slice.call(arguments);
const callback = questionArgs.find((item) => typeof item === 'function');
if (callback) {
const requestId = uuid();
sendMessage({
type: 'readlineRequest',
question: query,
requestId
});
function callbackHandler(message: ReadLineQuestionResponse) {
if (message.requestId === requestId) {
removeMessageHandler('readlineResponse', callbackHandler);
callback(message.answer);
}
}
addMessageHandler('readlineResponse', callbackHandler);
}
return originalQuesttion.apply(rlInterface, arguments as any);
};

return rlInterface;
};
}
}
2 changes: 1 addition & 1 deletion src/extension/server/tsnode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import * as path from 'path';
const tsNodePath = path.join(__dirname, '..', '..', '..', 'resources', 'scripts', 'node_modules', 'ts-node');
export function register(context: vm.Context) {
vm.runInNewContext(`require('${tsNodePath.replace(/\\/g, '/')}').register()`, context, {
displayErrors: true
displayErrors: false
});
}
25 changes: 24 additions & 1 deletion src/extension/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ export type CodeObject = {
friendlyName: string;
sourceMapFilename: string;
};
export type RequestType = RunCellRequest | PingRequest | InitializeRequest | TensorFlowVisRequest | PlotGenerated;
export type RequestType =
| RunCellRequest
| PingRequest
| InitializeRequest
| TensorFlowVisRequest
| PlotGenerated
| ReadLineQuestionResponse;
export type RunCellRequest = BaseMessage<
'cellExec',
{
Expand All @@ -63,6 +69,22 @@ export type TensorFlowVisRequest = BaseMessage<
| { request: 'heatmap'; requestId: string; success: boolean; error?: Error }
>;

export type ReadLineQuestionRequest = BaseMessage<
'readlineRequest',
{
question: string;
requestId: string;
}
>;

export type ReadLineQuestionResponse = BaseMessage<
'readlineResponse',
{
answer?: string;
requestId: string;
}
>;

// Responses
export type ResponseType =
| RunCellResponse
Expand All @@ -72,6 +94,7 @@ export type ResponseType =
| Initialized
| OutputResponse
| PlotGenerated
| ReadLineQuestionRequest
| TensorFlowVis;
export type LogMessage = BaseMessage<
'logMessage',
Expand Down

0 comments on commit 5e993b7

Please sign in to comment.