-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
546 additions
and
249 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
const registeredTransports = []; | ||
|
||
export default class Transport { | ||
static registerTransport(transport) { | ||
registeredTransports.push(transport); | ||
} | ||
|
||
static getDefaultTransport() { | ||
if (registeredTransports.length === 0) { | ||
throw new Error('No JSON transport registered'); | ||
} | ||
return registeredTransports[0]; | ||
} | ||
|
||
static getTransport(name, fallback = true) { | ||
let transport = registeredTransports.find(transport_ => transport_.name.startsWith(name)); | ||
if (!transport && fallback) { | ||
transport = Transport.getDefaultTransport(); | ||
} | ||
return transport; | ||
} | ||
|
||
constructor(name = 'Transport') { | ||
this.name = name; | ||
|
||
// Set up an initialization promise, so that we can defer the call of onInitialize | ||
this._initPromise = new Promise((resolve, reject) => { | ||
this._initResolvers = {resolve, reject}; | ||
}); | ||
this._messageQueue = []; | ||
|
||
this.userData = {}; | ||
|
||
this.onIninitialize = _ => _; | ||
this.onFinalize = _ => _; | ||
this.onMessage = null; | ||
} | ||
|
||
setCallbacks({onInitialize, onFinalize, onMessage}) { | ||
if (onInitialize) { | ||
this.onInitialize = onInitialize; | ||
} | ||
if (onFinalize) { | ||
this._onFinalize = onFinalize; | ||
} | ||
if (onMessage) { | ||
this._onMessage = onMessage; | ||
} | ||
|
||
if (onInitialize) { | ||
this._initPromise.then(initArgs => { | ||
onInitialize(initArgs); | ||
|
||
if (this._onMessage) { | ||
// Send any queued messages | ||
let message; | ||
while ((message = this._messageQueue.pop())) { | ||
console.debug('Delivering queued transport message', message); // eslint-disable-line | ||
this._onMessage(message); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
|
||
// Back-channel messaging | ||
sendJSONMessage() { | ||
// eslint-disable-next-line | ||
console.error('Back-channel not implemented for this transport'); | ||
} | ||
|
||
sendBinaryMessage() { | ||
// eslint-disable-next-line | ||
console.error('Back-channel not implemented for this transport'); | ||
} | ||
|
||
// | ||
// API for transports (not intended for apps) | ||
// | ||
|
||
_initialize(options = {}) { | ||
console.debug('Resolving init promise', options); // eslint-disable-line | ||
this._initResolvers.resolve({transport: this, ...options}); | ||
} | ||
|
||
_finalize(options = {}) { | ||
// TODO - could potentially be called without Initialize being called | ||
this.onFinalize({transport: this, ...options}); | ||
this._destroyed = true; | ||
} | ||
|
||
_messageReceived(message = {}) { | ||
message = {transport: this, ...message}; | ||
|
||
// TODO - could potentially be called without Initialize being called | ||
if (!this.onMessage) { | ||
console.debug('Queueing transport message', message); // eslint-disable-line | ||
this._messageQueue.push(message); | ||
return; | ||
} | ||
|
||
console.debug('Delivering transport message', message); // eslint-disable-line | ||
this.onMessage(message); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Transport | ||
|
||
The `Transport` base class is intended to abstract a number of client-host communication mechanisms, including: | ||
|
||
- Jupyter Widget based communication between a browser and a notebook | ||
- Browser: `postMessage` based communication between tabs and iframes | ||
- Android: Communication between Java application and JavaScript running in a `WebView` component | ||
- iOS: Communication between Swift and JavaScript running in a `UIWebView` component | ||
|
||
Longer term goals: | ||
|
||
- `WebSocket` based transport | ||
- Possibly add additional transports such as Colab notebook specific APIs. | ||
|
||
## Features | ||
|
||
- Binary data | ||
- Back-channel: Events | ||
- Back-channel: Errors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import {DOMWidgetModel} from '@jupyter-widgets/base'; | ||
import {MODULE_NAME, MODULE_VERSION} from '../version'; | ||
import {deserializeMatrix} from './utils/deserialize-matrix'; | ||
/** | ||
* | ||
* Note: Variables shared explictly between Python and JavaScript use snake_case | ||
*/ | ||
export default class JupyterTransportModel extends DOMWidgetModel { | ||
defaults() { | ||
return { | ||
...super.defaults(), | ||
_model_name: JupyterTransportModel.model_name, | ||
_model_module: JupyterTransportModel.model_module, | ||
_model_module_version: JupyterTransportModel.model_module_version, | ||
_view_name: JupyterTransportModel.view_name, | ||
_view_module: JupyterTransportModel.view_module, | ||
_view_module_version: JupyterTransportModel.view_module_version, | ||
custom_libraries: [], | ||
json_input: null, | ||
mapbox_key: null, | ||
selected_data: [], | ||
data_buffer: null, | ||
tooltip: null, | ||
width: '100%', | ||
height: 500, | ||
js_warning: false | ||
}; | ||
} | ||
|
||
static get serializers() { | ||
return { | ||
...DOMWidgetModel.serializers, | ||
// Add any extra serializers here | ||
data_buffer: {deserialize: deserializeMatrix} | ||
}; | ||
} | ||
|
||
static get model_name() { | ||
return 'JupyterTransportModel'; | ||
} | ||
static get model_module() { | ||
return MODULE_NAME; | ||
} | ||
static get model_module_version() { | ||
return MODULE_VERSION; | ||
} | ||
static get view_name() { | ||
return 'JupyterTransportView'; | ||
} | ||
static get view_module() { | ||
return MODULE_NAME; | ||
} | ||
static get view_module_version() { | ||
return MODULE_VERSION; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import {DOMWidgetView} from '@jupyter-widgets/base'; | ||
import {jupyterTransport} from './jupyter-transport'; | ||
|
||
export default class JupyterTransportView extends DOMWidgetView { | ||
initialize() { | ||
this.listenTo(this.model, 'destroy', this.remove); | ||
|
||
this.transport = jupyterTransport; | ||
|
||
// Expose Jupyter internals to enable work-arounds | ||
this.transport.jupyterModel = this.model; | ||
this.transport.jupyterView = this; | ||
this.transport._initialize(); | ||
} | ||
|
||
remove() { | ||
if (this.transport) { | ||
this.transport._finalize(); | ||
this.transport.jupyterModel = null; | ||
this.transport.jupyterView = null; | ||
this.transport = null; | ||
} | ||
} | ||
|
||
render() { | ||
super.render(); | ||
|
||
// TODO - looks like bind(this) is not needed here, it is already passed as 3rd arg... | ||
// TODO - remove and test | ||
this.model.on('change:json_input', this.onJsonChanged.bind(this), this); | ||
this.model.on('change:data_buffer', this.onDataBufferChanged.bind(this), this); | ||
|
||
this.onDataBufferChanged(); | ||
} | ||
|
||
onJsonChanged() { | ||
const json = JSON.parse(this.model.get('json_input')); | ||
this.transport._messageReceived({type: 'json', json}); | ||
} | ||
|
||
onDataBufferChanged() { | ||
const json = this.model.get('json_input'); | ||
const dataBuffer = this.model.get('data_buffer'); | ||
|
||
if (json && dataBuffer) { | ||
this.transport._messageReceived({ | ||
type: 'json-with-binary', | ||
json, | ||
binary: dataBuffer | ||
}); | ||
} else { | ||
this.transport._messageReceived({type: 'json', json}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Jupyter Widget based Transport implementation | ||
|
||
import {Transport} from '@deck.gl/json'; | ||
|
||
/** | ||
* A Transport subclass for communicating with Jupyter kernels | ||
* via the Jupyter Widget API. | ||
*/ | ||
export default class JupyterTransport extends Transport { | ||
constructor() { | ||
super('Jupyter Transport (JavaScript <=> Jupyter Kernel)'); | ||
this.jupyterModel = null; // Set manually by the Jupyter Widget View | ||
this.jupyterView = null; // Set manually by the Jupyter Widget View | ||
} | ||
|
||
// TODO - implement back-channel messaging for event handling etc | ||
sendJsonMessage({json, type}) { | ||
// this.jupyterModel. ... | ||
} | ||
} | ||
|
||
export const jupyterTransport = new JupyterTransport(); | ||
|
||
Transport.registerTransport(jupyterTransport); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 5 additions & 7 deletions
12
modules/jupyter-widget/src/create-deck.js → ...yter-widget/src/playground/create-deck.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export {initPlayground} from './playground'; | ||
|
||
// For to_html()... | ||
export {createDeck, updateDeck} from './create-deck'; |
Oops, something went wrong.