@jbrowse/core 2.3.3 → 2.4.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 (52) hide show
  1. package/BaseFeatureWidget/BaseFeatureDetail.d.ts +18 -19
  2. package/BaseFeatureWidget/BaseFeatureDetail.js +64 -61
  3. package/BaseFeatureWidget/SequenceBox.js +9 -3
  4. package/BaseFeatureWidget/SequenceFeatureDetails.js +70 -52
  5. package/BaseFeatureWidget/SequencePanel.d.ts +3 -3
  6. package/BaseFeatureWidget/SequencePanel.js +8 -5
  7. package/CorePlugin.js +2 -7
  8. package/PluginLoader.d.ts +8 -9
  9. package/PluginLoader.js +35 -41
  10. package/data_adapters/CytobandAdapter/CytobandAdapter.d.ts +8 -0
  11. package/data_adapters/CytobandAdapter/CytobandAdapter.js +40 -0
  12. package/data_adapters/CytobandAdapter/configSchema.d.ts +2 -0
  13. package/data_adapters/CytobandAdapter/configSchema.js +17 -0
  14. package/data_adapters/CytobandAdapter/index.d.ts +3 -0
  15. package/data_adapters/CytobandAdapter/index.js +37 -0
  16. package/package.json +5 -4
  17. package/pluggableElementTypes/PluggableElementBase.d.ts +1 -1
  18. package/pluggableElementTypes/PluggableElementBase.js +1 -2
  19. package/pluggableElementTypes/RpcMethodType.d.ts +5 -8
  20. package/pluggableElementTypes/RpcMethodType.js +22 -33
  21. package/pluggableElementTypes/renderers/CircularChordRendererType.d.ts +13 -2
  22. package/pluggableElementTypes/renderers/CircularChordRendererType.js +10 -2
  23. package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.d.ts +6 -0
  24. package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.js +9 -1
  25. package/pluggableElementTypes/renderers/ServerSideRendererType.js +2 -34
  26. package/tsconfig.build.tsbuildinfo +1 -1
  27. package/ui/App.js +3 -18
  28. package/ui/Dialog.js +8 -1
  29. package/ui/DropDownMenu.js +1 -4
  30. package/ui/EditableTypography.js +1 -1
  31. package/ui/LoadingEllipses.js +6 -6
  32. package/ui/Menu.js +11 -3
  33. package/ui/ResizeBar.d.ts +11 -0
  34. package/ui/ResizeBar.js +94 -0
  35. package/ui/ResizeHandle.d.ts +1 -1
  36. package/ui/ResizeHandle.js +1 -1
  37. package/ui/SanitizedHTML.js +3 -1
  38. package/ui/ViewContainer.js +3 -38
  39. package/ui/ViewMenu.d.ts +9 -0
  40. package/ui/ViewMenu.js +69 -0
  41. package/ui/ViewPanel.d.ts +19 -0
  42. package/ui/ViewPanel.js +49 -0
  43. package/ui/theme.d.ts +10 -156
  44. package/ui/theme.js +270 -48
  45. package/util/index.d.ts +16 -9
  46. package/util/index.js +30 -13
  47. package/util/map-obj.d.ts +3 -0
  48. package/util/map-obj.js +33 -0
  49. package/util/offscreenCanvasUtils.d.ts +18 -4
  50. package/util/offscreenCanvasUtils.js +48 -7
  51. package/data_adapters/CytobandAdapter.d.ts +0 -8
  52. package/data_adapters/CytobandAdapter.js +0 -49
package/util/index.js CHANGED
@@ -30,7 +30,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
30
30
  };
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
32
  exports.bytesForRegions = exports.objectHash = exports.hashCode = exports.updateStatus = exports.generateCodonTable = exports.defaultCodonTable = exports.defaultStops = exports.defaultStarts = exports.measureText = exports.rIC = exports.blobToDataURL = exports.complement = exports.reverse = exports.revcom = exports.isElectron = exports.stringify = exports.shorten = exports.minmax = exports.renameRegionsIfNeeded = exports.renameRegionIfNeeded = exports.makeAbortableReaction = exports.findLastIndex = exports.iterMap = exports.bpSpanPx = exports.featureSpanPx = exports.cartesianToPolar = exports.polarToCartesian = exports.degToRad = exports.radToDeg = exports.bpToPx = exports.clamp = exports.compareLocStrings = exports.compareLocs = exports.parseLocString = exports.parseLocStringOneBased = exports.assembleLocStringFast = exports.assembleLocString = exports.getContainingDisplay = exports.getContainingTrack = exports.getContainingView = exports.getSession = exports.findParentThatIs = exports.springAnimate = exports.findParentThat = exports.useDebouncedCallback = exports.useDebounce = exports.inProduction = exports.inDevelopment = exports.isFeature = exports.SimpleFeature = void 0;
33
- exports.avg = exports.sum = exports.min = exports.max = exports.localStorageGetItem = exports.getEnv = exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = exports.getBpDisplayStr = exports.supportedIndexingAdapters = void 0;
33
+ exports.avg = exports.sum = exports.min = exports.max = exports.localStorageSetItem = exports.localStorageGetItem = exports.getEnv = exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = exports.getBpDisplayStr = exports.supportedIndexingAdapters = void 0;
34
34
  /* eslint-disable @typescript-eslint/no-explicit-any */
35
35
  const react_1 = require("react");
36
36
  const is_object_1 = __importDefault(require("is-object"));
@@ -504,10 +504,10 @@ function bpSpanPx(leftBp, rightBp, region, bpPerPx) {
504
504
  }
505
505
  exports.bpSpanPx = bpSpanPx;
506
506
  // do an array map of an iterable
507
- function iterMap(iterable, func, sizeHint) {
507
+ function iterMap(iter, func, sizeHint) {
508
508
  const results = sizeHint ? new Array(sizeHint) : [];
509
509
  let counter = 0;
510
- for (const item of iterable) {
510
+ for (const item of iter) {
511
511
  results[counter] = func(item);
512
512
  counter += 1;
513
513
  }
@@ -664,8 +664,10 @@ function stringify({ refName, coord, oob, }) {
664
664
  : '';
665
665
  }
666
666
  exports.stringify = stringify;
667
- // this is recommended in a later comment in https://github.com/electron/electron/issues/2288
668
- // for detecting electron in a renderer process, which is the one that has node enabled for us
667
+ // this is recommended in a later comment in
668
+ // https://github.com/electron/electron/issues/2288 for detecting electron in a
669
+ // renderer process, which is the one that has node enabled for us
670
+ //
669
671
  // const isElectron = process.versions.electron
670
672
  // const i2 = process.versions.hasOwnProperty('electron')
671
673
  exports.isElectron = /electron/i.test(typeof navigator !== 'undefined' ? navigator.userAgent : '');
@@ -829,8 +831,8 @@ exports.defaultCodonTable = {
829
831
  GGT: 'G',
830
832
  };
831
833
  /**
832
- * take CodonTable above and generate larger codon table that includes
833
- * all permutations of upper and lower case nucleotides
834
+ * take CodonTable above and generate larger codon table that includes all
835
+ * permutations of upper and lower case nucleotides
834
836
  */
835
837
  function generateCodonTable(table) {
836
838
  const tempCodonTable = {};
@@ -1002,9 +1004,18 @@ function getStr(obj) {
1002
1004
  : String(obj);
1003
1005
  }
1004
1006
  exports.getStr = getStr;
1007
+ // tries to measure grid width without HTML tags included
1008
+ function coarseStripHTML(s) {
1009
+ return s.replace(/(<([^>]+)>)/gi, '');
1010
+ }
1005
1011
  // heuristic measurement for a column of a @mui/x-data-grid, pass in values from a column
1006
- function measureGridWidth(elements) {
1007
- return max(elements.map(element => Math.min(Math.max(measureText(getStr(element), 14) + 50, 80), 1000)));
1012
+ function measureGridWidth(elements, args) {
1013
+ const { padding = 30, minWidth = 80, fontSize = 12, maxWidth = 1000, stripHTML = false, } = args || {};
1014
+ return max(elements
1015
+ .map(element => getStr(element))
1016
+ .map(str => (stripHTML ? coarseStripHTML(str) : str))
1017
+ .map(str => measureText(str, fontSize))
1018
+ .map(n => Math.min(Math.max(n + padding, minWidth), maxWidth)));
1008
1019
  }
1009
1020
  exports.measureGridWidth = measureGridWidth;
1010
1021
  function getEnv(obj) {
@@ -1017,16 +1028,22 @@ function localStorageGetItem(item) {
1017
1028
  : undefined;
1018
1029
  }
1019
1030
  exports.localStorageGetItem = localStorageGetItem;
1020
- function max(arr) {
1021
- let max = -Infinity;
1031
+ function localStorageSetItem(str, item) {
1032
+ return typeof localStorage !== 'undefined'
1033
+ ? localStorage.setItem(str, item)
1034
+ : undefined;
1035
+ }
1036
+ exports.localStorageSetItem = localStorageSetItem;
1037
+ function max(arr, init = -Infinity) {
1038
+ let max = init;
1022
1039
  for (let i = 0; i < arr.length; i++) {
1023
1040
  max = arr[i] > max ? arr[i] : max;
1024
1041
  }
1025
1042
  return max;
1026
1043
  }
1027
1044
  exports.max = max;
1028
- function min(arr) {
1029
- let min = Infinity;
1045
+ function min(arr, init = Infinity) {
1046
+ let min = init;
1030
1047
  for (let i = 0; i < arr.length; i++) {
1031
1048
  min = arr[i] < min ? arr[i] : min;
1032
1049
  }
@@ -0,0 +1,3 @@
1
+ type Obj = Record<string, unknown>;
2
+ export default function map(object: Obj, mapper: (val: unknown) => void, isSeen?: WeakSet<object>): void;
3
+ export {};
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // adapted from map-obj (MIT), with modifications to pass the "whole object"
4
+ // from an array of objects into itself
5
+ const isObject = (value) => typeof value === 'object' && value !== null;
6
+ // Customized for this use-case
7
+ const isObjectCustom = (value) => isObject(value) &&
8
+ !(value instanceof RegExp) &&
9
+ !(value instanceof Error) &&
10
+ !(value instanceof Date) &&
11
+ !(globalThis.Blob && value instanceof globalThis.Blob);
12
+ function map(object, mapper, isSeen = new WeakSet()) {
13
+ if (isSeen.has(object)) {
14
+ return;
15
+ }
16
+ isSeen.add(object);
17
+ const mapArray = (array) => array.forEach(element => {
18
+ mapper(element);
19
+ if (isObject(element)) {
20
+ map(element, mapper, isSeen);
21
+ }
22
+ });
23
+ if (Array.isArray(object)) {
24
+ mapArray(object);
25
+ }
26
+ for (const value of Object.values(object)) {
27
+ mapper(value);
28
+ if (isObjectCustom(value)) {
29
+ Array.isArray(value) ? mapArray(value) : map(value, mapper, isSeen);
30
+ }
31
+ }
32
+ }
33
+ exports.default = map;
@@ -1,14 +1,28 @@
1
- /// <reference types="react" />
2
- export type RenderReturn = Record<string, unknown>;
1
+ import React from 'react';
2
+ export type RenderReturn = Record<string, unknown> | void;
3
+ type RendererRet = Promise<RenderReturn> | RenderReturn;
3
4
  export declare function renderToAbstractCanvas(width: number, height: number, opts: {
4
5
  exportSVG?: {
5
6
  rasterizeLayers?: boolean;
7
+ scale?: number;
6
8
  };
7
- highResolutionScaling: number;
8
- }, cb: (ctx: CanvasRenderingContext2D) => Promise<RenderReturn | void> | RenderReturn | void): Promise<{
9
+ highResolutionScaling?: number;
10
+ }, cb: (ctx: CanvasRenderingContext2D) => RendererRet): Promise<{
9
11
  canvasRecordedData: any;
10
12
  } | {
11
13
  reactElement: JSX.Element;
12
14
  } | {
13
15
  imageData: any;
14
16
  }>;
17
+ export declare function getSerializedSvg(results: {
18
+ width: number;
19
+ height: number;
20
+ canvasRecordedData: unknown;
21
+ }): Promise<string>;
22
+ export declare function ReactRendering({ rendering, }: {
23
+ rendering: {
24
+ reactElement?: React.ReactNode;
25
+ html?: string;
26
+ };
27
+ }): JSX.Element;
28
+ export {};
@@ -1,16 +1,39 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.renderToAbstractCanvas = void 0;
29
+ exports.ReactRendering = exports.getSerializedSvg = exports.renderToAbstractCanvas = void 0;
7
30
  const react_1 = __importDefault(require("react"));
8
31
  const canvas_sequencer_1 = require("canvas-sequencer");
9
32
  // locals
10
33
  const offscreenCanvasPonyfill_1 = require("./offscreenCanvasPonyfill");
11
34
  const index_1 = require("./index");
12
35
  async function renderToAbstractCanvas(width, height, opts, cb) {
13
- const { exportSVG, highResolutionScaling: scaling = 1 } = opts;
36
+ const { exportSVG, highResolutionScaling = 1 } = opts;
14
37
  if (exportSVG) {
15
38
  if (!exportSVG.rasterizeLayers) {
16
39
  const fakeCtx = new canvas_sequencer_1.CanvasSequence();
@@ -21,13 +44,13 @@ async function renderToAbstractCanvas(width, height, opts, cb) {
21
44
  };
22
45
  }
23
46
  else {
24
- const scale = 4;
25
- const canvas = (0, offscreenCanvasPonyfill_1.createCanvas)(Math.ceil(width * scale), height * scale);
47
+ const s = exportSVG.scale || highResolutionScaling;
48
+ const canvas = (0, offscreenCanvasPonyfill_1.createCanvas)(Math.ceil(width * s), height * s);
26
49
  const ctx = canvas.getContext('2d');
27
50
  if (!ctx) {
28
51
  throw new Error('2d canvas rendering not supported on this platform');
29
52
  }
30
- ctx.scale(scale, scale);
53
+ ctx.scale(s, s);
31
54
  const result = await cb(ctx);
32
55
  // two methods needed for converting canvas to PNG, one for webworker
33
56
  // offscreen canvas, one for main thread
@@ -42,14 +65,32 @@ async function renderToAbstractCanvas(width, height, opts, cb) {
42
65
  }
43
66
  }
44
67
  else {
45
- const canvas = (0, offscreenCanvasPonyfill_1.createCanvas)(Math.ceil(width * scaling), height * scaling);
68
+ const s = highResolutionScaling;
69
+ const canvas = (0, offscreenCanvasPonyfill_1.createCanvas)(Math.ceil(width * s), height * s);
46
70
  const ctx = canvas.getContext('2d');
47
71
  if (!ctx) {
48
72
  throw new Error('2d canvas rendering not supported on this platform');
49
73
  }
50
- ctx.scale(scaling, scaling);
74
+ ctx.scale(s, s);
51
75
  const result = await cb(ctx);
52
76
  return { ...result, imageData: await (0, offscreenCanvasPonyfill_1.createImageBitmap)(canvas) };
53
77
  }
54
78
  }
55
79
  exports.renderToAbstractCanvas = renderToAbstractCanvas;
80
+ async function getSerializedSvg(results) {
81
+ const { width, height, canvasRecordedData } = results;
82
+ const C2S = await Promise.resolve().then(() => __importStar(require('canvas2svg')));
83
+ const ctx = new C2S.default(width, height);
84
+ const seq = new canvas_sequencer_1.CanvasSequence(canvasRecordedData);
85
+ seq.execute(ctx);
86
+ // innerHTML strips the outer <svg> element from returned data, we add
87
+ // our own <svg> element in the view's SVG export
88
+ return ctx.getSvg().innerHTML;
89
+ }
90
+ exports.getSerializedSvg = getSerializedSvg;
91
+ function ReactRendering({ rendering, }) {
92
+ return (react_1.default.createElement(react_1.default.Fragment, null, react_1.default.isValidElement(rendering.reactElement) ? (rendering.reactElement) : (react_1.default.createElement("g", {
93
+ /* eslint-disable-next-line react/no-danger */
94
+ dangerouslySetInnerHTML: { __html: rendering.html || '' } }))));
95
+ }
96
+ exports.ReactRendering = ReactRendering;
@@ -1,8 +0,0 @@
1
- import SimpleFeature from '../util/simpleFeature';
2
- import { BaseAdapter } from './BaseAdapter';
3
- declare const configSchema: import("../configuration").AnyConfigurationSchemaType;
4
- declare class CytobandAdapter extends BaseAdapter {
5
- getData(): Promise<SimpleFeature[]>;
6
- freeResources(): void;
7
- }
8
- export { configSchema, CytobandAdapter as DataAdapter };
@@ -1,49 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DataAdapter = exports.configSchema = void 0;
7
- const simpleFeature_1 = __importDefault(require("../util/simpleFeature"));
8
- const configuration_1 = require("../configuration");
9
- const io_1 = require("../util/io");
10
- const BaseAdapter_1 = require("./BaseAdapter");
11
- /**
12
- * #config CytobandAdapter
13
- */
14
- function x() { } // eslint-disable-line @typescript-eslint/no-unused-vars
15
- const configSchema = (0, configuration_1.ConfigurationSchema)('CytobandAdapter', {
16
- /**
17
- * #slot
18
- */
19
- cytobandLocation: {
20
- type: 'fileLocation',
21
- defaultValue: { uri: '/path/to/cytoband.txt.gz' },
22
- },
23
- }, { explicitlyTyped: true });
24
- exports.configSchema = configSchema;
25
- class CytobandAdapter extends BaseAdapter_1.BaseAdapter {
26
- async getData() {
27
- const loc = (0, configuration_1.readConfObject)(this.config, 'cytobandLocation');
28
- if (loc.uri === '' || loc.uri === '/path/to/cytoband.txt.gz') {
29
- return [];
30
- }
31
- const data = await (0, io_1.openLocation)(loc).readFile('utf8');
32
- return data
33
- .split(/\n|\r\n|\r/)
34
- .filter(f => !!f.trim())
35
- .map(line => {
36
- const [refName, start, end, name, type] = line.split('\t');
37
- return new simpleFeature_1.default({
38
- uniqueId: line,
39
- refName,
40
- start: +start,
41
- end: +end,
42
- name,
43
- type,
44
- });
45
- });
46
- }
47
- freeResources( /* { region } */) { }
48
- }
49
- exports.DataAdapter = CytobandAdapter;