1
- import { DOMWidgetModel , DOMWidgetView } from ' @jupyter-widgets/base'
1
+ import { DOMWidgetModel , DOMWidgetView } from " @jupyter-widgets/base"
2
2
3
- //import {Document, DocumentChangedEvent, ModelChangedEvent} from "document"
4
- //import {Receiver, Fragment} from "protocol/receiver"
5
- //import {keys, values} from "core/util/object"
3
+ // Use only `import type`, so that all imports are erased at run time
4
+ import type { Document , DocJson , Patch , DocumentChangedEvent } from "@bokeh/bokehjs/document"
5
+ import type { DocumentChanged } from "@bokeh/bokehjs/document/events"
6
+ import type { Receiver , Fragment } from "@bokeh/bokehjs/protocol/receiver"
7
+ import type { RenderItem } from "@bokeh/bokehjs/embed/json"
8
+ import type { HasProps } from "@bokeh/bokehjs/core/has_props"
9
+ import type { Ref } from "@bokeh/bokehjs/core/util/refs"
10
+ import type { Serializer } from "@bokeh/bokehjs/core/serialization"
11
+ import type { BokehEvent } from "@bokeh/bokehjs/core/bokeh_events"
12
+ import type { add_document_standalone } from "@bokeh/bokehjs/embed/standalone"
6
13
7
- import { name , version } from './metadata'
14
+ import { name , version } from './metadata'
8
15
9
- function bk_require ( name : string ) : any {
10
- return ( window as any ) . Bokeh . require ( name )
16
+ declare const Bokeh : { require ( name : string ) : unknown }
17
+
18
+ function bk_require < T > ( name : string ) : T {
19
+ return Bokeh . require ( name ) as T
11
20
}
12
21
13
- type DocsJson = any
14
- type RenderItem = any
15
- type Document = any
16
- type DocumentChangedEvent = any
17
- type Receiver = any
18
- type Fragment = any
19
- type HasProps = any
20
- type Ref = any
22
+ declare const Jupyter : { notebook ?: unknown }
23
+
24
+ declare function require ( name : string ) : unknown
21
25
22
- const { keys, values } = Object
26
+ const { keys} = Object
23
27
24
28
const version_range = `^${ version } `
25
29
26
30
export type RenderBundle = {
27
- docs_json : DocsJson
31
+ docs_json : DocJson [ ]
28
32
render_items : RenderItem [ ]
29
33
div : string
30
34
}
31
35
32
- export interface DocumentChanged {
33
- event : 'jsevent'
34
- kind : string
35
- }
36
-
37
- export interface ModelChanged extends DocumentChanged {
38
- event : 'jsevent'
39
- kind : 'ModelChanged'
40
- id : string
41
- new : unknown
42
- attr : string
43
- }
44
-
45
- export interface MessageSent extends DocumentChanged {
46
- event : 'jsevent'
47
- kind : 'MessageSent'
48
- msg_data : {
49
- event_name : string
50
- event_values : {
51
- model : { id : string }
52
- [ other : string ] : any
53
- }
54
- }
55
- msg_type : string
36
+ /*
37
+ declare interface DocumentChanged {
38
+ event: "jsevent"
56
39
}
40
+ */
57
41
58
42
export class BokehModel extends DOMWidgetModel {
59
- defaults ( ) : any {
43
+ defaults ( ) : { [ key : string ] : unknown } {
60
44
return {
61
45
...super . defaults ( ) ,
62
46
@@ -69,7 +53,7 @@ export class BokehModel extends DOMWidgetModel {
69
53
_view_module_version : version_range ,
70
54
71
55
combine_events : false ,
72
- render_bundle : { }
56
+ render_bundle : { } ,
73
57
}
74
58
}
75
59
@@ -82,26 +66,23 @@ export class BokehView extends DOMWidgetView {
82
66
private _document : Document | null
83
67
private _receiver : Receiver
84
68
private _blocked : boolean
85
- private _msgs : any [ ]
69
+ private _msgs : DocumentChanged [ ]
86
70
private _idle : boolean
87
71
private _combine : boolean
88
72
89
- constructor ( options ?: any ) {
73
+ constructor ( options ?: unknown ) {
90
74
super ( options )
91
75
this . _document = null
92
76
this . _blocked = false
93
77
this . _idle = true
94
78
this . _combine = true
95
79
this . _msgs = [ ]
96
- const { Receiver } = bk_require ( 'protocol/receiver' )
97
- this . _receiver = new Receiver ( )
80
+ const receiver = bk_require < { Receiver : typeof Receiver } > ( 'protocol/receiver' )
81
+ this . _receiver = new receiver . Receiver ( )
98
82
this . model . on ( 'change:render_bundle' , ( ) => this . render ( ) )
99
- if (
100
- ( window as any ) . Jupyter != null &&
101
- ( window as any ) . Jupyter . notebook != null
102
- ) {
83
+ if ( Jupyter ?. notebook != null ) {
103
84
// Handle classic Jupyter notebook
104
- const events = ( window as any ) . require ( 'base/js/events' )
85
+ const events = require ( 'base/js/events' )
105
86
events . on ( 'kernel_idle.Kernel' , ( ) => this . _process_msg ( ) )
106
87
} else if ( ( this . model . widget_manager as any ) . context != null ) {
107
88
// Handle JupyterLab and Voila
@@ -117,15 +98,11 @@ export class BokehView extends DOMWidgetView {
117
98
}
118
99
} )
119
100
} else if ( this . model . get ( 'combine_events' ) ) {
120
- console . warn (
121
- 'BokehView cannot combine events because Kernel idle status cannot be determined.'
122
- )
101
+ console . warn ( 'BokehView cannot combine events because Kernel idle status cannot be determined.' )
123
102
this . _combine = false
124
103
}
125
104
} else if ( this . model . get ( 'combine_events' ) ) {
126
- console . warn (
127
- 'BokehView cannot combine events because Kernel idle status cannot be determined.'
128
- )
105
+ console . warn ( 'BokehView cannot combine events because Kernel idle status cannot be determined.' )
129
106
this . _combine = false
130
107
}
131
108
this . listenTo ( this . model , 'msg:custom' , ( content , buffers ) =>
@@ -143,27 +120,25 @@ export class BokehView extends DOMWidgetView {
143
120
144
121
render ( ) : void {
145
122
const bundle = JSON . parse ( this . model . get ( 'render_bundle' ) )
146
- const { docs_json, render_items, div } = bundle as RenderBundle
123
+ const { docs_json, render_items, div} = bundle as RenderBundle
147
124
this . el . innerHTML = div
148
- const element = this . el . children [ 0 ]
149
- const json = values ( docs_json ) [ 0 ]
150
- const { Document } = bk_require ( 'document' )
151
- const { add_document_standalone } = bk_require ( 'embed/standalone' )
152
- this . _document = Document . from_json ( json )
153
- for ( const item of render_items ) {
154
- const roots : { [ key : string ] : Element } = { }
155
- for ( const root_id in item . roots ) {
156
- roots [ root_id ] = element
157
- }
158
- add_document_standalone ( this . _document , element , roots )
125
+ const element = this . el . children [ 0 ] as HTMLElement
126
+ // assumes docs_json.length == 1 && render_items.length == 1
127
+ const doc_json = docs_json [ 0 ]
128
+ const render_item = render_items [ 0 ]
129
+ const document = bk_require < { Document : typeof Document } > ( 'document' )
130
+ const standalone = bk_require < { add_document_standalone : typeof add_document_standalone } > ( 'embed/standalone' )
131
+ this . _document = document . Document . from_json ( doc_json )
132
+ const roots : { [ key : string ] : HTMLElement } = { }
133
+ for ( const root_id in render_item . roots ) {
134
+ roots [ root_id ] = element
159
135
}
160
- this . _document . on_change ( ( event : any ) => this . _change_event ( event ) )
136
+ standalone . add_document_standalone ( this . _document , element , roots )
137
+ this . _document . on_change ( ( event ) => this . _change_event ( event ) )
161
138
}
162
139
163
- _combine_events (
164
- new_msg : ModelChanged | MessageSent
165
- ) : ( ModelChanged | MessageSent ) [ ] {
166
- const new_msgs = [ ]
140
+ _combine_events ( new_msg : DocumentChanged ) : DocumentChanged [ ] {
141
+ const new_msgs : DocumentChanged [ ] = [ ]
167
142
for ( const msg of this . _msgs ) {
168
143
if ( new_msg . kind != msg . kind ) {
169
144
new_msgs . push ( msg )
@@ -172,11 +147,13 @@ export class BokehView extends DOMWidgetView {
172
147
new_msgs . push ( msg )
173
148
}
174
149
} else if ( msg . kind == 'MessageSent' && new_msg . kind == 'MessageSent' ) {
150
+ // assert msg.msg_type == "bokeh_event"
151
+ const data = msg . msg_data as BokehEvent
152
+ const new_data = new_msg . msg_data as BokehEvent
175
153
if (
176
- msg . msg_data . event_values . model == null ||
177
- msg . msg_data . event_values . model . id !=
178
- new_msg . msg_data . event_values . model . id ||
179
- msg . msg_data . event_name != new_msg . msg_data . event_name
154
+ data . event_values . model == null ||
155
+ data . event_values . model . id != new_data . event_values . model . id ||
156
+ data . event_name != new_data . event_name
180
157
) {
181
158
new_msgs . push ( msg )
182
159
}
@@ -186,7 +163,7 @@ export class BokehView extends DOMWidgetView {
186
163
return new_msgs
187
164
}
188
165
189
- _send ( msg : ModelChanged | MessageSent ) : void {
166
+ _send ( msg : DocumentChanged ) : void {
190
167
if ( ! this . _idle && this . _combine && this . model . get ( 'combine_events' ) ) {
191
168
// Queue event and drop previous events on same model attribute
192
169
this . _msgs = this . _combine_events ( msg )
@@ -200,21 +177,18 @@ export class BokehView extends DOMWidgetView {
200
177
if ( this . _blocked ) {
201
178
return
202
179
}
203
- const { Serializer } = bk_require ( ' core/serialization' )
180
+ const serialization = bk_require < { Serializer : typeof Serializer } > ( " core/serialization" )
204
181
const references : Map < HasProps , Ref > = new Map ( )
205
182
for ( const model of event . document . _all_models . values ( ) ) {
206
183
references . set ( model , model . ref ( ) )
207
184
}
208
- const serializer = new Serializer ( { references} )
209
- const event_rep = serializer . encode ( event )
210
- event_rep . event = ' jsevent'
185
+ const serializer = new serialization . Serializer ( { references} )
186
+ const event_rep = serializer . encode ( event ) as DocumentChanged & { event : "jsevent" }
187
+ event_rep . event = " jsevent"
211
188
this . _send ( event_rep )
212
189
}
213
190
214
- protected _consume_patch (
215
- content : { msg : 'patch' ; payload ?: Fragment } ,
216
- buffers : DataView [ ]
217
- ) : void {
191
+ protected _consume_patch ( content : { msg : 'patch' ; payload ?: Fragment } , buffers : DataView [ ] ) : void {
218
192
if ( this . _document == null ) {
219
193
return
220
194
}
@@ -225,7 +199,7 @@ export class BokehView extends DOMWidgetView {
225
199
if ( comm_msg != null && keys ( comm_msg . content ) . length > 0 ) {
226
200
this . _blocked = true
227
201
try {
228
- this . _document . apply_json_patch ( comm_msg . content , comm_msg . buffers )
202
+ this . _document . apply_json_patch ( comm_msg . content as Patch , comm_msg . buffers )
229
203
} finally {
230
204
this . _blocked = false
231
205
}
0 commit comments