@genome-spy/core 0.52.0 → 0.53.1
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/bundle/{index-C8lYPtq_.js → index-B5cesONJ.js} +21 -21
- package/dist/bundle/index-BJLu48Hz.js +274 -0
- package/dist/bundle/{index-Sk-Wtwdn.js → index-BywMLhhd.js} +963 -989
- package/dist/bundle/{index-BwFvhduA.js → index-CSayoXbw.js} +7 -9
- package/dist/bundle/{index-CkI3Kd2P.js → index-DAJ8JQLE.js} +6 -5
- package/dist/bundle/{index-BtRKzKhM.js → index-_tI-fMQF.js} +414 -415
- package/dist/bundle/{index-CmBp-spD.js → index-e0oKgZbZ.js} +36 -36
- package/dist/bundle/{index-Z7JiNsFI.js → index-oqw_s02W.js} +10 -11
- package/dist/bundle/{index-mihmTLo-.js → index-uO0O4Uv-.js} +22 -22
- package/dist/bundle/index.es.js +3646 -3692
- package/dist/bundle/index.js +102 -103
- package/dist/bundle/{long-CYrAUkxh.js → long-D4tVjLLz.js} +5 -5
- package/dist/bundle/remoteFile-BkTxwFub.js +90 -0
- package/dist/schema.json +1 -1
- package/dist/src/data/sources/dataUtils.d.ts +5 -0
- package/dist/src/data/sources/dataUtils.d.ts.map +1 -1
- package/dist/src/data/sources/dataUtils.js +9 -0
- package/dist/src/data/sources/lazy/axisTickSource.js +1 -1
- package/dist/src/data/sources/lazy/bamSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +1 -1
- package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts +4 -6
- package/dist/src/data/sources/lazy/singleAxisLazySource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/singleAxisLazySource.js +4 -18
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +12 -7
- package/dist/src/data/transforms/clone.d.ts +1 -2
- package/dist/src/data/transforms/clone.d.ts.map +1 -1
- package/dist/src/data/transforms/clone.js +19 -4
- package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -1
- package/dist/src/data/transforms/filterScoredLabels.js +1 -4
- package/dist/src/data/transforms/transformFactory.d.ts.map +1 -1
- package/dist/src/encoder/encoder.d.ts +1 -1
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/fonts/bmFontMetrics.d.ts.map +1 -1
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/gl/dataToVertices.d.ts.map +1 -1
- package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
- package/dist/src/img/genomespy-favicon.svg +1 -34
- package/dist/src/spec/axis.d.ts +0 -2
- package/dist/src/spec/scale.d.ts +1 -1
- package/dist/src/utils/cloner.d.ts +8 -2
- package/dist/src/utils/cloner.d.ts.map +1 -1
- package/dist/src/utils/cloner.js +19 -2
- package/dist/src/utils/cloner.test.js +16 -5
- package/dist/src/utils/expression.d.ts.map +1 -1
- package/dist/src/utils/ui/tooltip.d.ts +1 -1
- package/dist/src/utils/ui/tooltip.d.ts.map +1 -1
- package/dist/src/view/paramMediator.d.ts +1 -1
- package/dist/src/view/paramMediator.d.ts.map +1 -1
- package/dist/src/view/scaleResolution.d.ts +9 -0
- package/dist/src/view/scaleResolution.d.ts.map +1 -1
- package/dist/src/view/scaleResolution.js +30 -0
- package/dist/src/view/zoom.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/bundle/index-Dixm7K89.js +0 -279
- package/dist/bundle/remoteFile-1_eCK3VV.js +0 -96
package/dist/src/utils/cloner.js
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @param {T} template The template object that
|
|
10
10
|
* @returns {(function(T):T) & { properties: string[] }}
|
|
11
|
-
* @template T
|
|
11
|
+
* @template {object} [T=object]
|
|
12
12
|
*/
|
|
13
13
|
export default function createCloner(template) {
|
|
14
14
|
// TODO: Check that only properties, not methods get cloned
|
|
15
15
|
const properties = /** @type {string[]} */ (
|
|
16
|
-
|
|
16
|
+
getAllProperties(template).filter((k) => typeof k == "string")
|
|
17
17
|
);
|
|
18
18
|
|
|
19
19
|
const cloner = /** @type {(function(T):T) & { properties: string[] }} */ (
|
|
@@ -32,3 +32,20 @@ export default function createCloner(template) {
|
|
|
32
32
|
|
|
33
33
|
return cloner;
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Needed for proxied Apache Arrow tables.
|
|
38
|
+
*
|
|
39
|
+
* @param {object} obj
|
|
40
|
+
*/
|
|
41
|
+
export function getAllProperties(obj) {
|
|
42
|
+
/** @type {string[]} */
|
|
43
|
+
let props = [];
|
|
44
|
+
do {
|
|
45
|
+
props = props.concat(Object.keys(obj));
|
|
46
|
+
obj = Object.getPrototypeOf(obj);
|
|
47
|
+
} while (obj && obj !== Object.prototype); // Traverse until the end of the prototype chain
|
|
48
|
+
|
|
49
|
+
const uniqueProps = Array.from(new Set(props));
|
|
50
|
+
return uniqueProps;
|
|
51
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { expect, test } from "vitest";
|
|
2
|
-
import createCloner from "./cloner.js";
|
|
2
|
+
import createCloner, { getAllProperties } from "./cloner.js";
|
|
3
3
|
|
|
4
4
|
const template = {
|
|
5
|
+
1: "iddqd",
|
|
5
6
|
a: 1,
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
c: "xyzzy",
|
|
8
|
+
b: "idclip",
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
test("Cloner clones object properly", () => {
|
|
@@ -14,11 +15,21 @@ test("Cloner clones object properly", () => {
|
|
|
14
15
|
expect(makeClone(template)).not.toBe(template);
|
|
15
16
|
|
|
16
17
|
const another = {
|
|
18
|
+
1: "hello",
|
|
17
19
|
a: 2,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
c: "idkfa",
|
|
21
|
+
b: "idclip",
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
expect(makeClone(another)).toEqual(another);
|
|
23
25
|
expect(makeClone(another)).not.toBe(another);
|
|
24
26
|
});
|
|
27
|
+
|
|
28
|
+
test("getAllProperties", () => {
|
|
29
|
+
expect(getAllProperties(template)).toEqual(["1", "a", "c", "b"]);
|
|
30
|
+
|
|
31
|
+
const obj = Object.create(template);
|
|
32
|
+
obj.d = 42;
|
|
33
|
+
|
|
34
|
+
expect(getAllProperties(obj)).toEqual(["d", "1", "a", "c", "b"]);
|
|
35
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/utils/expression.js"],"names":[],"mappings":"AA2DA;;;;;;;;;;GAUG;AACH,6CAHW,MAAM,sBACJ,kBAAkB,CAgC9B;;YAvCU,MAAM,EAAE;aACR,MAAM,EAAE;UACR,MAAM;;
|
|
1
|
+
{"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/utils/expression.js"],"names":[],"mappings":"AA2DA;;;;;;;;;;GAUG;AACH,6CAHW,MAAM,sBACJ,kBAAkB,CAgC9B;;YAvCU,MAAM,EAAE;aACR,MAAM,EAAE;UACR,MAAM;;iCAEH,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,qBAAqB,EAAE,KAAK,KAAK,GAAG,CAAC,GAAG,eAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../../src/utils/ui/tooltip.js"],"names":[],"mappings":"AAIA,gEAAiE;AAEjE;IACI;;OAEG;IACH,uBAFW,WAAW,EAsBrB;IAnBG,uBAA0B;IAE1B,wBAA4C;IAE5C,kBAAoB;IAGpB,kBAAkB;IAClB,uBADW,GAAG,CACwB;IAEtC,wBAA0B;IAE1B,sBAAsB;IACtB,+BAA+B;IAC/B,aADW,CAAC,MAAM,EAAE,MAAM,CAAC,CACC;IAE5B,sBAAsB;IAK1B;;OAEG;IACH,
|
|
1
|
+
{"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../../../src/utils/ui/tooltip.js"],"names":[],"mappings":"AAIA,gEAAiE;AAEjE;IACI;;OAEG;IACH,uBAFW,WAAW,EAsBrB;IAnBG,uBAA0B;IAE1B,wBAA4C;IAE5C,kBAAoB;IAGpB,kBAAkB;IAClB,uBADW,GAAG,CACwB;IAEtC,wBAA0B;IAE1B,sBAAsB;IACtB,+BAA+B;IAC/B,aADW,CAAC,MAAM,EAAE,MAAM,CAAC,CACC;IAE5B,sBAAsB;IAK1B;;OAEG;IACH,8BAKC;IAED,uBAEC;IAED,uBAEC;IAED;;OAEG;IACH,0BAFW,OAAO,QAOjB;IAED,wBAEC;IAED;;OAEG;IACH,4BAFW,UAAU,QAkCpB;IA/BG,8BAA0D;IAiC9D,wBAiBC;IAED;;OAEG;IACH,oBAFW,MAAM,GAAG,OAAO,KAAK,EAAE,cAAc,GAAG,WAAW,QAiB7D;IAED,cAGC;IAED;;;;;;;OAOG;IACH,sDAHuB,QAAQ,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAmBlF;IAED,sBAEC;CACJ"}
|
|
@@ -140,7 +140,7 @@ export default class ParamMediator {
|
|
|
140
140
|
* TODO: The proposed JavaScript signals may provide a better way to implement this.
|
|
141
141
|
* https://github.com/proposal-signals/proposal-signals
|
|
142
142
|
*/
|
|
143
|
-
export type ExprRefFunction =
|
|
143
|
+
export type ExprRefFunction = import("../utils/expression.js").ExpressionFunction & {
|
|
144
144
|
addListener: (listener: () => void) => void;
|
|
145
145
|
invalidate: () => void;
|
|
146
146
|
identifier: () => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paramMediator.d.ts","sourceRoot":"","sources":["../../../src/view/paramMediator.js"],"names":[],"mappings":"AAoUA;;;GAGG;AACH,6BAHW,GAAG,+CAKb;AAED;;;;;;;GAOG;AACH,oFASC;AAED;;;GAGG;AACH,gJAEC;AAED;;;GAGG;AACH,gMAEC;AAED;;;;;;;;;;GAUG;AACH,mFANW,aAAa,+CAEW,IAAI,KAwCtC;AAED;;;;;;GAMG;AACH,4CAHW,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;GAOG;AACH,2CAHW,GAAG,GACD,eAAe,CAW3B;AA9bD;;;;;;;;GAQG;AACH;IA2BI;;;;;OAKG;IACH,2BALW,MAAM,aAAa,EAU7B;IA7BD;;;OAGG;IACH,0BAHU,IAAI,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,CAAC,CAGvB;IA2Bf;;;OAGG;IACH,wEAzCqB,GAAG,KAAK,IAAI,CAmGhC;IAED;;;;;;;OAOG;IACH,6BANW,MAAM,6BAEN,OAAO,iBACS,IAAI,CAgC9B;IAED;;;OAGG;IACH,qBAFW,MAAM,WAlIc,GAAG,KAAK,IAAI,CA0I1C;IAED;;;OAGG;IACH,oBAFW,MAAM,OAIhB;IAED;;;OAGG;IACH,qBAFW,MAAM,OAKhB;IAED;;OAEG;IACH,kFAIC;IAED;;;;OAIG;IACH,gCAHW,MAAM,GACJ,aAAa,CAQzB;IAID;;;;OAIG;IACH,uBAFW,MAAM,mBA4EhB;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAKhB;IAED;;;;;OAKG;IACH,sBAFa,OAAO,CAiBnB;;CACJ
|
|
1
|
+
{"version":3,"file":"paramMediator.d.ts","sourceRoot":"","sources":["../../../src/view/paramMediator.js"],"names":[],"mappings":"AAoUA;;;GAGG;AACH,6BAHW,GAAG,+CAKb;AAED;;;;;;;GAOG;AACH,oFASC;AAED;;;GAGG;AACH,gJAEC;AAED;;;GAGG;AACH,gMAEC;AAED;;;;;;;;;;GAUG;AACH,mFANW,aAAa,+CAEW,IAAI,KAwCtC;AAED;;;;;;GAMG;AACH,4CAHW,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;GAOG;AACH,2CAHW,GAAG,GACD,eAAe,CAW3B;AA9bD;;;;;;;;GAQG;AACH;IA2BI;;;;;OAKG;IACH,2BALW,MAAM,aAAa,EAU7B;IA7BD;;;OAGG;IACH,0BAHU,IAAI,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,CAAC,CAGvB;IA2Bf;;;OAGG;IACH,wEAzCqB,GAAG,KAAK,IAAI,CAmGhC;IAED;;;;;;;OAOG;IACH,6BANW,MAAM,6BAEN,OAAO,iBACS,IAAI,CAgC9B;IAED;;;OAGG;IACH,qBAFW,MAAM,WAlIc,GAAG,KAAK,IAAI,CA0I1C;IAED;;;OAGG;IACH,oBAFW,MAAM,OAIhB;IAED;;;OAGG;IACH,qBAFW,MAAM,OAKhB;IAED;;OAEG;IACH,kFAIC;IAED;;;;OAIG;IACH,gCAHW,MAAM,GACJ,aAAa,CAQzB;IAID;;;;OAIG;IACH,uBAFW,MAAM,mBA4EhB;IAED;;;;OAIG;IACH,qBAFW,MAAM,OAKhB;IAED;;;;;OAKG;IACH,sBAFa,OAAO,CAiBnB;;CACJ;;;;;;;;8BAvTY,OAAO,wBAAwB,EAAE,kBAAkB,GAAG;IAAE,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,MAAM,CAAA;CAAC"}
|
|
@@ -126,6 +126,15 @@ export default class ScaleResolution implements ScaleResolutionApi {
|
|
|
126
126
|
* be generalized to other quantitative channels such as color, opacity, size, etc.
|
|
127
127
|
*/
|
|
128
128
|
getZoomLevel(): number;
|
|
129
|
+
/**
|
|
130
|
+
* Returns the length of the axis in pixels. Chooses the smallest of the views.
|
|
131
|
+
* They should all be the same, but some exotic configuration might break that assumption.
|
|
132
|
+
*
|
|
133
|
+
* This method is needed because positional channels have unit ranges and the
|
|
134
|
+
* length of the axis is not directly available from the scale. Ideally, ranges would
|
|
135
|
+
* be configured as pixels, but that is yet to be materialized.
|
|
136
|
+
*/
|
|
137
|
+
getAxisLength(): number;
|
|
129
138
|
/**
|
|
130
139
|
*
|
|
131
140
|
* @returns {import("../genome/genome.js").default}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/view/scaleResolution.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scaleResolution.d.ts","sourceRoot":"","sources":["../../../src/view/scaleResolution.js"],"names":[],"mappings":"AA88BA;;;;;;;;;;GAUG;AACH,6CAFW,OAAO,WAAW,EAAE,OAAO,GAAG,OAAO,WAAW,EAAE,OAAO,EAAE,QA4BrE;AAt8BD,0CAA2C;AAC3C,gCAAiC;AACjC,gCAAiC;AACjC,4BAA6B;AAC7B,4BAA6B;AAE7B;;;;;;;;GAQG;AACH;;;;;;;GAOG;AACH;IAyCI;;OAEG;IACH,2DASC;IARG,8CAAsB;IACtB,yDAAyD;IACzD,SADW,qBAAqB,EAAE,CACjB;IACjB,0FAA0F;IAC1F,MADW,OAAO,oBAAoB,EAAE,IAAI,CAC5B;IAEhB,iEAAiE;IACjE,MADW,MAAM,CACI;IAWzB;;;;;;;OAOG;IACH,4KAEC;IAED;;;OAGG;IACH,+KAEC;IAcD;;;;;OAKG;IACH,qBAFW,qBAAqB,QA4B/B;IA8MD;;;;OAIG;IACH,+DAOC;IAED;;OAEG;IACH,oBAyCC;IAED;;OAEG;IACH;eA5XkC,OAAO,kBAAkB,EAAE,KAAK;MAwajE;IAED,mBAEC;IAED;;OAEG;IACH,oBAFa,mFAA6B,CAOzC;IAED;;;;OAIG;IACH,oBAKC;IAED;;OAEG;IACH,sBAGC;IAUD;;;;;;;OAOG;IACH,kBALW,MAAM,eACN,MAAM,OACN,MAAM,GACJ,OAAO,CAwEnB;IAED;;;;;;OAMG;IACH,eAJW,mFAA6B,aAC7B,OAAO,GAAG,MAAM,iBA0D1B;IAED;;;;OAIG;IACH,qBAcC;IAED;;;;;OAKG;IACH,uBAOC;IAED;;;;;;;OAOG;IACH,wBAoBC;IA8DD;;;OAGG;IACH,aAFa,OAAO,qBAAqB,EAAE,OAAO,CAajD;IAID;;;;;OAKG;IACH,uBAFW,MAAM,yDAUhB;IAED;;OAEG;IACH,iBAFW,MAAM,yDAKhB;IAED;;;OAGG;IACH,6EAFa,MAAM,CAQlB;IAED;;;OAGG;IACH,mHAFa,MAAM,EAAE,CAOpB;;CACJ;;;;;UAh0BS,OAAO,eAAe,EAAE,OAAO;aAC/B,CAAC;gBACD,OAAO,oBAAoB,EAAE,mBAAmB;qFACd,OAAO,oBAAoB,EAAE,IAAI"}
|
|
@@ -730,6 +730,36 @@ export default class ScaleResolution {
|
|
|
730
730
|
return 1.0;
|
|
731
731
|
}
|
|
732
732
|
|
|
733
|
+
/**
|
|
734
|
+
* Returns the length of the axis in pixels. Chooses the smallest of the views.
|
|
735
|
+
* They should all be the same, but some exotic configuration might break that assumption.
|
|
736
|
+
*
|
|
737
|
+
* This method is needed because positional channels have unit ranges and the
|
|
738
|
+
* length of the axis is not directly available from the scale. Ideally, ranges would
|
|
739
|
+
* be configured as pixels, but that is yet to be materialized.
|
|
740
|
+
*/
|
|
741
|
+
getAxisLength() {
|
|
742
|
+
if (this.channel !== "x" && this.channel !== "y") {
|
|
743
|
+
throw new Error(
|
|
744
|
+
"Axis length is only defined for x and y channels!"
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// Here's a problem: if the view has been hidden, it may have stale coords.
|
|
749
|
+
// TODO: They should be cleared when the layout is invalidated.
|
|
750
|
+
// Alternatively, scale ranges could be set in pixels.
|
|
751
|
+
const lengths = this.members
|
|
752
|
+
.map(
|
|
753
|
+
(m) =>
|
|
754
|
+
m.view.coords?.[this.channel === "x" ? "width" : "height"]
|
|
755
|
+
)
|
|
756
|
+
.filter((len) => len > 0);
|
|
757
|
+
|
|
758
|
+
return lengths.length
|
|
759
|
+
? lengths.reduce((a, b) => Math.min(a, b), 10000)
|
|
760
|
+
: 0;
|
|
761
|
+
}
|
|
762
|
+
|
|
733
763
|
#getZoomExtent() {
|
|
734
764
|
const props = this.scale.props;
|
|
735
765
|
const zoom = props.zoom;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zoom.d.ts","sourceRoot":"","sources":["../../../src/view/zoom.js"],"names":[],"mappings":"AAkBA,0CAGC;AAgBD;;;;;;GAMG;AACH,yCANW,OAAO,8BAA8B,EAAE,OAAO,UAC9C,OAAO,uBAAuB,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"zoom.d.ts","sourceRoot":"","sources":["../../../src/view/zoom.js"],"names":[],"mappings":"AAkBA,0CAGC;AAgBD;;;;;;GAMG;AACH,yCANW,OAAO,8BAA8B,EAAE,OAAO,UAC9C,OAAO,uBAAuB,EAAE,OAAO,cACvC,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,UAC9B,OAAO,yBAAyB,EAAE,KAAK,aACvC,OAAO,sBAAsB,EAAE,OAAO,QAkJhD;;OA1LS,MAAM;OACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM"}
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"contributors": [],
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.53.1",
|
|
11
11
|
"jsdelivr": "dist/bundle/index.js",
|
|
12
12
|
"unpkg": "dist/bundle/index.js",
|
|
13
13
|
"browser": "dist/bundle/index.js",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/long": "^4.0.1"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "ad3f36346e1714b5bb9db0d6ff4a068ecfb945a3"
|
|
71
71
|
}
|
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
import { L as g } from "./__vite-browser-external-C--ziKoh.js";
|
|
2
|
-
import { b as w } from "./index-C8lYPtq_.js";
|
|
3
|
-
import { L as x, u as E } from "./long-CYrAUkxh.js";
|
|
4
|
-
import "./_commonjsHelpers-BIiJCwQW.js";
|
|
5
|
-
const m = 1;
|
|
6
|
-
class _ {
|
|
7
|
-
constructor({ filehandle: e, path: t }) {
|
|
8
|
-
if (e)
|
|
9
|
-
this.filehandle = e;
|
|
10
|
-
else if (t)
|
|
11
|
-
this.filehandle = new g(t);
|
|
12
|
-
else
|
|
13
|
-
throw new TypeError("either filehandle or path must be defined");
|
|
14
|
-
}
|
|
15
|
-
_readLongWithOverflow(e, t = 0, i = !0) {
|
|
16
|
-
const n = x.fromBytesLE(e.slice(t, t + 8), i);
|
|
17
|
-
if (n.greaterThan(Number.MAX_SAFE_INTEGER) || n.lessThan(Number.MIN_SAFE_INTEGER))
|
|
18
|
-
throw new TypeError("integer overflow");
|
|
19
|
-
return n.toNumber();
|
|
20
|
-
}
|
|
21
|
-
_getIndex() {
|
|
22
|
-
return this.index || (this.index = this._readIndex()), this.index;
|
|
23
|
-
}
|
|
24
|
-
async _readIndex() {
|
|
25
|
-
let e = w.Buffer.allocUnsafe(8);
|
|
26
|
-
await this.filehandle.read(e, 0, 8, 0);
|
|
27
|
-
const t = this._readLongWithOverflow(e, 0, !0);
|
|
28
|
-
if (!t)
|
|
29
|
-
return [[0, 0]];
|
|
30
|
-
const i = new Array(t + 1);
|
|
31
|
-
i[0] = [0, 0];
|
|
32
|
-
const n = 8 * 2 * t;
|
|
33
|
-
if (n > Number.MAX_SAFE_INTEGER)
|
|
34
|
-
throw new TypeError("integer overflow");
|
|
35
|
-
e = w.Buffer.allocUnsafe(n), await this.filehandle.read(e, 0, n, 8);
|
|
36
|
-
for (let s = 0; s < t; s += 1) {
|
|
37
|
-
const r = this._readLongWithOverflow(e, s * 16), a = this._readLongWithOverflow(e, s * 16 + 8);
|
|
38
|
-
i[s + 1] = [r, a];
|
|
39
|
-
}
|
|
40
|
-
return i;
|
|
41
|
-
}
|
|
42
|
-
async getLastBlock() {
|
|
43
|
-
const e = await this._getIndex();
|
|
44
|
-
if (e.length)
|
|
45
|
-
return e[e.length - 1];
|
|
46
|
-
}
|
|
47
|
-
async getRelevantBlocksForRead(e, t) {
|
|
48
|
-
const i = t + e;
|
|
49
|
-
if (e === 0)
|
|
50
|
-
return [];
|
|
51
|
-
const n = await this._getIndex(), s = [], r = (h, u) => {
|
|
52
|
-
const p = h[m], b = u ? u[m] : 1 / 0;
|
|
53
|
-
return p <= t && b > t ? 0 : p < t ? -1 : 1;
|
|
54
|
-
};
|
|
55
|
-
let a = 0, f = n.length - 1, o = Math.floor(n.length / 2), d = r(n[o], n[o + 1]);
|
|
56
|
-
for (; d !== 0; )
|
|
57
|
-
d > 0 ? f = o - 1 : d < 0 && (a = o + 1), o = Math.ceil((f - a) / 2) + a, d = r(n[o], n[o + 1]);
|
|
58
|
-
s.push(n[o]);
|
|
59
|
-
let c = o + 1;
|
|
60
|
-
for (; c < n.length && (s.push(n[c]), !(n[c][m] >= i)); c += 1)
|
|
61
|
-
;
|
|
62
|
-
return s[s.length - 1][m] < i && s.push([]), s;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
class y {
|
|
66
|
-
constructor({ filehandle: e, path: t, gziFilehandle: i, gziPath: n }) {
|
|
67
|
-
if (e)
|
|
68
|
-
this.filehandle = e;
|
|
69
|
-
else if (t)
|
|
70
|
-
this.filehandle = new g(t);
|
|
71
|
-
else
|
|
72
|
-
throw new TypeError("either filehandle or path must be defined");
|
|
73
|
-
if (!i && !n && !t)
|
|
74
|
-
throw new TypeError("either gziFilehandle or gziPath must be defined");
|
|
75
|
-
this.gzi = new _({
|
|
76
|
-
filehandle: i,
|
|
77
|
-
path: !i && !n && t ? n : `${t}.gzi`
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
async stat() {
|
|
81
|
-
const e = await this.filehandle.stat();
|
|
82
|
-
return Object.assign(e, {
|
|
83
|
-
size: await this.getUncompressedFileSize(),
|
|
84
|
-
blocks: void 0,
|
|
85
|
-
blksize: void 0
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
async getUncompressedFileSize() {
|
|
89
|
-
const [, e] = await this.gzi.getLastBlock(), { size: t } = await this.filehandle.stat(), i = w.Buffer.allocUnsafe(4), { bytesRead: n } = await this.filehandle.read(i, 0, 4, t - 28 - 4);
|
|
90
|
-
if (n !== 4)
|
|
91
|
-
throw new Error("read error");
|
|
92
|
-
const s = i.readUInt32LE(0);
|
|
93
|
-
return e + s;
|
|
94
|
-
}
|
|
95
|
-
async _readAndUncompressBlock(e, [t], [i]) {
|
|
96
|
-
let n = i;
|
|
97
|
-
n || (n = (await this.filehandle.stat()).size);
|
|
98
|
-
const s = n - t;
|
|
99
|
-
return await this.filehandle.read(e, 0, s, t), await E(e.slice(0, s));
|
|
100
|
-
}
|
|
101
|
-
async read(e, t, i, n) {
|
|
102
|
-
const s = await this.gzi.getRelevantBlocksForRead(i, n), r = w.Buffer.allocUnsafe(32768 * 2);
|
|
103
|
-
let a = t, f = 0;
|
|
104
|
-
for (let o = 0; o < s.length - 1; o += 1) {
|
|
105
|
-
const d = await this._readAndUncompressBlock(r, s[o], s[o + 1]), [, c] = s[o], h = c >= n ? 0 : n - c, u = Math.min(n + i, c + d.length) - c;
|
|
106
|
-
h >= 0 && h < d.length && (d.copy(e, a, h, u), a += u - h, f += u - h);
|
|
107
|
-
}
|
|
108
|
-
return { bytesRead: f, buffer: e };
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
function S(l, e) {
|
|
112
|
-
return l.offset + l.lineBytes * Math.floor(e / l.lineLength) + e % l.lineLength;
|
|
113
|
-
}
|
|
114
|
-
async function I(l, e) {
|
|
115
|
-
const t = await l.readFile(e);
|
|
116
|
-
if (!(t && t.length))
|
|
117
|
-
throw new Error("No data read from FASTA index (FAI) file");
|
|
118
|
-
let i = 0, n;
|
|
119
|
-
const s = t.toString("utf8").split(/\r?\n/).filter((r) => /\S/.test(r)).map((r) => r.split(" ")).filter((r) => r[0] !== "").map((r) => ((!n || n.name !== r[0]) && (n = { name: r[0], id: i }, i += 1), {
|
|
120
|
-
id: n.id,
|
|
121
|
-
name: r[0],
|
|
122
|
-
length: +r[1],
|
|
123
|
-
start: 0,
|
|
124
|
-
end: +r[1],
|
|
125
|
-
offset: +r[2],
|
|
126
|
-
lineLength: +r[3],
|
|
127
|
-
lineBytes: +r[4]
|
|
128
|
-
}));
|
|
129
|
-
return {
|
|
130
|
-
name: Object.fromEntries(s.map((r) => [r.name, r])),
|
|
131
|
-
id: Object.fromEntries(s.map((r) => [r.id, r]))
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
class B {
|
|
135
|
-
constructor({ fasta: e, fai: t, path: i, faiPath: n, chunkSizeLimit: s = 1e6 }) {
|
|
136
|
-
if (e)
|
|
137
|
-
this.fasta = e;
|
|
138
|
-
else if (i)
|
|
139
|
-
this.fasta = new g(i);
|
|
140
|
-
else
|
|
141
|
-
throw new Error("Need to pass filehandle for fasta or path to localfile");
|
|
142
|
-
if (t)
|
|
143
|
-
this.fai = t;
|
|
144
|
-
else if (n)
|
|
145
|
-
this.fai = new g(n);
|
|
146
|
-
else if (i)
|
|
147
|
-
this.fai = new g(`${i}.fai`);
|
|
148
|
-
else
|
|
149
|
-
throw new Error("Need to pass filehandle for or path to localfile");
|
|
150
|
-
this.chunkSizeLimit = s;
|
|
151
|
-
}
|
|
152
|
-
async _getIndexes(e) {
|
|
153
|
-
return this.indexes || (this.indexes = I(this.fai, e)), this.indexes;
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* @returns {array[string]} array of string sequence
|
|
157
|
-
* names that are present in the index, in which the
|
|
158
|
-
* array index indicates the sequence ID, and the value
|
|
159
|
-
* is the sequence name
|
|
160
|
-
*/
|
|
161
|
-
async getSequenceNames(e) {
|
|
162
|
-
return Object.keys((await this._getIndexes(e)).name);
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* @returns {array[string]} array of string sequence
|
|
166
|
-
* names that are present in the index, in which the
|
|
167
|
-
* array index indicates the sequence ID, and the value
|
|
168
|
-
* is the sequence name
|
|
169
|
-
*/
|
|
170
|
-
async getSequenceSizes(e) {
|
|
171
|
-
const t = {}, i = await this._getIndexes(e), n = Object.values(i.id);
|
|
172
|
-
for (let s = 0; s < n.length; s += 1)
|
|
173
|
-
t[n[s].name] = n[s].length;
|
|
174
|
-
return t;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* @returns {array[string]} array of string sequence
|
|
178
|
-
* names that are present in the index, in which the
|
|
179
|
-
* array index indicates the sequence ID, and the value
|
|
180
|
-
* is the sequence name
|
|
181
|
-
*/
|
|
182
|
-
async getSequenceSize(e, t) {
|
|
183
|
-
var i;
|
|
184
|
-
return (i = (await this._getIndexes(t)).name[e]) === null || i === void 0 ? void 0 : i.length;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
*
|
|
188
|
-
* @param {string} name
|
|
189
|
-
* @returns {Promise[boolean]} true if the file contains the given reference sequence name
|
|
190
|
-
*/
|
|
191
|
-
async hasReferenceSequence(e, t) {
|
|
192
|
-
return !!(await this._getIndexes(t)).name[e];
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
*
|
|
196
|
-
* @param {number} seqId
|
|
197
|
-
* @param {number} min
|
|
198
|
-
* @param {number} max
|
|
199
|
-
*/
|
|
200
|
-
async getResiduesById(e, t, i, n) {
|
|
201
|
-
const s = (await this._getIndexes(n)).id[e];
|
|
202
|
-
if (s)
|
|
203
|
-
return this._fetchFromIndexEntry(s, t, i, n);
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* @param {string} seqName
|
|
207
|
-
* @param {number} min
|
|
208
|
-
* @param {number} max
|
|
209
|
-
*/
|
|
210
|
-
async getResiduesByName(e, t, i, n) {
|
|
211
|
-
const s = (await this._getIndexes(n)).name[e];
|
|
212
|
-
if (s)
|
|
213
|
-
return this._fetchFromIndexEntry(s, t, i, n);
|
|
214
|
-
}
|
|
215
|
-
//alias for getResiduesByName
|
|
216
|
-
async getSequence(e, t, i, n) {
|
|
217
|
-
return this.getResiduesByName(e, t, i, n);
|
|
218
|
-
}
|
|
219
|
-
async _fetchFromIndexEntry(e, t = 0, i, n) {
|
|
220
|
-
let s = i;
|
|
221
|
-
if (t < 0)
|
|
222
|
-
throw new TypeError("regionStart cannot be less than 0");
|
|
223
|
-
if ((s === void 0 || s > e.length) && (s = e.length), t >= s)
|
|
224
|
-
return "";
|
|
225
|
-
const r = S(e, t), a = S(e, s) - r;
|
|
226
|
-
if (a > this.chunkSizeLimit)
|
|
227
|
-
throw new Error(`data size of ${a.toLocaleString()} bytes exceeded chunk size limit of ${this.chunkSizeLimit.toLocaleString()} bytes`);
|
|
228
|
-
const f = Buffer.allocUnsafe(a);
|
|
229
|
-
return await this.fasta.read(f, 0, a, r, n), f.toString("utf8").replace(/\s+/g, "");
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
class O extends B {
|
|
233
|
-
constructor({ fasta: e, path: t, fai: i, faiPath: n, gzi: s, gziPath: r, chunkSizeLimit: a }) {
|
|
234
|
-
super({ fasta: e, path: t, fai: i, faiPath: n, chunkSizeLimit: a }), e && s ? this.fasta = new y({
|
|
235
|
-
filehandle: e,
|
|
236
|
-
gziFilehandle: s
|
|
237
|
-
}) : t && r && (this.fasta = new y({ path: t, gziPath: r }));
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
function L(l) {
|
|
241
|
-
return l.split(">").filter((e) => /\S/.test(e)).map((e) => {
|
|
242
|
-
const [t, ...i] = e.split(`
|
|
243
|
-
`), [n, ...s] = t.split(" "), r = i.join("").replace(/\s/g, "");
|
|
244
|
-
return {
|
|
245
|
-
id: n,
|
|
246
|
-
description: s.join(" "),
|
|
247
|
-
sequence: r
|
|
248
|
-
};
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
class v {
|
|
252
|
-
constructor({ fasta: e, path: t }) {
|
|
253
|
-
if (e)
|
|
254
|
-
this.fasta = e;
|
|
255
|
-
else if (t)
|
|
256
|
-
this.fasta = new g(t);
|
|
257
|
-
else
|
|
258
|
-
throw new Error("Need to pass fasta or path");
|
|
259
|
-
this.data = this.fasta.readFile().then((i) => {
|
|
260
|
-
const n = i.toString("utf8");
|
|
261
|
-
return L(n);
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
async fetch(e, t, i) {
|
|
265
|
-
const s = (await this.data).find((a) => a.id === e), r = i - t;
|
|
266
|
-
if (!s)
|
|
267
|
-
throw new Error(`no sequence with id ${e} exists`);
|
|
268
|
-
return s.sequence.substr(t, r);
|
|
269
|
-
}
|
|
270
|
-
async getSequenceNames() {
|
|
271
|
-
return (await this.data).map((t) => t.id);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
export {
|
|
275
|
-
O as BgzipIndexedFasta,
|
|
276
|
-
v as FetchableSmallFasta,
|
|
277
|
-
B as IndexedFasta,
|
|
278
|
-
L as parseSmallFasta
|
|
279
|
-
};
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { b as u } from "./index-C8lYPtq_.js";
|
|
2
|
-
const h = typeof window < "u" ? window : typeof self < "u" ? self : { fetch: void 0 };
|
|
3
|
-
class b {
|
|
4
|
-
async getBufferFromResponse(e) {
|
|
5
|
-
if (typeof e.buffer == "function")
|
|
6
|
-
return e.buffer();
|
|
7
|
-
if (typeof e.arrayBuffer == "function") {
|
|
8
|
-
const t = await e.arrayBuffer();
|
|
9
|
-
return u.Buffer.from(t);
|
|
10
|
-
} else
|
|
11
|
-
throw new TypeError("invalid HTTP response object, has no buffer method, and no arrayBuffer method");
|
|
12
|
-
}
|
|
13
|
-
constructor(e, t = {}) {
|
|
14
|
-
this.baseOverrides = {}, this.url = e;
|
|
15
|
-
const r = t.fetch || h.fetch && h.fetch.bind(h);
|
|
16
|
-
if (!r)
|
|
17
|
-
throw new TypeError("no fetch function supplied, and none found in global environment");
|
|
18
|
-
t.overrides && (this.baseOverrides = t.overrides), this.fetchImplementation = r;
|
|
19
|
-
}
|
|
20
|
-
async fetch(e, t) {
|
|
21
|
-
let r;
|
|
22
|
-
try {
|
|
23
|
-
r = await this.fetchImplementation(e, t);
|
|
24
|
-
} catch (s) {
|
|
25
|
-
if (`${s}`.includes("Failed to fetch"))
|
|
26
|
-
console.warn(`generic-filehandle: refetching ${e} to attempt to work around chrome CORS header caching bug`), r = await this.fetchImplementation(e, {
|
|
27
|
-
...t,
|
|
28
|
-
cache: "reload"
|
|
29
|
-
});
|
|
30
|
-
else
|
|
31
|
-
throw s;
|
|
32
|
-
}
|
|
33
|
-
return r;
|
|
34
|
-
}
|
|
35
|
-
async read(e, t = 0, r, s = 0, o = {}) {
|
|
36
|
-
const { headers: i = {}, signal: f, overrides: n = {} } = o;
|
|
37
|
-
r < 1 / 0 ? i.range = `bytes=${s}-${s + r}` : r === 1 / 0 && s !== 0 && (i.range = `bytes=${s}-`);
|
|
38
|
-
const l = {
|
|
39
|
-
...this.baseOverrides,
|
|
40
|
-
...n,
|
|
41
|
-
headers: {
|
|
42
|
-
...i,
|
|
43
|
-
...n.headers,
|
|
44
|
-
...this.baseOverrides.headers
|
|
45
|
-
},
|
|
46
|
-
method: "GET",
|
|
47
|
-
redirect: "follow",
|
|
48
|
-
mode: "cors",
|
|
49
|
-
signal: f
|
|
50
|
-
}, a = await this.fetch(this.url, l);
|
|
51
|
-
if (!a.ok)
|
|
52
|
-
throw new Error(`HTTP ${a.status} ${a.statusText} ${this.url}`);
|
|
53
|
-
if (a.status === 200 && s === 0 || a.status === 206) {
|
|
54
|
-
const d = await this.getBufferFromResponse(a), w = d.copy(e, t, 0, Math.min(r, d.length)), m = a.headers.get("content-range"), c = /\/(\d+)$/.exec(m || "");
|
|
55
|
-
return c && c[1] && (this._stat = { size: parseInt(c[1], 10) }), { bytesRead: w, buffer: e };
|
|
56
|
-
}
|
|
57
|
-
throw a.status === 200 ? new Error("${this.url} fetch returned status 200, expected 206") : new Error(`HTTP ${a.status} fetching ${this.url}`);
|
|
58
|
-
}
|
|
59
|
-
async readFile(e = {}) {
|
|
60
|
-
let t, r;
|
|
61
|
-
typeof e == "string" ? (t = e, r = {}) : (t = e.encoding, r = e, delete r.encoding);
|
|
62
|
-
const { headers: s = {}, signal: o, overrides: i = {} } = r, f = {
|
|
63
|
-
headers: s,
|
|
64
|
-
method: "GET",
|
|
65
|
-
redirect: "follow",
|
|
66
|
-
mode: "cors",
|
|
67
|
-
signal: o,
|
|
68
|
-
...this.baseOverrides,
|
|
69
|
-
...i
|
|
70
|
-
}, n = await this.fetch(this.url, f);
|
|
71
|
-
if (!n)
|
|
72
|
-
throw new Error("generic-filehandle failed to fetch");
|
|
73
|
-
if (n.status !== 200)
|
|
74
|
-
throw Object.assign(new Error(`HTTP ${n.status} fetching ${this.url}`), {
|
|
75
|
-
status: n.status
|
|
76
|
-
});
|
|
77
|
-
if (t === "utf8")
|
|
78
|
-
return n.text();
|
|
79
|
-
if (t)
|
|
80
|
-
throw new Error(`unsupported encoding: ${t}`);
|
|
81
|
-
return this.getBufferFromResponse(n);
|
|
82
|
-
}
|
|
83
|
-
async stat() {
|
|
84
|
-
if (!this._stat) {
|
|
85
|
-
const e = u.Buffer.allocUnsafe(10);
|
|
86
|
-
if (await this.read(e, 0, 10, 0), !this._stat)
|
|
87
|
-
throw new Error(`unable to determine size of file at ${this.url}`);
|
|
88
|
-
}
|
|
89
|
-
return this._stat;
|
|
90
|
-
}
|
|
91
|
-
async close() {
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
export {
|
|
95
|
-
b as R
|
|
96
|
-
};
|