Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TypeScript and tsconfig.json #818

Merged
merged 7 commits into from
Feb 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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