@@ -160,13 +160,6 @@ def get_uid_str(uid):
160160const React = await importWithMap("react", importMap);
161161const { createRoot } = await importWithMap("react-dom/client", importMap);
162162
163- function asEsModule(component) {
164- return {
165- __esModule: true,
166- default: component,
167- };
168- }
169-
170163const e = React.createElement;
171164
172165const 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
311366class 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