@jbrowse/plugin-grid-bookmark 2.6.2 → 2.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.
- package/dist/GridBookmarkWidget/components/AssemblySelector.d.ts +3 -4
- package/dist/GridBookmarkWidget/components/AssemblySelector.js +27 -37
- package/dist/GridBookmarkWidget/components/BookmarkGrid.d.ts +6 -0
- package/dist/GridBookmarkWidget/components/BookmarkGrid.js +120 -0
- package/dist/GridBookmarkWidget/components/{ClearBookmarks.d.ts → DeleteBookmarks.d.ts} +2 -3
- package/dist/GridBookmarkWidget/components/DeleteBookmarks.js +41 -0
- package/dist/GridBookmarkWidget/components/DeleteBookmarksDialog.d.ts +7 -0
- package/dist/GridBookmarkWidget/components/DeleteBookmarksDialog.js +29 -0
- package/dist/GridBookmarkWidget/components/EditBookmarkLabelDialog.d.ts +8 -0
- package/dist/GridBookmarkWidget/components/EditBookmarkLabelDialog.js +50 -0
- package/dist/GridBookmarkWidget/components/ExportBookmarks.d.ts +6 -0
- package/dist/GridBookmarkWidget/components/{ClearBookmarks.js → ExportBookmarks.js} +9 -19
- package/dist/GridBookmarkWidget/components/ExportBookmarksDialog.d.ts +7 -0
- package/dist/GridBookmarkWidget/components/{DownloadBookmarks.js → ExportBookmarksDialog.js} +22 -20
- package/dist/GridBookmarkWidget/components/GridBookmarkWidget.d.ts +3 -4
- package/dist/GridBookmarkWidget/components/GridBookmarkWidget.js +28 -97
- package/dist/GridBookmarkWidget/components/ImportBookmarks.d.ts +3 -5
- package/dist/GridBookmarkWidget/components/ImportBookmarks.js +8 -64
- package/dist/GridBookmarkWidget/components/ImportBookmarksDialog.d.ts +7 -0
- package/dist/GridBookmarkWidget/components/ImportBookmarksDialog.js +129 -0
- package/{esm/GridBookmarkWidget/components/ClearBookmarks.d.ts → dist/GridBookmarkWidget/components/ShareBookmarks.d.ts} +2 -3
- package/dist/GridBookmarkWidget/components/ShareBookmarks.js +37 -0
- package/dist/GridBookmarkWidget/components/ShareBookmarksDialog.d.ts +7 -0
- package/dist/GridBookmarkWidget/components/ShareBookmarksDialog.js +106 -0
- package/dist/GridBookmarkWidget/model.d.ts +178 -11
- package/dist/GridBookmarkWidget/model.js +105 -27
- package/dist/GridBookmarkWidget/sessionSharing.d.ts +6 -0
- package/dist/GridBookmarkWidget/sessionSharing.js +96 -0
- package/dist/GridBookmarkWidget/utils.d.ts +19 -3
- package/dist/GridBookmarkWidget/utils.js +132 -40
- package/dist/index.d.ts +1 -1
- package/dist/index.js +100 -75
- package/esm/GridBookmarkWidget/components/AssemblySelector.d.ts +3 -4
- package/esm/GridBookmarkWidget/components/AssemblySelector.js +28 -38
- package/esm/GridBookmarkWidget/components/BookmarkGrid.d.ts +6 -0
- package/esm/GridBookmarkWidget/components/BookmarkGrid.js +92 -0
- package/{dist/GridBookmarkWidget/components/DownloadBookmarks.d.ts → esm/GridBookmarkWidget/components/DeleteBookmarks.d.ts} +2 -3
- package/esm/GridBookmarkWidget/components/DeleteBookmarks.js +13 -0
- package/esm/GridBookmarkWidget/components/DeleteBookmarksDialog.d.ts +7 -0
- package/esm/GridBookmarkWidget/components/DeleteBookmarksDialog.js +24 -0
- package/esm/GridBookmarkWidget/components/EditBookmarkLabelDialog.d.ts +8 -0
- package/esm/GridBookmarkWidget/components/EditBookmarkLabelDialog.js +25 -0
- package/esm/GridBookmarkWidget/components/ExportBookmarks.d.ts +6 -0
- package/esm/GridBookmarkWidget/components/ExportBookmarks.js +13 -0
- package/esm/GridBookmarkWidget/components/ExportBookmarksDialog.d.ts +7 -0
- package/esm/GridBookmarkWidget/components/ExportBookmarksDialog.js +35 -0
- package/esm/GridBookmarkWidget/components/GridBookmarkWidget.d.ts +3 -4
- package/esm/GridBookmarkWidget/components/GridBookmarkWidget.js +28 -74
- package/esm/GridBookmarkWidget/components/ImportBookmarks.d.ts +3 -5
- package/esm/GridBookmarkWidget/components/ImportBookmarks.js +10 -66
- package/esm/GridBookmarkWidget/components/ImportBookmarksDialog.d.ts +7 -0
- package/esm/GridBookmarkWidget/components/ImportBookmarksDialog.js +101 -0
- package/esm/GridBookmarkWidget/components/{DownloadBookmarks.d.ts → ShareBookmarks.d.ts} +2 -3
- package/esm/GridBookmarkWidget/components/ShareBookmarks.js +12 -0
- package/esm/GridBookmarkWidget/components/ShareBookmarksDialog.d.ts +7 -0
- package/esm/GridBookmarkWidget/components/ShareBookmarksDialog.js +78 -0
- package/esm/GridBookmarkWidget/model.d.ts +178 -11
- package/esm/GridBookmarkWidget/model.js +106 -28
- package/esm/GridBookmarkWidget/sessionSharing.d.ts +6 -0
- package/esm/GridBookmarkWidget/sessionSharing.js +68 -0
- package/esm/GridBookmarkWidget/utils.d.ts +19 -3
- package/esm/GridBookmarkWidget/utils.js +105 -39
- package/esm/index.d.ts +1 -1
- package/esm/index.js +101 -76
- package/package.json +4 -3
- package/dist/GridBookmarkWidget/components/DeleteBookmark.d.ts +0 -9
- package/dist/GridBookmarkWidget/components/DeleteBookmark.js +0 -31
- package/esm/GridBookmarkWidget/components/ClearBookmarks.js +0 -23
- package/esm/GridBookmarkWidget/components/DeleteBookmark.d.ts +0 -9
- package/esm/GridBookmarkWidget/components/DeleteBookmark.js +0 -26
- package/esm/GridBookmarkWidget/components/DownloadBookmarks.js +0 -33
|
@@ -2,55 +2,133 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
4
4
|
const mst_1 = require("@jbrowse/core/util/types/mst");
|
|
5
|
+
const util_1 = require("@jbrowse/core/util");
|
|
6
|
+
const mobx_1 = require("mobx");
|
|
5
7
|
const LabeledRegionModel = mobx_state_tree_1.types
|
|
6
|
-
.compose(mst_1.Region, mobx_state_tree_1.types.model('Label', {
|
|
8
|
+
.compose(mst_1.Region, mobx_state_tree_1.types.model('Label', {
|
|
9
|
+
label: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string, ''),
|
|
10
|
+
}))
|
|
7
11
|
.actions(self => ({
|
|
8
12
|
setLabel(label) {
|
|
9
13
|
self.label = label;
|
|
10
14
|
},
|
|
11
15
|
}));
|
|
12
|
-
|
|
16
|
+
const SharedBookmarksModel = mobx_state_tree_1.types.model('SharedBookmarksModel', {
|
|
17
|
+
sharedBookmarks: mobx_state_tree_1.types.maybe(mobx_state_tree_1.types.array(LabeledRegionModel)),
|
|
18
|
+
});
|
|
19
|
+
const localStorageKeyF = () => typeof window !== undefined
|
|
20
|
+
? `bookmarks-${[window.location.host + window.location.pathname].join('-')}`
|
|
21
|
+
: 'empty';
|
|
22
|
+
function f(_pluginManager) {
|
|
13
23
|
return mobx_state_tree_1.types
|
|
14
24
|
.model('GridBookmarkModel', {
|
|
25
|
+
/**
|
|
26
|
+
* #property
|
|
27
|
+
*/
|
|
15
28
|
id: mst_1.ElementId,
|
|
29
|
+
/**
|
|
30
|
+
* #property
|
|
31
|
+
*/
|
|
16
32
|
type: mobx_state_tree_1.types.literal('GridBookmarkWidget'),
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
33
|
+
/**
|
|
34
|
+
* #property
|
|
35
|
+
* removed by postProcessSnapshot, only loaded from localStorage
|
|
36
|
+
*/
|
|
37
|
+
bookmarks: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.array(LabeledRegionModel), () => JSON.parse((0, util_1.localStorageGetItem)(localStorageKeyF()) || '[]')),
|
|
20
38
|
})
|
|
39
|
+
.volatile(() => ({
|
|
40
|
+
selectedBookmarks: [],
|
|
41
|
+
selectedAssembliesPre: undefined,
|
|
42
|
+
}))
|
|
43
|
+
.views(self => ({
|
|
44
|
+
get bookmarkAssemblies() {
|
|
45
|
+
return [...new Set(self.bookmarks.map(r => r.assemblyName))];
|
|
46
|
+
},
|
|
47
|
+
get validAssemblies() {
|
|
48
|
+
const { assemblyManager } = (0, util_1.getSession)(self);
|
|
49
|
+
return new Set(this.bookmarkAssemblies.filter(a => assemblyManager.get(a)));
|
|
50
|
+
},
|
|
51
|
+
}))
|
|
52
|
+
.views(self => ({
|
|
53
|
+
get bookmarksWithValidAssemblies() {
|
|
54
|
+
return self.bookmarks.filter(e => self.validAssemblies.has(e.assemblyName));
|
|
55
|
+
},
|
|
56
|
+
}))
|
|
57
|
+
.views(self => ({
|
|
58
|
+
get sharedBookmarksModel() {
|
|
59
|
+
// requires cloning bookmarks with JSON.stringify/parse to avoid duplicate
|
|
60
|
+
// reference to same object in the same state tree, will otherwise error
|
|
61
|
+
// when performing share
|
|
62
|
+
return SharedBookmarksModel.create({
|
|
63
|
+
sharedBookmarks: JSON.parse(JSON.stringify(self.selectedBookmarks)),
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
get allBookmarksModel() {
|
|
67
|
+
// requires cloning bookmarks with JSON.stringify/parse to avoid duplicate
|
|
68
|
+
// reference to same object in the same state tree, will otherwise error
|
|
69
|
+
// when performing share
|
|
70
|
+
return SharedBookmarksModel.create({
|
|
71
|
+
sharedBookmarks: JSON.parse(JSON.stringify(self.bookmarksWithValidAssemblies)),
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
}))
|
|
75
|
+
.actions(self => ({
|
|
76
|
+
setSelectedAssemblies(assemblies) {
|
|
77
|
+
self.selectedAssembliesPre = assemblies;
|
|
78
|
+
},
|
|
79
|
+
}))
|
|
80
|
+
.views(self => ({
|
|
81
|
+
get selectedAssemblies() {
|
|
82
|
+
var _a, _b;
|
|
83
|
+
return ((_b = (_a = self.selectedAssembliesPre) === null || _a === void 0 ? void 0 : _a.filter(f => self.validAssemblies.has(f))) !== null && _b !== void 0 ? _b : [...self.validAssemblies]);
|
|
84
|
+
},
|
|
85
|
+
}))
|
|
21
86
|
.actions(self => ({
|
|
22
87
|
importBookmarks(regions) {
|
|
23
|
-
self.
|
|
88
|
+
self.bookmarks = (0, mobx_state_tree_1.cast)([...self.bookmarks, ...regions]);
|
|
24
89
|
},
|
|
25
90
|
addBookmark(region) {
|
|
26
|
-
self.
|
|
91
|
+
self.bookmarks.push(region);
|
|
27
92
|
},
|
|
28
93
|
removeBookmark(index) {
|
|
29
|
-
self.
|
|
94
|
+
self.bookmarks.splice(index, 1);
|
|
95
|
+
},
|
|
96
|
+
updateBookmarkLabel(bookmark, label) {
|
|
97
|
+
bookmark.correspondingObj.setLabel(label);
|
|
98
|
+
},
|
|
99
|
+
setSelectedBookmarks(bookmarks) {
|
|
100
|
+
self.selectedBookmarks = bookmarks;
|
|
30
101
|
},
|
|
102
|
+
setBookmarkedRegions(regions) {
|
|
103
|
+
self.bookmarks = (0, mobx_state_tree_1.cast)(regions);
|
|
104
|
+
},
|
|
105
|
+
}))
|
|
106
|
+
.actions(self => ({
|
|
31
107
|
clearAllBookmarks() {
|
|
32
|
-
self.
|
|
108
|
+
for (const bookmark of self.bookmarks) {
|
|
109
|
+
if (self.validAssemblies.has(bookmark.assemblyName)) {
|
|
110
|
+
self.bookmarks.remove(bookmark);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
33
113
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
114
|
+
clearSelectedBookmarks() {
|
|
115
|
+
for (const bookmark of self.selectedBookmarks) {
|
|
116
|
+
self.bookmarks.remove(bookmark.correspondingObj);
|
|
117
|
+
}
|
|
118
|
+
self.selectedBookmarks = [];
|
|
37
119
|
},
|
|
38
|
-
|
|
39
|
-
|
|
120
|
+
}))
|
|
121
|
+
.actions(self => ({
|
|
122
|
+
afterAttach() {
|
|
123
|
+
const key = localStorageKeyF();
|
|
124
|
+
(0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
|
|
125
|
+
(0, util_1.localStorageSetItem)(key, JSON.stringify(self.bookmarks));
|
|
126
|
+
}));
|
|
40
127
|
},
|
|
41
128
|
}))
|
|
42
|
-
.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
? self.bookmarkedRegions[0].assemblyName
|
|
47
|
-
: ''));
|
|
48
|
-
},
|
|
49
|
-
get assemblies() {
|
|
50
|
-
return [
|
|
51
|
-
...new Set(self.bookmarkedRegions.map(region => region.assemblyName)),
|
|
52
|
-
];
|
|
53
|
-
},
|
|
54
|
-
}));
|
|
129
|
+
.postProcessSnapshot(snap => {
|
|
130
|
+
const { bookmarks: _, ...rest } = snap;
|
|
131
|
+
return rest;
|
|
132
|
+
});
|
|
55
133
|
}
|
|
56
134
|
exports.default = f;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function shareSessionToDynamo(session: unknown, url: string, referer: string): Promise<{
|
|
2
|
+
json: any;
|
|
3
|
+
encryptedSession: string;
|
|
4
|
+
password: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function readSessionFromDynamo(baseUrl: string, sessionQueryParam: string, password: string, signal?: AbortSignal): Promise<string>;
|
|
@@ -0,0 +1,96 @@
|
|
|
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
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.readSessionFromDynamo = exports.shareSessionToDynamo = void 0;
|
|
27
|
+
// duplicated from products/jbrowse-web/src/sessionSharing.ts ; could possibly be moved into a higher directory and shared between the two
|
|
28
|
+
const utils_1 = require("./utils");
|
|
29
|
+
// from https://stackoverflow.com/questions/1349404/
|
|
30
|
+
function generateUID(length) {
|
|
31
|
+
return window
|
|
32
|
+
.btoa([...window.crypto.getRandomValues(new Uint8Array(length * 2))]
|
|
33
|
+
.map(b => String.fromCharCode(b))
|
|
34
|
+
.join(''))
|
|
35
|
+
.replaceAll(/[+/]/g, '')
|
|
36
|
+
.slice(0, length);
|
|
37
|
+
}
|
|
38
|
+
const encrypt = async (text, password) => {
|
|
39
|
+
const AES = await Promise.resolve().then(() => __importStar(require('crypto-js/aes')));
|
|
40
|
+
return AES.encrypt(text, password).toString();
|
|
41
|
+
};
|
|
42
|
+
const decrypt = async (text, password) => {
|
|
43
|
+
const AES = await Promise.resolve().then(() => __importStar(require('crypto-js/aes')));
|
|
44
|
+
const Utf8 = await Promise.resolve().then(() => __importStar(require('crypto-js/enc-utf8')));
|
|
45
|
+
const bytes = AES.decrypt(text, password);
|
|
46
|
+
return bytes.toString(Utf8);
|
|
47
|
+
};
|
|
48
|
+
function getErrorMsg(err) {
|
|
49
|
+
try {
|
|
50
|
+
const obj = JSON.parse(err);
|
|
51
|
+
return obj.message;
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
return err;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// writes the encrypted session, current datetime, and referer to DynamoDB
|
|
58
|
+
async function shareSessionToDynamo(session, url, referer) {
|
|
59
|
+
const sess = await (0, utils_1.toUrlSafeB64)(JSON.stringify(session));
|
|
60
|
+
const password = generateUID(5);
|
|
61
|
+
const encryptedSession = await encrypt(sess, password);
|
|
62
|
+
const data = new FormData();
|
|
63
|
+
data.append('session', encryptedSession);
|
|
64
|
+
data.append('dateShared', `${Date.now()}`);
|
|
65
|
+
data.append('referer', referer);
|
|
66
|
+
const response = await fetch(`${url}share`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
mode: 'cors',
|
|
69
|
+
body: data,
|
|
70
|
+
});
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
const err = await response.text();
|
|
73
|
+
throw new Error(getErrorMsg(err));
|
|
74
|
+
}
|
|
75
|
+
const json = await response.json();
|
|
76
|
+
return {
|
|
77
|
+
json,
|
|
78
|
+
encryptedSession,
|
|
79
|
+
password,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
exports.shareSessionToDynamo = shareSessionToDynamo;
|
|
83
|
+
async function readSessionFromDynamo(baseUrl, sessionQueryParam, password, signal) {
|
|
84
|
+
const sessionId = sessionQueryParam.split('share-')[1];
|
|
85
|
+
const url = `${baseUrl}?sessionId=${encodeURIComponent(sessionId)}`;
|
|
86
|
+
const response = await fetch(url, {
|
|
87
|
+
signal,
|
|
88
|
+
});
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
const err = await response.text();
|
|
91
|
+
throw new Error(getErrorMsg(err));
|
|
92
|
+
}
|
|
93
|
+
const json = await response.json();
|
|
94
|
+
return decrypt(json.session, password);
|
|
95
|
+
}
|
|
96
|
+
exports.readSessionFromDynamo = readSessionFromDynamo;
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import { AbstractViewModel } from '@jbrowse/core/util/types';
|
|
2
2
|
import { GridBookmarkModel } from './model';
|
|
3
|
-
|
|
4
|
-
export declare function
|
|
5
|
-
|
|
3
|
+
export declare function navToBookmark(locString: string, assembly: string, views: AbstractViewModel[], model: GridBookmarkModel): Promise<void>;
|
|
4
|
+
export declare function downloadBookmarkFile(fileFormat: string, model: GridBookmarkModel): void;
|
|
5
|
+
/**
|
|
6
|
+
* Pad the end of a base64 string with "=" to make it valid
|
|
7
|
+
* @param b64 - unpadded b64 string
|
|
8
|
+
*/
|
|
9
|
+
export declare function b64PadSuffix(b64: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Decode and inflate a url-safe base64 to a string
|
|
12
|
+
* See {@link https://en.wikipedia.org/wiki/Base64#URL_applications}
|
|
13
|
+
* @param b64 - a base64 string to decode and inflate
|
|
14
|
+
*/
|
|
15
|
+
export declare function fromUrlSafeB64(b64: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Compress and encode a string as url-safe base64
|
|
18
|
+
* See {@link https://en.wikipedia.org/wiki/Base64#URL_applications}
|
|
19
|
+
* @param str- a string to compress and encode
|
|
20
|
+
*/
|
|
21
|
+
export declare function toUrlSafeB64(str: string): Promise<string>;
|
|
@@ -1,25 +1,51 @@
|
|
|
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
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.downloadBookmarkFile = exports.navToBookmark = void 0;
|
|
26
|
+
exports.toUrlSafeB64 = exports.fromUrlSafeB64 = exports.b64PadSuffix = exports.downloadBookmarkFile = exports.navToBookmark = void 0;
|
|
4
27
|
const file_saver_1 = require("file-saver");
|
|
5
28
|
const util_1 = require("@jbrowse/core/util");
|
|
6
|
-
async function navToBookmark(locString, views, model) {
|
|
29
|
+
async function navToBookmark(locString, assembly, views, model) {
|
|
7
30
|
const session = (0, util_1.getSession)(model);
|
|
8
31
|
try {
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
32
|
+
// get the focused view
|
|
33
|
+
let view = views.find(view => view.id === session.focusedViewId);
|
|
34
|
+
// check if the focused view is the appropriate assembly, if not proceed
|
|
35
|
+
if ((view === null || view === void 0 ? void 0 : view.assemblyNames[0]) !== assembly) {
|
|
36
|
+
view = views.find(elt =>
|
|
37
|
+
// @ts-expect-error
|
|
38
|
+
elt.type === 'LinearGenomeView' && elt.assemblyNames[0] === assembly);
|
|
39
|
+
}
|
|
40
|
+
// if no view is opened of the selectedAssembly, open a new
|
|
41
|
+
// view with that assembly
|
|
17
42
|
if (!view) {
|
|
43
|
+
const newViewId = `${model.id}_${assembly}`;
|
|
18
44
|
view = session.addView('LinearGenomeView', {
|
|
19
45
|
id: newViewId,
|
|
20
46
|
});
|
|
21
47
|
}
|
|
22
|
-
await view.navToLocString(locString,
|
|
48
|
+
await view.navToLocString(locString, assembly);
|
|
23
49
|
}
|
|
24
50
|
catch (e) {
|
|
25
51
|
console.error(e);
|
|
@@ -27,35 +53,101 @@ async function navToBookmark(locString, views, model) {
|
|
|
27
53
|
}
|
|
28
54
|
}
|
|
29
55
|
exports.navToBookmark = navToBookmark;
|
|
30
|
-
function downloadBookmarkFile(
|
|
31
|
-
const {
|
|
32
|
-
const
|
|
33
|
-
?
|
|
34
|
-
:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
function downloadBookmarkFile(fileFormat, model) {
|
|
57
|
+
const { selectedBookmarks, bookmarksWithValidAssemblies } = model;
|
|
58
|
+
const bookmarksToDownload = selectedBookmarks.length === 0
|
|
59
|
+
? bookmarksWithValidAssemblies
|
|
60
|
+
: selectedBookmarks;
|
|
61
|
+
if (fileFormat === 'BED') {
|
|
62
|
+
const fileHeader = '';
|
|
63
|
+
const fileContents = {};
|
|
64
|
+
bookmarksToDownload.forEach(bookmark => {
|
|
65
|
+
const { label } = bookmark;
|
|
66
|
+
const labelVal = label === '' ? '.' : label;
|
|
67
|
+
const line = `${bookmark.refName}\t${bookmark.start}\t${bookmark.end}\t${labelVal}\n`;
|
|
68
|
+
fileContents[bookmark.assemblyName]
|
|
69
|
+
? fileContents[bookmark.assemblyName].push(line)
|
|
70
|
+
: (fileContents[bookmark.assemblyName] = [line]);
|
|
71
|
+
});
|
|
72
|
+
for (const assembly in fileContents) {
|
|
73
|
+
const fileContent = fileContents[assembly].reduce((a, b) => a + b, fileHeader);
|
|
74
|
+
const blob = new Blob([fileContent || ''], {
|
|
75
|
+
type: 'text/x-bed;charset=utf-8',
|
|
76
|
+
});
|
|
77
|
+
const fileName = `jbrowse_bookmarks_${assembly}.bed`;
|
|
78
|
+
(0, file_saver_1.saveAs)(blob, fileName);
|
|
48
79
|
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// TSV
|
|
83
|
+
const fileHeader = 'chrom\tstart\tend\tlabel\tassembly_name\tcoord_range\n';
|
|
84
|
+
const fileContents = bookmarksToDownload
|
|
85
|
+
.map(bookmark => {
|
|
86
|
+
const { label } = bookmark;
|
|
87
|
+
const labelVal = label === '' ? '.' : label;
|
|
88
|
+
const locString = (0, util_1.assembleLocString)(bookmark);
|
|
89
|
+
return `${bookmark.refName}\t${bookmark.start + 1}\t${bookmark.end}\t${labelVal}\t${bookmark.assemblyName}\t${locString}\n`;
|
|
90
|
+
})
|
|
91
|
+
.reduce((a, b) => a + b, fileHeader);
|
|
92
|
+
const blob = new Blob([fileContents || ''], {
|
|
93
|
+
type: 'text/tab-separated-values;charset=utf-8',
|
|
94
|
+
});
|
|
95
|
+
const fileName = 'jbrowse_bookmarks.tsv';
|
|
96
|
+
(0, file_saver_1.saveAs)(blob, fileName);
|
|
97
|
+
}
|
|
60
98
|
}
|
|
61
99
|
exports.downloadBookmarkFile = downloadBookmarkFile;
|
|
100
|
+
/**
|
|
101
|
+
* Pad the end of a base64 string with "=" to make it valid
|
|
102
|
+
* @param b64 - unpadded b64 string
|
|
103
|
+
*/
|
|
104
|
+
function b64PadSuffix(b64) {
|
|
105
|
+
let num = 0;
|
|
106
|
+
const mo = b64.length % 4;
|
|
107
|
+
switch (mo) {
|
|
108
|
+
case 3:
|
|
109
|
+
num = 1;
|
|
110
|
+
break;
|
|
111
|
+
case 2:
|
|
112
|
+
num = 2;
|
|
113
|
+
break;
|
|
114
|
+
case 0:
|
|
115
|
+
num = 0;
|
|
116
|
+
break;
|
|
117
|
+
default:
|
|
118
|
+
throw new Error('base64 not a valid length');
|
|
119
|
+
}
|
|
120
|
+
return b64 + '='.repeat(num);
|
|
121
|
+
}
|
|
122
|
+
exports.b64PadSuffix = b64PadSuffix;
|
|
123
|
+
/**
|
|
124
|
+
* Decode and inflate a url-safe base64 to a string
|
|
125
|
+
* See {@link https://en.wikipedia.org/wiki/Base64#URL_applications}
|
|
126
|
+
* @param b64 - a base64 string to decode and inflate
|
|
127
|
+
*/
|
|
128
|
+
async function fromUrlSafeB64(b64) {
|
|
129
|
+
const originalB64 = b64PadSuffix(b64.replaceAll('-', '+').replaceAll('_', '/'));
|
|
130
|
+
const { toByteArray } = await Promise.resolve().then(() => __importStar(require('base64-js')));
|
|
131
|
+
const { inflate } = await Promise.resolve().then(() => __importStar(require('pako')));
|
|
132
|
+
const bytes = toByteArray(originalB64);
|
|
133
|
+
const inflated = inflate(bytes);
|
|
134
|
+
return new TextDecoder().decode(inflated);
|
|
135
|
+
}
|
|
136
|
+
exports.fromUrlSafeB64 = fromUrlSafeB64;
|
|
137
|
+
/**
|
|
138
|
+
* Compress and encode a string as url-safe base64
|
|
139
|
+
* See {@link https://en.wikipedia.org/wiki/Base64#URL_applications}
|
|
140
|
+
* @param str- a string to compress and encode
|
|
141
|
+
*/
|
|
142
|
+
async function toUrlSafeB64(str) {
|
|
143
|
+
const bytes = new TextEncoder().encode(str);
|
|
144
|
+
const { deflate } = await Promise.resolve().then(() => __importStar(require('pako')));
|
|
145
|
+
const { fromByteArray } = await Promise.resolve().then(() => __importStar(require('base64-js')));
|
|
146
|
+
const deflated = deflate(bytes);
|
|
147
|
+
const encoded = fromByteArray(deflated);
|
|
148
|
+
const pos = encoded.indexOf('=');
|
|
149
|
+
return pos > 0
|
|
150
|
+
? encoded.slice(0, pos).replaceAll('+', '-').replaceAll('/', '_')
|
|
151
|
+
: encoded.replaceAll('+', '-').replaceAll('/', '_');
|
|
152
|
+
}
|
|
153
|
+
exports.toUrlSafeB64 = toUrlSafeB64;
|
package/dist/index.d.ts
CHANGED