@gmod/bed 2.0.6 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +11 -6
  3. package/dist/as/autoSqlSchemas.d.ts +10 -0
  4. package/dist/as/autoSqlSchemas.js +12 -24
  5. package/dist/as/autoSqlSchemas.js.map +1 -0
  6. package/dist/autoSql.d.ts +14 -0
  7. package/dist/autoSql.js +1344 -1629
  8. package/dist/autoSql.js.map +1 -0
  9. package/dist/defaultTypes.d.ts +5 -0
  10. package/dist/defaultTypes.js +32 -35
  11. package/dist/defaultTypes.js.map +1 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +7 -12
  14. package/dist/index.js.map +1 -0
  15. package/dist/parser.d.ts +13 -0
  16. package/dist/parser.js +90 -140
  17. package/dist/parser.js.map +1 -0
  18. package/dist/util.d.ts +18 -0
  19. package/dist/util.js +18 -34
  20. package/dist/util.js.map +1 -0
  21. package/esm/as/autoSqlSchemas.d.ts +10 -0
  22. package/esm/as/autoSqlSchemas.js +170 -0
  23. package/esm/as/autoSqlSchemas.js.map +1 -0
  24. package/esm/autoSql.d.ts +14 -0
  25. package/esm/autoSql.js +1515 -0
  26. package/esm/autoSql.js.map +1 -0
  27. package/esm/defaultTypes.d.ts +5 -0
  28. package/esm/defaultTypes.js +7 -0
  29. package/esm/defaultTypes.js.map +1 -0
  30. package/esm/index.d.ts +2 -0
  31. package/esm/index.js +3 -0
  32. package/esm/index.js.map +1 -0
  33. package/esm/parser.d.ts +13 -0
  34. package/esm/parser.js +89 -0
  35. package/esm/parser.js.map +1 -0
  36. package/esm/util.d.ts +18 -0
  37. package/esm/util.js +22 -0
  38. package/esm/util.js.map +1 -0
  39. package/package.json +22 -18
  40. package/src/as/README.md +7 -0
  41. package/src/as/autoSqlSchemas.ts +176 -0
  42. package/src/autoSql.js +1501 -0
  43. package/src/defaultTypes.ts +10 -0
  44. package/src/index.ts +3 -0
  45. package/src/parser.ts +99 -0
  46. package/src/util.ts +27 -0
@@ -0,0 +1,10 @@
1
+ import { parse } from './autoSql'
2
+ import { AutoSqlPreSchema } from './util'
3
+ import * as types from './as/autoSqlSchemas'
4
+
5
+ export default Object.fromEntries(
6
+ Object.entries(types).map(([key, val]) => [
7
+ key,
8
+ parse(val.trim()) as AutoSqlPreSchema,
9
+ ]),
10
+ )
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ import BED from './parser'
2
+
3
+ export default BED
package/src/parser.ts ADDED
@@ -0,0 +1,99 @@
1
+ import parser from './autoSql'
2
+ import types from './defaultTypes'
3
+ import { detectTypes, AutoSqlSchema, AutoSqlPreSchema } from './util'
4
+
5
+ const strandMap = { '.': 0, '-': -1, '+': 1 }
6
+
7
+ // heuristic that a BED file is BED12 like...the number in col 10 is blockCount-like
8
+ function isBed12Like(fields: string[]) {
9
+ return (
10
+ fields.length >= 12 &&
11
+ !Number.isNaN(parseInt(fields[9], 10)) &&
12
+ fields[10]?.split(',').filter(f => !!f).length === parseInt(fields[9], 10)
13
+ )
14
+ }
15
+ export default class BED {
16
+ private autoSql: AutoSqlSchema
17
+
18
+ private attemptDefaultBed?: boolean
19
+
20
+ constructor(args: { autoSql?: string; type?: string } = {}) {
21
+ if (args.autoSql) {
22
+ this.autoSql = detectTypes(parser.parse(args.autoSql) as AutoSqlPreSchema)
23
+ } else if (args.type) {
24
+ if (!types[args.type]) {
25
+ throw new Error('Type not found')
26
+ }
27
+ this.autoSql = detectTypes(types[args.type])
28
+ } else {
29
+ this.autoSql = detectTypes(types.defaultBedSchema)
30
+ this.attemptDefaultBed = true
31
+ }
32
+ }
33
+
34
+ /*
35
+ * parses a line of text as a BED line with the loaded autoSql schema
36
+ *
37
+ * @param line - a BED line as tab delimited text or array
38
+ * @param opts - supply opts.uniqueId
39
+ * @return a object representing a feature
40
+ */
41
+ parseLine(line: string | string[], opts: { uniqueId?: string } = {}) {
42
+ const { autoSql } = this
43
+ const { uniqueId } = opts
44
+ const fields = Array.isArray(line) ? line : line.split('\t')
45
+
46
+ let feature = {} as { [key: string]: any }
47
+ if (
48
+ !this.attemptDefaultBed ||
49
+ (this.attemptDefaultBed && isBed12Like(fields))
50
+ ) {
51
+ for (let i = 0; i < autoSql.fields.length; i++) {
52
+ const autoField = autoSql.fields[i]
53
+ let columnVal: any = fields[i]
54
+ const { isNumeric, isArray, arrayIsNumeric, name } = autoField
55
+ if (columnVal === null || columnVal === undefined) {
56
+ break
57
+ }
58
+ if (columnVal !== '.') {
59
+ if (isNumeric) {
60
+ const num = Number(columnVal)
61
+ columnVal = Number.isNaN(num) ? columnVal : num
62
+ } else if (isArray) {
63
+ columnVal = columnVal.split(',')
64
+ if (columnVal[columnVal.length - 1] === '') {
65
+ columnVal.pop()
66
+ }
67
+ if (arrayIsNumeric) {
68
+ columnVal = columnVal.map((str: string) => Number(str))
69
+ }
70
+ }
71
+
72
+ feature[name] = columnVal
73
+ }
74
+ }
75
+ } else {
76
+ const fieldNames = ['chrom', 'chromStart', 'chromEnd', 'name']
77
+ feature = Object.fromEntries(
78
+ fields.map((f, i) => [fieldNames[i] || 'field' + i, f]),
79
+ )
80
+ feature.chromStart = +feature.chromStart
81
+ feature.chromEnd = +feature.chromEnd
82
+ if (!Number.isNaN(Number.parseFloat(feature.field4))) {
83
+ feature.score = +feature.field4
84
+ delete feature.field4
85
+ }
86
+ if (feature.field5 === '+' || feature.field5 === '-') {
87
+ feature.strand = feature.field5
88
+ delete feature.field5
89
+ }
90
+ }
91
+ if (uniqueId) {
92
+ feature.uniqueId = uniqueId
93
+ }
94
+ feature.strand = strandMap[feature.strand as keyof typeof strandMap] || 0
95
+
96
+ feature.chrom = decodeURIComponent(feature.chrom)
97
+ return feature
98
+ }
99
+ }
package/src/util.ts ADDED
@@ -0,0 +1,27 @@
1
+ export interface AutoSqlPreSchema {
2
+ fields: { size: number; type: string; name: string }[]
3
+ }
4
+
5
+ /*
6
+ * adds some type annotations to the autoSql schema
7
+ * for numeric fields ['uint', 'int', 'float', 'long'] "isNumeric" is added
8
+ * for array types "isArray" is added
9
+ * for numeric array types "isArray" and "arrayIsNumeric" is set
10
+ *
11
+ * @param autoSql - an autoSql schema from the peg parser
12
+ * @return autoSql with type annotations added
13
+ */
14
+ export function detectTypes(autoSql: AutoSqlPreSchema) {
15
+ const numericTypes = ['uint', 'int', 'float', 'long']
16
+ return {
17
+ ...autoSql,
18
+ fields: autoSql.fields.map(autoField => ({
19
+ ...autoField,
20
+ isArray: autoField.size && autoField.type !== 'char',
21
+ arrayIsNumeric: autoField.size && numericTypes.includes(autoField.type),
22
+ isNumeric: !autoField.size && numericTypes.includes(autoField.type),
23
+ })),
24
+ }
25
+ }
26
+
27
+ export type AutoSqlSchema = ReturnType<typeof detectTypes>