Skip to content

Commit

Permalink
Merge pull request #818 from jtpio/typescript
Browse files Browse the repository at this point in the history
Add TypeScript and tsconfig.json
  • Loading branch information
SylvainCorlay authored Feb 4, 2021
2 parents 0f91e40 + 3bd48d2 commit 4cf9585
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 101 deletions.
9 changes: 0 additions & 9 deletions packages/voila/.babelrc

This file was deleted.

10 changes: 7 additions & 3 deletions packages/voila/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
"@jupyter-widgets/controls": "^1.5.0",
"@jupyter-widgets/jupyterlab-manager": "^1.0.0",
"@jupyter-widgets/output": "^2.0.0",
"@jupyterlab/docregistry": "^1.0.0",
"@jupyterlab/coreutils": "^3.0.0",
"@jupyterlab/outputarea": "^1.0.0",
"@jupyterlab/notebook": "^1.0.0",
"@jupyterlab/rendermime": "^1.0.0",
"@jupyterlab/services": "^4.0.0",
"@phosphor/algorithm": "^1.2.0",
Expand All @@ -27,7 +29,6 @@
"mathjax-full": "^3.0.0"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/preset-env": "^7.3.1",
"babel-loader": "^8.0.5",
Expand All @@ -36,19 +37,22 @@
"npm-run-all": "^4.1.5",
"p-limit": "^2.2.2",
"style-loader": "^0.23.1",
"typescript": "~4.1.3",
"url-loader": "^1.0.0",
"webpack": "^4.29.3",
"webpack-cli": "^3.2.3"
},
"style": "style/index.css",
"scripts": {
"build": "npm run build:lib && webpack",
"build:lib": "tsc",
"build:prod": "npm run build:lib && webpack --production",
"build:lib": "babel src --out-dir lib",
"clean": "jlpm run clean:lib",
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
"prepare": "npm run build:lib && webpack",
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "npm-run-all -p watch:*",
"watch:lib": "babel src --out-dir lib --watch",
"watch:lib": "tsc -w",
"watch:bundle": "webpack --watch --mode=development"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

import { PageConfig, URLExt } from '@jupyterlab/coreutils';
import '../style/index.css';

export {
Expand Down
9 changes: 6 additions & 3 deletions packages/voila/src/kernel.js → packages/voila/src/kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
import { Kernel, ServerConnection } from '@jupyterlab/services';
import { PageConfig } from '@jupyterlab/coreutils';

export async function connectKernel(baseUrl, kernelId) {
export async function connectKernel(
baseUrl: string,
kernelId: string
): Promise<Kernel.IKernel> {
baseUrl = baseUrl || PageConfig.getBaseUrl();
kernelId = kernelId || PageConfig.getOption('kernelId');
const connectionInfo = ServerConnection.makeSettings({ baseUrl });

let model = await Kernel.findById(kernelId, connectionInfo);
let kernel = await Kernel.connectTo(model, connectionInfo);
const model = await Kernel.findById(kernelId, connectionInfo);
const kernel = Kernel.connectTo(model, connectionInfo);
return kernel;
}
19 changes: 11 additions & 8 deletions packages/voila/src/loader.js → packages/voila/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

let cdn = 'https://unpkg.com/';
const cdn = 'https://unpkg.com/';

/**
* Load a package using requirejs and return a promise
*
* @param pkg Package name or names to load
*/
let requirePromise = function(pkg) {
const requirePromise = function(pkg: string[]) {
return new Promise((resolve, reject) => {
let require = window.requirejs;
const require = window.requirejs;
if (require === undefined) {
reject('Requirejs is needed, please ensure it is loaded on the page.');
} else {
Expand All @@ -25,7 +25,7 @@ let requirePromise = function(pkg) {
});
};

function moduleNameToCDNUrl(moduleName, moduleVersion) {
function moduleNameToCDNUrl(moduleName: string, moduleVersion: string) {
let packageName = moduleName;
let fileName = 'index'; // default filename
// if a '/' is present, like 'foo/bar', packageName is changed to 'foo', and path to 'bar'
Expand Down Expand Up @@ -56,18 +56,21 @@ function moduleNameToCDNUrl(moduleName, moduleVersion) {
*
* The semver range is only used with the CDN.
*/
export function requireLoader(moduleName, moduleVersion) {
export function requireLoader(
moduleName: string,
moduleVersion: string
): Promise<any> {
return requirePromise([`${moduleName}`]).catch(err => {
let failedId = err.requireModules && err.requireModules[0];
const failedId = err.requireModules && err.requireModules[0];
if (failedId) {
console.log(`Falling back to ${cdn} for ${moduleName}@${moduleVersion}`);
let require = window.requirejs;
const require = window.requirejs;
if (require === undefined) {
throw new Error(
'Requirejs is needed, please ensure it is loaded on the page.'
);
}
const conf = { paths: {} };
const conf: { paths: { [key: string]: string } } = { paths: {} };
conf.paths[moduleName] = moduleNameToCDNUrl(moduleName, moduleVersion);
require.undef(failedId);
require.config(conf);
Expand Down
64 changes: 42 additions & 22 deletions packages/voila/src/manager.js → packages/voila/src/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import * as AppUtils from '@jupyterlab/apputils';
import * as CoreUtils from '@jupyterlab/coreutils';
import * as DocRegistry from '@jupyterlab/docregistry';
import * as OutputArea from '@jupyterlab/outputarea';
import { DocumentRegistry } from '@jupyterlab/docregistry';
import { INotebookModel } from '@jupyterlab/notebook';
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';

import * as PhosphorWidget from '@phosphor/widgets';
import * as PhosphorSignaling from '@phosphor/signaling';
Expand All @@ -31,6 +34,7 @@ import { MessageLoop } from '@phosphor/messaging';

import { requireLoader } from './loader';
import { batchRateMap } from './utils';
import { Widget } from '@phosphor/widgets';

if (typeof window !== 'undefined' && typeof window.define !== 'undefined') {
window.define('@jupyter-widgets/base', base);
Expand All @@ -54,7 +58,11 @@ if (typeof window !== 'undefined' && typeof window.define !== 'undefined') {
const WIDGET_MIMETYPE = 'application/vnd.jupyter.widget-view+json';

export class WidgetManager extends JupyterLabManager {
constructor(context, rendermime, settings) {
constructor(
context: DocumentRegistry.IContext<INotebookModel>,
rendermime: IRenderMimeRegistry,
settings: JupyterLabManager.Settings
) {
super(context, rendermime, settings);
rendermime.addFactory(
{
Expand All @@ -65,23 +73,26 @@ export class WidgetManager extends JupyterLabManager {
1
);
this._registerWidgets();
this.loader = requireLoader;
this._loader = requireLoader;
}

async build_widgets() {
async build_widgets(): Promise<void> {
const models = await this._build_models();
const tags = document.body.querySelectorAll(
'script[type="application/vnd.jupyter.widget-view+json"]'
);
for (let i = 0; i !== tags.length; ++i) {
tags.forEach(async viewtag => {
if (!viewtag?.parentElement) {
return;
}
try {
const viewtag = tags[i];
const widgetViewObject = JSON.parse(viewtag.innerHTML);
const { model_id } = widgetViewObject;
const model = models[model_id];
const widgetel = document.createElement('div');
viewtag.parentElement.insertBefore(widgetel, viewtag);
const view = await this.display_model(undefined, model, {
// TODO: fix typing
await this.display_model(undefined as any, model, {
el: widgetel
});
} catch (error) {
Expand All @@ -95,16 +106,16 @@ export class WidgetManager extends JupyterLabManager {
// This workaround may not be necessary anymore with templates that make use
// of progressive rendering.
}
}
});
}

display_view(msg, view, options) {
async display_view(msg: any, view: any, options: any): Promise<Widget> {
if (options.el) {
PhosphorWidget.Widget.attach(view.pWidget, options.el);
}
if (view.el) {
view.el.setAttribute('data-voila-jupyter-widget', '');
view.el.addEventListener('jupyterWidgetResize', e => {
view.el.addEventListener('jupyterWidgetResize', (e: Event) => {
MessageLoop.postMessage(
view.pWidget,
PhosphorWidget.Widget.ResizeMessage.UnknownSize
Expand All @@ -114,7 +125,11 @@ export class WidgetManager extends JupyterLabManager {
return view.pWidget;
}

async loadClass(className, moduleName, moduleVersion) {
async loadClass(
className: string,
moduleName: string,
moduleVersion: string
): Promise<any> {
if (
moduleName === '@jupyter-widgets/base' ||
moduleName === '@jupyter-widgets/controls' ||
Expand All @@ -123,7 +138,7 @@ export class WidgetManager extends JupyterLabManager {
return super.loadClass(className, moduleName, moduleVersion);
} else {
// TODO: code duplicate from HTMLWidgetManager, consider a refactor
return this.loader(moduleName, moduleVersion).then(module => {
return this._loader(moduleName, moduleVersion).then(module => {
if (module[className]) {
return module[className];
} else {
Expand All @@ -140,30 +155,31 @@ export class WidgetManager extends JupyterLabManager {
}
}

// eslint-disable-next-line @typescript-eslint/no-empty-function
restoreWidgets(notebook) {}
restoreWidgets(notebook: INotebookModel): Promise<void> {
return Promise.resolve();
}

_registerWidgets() {
private _registerWidgets(): void {
this.register({
name: '@jupyter-widgets/base',
version: base.JUPYTER_WIDGETS_VERSION,
exports: base
exports: base as any
});
this.register({
name: '@jupyter-widgets/controls',
version: controls.JUPYTER_CONTROLS_VERSION,
exports: controls
exports: controls as any
});
this.register({
name: '@jupyter-widgets/output',
version: output.OUTPUT_WIDGET_VERSION,
exports: output
exports: output as any
});
}

async _build_models() {
async _build_models(): Promise<{ [key: string]: base.WidgetModel }> {
const comm_ids = await this._get_comm_info();
const models = {};
const models: { [key: string]: base.WidgetModel } = {};
/**
* For the classical notebook, iopub_msg_rate_limit=1000 (default)
* And for zmq, we are affected by the default ZMQ_SNDHWM setting of 1000
Expand All @@ -184,13 +200,13 @@ export class WidgetManager extends JupyterLabManager {

await Promise.all(
widgets_info.map(async widget_info => {
const state = widget_info.msg.content.data.state;
const state = (widget_info as any).msg.content.data.state;
const modelPromise = this.new_model(
{
model_name: state._model_name,
model_module: state._model_module,
model_module_version: state._model_module_version,
comm: widget_info.comm
comm: (widget_info as any).comm
},
state
);
Expand All @@ -202,7 +218,9 @@ export class WidgetManager extends JupyterLabManager {
return models;
}

async _update_comm(comm) {
async _update_comm(
comm: base.IClassicComm
): Promise<{ comm: base.IClassicComm; msg: any }> {
return new Promise((resolve, reject) => {
comm.on_msg(async msg => {
if (msg.content.data.buffer_paths) {
Expand All @@ -219,4 +237,6 @@ export class WidgetManager extends JupyterLabManager {
comm.send({ method: 'request_state' }, {});
});
}

private _loader: (name: any, version: any) => Promise<any>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ RegisterHTMLHandler(browserAdaptor());

// Override dynamically generated fonts in favor
// of our font css that is picked up by webpack.
class emptyFont extends TeXFont {}
emptyFont.defaultFonts = {};
class emptyFont extends TeXFont {
readonly defaultFonts = {};
}

const chtml = new CHTML({
font: new emptyFont()
Expand All @@ -47,7 +48,7 @@ const html = mathjax.document(document, {
OutputJax: chtml
});

export function renderMathJax() {
export function renderMathJax(): void {
html
.findMath()
.compile()
Expand Down
5 changes: 5 additions & 0 deletions packages/voila/src/typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// eslint-disable-next-line @typescript-eslint/naming-convention
declare interface Window {
define: any;
requirejs: any;
}
11 changes: 8 additions & 3 deletions packages/voila/src/utils.js → packages/voila/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import pLimit from 'p-limit';

const delay = sec => new Promise(resolve => setTimeout(resolve, sec * 1000));
const delay = (sec: number) =>
new Promise(resolve => setTimeout(resolve, sec * 1000));

/**
* Map a function onto a list where fn is being called at a limit of 'rate' number of calls per second.
* and 'room' number of parallel calls.
* Note that the minimum window at which rate is respected is room/rate seconds.
*/
export const batchRateMap = (list, fn, { room, rate }) => {
var limit = pLimit(room);
export const batchRateMap = (
list: string[],
fn: (...args: any[]) => Promise<any>,
{ room, rate }: { room: number; rate: number }
): Promise<any>[] => {
const limit = pLimit(room);
return list.map(async value => {
return new Promise((valueResolve, reject) => {
limit(() => {
Expand Down
8 changes: 8 additions & 0 deletions packages/voila/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfigbase",
"compilerOptions": {
"outDir": "lib",
"rootDir": "src"
},
"include": ["src/**/*"]
}
Loading

0 comments on commit 4cf9585

Please sign in to comment.