@genome-spy/app 0.90.0 → 1.1.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/SharedReadCache-Ey5QIiPM.js +207 -0
- package/dist/{agentApi-Z65dw-sD.js → agentApi-BgZUOeB-.js} +3333 -3298
- package/dist/agentApi.es.js +1480 -1445
- package/dist/esm-C-6g-SkZ.js +791 -0
- package/dist/{esm-L53qjcYH.js → esm-CJeszW-t.js} +344 -250
- package/dist/esm-CjkeZi__.js +238 -0
- package/dist/index.es.js +9 -11
- package/dist/index.js +362 -363
- package/dist/schema.json +7 -0
- package/package.json +7 -9
- package/LICENSE +0 -21
- package/dist/AbortablePromiseCache-BTmAcN-t.js +0 -96
- package/dist/esm-BiqrFjMh.js +0 -443
- package/dist/esm-DtNElqRr.js +0 -462
package/dist/schema.json
CHANGED
|
@@ -17894,6 +17894,13 @@
|
|
|
17894
17894
|
"$ref": "#/definitions/IndexUrlSourceRef",
|
|
17895
17895
|
"description": "URL of the index file. When `url` is a template, this can be an index URL template using the same placeholder and values.\n\n__Default value:__ `url` + `\".bai\"`."
|
|
17896
17896
|
},
|
|
17897
|
+
"tags": {
|
|
17898
|
+
"description": "SAM auxiliary tags to expose on each read, for example `[\"HP\", \"CB\"]`. Each tag is available as a field named `tag_` followed by the tag name, for example `tag_HP`. The field is `undefined` when a read lacks the tag. Tags that are not listed are not decoded.",
|
|
17899
|
+
"items": {
|
|
17900
|
+
"type": "string"
|
|
17901
|
+
},
|
|
17902
|
+
"type": "array"
|
|
17903
|
+
},
|
|
17897
17904
|
"type": {
|
|
17898
17905
|
"const": "bam",
|
|
17899
17906
|
"type": "string"
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"contributors": [],
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"homepage": "https://genomespy.app/",
|
|
11
|
-
"version": "
|
|
11
|
+
"version": "1.1.0",
|
|
12
12
|
"main": "dist/index.js",
|
|
13
13
|
"module": "dist/index.es.js",
|
|
14
14
|
"type": "module",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
],
|
|
52
52
|
"repository": {
|
|
53
53
|
"type": "git",
|
|
54
|
-
"url": "github
|
|
54
|
+
"url": "git+https://github.com/genome-spy/genome-spy.git",
|
|
55
55
|
"directory": "packages/app"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
@@ -63,15 +63,14 @@
|
|
|
63
63
|
"test:tsc:tests": "tsc -p tsconfig.tests.json --noEmit",
|
|
64
64
|
"smoke:examples:webgpu": "node ../core/scripts/runWebGpuExamples.mjs --scope app --all --compare-webgl",
|
|
65
65
|
"storybook": "storybook dev -p 6006",
|
|
66
|
-
"build-storybook": "storybook build"
|
|
67
|
-
"prepublishOnly": "npm run build"
|
|
66
|
+
"build-storybook": "storybook build"
|
|
68
67
|
},
|
|
69
68
|
"dependencies": {
|
|
70
69
|
"@floating-ui/dom": "^1.6.1",
|
|
71
70
|
"@fortawesome/fontawesome-free": "^6.4.2",
|
|
72
71
|
"@fortawesome/fontawesome-svg-core": "^6.4.2",
|
|
73
72
|
"@fortawesome/free-solid-svg-icons": "^6.4.2",
|
|
74
|
-
"@genome-spy/core": "^
|
|
73
|
+
"@genome-spy/core": "^1.1.0",
|
|
75
74
|
"@reduxjs/toolkit": "^2.11.0",
|
|
76
75
|
"d3-color": "^3.1.0",
|
|
77
76
|
"idb": "^7.1.1",
|
|
@@ -84,8 +83,7 @@
|
|
|
84
83
|
"zarrita": "^0.6.1"
|
|
85
84
|
},
|
|
86
85
|
"devDependencies": {
|
|
87
|
-
"@genome-spy/app-agent": "^
|
|
88
|
-
"@genome-spy/inspector": "^
|
|
89
|
-
}
|
|
90
|
-
"gitHead": "9c73e2cc6f8f3b5146c29ac69a9ae46fcc6d09a3"
|
|
86
|
+
"@genome-spy/app-agent": "^1.1.0",
|
|
87
|
+
"@genome-spy/inspector": "^1.1.0"
|
|
88
|
+
}
|
|
91
89
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2018-2026 Kari Lavikka
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
//#region ../../node_modules/@gmod/abortable-promise-cache/esm/AggregateAbortController.js
|
|
2
|
-
var e = class {}, t = class {
|
|
3
|
-
constructor() {
|
|
4
|
-
this.signals = /* @__PURE__ */ new Set(), this.abortController = new AbortController();
|
|
5
|
-
}
|
|
6
|
-
addSignal(t = new e()) {
|
|
7
|
-
if (this.signal.aborted) throw Error("cannot add a signal, already aborted!");
|
|
8
|
-
this.signals.add(t), t.aborted ? this.handleAborted(t) : typeof t.addEventListener == "function" && t.addEventListener("abort", () => {
|
|
9
|
-
this.handleAborted(t);
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
handleAborted(e) {
|
|
13
|
-
this.signals.delete(e), this.signals.size === 0 && this.abortController.abort();
|
|
14
|
-
}
|
|
15
|
-
get signal() {
|
|
16
|
-
return this.abortController.signal;
|
|
17
|
-
}
|
|
18
|
-
abort() {
|
|
19
|
-
this.abortController.abort();
|
|
20
|
-
}
|
|
21
|
-
}, n = class {
|
|
22
|
-
constructor() {
|
|
23
|
-
this.callbacks = /* @__PURE__ */ new Set();
|
|
24
|
-
}
|
|
25
|
-
addCallback(e = () => {}) {
|
|
26
|
-
this.callbacks.add(e), this.currentMessage && e(this.currentMessage);
|
|
27
|
-
}
|
|
28
|
-
callback(e) {
|
|
29
|
-
this.currentMessage = e;
|
|
30
|
-
for (let t of this.callbacks) t(e);
|
|
31
|
-
}
|
|
32
|
-
}, r = class e {
|
|
33
|
-
constructor({ fill: e, cache: t }) {
|
|
34
|
-
if (typeof e != "function") throw TypeError("must pass a fill function");
|
|
35
|
-
if (typeof t != "object") throw TypeError("must pass a cache object");
|
|
36
|
-
if (typeof t.get != "function" || typeof t.set != "function" || typeof t.delete != "function") throw TypeError("cache must implement get(key), set(key, val), and and delete(key)");
|
|
37
|
-
this.cache = t, this.fillCallback = e;
|
|
38
|
-
}
|
|
39
|
-
static isAbortException(e) {
|
|
40
|
-
return e.name === "AbortError" || e.code === "ERR_ABORTED" || e.message === "AbortError: aborted" || e.message === "Error: aborted";
|
|
41
|
-
}
|
|
42
|
-
evict(e, t) {
|
|
43
|
-
this.cache.get(e) === t && this.cache.delete(e);
|
|
44
|
-
}
|
|
45
|
-
fill(e, r, i, a) {
|
|
46
|
-
let o = new t(), s = new n();
|
|
47
|
-
s.addCallback(a);
|
|
48
|
-
let c = {
|
|
49
|
-
aborter: o,
|
|
50
|
-
promise: this.fillCallback(r, o.signal, (e) => {
|
|
51
|
-
s.callback(e);
|
|
52
|
-
}),
|
|
53
|
-
settled: !1,
|
|
54
|
-
statusReporter: s,
|
|
55
|
-
get aborted() {
|
|
56
|
-
return this.aborter.signal.aborted;
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
c.aborter.addSignal(i), c.aborter.signal.addEventListener("abort", () => {
|
|
60
|
-
c.settled || this.evict(e, c);
|
|
61
|
-
}), c.promise.then(() => {
|
|
62
|
-
c.settled = !0;
|
|
63
|
-
}, () => {
|
|
64
|
-
c.settled = !0, this.evict(e, c);
|
|
65
|
-
}).catch((e) => {
|
|
66
|
-
throw console.error(e), e;
|
|
67
|
-
}), this.cache.set(e, c);
|
|
68
|
-
}
|
|
69
|
-
static checkSinglePromise(e, t) {
|
|
70
|
-
function n() {
|
|
71
|
-
if (t?.aborted) throw Object.assign(/* @__PURE__ */ Error("aborted"), { code: "ERR_ABORTED" });
|
|
72
|
-
}
|
|
73
|
-
return e.then((e) => (n(), e), (e) => {
|
|
74
|
-
throw n(), e;
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
has(e) {
|
|
78
|
-
return this.cache.has(e);
|
|
79
|
-
}
|
|
80
|
-
get(t, n, r, i) {
|
|
81
|
-
if (!r && n instanceof AbortSignal) throw TypeError("second get argument appears to be an AbortSignal, perhaps you meant to pass `null` for the fill data?");
|
|
82
|
-
let a = this.cache.get(t);
|
|
83
|
-
return a ? a.aborted && !a.settled ? (this.evict(t, a), this.get(t, n, r, i)) : a.settled ? a.promise : (a.aborter.addSignal(r), a.statusReporter.addCallback(i), e.checkSinglePromise(a.promise, r)) : (this.fill(t, n, r, i), e.checkSinglePromise(this.cache.get(t).promise, r));
|
|
84
|
-
}
|
|
85
|
-
delete(e) {
|
|
86
|
-
let t = this.cache.get(e);
|
|
87
|
-
t && (t.settled || t.aborter.abort(), this.cache.delete(e));
|
|
88
|
-
}
|
|
89
|
-
clear() {
|
|
90
|
-
let e = this.cache.keys(), t = 0;
|
|
91
|
-
for (let n = e.next(); !n.done; n = e.next()) this.delete(n.value), t += 1;
|
|
92
|
-
return t;
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
//#endregion
|
|
96
|
-
export { r as t };
|
package/dist/esm-BiqrFjMh.js
DELETED
|
@@ -1,443 +0,0 @@
|
|
|
1
|
-
import { i as e, n as t } from "./esm-Dndm-NaA.js";
|
|
2
|
-
import { n } from "./esm-VFJeyk9i.js";
|
|
3
|
-
//#endregion
|
|
4
|
-
//#region ../../node_modules/@gmod/bgzf-filehandle/esm/long.js
|
|
5
|
-
function r(e, t = 0) {
|
|
6
|
-
let n = e.getUint32(t, !0);
|
|
7
|
-
return e.getUint32(t + 4, !0) * 4294967296 + n;
|
|
8
|
-
}
|
|
9
|
-
//#endregion
|
|
10
|
-
//#region ../../node_modules/@gmod/bgzf-filehandle/esm/gziIndex.js
|
|
11
|
-
var i = 16, a = {
|
|
12
|
-
compressed: /* @__PURE__ */ new Float64Array(),
|
|
13
|
-
uncompressed: /* @__PURE__ */ new Float64Array()
|
|
14
|
-
};
|
|
15
|
-
function o(e, t) {
|
|
16
|
-
let n = new Float64Array(t + 1), a = new Float64Array(t + 1), o = new DataView(e.buffer, e.byteOffset, e.byteLength);
|
|
17
|
-
for (let e = 0; e < t; e += 1) {
|
|
18
|
-
let t = e * i;
|
|
19
|
-
n[e + 1] = r(o, t), a[e + 1] = r(o, t + 8);
|
|
20
|
-
}
|
|
21
|
-
return {
|
|
22
|
-
compressed: n,
|
|
23
|
-
uncompressed: a
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
function s(e, t) {
|
|
27
|
-
let n = 0, r = e.length;
|
|
28
|
-
for (; n < r;) {
|
|
29
|
-
let i = n + r >>> 1;
|
|
30
|
-
e[i] <= t ? n = i + 1 : r = i;
|
|
31
|
-
}
|
|
32
|
-
return n;
|
|
33
|
-
}
|
|
34
|
-
var c = class {
|
|
35
|
-
filehandle;
|
|
36
|
-
index;
|
|
37
|
-
constructor({ filehandle: e }) {
|
|
38
|
-
this.filehandle = e;
|
|
39
|
-
}
|
|
40
|
-
_getIndex() {
|
|
41
|
-
return this.index ||= this._readIndex().catch((e) => {
|
|
42
|
-
throw this.index = void 0, e;
|
|
43
|
-
}), this.index;
|
|
44
|
-
}
|
|
45
|
-
async _readIndex() {
|
|
46
|
-
let e = await this.filehandle.read(8, 0), t = r(new DataView(e.buffer, e.byteOffset, e.byteLength));
|
|
47
|
-
if (t === 0) return o(/* @__PURE__ */ new Uint8Array(), 0);
|
|
48
|
-
if (t > (2 ** 53 - 1) / i) throw TypeError("integer overflow");
|
|
49
|
-
return o(await this.filehandle.read(i * t, 8), t);
|
|
50
|
-
}
|
|
51
|
-
async getRelevantBlocksForRead(e, t) {
|
|
52
|
-
if (e === 0) return {
|
|
53
|
-
...a,
|
|
54
|
-
nextCompressedPosition: void 0
|
|
55
|
-
};
|
|
56
|
-
let { compressed: n, uncompressed: r } = await this._getIndex(), i = s(r, t) - 1, o = s(r, t + e - 1);
|
|
57
|
-
return {
|
|
58
|
-
compressed: n.subarray(i, o),
|
|
59
|
-
uncompressed: r.subarray(i, o),
|
|
60
|
-
nextCompressedPosition: o < n.length ? n[o] : void 0
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}, l = 10, u = 33554432;
|
|
64
|
-
function d(e) {
|
|
65
|
-
let t = 0, n = [], r = () => {
|
|
66
|
-
t--, n.shift()?.();
|
|
67
|
-
};
|
|
68
|
-
return async (i) => {
|
|
69
|
-
t >= e && await new Promise((e) => {
|
|
70
|
-
n.push(e);
|
|
71
|
-
}), t++;
|
|
72
|
-
try {
|
|
73
|
-
return await i();
|
|
74
|
-
} finally {
|
|
75
|
-
r();
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function f(e, t, n) {
|
|
80
|
-
let r = [], i = e.length, a = 0;
|
|
81
|
-
for (; a < i;) {
|
|
82
|
-
let o = a + 1;
|
|
83
|
-
for (; o < i && t[o] - t[a] < u;) o += 1;
|
|
84
|
-
r.push({
|
|
85
|
-
compressedStart: e[a],
|
|
86
|
-
compressedEnd: o < i ? e[o] : n ?? e[i - 1] + 65536,
|
|
87
|
-
uncompressedStart: t[a]
|
|
88
|
-
}), a = o;
|
|
89
|
-
}
|
|
90
|
-
return r;
|
|
91
|
-
}
|
|
92
|
-
function p(e, t, n, r) {
|
|
93
|
-
let i = Math.max(0, n - t), a = Math.min(r, t + e.length) - t;
|
|
94
|
-
return i < e.length ? e.subarray(i, a) : /* @__PURE__ */ new Uint8Array();
|
|
95
|
-
}
|
|
96
|
-
var m = class {
|
|
97
|
-
filehandle;
|
|
98
|
-
gzi;
|
|
99
|
-
limit;
|
|
100
|
-
constructor({ filehandle: e, gziFilehandle: t, blockConcurrency: n = l }) {
|
|
101
|
-
this.filehandle = e, this.gzi = new c({ filehandle: t }), this.limit = d(n);
|
|
102
|
-
}
|
|
103
|
-
async read(n, r) {
|
|
104
|
-
let { compressed: i, uncompressed: a, nextCompressedPosition: o } = await this.gzi.getRelevantBlocksForRead(n, r);
|
|
105
|
-
if (i.length === 0) return /* @__PURE__ */ new Uint8Array();
|
|
106
|
-
let s = r + n, c = f(i, a, o), l = await Promise.all(c.map((e) => this.limit(async () => {
|
|
107
|
-
let n = await this.filehandle.read(e.compressedEnd - e.compressedStart, e.compressedStart);
|
|
108
|
-
return p(await t(n), e.uncompressedStart, r, s);
|
|
109
|
-
})));
|
|
110
|
-
return e(l);
|
|
111
|
-
}
|
|
112
|
-
}, h = new TextDecoder("utf8");
|
|
113
|
-
function g(e) {
|
|
114
|
-
return e.split(">").filter((e) => /\S/.test(e)).map((e) => {
|
|
115
|
-
let [t, ...n] = e.split("\n"), [r, ...i] = t.split(" "), a = n.join("").replace(/\s/g, "");
|
|
116
|
-
return {
|
|
117
|
-
id: r,
|
|
118
|
-
description: i.join(" "),
|
|
119
|
-
sequence: a
|
|
120
|
-
};
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
var _ = class {
|
|
124
|
-
data;
|
|
125
|
-
indexed;
|
|
126
|
-
constructor({ fasta: e, path: t }) {
|
|
127
|
-
let r;
|
|
128
|
-
if (e) r = e;
|
|
129
|
-
else if (t) r = new n(t);
|
|
130
|
-
else throw Error("Need to pass fasta or path");
|
|
131
|
-
this.data = r.readFile().then((e) => g(h.decode(e)));
|
|
132
|
-
}
|
|
133
|
-
getIndexed() {
|
|
134
|
-
return this.indexed ??= this.data.then((e) => new Map(e.map((e) => [e.id, e]))), this.indexed;
|
|
135
|
-
}
|
|
136
|
-
async fetch(e, t, n) {
|
|
137
|
-
let r = (await this.getIndexed()).get(e);
|
|
138
|
-
if (!r) throw Error(`no sequence with id ${e} exists`);
|
|
139
|
-
return r.sequence.slice(t, n);
|
|
140
|
-
}
|
|
141
|
-
async getSequenceNames() {
|
|
142
|
-
return (await this.data).map((e) => e.id);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
//#endregion
|
|
146
|
-
//#region ../../node_modules/@gmod/shared-read-cache/esm/throwIfAborted.js
|
|
147
|
-
function v(e) {
|
|
148
|
-
if (e?.aborted) throw y(e);
|
|
149
|
-
}
|
|
150
|
-
function y(e) {
|
|
151
|
-
let t = e.reason;
|
|
152
|
-
return t === void 0 ? new DOMException("This operation was aborted", "AbortError") : t;
|
|
153
|
-
}
|
|
154
|
-
//#endregion
|
|
155
|
-
//#region ../../node_modules/@gmod/shared-read-cache/esm/SharedReadCache.js
|
|
156
|
-
function b(e) {
|
|
157
|
-
typeof e == "object" && e && "unref" in e && typeof e.unref == "function" && e.unref();
|
|
158
|
-
}
|
|
159
|
-
var x = class {
|
|
160
|
-
entries = /* @__PURE__ */ new Map();
|
|
161
|
-
total = 0;
|
|
162
|
-
settledCount = 0;
|
|
163
|
-
limit;
|
|
164
|
-
budget;
|
|
165
|
-
membership;
|
|
166
|
-
fill;
|
|
167
|
-
sizeOf;
|
|
168
|
-
toCacheKey;
|
|
169
|
-
evictionPolicy;
|
|
170
|
-
pending = 0;
|
|
171
|
-
batch = 0;
|
|
172
|
-
idleTimeoutMs;
|
|
173
|
-
sweepTimer;
|
|
174
|
-
constructor({ fill: e, maxSize: t = Infinity, sizeOf: n = () => 1, cacheKey: r = (e) => String(e), evictionPolicy: i = "lru", idleTimeoutMs: a = 0, budget: o } = {}) {
|
|
175
|
-
this.fill = e, this.evictionPolicy = i, this.limit = t, this.budget = o, this.membership = o?.register(this), this.sizeOf = n, this.toCacheKey = r, this.idleTimeoutMs = a > 0 ? a : void 0;
|
|
176
|
-
}
|
|
177
|
-
get size() {
|
|
178
|
-
return this.entries.size;
|
|
179
|
-
}
|
|
180
|
-
get totalSize() {
|
|
181
|
-
return this.total;
|
|
182
|
-
}
|
|
183
|
-
get maxSize() {
|
|
184
|
-
return this.limit;
|
|
185
|
-
}
|
|
186
|
-
set maxSize(e) {
|
|
187
|
-
this.limit = e, this.evict();
|
|
188
|
-
}
|
|
189
|
-
waiterCount(e) {
|
|
190
|
-
return this.entries.get(this.toCacheKey(e))?.signals.size ?? 0;
|
|
191
|
-
}
|
|
192
|
-
async get(e, t, n) {
|
|
193
|
-
v(t);
|
|
194
|
-
let r = this.toCacheKey(e), i = this.entries.get(r);
|
|
195
|
-
i && (this.isDoomed(i) ? (this.deleteKey(r), i = void 0) : this.touch(r, i)), i ??= this.start(r, e, n), i.settled || this.join(i, t);
|
|
196
|
-
try {
|
|
197
|
-
let e = await this.settleFor(i, t);
|
|
198
|
-
return v(t), e;
|
|
199
|
-
} catch (e) {
|
|
200
|
-
throw v(t), e;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
settleFor(e, t) {
|
|
204
|
-
if (e.settled || t === void 0 || typeof t.addEventListener != "function") return e.promise;
|
|
205
|
-
let n = new AbortController();
|
|
206
|
-
return Promise.race([e.promise, new Promise((e, r) => {
|
|
207
|
-
t.addEventListener("abort", () => {
|
|
208
|
-
r(y(t));
|
|
209
|
-
}, {
|
|
210
|
-
once: !0,
|
|
211
|
-
signal: n.signal
|
|
212
|
-
});
|
|
213
|
-
})]).finally(() => {
|
|
214
|
-
n.abort();
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
getIfCached(e) {
|
|
218
|
-
let t = this.toCacheKey(e), n = this.entries.get(t);
|
|
219
|
-
if (n) {
|
|
220
|
-
if (this.isDoomed(n)) {
|
|
221
|
-
this.deleteKey(t);
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
return this.touch(t, n), n.promise;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
has(e) {
|
|
228
|
-
let t = this.entries.get(this.toCacheKey(e));
|
|
229
|
-
return t !== void 0 && !this.isDoomed(t);
|
|
230
|
-
}
|
|
231
|
-
delete(e) {
|
|
232
|
-
this.deleteKey(this.toCacheKey(e));
|
|
233
|
-
}
|
|
234
|
-
clear() {
|
|
235
|
-
for (let e of this.entries.values()) this.detach(e);
|
|
236
|
-
this.entries.clear(), this.charge(-this.total), this.total = 0, this.settledCount = 0, this.stopSweep();
|
|
237
|
-
}
|
|
238
|
-
touch(e, t) {
|
|
239
|
-
this.entries.delete(e), this.entries.set(e, t), t.batch = this.batch, t.lastTouched = Date.now(), t.seq = this.stamp();
|
|
240
|
-
}
|
|
241
|
-
stamp() {
|
|
242
|
-
return this.budget ? this.budget.nextSeq() : 0;
|
|
243
|
-
}
|
|
244
|
-
isDoomed(e) {
|
|
245
|
-
return !e.settled && e.controller.signal.aborted;
|
|
246
|
-
}
|
|
247
|
-
sweepIdle() {
|
|
248
|
-
let e = this.idleTimeoutMs;
|
|
249
|
-
if (e === void 0) return;
|
|
250
|
-
let t = Date.now() - e, n = 0;
|
|
251
|
-
for (let [e, r] of this.entries) r.settled && (r.lastTouched <= t ? this.deleteKey(e) : n++);
|
|
252
|
-
n === 0 && this.stopSweep();
|
|
253
|
-
}
|
|
254
|
-
startSweep() {
|
|
255
|
-
let e = this.idleTimeoutMs;
|
|
256
|
-
if (e === void 0 || this.sweepTimer !== void 0) return;
|
|
257
|
-
let t = Math.max(1e3, Math.floor(e / 4));
|
|
258
|
-
this.sweepTimer = setInterval(() => {
|
|
259
|
-
this.sweepIdle();
|
|
260
|
-
}, t), b(this.sweepTimer);
|
|
261
|
-
}
|
|
262
|
-
stopSweep() {
|
|
263
|
-
this.sweepTimer !== void 0 && (clearInterval(this.sweepTimer), this.sweepTimer = void 0);
|
|
264
|
-
}
|
|
265
|
-
start(e, t, n) {
|
|
266
|
-
let r = n ?? (this.fill && ((e) => this.fill(t, e)));
|
|
267
|
-
if (!r) throw Error("SharedReadCache needs a fill, either on the cache or on the get() call");
|
|
268
|
-
let i = new AbortController(), a = {
|
|
269
|
-
promise: r(i.signal),
|
|
270
|
-
signals: /* @__PURE__ */ new Set(),
|
|
271
|
-
pinned: !1,
|
|
272
|
-
controller: i,
|
|
273
|
-
dispose: new AbortController(),
|
|
274
|
-
settled: !1,
|
|
275
|
-
counted: !0,
|
|
276
|
-
size: 0,
|
|
277
|
-
batch: this.batch,
|
|
278
|
-
lastTouched: Date.now(),
|
|
279
|
-
seq: this.stamp()
|
|
280
|
-
};
|
|
281
|
-
this.entries.set(e, a), this.pending++;
|
|
282
|
-
let o = () => {
|
|
283
|
-
a.settled = !0, this.detach(a), a.dispose.abort(), a.signals.clear();
|
|
284
|
-
};
|
|
285
|
-
return a.promise.then((t) => {
|
|
286
|
-
if (o(), this.entries.get(e) === a) {
|
|
287
|
-
let n = this.weigh(t);
|
|
288
|
-
n === void 0 ? this.entries.delete(e) : (a.lastTouched = Date.now(), this.settledCount++, a.size = n, this.total += n, this.charge(n), this.startSweep());
|
|
289
|
-
}
|
|
290
|
-
this.maybeEvict();
|
|
291
|
-
}, () => {
|
|
292
|
-
this.entries.get(e) === a && this.deleteKey(e), o(), this.maybeEvict();
|
|
293
|
-
}), a;
|
|
294
|
-
}
|
|
295
|
-
weigh(e) {
|
|
296
|
-
try {
|
|
297
|
-
let t = this.sizeOf(e);
|
|
298
|
-
return Number.isFinite(t) && t >= 0 ? t : void 0;
|
|
299
|
-
} catch {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
join(e, t) {
|
|
304
|
-
t === void 0 ? e.pinned = !0 : t.aborted ? !e.pinned && e.signals.size === 0 && e.controller.abort(t.reason) : typeof t.addEventListener == "function" ? e.signals.has(t) || (e.signals.add(t), t.addEventListener("abort", () => {
|
|
305
|
-
e.signals.delete(t), !e.pinned && e.signals.size === 0 && (e.controller.abort(t.reason), this.detach(e));
|
|
306
|
-
}, {
|
|
307
|
-
once: !0,
|
|
308
|
-
signal: e.dispose.signal
|
|
309
|
-
})) : e.pinned = !0;
|
|
310
|
-
}
|
|
311
|
-
deleteKey(e) {
|
|
312
|
-
let t = this.entries.get(e);
|
|
313
|
-
t && (this.entries.delete(e), this.detach(t), t.settled && this.settledCount--, this.total -= t.size, this.charge(-t.size));
|
|
314
|
-
}
|
|
315
|
-
detach(e) {
|
|
316
|
-
e.counted && (e.counted = !1, this.pending--);
|
|
317
|
-
}
|
|
318
|
-
charge(e) {
|
|
319
|
-
this.budget && this.membership && this.budget.charge(this.membership, e);
|
|
320
|
-
}
|
|
321
|
-
lruSpare() {
|
|
322
|
-
if (!(this.settledCount <= 1)) {
|
|
323
|
-
for (let [e, t] of this.entries) if (t.settled) return {
|
|
324
|
-
cacheKey: e,
|
|
325
|
-
seq: t.seq
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
release(e) {
|
|
330
|
-
this.deleteKey(e);
|
|
331
|
-
}
|
|
332
|
-
maybeEvict() {
|
|
333
|
-
(this.evictionPolicy === "lru" || this.pending === 0) && (this.evict(), this.evictionPolicy === "batch" && this.batch++, this.budget?.evict());
|
|
334
|
-
}
|
|
335
|
-
evict() {
|
|
336
|
-
if (this.limit !== Infinity) {
|
|
337
|
-
if (this.evictionPolicy === "batch") {
|
|
338
|
-
for (let [e, t] of this.entries) {
|
|
339
|
-
if (this.total <= this.limit) break;
|
|
340
|
-
t.batch !== this.batch && t.settled && this.deleteKey(e);
|
|
341
|
-
}
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
if (!(this.total <= this.limit)) for (let [e, t] of this.entries) {
|
|
345
|
-
if (this.total <= this.limit || this.settledCount <= 1) break;
|
|
346
|
-
t.settled && this.deleteKey(e);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}, S = new TextDecoder("utf8");
|
|
351
|
-
function C(e, t, n, r) {
|
|
352
|
-
return e + t * Math.floor(r / n) + r % n;
|
|
353
|
-
}
|
|
354
|
-
async function w(e, t = {}) {
|
|
355
|
-
let n = S.decode(await e.readFile(t)), r = /* @__PURE__ */ new Map();
|
|
356
|
-
for (let e of n.split("\n")) {
|
|
357
|
-
let t = e.trim();
|
|
358
|
-
if (!t) continue;
|
|
359
|
-
let n = t.split(" ");
|
|
360
|
-
if (n.length < 5) throw Error(`Malformed FAI line (expected 5 tab-separated columns, got ${String(n.length)}): ${t}`);
|
|
361
|
-
let [i, a, o, s, c] = n;
|
|
362
|
-
if (i.startsWith(">")) throw Error("found > in sequence name, might have supplied FASTA file for the FASTA index");
|
|
363
|
-
let l = +a, u = +s;
|
|
364
|
-
if (l > 0 && u === 0) throw Error(`Invalid FAI index for "${i}": LINEBASES is 0, FASTA likely missing trailing newline; regenerate the .fai index`);
|
|
365
|
-
r.set(i, {
|
|
366
|
-
length: l,
|
|
367
|
-
offset: +o,
|
|
368
|
-
lineLength: u,
|
|
369
|
-
lineBytes: +c
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
return r;
|
|
373
|
-
}
|
|
374
|
-
async function T(e, t, n = 0, r, i) {
|
|
375
|
-
if (n < 0) throw TypeError("regionStart cannot be less than 0");
|
|
376
|
-
let a = Math.min(r ?? t.length, t.length);
|
|
377
|
-
if (n >= a) return "";
|
|
378
|
-
let o = C(t.offset, t.lineBytes, t.lineLength, n), s = C(t.offset, t.lineBytes, t.lineLength, a) - o, c = S.decode(await e.read(s, o, i)).replace(/\s+/g, "");
|
|
379
|
-
if (/[^\x20-\x7e]/.test(c.slice(0, 1e3))) throw Error("Non-ASCII bytes in sequence; file may be gzip — use BgzipIndexedFasta or decompress");
|
|
380
|
-
return c;
|
|
381
|
-
}
|
|
382
|
-
var E = class {
|
|
383
|
-
fasta;
|
|
384
|
-
fai;
|
|
385
|
-
indexCache = new x({});
|
|
386
|
-
constructor({ fasta: e, fai: t, path: r, faiPath: i }) {
|
|
387
|
-
if (e) this.fasta = e;
|
|
388
|
-
else if (r) this.fasta = new n(r);
|
|
389
|
-
else throw Error("Need to pass filehandle for fasta or path to localfile");
|
|
390
|
-
if (t) this.fai = t;
|
|
391
|
-
else if (i) this.fai = new n(i);
|
|
392
|
-
else if (r) this.fai = new n(`${r}.fai`);
|
|
393
|
-
else throw Error("Need to pass filehandle for fai or path to localfile");
|
|
394
|
-
}
|
|
395
|
-
getIndexes(e) {
|
|
396
|
-
return this.indexCache.get("fai", e?.signal, (t) => w(this.fai, {
|
|
397
|
-
...e,
|
|
398
|
-
signal: t
|
|
399
|
-
}));
|
|
400
|
-
}
|
|
401
|
-
async getSequenceNames(e) {
|
|
402
|
-
return [...(await this.getIndexes(e)).keys()];
|
|
403
|
-
}
|
|
404
|
-
async getSequenceSizes(e) {
|
|
405
|
-
let t = {};
|
|
406
|
-
for (let [n, r] of await this.getIndexes(e)) t[n] = r.length;
|
|
407
|
-
return t;
|
|
408
|
-
}
|
|
409
|
-
async getSequenceSize(e, t) {
|
|
410
|
-
return (await this.getIndexes(t)).get(e)?.length;
|
|
411
|
-
}
|
|
412
|
-
async hasReferenceSequence(e, t) {
|
|
413
|
-
return (await this.getIndexes(t)).has(e);
|
|
414
|
-
}
|
|
415
|
-
async getResiduesByName(e, t, n, r) {
|
|
416
|
-
let i = (await this.getIndexes(r)).get(e);
|
|
417
|
-
if (i !== void 0) return T(this.fasta, i, t, n, r);
|
|
418
|
-
}
|
|
419
|
-
async getSequence(e, t, n, r) {
|
|
420
|
-
return this.getResiduesByName(e, t, n, r);
|
|
421
|
-
}
|
|
422
|
-
}, D = class extends E {
|
|
423
|
-
constructor({ fasta: e, path: t, fai: r, faiPath: i, gzi: a, gziPath: o }) {
|
|
424
|
-
let s;
|
|
425
|
-
if (e && a) s = new m({
|
|
426
|
-
filehandle: e,
|
|
427
|
-
gziFilehandle: a
|
|
428
|
-
});
|
|
429
|
-
else if (t && o) s = new m({
|
|
430
|
-
filehandle: new n(t),
|
|
431
|
-
gziFilehandle: new n(o)
|
|
432
|
-
});
|
|
433
|
-
else throw Error("BgzipIndexedFasta requires either {fasta, gzi} or {path, gziPath}");
|
|
434
|
-
super({
|
|
435
|
-
fasta: s,
|
|
436
|
-
fai: r,
|
|
437
|
-
faiPath: i,
|
|
438
|
-
path: t
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
};
|
|
442
|
-
//#endregion
|
|
443
|
-
export { D as BgzipIndexedFasta, _ as FetchableSmallFasta, E as IndexedFasta, g as parseSmallFasta };
|