@jbrowse/plugin-alignments 3.0.1 → 3.0.3

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 (37) hide show
  1. package/dist/BamAdapter/BamAdapter.d.ts +1 -0
  2. package/dist/BamAdapter/BamAdapter.js +17 -16
  3. package/dist/CramAdapter/CramAdapter.d.ts +6 -1
  4. package/dist/CramAdapter/CramAdapter.js +29 -28
  5. package/dist/LinearPileupDisplay/doAfterAttach.d.ts +20 -0
  6. package/dist/LinearPileupDisplay/doAfterAttach.js +69 -0
  7. package/dist/LinearPileupDisplay/model.js +9 -56
  8. package/dist/LinearSNPCoverageDisplay/model.d.ts +1 -0
  9. package/dist/LinearSNPCoverageDisplay/model.js +4 -4
  10. package/dist/PileupRPC/methods/GetGlobalValueForTag.js +3 -2
  11. package/dist/PileupRPC/methods/GetReducedFeatures.js +5 -3
  12. package/dist/PileupRPC/methods/GetVisibleModifications.js +8 -5
  13. package/dist/PileupRenderer/PileupRenderer.js +22 -20
  14. package/dist/PileupRenderer/types.d.ts +1 -0
  15. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +3 -1
  16. package/dist/SNPCoverageRenderer/types.d.ts +1 -0
  17. package/dist/shared/getUniqueModifications.d.ts +8 -7
  18. package/dist/shared/getUniqueModifications.js +6 -3
  19. package/esm/BamAdapter/BamAdapter.d.ts +1 -0
  20. package/esm/BamAdapter/BamAdapter.js +17 -16
  21. package/esm/CramAdapter/CramAdapter.d.ts +6 -1
  22. package/esm/CramAdapter/CramAdapter.js +29 -28
  23. package/esm/LinearPileupDisplay/doAfterAttach.d.ts +20 -0
  24. package/esm/LinearPileupDisplay/doAfterAttach.js +66 -0
  25. package/esm/LinearPileupDisplay/model.js +11 -58
  26. package/esm/LinearSNPCoverageDisplay/model.d.ts +1 -0
  27. package/esm/LinearSNPCoverageDisplay/model.js +4 -4
  28. package/esm/PileupRPC/methods/GetGlobalValueForTag.js +3 -2
  29. package/esm/PileupRPC/methods/GetReducedFeatures.js +5 -3
  30. package/esm/PileupRPC/methods/GetVisibleModifications.js +8 -5
  31. package/esm/PileupRenderer/PileupRenderer.js +23 -21
  32. package/esm/PileupRenderer/types.d.ts +1 -0
  33. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +3 -1
  34. package/esm/SNPCoverageRenderer/types.d.ts +1 -0
  35. package/esm/shared/getUniqueModifications.d.ts +8 -7
  36. package/esm/shared/getUniqueModifications.js +6 -3
  37. package/package.json +6 -6
@@ -26,6 +26,7 @@ export default class BamAdapter extends BaseFeatureDataAdapter {
26
26
  }>;
27
27
  getHeader(_opts?: BaseOptions): Promise<string | undefined>;
28
28
  private setupPre;
29
+ setupPre2(opts?: BaseOptions): Promise<Header>;
29
30
  setup(opts?: BaseOptions): Promise<Header>;
30
31
  getRefNames(opts?: BaseOptions): Promise<string[]>;
31
32
  private seqFetch;
@@ -56,26 +56,23 @@ class BamAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
56
56
  const { bam } = await this.configure();
57
57
  return bam.getHeaderText();
58
58
  }
59
- async setupPre(opts) {
60
- const { statusCallback = () => { } } = opts || {};
59
+ async setupPre(_opts) {
61
60
  const { bam } = await this.configure();
62
- this.samHeader = await (0, util_1.updateStatus)('Downloading index', statusCallback, async () => {
63
- const samHeader = await bam.getHeader();
64
- const idToName = [];
65
- const nameToId = {};
66
- samHeader === null || samHeader === void 0 ? void 0 : samHeader.filter(l => l.tag === 'SQ').forEach((sqLine, refId) => {
67
- const SN = sqLine.data.find(item => item.tag === 'SN');
68
- if (SN) {
69
- const refName = SN.value;
70
- nameToId[refName] = refId;
71
- idToName[refId] = refName;
72
- }
73
- });
74
- return { idToName, nameToId };
61
+ const samHeader = await bam.getHeader();
62
+ const idToName = [];
63
+ const nameToId = {};
64
+ samHeader === null || samHeader === void 0 ? void 0 : samHeader.filter(l => l.tag === 'SQ').forEach((sqLine, refId) => {
65
+ const SN = sqLine.data.find(item => item.tag === 'SN');
66
+ if (SN) {
67
+ const refName = SN.value;
68
+ nameToId[refName] = refId;
69
+ idToName[refId] = refName;
70
+ }
75
71
  });
72
+ this.samHeader = { idToName, nameToId };
76
73
  return this.samHeader;
77
74
  }
78
- async setup(opts) {
75
+ async setupPre2(opts) {
79
76
  if (!this.setupP) {
80
77
  this.setupP = this.setupPre(opts).catch((e) => {
81
78
  this.setupP = undefined;
@@ -84,6 +81,10 @@ class BamAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
84
81
  }
85
82
  return this.setupP;
86
83
  }
84
+ async setup(opts) {
85
+ const { statusCallback = () => { } } = opts || {};
86
+ return (0, util_1.updateStatus)('Downloading index', statusCallback, () => this.setupPre2(opts));
87
+ }
87
88
  async getRefNames(opts) {
88
89
  const { idToName } = await this.setup(opts);
89
90
  return idToName;
@@ -28,7 +28,12 @@ export default class CramAdapter extends BaseFeatureDataAdapter {
28
28
  getHeader(_opts?: BaseOptions): Promise<string | undefined>;
29
29
  private seqFetch;
30
30
  private setupPre;
31
- private setup;
31
+ private setupPre2;
32
+ setup(opts?: BaseOptions): Promise<{
33
+ samHeader: Header;
34
+ cram: IndexedCramFile;
35
+ sequenceAdapter: BaseSequenceAdapter;
36
+ }>;
32
37
  getRefNames(opts?: BaseOptions): Promise<string[]>;
33
38
  refNameToId(refName: string): number | undefined;
34
39
  refIdToName(refId: number): string | undefined;
@@ -94,36 +94,33 @@ class CramAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
94
94
  }
95
95
  return sequence;
96
96
  }
97
- async setupPre(opts) {
98
- const { statusCallback = () => { } } = opts || {};
99
- return (0, util_1.updateStatus)('Downloading index', statusCallback, async () => {
100
- const conf = await this.configure();
101
- const { cram } = conf;
102
- const samHeader = await cram.cram.getSamHeader();
103
- const idToName = [];
104
- const nameToId = {};
105
- samHeader
106
- .filter(l => l.tag === 'SQ')
107
- .forEach((sqLine, refId) => {
108
- const SN = sqLine.data.find(item => item.tag === 'SN');
109
- if (SN) {
110
- const refName = SN.value;
111
- nameToId[refName] = refId;
112
- idToName[refId] = refName;
113
- }
114
- });
115
- const readGroups = samHeader
116
- .filter(l => l.tag === 'RG')
117
- .map(rgLine => { var _a; return (_a = rgLine.data.find(item => item.tag === 'ID')) === null || _a === void 0 ? void 0 : _a.value; });
118
- const data = { idToName, nameToId, readGroups };
119
- this.samHeader = data;
120
- return {
121
- samHeader: data,
122
- ...conf,
123
- };
97
+ async setupPre(_opts) {
98
+ const conf = await this.configure();
99
+ const { cram } = conf;
100
+ const samHeader = await cram.cram.getSamHeader();
101
+ const idToName = [];
102
+ const nameToId = {};
103
+ samHeader
104
+ .filter(l => l.tag === 'SQ')
105
+ .forEach((sqLine, refId) => {
106
+ const SN = sqLine.data.find(item => item.tag === 'SN');
107
+ if (SN) {
108
+ const refName = SN.value;
109
+ nameToId[refName] = refId;
110
+ idToName[refId] = refName;
111
+ }
124
112
  });
113
+ const readGroups = samHeader
114
+ .filter(l => l.tag === 'RG')
115
+ .map(rgLine => { var _a; return (_a = rgLine.data.find(item => item.tag === 'ID')) === null || _a === void 0 ? void 0 : _a.value; });
116
+ const data = { idToName, nameToId, readGroups };
117
+ this.samHeader = data;
118
+ return {
119
+ samHeader: data,
120
+ ...conf,
121
+ };
125
122
  }
126
- async setup(opts) {
123
+ async setupPre2(opts) {
127
124
  if (!this.setupP) {
128
125
  this.setupP = this.setupPre(opts).catch((e) => {
129
126
  this.setupP = undefined;
@@ -132,6 +129,10 @@ class CramAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
132
129
  }
133
130
  return this.setupP;
134
131
  }
132
+ async setup(opts) {
133
+ const { statusCallback = () => { } } = opts || {};
134
+ return (0, util_1.updateStatus)('Downloading index', statusCallback, () => this.setupPre2(opts));
135
+ }
135
136
  async getRefNames(opts) {
136
137
  const { samHeader } = await this.setup(opts);
137
138
  if (!samHeader.idToName) {
@@ -0,0 +1,20 @@
1
+ import type { ModificationType, SortedBy } from '../shared/types';
2
+ import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
+ export declare function doAfterAttach(model: {
4
+ autorunReady: boolean;
5
+ sortedBy?: SortedBy;
6
+ adapterConfig: AnyConfigurationModel;
7
+ rendererType: {
8
+ name: string;
9
+ };
10
+ sortReady: boolean;
11
+ currSortBpPerPx: number;
12
+ parentTrack: any;
13
+ renderPropsPre: () => Record<string, unknown>;
14
+ setCurrSortBpPerPx: (arg: number) => void;
15
+ setError: (arg: unknown) => void;
16
+ updateVisibleModifications: (arg: ModificationType[]) => void;
17
+ setModificationsReady: (arg: boolean) => void;
18
+ setSortReady: (arg: boolean) => void;
19
+ setMessage: (arg: string) => void;
20
+ }): void;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.doAfterAttach = doAfterAttach;
4
+ const util_1 = require("@jbrowse/core/util");
5
+ const tracks_1 = require("@jbrowse/core/util/tracks");
6
+ const mobx_state_tree_1 = require("mobx-state-tree");
7
+ const getUniqueModifications_1 = require("../shared/getUniqueModifications");
8
+ const util_2 = require("../util");
9
+ function doAfterAttach(model) {
10
+ (0, util_2.createAutorun)(model, async () => {
11
+ const view = (0, util_1.getContainingView)(model);
12
+ if (!model.autorunReady) {
13
+ return;
14
+ }
15
+ model.setCurrSortBpPerPx(view.bpPerPx);
16
+ }, { delay: 1000 });
17
+ (0, util_2.createAutorun)(model, async () => {
18
+ const { rpcManager } = (0, util_1.getSession)(model);
19
+ const view = (0, util_1.getContainingView)(model);
20
+ if (!model.autorunReady) {
21
+ return;
22
+ }
23
+ const { sortedBy, adapterConfig, rendererType, sortReady } = model;
24
+ const { bpPerPx } = view;
25
+ if (sortedBy && (!sortReady || model.currSortBpPerPx === view.bpPerPx)) {
26
+ const { pos, refName, assemblyName } = sortedBy;
27
+ await model.rendererType.renderInClient(rpcManager, {
28
+ assemblyName,
29
+ regions: [
30
+ {
31
+ start: pos,
32
+ end: pos + 1,
33
+ refName,
34
+ assemblyName,
35
+ },
36
+ ],
37
+ adapterConfig,
38
+ rendererType: rendererType.name,
39
+ sessionId: (0, tracks_1.getRpcSessionId)(model),
40
+ layoutId: view.id,
41
+ timeout: 1000000,
42
+ statusCallback: (arg) => {
43
+ model.setMessage(arg);
44
+ },
45
+ ...model.renderPropsPre(),
46
+ });
47
+ }
48
+ if ((0, mobx_state_tree_1.isAlive)(model)) {
49
+ model.setCurrSortBpPerPx(bpPerPx);
50
+ model.setSortReady(true);
51
+ }
52
+ }, { delay: 1000 });
53
+ (0, util_2.createAutorun)(model, async () => {
54
+ if (!model.autorunReady) {
55
+ return;
56
+ }
57
+ const { adapterConfig } = model;
58
+ const { staticBlocks } = (0, util_1.getContainingView)(model);
59
+ const vals = await (0, getUniqueModifications_1.getUniqueModifications)({
60
+ model,
61
+ adapterConfig,
62
+ blocks: staticBlocks,
63
+ });
64
+ if ((0, mobx_state_tree_1.isAlive)(model)) {
65
+ model.updateVisibleModifications(vals);
66
+ model.setModificationsReady(true);
67
+ }
68
+ }, { delay: 1000 });
69
+ }
@@ -39,7 +39,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const react_1 = require("react");
40
40
  const configuration_1 = require("@jbrowse/core/configuration");
41
41
  const util_1 = require("@jbrowse/core/util");
42
- const tracks_1 = require("@jbrowse/core/util/tracks");
43
42
  const ColorLens_1 = __importDefault(require("@mui/icons-material/ColorLens"));
44
43
  const SwapVert_1 = __importDefault(require("@mui/icons-material/SwapVert"));
45
44
  const Visibility_1 = __importDefault(require("@mui/icons-material/Visibility"));
@@ -47,7 +46,6 @@ const Workspaces_1 = __importDefault(require("@mui/icons-material/Workspaces"));
47
46
  const mobx_1 = require("mobx");
48
47
  const mobx_state_tree_1 = require("mobx-state-tree");
49
48
  const SharedLinearPileupDisplayMixin_1 = require("./SharedLinearPileupDisplayMixin");
50
- const getUniqueModifications_1 = require("../shared/getUniqueModifications");
51
49
  const util_2 = require("../util");
52
50
  const SortByTagDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/SortByTagDialog'))));
53
51
  const GroupByDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/GroupByDialog'))));
@@ -349,62 +347,17 @@ function stateModelFactory(configSchema) {
349
347
  })
350
348
  .actions(self => ({
351
349
  afterAttach() {
352
- (0, util_2.createAutorun)(self, async () => {
353
- const view = (0, util_1.getContainingView)(self);
354
- if (!self.autorunReady) {
355
- return;
350
+ ;
351
+ (async () => {
352
+ try {
353
+ const { doAfterAttach } = await Promise.resolve().then(() => __importStar(require('./doAfterAttach')));
354
+ doAfterAttach(self);
356
355
  }
357
- self.setCurrSortBpPerPx(view.bpPerPx);
358
- }, { delay: 1000 });
359
- (0, util_2.createAutorun)(self, async () => {
360
- const { rpcManager } = (0, util_1.getSession)(self);
361
- const view = (0, util_1.getContainingView)(self);
362
- if (!self.autorunReady) {
363
- return;
356
+ catch (e) {
357
+ (0, util_1.getSession)(self).notifyError(`${e}`, e);
358
+ console.error(e);
364
359
  }
365
- const { sortedBy, adapterConfig, rendererType, sortReady } = self;
366
- const { bpPerPx } = view;
367
- if (sortedBy &&
368
- (!sortReady || self.currSortBpPerPx === view.bpPerPx)) {
369
- const { pos, refName, assemblyName } = sortedBy;
370
- await self.rendererType.renderInClient(rpcManager, {
371
- assemblyName,
372
- regions: [
373
- {
374
- start: pos,
375
- end: pos + 1,
376
- refName,
377
- assemblyName,
378
- },
379
- ],
380
- adapterConfig,
381
- rendererType: rendererType.name,
382
- sessionId: (0, tracks_1.getRpcSessionId)(self),
383
- layoutId: view.id,
384
- timeout: 1000000,
385
- ...self.renderPropsPre(),
386
- });
387
- }
388
- if ((0, mobx_state_tree_1.isAlive)(self)) {
389
- self.setCurrSortBpPerPx(bpPerPx);
390
- self.setSortReady(true);
391
- }
392
- }, { delay: 1000 });
393
- (0, util_2.createAutorun)(self, async () => {
394
- if (!self.autorunReady) {
395
- return;
396
- }
397
- const { staticBlocks } = (0, util_1.getContainingView)(self);
398
- const vals = await (0, getUniqueModifications_1.getUniqueModifications)({
399
- self,
400
- adapterConfig: (0, configuration_1.getConf)(self.parentTrack, 'adapter'),
401
- blocks: staticBlocks,
402
- });
403
- if ((0, mobx_state_tree_1.isAlive)(self)) {
404
- self.updateVisibleModifications(vals);
405
- self.setModificationsReady(true);
406
- }
407
- });
360
+ })();
408
361
  },
409
362
  }));
410
363
  }
@@ -97,6 +97,7 @@ declare function stateModelFactory(pluginManager: PluginManager, configSchema: A
97
97
  configuration: AnyConfigurationSchemaType;
98
98
  } & {
99
99
  type: import("mobx-state-tree").ISimpleType<"LinearWiggleDisplay">;
100
+ invertedSetting: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<boolean>>;
100
101
  } & {
101
102
  type: import("mobx-state-tree").ISimpleType<"LinearSNPCoverageDisplay">;
102
103
  showInterbaseCounts: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<boolean>>;
@@ -171,7 +171,7 @@ function stateModelFactory(pluginManager, configSchema) {
171
171
  const { colorBy } = self;
172
172
  if ((colorBy === null || colorBy === void 0 ? void 0 : colorBy.type) === 'modifications') {
173
173
  const vals = await (0, getUniqueModifications_1.getUniqueModifications)({
174
- self,
174
+ model: self,
175
175
  adapterConfig: (0, configuration_1.getConf)(self.parentTrack, 'adapter'),
176
176
  blocks: staticBlocks,
177
177
  });
@@ -218,7 +218,7 @@ function stateModelFactory(pluginManager, configSchema) {
218
218
  get rendererTypeName() {
219
219
  return rendererTypes.get('snpcoverage');
220
220
  },
221
- get needsScalebar() {
221
+ get graphType() {
222
222
  return true;
223
223
  },
224
224
  contextMenuItems() {
@@ -242,7 +242,7 @@ function stateModelFactory(pluginManager, configSchema) {
242
242
  type: 'checkbox',
243
243
  checked: self.showInterbaseCountsSetting,
244
244
  onClick: () => {
245
- self.setShowInterbaseCounts(self.showInterbaseCountsSetting);
245
+ self.setShowInterbaseCounts(!self.showInterbaseCountsSetting);
246
246
  },
247
247
  },
248
248
  {
@@ -251,7 +251,7 @@ function stateModelFactory(pluginManager, configSchema) {
251
251
  type: 'checkbox',
252
252
  checked: self.showArcsSetting,
253
253
  onClick: () => {
254
- self.setShowArcs(self.showArcsSetting);
254
+ self.setShowArcs(!self.showArcsSetting);
255
255
  },
256
256
  },
257
257
  ];
@@ -13,9 +13,10 @@ class PileupGetGlobalValueForTag extends base_1.default {
13
13
  this.name = 'PileupGetGlobalValueForTag';
14
14
  }
15
15
  async execute(args, rpcDriver) {
16
- const { adapterConfig, sessionId, regions, tag } = await this.deserializeArguments(args, rpcDriver);
16
+ const deserializedArgs = await this.deserializeArguments(args, rpcDriver);
17
+ const { adapterConfig, sessionId, regions, tag } = deserializedArgs;
17
18
  const dataAdapter = (await (0, dataAdapterCache_1.getAdapter)(this.pluginManager, sessionId, adapterConfig)).dataAdapter;
18
- const features = dataAdapter.getFeaturesInMultipleRegions(regions);
19
+ const features = dataAdapter.getFeaturesInMultipleRegions(regions, deserializedArgs);
19
20
  const featuresArray = await (0, rxjs_1.firstValueFrom)(features.pipe((0, operators_1.toArray)()));
20
21
  return [
21
22
  ...new Set(featuresArray
@@ -16,10 +16,12 @@ class PileupGetReducedFeatures extends base_1.default {
16
16
  this.name = 'PileupGetReducedFeatures';
17
17
  }
18
18
  async execute(args, rpcDriver) {
19
- const des = await this.deserializeArguments(args, rpcDriver);
20
- const { adapterConfig, sessionId, regions } = des;
19
+ const deserializedArgs = await this.deserializeArguments(args, rpcDriver);
20
+ const { adapterConfig, sessionId, regions } = deserializedArgs;
21
21
  const dataAdapter = (await (0, dataAdapterCache_1.getAdapter)(this.pluginManager, sessionId, adapterConfig)).dataAdapter;
22
- const featuresArray = await (0, rxjs_1.firstValueFrom)(dataAdapter.getFeaturesInMultipleRegions(regions, des).pipe((0, operators_1.toArray)()));
22
+ const featuresArray = await (0, rxjs_1.firstValueFrom)(dataAdapter
23
+ .getFeaturesInMultipleRegions(regions, deserializedArgs)
24
+ .pipe((0, operators_1.toArray)()));
23
25
  const reduced = (0, util_1.dedupe)(featuresArray.map(f => {
24
26
  var _a;
25
27
  return ({
@@ -15,17 +15,20 @@ class PileupGetVisibleModifications extends base_1.default {
15
15
  this.name = 'PileupGetVisibleModifications';
16
16
  }
17
17
  async execute(args, rpcDriver) {
18
- const { adapterConfig, sessionId, regions } = await this.deserializeArguments(args, rpcDriver);
18
+ const deserializeArguments = await this.deserializeArguments(args, rpcDriver);
19
+ const { adapterConfig, sessionId, regions } = deserializeArguments;
19
20
  const dataAdapter = (await (0, dataAdapterCache_1.getAdapter)(this.pluginManager, sessionId, adapterConfig)).dataAdapter;
20
- const featuresArray = await (0, rxjs_1.firstValueFrom)(dataAdapter.getFeaturesInMultipleRegions(regions).pipe((0, operators_1.toArray)()));
21
+ const featuresArray = await (0, rxjs_1.firstValueFrom)(dataAdapter
22
+ .getFeaturesInMultipleRegions(regions, deserializeArguments)
23
+ .pipe((0, operators_1.toArray)()));
21
24
  const uniqueModifications = new Map();
22
- featuresArray.forEach(f => {
23
- for (const mod of (0, ModificationParser_1.getModTypes)((0, util_1.getTagAlt)(f, 'MM', 'Mm') || '')) {
25
+ for (const feat of featuresArray) {
26
+ for (const mod of (0, ModificationParser_1.getModTypes)((0, util_1.getTagAlt)(feat, 'MM', 'Mm') || '')) {
24
27
  if (!uniqueModifications.has(mod.type)) {
25
28
  uniqueModifications.set(mod.type, mod);
26
29
  }
27
30
  }
28
- });
31
+ }
29
32
  return [...uniqueModifications.values()];
30
33
  }
31
34
  }
@@ -75,31 +75,33 @@ class PileupRenderer extends BoxRendererType_1.default {
75
75
  async render(renderProps) {
76
76
  const features = await this.getFeatures(renderProps);
77
77
  const layout = this.createLayoutInWorker(renderProps);
78
- const { colorBy, regions, bpPerPx } = renderProps;
78
+ const { statusCallback = () => { }, colorBy, regions, bpPerPx } = renderProps;
79
79
  const region = regions[0];
80
- const regionSequence = (colorBy === null || colorBy === void 0 ? void 0 : colorBy.type) === 'methylation' && features.size
81
- ? await this.fetchSequence(renderProps, region)
82
- : undefined;
83
- const { layoutRecords, height } = (0, layoutFeatures_1.layoutFeats)({
80
+ const width = (region.end - region.start) / bpPerPx;
81
+ const { layoutRecords, height } = await (0, util_1.updateStatus)('Creating layout', statusCallback, () => (0, layoutFeatures_1.layoutFeats)({
84
82
  ...renderProps,
85
83
  features,
86
84
  layout,
87
- });
88
- const width = (region.end - region.start) / bpPerPx;
89
- const { makeImageData } = await Promise.resolve().then(() => __importStar(require('./makeImageData')));
90
- const res = await (0, util_1.renderToAbstractCanvas)(width, height, renderProps, ctx => {
91
- makeImageData({
92
- ctx,
93
- layoutRecords,
94
- canvasWidth: width,
95
- renderArgs: {
96
- ...renderProps,
97
- layout,
98
- features,
99
- regionSequence,
100
- },
85
+ }));
86
+ const res = await (0, util_1.updateStatus)('Rendering alignments', statusCallback, async () => {
87
+ const regionSequence = (colorBy === null || colorBy === void 0 ? void 0 : colorBy.type) === 'methylation' && features.size
88
+ ? await this.fetchSequence(renderProps, region)
89
+ : undefined;
90
+ const { makeImageData } = await Promise.resolve().then(() => __importStar(require('./makeImageData')));
91
+ return (0, util_1.renderToAbstractCanvas)(width, height, renderProps, ctx => {
92
+ makeImageData({
93
+ ctx,
94
+ layoutRecords,
95
+ canvasWidth: width,
96
+ renderArgs: {
97
+ ...renderProps,
98
+ layout,
99
+ features,
100
+ regionSequence,
101
+ },
102
+ });
103
+ return undefined;
101
104
  });
102
- return undefined;
103
105
  });
104
106
  const results = await super.render({
105
107
  ...renderProps,
@@ -14,6 +14,7 @@ export interface RenderArgsDeserialized extends BoxRenderArgsDeserialized {
14
14
  sortedBy?: SortedBy;
15
15
  showSoftClip: boolean;
16
16
  highResolutionScaling: number;
17
+ statusCallback?: (arg: string) => void;
17
18
  }
18
19
  export interface ProcessedRenderArgs extends RenderArgsDeserialized {
19
20
  features: Map<string, Feature>;
@@ -33,11 +33,13 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ const util_1 = require("@jbrowse/core/util");
36
37
  const plugin_wiggle_1 = require("@jbrowse/plugin-wiggle");
37
38
  class SNPCoverageRenderer extends plugin_wiggle_1.WiggleBaseRenderer {
38
39
  async draw(ctx, props) {
40
+ const { statusCallback = () => { } } = props;
39
41
  const { makeImage } = await Promise.resolve().then(() => __importStar(require('./makeImage')));
40
- await makeImage(ctx, props);
42
+ await (0, util_1.updateStatus)('Rendering coverage', statusCallback, () => makeImage(ctx, props));
41
43
  return undefined;
42
44
  }
43
45
  }
@@ -15,5 +15,6 @@ export interface RenderArgsDeserializedWithFeatures extends RenderArgsDeserializ
15
15
  };
16
16
  displayCrossHatches: boolean;
17
17
  visibleModifications?: Record<string, ModificationTypeWithColor>;
18
+ statusCallback?: (arg: string) => void;
18
19
  colorBy: ColorBy;
19
20
  }
@@ -2,13 +2,14 @@ import type { ModificationType } from './types';
2
2
  import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
3
  import type { BlockSet } from '@jbrowse/core/util/blockTypes';
4
4
  import type { IAnyStateTreeNode } from 'mobx-state-tree';
5
- export declare function getUniqueModifications({ self, adapterConfig, blocks, opts, }: {
6
- self: IAnyStateTreeNode;
5
+ export interface ModificationOpts {
6
+ headers?: Record<string, string>;
7
+ stopToken?: string;
8
+ filters: string[];
9
+ }
10
+ export declare function getUniqueModifications({ model, adapterConfig, blocks, opts, }: {
11
+ model: IAnyStateTreeNode;
7
12
  adapterConfig: AnyConfigurationModel;
8
13
  blocks: BlockSet;
9
- opts?: {
10
- headers?: Record<string, string>;
11
- stopToken?: string;
12
- filters: string[];
13
- };
14
+ opts?: ModificationOpts;
14
15
  }): Promise<ModificationType[]>;
@@ -3,13 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getUniqueModifications = getUniqueModifications;
4
4
  const util_1 = require("@jbrowse/core/util");
5
5
  const tracks_1 = require("@jbrowse/core/util/tracks");
6
- async function getUniqueModifications({ self, adapterConfig, blocks, opts, }) {
7
- const { rpcManager } = (0, util_1.getSession)(self);
8
- const sessionId = (0, tracks_1.getRpcSessionId)(self);
6
+ async function getUniqueModifications({ model, adapterConfig, blocks, opts, }) {
7
+ const { rpcManager } = (0, util_1.getSession)(model);
8
+ const sessionId = (0, tracks_1.getRpcSessionId)(model);
9
9
  const values = await rpcManager.call(sessionId, 'PileupGetVisibleModifications', {
10
10
  adapterConfig,
11
11
  sessionId,
12
12
  regions: blocks.contentBlocks,
13
+ statusCallback: (arg) => {
14
+ model.setMessage(arg);
15
+ },
13
16
  ...opts,
14
17
  });
15
18
  return values;
@@ -26,6 +26,7 @@ export default class BamAdapter extends BaseFeatureDataAdapter {
26
26
  }>;
27
27
  getHeader(_opts?: BaseOptions): Promise<string | undefined>;
28
28
  private setupPre;
29
+ setupPre2(opts?: BaseOptions): Promise<Header>;
29
30
  setup(opts?: BaseOptions): Promise<Header>;
30
31
  getRefNames(opts?: BaseOptions): Promise<string[]>;
31
32
  private seqFetch;
@@ -51,26 +51,23 @@ export default class BamAdapter extends BaseFeatureDataAdapter {
51
51
  const { bam } = await this.configure();
52
52
  return bam.getHeaderText();
53
53
  }
54
- async setupPre(opts) {
55
- const { statusCallback = () => { } } = opts || {};
54
+ async setupPre(_opts) {
56
55
  const { bam } = await this.configure();
57
- this.samHeader = await updateStatus('Downloading index', statusCallback, async () => {
58
- const samHeader = await bam.getHeader();
59
- const idToName = [];
60
- const nameToId = {};
61
- samHeader === null || samHeader === void 0 ? void 0 : samHeader.filter(l => l.tag === 'SQ').forEach((sqLine, refId) => {
62
- const SN = sqLine.data.find(item => item.tag === 'SN');
63
- if (SN) {
64
- const refName = SN.value;
65
- nameToId[refName] = refId;
66
- idToName[refId] = refName;
67
- }
68
- });
69
- return { idToName, nameToId };
56
+ const samHeader = await bam.getHeader();
57
+ const idToName = [];
58
+ const nameToId = {};
59
+ samHeader === null || samHeader === void 0 ? void 0 : samHeader.filter(l => l.tag === 'SQ').forEach((sqLine, refId) => {
60
+ const SN = sqLine.data.find(item => item.tag === 'SN');
61
+ if (SN) {
62
+ const refName = SN.value;
63
+ nameToId[refName] = refId;
64
+ idToName[refId] = refName;
65
+ }
70
66
  });
67
+ this.samHeader = { idToName, nameToId };
71
68
  return this.samHeader;
72
69
  }
73
- async setup(opts) {
70
+ async setupPre2(opts) {
74
71
  if (!this.setupP) {
75
72
  this.setupP = this.setupPre(opts).catch((e) => {
76
73
  this.setupP = undefined;
@@ -79,6 +76,10 @@ export default class BamAdapter extends BaseFeatureDataAdapter {
79
76
  }
80
77
  return this.setupP;
81
78
  }
79
+ async setup(opts) {
80
+ const { statusCallback = () => { } } = opts || {};
81
+ return updateStatus('Downloading index', statusCallback, () => this.setupPre2(opts));
82
+ }
82
83
  async getRefNames(opts) {
83
84
  const { idToName } = await this.setup(opts);
84
85
  return idToName;
@@ -28,7 +28,12 @@ export default class CramAdapter extends BaseFeatureDataAdapter {
28
28
  getHeader(_opts?: BaseOptions): Promise<string | undefined>;
29
29
  private seqFetch;
30
30
  private setupPre;
31
- private setup;
31
+ private setupPre2;
32
+ setup(opts?: BaseOptions): Promise<{
33
+ samHeader: Header;
34
+ cram: IndexedCramFile;
35
+ sequenceAdapter: BaseSequenceAdapter;
36
+ }>;
32
37
  getRefNames(opts?: BaseOptions): Promise<string[]>;
33
38
  refNameToId(refName: string): number | undefined;
34
39
  refIdToName(refId: number): string | undefined;
@@ -89,36 +89,33 @@ export default class CramAdapter extends BaseFeatureDataAdapter {
89
89
  }
90
90
  return sequence;
91
91
  }
92
- async setupPre(opts) {
93
- const { statusCallback = () => { } } = opts || {};
94
- return updateStatus('Downloading index', statusCallback, async () => {
95
- const conf = await this.configure();
96
- const { cram } = conf;
97
- const samHeader = await cram.cram.getSamHeader();
98
- const idToName = [];
99
- const nameToId = {};
100
- samHeader
101
- .filter(l => l.tag === 'SQ')
102
- .forEach((sqLine, refId) => {
103
- const SN = sqLine.data.find(item => item.tag === 'SN');
104
- if (SN) {
105
- const refName = SN.value;
106
- nameToId[refName] = refId;
107
- idToName[refId] = refName;
108
- }
109
- });
110
- const readGroups = samHeader
111
- .filter(l => l.tag === 'RG')
112
- .map(rgLine => { var _a; return (_a = rgLine.data.find(item => item.tag === 'ID')) === null || _a === void 0 ? void 0 : _a.value; });
113
- const data = { idToName, nameToId, readGroups };
114
- this.samHeader = data;
115
- return {
116
- samHeader: data,
117
- ...conf,
118
- };
92
+ async setupPre(_opts) {
93
+ const conf = await this.configure();
94
+ const { cram } = conf;
95
+ const samHeader = await cram.cram.getSamHeader();
96
+ const idToName = [];
97
+ const nameToId = {};
98
+ samHeader
99
+ .filter(l => l.tag === 'SQ')
100
+ .forEach((sqLine, refId) => {
101
+ const SN = sqLine.data.find(item => item.tag === 'SN');
102
+ if (SN) {
103
+ const refName = SN.value;
104
+ nameToId[refName] = refId;
105
+ idToName[refId] = refName;
106
+ }
119
107
  });
108
+ const readGroups = samHeader
109
+ .filter(l => l.tag === 'RG')
110
+ .map(rgLine => { var _a; return (_a = rgLine.data.find(item => item.tag === 'ID')) === null || _a === void 0 ? void 0 : _a.value; });
111
+ const data = { idToName, nameToId, readGroups };
112
+ this.samHeader = data;
113
+ return {
114
+ samHeader: data,
115
+ ...conf,
116
+ };
120
117
  }
121
- async setup(opts) {
118
+ async setupPre2(opts) {
122
119
  if (!this.setupP) {
123
120
  this.setupP = this.setupPre(opts).catch((e) => {
124
121
  this.setupP = undefined;
@@ -127,6 +124,10 @@ export default class CramAdapter extends BaseFeatureDataAdapter {
127
124
  }
128
125
  return this.setupP;
129
126
  }
127
+ async setup(opts) {
128
+ const { statusCallback = () => { } } = opts || {};
129
+ return updateStatus('Downloading index', statusCallback, () => this.setupPre2(opts));
130
+ }
130
131
  async getRefNames(opts) {
131
132
  const { samHeader } = await this.setup(opts);
132
133
  if (!samHeader.idToName) {
@@ -0,0 +1,20 @@
1
+ import type { ModificationType, SortedBy } from '../shared/types';
2
+ import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
+ export declare function doAfterAttach(model: {
4
+ autorunReady: boolean;
5
+ sortedBy?: SortedBy;
6
+ adapterConfig: AnyConfigurationModel;
7
+ rendererType: {
8
+ name: string;
9
+ };
10
+ sortReady: boolean;
11
+ currSortBpPerPx: number;
12
+ parentTrack: any;
13
+ renderPropsPre: () => Record<string, unknown>;
14
+ setCurrSortBpPerPx: (arg: number) => void;
15
+ setError: (arg: unknown) => void;
16
+ updateVisibleModifications: (arg: ModificationType[]) => void;
17
+ setModificationsReady: (arg: boolean) => void;
18
+ setSortReady: (arg: boolean) => void;
19
+ setMessage: (arg: string) => void;
20
+ }): void;
@@ -0,0 +1,66 @@
1
+ import { getContainingView, getSession } from '@jbrowse/core/util';
2
+ import { getRpcSessionId } from '@jbrowse/core/util/tracks';
3
+ import { isAlive } from 'mobx-state-tree';
4
+ import { getUniqueModifications } from '../shared/getUniqueModifications';
5
+ import { createAutorun } from '../util';
6
+ export function doAfterAttach(model) {
7
+ createAutorun(model, async () => {
8
+ const view = getContainingView(model);
9
+ if (!model.autorunReady) {
10
+ return;
11
+ }
12
+ model.setCurrSortBpPerPx(view.bpPerPx);
13
+ }, { delay: 1000 });
14
+ createAutorun(model, async () => {
15
+ const { rpcManager } = getSession(model);
16
+ const view = getContainingView(model);
17
+ if (!model.autorunReady) {
18
+ return;
19
+ }
20
+ const { sortedBy, adapterConfig, rendererType, sortReady } = model;
21
+ const { bpPerPx } = view;
22
+ if (sortedBy && (!sortReady || model.currSortBpPerPx === view.bpPerPx)) {
23
+ const { pos, refName, assemblyName } = sortedBy;
24
+ await model.rendererType.renderInClient(rpcManager, {
25
+ assemblyName,
26
+ regions: [
27
+ {
28
+ start: pos,
29
+ end: pos + 1,
30
+ refName,
31
+ assemblyName,
32
+ },
33
+ ],
34
+ adapterConfig,
35
+ rendererType: rendererType.name,
36
+ sessionId: getRpcSessionId(model),
37
+ layoutId: view.id,
38
+ timeout: 1000000,
39
+ statusCallback: (arg) => {
40
+ model.setMessage(arg);
41
+ },
42
+ ...model.renderPropsPre(),
43
+ });
44
+ }
45
+ if (isAlive(model)) {
46
+ model.setCurrSortBpPerPx(bpPerPx);
47
+ model.setSortReady(true);
48
+ }
49
+ }, { delay: 1000 });
50
+ createAutorun(model, async () => {
51
+ if (!model.autorunReady) {
52
+ return;
53
+ }
54
+ const { adapterConfig } = model;
55
+ const { staticBlocks } = getContainingView(model);
56
+ const vals = await getUniqueModifications({
57
+ model,
58
+ adapterConfig,
59
+ blocks: staticBlocks,
60
+ });
61
+ if (isAlive(model)) {
62
+ model.updateVisibleModifications(vals);
63
+ model.setModificationsReady(true);
64
+ }
65
+ }, { delay: 1000 });
66
+ }
@@ -1,16 +1,14 @@
1
1
  import { lazy } from 'react';
2
2
  import { ConfigurationReference, getConf, readConfObject, } from '@jbrowse/core/configuration';
3
3
  import { getContainingView, getEnv, getSession } from '@jbrowse/core/util';
4
- import { getRpcSessionId } from '@jbrowse/core/util/tracks';
5
4
  import ColorLensIcon from '@mui/icons-material/ColorLens';
6
5
  import SwapVertIcon from '@mui/icons-material/SwapVert';
7
6
  import VisibilityIcon from '@mui/icons-material/Visibility';
8
7
  import WorkspacesIcon from '@mui/icons-material/Workspaces';
9
8
  import { observable } from 'mobx';
10
- import { isAlive, types } from 'mobx-state-tree';
9
+ import { types } from 'mobx-state-tree';
11
10
  import { SharedLinearPileupDisplayMixin } from './SharedLinearPileupDisplayMixin';
12
- import { getUniqueModifications } from '../shared/getUniqueModifications';
13
- import { createAutorun, getColorForModification, modificationData, } from '../util';
11
+ import { getColorForModification, modificationData } from '../util';
14
12
  const SortByTagDialog = lazy(() => import('./components/SortByTagDialog'));
15
13
  const GroupByDialog = lazy(() => import('./components/GroupByDialog'));
16
14
  function stateModelFactory(configSchema) {
@@ -311,62 +309,17 @@ function stateModelFactory(configSchema) {
311
309
  })
312
310
  .actions(self => ({
313
311
  afterAttach() {
314
- createAutorun(self, async () => {
315
- const view = getContainingView(self);
316
- if (!self.autorunReady) {
317
- return;
312
+ ;
313
+ (async () => {
314
+ try {
315
+ const { doAfterAttach } = await import('./doAfterAttach');
316
+ doAfterAttach(self);
318
317
  }
319
- self.setCurrSortBpPerPx(view.bpPerPx);
320
- }, { delay: 1000 });
321
- createAutorun(self, async () => {
322
- const { rpcManager } = getSession(self);
323
- const view = getContainingView(self);
324
- if (!self.autorunReady) {
325
- return;
318
+ catch (e) {
319
+ getSession(self).notifyError(`${e}`, e);
320
+ console.error(e);
326
321
  }
327
- const { sortedBy, adapterConfig, rendererType, sortReady } = self;
328
- const { bpPerPx } = view;
329
- if (sortedBy &&
330
- (!sortReady || self.currSortBpPerPx === view.bpPerPx)) {
331
- const { pos, refName, assemblyName } = sortedBy;
332
- await self.rendererType.renderInClient(rpcManager, {
333
- assemblyName,
334
- regions: [
335
- {
336
- start: pos,
337
- end: pos + 1,
338
- refName,
339
- assemblyName,
340
- },
341
- ],
342
- adapterConfig,
343
- rendererType: rendererType.name,
344
- sessionId: getRpcSessionId(self),
345
- layoutId: view.id,
346
- timeout: 1000000,
347
- ...self.renderPropsPre(),
348
- });
349
- }
350
- if (isAlive(self)) {
351
- self.setCurrSortBpPerPx(bpPerPx);
352
- self.setSortReady(true);
353
- }
354
- }, { delay: 1000 });
355
- createAutorun(self, async () => {
356
- if (!self.autorunReady) {
357
- return;
358
- }
359
- const { staticBlocks } = getContainingView(self);
360
- const vals = await getUniqueModifications({
361
- self,
362
- adapterConfig: getConf(self.parentTrack, 'adapter'),
363
- blocks: staticBlocks,
364
- });
365
- if (isAlive(self)) {
366
- self.updateVisibleModifications(vals);
367
- self.setModificationsReady(true);
368
- }
369
- });
322
+ })();
370
323
  },
371
324
  }));
372
325
  }
@@ -97,6 +97,7 @@ declare function stateModelFactory(pluginManager: PluginManager, configSchema: A
97
97
  configuration: AnyConfigurationSchemaType;
98
98
  } & {
99
99
  type: import("mobx-state-tree").ISimpleType<"LinearWiggleDisplay">;
100
+ invertedSetting: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<boolean>>;
100
101
  } & {
101
102
  type: import("mobx-state-tree").ISimpleType<"LinearSNPCoverageDisplay">;
102
103
  showInterbaseCounts: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<boolean>>;
@@ -133,7 +133,7 @@ function stateModelFactory(pluginManager, configSchema) {
133
133
  const { colorBy } = self;
134
134
  if ((colorBy === null || colorBy === void 0 ? void 0 : colorBy.type) === 'modifications') {
135
135
  const vals = await getUniqueModifications({
136
- self,
136
+ model: self,
137
137
  adapterConfig: getConf(self.parentTrack, 'adapter'),
138
138
  blocks: staticBlocks,
139
139
  });
@@ -180,7 +180,7 @@ function stateModelFactory(pluginManager, configSchema) {
180
180
  get rendererTypeName() {
181
181
  return rendererTypes.get('snpcoverage');
182
182
  },
183
- get needsScalebar() {
183
+ get graphType() {
184
184
  return true;
185
185
  },
186
186
  contextMenuItems() {
@@ -204,7 +204,7 @@ function stateModelFactory(pluginManager, configSchema) {
204
204
  type: 'checkbox',
205
205
  checked: self.showInterbaseCountsSetting,
206
206
  onClick: () => {
207
- self.setShowInterbaseCounts(self.showInterbaseCountsSetting);
207
+ self.setShowInterbaseCounts(!self.showInterbaseCountsSetting);
208
208
  },
209
209
  },
210
210
  {
@@ -213,7 +213,7 @@ function stateModelFactory(pluginManager, configSchema) {
213
213
  type: 'checkbox',
214
214
  checked: self.showArcsSetting,
215
215
  onClick: () => {
216
- self.setShowArcs(self.showArcsSetting);
216
+ self.setShowArcs(!self.showArcsSetting);
217
217
  },
218
218
  },
219
219
  ];
@@ -8,9 +8,10 @@ export default class PileupGetGlobalValueForTag extends PileupBaseRPC {
8
8
  this.name = 'PileupGetGlobalValueForTag';
9
9
  }
10
10
  async execute(args, rpcDriver) {
11
- const { adapterConfig, sessionId, regions, tag } = await this.deserializeArguments(args, rpcDriver);
11
+ const deserializedArgs = await this.deserializeArguments(args, rpcDriver);
12
+ const { adapterConfig, sessionId, regions, tag } = deserializedArgs;
12
13
  const dataAdapter = (await getAdapter(this.pluginManager, sessionId, adapterConfig)).dataAdapter;
13
- const features = dataAdapter.getFeaturesInMultipleRegions(regions);
14
+ const features = dataAdapter.getFeaturesInMultipleRegions(regions, deserializedArgs);
14
15
  const featuresArray = await firstValueFrom(features.pipe(toArray()));
15
16
  return [
16
17
  ...new Set(featuresArray
@@ -11,10 +11,12 @@ export default class PileupGetReducedFeatures extends PileupBaseRPC {
11
11
  this.name = 'PileupGetReducedFeatures';
12
12
  }
13
13
  async execute(args, rpcDriver) {
14
- const des = await this.deserializeArguments(args, rpcDriver);
15
- const { adapterConfig, sessionId, regions } = des;
14
+ const deserializedArgs = await this.deserializeArguments(args, rpcDriver);
15
+ const { adapterConfig, sessionId, regions } = deserializedArgs;
16
16
  const dataAdapter = (await getAdapter(this.pluginManager, sessionId, adapterConfig)).dataAdapter;
17
- const featuresArray = await firstValueFrom(dataAdapter.getFeaturesInMultipleRegions(regions, des).pipe(toArray()));
17
+ const featuresArray = await firstValueFrom(dataAdapter
18
+ .getFeaturesInMultipleRegions(regions, deserializedArgs)
19
+ .pipe(toArray()));
18
20
  const reduced = dedupe(featuresArray.map(f => {
19
21
  var _a;
20
22
  return ({
@@ -10,17 +10,20 @@ export default class PileupGetVisibleModifications extends PileupBaseRPC {
10
10
  this.name = 'PileupGetVisibleModifications';
11
11
  }
12
12
  async execute(args, rpcDriver) {
13
- const { adapterConfig, sessionId, regions } = await this.deserializeArguments(args, rpcDriver);
13
+ const deserializeArguments = await this.deserializeArguments(args, rpcDriver);
14
+ const { adapterConfig, sessionId, regions } = deserializeArguments;
14
15
  const dataAdapter = (await getAdapter(this.pluginManager, sessionId, adapterConfig)).dataAdapter;
15
- const featuresArray = await firstValueFrom(dataAdapter.getFeaturesInMultipleRegions(regions).pipe(toArray()));
16
+ const featuresArray = await firstValueFrom(dataAdapter
17
+ .getFeaturesInMultipleRegions(regions, deserializeArguments)
18
+ .pipe(toArray()));
16
19
  const uniqueModifications = new Map();
17
- featuresArray.forEach(f => {
18
- for (const mod of getModTypes(getTagAlt(f, 'MM', 'Mm') || '')) {
20
+ for (const feat of featuresArray) {
21
+ for (const mod of getModTypes(getTagAlt(feat, 'MM', 'Mm') || '')) {
19
22
  if (!uniqueModifications.has(mod.type)) {
20
23
  uniqueModifications.set(mod.type, mod);
21
24
  }
22
25
  }
23
- });
26
+ }
24
27
  return [...uniqueModifications.values()];
25
28
  }
26
29
  }
@@ -1,7 +1,7 @@
1
1
  import { readConfObject } from '@jbrowse/core/configuration';
2
2
  import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
3
3
  import BoxRendererType from '@jbrowse/core/pluggableElementTypes/renderers/BoxRendererType';
4
- import { renderToAbstractCanvas } from '@jbrowse/core/util';
4
+ import { renderToAbstractCanvas, updateStatus } from '@jbrowse/core/util';
5
5
  import { PileupLayoutSession } from './PileupLayoutSession';
6
6
  import { fetchSequence } from '../util';
7
7
  import { layoutFeats } from './layoutFeatures';
@@ -37,31 +37,33 @@ export default class PileupRenderer extends BoxRendererType {
37
37
  async render(renderProps) {
38
38
  const features = await this.getFeatures(renderProps);
39
39
  const layout = this.createLayoutInWorker(renderProps);
40
- const { colorBy, regions, bpPerPx } = renderProps;
40
+ const { statusCallback = () => { }, colorBy, regions, bpPerPx } = renderProps;
41
41
  const region = regions[0];
42
- const regionSequence = (colorBy === null || colorBy === void 0 ? void 0 : colorBy.type) === 'methylation' && features.size
43
- ? await this.fetchSequence(renderProps, region)
44
- : undefined;
45
- const { layoutRecords, height } = layoutFeats({
42
+ const width = (region.end - region.start) / bpPerPx;
43
+ const { layoutRecords, height } = await updateStatus('Creating layout', statusCallback, () => layoutFeats({
46
44
  ...renderProps,
47
45
  features,
48
46
  layout,
49
- });
50
- const width = (region.end - region.start) / bpPerPx;
51
- const { makeImageData } = await import('./makeImageData');
52
- const res = await renderToAbstractCanvas(width, height, renderProps, ctx => {
53
- makeImageData({
54
- ctx,
55
- layoutRecords,
56
- canvasWidth: width,
57
- renderArgs: {
58
- ...renderProps,
59
- layout,
60
- features,
61
- regionSequence,
62
- },
47
+ }));
48
+ const res = await updateStatus('Rendering alignments', statusCallback, async () => {
49
+ const regionSequence = (colorBy === null || colorBy === void 0 ? void 0 : colorBy.type) === 'methylation' && features.size
50
+ ? await this.fetchSequence(renderProps, region)
51
+ : undefined;
52
+ const { makeImageData } = await import('./makeImageData');
53
+ return renderToAbstractCanvas(width, height, renderProps, ctx => {
54
+ makeImageData({
55
+ ctx,
56
+ layoutRecords,
57
+ canvasWidth: width,
58
+ renderArgs: {
59
+ ...renderProps,
60
+ layout,
61
+ features,
62
+ regionSequence,
63
+ },
64
+ });
65
+ return undefined;
63
66
  });
64
- return undefined;
65
67
  });
66
68
  const results = await super.render({
67
69
  ...renderProps,
@@ -14,6 +14,7 @@ export interface RenderArgsDeserialized extends BoxRenderArgsDeserialized {
14
14
  sortedBy?: SortedBy;
15
15
  showSoftClip: boolean;
16
16
  highResolutionScaling: number;
17
+ statusCallback?: (arg: string) => void;
17
18
  }
18
19
  export interface ProcessedRenderArgs extends RenderArgsDeserialized {
19
20
  features: Map<string, Feature>;
@@ -1,8 +1,10 @@
1
+ import { updateStatus } from '@jbrowse/core/util';
1
2
  import { WiggleBaseRenderer } from '@jbrowse/plugin-wiggle';
2
3
  export default class SNPCoverageRenderer extends WiggleBaseRenderer {
3
4
  async draw(ctx, props) {
5
+ const { statusCallback = () => { } } = props;
4
6
  const { makeImage } = await import('./makeImage');
5
- await makeImage(ctx, props);
7
+ await updateStatus('Rendering coverage', statusCallback, () => makeImage(ctx, props));
6
8
  return undefined;
7
9
  }
8
10
  }
@@ -15,5 +15,6 @@ export interface RenderArgsDeserializedWithFeatures extends RenderArgsDeserializ
15
15
  };
16
16
  displayCrossHatches: boolean;
17
17
  visibleModifications?: Record<string, ModificationTypeWithColor>;
18
+ statusCallback?: (arg: string) => void;
18
19
  colorBy: ColorBy;
19
20
  }
@@ -2,13 +2,14 @@ import type { ModificationType } from './types';
2
2
  import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
3
  import type { BlockSet } from '@jbrowse/core/util/blockTypes';
4
4
  import type { IAnyStateTreeNode } from 'mobx-state-tree';
5
- export declare function getUniqueModifications({ self, adapterConfig, blocks, opts, }: {
6
- self: IAnyStateTreeNode;
5
+ export interface ModificationOpts {
6
+ headers?: Record<string, string>;
7
+ stopToken?: string;
8
+ filters: string[];
9
+ }
10
+ export declare function getUniqueModifications({ model, adapterConfig, blocks, opts, }: {
11
+ model: IAnyStateTreeNode;
7
12
  adapterConfig: AnyConfigurationModel;
8
13
  blocks: BlockSet;
9
- opts?: {
10
- headers?: Record<string, string>;
11
- stopToken?: string;
12
- filters: string[];
13
- };
14
+ opts?: ModificationOpts;
14
15
  }): Promise<ModificationType[]>;
@@ -1,12 +1,15 @@
1
1
  import { getSession } from '@jbrowse/core/util';
2
2
  import { getRpcSessionId } from '@jbrowse/core/util/tracks';
3
- export async function getUniqueModifications({ self, adapterConfig, blocks, opts, }) {
4
- const { rpcManager } = getSession(self);
5
- const sessionId = getRpcSessionId(self);
3
+ export async function getUniqueModifications({ model, adapterConfig, blocks, opts, }) {
4
+ const { rpcManager } = getSession(model);
5
+ const sessionId = getRpcSessionId(model);
6
6
  const values = await rpcManager.call(sessionId, 'PileupGetVisibleModifications', {
7
7
  adapterConfig,
8
8
  sessionId,
9
9
  regions: blocks.contentBlocks,
10
+ statusCallback: (arg) => {
11
+ model.setMessage(arg);
12
+ },
10
13
  ...opts,
11
14
  });
12
15
  return values;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-alignments",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "JBrowse 2 alignments adapters, tracks, etc.",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -38,10 +38,10 @@
38
38
  "dependencies": {
39
39
  "@gmod/bam": "^5.0.0",
40
40
  "@gmod/cram": "^4.0.1",
41
- "@jbrowse/core": "^3.0.1",
42
- "@jbrowse/plugin-linear-genome-view": "^3.0.1",
43
- "@jbrowse/plugin-wiggle": "^3.0.1",
44
- "@jbrowse/sv-core": "^3.0.1",
41
+ "@jbrowse/core": "^3.0.3",
42
+ "@jbrowse/plugin-linear-genome-view": "^3.0.3",
43
+ "@jbrowse/plugin-wiggle": "^3.0.3",
44
+ "@jbrowse/sv-core": "^3.0.3",
45
45
  "@mui/icons-material": "^6.0.0",
46
46
  "@mui/material": "^6.0.0",
47
47
  "canvas2svg": "^1.0.16",
@@ -63,5 +63,5 @@
63
63
  "distModule": "esm/index.js",
64
64
  "srcModule": "src/index.ts",
65
65
  "module": "esm/index.js",
66
- "gitHead": "aa2f1d1a89d2361c7fd1a93fe29506fa4554f5cc"
66
+ "gitHead": "f516540428282351d26e46743e69a724651bfb2c"
67
67
  }