@jbrowse/plugin-gtf 2.13.1 → 2.15.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.
@@ -2,16 +2,18 @@ import { BaseFeatureDataAdapter, BaseOptions } from '@jbrowse/core/data_adapters
2
2
  import { NoAssemblyRegion } from '@jbrowse/core/util/types';
3
3
  import IntervalTree from '@flatten-js/interval-tree';
4
4
  import { Feature } from '@jbrowse/core/util';
5
+ type StatusCallback = (arg: string) => void;
5
6
  export default class GtfAdapter extends BaseFeatureDataAdapter {
6
- protected gtfFeatures?: Promise<{
7
- feats: Record<string, string[]>;
7
+ calculatedIntervalTreeMap: Record<string, IntervalTree>;
8
+ gtfFeatures?: Promise<{
9
+ header: string;
10
+ intervalTreeMap: Record<string, (sc?: StatusCallback) => IntervalTree>;
8
11
  }>;
9
- protected intervalTrees: Record<string, Promise<IntervalTree | undefined> | undefined>;
10
12
  private loadDataP;
11
13
  private loadData;
12
14
  getRefNames(opts?: BaseOptions): Promise<string[]>;
13
- private loadFeatureIntervalTreeHelper;
14
- private loadFeatureIntervalTree;
15
+ getHeader(opts?: BaseOptions): Promise<string>;
15
16
  getFeatures(query: NoAssemblyRegion, opts?: BaseOptions): import("rxjs").Observable<Feature>;
16
17
  freeResources(): void;
17
18
  }
19
+ export {};
@@ -12,43 +12,79 @@ const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
12
12
  const gtf_1 = __importDefault(require("@gmod/gtf"));
13
13
  // locals
14
14
  const util_2 = require("../util");
15
- function isGzip(buf) {
16
- return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
17
- }
15
+ const decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;
18
16
  class GtfAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
19
17
  constructor() {
20
18
  super(...arguments);
21
- this.intervalTrees = {};
19
+ this.calculatedIntervalTreeMap = {};
22
20
  }
23
- async loadDataP(opts = {}) {
24
- const gtfLoc = this.getConf('gtfLocation');
25
- const buffer = await (0, io_1.openLocation)(gtfLoc, this.pluginManager).readFile(opts);
26
- const buf = isGzip(buffer) ? await (0, bgzf_filehandle_1.unzip)(buffer) : buffer;
27
- // 512MB max chrome string length is 512MB
28
- if (buf.length > 536870888) {
29
- throw new Error('Data exceeds maximum string length (512MB)');
30
- }
31
- const data = new TextDecoder('utf8', { fatal: true }).decode(buf);
32
- const lines = data
33
- .split(/\n|\r\n|\r/)
34
- .filter(f => !!f && !f.startsWith('#'));
35
- const feats = {};
36
- for (const line of lines) {
37
- if (line.startsWith('#')) {
38
- continue;
21
+ async loadDataP(opts) {
22
+ const { statusCallback = () => { } } = opts || {};
23
+ const buf = (await (0, io_1.openLocation)(this.getConf('gtfLocation'), this.pluginManager).readFile(opts));
24
+ const buffer = (0, util_1.isGzip)(buf)
25
+ ? await (0, util_1.updateStatus)('Unzipping', statusCallback, () => (0, bgzf_filehandle_1.unzip)(buf))
26
+ : buf;
27
+ const headerLines = [];
28
+ const featureMap = {};
29
+ let blockStart = 0;
30
+ let i = 0;
31
+ while (blockStart < buffer.length) {
32
+ const n = buffer.indexOf('\n', blockStart);
33
+ // could be a non-newline ended file, so slice to end of file if n===-1
34
+ const b = n === -1 ? buffer.subarray(blockStart) : buffer.subarray(blockStart, n);
35
+ const line = ((decoder === null || decoder === void 0 ? void 0 : decoder.decode(b)) || b.toString()).trim();
36
+ if (line) {
37
+ if (line.startsWith('#')) {
38
+ headerLines.push(line);
39
+ }
40
+ else if (line.startsWith('>')) {
41
+ break;
42
+ }
43
+ else {
44
+ const ret = line.indexOf('\t');
45
+ const refName = line.slice(0, ret);
46
+ if (!featureMap[refName]) {
47
+ featureMap[refName] = '';
48
+ }
49
+ featureMap[refName] += `${line}\n`;
50
+ }
39
51
  }
40
- const tab = line.indexOf('\t');
41
- const refName = line.slice(0, tab);
42
- if (!feats[refName]) {
43
- feats[refName] = [];
52
+ if (i++ % 10000 === 0) {
53
+ statusCallback(`Loading ${Math.floor(blockStart / 1000000).toLocaleString('en-US')}/${Math.floor(buffer.length / 1000000).toLocaleString('en-US')} MB`);
44
54
  }
45
- feats[refName].push(line);
55
+ blockStart = n + 1;
46
56
  }
47
- return { feats };
57
+ const intervalTreeMap = Object.fromEntries(Object.entries(featureMap).map(([refName, lines]) => [
58
+ refName,
59
+ (sc) => {
60
+ if (!this.calculatedIntervalTreeMap[refName]) {
61
+ sc === null || sc === void 0 ? void 0 : sc('Parsing GTF data');
62
+ const intervalTree = new interval_tree_1.default();
63
+ gtf_1.default.parseStringSync(lines, {
64
+ parseFeatures: true,
65
+ parseComments: false,
66
+ parseDirectives: false,
67
+ parseSequences: false,
68
+ })
69
+ .flat()
70
+ .map((f, i) => new util_1.SimpleFeature({
71
+ data: (0, util_2.featureData)(f),
72
+ id: `${this.id}-${refName}-${i}`,
73
+ }))
74
+ .forEach(obj => intervalTree.insert([obj.get('start'), obj.get('end')], obj));
75
+ this.calculatedIntervalTreeMap[refName] = intervalTree;
76
+ }
77
+ return this.calculatedIntervalTreeMap[refName];
78
+ },
79
+ ]));
80
+ return {
81
+ header: headerLines.join('\n'),
82
+ intervalTreeMap,
83
+ };
48
84
  }
49
85
  async loadData(opts = {}) {
50
86
  if (!this.gtfFeatures) {
51
- this.gtfFeatures = this.loadDataP(opts).catch(e => {
87
+ this.gtfFeatures = this.loadDataP(opts).catch((e) => {
52
88
  this.gtfFeatures = undefined;
53
89
  throw e;
54
90
  });
@@ -56,46 +92,22 @@ class GtfAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
56
92
  return this.gtfFeatures;
57
93
  }
58
94
  async getRefNames(opts = {}) {
59
- const { feats } = await this.loadData(opts);
60
- return Object.keys(feats);
61
- }
62
- async loadFeatureIntervalTreeHelper(refName) {
63
- const { feats } = await this.loadData();
64
- const lines = feats[refName];
65
- if (!lines) {
66
- return undefined;
67
- }
68
- const data = gtf_1.default.parseStringSync(lines.join('\n'), {
69
- parseFeatures: true,
70
- parseComments: false,
71
- parseDirectives: false,
72
- parseSequences: false,
73
- });
74
- const intervalTree = new interval_tree_1.default();
75
- const ret = data.flat().map((f, i) => new util_1.SimpleFeature({
76
- data: (0, util_2.featureData)(f),
77
- id: `${this.id}-${refName}-${i}`,
78
- }));
79
- for (const obj of ret) {
80
- intervalTree.insert([obj.get('start'), obj.get('end')], obj);
81
- }
82
- return intervalTree;
95
+ const { intervalTreeMap } = await this.loadData(opts);
96
+ return Object.keys(intervalTreeMap);
83
97
  }
84
- async loadFeatureIntervalTree(refName) {
85
- if (!this.intervalTrees[refName]) {
86
- this.intervalTrees[refName] = this.loadFeatureIntervalTreeHelper(refName).catch(e => {
87
- this.intervalTrees[refName] = undefined;
88
- throw e;
89
- });
90
- }
91
- return this.intervalTrees[refName];
98
+ async getHeader(opts = {}) {
99
+ const { header } = await this.loadData(opts);
100
+ return header;
92
101
  }
93
102
  getFeatures(query, opts = {}) {
94
103
  return (0, rxjs_1.ObservableCreate)(async (observer) => {
104
+ var _a;
95
105
  try {
96
106
  const { start, end, refName } = query;
97
- const intervalTree = await this.loadFeatureIntervalTree(refName);
98
- intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f => observer.next(f));
107
+ const { intervalTreeMap } = await this.loadData(opts);
108
+ (_a = intervalTreeMap[refName]) === null || _a === void 0 ? void 0 : _a.call(intervalTreeMap, opts.statusCallback).search([start, end]).forEach(f => {
109
+ observer.next(f);
110
+ });
99
111
  observer.complete();
100
112
  }
101
113
  catch (e) {
package/dist/util.d.ts CHANGED
@@ -5,7 +5,7 @@ export interface FeatureLoc {
5
5
  end: number;
6
6
  strand: Strand;
7
7
  seq_name: string;
8
- child_features: FeatureLoc[][];
8
+ child_features?: FeatureLoc[][];
9
9
  data: unknown;
10
10
  derived_features: unknown;
11
11
  attributes: Record<string, unknown[]>;
package/dist/util.js CHANGED
@@ -8,10 +8,10 @@ function featureData(data) {
8
8
  f.phase = Number(data.frame);
9
9
  f.refName = data.seq_name;
10
10
  if (data.score === null) {
11
- delete f.score;
11
+ f.score = undefined;
12
12
  }
13
13
  if (data.frame === null) {
14
- delete f.score;
14
+ f.score = undefined;
15
15
  }
16
16
  const defaultFields = new Set([
17
17
  'start',
@@ -30,12 +30,12 @@ function featureData(data) {
30
30
  // reproduces behavior of NCList
31
31
  b += '2';
32
32
  }
33
- if (data.attributes[a] !== null) {
33
+ if (data.attributes[a]) {
34
34
  let attr = data.attributes[a];
35
35
  if (Array.isArray(attr) && attr.length === 1) {
36
36
  // gtf uses double quotes for text values in the attributes column,
37
37
  // remove them
38
- attr = `${attr[0]}`.replaceAll(/^"|"$/g, '');
38
+ attr = attr[0].replaceAll(/^"|"$/g, '');
39
39
  }
40
40
  f[b] = attr;
41
41
  }
@@ -46,15 +46,14 @@ function featureData(data) {
46
46
  if (data.child_features && data.child_features.length > 0) {
47
47
  f.subfeatures = data.child_features.flatMap(childLocs => childLocs.map(childLoc => featureData(childLoc)));
48
48
  }
49
- delete f.child_features;
50
- delete f.data;
51
- delete f.derived_features;
52
- // eslint-disable-next-line no-underscore-dangle
53
- delete f._linehash;
54
- delete f.attributes;
55
- delete f.seq_name;
56
- delete f.featureType;
57
- delete f.frame;
49
+ f.child_features = undefined;
50
+ f.data = undefined;
51
+ f.derived_features = undefined;
52
+ f._linehash = undefined;
53
+ f.attributes = undefined;
54
+ f.seq_name = undefined;
55
+ f.featureType = undefined;
56
+ f.frame = undefined;
58
57
  if (f.transcript_id) {
59
58
  f.name = f.transcript_id;
60
59
  }
@@ -2,16 +2,18 @@ import { BaseFeatureDataAdapter, BaseOptions } from '@jbrowse/core/data_adapters
2
2
  import { NoAssemblyRegion } from '@jbrowse/core/util/types';
3
3
  import IntervalTree from '@flatten-js/interval-tree';
4
4
  import { Feature } from '@jbrowse/core/util';
5
+ type StatusCallback = (arg: string) => void;
5
6
  export default class GtfAdapter extends BaseFeatureDataAdapter {
6
- protected gtfFeatures?: Promise<{
7
- feats: Record<string, string[]>;
7
+ calculatedIntervalTreeMap: Record<string, IntervalTree>;
8
+ gtfFeatures?: Promise<{
9
+ header: string;
10
+ intervalTreeMap: Record<string, (sc?: StatusCallback) => IntervalTree>;
8
11
  }>;
9
- protected intervalTrees: Record<string, Promise<IntervalTree | undefined> | undefined>;
10
12
  private loadDataP;
11
13
  private loadData;
12
14
  getRefNames(opts?: BaseOptions): Promise<string[]>;
13
- private loadFeatureIntervalTreeHelper;
14
- private loadFeatureIntervalTree;
15
+ getHeader(opts?: BaseOptions): Promise<string>;
15
16
  getFeatures(query: NoAssemblyRegion, opts?: BaseOptions): import("rxjs").Observable<Feature>;
16
17
  freeResources(): void;
17
18
  }
19
+ export {};
@@ -2,48 +2,84 @@ import { BaseFeatureDataAdapter, } from '@jbrowse/core/data_adapters/BaseAdapter
2
2
  import { openLocation } from '@jbrowse/core/util/io';
3
3
  import { ObservableCreate } from '@jbrowse/core/util/rxjs';
4
4
  import IntervalTree from '@flatten-js/interval-tree';
5
- import { SimpleFeature } from '@jbrowse/core/util';
5
+ import { SimpleFeature, updateStatus, isGzip, } from '@jbrowse/core/util';
6
6
  import { unzip } from '@gmod/bgzf-filehandle';
7
7
  import gtf from '@gmod/gtf';
8
8
  // locals
9
9
  import { featureData } from '../util';
10
- function isGzip(buf) {
11
- return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
12
- }
10
+ const decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf8') : undefined;
13
11
  export default class GtfAdapter extends BaseFeatureDataAdapter {
14
12
  constructor() {
15
13
  super(...arguments);
16
- this.intervalTrees = {};
14
+ this.calculatedIntervalTreeMap = {};
17
15
  }
18
- async loadDataP(opts = {}) {
19
- const gtfLoc = this.getConf('gtfLocation');
20
- const buffer = await openLocation(gtfLoc, this.pluginManager).readFile(opts);
21
- const buf = isGzip(buffer) ? await unzip(buffer) : buffer;
22
- // 512MB max chrome string length is 512MB
23
- if (buf.length > 536870888) {
24
- throw new Error('Data exceeds maximum string length (512MB)');
25
- }
26
- const data = new TextDecoder('utf8', { fatal: true }).decode(buf);
27
- const lines = data
28
- .split(/\n|\r\n|\r/)
29
- .filter(f => !!f && !f.startsWith('#'));
30
- const feats = {};
31
- for (const line of lines) {
32
- if (line.startsWith('#')) {
33
- continue;
16
+ async loadDataP(opts) {
17
+ const { statusCallback = () => { } } = opts || {};
18
+ const buf = (await openLocation(this.getConf('gtfLocation'), this.pluginManager).readFile(opts));
19
+ const buffer = isGzip(buf)
20
+ ? await updateStatus('Unzipping', statusCallback, () => unzip(buf))
21
+ : buf;
22
+ const headerLines = [];
23
+ const featureMap = {};
24
+ let blockStart = 0;
25
+ let i = 0;
26
+ while (blockStart < buffer.length) {
27
+ const n = buffer.indexOf('\n', blockStart);
28
+ // could be a non-newline ended file, so slice to end of file if n===-1
29
+ const b = n === -1 ? buffer.subarray(blockStart) : buffer.subarray(blockStart, n);
30
+ const line = ((decoder === null || decoder === void 0 ? void 0 : decoder.decode(b)) || b.toString()).trim();
31
+ if (line) {
32
+ if (line.startsWith('#')) {
33
+ headerLines.push(line);
34
+ }
35
+ else if (line.startsWith('>')) {
36
+ break;
37
+ }
38
+ else {
39
+ const ret = line.indexOf('\t');
40
+ const refName = line.slice(0, ret);
41
+ if (!featureMap[refName]) {
42
+ featureMap[refName] = '';
43
+ }
44
+ featureMap[refName] += `${line}\n`;
45
+ }
34
46
  }
35
- const tab = line.indexOf('\t');
36
- const refName = line.slice(0, tab);
37
- if (!feats[refName]) {
38
- feats[refName] = [];
47
+ if (i++ % 10000 === 0) {
48
+ statusCallback(`Loading ${Math.floor(blockStart / 1000000).toLocaleString('en-US')}/${Math.floor(buffer.length / 1000000).toLocaleString('en-US')} MB`);
39
49
  }
40
- feats[refName].push(line);
50
+ blockStart = n + 1;
41
51
  }
42
- return { feats };
52
+ const intervalTreeMap = Object.fromEntries(Object.entries(featureMap).map(([refName, lines]) => [
53
+ refName,
54
+ (sc) => {
55
+ if (!this.calculatedIntervalTreeMap[refName]) {
56
+ sc === null || sc === void 0 ? void 0 : sc('Parsing GTF data');
57
+ const intervalTree = new IntervalTree();
58
+ gtf.parseStringSync(lines, {
59
+ parseFeatures: true,
60
+ parseComments: false,
61
+ parseDirectives: false,
62
+ parseSequences: false,
63
+ })
64
+ .flat()
65
+ .map((f, i) => new SimpleFeature({
66
+ data: featureData(f),
67
+ id: `${this.id}-${refName}-${i}`,
68
+ }))
69
+ .forEach(obj => intervalTree.insert([obj.get('start'), obj.get('end')], obj));
70
+ this.calculatedIntervalTreeMap[refName] = intervalTree;
71
+ }
72
+ return this.calculatedIntervalTreeMap[refName];
73
+ },
74
+ ]));
75
+ return {
76
+ header: headerLines.join('\n'),
77
+ intervalTreeMap,
78
+ };
43
79
  }
44
80
  async loadData(opts = {}) {
45
81
  if (!this.gtfFeatures) {
46
- this.gtfFeatures = this.loadDataP(opts).catch(e => {
82
+ this.gtfFeatures = this.loadDataP(opts).catch((e) => {
47
83
  this.gtfFeatures = undefined;
48
84
  throw e;
49
85
  });
@@ -51,46 +87,22 @@ export default class GtfAdapter extends BaseFeatureDataAdapter {
51
87
  return this.gtfFeatures;
52
88
  }
53
89
  async getRefNames(opts = {}) {
54
- const { feats } = await this.loadData(opts);
55
- return Object.keys(feats);
56
- }
57
- async loadFeatureIntervalTreeHelper(refName) {
58
- const { feats } = await this.loadData();
59
- const lines = feats[refName];
60
- if (!lines) {
61
- return undefined;
62
- }
63
- const data = gtf.parseStringSync(lines.join('\n'), {
64
- parseFeatures: true,
65
- parseComments: false,
66
- parseDirectives: false,
67
- parseSequences: false,
68
- });
69
- const intervalTree = new IntervalTree();
70
- const ret = data.flat().map((f, i) => new SimpleFeature({
71
- data: featureData(f),
72
- id: `${this.id}-${refName}-${i}`,
73
- }));
74
- for (const obj of ret) {
75
- intervalTree.insert([obj.get('start'), obj.get('end')], obj);
76
- }
77
- return intervalTree;
90
+ const { intervalTreeMap } = await this.loadData(opts);
91
+ return Object.keys(intervalTreeMap);
78
92
  }
79
- async loadFeatureIntervalTree(refName) {
80
- if (!this.intervalTrees[refName]) {
81
- this.intervalTrees[refName] = this.loadFeatureIntervalTreeHelper(refName).catch(e => {
82
- this.intervalTrees[refName] = undefined;
83
- throw e;
84
- });
85
- }
86
- return this.intervalTrees[refName];
93
+ async getHeader(opts = {}) {
94
+ const { header } = await this.loadData(opts);
95
+ return header;
87
96
  }
88
97
  getFeatures(query, opts = {}) {
89
98
  return ObservableCreate(async (observer) => {
99
+ var _a;
90
100
  try {
91
101
  const { start, end, refName } = query;
92
- const intervalTree = await this.loadFeatureIntervalTree(refName);
93
- intervalTree === null || intervalTree === void 0 ? void 0 : intervalTree.search([start, end]).forEach(f => observer.next(f));
102
+ const { intervalTreeMap } = await this.loadData(opts);
103
+ (_a = intervalTreeMap[refName]) === null || _a === void 0 ? void 0 : _a.call(intervalTreeMap, opts.statusCallback).search([start, end]).forEach(f => {
104
+ observer.next(f);
105
+ });
94
106
  observer.complete();
95
107
  }
96
108
  catch (e) {
package/esm/util.d.ts CHANGED
@@ -5,7 +5,7 @@ export interface FeatureLoc {
5
5
  end: number;
6
6
  strand: Strand;
7
7
  seq_name: string;
8
- child_features: FeatureLoc[][];
8
+ child_features?: FeatureLoc[][];
9
9
  data: unknown;
10
10
  derived_features: unknown;
11
11
  attributes: Record<string, unknown[]>;
package/esm/util.js CHANGED
@@ -5,10 +5,10 @@ export function featureData(data) {
5
5
  f.phase = Number(data.frame);
6
6
  f.refName = data.seq_name;
7
7
  if (data.score === null) {
8
- delete f.score;
8
+ f.score = undefined;
9
9
  }
10
10
  if (data.frame === null) {
11
- delete f.score;
11
+ f.score = undefined;
12
12
  }
13
13
  const defaultFields = new Set([
14
14
  'start',
@@ -27,12 +27,12 @@ export function featureData(data) {
27
27
  // reproduces behavior of NCList
28
28
  b += '2';
29
29
  }
30
- if (data.attributes[a] !== null) {
30
+ if (data.attributes[a]) {
31
31
  let attr = data.attributes[a];
32
32
  if (Array.isArray(attr) && attr.length === 1) {
33
33
  // gtf uses double quotes for text values in the attributes column,
34
34
  // remove them
35
- attr = `${attr[0]}`.replaceAll(/^"|"$/g, '');
35
+ attr = attr[0].replaceAll(/^"|"$/g, '');
36
36
  }
37
37
  f[b] = attr;
38
38
  }
@@ -43,15 +43,14 @@ export function featureData(data) {
43
43
  if (data.child_features && data.child_features.length > 0) {
44
44
  f.subfeatures = data.child_features.flatMap(childLocs => childLocs.map(childLoc => featureData(childLoc)));
45
45
  }
46
- delete f.child_features;
47
- delete f.data;
48
- delete f.derived_features;
49
- // eslint-disable-next-line no-underscore-dangle
50
- delete f._linehash;
51
- delete f.attributes;
52
- delete f.seq_name;
53
- delete f.featureType;
54
- delete f.frame;
46
+ f.child_features = undefined;
47
+ f.data = undefined;
48
+ f.derived_features = undefined;
49
+ f._linehash = undefined;
50
+ f.attributes = undefined;
51
+ f.seq_name = undefined;
52
+ f.featureType = undefined;
53
+ f.frame = undefined;
55
54
  if (f.transcript_id) {
56
55
  f.name = f.transcript_id;
57
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-gtf",
3
- "version": "2.13.1",
3
+ "version": "2.15.0",
4
4
  "description": "JBrowse 2 gtf feature adapter",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -24,7 +24,7 @@
24
24
  ],
25
25
  "scripts": {
26
26
  "build": "npm-run-all build:*",
27
- "test": "cd ../..; jest plugins/gtf --passWithNoTests",
27
+ "test": "cd ../..; jest --passWithNoTests plugins/gtf --passWithNoTests",
28
28
  "prepublishOnly": "yarn test",
29
29
  "prepack": "yarn build && yarn useDist",
30
30
  "postpack": "yarn useSrc",
@@ -43,7 +43,7 @@
43
43
  "peerDependencies": {
44
44
  "@jbrowse/core": "^2.0.0",
45
45
  "@jbrowse/plugin-linear-genome-view": "^2.0.0",
46
- "@mui/material": "^5.0.0",
46
+ "@mui/material": "^6.0.0",
47
47
  "mobx": "^6.0.0",
48
48
  "mobx-react": "^9.0.0",
49
49
  "mobx-state-tree": "^5.0.0",
@@ -56,5 +56,5 @@
56
56
  "distModule": "esm/index.js",
57
57
  "srcModule": "src/index.ts",
58
58
  "module": "esm/index.js",
59
- "gitHead": "fcebca71cc1d066654603e1a9accfa6c6d4f764d"
59
+ "gitHead": "87eeb1fbf8311dbf88d5e75b5a265f03beffdda8"
60
60
  }