Skip to content

Commit

Permalink
Use proper bokehjs' type in src/widgets.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
mattpap committed Mar 7, 2023
1 parent 560c2ed commit bbe4cbe
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 100 deletions.
26 changes: 1 addition & 25 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,5 @@ module.exports = {
},
plugins: ['@typescript-eslint'],
rules: {
'@typescript-eslint/naming-convention': [
'warn',
{
'selector': 'interface',
'format': ['PascalCase'],
'custom': {
'regex': '^I[A-Z]',
'match': true
}
}
],
'@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-namespace': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/quotes': [
'error',
'single',
{ avoidEscape: true, allowTemplateLiterals: false }
],
curly: ['error', 'all'],
semi: ['warn', 'never'],
eqeqeq: 'warn',
'prefer-arrow-callback': 'error'
}
};
}
11 changes: 11 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"style-loader": "^2.0.0"
},
"devDependencies": {
"@bokeh/bokehjs": "^3.1.0rc.1",
"@jupyterlab/builder": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^4.8.1",
"@typescript-eslint/parser": "^4.8.1",
Expand Down
119 changes: 45 additions & 74 deletions src/widgets.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,43 @@
import { DOMWidgetModel, DOMWidgetView } from '@jupyter-widgets/base'
import {DOMWidgetModel, DOMWidgetView} from "@jupyter-widgets/base"

//import {Document, DocumentChangedEvent, ModelChangedEvent} from "document"
//import {Receiver, Fragment} from "protocol/receiver"
//import {keys, values} from "core/util/object"
// Use only `import type`, so that all imports are erased at run time
import type {Document, DocJson, Patch, DocumentChangedEvent} from "@bokeh/bokehjs/document"
import type {DocumentChanged} from "@bokeh/bokehjs/document/events"
import type {Receiver, Fragment} from "@bokeh/bokehjs/protocol/receiver"
import type {RenderItem} from "@bokeh/bokehjs/embed/json"
import type {Serializer} from "@bokeh/bokehjs/core/serialization"
import type {add_document_standalone} from "@bokeh/bokehjs/embed/standalone"

import { name, version } from './metadata'
import {name, version} from './metadata'

function bk_require(name: string): any {
return (window as any).Bokeh.require(name)
declare const Bokeh: {require(name: string): unknown}

function bk_require<T>(name: string): T {
return Bokeh.require(name) as T
}

type DocsJson = any
type RenderItem = any
type Document = any
type DocumentChangedEvent = any
type Receiver = any
type Fragment = any
declare const Jupyter: {notebook?: unknown}

declare function require(name: string): unknown

const { keys, values } = Object
const {keys, values} = Object

const version_range = `^${version}`

export type RenderBundle = {
docs_json: DocsJson
docs_json: DocJson[]
render_items: RenderItem[]
div: string
}

export interface DocumentChanged {
event: 'jsevent'
kind: string
}

export interface ModelChanged extends DocumentChanged {
event: 'jsevent'
kind: 'ModelChanged'
id: string
new: unknown
attr: string
}

export interface MessageSent extends DocumentChanged {
event: 'jsevent'
kind: 'MessageSent'
msg_data: {
event_name: string
event_values: {
model: { id: string }
[other: string]: any
}
}
msg_type: string
/*
declare interface DocumentChanged {
event: "jsevent"
}
*/

export class BokehModel extends DOMWidgetModel {
defaults(): any {
defaults(): {[key: string]: unknown} {
return {
...super.defaults(),

Expand All @@ -67,7 +50,7 @@ export class BokehModel extends DOMWidgetModel {
_view_module_version: version_range,

combine_events: false,
render_bundle: {}
render_bundle: {},
}
}

Expand All @@ -80,7 +63,7 @@ export class BokehView extends DOMWidgetView {
private _document: Document | null
private _receiver: Receiver
private _blocked: boolean
private _msgs: any[]
private _msgs: DocumentChanged[]
private _idle: boolean
private _combine: boolean

Expand All @@ -91,15 +74,12 @@ export class BokehView extends DOMWidgetView {
this._idle = true
this._combine = true
this._msgs = []
const { Receiver } = bk_require('protocol/receiver')
const {Receiver} = bk_require('protocol/receiver')
this._receiver = new Receiver()
this.model.on('change:render_bundle', () => this.render())
if (
(window as any).Jupyter != null &&
(window as any).Jupyter.notebook != null
) {
if (Jupyter?.notebook != null) {
// Handle classic Jupyter notebook
const events = (window as any).require('base/js/events')
const events = require('base/js/events')
events.on('kernel_idle.Kernel', () => this._process_msg())
} else if ((this.model.widget_manager as any).context != null) {
// Handle JupyterLab and Voila
Expand All @@ -115,15 +95,11 @@ export class BokehView extends DOMWidgetView {
}
})
} else if (this.model.get('combine_events')) {
console.warn(
'BokehView cannot combine events because Kernel idle status cannot be determined.'
)
console.warn('BokehView cannot combine events because Kernel idle status cannot be determined.')
this._combine = false
}
} else if (this.model.get('combine_events')) {
console.warn(
'BokehView cannot combine events because Kernel idle status cannot be determined.'
)
console.warn('BokehView cannot combine events because Kernel idle status cannot be determined.')
this._combine = false
}
this.listenTo(this.model, 'msg:custom', (content, buffers) =>
Expand All @@ -145,23 +121,21 @@ export class BokehView extends DOMWidgetView {
this.el.innerHTML = div
const element = this.el.children[0]
const json = values(docs_json)[0]
const { Document } = bk_require('document')
const { add_document_standalone } = bk_require('embed/standalone')
this._document = Document.from_json(json)
const document = bk_require<{Document: typeof Document}>('document')
const standalone = bk_require<{add_document_standalone: typeof add_document_standalone}>('embed/standalone')
this._document = document.Document.from_json(json)
for (const item of render_items) {
const roots: { [key: string]: Element } = {}
const roots: {[key: string]: Element} = {}
for (const root_id in item.roots) {
roots[root_id] = element
}
add_document_standalone(this._document, element, roots)
standalone.add_document_standalone(this._document, element, roots)
}
this._document.on_change((event: any) => this._change_event(event))
this._document.on_change((event) => this._change_event(event))
}

_combine_events(
new_msg: ModelChanged | MessageSent
): (ModelChanged | MessageSent)[] {
const new_msgs = []
_combine_events(new_msg: DocumentChanged): DocumentChanged[] {
const new_msgs: DocumentChanged[] = []
for (const msg of this._msgs) {
if (new_msg.kind != msg.kind) {
new_msgs.push(msg)
Expand All @@ -184,7 +158,7 @@ export class BokehView extends DOMWidgetView {
return new_msgs
}

_send(msg: ModelChanged | MessageSent): void {
_send(msg: DocumentChanged): void {
if (!this._idle && this._combine && this.model.get('combine_events')) {
// Queue event and drop previous events on same model attribute
this._msgs = this._combine_events(msg)
Expand All @@ -198,17 +172,14 @@ export class BokehView extends DOMWidgetView {
if (this._blocked) {
return
}
const { Serializer } = bk_require('core/serialization')
const serializer = new Serializer()
const event_rep = serializer.encode(event)
event_rep.event = 'jsevent'
const serialization = bk_require<{Serializer: typeof Serializer}>("core/serialization")
const serializer = new serialization.Serializer()
const event_rep = serializer.encode(event) as DocumentChanged & {event: "jsevent"}
event_rep.event = "jsevent"
this._send(event_rep)
}

protected _consume_patch(
content: { msg: 'patch'; payload?: Fragment },
buffers: DataView[]
): void {
protected _consume_patch(content: {msg: 'patch'; payload?: Fragment}, buffers: DataView[]): void {
if (this._document == null) {
return
}
Expand All @@ -219,7 +190,7 @@ export class BokehView extends DOMWidgetView {
if (comm_msg != null && keys(comm_msg.content).length > 0) {
this._blocked = true
try {
this._document.apply_json_patch(comm_msg.content, comm_msg.buffers)
this._document.apply_json_patch(comm_msg.content as Patch, comm_msg.buffers)
} finally {
this._blocked = false
}
Expand Down
7 changes: 6 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
"strict": true,
"strictNullChecks": false,
"target": "es2017",
"types": []
"types": [],
"paths": {
"@bokeh/bokehjs/*": [
"./node_modules/@bokeh/bokehjs/build/js/lib/*"
]
}
},
"include": ["src/*"]
}

0 comments on commit bbe4cbe

Please sign in to comment.