higlass 1.12.4 → 1.13.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.
Files changed (93) hide show
  1. package/README.md +3 -3
  2. package/app/globals.d.ts +11 -0
  3. package/app/missing-types.d.ts +21 -0
  4. package/app/scripts/CenterTrack.jsx +0 -1
  5. package/app/scripts/DraggableDiv.jsx +0 -1
  6. package/app/scripts/GenomePositionSearchBox.jsx +0 -1
  7. package/app/scripts/PixiTrack.js +106 -42
  8. package/app/scripts/Track.js +153 -45
  9. package/app/scripts/TrackRenderer.jsx +452 -135
  10. package/app/scripts/VerticalTiledPlot.jsx +0 -1
  11. package/app/scripts/configs/default-tracks-for-datatype.js +3 -2
  12. package/app/scripts/configs/primitives.js +3 -2
  13. package/app/scripts/configs/tracks-info-by-type.js +4 -1
  14. package/app/scripts/configs/tracks-info.js +25 -1
  15. package/app/scripts/hocs/with-pub-sub.jsx +3 -1
  16. package/app/scripts/types.ts +105 -0
  17. package/app/scripts/utils/abs-to-chr.js +16 -1
  18. package/app/scripts/utils/accessor-transposition.js +5 -4
  19. package/app/scripts/utils/add-arrays.js +9 -7
  20. package/app/scripts/utils/add-class.js +4 -2
  21. package/app/scripts/utils/add-event-listener-once.js +9 -3
  22. package/app/scripts/utils/background-task-scheduler.js +58 -2
  23. package/app/scripts/utils/base64-to-canvas.js +12 -5
  24. package/app/scripts/utils/chr-to-abs.js +10 -0
  25. package/app/scripts/utils/chrom-info-bisector.js +4 -1
  26. package/app/scripts/utils/clone-event.js +11 -4
  27. package/app/scripts/utils/color-to-hex.js +8 -0
  28. package/app/scripts/utils/color-to-rgba.js +8 -0
  29. package/app/scripts/utils/data-to-genomic-loci.js +13 -1
  30. package/app/scripts/utils/debounce.js +16 -11
  31. package/app/scripts/utils/dec-to-hex-str.js +7 -0
  32. package/app/scripts/utils/dict-from-tuples.js +11 -3
  33. package/app/scripts/utils/dict-items.js +15 -0
  34. package/app/scripts/utils/dict-keys.js +11 -1
  35. package/app/scripts/utils/dict-values.js +7 -0
  36. package/app/scripts/utils/download.js +14 -11
  37. package/app/scripts/utils/flatten.js +5 -2
  38. package/app/scripts/utils/for-each.js +7 -5
  39. package/app/scripts/utils/forward-event.js +3 -2
  40. package/app/scripts/utils/genome-loci-to-pixels.js +8 -0
  41. package/app/scripts/utils/genomic-range-to-chromosome-chunks.js +13 -6
  42. package/app/scripts/utils/get-aggregation-function.js +10 -2
  43. package/app/scripts/utils/get-element-dim.js +6 -0
  44. package/app/scripts/utils/gradient.js +14 -0
  45. package/app/scripts/utils/has-class.js +6 -4
  46. package/app/scripts/utils/hex-string-to-int.js +11 -4
  47. package/app/scripts/utils/index.js +1 -0
  48. package/app/scripts/utils/into-the-void.js +2 -1
  49. package/app/scripts/utils/is-track-or-child-track.js +6 -0
  50. package/app/scripts/utils/is-track-range-selectable.js +10 -1
  51. package/app/scripts/utils/is-within.js +9 -7
  52. package/app/scripts/utils/lat-to-y.js +6 -3
  53. package/app/scripts/utils/lng-to-x.js +4 -3
  54. package/app/scripts/utils/map.js +5 -2
  55. package/app/scripts/utils/max-non-zero.js +6 -0
  56. package/app/scripts/utils/max.js +4 -3
  57. package/app/scripts/utils/min-non-zero.js +6 -0
  58. package/app/scripts/utils/min.js +4 -3
  59. package/app/scripts/utils/mod.js +4 -3
  60. package/app/scripts/utils/numericify-version.js +5 -0
  61. package/app/scripts/utils/obj-vals.js +3 -2
  62. package/app/scripts/utils/or.js +4 -3
  63. package/app/scripts/utils/parse-chromsizes-rows.js +26 -5
  64. package/app/scripts/utils/q.js +3 -2
  65. package/app/scripts/utils/rad-to-deg.js +3 -2
  66. package/app/scripts/utils/reduce.js +2 -2
  67. package/app/scripts/utils/rel-to-abs-chrom-pos.js +10 -0
  68. package/app/scripts/utils/remove-class.js +3 -2
  69. package/app/scripts/utils/reset-d3-brush-style.js +7 -2
  70. package/app/scripts/utils/rgb-to-hex.js +9 -0
  71. package/app/scripts/utils/scales-center-and-k.js +5 -3
  72. package/app/scripts/utils/scales-to-genome-loci.js +10 -0
  73. package/app/scripts/utils/selected-items-to-cum-weights.js +12 -4
  74. package/app/scripts/utils/selected-items-to-size.js +5 -2
  75. package/app/scripts/utils/show-mouse-position.js +62 -19
  76. package/app/scripts/utils/some.js +6 -4
  77. package/app/scripts/utils/sum.js +4 -3
  78. package/app/scripts/utils/throttle-and-debounce.js +15 -6
  79. package/app/scripts/utils/tile-to-canvas.js +8 -4
  80. package/app/scripts/utils/timeout.js +2 -0
  81. package/app/scripts/utils/to-void.js +2 -0
  82. package/app/scripts/utils/total-track-pixel-height.js +11 -12
  83. package/app/scripts/utils/trim-trailing-slash.js +3 -2
  84. package/app/scripts/utils/type-guards.js +41 -0
  85. package/app/scripts/utils/value-to-color.js +7 -6
  86. package/app/scripts/utils/visit-positioned-tracks.js +16 -11
  87. package/app/scripts/utils/visit-tracks.js +12 -13
  88. package/dist/esm.html +283 -0
  89. package/dist/hglib.js +42 -82804
  90. package/dist/hglib.min.js +86 -105
  91. package/dist/higlass.mjs +207 -0
  92. package/dist/index.html +6 -6
  93. package/package.json +23 -5
@@ -1,8 +1,23 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @template T
5
+ * @typedef {Array<{ [Key in keyof T]: [Key, T[Key]] }[keyof T]>} DictItems
6
+ */
7
+
1
8
  /**
2
9
  * Return an array of (key,value) pairs that are present in this
3
10
  * dictionary
11
+ *
12
+ * TODO(Trevor): Replace with `Object.entries`?
13
+ *
14
+ * @template {object} T
15
+ * @param {T} dictionary
16
+ *
17
+ * @returns {DictItems<T>}
4
18
  */
5
19
  const dictItems = (dictionary) => {
20
+ /** @type {DictItems<T>} */
6
21
  const keyValues = [];
7
22
 
8
23
  for (const key in dictionary) {
@@ -1,10 +1,20 @@
1
+ // @ts-check
2
+
1
3
  /**
2
- * Return an array of values that are present in this dictionary
4
+ * Return an array of keys that are present in this dictionary
5
+ *
6
+ * TODO(Trevor): Replace with `Object.keys`?
7
+ *
8
+ * @template T
9
+ * @param {T} dictionary
10
+ * @returns {Array<keyof T>}
3
11
  */
4
12
  export default function dictKeys(dictionary) {
13
+ /** @type {Array<keyof T>} */
5
14
  const keys = [];
6
15
 
7
16
  for (const key in dictionary) {
17
+ // @ts-expect-error - TS inference not good enough to infer the correct type
8
18
  if (dictionary.hasOwnProperty(key)) {
9
19
  keys.push(key);
10
20
  }
@@ -1,7 +1,14 @@
1
+ // @ts-check
2
+
1
3
  /**
2
4
  * Return an array of values that are present in this dictionary
5
+ *
6
+ * @template {object} T
7
+ * @param {T} dictionary
8
+ * @returns {Array<T[keyof T]>}
3
9
  */
4
10
  export default function dictValues(dictionary) {
11
+ /** @type {Array<T[keyof T]>} */
5
12
  const values = [];
6
13
 
7
14
  for (const key in dictionary) {
@@ -1,3 +1,10 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * Download a file to the user's computer.
5
+ * @param {string} filename - Name of the file to download
6
+ * @param {string | Blob} stringOrBlob - Contents of the file to download
7
+ */
1
8
  export function download(filename, stringOrBlob) {
2
9
  // yanked from here
3
10
  // https://stackoverflow.com/questions/3665115/create-a-file-in-memory-for-user-to-download-not-through-server
@@ -6,17 +13,13 @@ export function download(filename, stringOrBlob) {
6
13
  typeof stringOrBlob === 'string'
7
14
  ? new Blob([stringOrBlob], { type: 'application/octet-stream' })
8
15
  : stringOrBlob;
9
- if (window.navigator.msSaveOrOpenBlob) {
10
- window.navigator.msSaveBlob(blob, filename);
11
- } else {
12
- const elem = window.document.createElement('a');
13
- elem.href = window.URL.createObjectURL(blob);
14
- elem.download = filename;
15
- document.body.appendChild(elem);
16
- elem.click();
17
- document.body.removeChild(elem);
18
- URL.revokeObjectURL(elem.href);
19
- }
16
+ const elem = window.document.createElement('a');
17
+ elem.href = window.URL.createObjectURL(blob);
18
+ elem.download = filename;
19
+ document.body.appendChild(elem);
20
+ elem.click();
21
+ document.body.removeChild(elem);
22
+ URL.revokeObjectURL(elem.href);
20
23
  }
21
24
 
22
25
  export default download;
@@ -2,9 +2,12 @@ import reduce from './reduce';
2
2
 
3
3
  /**
4
4
  * Function for flattening a nested array. It returns a curried reducer.
5
- * @param {array} Nested array
6
- * @return {array} Flatt array
5
+ *
6
+ * @template T
7
+ * @param {Array<Array<T>>} Nested array
8
+ * @return {Array<T>} Flat array
7
9
  */
8
10
  const flatten = reduce((a, b) => a.concat(b), []);
9
11
 
12
+ // TODO(Trevor): Not referenced anywhere. Remove?
10
13
  export default flatten;
@@ -1,10 +1,12 @@
1
+ // @ts-check
1
2
  /**
2
- * Functional version of `Array.forEach`. More flexible and applicable to
3
- * other array-like data types.
4
- * @param {function} f Modifier function applied on every item of the
5
- * array.
6
- * @return {*} Modified array-like variable.
3
+ * Functional version of `Array.forEach`. More flexible and applicable to other array-like data types.
4
+ *
5
+ * @template T
6
+ * @param {<T>(item: T) => void} f - Modifier function applied on every item of the array.
7
+ * @return {(arr: ArrayLike<T>) => void} Modified array-like variable.
7
8
  */
8
9
  const forEach = (f) => (x) => Array.prototype.forEach.call(x, f);
9
10
 
11
+ // TODO(Trevor): Not referenced anywhere. Remove?
10
12
  export default forEach;
@@ -1,9 +1,10 @@
1
+ // @ts-check
1
2
  import cloneEvent from './clone-event';
2
3
 
3
4
  /**
4
5
  * Forward an event by cloning and dispatching it.
5
- * @param {object} event Event to be forwarded.
6
- * @param {object} target Target HTML element for the event.
6
+ * @param {Event} event - Event to be forwarded.
7
+ * @param {HTMLElement} target - Target HTML element for the event.
7
8
  */
8
9
  const forwardEvent = (event, target) => {
9
10
  target.dispatchEvent(cloneEvent(event));
@@ -1,5 +1,13 @@
1
+ // @ts-check
1
2
  import chrToAbs from './chr-to-abs';
2
3
 
4
+ /**
5
+ * Convert a genome locus to an absolute genome position.
6
+ * @template {string} Name
7
+ * @param {[Name, number, Name, number]} genomeLoci - Genome locus
8
+ * @param {import('../types').ChromInfo<Name>} chromInfo - Chromosome info object
9
+ * @return {[start: number, end: number]} The absolute genome position.
10
+ */
3
11
  const genomeLociToPixels = (genomeLoci, chromInfo) => [
4
12
  chrToAbs(genomeLoci[0], genomeLoci[1], chromInfo),
5
13
  chrToAbs(genomeLoci[2], genomeLoci[3], chromInfo),
@@ -1,13 +1,17 @@
1
+ // @ts-check
2
+
1
3
  /**
2
4
  * Using the [genomicStart, genomicEnd] range, get an array of "chromosome chunks",
3
5
  * where each chunk range starts and ends with the same chromosome.
4
6
  * Start a new chromosome chunk at each chromosome boundary.
5
- * @param {array} chromSizes Array of [chrName, chrLen] tuples.
6
- * @param {object} genomicStart A genomic position object returned from abs2genomic { chr, pos }.
7
- * @param {object} genomicEnd A genomic position object returned from abs2genomic { chr, pos }.
8
- * @param {number} binSize The resolution / bin size.
9
- * @param {number} tileSize The tile size (probably 256).
10
- * @returns {array} Returns array of [chrName, zStart, zEnd] tuples.
7
+ *
8
+ * @template {string} Name
9
+ * @param {Array<[charName: Name, chrLen: number]>} chromSizes - Array of [chrName, chrLen] tuples.
10
+ * @param {{ chr: Name, pos: number }} genomicStart - A genomic position object returned from abs2genomic { chr, pos }.
11
+ * @param {{ chr: Name, pos: number }} genomicEnd - A genomic position object returned from abs2genomic { chr, pos }.
12
+ * @param {number} binSize - The resolution / bin size.
13
+ * @param {number} tileSize - The tile size (probably 256).
14
+ * @returns {Array<[chrName: Name, zStart: number, zEnd: number]>} Returns array of [chrName, zStart, zEnd] tuples.
11
15
  */
12
16
  function genomicRangeToChromosomeChunks(
13
17
  chromSizes,
@@ -19,6 +23,7 @@ function genomicRangeToChromosomeChunks(
19
23
  const { chr: chrStart, pos: chrStartPos } = genomicStart;
20
24
  const { chr: chrEnd, pos: chrEndPos } = genomicEnd;
21
25
 
26
+ /** @type {Array<[chrName: Name, zStart: number, zEnd: number]>} */
22
27
  const chrChunks = [];
23
28
  if (chrStart === chrEnd) {
24
29
  // This tile does _not_ cross a chromosome boundary.
@@ -37,7 +42,9 @@ function genomicRangeToChromosomeChunks(
37
42
 
38
43
  // Create a separate chunk for each chromosome that lies within the range.
39
44
  for (let chrIndex = chrStartIndex; chrIndex <= chrEndIndex; chrIndex++) {
45
+ /** @type {number} */
40
46
  let chrChunkStart;
47
+ /** @type {number} */
41
48
  let chrChunkEnd;
42
49
 
43
50
  const [currChrName, currChrLen] = chromSizes[chrIndex];
@@ -1,11 +1,18 @@
1
+ // @ts-check
1
2
  import { mean, sum, variance, deviation } from 'd3-array';
2
3
 
3
4
  /**
4
5
  * Get an aggregation function from a function name.
5
- * @param {string} name The name of an aggregation function
6
+ * @template {'mean' | 'sum' | 'variance' | 'deviation'} Type
7
+ * @param {Type} name - The name of an aggregation function
6
8
  * ('mean', 'sum', 'variance', 'deviation'). If an unknown string is passed,
7
9
  * the mean function will be used, and a console warning will be thrown.
8
- * @returns {function} The function of interest as determined by the string,
10
+ * @returns {{
11
+ * mean: typeof mean,
12
+ * sum: typeof sum,
13
+ * variance: typeof variance,
14
+ * deviation: typeof deviation,
15
+ * }[Type]} The function of interest as determined by the string,
9
16
  */
10
17
  const getAggregationFunction = (name) => {
11
18
  let aggFunc;
@@ -29,6 +36,7 @@ const getAggregationFunction = (name) => {
29
36
  'Encountered an unsupported selectedRowsAggregationMode option.',
30
37
  );
31
38
  }
39
+ // @ts-expect-error - TS can't infer type-mapping
32
40
  return aggFunc;
33
41
  };
34
42
 
@@ -1,5 +1,11 @@
1
+ // @ts-check
1
2
  import { ElementResizeListener } from '../services';
2
3
 
4
+ /**
5
+ * Get the dimensions of an element
6
+ * @param {HTMLElement} element - DOM element to get dimensions of.
7
+ * @return {[width: number, height: number]} The width and height of the element.
8
+ */
3
9
  const getElementDim = (element) => {
4
10
  ElementResizeListener.listen();
5
11
 
@@ -1,3 +1,14 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @param {{ from: number, color: string }[]} steps
5
+ * @param {number} width
6
+ * @param {number} height
7
+ * @param {number} fromX
8
+ * @param {number} fromY
9
+ * @param {number} toX
10
+ * @param {number} toY
11
+ */
1
12
  const gradient = (
2
13
  steps,
3
14
  width = 1,
@@ -12,6 +23,9 @@ const gradient = (
12
23
  canvas.height = height;
13
24
 
14
25
  const ctx = canvas.getContext('2d');
26
+ if (!ctx) {
27
+ throw new Error('Could not get canvas context');
28
+ }
15
29
  const grd = ctx.createLinearGradient(fromX, fromY, toX, toY);
16
30
 
17
31
  steps.forEach((step) => {
@@ -1,15 +1,17 @@
1
+ // @ts-check
2
+
1
3
  const XMLNS = 'http://www.w3.org/2000/svg';
2
4
 
3
5
  /**
4
6
  * Check if an HTML or SVG element has a certain class
5
- * @param {object} el HTML or SVG element to be checked.
6
- * @param {string} className Class name to be checked for.
7
- * @return {boolean} If `true` `el` has the class name.
7
+ * @param {Element} el - HTML or SVG element to be checked.
8
+ * @param {string} className - Class name to be checked for.
9
+ * @return {boolean} If `true` `el` has the class name.
8
10
  */
9
11
  const hasClass = (el, className) => {
10
12
  if (el.namespaceURI === XMLNS) {
11
13
  const _class = el.getAttribute('class');
12
- return _class && !!_class.match(new RegExp(`(\\s|^)${className}(\\s|$)`));
14
+ return !!_class && !!_class.match(new RegExp(`(\\s|^)${className}(\\s|$)`));
13
15
  }
14
16
 
15
17
  if (el.classList) return el.classList.contains(className);
@@ -1,8 +1,15 @@
1
+ // @ts-check
1
2
  /**
2
- * Convert a HEX string into a HEX integer. E.g., #FF0000 is translated to
3
- * 16711680.
4
- * @param {string} str HEX string
5
- * @return {integer} HEX number
3
+ * Convert a HEX string into a HEX integer.
4
+ *
5
+ * @example
6
+ * ```js
7
+ * // returns 16711680
8
+ * hexStrToInt("#FF0000");
9
+ * ```
10
+ *
11
+ * @param {string} str - HEX string
12
+ * @return {number} An (integer) HEX number
6
13
  */
7
14
  const hexStrToInt = (str) => parseInt(str.replace(/^#/, ''), 16);
8
15
 
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  export { default as absToChr } from './abs-to-chr';
2
3
  export { default as accessorTransposition } from './accessor-transposition';
3
4
  export { default as addArrays } from './add-arrays';
@@ -1,6 +1,7 @@
1
+ // @ts-check
1
2
  /**
2
3
  * An adventure into the abyss of void!
3
- * @return {undefined} The explorers find nothing but void.
4
+ * @type {(...args: any[]) => void} The explorers find nothing but void.
4
5
  */
5
6
  const intoTheVoid = () => {};
6
7
 
@@ -1,5 +1,11 @@
1
+ // @ts-check
1
2
  import CombinedTrack from '../CombinedTrack';
2
3
 
4
+ /**
5
+ * @param {import('../types').TrackObject} testTrack
6
+ * @param {import('../types').TrackObject} track
7
+ * @returns {boolean}
8
+ */
3
9
  const isTrackOrChildTrack = (testTrack, track) => {
4
10
  if (track === testTrack) return true;
5
11
  if (track instanceof CombinedTrack) {
@@ -1,5 +1,11 @@
1
+ // @ts-check
1
2
  import or from './or';
2
3
 
4
+ /**
5
+ * Return true if this track is selectable by range.
6
+ * @param {import('../types').TrackConfig} track
7
+ * @returns {boolean}
8
+ */
3
9
  export const IS_TRACK_RANGE_SELECTABLE = (track) => {
4
10
  switch (track.type) {
5
11
  case 'heatmap':
@@ -24,7 +30,10 @@ export const IS_TRACK_RANGE_SELECTABLE = (track) => {
24
30
  return true;
25
31
 
26
32
  case 'combined': {
27
- return track.contents
33
+ /** @type {import('../types').TrackConfig[]} */
34
+ // @ts-expect-error - TS should be able to narrow the type but isn't smart enough
35
+ const contents = track.contents;
36
+ return contents
28
37
  .map((t) => IS_TRACK_RANGE_SELECTABLE(t))
29
38
  .reduce(or, false);
30
39
  }
@@ -1,12 +1,14 @@
1
+ // @ts-check
2
+
1
3
  /**
2
4
  * Check if a 2D or 1D point is within a rectangle or range
3
- * @param {number} x The point's X coordinate.
4
- * @param {number} y The point's Y coordinate.
5
- * @param {number} minX The rectangle's start X coordinate.
6
- * @param {number} maxX The rectangle's start X coordinate.
7
- * @param {number} minY The rectangle's start X coordinate.
8
- * @param {number} maxY The rectangle's start X coordinate.
9
- * @return {boolean} If `true` the [x,y] point is in the rectangle.
5
+ * @param {number} x - The point's X coordinate.
6
+ * @param {number} y - The point's Y coordinate.
7
+ * @param {number} minX - The rectangle's start X coordinate.
8
+ * @param {number} maxX - The rectangle's start X coordinate.
9
+ * @param {number} minY - The rectangle's start X coordinate.
10
+ * @param {number} maxY - The rectangle's start X coordinate.
11
+ * @return {boolean} If `true` the [x,y] point is in the rectangle.
10
12
  */
11
13
  const isWithin = (x, y, minX, maxX, minY, maxY, is1d = false) =>
12
14
  is1d
@@ -1,10 +1,13 @@
1
+ // @ts-check
2
+
3
+ /** @param {number} y */
1
4
  export const invGudermannian = (y) => Math.log(Math.tan((y + Math.PI / 2) / 2));
2
5
 
3
6
  /**
4
7
  * Translate latitude to Y in the Mercator projection
5
- * @param {number} lat Latitude.
6
- * @param {number} zoom Zoom level
7
- * @return {number} Y coordinate in the Mercator projection.
8
+ * @param {number} lat - Latitude.
9
+ * @param {number} zoom - Zoom level
10
+ * @return {number} Y coordinate in the Mercator projection.
8
11
  */
9
12
  const latToY = (lat, zoom) => {
10
13
  let latRad = (lat * Math.PI) / 180.0;
@@ -1,8 +1,9 @@
1
+ // @ts-check
1
2
  /**
2
3
  * Convert longitude to the X coordinate in the Mercator projection.
3
- * @param {number} lng Longitude
4
- * @param {number} zoom Zoom level
5
- * @return {number} X coordinate in the Mercator projection.
4
+ * @param {number} lng - Longitude
5
+ * @param {number} zoom - Zoom level
6
+ * @return {number} X coordinate in the Mercator projection.
6
7
  */
7
8
  const lngToX = (lng, zoom) => (2 ** zoom * (lng + 180.0)) / 360.0;
8
9
 
@@ -1,3 +1,4 @@
1
+ // @ts-check
1
2
  /**
2
3
  * Exposed map function. You can do cool stuff with that!
3
4
  *
@@ -5,9 +6,11 @@
5
6
  * The pure map function is more powerful because it can be used on data types
6
7
  * other than Array too.
7
8
  *
8
- * @param {Function} f Mapping function.
9
- * @return {Array} Mapped array.
9
+ * @template T, B
10
+ * @param {(item: T, idx?: number) => B} f - Mapping function.
11
+ * @return {(x: Array<T>) => Array<B>} Mapped array.
10
12
  */
13
+ // @ts-expect-error - TS can't infer the type of the returned function.
11
14
  const map = (f) => (x) => Array.prototype.map.call(x, f);
12
15
 
13
16
  export default map;
@@ -1,5 +1,11 @@
1
+ // @ts-check
1
2
  const epsilon = 0.0000001;
2
3
 
4
+ /**
5
+ * Calculate the maximum non-zero value in the data
6
+ * @param {ArrayLike<number>} data - An array of values
7
+ * @returns {number} The maximum non-zero value in the array
8
+ */
3
9
  export default function maxNonZero(data) {
4
10
  /**
5
11
  * Calculate the minimum non-zero value in the data
@@ -1,10 +1,11 @@
1
+ // @ts-check
1
2
  /**
2
3
  * Fast version of `Math.max`. Based on
3
4
  * https://jsperf.com/math-min-max-vs-ternary-vs-if/24 `Math.max` is not
4
5
  * very fast
5
- * @param {number} a Value A
6
- * @param {number} b Value B
7
- * @return {boolean} If `true` A is greater than B.
6
+ * @param {number} a - Value A
7
+ * @param {number} b - Value B
8
+ * @return {number} If `true` A is greater than B.
8
9
  */
9
10
  const max = (a, b) => (a > b ? a : b);
10
11
 
@@ -1,5 +1,11 @@
1
+ // @ts-check
1
2
  const epsilon = 0.0000001;
2
3
 
4
+ /**
5
+ * Calculate the minimum non-zero value in the data
6
+ * @param {ArrayLike<number>} data - An array of values
7
+ * @returns {number} The minimum non-zero value in the array
8
+ */
3
9
  export default function minNonZero(data) {
4
10
  /**
5
11
  * Calculate the minimum non-zero value in the data
@@ -1,10 +1,11 @@
1
+ // @ts-check
1
2
  /**
2
3
  * Fast version of `Math.min`. Based on
3
4
  * https://jsperf.com/math-min-max-vs-ternary-vs-if/24 `Math.max` is not
4
5
  * very fast
5
- * @param {number} a Value A
6
- * @param {number} b Value B
7
- * @return {boolean} If `true` A is smaller than B.
6
+ * @param {number} a - Value A
7
+ * @param {number} b - Value B
8
+ * @return {number} If `true` A is smaller than B.
8
9
  */
9
10
  const min = (a, b) => (a < b ? a : b);
10
11
 
@@ -1,9 +1,10 @@
1
+ // @ts-check
1
2
  /**
2
3
  * Non-negative modulo function. E.g., `mod(-1, 5) === 4` while `-1 % 5 === -1`.
3
4
  *
4
- * @param {Integer} n Dividend
5
- * @param {Integer} m Divisor
6
- * @return {Integer} Remainder
5
+ * @param {number} n - Dividend (integer)
6
+ * @param {number} m - Divisor (integer)
7
+ * @return {number} Remainder (integer)
7
8
  */
8
9
  const mod = (n, m) => ((n % m) + m) % m;
9
10
 
@@ -1,3 +1,8 @@
1
+ // @ts-check
2
+ /**
3
+ * @param {string} version
4
+ * @returns {number}
5
+ */
1
6
  const numericifyVersion = (version) => {
2
7
  const parts = version.split('.');
3
8
  const tailLen = parts.slice(1).join('').length;
@@ -3,9 +3,10 @@ import map from './map';
3
3
  /**
4
4
  * Convert an object into array which entries are the prop values of the object
5
5
  *
6
- * @param {Object} obj Object to be arrayified
7
- * @return {Array} Array of the object.
6
+ * @param {Object} obj - Object to be arrayified
7
+ * @return {Array} Array of the object.
8
8
  */
9
9
  const objVals = (obj) => map((key) => obj[key])(Object.keys(obj));
10
10
 
11
+ // TODO(Trevor): We already have dictValues and `Object.values`? Can we get rid of this?
11
12
  export default objVals;
@@ -1,8 +1,9 @@
1
+ // @ts-check
1
2
  /**
2
3
  * Logical or operator for convenience.
3
- * @param {*} a Value A
4
- * @param {*} b Value B
5
- * @return {boolean} If `true` one of the two or both values are truthy.
4
+ * @param {boolean} a - Value A
5
+ * @param {boolean} b - Value B
6
+ * @return {boolean} If `true` one of the two or both values are truthy.
6
7
  */
7
8
  const or = (a, b) => a || b;
8
9
 
@@ -1,13 +1,34 @@
1
+ // @ts-check
2
+
3
+ /** @typedef {[string, number]} ChromsizeRow */
4
+
5
+ /**
6
+ * @typedef CumulativeChromsizeEntry
7
+ * @property {number} id
8
+ * @property {string} chr
9
+ * @property {number} pos
10
+ */
11
+
12
+ /**
13
+ * @typedef ParsedChromsizes
14
+ * @property {CumulativeChromsizeEntry[]} cumPositions
15
+ * @property {Record<string, CumulativeChromsizeEntry>} chrPositions
16
+ * @property {number} totalLength
17
+ * @property {Record<string, number>} chromLengths
18
+ */
19
+
1
20
  /**
2
- * Parse an array of chromsizes, for example that result
3
- * from reading rows of a chromsizes CSV file.
4
- * @param {array} data Array of [chrName, chrLen] "tuples".
5
- * @returns {object} Object containing properties
6
- * { cumPositions, chrPositions, totalLength, chromLengths }.
21
+ * Parse an array of chromsizes, for example that result from reading rows of a chromsizes CSV file.
22
+ *
23
+ * @param {ArrayLike<ChromsizeRow>} data - Array of [chrName, chrLen] "tuples".
24
+ * @returns {ParsedChromsizes}
7
25
  */
8
26
  function parseChromsizesRows(data) {
27
+ /** @type {Array<CumulativeChromsizeEntry>} */
9
28
  const cumValues = [];
29
+ /** @type {Record<string, number>} */
10
30
  const chromLengths = {};
31
+ /** @type {Record<string, CumulativeChromsizeEntry>} */
11
32
  const chrPositions = {};
12
33
 
13
34
  let totalLength = 0;
@@ -11,8 +11,8 @@
11
11
  * console.log(myFancyQuery(myFancyObj)) ==> 'Sweet!'
12
12
  * console.log(myFancyQuery(myNotSoFancyObj)) ==> undefined
13
13
  * ```
14
- * @param {[type]} queryStr [description]
15
- * @return {[type]} [description]
14
+ * @param {string} queryStr - dot-notation query string
15
+ * @return {unknown}
16
16
  */
17
17
  const q = (queryStr) => {
18
18
  try {
@@ -29,4 +29,5 @@ const q = (queryStr) => {
29
29
  }
30
30
  };
31
31
 
32
+ // TODO(Trevor): This is not referenced anywhere in the codebase, but it is exported. Remove?
32
33
  export default q;
@@ -1,7 +1,8 @@
1
+ // @ts-check
1
2
  /**
2
3
  * Convert radiance to degree
3
- * @param {number} rad Radiance
4
- * @return {number} Degree
4
+ * @param {number} rad - Radiance
5
+ * @return {number} Degree
5
6
  */
6
7
  const radToDeg = (rad) => (rad * 180) / Math.PI;
7
8
 
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Pure functional reducer. Can be used for currying stuff. Check out
3
- * `flatten.js`.
2
+ * Pure functional reducer. Can be used for currying stuff. Check out `flatten.js`.
4
3
  * @param {function} f Reducer function.
5
4
  * @return {array} Curried function that accepts an array to be reduced.
6
5
  */
7
6
  const reduce = (f) => (x) => Array.prototype.reduce.call(x, f);
8
7
 
8
+ // TODO(Trevor): Not referenced anywhere. Remove?
9
9
  export default reduce;