@genome-spy/core 0.71.0 → 0.72.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.
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Load a data set in Apache Parquet format for use in Vega.
3
+ * @param {ArrayBuffer|Uint8Array} data Parquet binary data.
4
+ * @returns {Promise<Record<string,any>[]>} A promise that resolves to an array of data objects representing
5
+ * rows of a data table.
6
+ */
7
+ declare function parquet(data: ArrayBuffer | Uint8Array): Promise<Record<string, any>[]>;
8
+ declare namespace parquet {
9
+ let responseType: string;
10
+ }
11
+ export default parquet;
12
+ //# sourceMappingURL=parquet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parquet.d.ts","sourceRoot":"","sources":["../../../../src/data/formats/parquet.js"],"names":[],"mappings":"AAYA;;;;;GAKG;AACH,+BAJW,WAAW,GAAC,UAAU,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAC,GAAG,CAAC,EAAE,CAAC,CAWzC"}
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Adapted from: https://github.com/vega/vega-loader-parquet/blob/main/src/index.js
3
+ */
4
+
5
+ /**
6
+ * @returns {Promise<typeof import("./parquetRead.js").parquetReadObjects>}
7
+ */
8
+ async function loadParquetReadObjects() {
9
+ const { parquetReadObjects } = await import("./parquetRead.js");
10
+ return parquetReadObjects;
11
+ }
12
+
13
+ /**
14
+ * Load a data set in Apache Parquet format for use in Vega.
15
+ * @param {ArrayBuffer|Uint8Array} data Parquet binary data.
16
+ * @returns {Promise<Record<string,any>[]>} A promise that resolves to an array of data objects representing
17
+ * rows of a data table.
18
+ */
19
+ export default async function parquet(data) {
20
+ const parquetReadObjects = await loadParquetReadObjects();
21
+ const buffer =
22
+ data instanceof Uint8Array
23
+ ? /** @type {ArrayBuffer} */ (data.buffer)
24
+ : data;
25
+
26
+ return await parquetReadObjects({ file: buffer });
27
+ }
28
+
29
+ parquet.responseType = "arrayBuffer";
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @param {ObjectParquetReadOptions} options
3
+ * @returns {Promise<void>}
4
+ */
5
+ export function parquetRead(options: ObjectParquetReadOptions): Promise<void>;
6
+ /**
7
+ * @param {Omit<ObjectParquetReadOptions, "onComplete">} options
8
+ * @returns {Promise<Record<string, any>[]>}
9
+ */
10
+ export function parquetReadObjects(options: Omit<ObjectParquetReadOptions, "onComplete">): Promise<Record<string, any>[]>;
11
+ /**
12
+ * Object-row variant of Parquet read options used by this trimmed reader.
13
+ */
14
+ export type ObjectParquetReadOptions = Omit<import("hyparquet").ParquetReadOptions, "rowFormat" | "filter" | "filterStrict" | "onComplete"> & {
15
+ onComplete?: (rows: Record<string, any>[]) => void;
16
+ };
17
+ export type RowGroupObjectBuilder = (groupData: Record<string, any>[], selectStart: number, selectCount: number, columnData: import("hyparquet").DecodedArray[], columnSkipped: number[]) => Record<string, any>[];
18
+ //# sourceMappingURL=parquetRead.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parquetRead.d.ts","sourceRoot":"","sources":["../../../../src/data/formats/parquetRead.js"],"names":[],"mappings":"AAqOA;;;GAGG;AACH,qCAHW,wBAAwB,GACtB,OAAO,CAAC,IAAI,CAAC,CAiFzB;AAED;;;GAGG;AACH,4CAHW,IAAI,CAAC,wBAAwB,EAAE,YAAY,CAAC,GAC1C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAS1C;;;;uCAlTY,IAAI,CAChB,OAAU,WAAW,EAAE,kBAAkB,EACzC,WAAc,GAAG,QAAQ,GAAG,cAAc,GAAG,YAAY,CACtD,GAAG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,IAAI,CAAA;CAClD;oCAIS,CACT,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAChC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,OAAO,WAAW,EAAE,YAAY,EAAE,EAC9C,aAAa,EAAE,MAAM,EAAE,KACnB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE"}
@@ -0,0 +1,326 @@
1
+ /*
2
+ * Adapted from hyparquet internals:
3
+ * https://github.com/hyparam/hyparquet (notably src/read.js and src/rowgroup.js).
4
+ *
5
+ * GenomeSpy-specific changes in this copy:
6
+ * - object-row output only (array row format removed)
7
+ * - filtering support removed
8
+ * - hot row transpose path optimized with cached codegen for typical schemas
9
+ * - fallback to interpreted row builder for very wide schemas
10
+ */
11
+
12
+ import { parquetMetadataAsync, parquetSchema } from "hyparquet/src/metadata.js";
13
+ import { parquetPlan, prefetchAsyncBuffer } from "hyparquet/src/plan.js";
14
+ import { assembleAsync, readRowGroup } from "hyparquet/src/rowgroup.js";
15
+ import { concat } from "hyparquet/src/utils.js";
16
+
17
+ /**
18
+ * Object-row variant of Parquet read options used by this trimmed reader.
19
+ *
20
+ * @typedef {Omit<
21
+ * import("hyparquet").ParquetReadOptions,
22
+ * "rowFormat" | "filter" | "filterStrict" | "onComplete"
23
+ * > & {
24
+ * onComplete?: (rows: Record<string, any>[]) => void
25
+ * }} ObjectParquetReadOptions
26
+ */
27
+
28
+ /**
29
+ * @typedef {(
30
+ * groupData: Record<string, any>[],
31
+ * selectStart: number,
32
+ * selectCount: number,
33
+ * columnData: import("hyparquet").DecodedArray[],
34
+ * columnSkipped: number[]
35
+ * ) => Record<string, any>[]} RowGroupObjectBuilder
36
+ */
37
+
38
+ /** @type {Map<string, RowGroupObjectBuilder>} */
39
+ const rowGroupObjectBuilderCache = new Map();
40
+
41
+ const MAX_CODEGEN_COLUMNS = 200;
42
+
43
+ /**
44
+ * @param {ObjectParquetReadOptions} options
45
+ * @returns {import("hyparquet").AsyncRowGroup[]}
46
+ */
47
+ function parquetReadAsync(options) {
48
+ if (!options.metadata) {
49
+ throw new Error("parquet requires metadata");
50
+ }
51
+
52
+ const plan = parquetPlan(options);
53
+ options.file = prefetchAsyncBuffer(options.file, plan);
54
+
55
+ return plan.groups.map((groupPlan) =>
56
+ readRowGroup(options, plan, groupPlan)
57
+ );
58
+ }
59
+
60
+ /**
61
+ * Flatten decoded data pages into a single decoded array.
62
+ * This local version avoids chunked slice/push overhead in hot paths.
63
+ *
64
+ * @param {import("hyparquet").DecodedArray[] | undefined} chunks
65
+ * @returns {import("hyparquet").DecodedArray}
66
+ */
67
+ function flattenColumnChunks(chunks) {
68
+ if (!chunks) {
69
+ return [];
70
+ }
71
+
72
+ if (chunks.length === 1) {
73
+ return chunks[0];
74
+ }
75
+
76
+ let totalLength = 0;
77
+ for (const chunk of chunks) {
78
+ totalLength += chunk.length;
79
+ }
80
+
81
+ const output = Array(totalLength);
82
+ let offset = 0;
83
+ for (const chunk of chunks) {
84
+ for (let i = 0; i < chunk.length; i++) {
85
+ output[offset + i] = chunk[i];
86
+ }
87
+ offset += chunk.length;
88
+ }
89
+
90
+ return output;
91
+ }
92
+
93
+ /**
94
+ * @param {string[]} columnNames
95
+ * @returns {RowGroupObjectBuilder}
96
+ */
97
+ function getRowGroupObjectBuilder(columnNames) {
98
+ // Compile one builder per column layout to keep object writes monomorphic.
99
+ const signature = columnNames.join("\u001f");
100
+ const cached = rowGroupObjectBuilderCache.get(signature);
101
+ if (cached) {
102
+ return cached;
103
+ }
104
+
105
+ const assignments = columnNames
106
+ .map(
107
+ (columnName, i) =>
108
+ JSON.stringify(columnName) +
109
+ ": columnData[" +
110
+ i +
111
+ "][row - columnSkipped[" +
112
+ i +
113
+ "]]"
114
+ )
115
+ .join(",\n");
116
+
117
+ const builder = /** @type {RowGroupObjectBuilder} */ (
118
+ new Function(
119
+ "groupData",
120
+ "selectStart",
121
+ "selectCount",
122
+ "columnData",
123
+ "columnSkipped",
124
+ // Keep generated code focused on the tight row loop only.
125
+ "for (let selectRow = 0; selectRow < selectCount; selectRow++) {\n" +
126
+ " const row = selectStart + selectRow;\n" +
127
+ " groupData[selectRow] = {\n" +
128
+ assignments +
129
+ "\n" +
130
+ " };\n" +
131
+ "}\n" +
132
+ "return groupData;"
133
+ )
134
+ );
135
+
136
+ rowGroupObjectBuilderCache.set(signature, builder);
137
+
138
+ return builder;
139
+ }
140
+
141
+ /**
142
+ * @param {Record<string, any>[]} groupData
143
+ * @param {number} selectStart
144
+ * @param {number} selectCount
145
+ * @param {string[]} columnNames
146
+ * @param {import("hyparquet").DecodedArray[]} columnData
147
+ * @param {number[]} columnSkipped
148
+ * @returns {Record<string, any>[]}
149
+ */
150
+ function buildRowsInterpreted(
151
+ groupData,
152
+ selectStart,
153
+ selectCount,
154
+ columnNames,
155
+ columnData,
156
+ columnSkipped
157
+ ) {
158
+ for (let selectRow = 0; selectRow < selectCount; selectRow++) {
159
+ const row = selectStart + selectRow;
160
+ /** @type {Record<string, any>} */
161
+ const rowData = {};
162
+ for (let i = 0; i < columnNames.length; i++) {
163
+ rowData[columnNames[i]] = columnData[i][row - columnSkipped[i]];
164
+ }
165
+ groupData[selectRow] = rowData;
166
+ }
167
+
168
+ return groupData;
169
+ }
170
+
171
+ /**
172
+ * Object-only copy of hyparquet's asyncGroupToRows.
173
+ *
174
+ * @param {import("hyparquet").AsyncRowGroup} asyncGroup
175
+ * @param {number} selectStart
176
+ * @param {number} selectEnd
177
+ * @returns {Promise<Record<string, any>[]>}
178
+ */
179
+ async function asyncGroupToRowsObject(
180
+ { asyncColumns },
181
+ selectStart,
182
+ selectEnd
183
+ ) {
184
+ // Resolve all async column pages once before entering the hot transpose loop.
185
+ const pages = await Promise.all(asyncColumns.map((column) => column.data));
186
+ const columnCount = asyncColumns.length;
187
+
188
+ /** @type {string[]} */
189
+ const columnNames = Array(columnCount);
190
+ /** @type {import("hyparquet").DecodedArray[]} */
191
+ const columnData = Array(columnCount);
192
+ /** @type {number[]} */
193
+ const columnSkipped = Array(columnCount);
194
+
195
+ // Precompute all indirections outside the generated function.
196
+ for (let i = 0; i < columnCount; i++) {
197
+ columnNames[i] = asyncColumns[i].pathInSchema[0];
198
+ columnData[i] = flattenColumnChunks(pages[i].data);
199
+ columnSkipped[i] = pages[i].skipped;
200
+ }
201
+
202
+ const selectCount = selectEnd - selectStart;
203
+
204
+ /** @type {Record<string, any>[]} */
205
+ const groupData = Array(selectCount);
206
+
207
+ // Avoid excessively large generated functions for very wide schemas.
208
+ if (columnCount > MAX_CODEGEN_COLUMNS) {
209
+ return buildRowsInterpreted(
210
+ groupData,
211
+ selectStart,
212
+ selectCount,
213
+ columnNames,
214
+ columnData,
215
+ columnSkipped
216
+ );
217
+ }
218
+
219
+ const buildRows = getRowGroupObjectBuilder(columnNames);
220
+
221
+ return buildRows(
222
+ groupData,
223
+ selectStart,
224
+ selectCount,
225
+ columnData,
226
+ columnSkipped
227
+ );
228
+ }
229
+
230
+ /**
231
+ * @param {ObjectParquetReadOptions} options
232
+ * @returns {Promise<void>}
233
+ */
234
+ export async function parquetRead(options) {
235
+ if ("rowFormat" in options) {
236
+ throw new Error(
237
+ 'parquetRead supports only object rows; use rowFormat: "object" implicitly'
238
+ );
239
+ }
240
+ if ("filter" in options || "filterStrict" in options) {
241
+ throw new Error("parquetRead does not support filtering");
242
+ }
243
+
244
+ options.metadata ??= await parquetMetadataAsync(options.file, options);
245
+
246
+ const { rowStart = 0, rowEnd, onChunk, onComplete } = options;
247
+
248
+ const asyncGroups = parquetReadAsync(options);
249
+
250
+ if (!onComplete && !onChunk) {
251
+ for (const { asyncColumns } of asyncGroups) {
252
+ for (const { data } of asyncColumns) {
253
+ await data;
254
+ }
255
+ }
256
+ return;
257
+ }
258
+
259
+ const schemaTree = parquetSchema(options.metadata);
260
+ const assembled = asyncGroups.map((group) =>
261
+ assembleAsync(group, schemaTree, options.parsers)
262
+ );
263
+
264
+ if (onChunk) {
265
+ for (const asyncGroup of assembled) {
266
+ for (const asyncColumn of asyncGroup.asyncColumns) {
267
+ asyncColumn.data.then(
268
+ /**
269
+ * @param {{ data: import("hyparquet").DecodedArray[]; skipped: number }} chunk
270
+ */
271
+ (chunk) => {
272
+ let chunkRowStart =
273
+ asyncGroup.groupStart + chunk.skipped;
274
+ for (const columnData of chunk.data) {
275
+ onChunk({
276
+ columnName: asyncColumn.pathInSchema[0],
277
+ columnData,
278
+ rowStart: chunkRowStart,
279
+ rowEnd: chunkRowStart + columnData.length,
280
+ });
281
+ chunkRowStart += columnData.length;
282
+ }
283
+ }
284
+ );
285
+ }
286
+ }
287
+ }
288
+
289
+ if (onComplete) {
290
+ /** @type {Record<string, any>[]} */
291
+ const rows = [];
292
+ for (const asyncGroup of assembled) {
293
+ const selectStart = Math.max(rowStart - asyncGroup.groupStart, 0);
294
+ const selectEnd = Math.min(
295
+ (rowEnd ?? Infinity) - asyncGroup.groupStart,
296
+ asyncGroup.groupRows
297
+ );
298
+ const groupData = await asyncGroupToRowsObject(
299
+ asyncGroup,
300
+ selectStart,
301
+ selectEnd
302
+ );
303
+ concat(rows, groupData);
304
+ }
305
+ onComplete(rows);
306
+ } else {
307
+ for (const { asyncColumns } of assembled) {
308
+ for (const { data } of asyncColumns) {
309
+ await data;
310
+ }
311
+ }
312
+ }
313
+ }
314
+
315
+ /**
316
+ * @param {Omit<ObjectParquetReadOptions, "onComplete">} options
317
+ * @returns {Promise<Record<string, any>[]>}
318
+ */
319
+ export function parquetReadObjects(options) {
320
+ return new Promise((onComplete, reject) => {
321
+ parquetRead({
322
+ ...options,
323
+ onComplete,
324
+ }).catch(reject);
325
+ });
326
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"urlSource.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/urlSource.js"],"names":[],"mappings":"AASA;;;GAGG;AACH,gCAHW,OAAO,CAAC,OAAO,oBAAoB,EAAE,IAAI,CAAC,GACxC,IAAI,IAAI,OAAO,oBAAoB,EAAE,OAAO,CAIxD;AAED;IACI;;;OAGG;IACH,oBAHW,OAAO,oBAAoB,EAAE,OAAO,QACpC,OAAO,oBAAoB,EAAE,OAAO,EAc9C;IATG,6CAMC;IAED,gBAAiC;;CAuGxC;uBAtIsB,iBAAiB"}
1
+ {"version":3,"file":"urlSource.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/urlSource.js"],"names":[],"mappings":"AASA;;;GAGG;AACH,gCAHW,OAAO,CAAC,OAAO,oBAAoB,EAAE,IAAI,CAAC,GACxC,IAAI,IAAI,OAAO,oBAAoB,EAAE,OAAO,CAIxD;AAED;IACI;;;OAGG;IACH,oBAHW,OAAO,oBAAoB,EAAE,OAAO,QACpC,OAAO,oBAAoB,EAAE,OAAO,EAc9C;IATG,6CAMC;IAED,gBAAiC;;CA4GxC;uBA3IsB,iBAAiB"}
@@ -110,15 +110,20 @@ export default class UrlSource extends DataSource {
110
110
  * @param {any} content
111
111
  * @param {string} [url]
112
112
  */
113
- const readAndParse = (content, url) => {
113
+ const readAndParse = async (content, url) => {
114
114
  try {
115
- /** @type {any[]} */
116
- const data = read(content, format);
115
+ /** @type {any[] | Promise<any[]>} */
116
+ const dataOrPromise = read(content, format);
117
+ const data =
118
+ dataOrPromise instanceof Promise
119
+ ? await dataOrPromise
120
+ : dataOrPromise;
117
121
  this.beginBatch({ type: "file", url: url });
118
122
  for (const d of data) {
119
123
  this._propagate(d);
120
124
  }
121
125
  } catch (e) {
126
+ console.warn(e);
122
127
  throw new Error(`Cannot parse: ${url}: ${e.message}`);
123
128
  }
124
129
  };
@@ -54,12 +54,12 @@ export function isChannelDefWithScale(channelDef: import("../spec/channel.js").C
54
54
  /**
55
55
  * @param {import("../spec/channel.js").ChannelDef} channelDef
56
56
  */
57
- export function findChannelDefWithScale(channelDef: import("../spec/channel.js").ChannelDef): import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, string> | import("../spec/channel.js").PositionFieldDef | import("../spec/channel.js").PositionDatumDef | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, number> | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").FieldDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").DatumDef<import("../spec/parameter.js").ExprRef | import("../spec/channel.js").Scalar> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").DomainContributionMixins) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").ValueDefBase<string | import("../spec/parameter.js").ExprRef> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").DomainContributionMixins) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").ValueDefBase<number | import("../spec/parameter.js").ExprRef> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").DomainContributionMixins);
57
+ export function findChannelDefWithScale(channelDef: import("../spec/channel.js").ChannelDef): import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, string> | import("../spec/channel.js").PositionFieldDef | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").PositionDatumDef | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, number> | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").ValueDefBase<string | import("../spec/parameter.js").ExprRef> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").DomainContributionMixins) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").ValueDefBase<number | import("../spec/parameter.js").ExprRef> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").DomainContributionMixins) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").FieldDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").DatumDef<import("../spec/parameter.js").ExprRef | import("../spec/channel.js").Scalar> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").DomainContributionMixins);
58
58
  /**
59
59
  * @param {import("../view/unitView.js").default} view
60
60
  * @param {import("../spec/channel.js").Channel} channel
61
61
  */
62
- export function getChannelDefWithScale(view: import("../view/unitView.js").default, channel: import("../spec/channel.js").Channel): import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, string> | import("../spec/channel.js").PositionFieldDef | import("../spec/channel.js").PositionDatumDef | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, number> | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").TypeForShape>, string> | (import("../spec/channel.js").FieldDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | (import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").DatumDef<import("../spec/parameter.js").ExprRef | import("../spec/channel.js").Scalar> & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | (import("../spec/channel.js").ChromPosDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").TypeMixins<"locus"> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").XIndexDef);
62
+ export function getChannelDefWithScale(view: import("../view/unitView.js").default, channel: import("../spec/channel.js").Channel): import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, string> | import("../spec/channel.js").PositionFieldDef | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").PositionDatumDef | (import("../spec/channel.js").FieldDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | (import("../spec/channel.js").ChromPosDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").TypeMixins<"locus"> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").XIndexDef) | (import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").DatumDef<import("../spec/parameter.js").ExprRef | import("../spec/channel.js").Scalar> & import("../spec/channel.js").DomainContributionMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type> & import("../spec/channel.js").PositionMixins & import("../spec/channel.js").XIndexDef) | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, number> | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").TypeForShape>, string>;
63
63
  /**
64
64
  * @param {import("../spec/channel.js").ChannelDef} channelDef
65
65
  * @returns {channelDef is import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>}
@@ -51,7 +51,7 @@ export default class BmFontManager {
51
51
  * @param {FontWeight | keyof WEIGHTS} weight
52
52
  * @returns {FontEntry}
53
53
  */
54
- getFont(family: string, style?: FontStyle, weight?: FontWeight | ("bold" | "normal" | "medium" | "thin" | "light" | "regular" | "black")): FontEntry;
54
+ getFont(family: string, style?: FontStyle, weight?: FontWeight | ("bold" | "normal" | "thin" | "light" | "regular" | "medium" | "black")): FontEntry;
55
55
  /**
56
56
  *
57
57
  * @param {FontEntry} fontEntry An uninitialized font entry
@@ -60,9 +60,9 @@ export default class Genome {
60
60
  */
61
61
  constructor(config: GenomeConfig);
62
62
  config: {
63
+ url: string;
63
64
  name: string;
64
65
  } | {
65
- url: string;
66
66
  name: string;
67
67
  } | {
68
68
  contigs: import("../spec/genome.js").Contig[];
@@ -1 +1 @@
1
- {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"AA+CA;IAoBI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA0CpD;IAvCG,uBAA0B;IAC1B,oDAAsB;IAItB,sCAAsC;IACtC,wCAAgB;IAEhB,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,CAAC,CAAS,IAAM,EAAN,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,yBAFU,CAAC,IAAI,qEAAM,KAAK,OAAO,CAE8B;IAE/D,oFAAoF;IACpF,iBADW,MAAM,CAAC,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,8EAAyB;IAIzB,YAAkC;IAatC;;;OAGG;IACH,oCAFW,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAYf;IAED;;;OAGG;IACH,uBAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;OAGG;IACH,0BAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAMb;IA8DG,iDAAsB;IAQ1B;;OAEG;IACH,gBAqBC;IA+KD;;;OAGG;IACH,UAFa,OAAO,CAAC,OAAO,CAAC,CAyC5B;IAED,2CAiBC;IAED,4BAEC;IAED;;;;;;;OAOG;IACH,cAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAKlF;IAED;;;;;;;;OAQG;IACH,4BANW,MAAM,kBACN,MAAM,qBACN,MAAM,eACN,MAAM,UAuBhB;IAED;;;MAEC;IAED,sBAEC;IAED,kBAEC;IAED,iCAEC;IAED,oEAYC;IAED,uFAWC;;CACJ;;;;iCA/jBY,eAAe,GAAG,QAAQ,GAAG,gBAAgB,GAAG,kBAAkB;4BAbnC,uBAAuB;qBAR9C,qBAAqB;wBAElB,yBAAyB;qBAL5B,oBAAoB"}
1
+ {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"AAiDA;IAoBI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA0CpD;IAvCG,uBAA0B;IAC1B,oDAAsB;IAItB,sCAAsC;IACtC,wCAAgB;IAEhB,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,CAAC,CAAS,IAAM,EAAN,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,yBAFU,CAAC,IAAI,qEAAM,KAAK,OAAO,CAE8B;IAE/D,oFAAoF;IACpF,iBADW,MAAM,CAAC,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,8EAAyB;IAIzB,YAAkC;IAatC;;;OAGG;IACH,oCAFW,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAYf;IAED;;;OAGG;IACH,uBAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;OAGG;IACH,0BAHW,MAAM,YACN,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,QAI9B;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAMb;IA8DG,iDAAsB;IAQ1B;;OAEG;IACH,gBAqBC;IA+KD;;;OAGG;IACH,UAFa,OAAO,CAAC,OAAO,CAAC,CAyC5B;IAED,2CAiBC;IAED,4BAEC;IAED;;;;;;;OAOG;IACH,cAFa,CAAC,SAFH,CAAC,cACD,CAAS,IAAC,EAAD,CAAC,KAAE,OAAO,CAAC,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAKlF;IAED;;;;;;;;OAQG;IACH,4BANW,MAAM,kBACN,MAAM,qBACN,MAAM,eACN,MAAM,UAuBhB;IAED;;;MAEC;IAED,sBAEC;IAED,kBAEC;IAED,iCAEC;IAED,oEAYC;IAED,uFAWC;;CACJ;;;;iCAhkBY,eAAe,GAAG,QAAQ,GAAG,gBAAgB,GAAG,kBAAkB;4BAdnC,uBAAuB;qBAR9C,qBAAqB;wBAElB,yBAAyB;qBAL5B,oBAAoB"}
@@ -37,6 +37,7 @@ import {
37
37
  } from "./genomeSpy/viewHierarchyConfig.js";
38
38
  import { exportCanvas } from "./genomeSpy/canvasExport.js";
39
39
  import { validateSelectorConstraints } from "./view/viewSelectors.js";
40
+ import parquet from "./data/formats/parquet.js";
40
41
 
41
42
  /**
42
43
  * Events that are broadcasted to all views.
@@ -44,6 +45,7 @@ import { validateSelectorConstraints } from "./view/viewSelectors.js";
44
45
  */
45
46
 
46
47
  vegaFormats("fasta", fasta);
48
+ vegaFormats("parquet", parquet);
47
49
 
48
50
  export default class GenomeSpy {
49
51
  /** @type {(() => void)[]} */
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Build-time options for sizing the hash table.
3
+ *
4
+ * @typedef {object} HashTableBuildOptions
5
+ * @property {number} [capacity] Power-of-two table size override.
6
+ * @property {number} [maxLoadFactor] Maximum load factor before resizing.
7
+ */
8
+ /**
9
+ * Packed table payload ready for WebGL texture upload.
10
+ *
11
+ * @typedef {object} HashTableBuildResult
12
+ * @property {Uint32Array} table Hash table slots that contain keys.
13
+ * @property {number} capacity Table capacity (number of slots).
14
+ * @property {number} size Number of stored keys.
15
+ */
16
+ /**
17
+ * 32-bit integer hash for u32 keys. Keep in sync with GLSL hash32.
18
+ *
19
+ * @param {number} value
20
+ * @returns {number}
21
+ */
22
+ export function hash32(value: number): number;
23
+ /**
24
+ * Build a hash table for set membership checks.
25
+ *
26
+ * @param {Iterable<number>} keys
27
+ * @param {HashTableBuildOptions} [options]
28
+ * @returns {HashTableBuildResult}
29
+ */
30
+ export function buildHashTableSet(keys: Iterable<number>, options?: HashTableBuildOptions): HashTableBuildResult;
31
+ /**
32
+ * Computes a 2D texture layout for a power-of-two hash table capacity.
33
+ *
34
+ * The returned dimensions satisfy `width * height === capacity`.
35
+ *
36
+ * @param {number} capacity
37
+ * @param {number} maxTextureSize
38
+ * @returns {{ width: number, height: number }}
39
+ */
40
+ export function computeHashTextureDimensions(capacity: number, maxTextureSize: number): {
41
+ width: number;
42
+ height: number;
43
+ };
44
+ /** Sentinel key that marks an empty hash slot. */
45
+ export const HASH_EMPTY_KEY: 4294967295;
46
+ /** Default maximum load factor for table sizing. */
47
+ export const DEFAULT_MAX_LOAD_FACTOR: 0.6;
48
+ /**
49
+ * Build-time options for sizing the hash table.
50
+ */
51
+ export type HashTableBuildOptions = {
52
+ /**
53
+ * Power-of-two table size override.
54
+ */
55
+ capacity?: number;
56
+ /**
57
+ * Maximum load factor before resizing.
58
+ */
59
+ maxLoadFactor?: number;
60
+ };
61
+ /**
62
+ * Packed table payload ready for WebGL texture upload.
63
+ */
64
+ export type HashTableBuildResult = {
65
+ /**
66
+ * Hash table slots that contain keys.
67
+ */
68
+ table: Uint32Array;
69
+ /**
70
+ * Table capacity (number of slots).
71
+ */
72
+ capacity: number;
73
+ /**
74
+ * Number of stored keys.
75
+ */
76
+ size: number;
77
+ };
78
+ //# sourceMappingURL=hashTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hashTable.d.ts","sourceRoot":"","sources":["../../../src/gl/hashTable.js"],"names":[],"mappings":"AAQA;;;;;;GAMG;AAEH;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,8BAHW,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;GAMG;AACH,wCAJW,QAAQ,CAAC,MAAM,CAAC,YAChB,qBAAqB,GACnB,oBAAoB,CAkDhC;AAED;;;;;;;;GAQG;AACH,uDAJW,MAAM,kBACN,MAAM,GACJ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CA+B7C;AAxID,kDAAkD;AAClD,6BAA8B,UAAW,CAAC;AAE1C,oDAAoD;AACpD,sCAAuC,GAAG,CAAC;;;;;;;;eAQ7B,MAAM;;;;oBACN,MAAM;;;;;;;;;WAON,WAAW;;;;cACX,MAAM;;;;UACN,MAAM"}