@jbrowse/core 1.6.7 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/BaseFeatureWidget/BaseFeatureDetail.d.ts +2 -2
  2. package/PluginLoader.d.ts +11 -3
  3. package/PluginLoader.js +37 -89
  4. package/PluginManager.d.ts +2 -2
  5. package/PluginManager.js +4 -6
  6. package/ReExports/modules.d.ts +2 -2
  7. package/assemblyManager/assemblyManager.d.ts +21 -21
  8. package/configuration/util.js +1 -5
  9. package/data_adapters/BaseAdapter.js +70 -108
  10. package/package.json +5 -8
  11. package/pluggableElementTypes/WidgetType.d.ts +1 -2
  12. package/pluggableElementTypes/models/BaseViewModel.js +1 -1
  13. package/pluggableElementTypes/models/InternetAccountModel.js +51 -69
  14. package/pluggableElementTypes/renderers/FeatureRendererType.js +14 -19
  15. package/rpc/BaseRpcDriver.d.ts +7 -8
  16. package/rpc/BaseRpcDriver.js +35 -44
  17. package/rpc/BaseRpcDriver.test.js +2 -2
  18. package/rpc/RpcManager.js +29 -11
  19. package/rpc/WebWorkerRpcDriver.d.ts +2 -6
  20. package/rpc/WebWorkerRpcDriver.js +6 -5
  21. package/rpc/configSchema.js +14 -6
  22. package/ui/App.js +13 -17
  23. package/ui/AssemblySelector.d.ts +4 -1
  24. package/ui/AssemblySelector.js +69 -8
  25. package/ui/PrerenderedCanvas.js +1 -26
  26. package/ui/ViewContainer.d.ts +5 -5
  27. package/ui/ViewContainer.js +12 -7
  28. package/util/index.d.ts +12 -5
  29. package/util/index.js +47 -26
  30. package/util/io/index.js +3 -1
  31. package/util/layouts/BaseLayout.d.ts +1 -0
  32. package/util/layouts/GranularRectLayout.js +2 -0
  33. package/util/layouts/PrecomputedLayout.js +2 -1
  34. package/util/offscreenCanvas/Canvas2DContextShim/Canvas2DContextShim.test.d.ts +1 -0
  35. package/util/offscreenCanvas/Canvas2DContextShim/Canvas2DContextShim.test.js +15 -0
  36. package/util/offscreenCanvas/Canvas2DContextShim/context.d.ts +56 -0
  37. package/util/offscreenCanvas/Canvas2DContextShim/context.js +356 -0
  38. package/util/offscreenCanvas/Canvas2DContextShim/index.d.ts +2 -0
  39. package/util/offscreenCanvas/Canvas2DContextShim/index.js +13 -0
  40. package/util/offscreenCanvas/Canvas2DContextShim/svg.d.ts +3 -0
  41. package/util/offscreenCanvas/Canvas2DContextShim/svg.js +210 -0
  42. package/util/offscreenCanvas/Canvas2DContextShim/types.d.ts +50 -0
  43. package/util/offscreenCanvas/Canvas2DContextShim/types.js +59 -0
  44. package/util/offscreenCanvas/Canvas2DContextShim/util.d.ts +12 -0
  45. package/util/offscreenCanvas/Canvas2DContextShim/util.js +91 -0
  46. package/util/offscreenCanvas/CanvasShim.d.ts +11 -0
  47. package/util/offscreenCanvas/CanvasShim.js +54 -0
  48. package/util/offscreenCanvas/index.d.ts +14 -0
  49. package/util/offscreenCanvas/index.js +170 -0
  50. package/util/offscreenCanvas/ponyfill.d.ts +6 -0
  51. package/util/offscreenCanvas/ponyfill.js +145 -0
  52. package/util/offscreenCanvas/types.d.ts +16 -0
  53. package/util/offscreenCanvas/types.js +14 -0
  54. package/util/offscreenCanvasPonyfill.d.ts +1 -58
  55. package/util/offscreenCanvasPonyfill.js +10 -815
  56. package/util/offscreenCanvasUtils.d.ts +1 -13
  57. package/util/offscreenCanvasUtils.js +12 -124
  58. package/util/simpleFeature.d.ts +1 -0
  59. package/util/tracks.js +4 -1
  60. package/ui/NewSessionCards.d.ts +0 -14
  61. package/ui/NewSessionCards.js +0 -136
@@ -114,10 +114,11 @@ var FeatureRendererType = /*#__PURE__*/function (_ServerSideRendererTy) {
114
114
  key: "serializeResultsInWorker",
115
115
  value: function serializeResultsInWorker(result, args) {
116
116
  var serialized = (0, _get2.default)((0, _getPrototypeOf2.default)(FeatureRendererType.prototype), "serializeResultsInWorker", this).call(this, result, args);
117
+ var features = result.features;
117
118
  return _objectSpread(_objectSpread({}, serialized), {}, {
118
- features: (0, _util.iterMap)(result.features.values(), function (f) {
119
+ features: (0, _util.iterMap)(features.values(), function (f) {
119
120
  return f.toJSON();
120
- })
121
+ }, features.size)
121
122
  });
122
123
  }
123
124
  /**
@@ -145,7 +146,7 @@ var FeatureRendererType = /*#__PURE__*/function (_ServerSideRendererTy) {
145
146
  var _getFeatures = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(renderArgs) {
146
147
  var _this = this;
147
148
 
148
- var signal, regions, sessionId, adapterConfig, _yield$getAdapter, dataAdapter, features, requestRegions, region, featureObservable;
149
+ var signal, regions, sessionId, adapterConfig, _yield$getAdapter, dataAdapter, features, requestRegions, region, featureObservable, feats;
149
150
 
150
151
  return _regenerator.default.wrap(function _callee$(_context) {
151
152
  while (1) {
@@ -188,24 +189,18 @@ var FeatureRendererType = /*#__PURE__*/function (_ServerSideRendererTy) {
188
189
  renderArgs) : // @ts-ignore
189
190
  dataAdapter.getFeaturesInMultipleRegions(requestRegions, renderArgs);
190
191
  _context.next = 13;
191
- return featureObservable.pipe((0, _operators.tap)(function () {
192
- return (0, _util.checkAbortSignal)(signal);
193
- }), (0, _operators.filter)(function (feature) {
194
- return _this.featurePassesFilters(renderArgs, feature);
195
- }), (0, _operators.tap)(function (feature) {
196
- var id = feature.id();
197
-
198
- if (!id) {
199
- throw new Error("invalid feature id \"".concat(id, "\""));
200
- }
201
-
202
- features.set(id, feature);
203
- }), (0, _operators.ignoreElements)()).toPromise();
192
+ return featureObservable.pipe((0, _operators.toArray)()).toPromise();
204
193
 
205
194
  case 13:
206
- return _context.abrupt("return", features);
207
-
208
- case 14:
195
+ feats = _context.sent;
196
+ (0, _util.checkAbortSignal)(signal);
197
+ return _context.abrupt("return", new Map(feats.filter(function (feat) {
198
+ return _this.featurePassesFilters(renderArgs, feat);
199
+ }).map(function (feat) {
200
+ return [feat.id(), feat];
201
+ })));
202
+
203
+ case 16:
209
204
  case "end":
210
205
  return _context.stop();
211
206
  }
@@ -1,5 +1,5 @@
1
1
  import PluginManager from '../PluginManager';
2
- import { AnyConfigurationModel } from '../configuration/configurationSchema';
2
+ import { AnyConfigurationModel } from '../configuration';
3
3
  export interface WorkerHandle {
4
4
  status?: string;
5
5
  error?: Error;
@@ -18,26 +18,25 @@ export interface RpcDriverConstructorArgs {
18
18
  export declare function watchWorker(worker: WorkerHandle, pingTime: number, rpcDriverClassName: string): Promise<unknown>;
19
19
  declare class LazyWorker {
20
20
  driver: BaseRpcDriver;
21
- worker?: WorkerHandle;
21
+ workerP?: Promise<WorkerHandle> | undefined;
22
22
  constructor(driver: BaseRpcDriver);
23
- getWorker(pluginManager: PluginManager, rpcDriverClassName: string): Promise<WorkerHandle>;
23
+ getWorker(): Promise<WorkerHandle>;
24
24
  }
25
25
  export default abstract class BaseRpcDriver {
26
26
  abstract name: string;
27
27
  private lastWorkerAssignment;
28
28
  private workerAssignments;
29
- private workerCount;
30
- abstract makeWorker(pluginManager: PluginManager): Promise<WorkerHandle>;
29
+ abstract makeWorker(): Promise<WorkerHandle>;
31
30
  private workerPool?;
32
31
  maxPingTime: number;
33
32
  workerCheckFrequency: number;
34
33
  config: AnyConfigurationModel;
35
34
  constructor(args: RpcDriverConstructorArgs);
36
- filterArgs<THING_TYPE>(thing: THING_TYPE, pluginManager: PluginManager, sessionId: string): THING_TYPE;
37
- remoteAbort(pluginManager: PluginManager, sessionId: string, functionName: string, signalId: number): Promise<void>;
35
+ filterArgs<THING_TYPE>(thing: THING_TYPE, sessionId: string): THING_TYPE;
36
+ remoteAbort(sessionId: string, functionName: string, signalId: number): Promise<void>;
38
37
  createWorkerPool(): LazyWorker[];
39
38
  getWorkerPool(): LazyWorker[];
40
- getWorker(sessionId: string, pluginManager: PluginManager): Promise<WorkerHandle>;
39
+ getWorker(sessionId: string): Promise<WorkerHandle>;
41
40
  call(pluginManager: PluginManager, sessionId: string, functionName: string, args: {
42
41
  statusCallback?: (message: string) => void;
43
42
  }, options?: {}): Promise<unknown>;
@@ -30,6 +30,8 @@ var _util = require("../util");
30
30
 
31
31
  var _remoteAbortSignals = require("./remoteAbortSignals");
32
32
 
33
+ var _configuration = require("../configuration");
34
+
33
35
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
34
36
 
35
37
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
@@ -119,48 +121,38 @@ var LazyWorker = /*#__PURE__*/function () {
119
121
  function LazyWorker(driver) {
120
122
  (0, _classCallCheck2.default)(this, LazyWorker);
121
123
  this.driver = driver;
122
- (0, _defineProperty2.default)(this, "worker", void 0);
124
+ (0, _defineProperty2.default)(this, "workerP", void 0);
123
125
  }
124
126
 
125
127
  (0, _createClass2.default)(LazyWorker, [{
126
128
  key: "getWorker",
127
129
  value: function () {
128
- var _getWorker = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(pluginManager, rpcDriverClassName) {
130
+ var _getWorker = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
129
131
  var _this = this;
130
132
 
131
- var worker;
132
133
  return _regenerator.default.wrap(function _callee$(_context) {
133
134
  while (1) {
134
135
  switch (_context.prev = _context.next) {
135
136
  case 0:
136
- if (this.worker) {
137
- _context.next = 6;
138
- break;
137
+ if (!this.workerP) {
138
+ this.workerP = this.driver.makeWorker().then(function (worker) {
139
+ watchWorker(worker, _this.driver.maxPingTime, _this.driver.name).catch(function (error) {
140
+ if (worker) {
141
+ console.error('worker did not respond, killing and generating new one');
142
+ console.error(error);
143
+ worker.destroy();
144
+ worker.status = 'killed';
145
+ worker.error = error;
146
+ _this.workerP = undefined;
147
+ }
148
+ });
149
+ return worker;
150
+ });
139
151
  }
140
152
 
141
- _context.next = 3;
142
- return this.driver.makeWorker(pluginManager);
153
+ return _context.abrupt("return", this.workerP);
143
154
 
144
- case 3:
145
- worker = _context.sent;
146
- watchWorker(worker, this.driver.maxPingTime, rpcDriverClassName).catch(function (error) {
147
- if (_this.worker) {
148
- console.error('worker did not respond, killing and generating new one');
149
- console.error(error);
150
-
151
- _this.worker.destroy();
152
-
153
- _this.worker.status = 'killed';
154
- _this.worker.error = error;
155
- _this.worker = undefined;
156
- }
157
- });
158
- this.worker = worker;
159
-
160
- case 6:
161
- return _context.abrupt("return", this.worker);
162
-
163
- case 7:
155
+ case 2:
164
156
  case "end":
165
157
  return _context.stop();
166
158
  }
@@ -168,7 +160,7 @@ var LazyWorker = /*#__PURE__*/function () {
168
160
  }, _callee, this);
169
161
  }));
170
162
 
171
- function getWorker(_x4, _x5) {
163
+ function getWorker() {
172
164
  return _getWorker.apply(this, arguments);
173
165
  }
174
166
 
@@ -184,7 +176,6 @@ var BaseRpcDriver = /*#__PURE__*/function () {
184
176
  (0, _defineProperty2.default)(this, "name", void 0);
185
177
  (0, _defineProperty2.default)(this, "lastWorkerAssignment", -1);
186
178
  (0, _defineProperty2.default)(this, "workerAssignments", new Map());
187
- (0, _defineProperty2.default)(this, "workerCount", 0);
188
179
  (0, _defineProperty2.default)(this, "workerPool", void 0);
189
180
  (0, _defineProperty2.default)(this, "maxPingTime", 30000);
190
181
  (0, _defineProperty2.default)(this, "workerCheckFrequency", 5000);
@@ -195,19 +186,19 @@ var BaseRpcDriver = /*#__PURE__*/function () {
195
186
 
196
187
  (0, _createClass2.default)(BaseRpcDriver, [{
197
188
  key: "filterArgs",
198
- value: function filterArgs(thing, pluginManager, sessionId) {
189
+ value: function filterArgs(thing, sessionId) {
199
190
  var _this2 = this;
200
191
 
201
192
  if (Array.isArray(thing)) {
202
193
  return thing.filter(isClonable).map(function (t) {
203
- return _this2.filterArgs(t, pluginManager, sessionId);
194
+ return _this2.filterArgs(t, sessionId);
204
195
  });
205
196
  }
206
197
 
207
198
  if ((0, _typeof2.default)(thing) === 'object' && thing !== null) {
208
199
  // AbortSignals are specially handled
209
200
  if (thing instanceof AbortSignal) {
210
- return (0, _remoteAbortSignals.serializeAbortSignal)(thing, this.remoteAbort.bind(this, pluginManager, sessionId));
201
+ return (0, _remoteAbortSignals.serializeAbortSignal)(thing, this.remoteAbort.bind(this, sessionId));
211
202
  }
212
203
 
213
204
  if ((0, _mobxStateTree.isStateTreeNode)(thing) && !(0, _mobxStateTree.isAlive)(thing)) {
@@ -227,7 +218,7 @@ var BaseRpcDriver = /*#__PURE__*/function () {
227
218
  k = _ref2[0],
228
219
  v = _ref2[1];
229
220
 
230
- return [k, _this2.filterArgs(v, pluginManager, sessionId)];
221
+ return [k, _this2.filterArgs(v, sessionId)];
231
222
  }));
232
223
  }
233
224
 
@@ -236,14 +227,14 @@ var BaseRpcDriver = /*#__PURE__*/function () {
236
227
  }, {
237
228
  key: "remoteAbort",
238
229
  value: function () {
239
- var _remoteAbort = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(pluginManager, sessionId, functionName, signalId) {
230
+ var _remoteAbort = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(sessionId, functionName, signalId) {
240
231
  var worker;
241
232
  return _regenerator.default.wrap(function _callee2$(_context2) {
242
233
  while (1) {
243
234
  switch (_context2.prev = _context2.next) {
244
235
  case 0:
245
236
  _context2.next = 2;
246
- return this.getWorker(sessionId, pluginManager);
237
+ return this.getWorker(sessionId);
247
238
 
248
239
  case 2:
249
240
  worker = _context2.sent;
@@ -262,7 +253,7 @@ var BaseRpcDriver = /*#__PURE__*/function () {
262
253
  }, _callee2, this);
263
254
  }));
264
255
 
265
- function remoteAbort(_x6, _x7, _x8, _x9) {
256
+ function remoteAbort(_x4, _x5, _x6) {
266
257
  return _remoteAbort.apply(this, arguments);
267
258
  }
268
259
 
@@ -274,7 +265,7 @@ var BaseRpcDriver = /*#__PURE__*/function () {
274
265
  var _this3 = this;
275
266
 
276
267
  var hardwareConcurrency = detectHardwareConcurrency();
277
- var workerCount = this.workerCount || Math.max(1, Math.ceil((hardwareConcurrency - 2) / 3));
268
+ var workerCount = (0, _configuration.readConfObject)(this.config, 'workerCount') || (0, _util.clamp)(1, Math.max(1, hardwareConcurrency - 1), 5);
278
269
  return (0, _toConsumableArray2.default)(new Array(workerCount)).map(function () {
279
270
  return new LazyWorker(_this3);
280
271
  });
@@ -293,7 +284,7 @@ var BaseRpcDriver = /*#__PURE__*/function () {
293
284
  }, {
294
285
  key: "getWorker",
295
286
  value: function () {
296
- var _getWorker2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(sessionId, pluginManager) {
287
+ var _getWorker2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(sessionId) {
297
288
  var workers, workerNumber, workerAssignment, worker;
298
289
  return _regenerator.default.wrap(function _callee3$(_context3) {
299
290
  while (1) {
@@ -310,7 +301,7 @@ var BaseRpcDriver = /*#__PURE__*/function () {
310
301
  } // console.log(`${sessionId} -> worker ${workerNumber}`)
311
302
 
312
303
 
313
- worker = workers[workerNumber].getWorker(pluginManager, this.name);
304
+ worker = workers[workerNumber].getWorker();
314
305
 
315
306
  if (worker) {
316
307
  _context3.next = 6;
@@ -330,7 +321,7 @@ var BaseRpcDriver = /*#__PURE__*/function () {
330
321
  }, _callee3, this);
331
322
  }));
332
323
 
333
- function getWorker(_x10, _x11) {
324
+ function getWorker(_x7) {
334
325
  return _getWorker2.apply(this, arguments);
335
326
  }
336
327
 
@@ -369,7 +360,7 @@ var BaseRpcDriver = /*#__PURE__*/function () {
369
360
  case 3:
370
361
  done = false;
371
362
  _context4.next = 6;
372
- return this.getWorker(sessionId, pluginManager);
363
+ return this.getWorker(sessionId);
373
364
 
374
365
  case 6:
375
366
  worker = _context4.sent;
@@ -379,7 +370,7 @@ var BaseRpcDriver = /*#__PURE__*/function () {
379
370
 
380
371
  case 10:
381
372
  serializedArgs = _context4.sent;
382
- filteredAndSerializedArgs = this.filterArgs(serializedArgs, pluginManager, sessionId); // now actually call the worker
373
+ filteredAndSerializedArgs = this.filterArgs(serializedArgs, sessionId); // now actually call the worker
383
374
 
384
375
  callP = worker.call(functionName, filteredAndSerializedArgs, _objectSpread({
385
376
  timeout: 5 * 60 * 1000,
@@ -417,7 +408,7 @@ var BaseRpcDriver = /*#__PURE__*/function () {
417
408
  }, _callee4, this);
418
409
  }));
419
410
 
420
- function call(_x12, _x13, _x14, _x15) {
411
+ function call(_x8, _x9, _x10, _x11) {
421
412
  return _call.apply(this, arguments);
422
413
  }
423
414
 
@@ -334,7 +334,7 @@ var MockRpcDriver = /*#__PURE__*/function (_BaseRpcDriver) {
334
334
  (0, _createClass2.default)(MockRpcDriver, [{
335
335
  key: "makeWorker",
336
336
  value: function () {
337
- var _makeWorker = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(_pluginManager) {
337
+ var _makeWorker = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5() {
338
338
  return _regenerator.default.wrap(function _callee5$(_context5) {
339
339
  while (1) {
340
340
  switch (_context5.prev = _context5.next) {
@@ -349,7 +349,7 @@ var MockRpcDriver = /*#__PURE__*/function (_BaseRpcDriver) {
349
349
  }, _callee5);
350
350
  }));
351
351
 
352
- function makeWorker(_x2) {
352
+ function makeWorker() {
353
353
  return _makeWorker.apply(this, arguments);
354
354
  }
355
355
 
package/rpc/RpcManager.js CHANGED
@@ -25,6 +25,10 @@ var _WebWorkerRpcDriver = _interopRequireDefault(require("./WebWorkerRpcDriver")
25
25
 
26
26
  var _MainThreadRpcDriver = _interopRequireDefault(require("./MainThreadRpcDriver"));
27
27
 
28
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
29
+
30
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
31
+
28
32
  var DriverClasses = {
29
33
  WebWorkerRpcDriver: _WebWorkerRpcDriver.default,
30
34
  MainThreadRpcDriver: _MainThreadRpcDriver.default
@@ -54,21 +58,35 @@ var RpcManager = /*#__PURE__*/function () {
54
58
  return driver;
55
59
  }
56
60
 
57
- var backendConfiguration = this.backendConfigurations[backendName];
58
- var DriverClassImpl = DriverClasses[backendName];
61
+ var newDriver;
62
+ var config = this.mainConfiguration.drivers.get('WebWorkerRpcDriver');
59
63
 
60
- if (!DriverClassImpl) {
61
- throw new Error("requested RPC driver \"".concat(backendName, "\" is not installed"));
62
- }
64
+ if (backendName === 'MainThreadRpcDriver') {
65
+ var backendConfiguration = this.backendConfigurations.MainThreadRpcDriver;
63
66
 
64
- if (!backendConfiguration) {
65
- throw new Error("requested RPC driver \"".concat(backendName, "\" is missing config"));
66
- } // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ if (!backendConfiguration) {
68
+ throw new Error("requested RPC driver \"".concat(backendName, "\" is missing config"));
69
+ }
67
70
 
71
+ newDriver = new _MainThreadRpcDriver.default(_objectSpread(_objectSpread({}, backendConfiguration), {}, {
72
+ config: config
73
+ }));
74
+ } else if (backendName === 'WebWorkerRpcDriver') {
75
+ var _backendConfiguration = this.backendConfigurations.WebWorkerRpcDriver;
76
+
77
+ if (!_backendConfiguration) {
78
+ throw new Error("requested RPC driver \"".concat(backendName, "\" is missing config"));
79
+ }
80
+
81
+ newDriver = new _WebWorkerRpcDriver.default(_objectSpread(_objectSpread({}, _backendConfiguration), {}, {
82
+ config: config
83
+ }), {
84
+ plugins: this.pluginManager.runtimePluginDefinitions
85
+ });
86
+ } else {
87
+ throw new Error("requested RPC driver \"".concat(backendName, "\" is not installed"));
88
+ }
68
89
 
69
- var newDriver = new DriverClassImpl(backendConfiguration, {
70
- plugins: this.pluginManager.runtimePluginDefinitions
71
- });
72
90
  this.driverObjects.set(backendName, newDriver);
73
91
  return newDriver;
74
92
  }
@@ -1,12 +1,8 @@
1
1
  import Rpc from 'librpc-web-mod';
2
2
  import BaseRpcDriver, { RpcDriverConstructorArgs } from './BaseRpcDriver';
3
3
  import { PluginDefinition } from '../PluginLoader';
4
- interface WebpackWorker {
5
- new (): Worker;
6
- prototype: Worker;
7
- }
8
4
  interface WebWorkerRpcDriverConstructorArgs extends RpcDriverConstructorArgs {
9
- WorkerClass: WebpackWorker;
5
+ makeWorkerInstance: () => Worker;
10
6
  }
11
7
  declare class WebWorkerHandle extends Rpc.Client {
12
8
  destroy(): void;
@@ -20,7 +16,7 @@ export default class WebWorkerRpcDriver extends BaseRpcDriver {
20
16
  plugins: PluginDefinition[];
21
17
  };
22
18
  name: string;
23
- WorkerClass: WebpackWorker;
19
+ makeWorkerInstance: () => Worker;
24
20
  constructor(args: WebWorkerRpcDriverConstructorArgs, workerBootConfiguration: {
25
21
  plugins: PluginDefinition[];
26
22
  });
@@ -116,8 +116,8 @@ var WebWorkerRpcDriver = /*#__PURE__*/function (_BaseRpcDriver) {
116
116
  _this = _super2.call(this, args);
117
117
  _this.workerBootConfiguration = workerBootConfiguration;
118
118
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "name", 'WebWorkerRpcDriver');
119
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "WorkerClass", void 0);
120
- _this.WorkerClass = args.WorkerClass;
119
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "makeWorkerInstance", void 0);
120
+ _this.makeWorkerInstance = args.makeWorkerInstance;
121
121
  return _this;
122
122
  }
123
123
 
@@ -127,7 +127,7 @@ var WebWorkerRpcDriver = /*#__PURE__*/function (_BaseRpcDriver) {
127
127
  var _makeWorker = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
128
128
  var _this2 = this;
129
129
 
130
- var worker, p;
130
+ var instance, worker, p;
131
131
  return _regenerator.default.wrap(function _callee2$(_context2) {
132
132
  while (1) {
133
133
  switch (_context2.prev = _context2.next) {
@@ -135,8 +135,9 @@ var WebWorkerRpcDriver = /*#__PURE__*/function (_BaseRpcDriver) {
135
135
  // note that we are making a Rpc.Client connection with a worker pool of
136
136
  // one for each worker, because we want to do our own state-group-aware
137
137
  // load balancing rather than using librpc's builtin round-robin
138
+ instance = this.makeWorkerInstance();
138
139
  worker = new WebWorkerHandle({
139
- workers: [new this.WorkerClass()]
140
+ workers: [instance]
140
141
  }); // send the worker its boot configuration using info from the pluginManager
141
142
 
142
143
  p = new Promise(function (resolve, reject) {
@@ -152,7 +153,7 @@ var WebWorkerRpcDriver = /*#__PURE__*/function (_BaseRpcDriver) {
152
153
  });
153
154
  return _context2.abrupt("return", p);
154
155
 
155
- case 3:
156
+ case 4:
156
157
  case "end":
157
158
  return _context2.stop();
158
159
  }
@@ -9,14 +9,22 @@ var _mobxStateTree = require("mobx-state-tree");
9
9
 
10
10
  var _configuration = require("../configuration");
11
11
 
12
- var MainThreadRpcDriverConfigSchema = (0, _configuration.ConfigurationSchema)('MainThreadRpcDriver', {}, {
12
+ var BaseRpcDriverConfigSchema = (0, _configuration.ConfigurationSchema)('BaseRpcDriver', {
13
+ workerCount: {
14
+ type: 'number',
15
+ description: 'The number of workers to use. If 0 (the default) JBrowse will decide how many workers to use.',
16
+ defaultValue: 0
17
+ }
18
+ }, {
13
19
  explicitlyTyped: true
14
20
  });
15
- var WebWorkerRpcDriverConfigSchema = (0, _configuration.ConfigurationSchema)('WebWorkerRpcDriver', {}, {
16
- explicitlyTyped: true
21
+ var MainThreadRpcDriverConfigSchema = (0, _configuration.ConfigurationSchema)('MainThreadRpcDriver', {}, {
22
+ explicitlyTyped: true,
23
+ baseConfiguration: BaseRpcDriverConfigSchema
17
24
  });
18
- var ElectronRpcDriverConfigSchema = (0, _configuration.ConfigurationSchema)('ElectronRpcDriver', {}, {
19
- explicitlyTyped: true
25
+ var WebWorkerRpcDriverConfigSchema = (0, _configuration.ConfigurationSchema)('WebWorkerRpcDriver', {}, {
26
+ explicitlyTyped: true,
27
+ baseConfiguration: BaseRpcDriverConfigSchema
20
28
  });
21
29
 
22
30
  var _default = (0, _configuration.ConfigurationSchema)('RpcOptions', {
@@ -25,7 +33,7 @@ var _default = (0, _configuration.ConfigurationSchema)('RpcOptions', {
25
33
  description: 'the RPC driver to use for tracks and tasks that are not configured to use a specific RPC backend',
26
34
  defaultValue: 'MainThreadRpcDriver'
27
35
  },
28
- drivers: _mobxStateTree.types.optional(_mobxStateTree.types.map(_mobxStateTree.types.union(MainThreadRpcDriverConfigSchema, WebWorkerRpcDriverConfigSchema, ElectronRpcDriverConfigSchema)), {
36
+ drivers: _mobxStateTree.types.optional(_mobxStateTree.types.map(_mobxStateTree.types.union(MainThreadRpcDriverConfigSchema, WebWorkerRpcDriverConfigSchema)), {
29
37
  MainThreadRpcDriver: {
30
38
  type: 'MainThreadRpcDriver'
31
39
  }
package/ui/App.js CHANGED
@@ -238,23 +238,19 @@ var App = (0, _mobxReact.observer)(function (_ref2) {
238
238
  }
239
239
 
240
240
  var ReactComponent = viewType.ReactComponent;
241
- return (
242
- /*#__PURE__*/
243
- // @ts-ignore
244
- _react.default.createElement(_ViewContainer.default, {
245
- key: "view-".concat(view.id),
246
- view: view,
247
- onClose: function onClose() {
248
- return session.removeView(view);
249
- }
250
- }, /*#__PURE__*/_react.default.createElement(_react.Suspense, {
251
- fallback: /*#__PURE__*/_react.default.createElement("div", null, "Loading...")
252
- }, /*#__PURE__*/_react.default.createElement(ReactComponent, {
253
- model: view,
254
- session: session,
255
- getTrackType: pluginManager.getTrackType
256
- })))
257
- );
241
+ return /*#__PURE__*/_react.default.createElement(_ViewContainer.default, {
242
+ key: "view-".concat(view.id),
243
+ view: view,
244
+ onClose: function onClose() {
245
+ return session.removeView(view);
246
+ }
247
+ }, /*#__PURE__*/_react.default.createElement(_react.Suspense, {
248
+ fallback: /*#__PURE__*/_react.default.createElement("div", null, "Loading...")
249
+ }, /*#__PURE__*/_react.default.createElement(ReactComponent, {
250
+ model: view,
251
+ session: session,
252
+ getTrackType: pluginManager.getTrackType
253
+ })));
258
254
  }) : /*#__PURE__*/_react.default.createElement(_core.Paper, {
259
255
  className: classes.selectPaper
260
256
  }, /*#__PURE__*/_react.default.createElement(_core.Typography, null, "Select a view to launch"), /*#__PURE__*/_react.default.createElement(_core.Select, {
@@ -1,8 +1,11 @@
1
1
  /// <reference types="react" />
2
+ import { InputProps as IIP } from '@material-ui/core';
2
3
  import { AbstractSessionModel } from '../util';
3
- declare const AssemblySelector: ({ session, onChange, selected, }: {
4
+ declare const AssemblySelector: ({ session, onChange, selected, InputProps, extra, }: {
4
5
  session: AbstractSessionModel;
5
6
  onChange: (arg: string) => void;
6
7
  selected: string | undefined;
8
+ InputProps?: IIP | undefined;
9
+ extra?: unknown;
7
10
  }) => JSX.Element;
8
11
  export default AssemblySelector;
@@ -2,12 +2,16 @@
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+
5
7
  Object.defineProperty(exports, "__esModule", {
6
8
  value: true
7
9
  });
8
10
  exports.default = void 0;
9
11
 
10
- var _react = _interopRequireDefault(require("react"));
12
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
+
14
+ var _react = _interopRequireWildcard(require("react"));
11
15
 
12
16
  var _mobxReact = require("mobx-react");
13
17
 
@@ -15,35 +19,92 @@ var _configuration = require("../configuration");
15
19
 
16
20
  var _core = require("@material-ui/core");
17
21
 
22
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23
+
24
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
+
18
26
  var useStyles = (0, _core.makeStyles)(function () {
19
27
  return {
20
28
  importFormEntry: {
21
29
  minWidth: 180
22
30
  }
23
31
  };
24
- });
32
+ }); // Hook from https://usehooks.com/useLocalStorage/
33
+
34
+ function useLocalStorage(key, initialValue) {
35
+ var _useState = (0, _react.useState)(function () {
36
+ if (typeof window === 'undefined') {
37
+ return initialValue;
38
+ }
39
+
40
+ try {
41
+ var item = window.localStorage.getItem(key);
42
+ return item ? JSON.parse(item) : initialValue;
43
+ } catch (error) {
44
+ console.error(error);
45
+ return initialValue;
46
+ }
47
+ }),
48
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
49
+ storedValue = _useState2[0],
50
+ setStoredValue = _useState2[1];
51
+
52
+ var setValue = function setValue(value) {
53
+ try {
54
+ var valueToStore = value instanceof Function ? value(storedValue) : value;
55
+ setStoredValue(valueToStore);
56
+
57
+ if (typeof window !== 'undefined') {
58
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
59
+ }
60
+ } catch (error) {
61
+ console.error(error);
62
+ }
63
+ };
64
+
65
+ return [storedValue, setValue];
66
+ }
67
+
25
68
  var AssemblySelector = (0, _mobxReact.observer)(function (_ref) {
26
69
  var session = _ref.session,
27
- _onChange = _ref.onChange,
28
- selected = _ref.selected;
70
+ onChange = _ref.onChange,
71
+ selected = _ref.selected,
72
+ InputProps = _ref.InputProps,
73
+ _ref$extra = _ref.extra,
74
+ extra = _ref$extra === void 0 ? 0 : _ref$extra;
29
75
  var classes = useStyles();
30
76
  var assemblyNames = session.assemblyNames,
31
- assemblyManager = session.assemblyManager;
77
+ assemblyManager = session.assemblyManager; // constructs a localstorage key based on host/path/config to help
78
+ // remember. non-config assists usage with e.g. embedded apps
79
+
80
+ var config = new URLSearchParams(window.location.search).get('config');
81
+
82
+ var _useLocalStorage = useLocalStorage("lastAssembly-".concat([window.location.host + window.location.pathname, config, extra].join('-')), selected),
83
+ _useLocalStorage2 = (0, _slicedToArray2.default)(_useLocalStorage, 2),
84
+ lastSelected = _useLocalStorage2[0],
85
+ setLastSelected = _useLocalStorage2[1];
86
+
87
+ var selection = assemblyNames.includes(lastSelected || '') ? lastSelected : selected;
88
+ (0, _react.useEffect)(function () {
89
+ if (selection && selection !== selected) {
90
+ onChange(selection);
91
+ }
92
+ }, [selection, onChange, selected]);
32
93
  var error = assemblyNames.length ? '' : 'No configured assemblies';
33
94
  return /*#__PURE__*/_react.default.createElement(_core.TextField, {
34
95
  select: true,
35
96
  label: "Assembly",
36
97
  variant: "outlined",
37
- margin: "normal",
38
98
  helperText: error || 'Select assembly to view',
39
- value: error ? '' : selected,
99
+ value: error ? '' : selection,
40
100
  inputProps: {
41
101
  'data-testid': 'assembly-selector'
42
102
  },
43
103
  onChange: function onChange(event) {
44
- return _onChange(event.target.value);
104
+ return setLastSelected(event.target.value);
45
105
  },
46
106
  error: !!error,
107
+ InputProps: InputProps,
47
108
  disabled: !!error,
48
109
  className: classes.importFormEntry
49
110
  }, assemblyNames.map(function (name) {