@sjcrh/proteinpaint-shared 2.177.0 → 2.178.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjcrh/proteinpaint-shared",
3
- "version": "2.177.0",
3
+ "version": "2.178.0",
4
4
  "description": "ProteinPaint code that is shared between server and client-side workspaces",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/common.js CHANGED
@@ -22,10 +22,12 @@ export const TermTypeGroups = {
22
22
  GENE_EXPRESSION: 'Gene Expression',
23
23
  GSEA: 'GSEA',
24
24
  METABOLITE_INTENSITY: 'Metabolite Intensity',
25
+ WHOLE_PROTEOME_ABUNDANCE: 'Whole Proteome Abundance',
25
26
  MUTATION_CNV_FUSION: 'Mutation/CNV/Fusion',
26
27
  MUTATION_SIGNATURE: 'Mutation Signature',
27
28
  PROTEIN_EXPRESSION: 'Protein Expression',
28
29
  SINGLECELL_CELLTYPE: 'Single-cell Cell Type',
30
+ SINGLECELL_GENE_EXPRESSION: 'Single-cell Gene Expression',
29
31
  SNP: 'SNP Genotype',
30
32
  SNP_LIST: 'SNP List',
31
33
  SNP_LOCUS: 'SNP Locus',
@@ -65,6 +67,8 @@ export const dtcloss = 9
65
67
  export const dtloh = 10
66
68
  export const dtmetaboliteintensity = 11
67
69
  export const dtssgsea = 12
70
+ export const dtdnamethylation = 13
71
+ export const dtwholeproteomeabundance = 14
68
72
  // add new dt value here. !!!DO NOT change value of existing dt!!!
69
73
 
70
74
  export const dt2label = {
@@ -78,7 +82,8 @@ export const dt2label = {
78
82
  [dtcloss]: 'C-loss',
79
83
  [dtloh]: 'LOH',
80
84
  [dtgeneexpression]: 'Gene Expression',
81
- [dtmetaboliteintensity]: 'Metabolite Intensity'
85
+ [dtmetaboliteintensity]: 'Metabolite Intensity',
86
+ [dtwholeproteomeabundance]: 'Whole Proteome Abundance'
82
87
  }
83
88
 
84
89
  // Maps dt types to UI labels and lesion types for GRIN2
@@ -9,7 +9,9 @@ import { deepFreeze } from './helpers.js'
9
9
  - this addresses issues with ky.json() or got.json(), where a HTTP 404 NOT FOUND
10
10
  response with text/html can break error handling/logging, making it harder to debug
11
11
 
12
- - this also automatically handles multipart responses
12
+ - this also automatically handles multipart responses
13
+
14
+ - NOTE: for backend, use xfetch() instead, it uses ky() and its built-in retry support
13
15
 
14
16
  arguments:
15
17
  url
@@ -221,22 +223,27 @@ export async function memFetch(url, init, opts = {}) {
221
223
  dataCache.set(dataKey, { response, exp: Date.now() + cacheLifetime })
222
224
  return response
223
225
  })
224
- : fetch(url, init).then(async r => {
225
- const response = await processResponse(r)
226
- if (!r.ok) {
227
- console.trace(response)
228
- throw (
229
- 'memFetch error ' +
230
- r.status +
231
- ': ' +
232
- (typeof response == 'object' ? response.message || response.error : response)
233
- )
234
- }
235
- // replace the cached promise result with the actual data,
236
- // since persisting a cached promise for a long time is likely not best practice
237
- dataCache.set(dataKey, { response: deepFreeze(response), exp: Date.now() + cacheLifetime })
238
- return response
239
- })
226
+ : fetch(url, init)
227
+ .then(async r => {
228
+ const response = await processResponse(r)
229
+ if (!r.ok) {
230
+ console.trace(response)
231
+ throw (
232
+ 'memFetch error ' +
233
+ r.status +
234
+ ': ' +
235
+ (typeof response == 'object' ? response.message || response.error : response)
236
+ )
237
+ }
238
+ // replace the cached promise result with the actual data,
239
+ // since persisting a cached promise for a long time is likely not best practice
240
+ dataCache.set(dataKey, { response: deepFreeze(response), exp: Date.now() + cacheLifetime })
241
+ return response
242
+ })
243
+ .catch(e => {
244
+ if (dataCache.get(dataKey)) dataCache.delete(dataKey)
245
+ throw e
246
+ })
240
247
 
241
248
  dataCache.set(dataKey, { response: result, exp: Date.now() + cacheLifetime })
242
249
  manageCacheSize(now)
@@ -244,7 +251,7 @@ export async function memFetch(url, init, opts = {}) {
244
251
  } catch (e) {
245
252
  // delete this cache only if it is a promise;
246
253
  // do not delete a valid resolved data cache
247
- if (dataCache.get(dataKey) instanceof Promise) delete dataCache.delete(dataKey)
254
+ if (dataCache.get(dataKey) instanceof Promise) dataCache.delete(dataKey)
248
255
  throw e
249
256
  }
250
257
  }
@@ -17,7 +17,9 @@ export const graphableTypes = new Set([
17
17
  'dtsv',
18
18
  'date',
19
19
  TermTypes.SSGSEA,
20
+ TermTypes.DNA_METHYLATION,
20
21
  TermTypes.METABOLITE_INTENSITY,
22
+ TermTypes.WHOLE_PROTEOME_ABUNDANCE,
21
23
  TermTypes.SINGLECELL_GENE_EXPRESSION,
22
24
  TermTypes.SINGLECELL_CELLTYPE,
23
25
  TermTypes.SNP,
@@ -66,8 +68,8 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
66
68
  const usecase = _usecase || {}
67
69
 
68
70
  // may apply dataset specific override filter for a use case
69
- if (typeof ds?.usecase?.[use.target] == 'function') {
70
- return ds.usecase[use.target](term, use)
71
+ if (typeof ds?.usecase?.[usecase.target] == 'function') {
72
+ return ds.usecase[usecase.target](term, usecase)
71
73
  }
72
74
 
73
75
  // if (term.isprivate && !user.roleCanUse(term)) return false
@@ -75,10 +77,11 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
75
77
  const uses = new Set()
76
78
  // note: expects term.child_types to be null if term.isleaf == true
77
79
  const child_types = term.child_types || []
78
-
79
80
  // default handling
80
81
  switch (usecase.target) {
81
82
  case 'barchart':
83
+ case 'violin':
84
+ case 'boxplot':
82
85
  case 'summary':
83
86
  if (term.type && term.type !== 'survival') uses.add('plot')
84
87
  if (hasAllowedChildTypes(child_types, ['survival'])) uses.add('branch')
@@ -89,6 +92,10 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
89
92
  if (term.type && term.type !== 'survival') uses.add('plot')
90
93
  if (hasAllowedChildTypes(child_types, ['survival'])) uses.add('branch')
91
94
  return uses
95
+ } else {
96
+ if (graphableTypes.has(term.type)) uses.add('plot')
97
+ if (!term.isleaf) uses.add('branch')
98
+ return uses
92
99
  }
93
100
 
94
101
  case 'matrix':
@@ -107,6 +114,13 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
107
114
  uses.add('plot')
108
115
  }
109
116
  if (hasNumericChild(child_types)) uses.add('branch')
117
+ } else if (usecase?.vocab?.type == 'singleCell') {
118
+ /** TODO: Revisit this approach. Seems chaotic. */
119
+ if (term.type && term.type.startsWith('singleCell')) {
120
+ if (term.plot && term.plot == usecase.vocab?.config.name) {
121
+ uses.add('plot')
122
+ }
123
+ }
110
124
  } else {
111
125
  if (graphableTypes.has(term.type)) uses.add('plot')
112
126
  if (!term.isleaf) uses.add('branch')
@@ -139,7 +153,7 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
139
153
  }
140
154
  return uses
141
155
 
142
- case 'numericTermCollections':
156
+ case 'termCollections':
143
157
  if (usecase.detail?.termIds?.includes(term.id)) uses.add('plot')
144
158
  if (usecase.detail?.branchIds?.includes(term.id)) uses.add('branch')
145
159
  return uses
@@ -170,6 +184,7 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
170
184
  if (hasAllowedChildTypes(child_types, ['condition', 'survival'])) uses.add('branch')
171
185
  return uses
172
186
  }
187
+ return uses
173
188
 
174
189
  case 'survival':
175
190
  if (usecase.detail == 'term') {
@@ -182,6 +197,7 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
182
197
  if (hasAllowedChildTypes(child_types, ['survival'])) uses.add('branch')
183
198
  return uses
184
199
  }
200
+ return uses
185
201
 
186
202
  case 'regression':
187
203
  if (usecase.detail == 'outcome') {
@@ -207,8 +223,9 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
207
223
  if (hasChildTypes(child_types, ['categorical', 'float', 'integer'])) uses.add('branch')
208
224
  return uses
209
225
  }
226
+ return uses
210
227
 
211
- case 'filter':
228
+ case 'filter': {
212
229
  // apply "exlst" to other targets as needed
213
230
  const exlst = termdbConfig?.excludedTermtypeByTarget?.filter
214
231
  if (exlst) {
@@ -216,7 +233,11 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
216
233
  if (child_types.find(t => !exlst.includes(t))) uses.add('branch') // there's a non-excluded child type, allow branch to show
217
234
  return uses
218
235
  }
219
- // no specific rule for filter. pass and use default rules
236
+ // no specific rule for filter. use default rules
237
+ if (graphableTypes.has(term.type)) uses.add('plot')
238
+ if (!term.isleaf) uses.add('branch')
239
+ return uses
240
+ }
220
241
 
221
242
  case 'correlationVolcano':
222
243
  if (usecase.detail == 'numeric') {
package/src/terms.js CHANGED
@@ -1,4 +1,12 @@
1
- import { dtgeneexpression, dtssgsea, dtmetaboliteintensity, TermTypeGroups, dtTerms } from './common.js'
1
+ import {
2
+ dtgeneexpression,
3
+ dtssgsea,
4
+ dtdnamethylation,
5
+ dtmetaboliteintensity,
6
+ dtwholeproteomeabundance,
7
+ TermTypeGroups,
8
+ dtTerms
9
+ } from './common.js'
2
10
 
3
11
  // moved TermTypeGroups to `server/src/common.js`, so now has to re-export
4
12
  export { TermTypeGroups } from './common.js'
@@ -26,6 +34,7 @@ export const TermTypes = {
26
34
  GENE_VARIANT: 'geneVariant',
27
35
  GENE_EXPRESSION: 'geneExpression',
28
36
  SSGSEA: 'ssGSEA',
37
+ DNA_METHYLATION: 'dnaMethylation',
29
38
  CATEGORICAL: 'categorical',
30
39
  INTEGER: 'integer',
31
40
  FLOAT: 'float',
@@ -36,6 +45,7 @@ export const TermTypes = {
36
45
  SURVIVAL: 'survival',
37
46
  SAMPLELST: 'samplelst',
38
47
  METABOLITE_INTENSITY: 'metaboliteIntensity',
48
+ WHOLE_PROTEOME_ABUNDANCE: 'wholeProteomeAbundance',
39
49
  SINGLECELL_GENE_EXPRESSION: 'singleCellGeneExpression',
40
50
  SINGLECELL_CELLTYPE: 'singleCellCellType',
41
51
  MULTIVALUE: 'multivalue',
@@ -52,7 +62,9 @@ export const NUMERIC_DICTIONARY_TERM = 'numericDictTerm'
52
62
  export const TermTypes2Dt = {
53
63
  [TermTypes.GENE_EXPRESSION]: dtgeneexpression,
54
64
  [TermTypes.SSGSEA]: dtssgsea,
55
- [TermTypes.METABOLITE_INTENSITY]: dtmetaboliteintensity
65
+ [TermTypes.DNA_METHYLATION]: dtdnamethylation,
66
+ [TermTypes.METABOLITE_INTENSITY]: dtmetaboliteintensity,
67
+ [TermTypes.WHOLE_PROTEOME_ABUNDANCE]: dtwholeproteomeabundance
56
68
  }
57
69
 
58
70
  // maps term type to group (as is shown as toggles in search ui)
@@ -69,9 +81,12 @@ export const typeGroup = {
69
81
  [TermTypes.SNP_LOCUS]: TermTypeGroups.SNP_LOCUS,
70
82
  [TermTypes.GENE_EXPRESSION]: TermTypeGroups.GENE_EXPRESSION,
71
83
  [TermTypes.SSGSEA]: TermTypeGroups.SSGSEA,
84
+ [TermTypes.DNA_METHYLATION]: TermTypeGroups.DNA_METHYLATION,
72
85
  [TermTypes.METABOLITE_INTENSITY]: TermTypeGroups.METABOLITE_INTENSITY,
86
+ [TermTypes.WHOLE_PROTEOME_ABUNDANCE]: TermTypeGroups.WHOLE_PROTEOME_ABUNDANCE,
73
87
  [TermTypes.TERM_COLLECTION]: TermTypeGroups.TERM_COLLECTION,
74
- [TermTypes.SINGLECELL_CELLTYPE]: TermTypeGroups.SINGLECELL_CELLTYPE
88
+ [TermTypes.SINGLECELL_CELLTYPE]: TermTypeGroups.SINGLECELL_CELLTYPE,
89
+ [TermTypes.SINGLECELL_GENE_EXPRESSION]: TermTypeGroups.SINGLECELL_GENE_EXPRESSION
75
90
  }
76
91
 
77
92
  const nonDictTypes = new Set([
@@ -80,8 +95,10 @@ const nonDictTypes = new Set([
80
95
  TermTypes.SNP_LOCUS,
81
96
  TermTypes.GENE_EXPRESSION,
82
97
  TermTypes.SSGSEA,
98
+ TermTypes.DNA_METHYLATION,
83
99
  TermTypes.GENE_VARIANT,
84
100
  TermTypes.METABOLITE_INTENSITY,
101
+ TermTypes.WHOLE_PROTEOME_ABUNDANCE,
85
102
  TermTypes.SINGLECELL_GENE_EXPRESSION,
86
103
  TermTypes.SINGLECELL_CELLTYPE
87
104
  ])
@@ -94,7 +111,9 @@ export const numericTypes = new Set([
94
111
  TermTypes.FLOAT,
95
112
  TermTypes.GENE_EXPRESSION,
96
113
  TermTypes.SSGSEA,
114
+ TermTypes.DNA_METHYLATION,
97
115
  TermTypes.METABOLITE_INTENSITY,
116
+ TermTypes.WHOLE_PROTEOME_ABUNDANCE,
98
117
  TermTypes.SINGLECELL_GENE_EXPRESSION,
99
118
  TermTypes.DATE
100
119
  ])
@@ -105,7 +124,7 @@ export const annoNumericTypes = new Set([TermTypes.INTEGER, TermTypes.FLOAT, Ter
105
124
 
106
125
  const categoricalTypes = new Set([TermTypes.CATEGORICAL, TermTypes.SNP])
107
126
 
108
- const singleSampleTerms = new Set([TermTypes.SINGLECELL_GENE_EXPRESSION])
127
+ const singleSampleTerms = new Set([TermTypes.SINGLECELL_CELLTYPE, TermTypes.SINGLECELL_GENE_EXPRESSION])
109
128
 
110
129
  export function isSingleSampleTerm(term) {
111
130
  if (!term) return false
@@ -139,7 +158,10 @@ export function equals(t1, t2) {
139
158
  return t1.gene == t2.gene
140
159
  case TermTypes.SSGSEA:
141
160
  return t1.id == t2.id
161
+ case TermTypes.DNA_METHYLATION:
162
+ return t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop
142
163
  case TermTypes.METABOLITE_INTENSITY:
164
+ case TermTypes.WHOLE_PROTEOME_ABUNDANCE:
143
165
  return t1.name == t2.name
144
166
  case TermTypes.GENE_VARIANT:
145
167
  return t1.gene == t2.gene || (t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop)
@@ -214,8 +236,10 @@ const typeMap = {
214
236
  integer: 'Numerical',
215
237
  geneExpression: 'Gene Expression',
216
238
  ssGSEA: 'Geneset Expression',
239
+ dnaMethylation: 'DNA Methylation',
217
240
  geneVariant: 'Gene Variant',
218
241
  metaboliteIntensity: 'Metabolite Intensity',
242
+ wholeProteomeAbundance: 'Whole Proteome Abundance',
219
243
  multiValue: 'Multi Value',
220
244
  singleCellGeneExpression: 'Single Cell, Gene Expression',
221
245
  singleCellCellType: 'Single Cell, Cell Type',