Skip to content

Commit 7b1458b

Browse files
authored
Support for plugins (#324)
* Support plugin_esm * Support for plugins * Update widget.py * Lint
1 parent 83b1411 commit 7b1458b

File tree

2 files changed

+78
-13
lines changed

2 files changed

+78
-13
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "vitessce"
7-
version = "3.2.1"
7+
version = "3.2.2"
88
authors = [
99
{ name="Mark Keller", email="[email protected]" },
1010
]

vitessce/widget.py

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,6 @@ def get_uid_str(uid):
160160
const React = await importWithMap("react", importMap);
161161
const { createRoot } = await importWithMap("react-dom/client", importMap);
162162
163-
function asEsModule(component) {
164-
return {
165-
__esModule: true,
166-
default: component,
167-
};
168-
}
169-
170163
const e = React.createElement;
171164
172165
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
@@ -206,6 +199,8 @@ def get_uid_str(uid):
206199
const jsDevMode = view.model.get('js_dev_mode');
207200
const jsPackageVersion = view.model.get('js_package_version');
208201
const customJsUrl = view.model.get('custom_js_url');
202+
const pluginEsm = view.model.get('plugin_esm');
203+
const remountOnUidChange = view.model.get('remount_on_uid_change');
209204
210205
const pkgName = (jsDevMode ? "@vitessce/dev" : "vitessce");
211206
@@ -214,7 +209,42 @@ def get_uid_str(uid):
214209
: `https://unpkg.com/${pkgName}@${jsPackageVersion}`
215210
);
216211
217-
const { Vitessce } = await importWithMap("vitessce", importMap);
212+
const {
213+
Vitessce,
214+
PluginFileType,
215+
PluginViewType,
216+
PluginCoordinationType,
217+
PluginJointFileType,
218+
z,
219+
useCoordination,
220+
} = await importWithMap("vitessce", importMap);
221+
222+
let pluginViewTypes;
223+
let pluginCoordinationTypes;
224+
let pluginFileTypes;
225+
let pluginJointFileTypes;
226+
227+
try {
228+
const pluginEsmUrl = URL.createObjectURL(new Blob([pluginEsm], { type: "text/javascript" }));
229+
const pluginModule = (await import(pluginEsmUrl)).default;
230+
URL.revokeObjectURL(pluginEsmUrl);
231+
232+
const pluginsObj = await pluginModule.createPlugins({
233+
React,
234+
PluginFileType,
235+
PluginViewType,
236+
PluginCoordinationType,
237+
PluginJointFileType,
238+
z,
239+
useCoordination,
240+
});
241+
pluginViewTypes = pluginsObj.pluginViewTypes;
242+
pluginCoordinationTypes = pluginsObj.pluginCoordinationTypes;
243+
pluginFileTypes = pluginsObj.pluginFileTypes;
244+
pluginJointFileTypes = pluginsObj.pluginJointFileTypes;
245+
} catch(e) {
246+
console.error(e);
247+
}
218248
219249
function VitessceWidget(props) {
220250
const { model } = props;
@@ -277,7 +307,11 @@ def get_uid_str(uid):
277307
});
278308
}, []);
279309
280-
const vitessceProps = { height, theme, config, onConfigChange, validateConfig };
310+
const vitessceProps = {
311+
height, theme, config, onConfigChange, validateConfig,
312+
pluginViewTypes, pluginCoordinationTypes, pluginFileTypes, pluginJointFileTypes,
313+
remountOnUidChange,
314+
};
281315
282316
return e('div', { ref: divRef, style: { height: height + 'px' } },
283317
e(React.Suspense, { fallback: e('div', {}, 'Loading...') },
@@ -307,6 +341,27 @@ def get_uid_str(uid):
307341
}
308342
"""
309343

344+
DEFAULT_PLUGIN_ESM = """
345+
function createPlugins(utilsForPlugins) {
346+
const {
347+
React,
348+
PluginFileType,
349+
PluginViewType,
350+
PluginCoordinationType,
351+
PluginJointFileType,
352+
z,
353+
useCoordination,
354+
} = utilsForPlugins;
355+
return {
356+
pluginViewTypes: undefined,
357+
pluginFileTypes: undefined,
358+
pluginCoordinationTypes: undefined,
359+
pluginJointFileTypes: undefined,
360+
};
361+
}
362+
export default { createPlugins };
363+
"""
364+
310365

311366
class VitessceWidget(anywidget.AnyWidget):
312367
"""
@@ -327,11 +382,13 @@ class VitessceWidget(anywidget.AnyWidget):
327382

328383
next_port = DEFAULT_PORT
329384

330-
js_package_version = Unicode('3.3.3').tag(sync=True)
385+
js_package_version = Unicode('3.3.6').tag(sync=True)
331386
js_dev_mode = Bool(False).tag(sync=True)
332387
custom_js_url = Unicode('').tag(sync=True)
388+
plugin_esm = Unicode(DEFAULT_PLUGIN_ESM).tag(sync=True)
389+
remount_on_uid_change = Bool(True).tag(sync=True)
333390

334-
def __init__(self, config, height=600, theme='auto', uid=None, port=None, proxy=False, js_package_version='3.3.3', js_dev_mode=False, custom_js_url=''):
391+
def __init__(self, config, height=600, theme='auto', uid=None, port=None, proxy=False, js_package_version='3.3.6', js_dev_mode=False, custom_js_url='', plugin_esm=DEFAULT_PLUGIN_ESM, remount_on_uid_change=True):
335392
"""
336393
Construct a new Vitessce widget.
337394
@@ -341,6 +398,11 @@ def __init__(self, config, height=600, theme='auto', uid=None, port=None, proxy=
341398
:param int height: The height of the widget, in pixels. By default, 600.
342399
:param int port: The port to use when serving data objects on localhost. By default, 8000.
343400
:param bool proxy: Is this widget being served through a proxy, for example with a cloud notebook (e.g. Binder)?
401+
:param str js_package_version: The version of the NPM package ('vitessce' if not js_dev_mode else '@vitessce/dev').
402+
:param bool js_dev_mode: Should @vitessce/dev be used (typically for debugging purposes)? By default, False.
403+
:param str custom_js_url: A URL to a JavaScript file to use (instead of 'vitessce' or '@vitessce/dev' NPM package).
404+
:param str plugin_esm: JavaScript module that defines a createPlugins function. Optional.
405+
:param bool remount_on_uid_change: Passed to the remountOnUidChange prop of the <Vitessce/> React component. By default, True.
344406
345407
.. code-block:: python
346408
:emphasize-lines: 4
@@ -364,6 +426,7 @@ def __init__(self, config, height=600, theme='auto', uid=None, port=None, proxy=
364426
super(VitessceWidget, self).__init__(
365427
config=config_dict, height=height, theme=theme, proxy=proxy,
366428
js_package_version=js_package_version, js_dev_mode=js_dev_mode, custom_js_url=custom_js_url,
429+
plugin_esm=plugin_esm, remount_on_uid_change=remount_on_uid_change,
367430
uid=uid_str,
368431
)
369432

@@ -399,7 +462,7 @@ def close(self):
399462
# Launch Vitessce using plain HTML representation (no ipywidgets)
400463

401464

402-
def ipython_display(config, height=600, theme='auto', base_url=None, host_name=None, uid=None, port=None, proxy=False, js_package_version='3.3.3', js_dev_mode=False, custom_js_url=''):
465+
def ipython_display(config, height=600, theme='auto', base_url=None, host_name=None, uid=None, port=None, proxy=False, js_package_version='3.3.6', js_dev_mode=False, custom_js_url='', plugin_esm=DEFAULT_PLUGIN_ESM, remount_on_uid_change=True):
403466
from IPython.display import display, HTML
404467
uid_str = "vitessce" + get_uid_str(uid)
405468

@@ -414,6 +477,8 @@ def ipython_display(config, height=600, theme='auto', base_url=None, host_name=N
414477
"js_package_version": js_package_version,
415478
"js_dev_mode": js_dev_mode,
416479
"custom_js_url": custom_js_url,
480+
"plugin_esm": plugin_esm,
481+
"remount_on_uid_change": remount_on_uid_change,
417482
"proxy": proxy,
418483
"has_host_name": host_name is not None,
419484
"height": height,

0 commit comments

Comments
 (0)