@sjcrh/proteinpaint-server 2.114.0 → 2.115.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-server",
3
- "version": "2.114.0",
3
+ "version": "2.115.0",
4
4
  "type": "module",
5
5
  "description": "a genomics visualization tool for exploring a cohort's genotype and phenotype data",
6
6
  "main": "src/app.js",
@@ -19,8 +19,9 @@
19
19
  "start": "tsx watch . /start.js",
20
20
  "test:unit": "tsx emitImports.js unit > serverTests.js && c8 tsx serverTests.js && rm -rf ./cache",
21
21
  "precombined:coverage": "tsx emitImports.js unit > serverTests.js",
22
- "combined:coverage": "closeCoverageKey=test c8 --all --src=proteinpaint/server --experimental-monocart -r=v8 -r=html -r=json -r=markdown-summary -r=markdown-details -o=./.coverage tsx ./coverage.js & ",
22
+ "combined:coverage": "coverageKey=test c8 --all --src=proteinpaint/server --experimental-monocart -r=v8 -r=html -r=json -r=markdown-summary -r=markdown-details -o=./.coverage tsx ./coverage.js & ",
23
23
  "postcombined:coverage": "rm -rf ./cache",
24
+ "spec:coverage": "tsx test/relevant.js",
24
25
  "getconf": "../build/getConfigProp.js",
25
26
  "doc": "../augen/build.sh routes shared/types/routes shared/checkers ../public/docs/server",
26
27
  "mjs": "esbuild \"$DIR/*.ts\" --platform=node --outdir=\"$DIR\" --format=esm",
@@ -64,10 +65,10 @@
64
65
  "typescript": "^5.6.3"
65
66
  },
66
67
  "dependencies": {
67
- "@sjcrh/augen": "2.113.0",
68
+ "@sjcrh/augen": "2.115.0",
68
69
  "@sjcrh/proteinpaint-rust": "2.114.0",
69
- "@sjcrh/proteinpaint-shared": "2.114.0",
70
- "@sjcrh/proteinpaint-types": "2.114.0",
70
+ "@sjcrh/proteinpaint-shared": "2.115.0",
71
+ "@sjcrh/proteinpaint-types": "2.115.0",
71
72
  "@types/express": "^5.0.0",
72
73
  "@types/express-session": "^1.18.1",
73
74
  "better-sqlite3": "^9.4.1",
@@ -5,6 +5,7 @@ import serverconfig from "../src/serverconfig.js";
5
5
  import { mayLog } from "#src/helpers.ts";
6
6
  import path from "path";
7
7
  import { getStdDev } from "#shared/descriptive.stats.js";
8
+ import { formatElapsedTime } from "#shared/time.js";
8
9
  const minArrayLength = 3;
9
10
  const minSD = 0.05;
10
11
  const api = {
@@ -92,7 +93,9 @@ async function compute(q, ds, genome) {
92
93
  const output = {
93
94
  terms: JSON.parse(await run_R(path.join(serverconfig.binpath, "utils", "corr.R"), JSON.stringify(input)))
94
95
  };
95
- mayLog("Time taken to run correlation analysis:", Date.now() - time1);
96
+ const elapsedMs = Date.now() - time1;
97
+ const formattedTime = formatElapsedTime(elapsedMs);
98
+ mayLog("Time taken to run correlation analysis:", formattedTime);
96
99
  for (const t of output.terms) {
97
100
  const t2 = {
98
101
  tw$id: t.id,
@@ -23,18 +23,7 @@ function init({ genomes }) {
23
23
  if (!ds)
24
24
  throw "invalid dataset name";
25
25
  const sampleId = query.sample_id;
26
- if (ds.queries.WSImages.sources) {
27
- const images2 = [];
28
- if (ds.queries.WSImages.sources) {
29
- images2.push({
30
- filename: sampleId + "_fsspec.json",
31
- metadata: ""
32
- });
33
- }
34
- res.send({ sampleWSImages: images2 });
35
- return;
36
- }
37
- const images = await ds.queries.WSImages.getWSImages({ sampleId });
26
+ const images = await ds.queries.WSImages.getWSImages(sampleId);
38
27
  res.send({ sampleWSImages: images });
39
28
  } catch (e) {
40
29
  console.log(e);
@@ -42,32 +31,31 @@ function init({ genomes }) {
42
31
  }
43
32
  };
44
33
  }
45
- function validate_query_getSampleWSImages(ds) {
46
- const q = ds.queries?.WSImages;
47
- if (!q)
34
+ async function validate_query_getSampleWSImages(ds) {
35
+ if (!ds.queries?.WSImages)
48
36
  return;
49
- nativeValidateQuery(ds);
37
+ validateQuery(ds);
50
38
  }
51
- function nativeValidateQuery(ds) {
52
- ds.queries.WSImages.getWSImages = async (q) => {
53
- return await getWSImages(ds, q.sampleId);
54
- };
55
- }
56
- async function getWSImages(ds, sampleName) {
57
- const sql = `SELECT wsimages.filename as filename, wsimages.metadata as metadata
58
- FROM wsimages
59
- INNER JOIN sampleidmap
60
- ON wsimages.sample = sampleidmap.id
61
- WHERE sampleidmap.name = ?`;
62
- const rows = ds.cohort.db.connection.prepare(sql).all(sampleName);
63
- const images = [];
64
- for (const row of rows) {
65
- images.push({
66
- filename: row.filename,
67
- metadata: row.metadata
68
- });
39
+ function validateQuery(ds) {
40
+ if (typeof ds.queries.WSImages.getWSImages == "function") {
41
+ return;
69
42
  }
70
- return images;
43
+ ds.queries.WSImages.getWSImages = async (sampleName) => {
44
+ const sql = `SELECT wsimages.filename as filename, wsimages.metadata as metadata
45
+ FROM wsimages
46
+ INNER JOIN sampleidmap
47
+ ON wsimages.sample = sampleidmap.id
48
+ WHERE sampleidmap.name = ?`;
49
+ const rows = ds.cohort.db.connection.prepare(sql).all(sampleName);
50
+ const images = [];
51
+ for (const row of rows) {
52
+ images.push({
53
+ filename: row.filename,
54
+ metadata: row.metadata
55
+ });
56
+ }
57
+ return images;
58
+ };
71
59
  }
72
60
  export {
73
61
  api,
@@ -0,0 +1,51 @@
1
+ import { topMutatedGenePayload } from "#types/checkers";
2
+ const api = {
3
+ endpoint: "termdb/topMutatedGenes",
4
+ methods: {
5
+ get: {
6
+ init,
7
+ ...topMutatedGenePayload
8
+ },
9
+ post: {
10
+ init,
11
+ ...topMutatedGenePayload
12
+ }
13
+ }
14
+ };
15
+ function init({ genomes }) {
16
+ return async (req, res) => {
17
+ try {
18
+ const q = req.query;
19
+ const g = genomes[q.genome];
20
+ if (!g)
21
+ throw "genome missing";
22
+ const ds = g.datasets?.[q.dslabel];
23
+ if (!ds)
24
+ throw "ds missing";
25
+ if (!ds.queries?.topMutatedGenes)
26
+ throw "not supported by ds";
27
+ const genes = await ds.queries.topMutatedGenes.get(q);
28
+ const payload = { genes };
29
+ res.send(payload);
30
+ } catch (e) {
31
+ res.send({ status: "error", error: e.message || e });
32
+ if (e.stack)
33
+ console.log(e.stack);
34
+ else
35
+ console.trace(e);
36
+ }
37
+ };
38
+ }
39
+ function validate_query_getTopMutatedGenes(ds, genome) {
40
+ const q = ds.queries?.topMutatedGenes;
41
+ if (!q)
42
+ return;
43
+ if (typeof q.get == "function")
44
+ return;
45
+ q.get = async (param) => {
46
+ };
47
+ }
48
+ export {
49
+ api,
50
+ validate_query_getTopMutatedGenes
51
+ };
@@ -0,0 +1,74 @@
1
+ import { wsiSamplesPayload } from "#types/checkers";
2
+ const routePath = "wsisamples";
3
+ const api = {
4
+ endpoint: `${routePath}`,
5
+ methods: {
6
+ get: {
7
+ ...wsiSamplesPayload,
8
+ init
9
+ },
10
+ post: {
11
+ ...wsiSamplesPayload,
12
+ init
13
+ }
14
+ }
15
+ };
16
+ function init({ genomes }) {
17
+ return async (req, res) => {
18
+ try {
19
+ const query = req.query;
20
+ const g = genomes[query.genome];
21
+ if (!g)
22
+ throw new Error("Invalid genome name");
23
+ const ds = g.datasets[query.dslabel];
24
+ if (!ds)
25
+ throw "Invalid dslabel";
26
+ const images = await ds.queries.WSImages.getSamples();
27
+ const payload = {
28
+ samples: images
29
+ };
30
+ res.status(200).json(payload);
31
+ } catch (e) {
32
+ console.warn(e);
33
+ res.status(500).send({
34
+ status: "error",
35
+ error: e.message || e
36
+ });
37
+ }
38
+ };
39
+ }
40
+ async function validate_query_getWSISamples(ds) {
41
+ const q = ds.queries?.WSImages;
42
+ if (!q)
43
+ return;
44
+ validateQuery(ds);
45
+ }
46
+ function validateQuery(ds) {
47
+ if (typeof ds.queries.WSImages.getSamples == "function") {
48
+ return;
49
+ }
50
+ ds.queries.WSImages.getSamples = async () => {
51
+ const sql = `SELECT wsimages.sample as sample, wsimages.filename as filename, wsimages.metadata as metadata, sampleidmap.name as sampleName
52
+ FROM wsimages
53
+ INNER JOIN sampleidmap
54
+ ON wsimages.sample = sampleidmap.id`;
55
+ try {
56
+ const rows = ds.cohort.db.connection.prepare(sql).all();
57
+ const sampleMap = {};
58
+ for (const row of rows) {
59
+ if (!sampleMap[row.sample]) {
60
+ sampleMap[row.sample] = { sampleId: row.sampleName, wsimages: [] };
61
+ }
62
+ sampleMap[row.sample].wsimages.push(row.filename);
63
+ }
64
+ return Object.values(sampleMap);
65
+ } catch (error) {
66
+ console.error("Error fetching samples:", error);
67
+ throw error;
68
+ }
69
+ };
70
+ }
71
+ export {
72
+ api,
73
+ validate_query_getWSISamples
74
+ };