@sjcrh/proteinpaint-shared 2.189.0 → 2.190.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/README.md +14 -10
- package/dist/src/fetch-helpers.d.ts +3 -1
- package/dist/src/fetch-helpers.js.map +2 -2
- package/dist/src/index.d.ts +1 -2
- package/dist/src/index.js +1 -2
- package/dist/src/index.js.map +2 -2
- package/dist/src/scatter.d.ts +8 -0
- package/dist/src/scatter.js +17 -0
- package/dist/src/scatter.js.map +7 -0
- package/dist/src/terms.d.ts +3 -26
- package/dist/src/terms.js +71 -56
- package/dist/src/terms.js.map +3 -3
- package/package.json +21 -20
- package/constants/AiHisto.ts +0 -31
- package/constants/README.md +0 -11
- package/devTs.ts +0 -3
- package/dist/constants/AiHisto.d.ts +0 -25
- package/dist/constants/AiHisto.js +0 -29
- package/dist/constants/AiHisto.js.map +0 -7
- package/dist/src/aiHisto.d.ts +0 -5
- package/dist/src/aiHisto.js +0 -15
- package/dist/src/aiHisto.js.map +0 -7
package/README.md
CHANGED
|
@@ -8,26 +8,30 @@ code. Do NOT put utility/helper code here that are specific to only one
|
|
|
8
8
|
workspace, those files should be saved in that workspace.
|
|
9
9
|
|
|
10
10
|
IMPORTANT:
|
|
11
|
-
- code must work in browser and nodejs: do not import libs, deps, or globals that
|
|
12
|
-
are specific to `nodejs` or `browser` environments, like `fs` or `DOM` elements
|
|
11
|
+
- Shared code must work in browser and nodejs: do not import libs, deps, or globals that
|
|
12
|
+
are specific to `nodejs` or `browser` environments, like `fs` or `DOM` elements.
|
|
13
|
+
- Except for contants, do not import from this workspace (aka `@sjcrh/proteinpaint-shared/`
|
|
14
|
+
or `#shared`) into `shared/types` as that will cause cyclical imports that break bundler
|
|
15
|
+
startup or `tsc` compilation.
|
|
13
16
|
|
|
14
17
|
## Develop
|
|
15
18
|
|
|
16
|
-
It is much simpler to import
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
It is much simpler to import directly from `@sjcrh/proteinpaint-shared`. Avoid file-specific
|
|
20
|
+
imports unless tree-shaking performance is a concern. If a specific shared file must be imported,
|
|
21
|
+
prefer an alias such as `#shared/someFile.js`, which shields importers from shared code
|
|
22
|
+
file renames or reorganizations.
|
|
19
23
|
|
|
20
24
|
For server dev, the `tsx` library will accept imports with or without file extension.
|
|
21
25
|
Server (consumer) code should use `@sjcrh/proteinpaint-shared`, or if for some reason
|
|
22
26
|
a shared file must be specific, it MUST use the `.js` file extension (e.g.,
|
|
23
27
|
`#shared/someFile.js`).
|
|
24
28
|
|
|
25
|
-
For client dev, the esbuild config will bundle the
|
|
26
|
-
when `.js` extension is used to import what is actually a `.ts` file
|
|
27
|
-
custom plugins like dirname.
|
|
29
|
+
For client dev, the esbuild config will bundle the `#shared` imports correctly, even
|
|
30
|
+
when `.js` extension is used to import what is actually a `.ts` file.
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
Do not import from `#shared/utils` to `#shared/types` - it may cause `tsc` compilation or `esbuild`
|
|
33
|
+
build errors. Only imports in the opposite direction, from `shared/types` to `shared/utils`, is allowed
|
|
34
|
+
to to ensure that there are no cyclical imports that breaks type checks or bundling.
|
|
31
35
|
|
|
32
36
|
## Build
|
|
33
37
|
|
|
@@ -4,5 +4,7 @@ export declare function processFormData(res: any): Promise<{}>;
|
|
|
4
4
|
export declare function memFetch(url: any, init: Record<string, any>, opts?: Record<string, any>): Promise<any>;
|
|
5
5
|
export declare function deleteCache(key: any): void;
|
|
6
6
|
export declare function manageCacheSize(_now: any): void;
|
|
7
|
-
export declare function getDataName(url:
|
|
7
|
+
export declare function getDataName(url: string, init: {
|
|
8
|
+
[optKey: string]: any;
|
|
9
|
+
}): Promise<string>;
|
|
8
10
|
export declare function clearMemFetchDataCache(opts?: Record<string, any>): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/fetch-helpers.ts"],
|
|
4
|
-
"sourcesContent": ["import { hash } from './hash.js'\nimport { encode } from './urljson.js'\nimport { deepFreeze } from './helpers.js'\n\n// tracks serverData objects so their associated cache entries can be cleared; uses WeakMap to avoid memory leaks\nconst optsServerDataNames = new WeakMap()\n\n/*\n\tezFetch()\n\tfetch wrapper with automatic response content-type detection and handling\n\n\t- this addresses issues with ky.json() or got.json(), where a HTTP 404 NOT FOUND\n\t\tresponse with text/html can break error handling/logging, making it harder to debug\n\n\t- this also automatically handles multipart responses\n\n - NOTE: for backend, use xfetch() instead, it uses ky() and its built-in retry support\n\n\targuments:\n\turl\n\tinit{headers?, body?}\n\t- first two arguments are same as native fetch\n*/\nexport async function ezFetch(_url, init: Record<string, any> = {}, opts: Record<string, any> = {}) {\n\tconst url = opts.autoMethod ? mayAdjustRequest(_url, init) : _url\n\tif (typeof init.body === 'object') init.body = JSON.stringify(init.body)\n\n\treturn fetch(url, init).then(async r => {\n\t\tconst response = await processResponse(r)\n\t\tif (!r.ok) {\n\t\t\tconsole.log('ezFetch error ' + r.status)\n\t\t\tconsole.log(response)\n\t\t\tthrow response\n\t\t}\n\t\treturn response\n\t})\n}\n\nfunction mayAdjustRequest(url, init: Record<string, any>) {\n\tconst method = init.method?.toUpperCase() || 'GET'\n\tif (method == 'POST') {\n\t\tif (!init.headers) init.headers = {}\n\t\tif (init.body) {\n\t\t\tif (!init.headers['content-type']) init.headers['content-type'] = 'application/json'\n\t\t\tif (init.headers['content-type'].toLowerCase() == 'application/json') {\n\t\t\t\t// if consumer code has pre-encoded the body, parse to verify correctness\n\t\t\t\tif (typeof init.body == 'string') init.body = JSON.parse(init.body)\n\t\t\t\tinit.body = JSON.stringify(init.body)\n\t\t\t}\n\t\t}\n\t\treturn url\n\t}\n\t// default to GET method per native fetch\n\tif (init.body) {\n\t\tif (typeof init.body != 'object') throw `init.body should be an object`\n\t\t// init.body should be an object, to be converted to GET URL search parameter strings\n\t\tif (!url.includes('?')) url += '?'\n\t\treturn `${url}${encode(init.body)}`\n\t}\n}\n\n/* \nr: a native fetch response argument\n\npotentially allow \"application/octet-stream\" as response type\nin such case it will not try to parse it as json\nalso the caller should just call dofetch2() without a serverData{}\nrather than dofetch3\n*/\nexport async function processResponse(r) {\n\t// if (!r.ok) {\n\t// throw new Error(`HTTP error! status: ${r.status}`)\n\t// }\n\tconst ct = r.headers.get('content-type') // content type is always present\n\tif (!ct) throw `missing response.header['content-type']`\n\tif (ct.includes('/json')) {\n\t\tconst payload = await r.json()\n\t\t// server should use a standard HTTP response status 400+, 500+\n\t\t// so that !r.ok will already be caught when wrapping fetch with try-catch\n\t\t// if (payload.error || payload.status == '') throw payload\n\t\t// if (payload.status === 'error') throw payload.message || payload\n\t\treturn payload\n\t}\n\tif (ct.includes('/text') || ct.includes('text/')) {\n\t\treturn r.text()\n\t}\n\tif (ct.includes('multipart')) {\n\t\tif (ct.startsWith('multipart/form-data')) return processFormData(r)\n\t\telse throw `cannot handle response content-type: '${ct}'`\n\t}\n\tif (ct == 'application/x-ndjson-nestedkey') {\n\t\treturn processNDJSON_nestedKey(r)\n\t}\n\t// call blob() as catch-all\n\t// https://developer.mozilla.org/en-US/docs/Web/API/Response\n\treturn r.blob()\n}\n\n/*\n\texpected response format\n\t--boundary-text-from-HTTP-headers-content-type\n\theader-key1: header-value1\n\theader-key2: header-value2\n\n\t...json, text, blob, value, etc...\n\t--boundary-text-from-HTTP-headers-content-type\n\t... same format as previous chunk ...\n\n\t--boundary-text-from-HTTP-headers-content-type--\n*/\n\nexport async function processFormData(res) {\n\tconst data = {}\n\tconst form = await res.formData()\n\t// The key of each form entry is a string, and the value is either a string or a Blob.\n\t// see https://developer.mozilla.org/en-US/docs/Web/API/FormData/entries\n\tfor (const [key, value] of form.entries()) {\n\t\tif (value.type) {\n\t\t\t// value is a Blob\n\t\t\tdata[key] = { headers: { 'content-type': value.type }, body: value }\n\t\t} else {\n\t\t\t// value is a string, assume to be application/x-jsonlines (one json encoded value per line)\n\t\t\t// and convert into an array of json-decoded values\n\t\t\tconst body = !value ? [] : value.trim().split('\\n').map(JSON.parse)\n\t\t\tdata[key] = { headers: { 'content-type': 'application/json' }, body }\n\t\t}\n\t}\n\treturn data\n}\n\nasync function processNDJSON_nestedKey(r) {\n\t// 1. Pipe through TextDecoder to convert bytes to text\n\tconst stream = r.body.pipeThrough(new TextDecoderStream())\n\tconst reader = stream.getReader()\n\tlet rootObj = {}\n\n\tlet buffer = ''\n\n\tlet done = false\n\twhile (!done) {\n\t\tconst readResult = await reader.read()\n\t\tdone = readResult.done\n\t\tif (done) break\n\t\tconst value = readResult.value\n\n\t\t// 2. Add new chunk to buffer\n\t\tbuffer += value\n\n\t\t// 3. Split by newline\n\t\tconst parts = buffer.split('\\n')\n\n\t\t// 4. Keep the last partial line in the buffer\n\t\tbuffer = parts.pop() ?? ''\n\n\t\t// 5. Process complete lines\n\t\tfor (const line of parts) {\n\t\t\tif (line.trim()) {\n\t\t\t\tconst [keys, data] = JSON.parse(line) //; console.log(143, keys, data) // Process JSON data\n\t\t\t\tif (!keys.length) rootObj = data\n\t\t\t\telse {\n\t\t\t\t\tconst lastKey = keys.pop()\n\t\t\t\t\tlet target = rootObj\n\t\t\t\t\tfor (const k of keys) target = target[k]\n\t\t\t\t\ttarget[lastKey] = data\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn rootObj\n}\n\n// key: request object reference or computed string dataName\n// value: {\n// response: fetch promise or response,\n// exp: expiration timestamp\n// }\nconst dataCache = new Map()\n// maximum number of cached dataNames, oldest will be deleted if this is exceeded\nconst maxNumOfDataKeys = 10\nconst cacheLifetime = 1000 * 60 * 5\n/*\n\tmemFetch()\n\t- fetch wrapper that saves cached responses into memory and recovers them for matching subsequent requests\n\t- recommended for caching responses in the backend, with the opts.q argument to cache per expressjs request object\n\t- should call deleteCache(request) at the end of request handling, to free unneeded cache\n\t\n\tSee the usage note for getDataName() to avoid non-unique request/response.\n\t\n\tArguments:\n\turl\n\tinit{headers?, body?}\n\t- first two arguments are same as native fetch\n - when passing opts.client, may include other applicable options inside the init{} object, such as retry\n\n\topts{client}\n\n client: use this http client instead of native fetch\n - since fetch-helpers is shared between server and frontend workspaces, \n cannot directly import non-native modules at the beginning of this code file \n - for server side usage, client may be `xfetch()`, `ky` or other libraries \n*/\nexport async function memFetch(url, init: Record<string, any>, opts: Record<string, any> = {}) {\n\tif (typeof init.body === 'object') init.body = JSON.stringify(init.body)\n\tconst dataKey = opts.q || (await getDataName(url, init))\n\tconst { response } = dataCache.get(dataKey) || {}\n\tconst now = Date.now()\n\tlet result = response // either a Promise or actual data\n\n\tif (result) {\n\t\t// extend the expiration, since exp is more about managing the cache size\n\t\t// and not the validity of the cached response. A response for the current\n\t\t// dataName req.url + body + headers is technically valid until a new data version\n\t\t// gets published.\n\t\tdataCache.set(dataKey, { response, exp: now + cacheLifetime })\n\t\treturn result\n\t} else {\n\t\ttry {\n\t\t\t// IMPORTANT: do not await so that this same promise may be reused\n\t\t\t// by subsequent requests with the same dataKey\n\t\t\tresult = opts.client\n\t\t\t\t? opts.client(url, init, Object.assign(opts, { client: undefined })).then(response => {\n\t\t\t\t\t\t// replace the cached promise result with the actual data,\n\t\t\t\t\t\t// since persisting a cached promise for a long time is likely not best practice\n\t\t\t\t\t\tdataCache.set(dataKey, { response, exp: Date.now() + cacheLifetime })\n\t\t\t\t\t\treturn response\n\t\t\t\t })\n\t\t\t\t: fetch(url, init)\n\t\t\t\t\t\t.then(async r => {\n\t\t\t\t\t\t\tconst response = await processResponse(r)\n\t\t\t\t\t\t\tif (!r.ok) {\n\t\t\t\t\t\t\t\tconsole.trace(response)\n\t\t\t\t\t\t\t\tthrow (\n\t\t\t\t\t\t\t\t\t'memFetch error ' +\n\t\t\t\t\t\t\t\t\tr.status +\n\t\t\t\t\t\t\t\t\t': ' +\n\t\t\t\t\t\t\t\t\t(typeof response == 'object' ? response.message || response.error : response)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// replace the cached promise result with the actual data,\n\t\t\t\t\t\t\t// since persisting a cached promise for a long time is likely not best practice\n\t\t\t\t\t\t\tdataCache.set(dataKey, { response: deepFreeze(response), exp: Date.now() + cacheLifetime })\n\t\t\t\t\t\t\treturn response\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch(e => {\n\t\t\t\t\t\t\tif (dataCache.get(dataKey)) dataCache.delete(dataKey)\n\t\t\t\t\t\t\tthrow e\n\t\t\t\t\t\t})\n\n\t\t\tdataCache.set(dataKey, { response: result, exp: Date.now() + cacheLifetime })\n\t\t\tmanageCacheSize(now)\n\t\t\treturn result\n\t\t} catch (e) {\n\t\t\t// delete this cache only if it is a promise;\n\t\t\t// do not delete a valid resolved data cache\n\t\t\tif (dataCache.get(dataKey) instanceof Promise) dataCache.delete(dataKey)\n\t\t\tthrow e\n\t\t}\n\t}\n}\n\nexport function deleteCache(key) {\n\tdataCache.delete(key)\n}\n\nexport function manageCacheSize(_now) {\n\tconst now = _now || Date.now()\n\tconst keyExp: { key: any; exp: number }[] = []\n\tfor (const [key, result] of dataCache.entries()) {\n\t\tif (result.exp < now) dataCache.delete(key)\n\t\telse keyExp.push({ key, exp: result.exp })\n\t}\n\tif (dataCache.size > maxNumOfDataKeys) {\n\t\tconst oldestEntries = keyExp.sort((a, b) => a.exp - b.exp).slice(maxNumOfDataKeys)\n\t\tfor (const entry of oldestEntries) dataCache.delete(entry.key)\n\t}\n}\n\n/*\n\tNOTE: When used in client-side code, an HttpOnly cookie for a logged in user will not be\n\ttracked in init.headers below. \n*/\nexport async function getDataName(url, init) {\n\t// IMPORTANT: must ensure dataName is unique to either public or logged-in user\n\tconst dataName = url + ' | ' + init.method + ' | ' + init.body + ' | ' + JSON.stringify(init.headers)\n\treturn await hash(dataName)\n}\n\n//\nexport function clearMemFetchDataCache(opts: Record<string, any> = {}) {\n\tif (!opts.serverData) {\n\t\tdataCache.clear()\n\t\treturn\n\t}\n\tif (typeof opts.serverData != 'object') throw `opts.serverData is not an object`\n\tfor (const k of Object.keys(opts.serverData)) {\n\t\tdelete opts.serverData[k]\n\t}\n\tif (optsServerDataNames.has(opts.serverData)) optsServerDataNames.delete(opts.serverData)\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { hash } from './hash.js'\nimport { encode } from './urljson.js'\nimport { deepFreeze } from './helpers.js'\n\n// tracks serverData objects so their associated cache entries can be cleared; uses WeakMap to avoid memory leaks\nconst optsServerDataNames = new WeakMap()\n\n/*\n\tezFetch()\n\tfetch wrapper with automatic response content-type detection and handling\n\n\t- this addresses issues with ky.json() or got.json(), where a HTTP 404 NOT FOUND\n\t\tresponse with text/html can break error handling/logging, making it harder to debug\n\n\t- this also automatically handles multipart responses\n\n - NOTE: for backend, use xfetch() instead, it uses ky() and its built-in retry support\n\n\targuments:\n\turl\n\tinit{headers?, body?}\n\t- first two arguments are same as native fetch\n*/\nexport async function ezFetch(_url, init: Record<string, any> = {}, opts: Record<string, any> = {}) {\n\tconst url = opts.autoMethod ? mayAdjustRequest(_url, init) : _url\n\tif (typeof init.body === 'object') init.body = JSON.stringify(init.body)\n\n\treturn fetch(url, init).then(async r => {\n\t\tconst response = await processResponse(r)\n\t\tif (!r.ok) {\n\t\t\tconsole.log('ezFetch error ' + r.status)\n\t\t\tconsole.log(response)\n\t\t\tthrow response\n\t\t}\n\t\treturn response\n\t})\n}\n\nfunction mayAdjustRequest(url, init: Record<string, any>) {\n\tconst method = init.method?.toUpperCase() || 'GET'\n\tif (method == 'POST') {\n\t\tif (!init.headers) init.headers = {}\n\t\tif (init.body) {\n\t\t\tif (!init.headers['content-type']) init.headers['content-type'] = 'application/json'\n\t\t\tif (init.headers['content-type'].toLowerCase() == 'application/json') {\n\t\t\t\t// if consumer code has pre-encoded the body, parse to verify correctness\n\t\t\t\tif (typeof init.body == 'string') init.body = JSON.parse(init.body)\n\t\t\t\tinit.body = JSON.stringify(init.body)\n\t\t\t}\n\t\t}\n\t\treturn url\n\t}\n\t// default to GET method per native fetch\n\tif (init.body) {\n\t\tif (typeof init.body != 'object') throw `init.body should be an object`\n\t\t// init.body should be an object, to be converted to GET URL search parameter strings\n\t\tif (!url.includes('?')) url += '?'\n\t\treturn `${url}${encode(init.body)}`\n\t}\n}\n\n/* \nr: a native fetch response argument\n\npotentially allow \"application/octet-stream\" as response type\nin such case it will not try to parse it as json\nalso the caller should just call dofetch2() without a serverData{}\nrather than dofetch3\n*/\nexport async function processResponse(r) {\n\t// if (!r.ok) {\n\t// throw new Error(`HTTP error! status: ${r.status}`)\n\t// }\n\tconst ct = r.headers.get('content-type') // content type is always present\n\tif (!ct) throw `missing response.header['content-type']`\n\tif (ct.includes('/json')) {\n\t\tconst payload = await r.json()\n\t\t// server should use a standard HTTP response status 400+, 500+\n\t\t// so that !r.ok will already be caught when wrapping fetch with try-catch\n\t\t// if (payload.error || payload.status == '') throw payload\n\t\t// if (payload.status === 'error') throw payload.message || payload\n\t\treturn payload\n\t}\n\tif (ct.includes('/text') || ct.includes('text/')) {\n\t\treturn r.text()\n\t}\n\tif (ct.includes('multipart')) {\n\t\tif (ct.startsWith('multipart/form-data')) return processFormData(r)\n\t\telse throw `cannot handle response content-type: '${ct}'`\n\t}\n\tif (ct == 'application/x-ndjson-nestedkey') {\n\t\treturn processNDJSON_nestedKey(r)\n\t}\n\t// call blob() as catch-all\n\t// https://developer.mozilla.org/en-US/docs/Web/API/Response\n\treturn r.blob()\n}\n\n/*\n\texpected response format\n\t--boundary-text-from-HTTP-headers-content-type\n\theader-key1: header-value1\n\theader-key2: header-value2\n\n\t...json, text, blob, value, etc...\n\t--boundary-text-from-HTTP-headers-content-type\n\t... same format as previous chunk ...\n\n\t--boundary-text-from-HTTP-headers-content-type--\n*/\n\nexport async function processFormData(res) {\n\tconst data = {}\n\tconst form = await res.formData()\n\t// The key of each form entry is a string, and the value is either a string or a Blob.\n\t// see https://developer.mozilla.org/en-US/docs/Web/API/FormData/entries\n\tfor (const [key, value] of form.entries()) {\n\t\tif (value.type) {\n\t\t\t// value is a Blob\n\t\t\tdata[key] = { headers: { 'content-type': value.type }, body: value }\n\t\t} else {\n\t\t\t// value is a string, assume to be application/x-jsonlines (one json encoded value per line)\n\t\t\t// and convert into an array of json-decoded values\n\t\t\tconst body = !value ? [] : value.trim().split('\\n').map(JSON.parse)\n\t\t\tdata[key] = { headers: { 'content-type': 'application/json' }, body }\n\t\t}\n\t}\n\treturn data\n}\n\nasync function processNDJSON_nestedKey(r) {\n\t// 1. Pipe through TextDecoder to convert bytes to text\n\tconst stream = r.body.pipeThrough(new TextDecoderStream())\n\tconst reader = stream.getReader()\n\tlet rootObj = {}\n\n\tlet buffer = ''\n\n\tlet done = false\n\twhile (!done) {\n\t\tconst readResult = await reader.read()\n\t\tdone = readResult.done\n\t\tif (done) break\n\t\tconst value = readResult.value\n\n\t\t// 2. Add new chunk to buffer\n\t\tbuffer += value\n\n\t\t// 3. Split by newline\n\t\tconst parts = buffer.split('\\n')\n\n\t\t// 4. Keep the last partial line in the buffer\n\t\tbuffer = parts.pop() ?? ''\n\n\t\t// 5. Process complete lines\n\t\tfor (const line of parts) {\n\t\t\tif (line.trim()) {\n\t\t\t\tconst [keys, data] = JSON.parse(line) //; console.log(143, keys, data) // Process JSON data\n\t\t\t\tif (!keys.length) rootObj = data\n\t\t\t\telse {\n\t\t\t\t\tconst lastKey = keys.pop()\n\t\t\t\t\tlet target = rootObj\n\t\t\t\t\tfor (const k of keys) target = target[k]\n\t\t\t\t\ttarget[lastKey] = data\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn rootObj\n}\n\n// key: request object reference or computed string dataName\n// value: {\n// response: fetch promise or response,\n// exp: expiration timestamp\n// }\nconst dataCache = new Map()\n// maximum number of cached dataNames, oldest will be deleted if this is exceeded\nconst maxNumOfDataKeys = 10\nconst cacheLifetime = 1000 * 60 * 5\n/*\n\tmemFetch()\n\t- fetch wrapper that saves cached responses into memory and recovers them for matching subsequent requests\n\t- recommended for caching responses in the backend, with the opts.q argument to cache per expressjs request object\n\t- should call deleteCache(request) at the end of request handling, to free unneeded cache\n\t\n\tSee the usage note for getDataName() to avoid non-unique request/response.\n\t\n\tArguments:\n\turl\n\tinit{headers?, body?}\n\t- first two arguments are same as native fetch\n - when passing opts.client, may include other applicable options inside the init{} object, such as retry\n\n\topts{client}\n\n client: use this http client instead of native fetch\n - since fetch-helpers is shared between server and frontend workspaces, \n cannot directly import non-native modules at the beginning of this code file \n - for server side usage, client may be `xfetch()`, `ky` or other libraries \n*/\nexport async function memFetch(url, init: Record<string, any>, opts: Record<string, any> = {}) {\n\tif (typeof init.body === 'object') init.body = JSON.stringify(init.body)\n\tconst dataKey = opts.q || (await getDataName(url, init))\n\tconst { response } = dataCache.get(dataKey) || {}\n\tconst now = Date.now()\n\tlet result = response // either a Promise or actual data\n\n\tif (result) {\n\t\t// extend the expiration, since exp is more about managing the cache size\n\t\t// and not the validity of the cached response. A response for the current\n\t\t// dataName req.url + body + headers is technically valid until a new data version\n\t\t// gets published.\n\t\tdataCache.set(dataKey, { response, exp: now + cacheLifetime })\n\t\treturn result\n\t} else {\n\t\ttry {\n\t\t\t// IMPORTANT: do not await so that this same promise may be reused\n\t\t\t// by subsequent requests with the same dataKey\n\t\t\tresult = opts.client\n\t\t\t\t? opts.client(url, init, Object.assign(opts, { client: undefined })).then(response => {\n\t\t\t\t\t\t// replace the cached promise result with the actual data,\n\t\t\t\t\t\t// since persisting a cached promise for a long time is likely not best practice\n\t\t\t\t\t\tdataCache.set(dataKey, { response, exp: Date.now() + cacheLifetime })\n\t\t\t\t\t\treturn response\n\t\t\t\t })\n\t\t\t\t: fetch(url, init)\n\t\t\t\t\t\t.then(async r => {\n\t\t\t\t\t\t\tconst response = await processResponse(r)\n\t\t\t\t\t\t\tif (!r.ok) {\n\t\t\t\t\t\t\t\tconsole.trace(response)\n\t\t\t\t\t\t\t\tthrow (\n\t\t\t\t\t\t\t\t\t'memFetch error ' +\n\t\t\t\t\t\t\t\t\tr.status +\n\t\t\t\t\t\t\t\t\t': ' +\n\t\t\t\t\t\t\t\t\t(typeof response == 'object' ? response.message || response.error : response)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// replace the cached promise result with the actual data,\n\t\t\t\t\t\t\t// since persisting a cached promise for a long time is likely not best practice\n\t\t\t\t\t\t\tdataCache.set(dataKey, { response: deepFreeze(response), exp: Date.now() + cacheLifetime })\n\t\t\t\t\t\t\treturn response\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch(e => {\n\t\t\t\t\t\t\tif (dataCache.get(dataKey)) dataCache.delete(dataKey)\n\t\t\t\t\t\t\tthrow e\n\t\t\t\t\t\t})\n\n\t\t\tdataCache.set(dataKey, { response: result, exp: Date.now() + cacheLifetime })\n\t\t\tmanageCacheSize(now)\n\t\t\treturn result\n\t\t} catch (e) {\n\t\t\t// delete this cache only if it is a promise;\n\t\t\t// do not delete a valid resolved data cache\n\t\t\tif (dataCache.get(dataKey) instanceof Promise) dataCache.delete(dataKey)\n\t\t\tthrow e\n\t\t}\n\t}\n}\n\nexport function deleteCache(key) {\n\tdataCache.delete(key)\n}\n\nexport function manageCacheSize(_now) {\n\tconst now = _now || Date.now()\n\tconst keyExp: { key: any; exp: number }[] = []\n\tfor (const [key, result] of dataCache.entries()) {\n\t\tif (result.exp < now) dataCache.delete(key)\n\t\telse keyExp.push({ key, exp: result.exp })\n\t}\n\tif (dataCache.size > maxNumOfDataKeys) {\n\t\tconst oldestEntries = keyExp.sort((a, b) => a.exp - b.exp).slice(maxNumOfDataKeys)\n\t\tfor (const entry of oldestEntries) dataCache.delete(entry.key)\n\t}\n}\n\n/*\n\tNOTE: When used in client-side code, an HttpOnly cookie for a logged in user will not be\n\ttracked in init.headers below. \n*/\nexport async function getDataName(url: string, init: { [optKey: string]: any }) {\n\t// IMPORTANT: must ensure dataName is unique to either public or logged-in user\n\tconst dataName = url + ' | ' + init.method + ' | ' + init.body + ' | ' + JSON.stringify(init.headers)\n\treturn await hash(dataName)\n}\n\n//\nexport function clearMemFetchDataCache(opts: Record<string, any> = {}) {\n\tif (!opts.serverData) {\n\t\tdataCache.clear()\n\t\treturn\n\t}\n\tif (typeof opts.serverData != 'object') throw `opts.serverData is not an object`\n\tfor (const k of Object.keys(opts.serverData)) {\n\t\tdelete opts.serverData[k]\n\t}\n\tif (optsServerDataNames.has(opts.serverData)) optsServerDataNames.delete(opts.serverData)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["response"]
|
|
7
7
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export * from '../constants/AiHisto.js';
|
|
2
|
-
export * from './aiHisto.js';
|
|
3
1
|
export * from './bulk.js';
|
|
4
2
|
export * from './clustering.js';
|
|
5
3
|
export * from './common.js';
|
|
@@ -12,6 +10,7 @@ export * from './helpers.js';
|
|
|
12
10
|
export * from './joinUrl.js';
|
|
13
11
|
export * from './mds3tk.js';
|
|
14
12
|
export * from './roundValue.js';
|
|
13
|
+
export * from './scatter.js';
|
|
15
14
|
export * from './termdb.bins.js';
|
|
16
15
|
export * from './termdb.initbinconfig.js';
|
|
17
16
|
export * from './termdb.usecase.js';
|
package/dist/src/index.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export * from "../constants/AiHisto.js";
|
|
2
|
-
export * from "./aiHisto.js";
|
|
3
1
|
export * from "./bulk.js";
|
|
4
2
|
export * from "./clustering.js";
|
|
5
3
|
export * from "./common.js";
|
|
@@ -12,6 +10,7 @@ export * from "./helpers.js";
|
|
|
12
10
|
export * from "./joinUrl.js";
|
|
13
11
|
export * from "./mds3tk.js";
|
|
14
12
|
export * from "./roundValue.js";
|
|
13
|
+
export * from "./scatter.js";
|
|
15
14
|
export * from "./termdb.bins.js";
|
|
16
15
|
export * from "./termdb.initbinconfig.js";
|
|
17
16
|
export * from "./termdb.usecase.js";
|
package/dist/src/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["// IMPORTANT: import .js extension, even though the actual code files are .ts\
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["// IMPORTANT: import .js extension, even though the actual code files are .ts\n// please list in alphanumeric order for readability\nexport * from './bulk.js'\nexport * from './clustering.js'\nexport * from './common.js'\nexport * from './compute.percentile.js'\nexport * from './fetch-helpers.js'\nexport * from './fileSize.js'\nexport * from './filter.js'\nexport * from './hash.js'\nexport * from './helpers.js'\nexport * from './joinUrl.js'\nexport * from './mds3tk.js'\nexport * from './roundValue.js'\nexport * from './scatter.js'\nexport * from './termdb.bins.js'\nexport * from './termdb.initbinconfig.js'\nexport * from './termdb.usecase.js'\nexport * from './terms.js'\nexport * from './time.js'\nexport * from './tree.js'\nexport * from './urljson.js'\nexport * from './vcf.ann.js'\nexport * from './vcf.csq.js'\nexport * from './vcf.info.js'\nexport * from './vcf.js'\nexport * from './vcf.type.js'\n"],
|
|
5
|
+
"mappings": "AAEA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** The scatter renders both on the client and the server.
|
|
2
|
+
* The consts and functions below are data processing and formatting utils used
|
|
3
|
+
* in both contexts. */
|
|
4
|
+
export declare const xAxisOffSet = 80;
|
|
5
|
+
export declare const yAxisOffSet = 30;
|
|
6
|
+
export declare function getCoordinate(val: number, min: number | null, max: number | null): number;
|
|
7
|
+
/** Extra space prevents clipping data points on the scale (i.e. plot axis) */
|
|
8
|
+
export declare function calculatePadding(minScale: number | null, maxScale: number | null, min: number, max: number): number;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const xAxisOffSet = 80;
|
|
2
|
+
const yAxisOffSet = 30;
|
|
3
|
+
function getCoordinate(val, min, max) {
|
|
4
|
+
if (min != null && val < min) return min;
|
|
5
|
+
if (max != null && val > max) return max;
|
|
6
|
+
return val;
|
|
7
|
+
}
|
|
8
|
+
function calculatePadding(minScale, maxScale, min, max) {
|
|
9
|
+
return minScale != null || maxScale != null ? 0 : (max - min) * 0.01;
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
calculatePadding,
|
|
13
|
+
getCoordinate,
|
|
14
|
+
xAxisOffSet,
|
|
15
|
+
yAxisOffSet
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=scatter.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/scatter.ts"],
|
|
4
|
+
"sourcesContent": ["/** The scatter renders both on the client and the server.\n * The consts and functions below are data processing and formatting utils used\n * in both contexts. */\n\nexport const xAxisOffSet = 80\nexport const yAxisOffSet = 30\n\nexport function getCoordinate(val: number, min: number | null, max: number | null) {\n\tif (min != null && val < min) return min\n\tif (max != null && val > max) return max\n\treturn val\n}\n\n/** Extra space prevents clipping data points on the scale (i.e. plot axis) */\nexport function calculatePadding(minScale: number | null, maxScale: number | null, min: number, max: number) {\n\treturn minScale != null || maxScale != null ? 0 : (max - min) * 0.01\n}\n"],
|
|
5
|
+
"mappings": "AAIO,MAAM,cAAc;AACpB,MAAM,cAAc;AAEpB,SAAS,cAAc,KAAa,KAAoB,KAAoB;AAClF,MAAI,OAAO,QAAQ,MAAM,IAAK,QAAO;AACrC,MAAI,OAAO,QAAQ,MAAM,IAAK,QAAO;AACrC,SAAO;AACR;AAGO,SAAS,iBAAiB,UAAyB,UAAyB,KAAa,KAAa;AAC5G,SAAO,YAAY,QAAQ,YAAY,OAAO,KAAK,MAAM,OAAO;AACjE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/src/terms.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Term } from '#types';
|
|
2
|
+
export { GENE_VARIANT, GENE_EXPRESSION, ISOFORM_EXPRESSION, SSGSEA, DNA_METHYLATION, CATEGORICAL, INTEGER, FLOAT, SNP, SNP_LIST, SNP_LOCUS, CONDITION, SURVIVAL, SAMPLELST, METABOLITE_INTENSITY, PROTEOME_ABUNDANCE, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION, MULTIVALUE, DATE, TERM_COLLECTION, TermTypes } from '#types';
|
|
2
3
|
export { TermTypeGroups } from './common.js';
|
|
3
4
|
export declare const ROOT_SAMPLE_TYPE = 1;
|
|
4
5
|
export declare const DEFAULT_SAMPLE_TYPE = 2;
|
|
@@ -6,31 +7,6 @@ export declare const NumericModes: {
|
|
|
6
7
|
continuous: string;
|
|
7
8
|
discrete: string;
|
|
8
9
|
};
|
|
9
|
-
export declare const CATEGORICAL = "categorical";
|
|
10
|
-
export declare const CONDITION = "condition";
|
|
11
|
-
export declare const DATE = "date";
|
|
12
|
-
export declare const DNA_METHYLATION = "dnaMethylation";
|
|
13
|
-
export declare const FLOAT = "float";
|
|
14
|
-
export declare const GENE_VARIANT = "geneVariant";
|
|
15
|
-
export declare const GENE_EXPRESSION = "geneExpression";
|
|
16
|
-
export declare const ISOFORM_EXPRESSION = "isoformExpression";
|
|
17
|
-
export declare const INTEGER = "integer";
|
|
18
|
-
export declare const METABOLITE_INTENSITY = "metaboliteIntensity";
|
|
19
|
-
export declare const MULTIVALUE = "multivalue";
|
|
20
|
-
export declare const SAMPLELST = "samplelst";
|
|
21
|
-
export declare const SINGLECELL_CELLTYPE = "singleCellCellType";
|
|
22
|
-
export declare const SINGLECELL_GENE_EXPRESSION = "singleCellGeneExpression";
|
|
23
|
-
export declare const SNP = "snp";
|
|
24
|
-
export declare const SNP_LIST = "snplst";
|
|
25
|
-
export declare const SNP_LOCUS = "snplocus";
|
|
26
|
-
export declare const SSGSEA = "ssGSEA";
|
|
27
|
-
export declare const SURVIVAL = "survival";
|
|
28
|
-
export declare const TERM_COLLECTION = "termCollection";
|
|
29
|
-
export declare const PROTEOME_ABUNDANCE = "proteomeAbundance";
|
|
30
|
-
export declare const PROTEOME_DAP = "proteomeDAP";
|
|
31
|
-
export declare const TermTypes: {
|
|
32
|
-
[key: string]: string;
|
|
33
|
-
};
|
|
34
10
|
export declare const dtTermTypes: Set<string>;
|
|
35
11
|
export declare const NUMERIC_DICTIONARY_TERM = "numericDictTerm";
|
|
36
12
|
export declare const TermTypes2Dt: {
|
|
@@ -64,7 +40,7 @@ export declare const typeGroup: {
|
|
|
64
40
|
singleCellGeneExpression: string;
|
|
65
41
|
};
|
|
66
42
|
export declare const numericTypes: Set<string>;
|
|
67
|
-
export declare const
|
|
43
|
+
export declare const dictionaryNumericTypes: Set<string>;
|
|
68
44
|
export declare function isSingleCellTerm(term: any): boolean;
|
|
69
45
|
export declare function isNumericTerm(term: Term): boolean;
|
|
70
46
|
export declare function isCategoricalTerm(term: Term): boolean;
|
|
@@ -75,6 +51,7 @@ export declare function equals(t1: any, t2: any): boolean;
|
|
|
75
51
|
export declare function getBin(lst: any[], value: number): number;
|
|
76
52
|
export declare function getSampleType(term: any, ds: any): any;
|
|
77
53
|
export declare function getParentType(types: Set<string>, ds: any): any;
|
|
54
|
+
export declare function isParentType(term: any, ds: any): boolean;
|
|
78
55
|
export declare function termType2label(type: string): string;
|
|
79
56
|
export declare function getDateFromNumber(value: number): Date;
|
|
80
57
|
export declare function getDateStrFromNumber(value: number): string;
|
package/dist/src/terms.js
CHANGED
|
@@ -7,36 +7,7 @@ import {
|
|
|
7
7
|
TermTypeGroups,
|
|
8
8
|
dtTerms
|
|
9
9
|
} from "./common.js";
|
|
10
|
-
import {
|
|
11
|
-
const ROOT_SAMPLE_TYPE = 1;
|
|
12
|
-
const DEFAULT_SAMPLE_TYPE = 2;
|
|
13
|
-
const NumericModes = {
|
|
14
|
-
continuous: "continuous",
|
|
15
|
-
discrete: "discrete"
|
|
16
|
-
};
|
|
17
|
-
const CATEGORICAL = "categorical";
|
|
18
|
-
const CONDITION = "condition";
|
|
19
|
-
const DATE = "date";
|
|
20
|
-
const DNA_METHYLATION = "dnaMethylation";
|
|
21
|
-
const FLOAT = "float";
|
|
22
|
-
const GENE_VARIANT = "geneVariant";
|
|
23
|
-
const GENE_EXPRESSION = "geneExpression";
|
|
24
|
-
const ISOFORM_EXPRESSION = "isoformExpression";
|
|
25
|
-
const INTEGER = "integer";
|
|
26
|
-
const METABOLITE_INTENSITY = "metaboliteIntensity";
|
|
27
|
-
const MULTIVALUE = "multivalue";
|
|
28
|
-
const SAMPLELST = "samplelst";
|
|
29
|
-
const SINGLECELL_CELLTYPE = "singleCellCellType";
|
|
30
|
-
const SINGLECELL_GENE_EXPRESSION = "singleCellGeneExpression";
|
|
31
|
-
const SNP = "snp";
|
|
32
|
-
const SNP_LIST = "snplst";
|
|
33
|
-
const SNP_LOCUS = "snplocus";
|
|
34
|
-
const SSGSEA = "ssGSEA";
|
|
35
|
-
const SURVIVAL = "survival";
|
|
36
|
-
const TERM_COLLECTION = "termCollection";
|
|
37
|
-
const PROTEOME_ABUNDANCE = "proteomeAbundance";
|
|
38
|
-
const PROTEOME_DAP = "proteomeDAP";
|
|
39
|
-
const TermTypes = {
|
|
10
|
+
import {
|
|
40
11
|
GENE_VARIANT,
|
|
41
12
|
GENE_EXPRESSION,
|
|
42
13
|
ISOFORM_EXPRESSION,
|
|
@@ -57,7 +28,39 @@ const TermTypes = {
|
|
|
57
28
|
SINGLECELL_GENE_EXPRESSION,
|
|
58
29
|
MULTIVALUE,
|
|
59
30
|
DATE,
|
|
60
|
-
TERM_COLLECTION
|
|
31
|
+
TERM_COLLECTION,
|
|
32
|
+
TermTypes
|
|
33
|
+
} from "#types";
|
|
34
|
+
import {
|
|
35
|
+
GENE_VARIANT as GENE_VARIANT2,
|
|
36
|
+
GENE_EXPRESSION as GENE_EXPRESSION2,
|
|
37
|
+
ISOFORM_EXPRESSION as ISOFORM_EXPRESSION2,
|
|
38
|
+
SSGSEA as SSGSEA2,
|
|
39
|
+
DNA_METHYLATION as DNA_METHYLATION2,
|
|
40
|
+
CATEGORICAL as CATEGORICAL2,
|
|
41
|
+
INTEGER as INTEGER2,
|
|
42
|
+
FLOAT as FLOAT2,
|
|
43
|
+
SNP as SNP2,
|
|
44
|
+
SNP_LIST as SNP_LIST2,
|
|
45
|
+
SNP_LOCUS as SNP_LOCUS2,
|
|
46
|
+
CONDITION as CONDITION2,
|
|
47
|
+
SURVIVAL as SURVIVAL2,
|
|
48
|
+
SAMPLELST as SAMPLELST2,
|
|
49
|
+
METABOLITE_INTENSITY as METABOLITE_INTENSITY2,
|
|
50
|
+
PROTEOME_ABUNDANCE as PROTEOME_ABUNDANCE2,
|
|
51
|
+
SINGLECELL_CELLTYPE as SINGLECELL_CELLTYPE2,
|
|
52
|
+
SINGLECELL_GENE_EXPRESSION as SINGLECELL_GENE_EXPRESSION2,
|
|
53
|
+
MULTIVALUE as MULTIVALUE2,
|
|
54
|
+
DATE as DATE2,
|
|
55
|
+
TERM_COLLECTION as TERM_COLLECTION2,
|
|
56
|
+
TermTypes as TermTypes2
|
|
57
|
+
} from "#types";
|
|
58
|
+
import { TermTypeGroups as TermTypeGroups2 } from "./common.js";
|
|
59
|
+
const ROOT_SAMPLE_TYPE = 1;
|
|
60
|
+
const DEFAULT_SAMPLE_TYPE = 2;
|
|
61
|
+
const NumericModes = {
|
|
62
|
+
continuous: "continuous",
|
|
63
|
+
discrete: "discrete"
|
|
61
64
|
};
|
|
62
65
|
const dtTermTypes = new Set(dtTerms.map((t) => t.type));
|
|
63
66
|
for (const dtTermType of dtTermTypes) {
|
|
@@ -123,7 +126,7 @@ const numericTypes = /* @__PURE__ */ new Set([
|
|
|
123
126
|
SINGLECELL_GENE_EXPRESSION,
|
|
124
127
|
DATE
|
|
125
128
|
]);
|
|
126
|
-
const
|
|
129
|
+
const dictionaryNumericTypes = /* @__PURE__ */ new Set([INTEGER, FLOAT, DATE]);
|
|
127
130
|
const categoricalTypes = /* @__PURE__ */ new Set([CATEGORICAL, SNP]);
|
|
128
131
|
const singleCellTerms = /* @__PURE__ */ new Set([SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION]);
|
|
129
132
|
function isSingleCellTerm(term) {
|
|
@@ -215,6 +218,18 @@ function getParentType(types, ds) {
|
|
|
215
218
|
}
|
|
216
219
|
return null;
|
|
217
220
|
}
|
|
221
|
+
function isParentType(term, ds) {
|
|
222
|
+
if (!ds.cohort.termdb.hasSampleAncestry) return false;
|
|
223
|
+
const sampleType = getSampleType(term, ds);
|
|
224
|
+
if (!sampleType) throw "sample type is not defined";
|
|
225
|
+
const sampleTypeObj = ds.cohort.termdb.sampleTypes[sampleType];
|
|
226
|
+
if (!sampleTypeObj) throw "invalid sample type";
|
|
227
|
+
if (Number.isInteger(sampleTypeObj.parent_id)) {
|
|
228
|
+
return false;
|
|
229
|
+
} else {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
218
233
|
const typeMap = {
|
|
219
234
|
categorical: "Categorical",
|
|
220
235
|
condition: "Condition",
|
|
@@ -274,36 +289,35 @@ function getDaysInYear(year) {
|
|
|
274
289
|
return days;
|
|
275
290
|
}
|
|
276
291
|
export {
|
|
277
|
-
CATEGORICAL,
|
|
278
|
-
CONDITION,
|
|
279
|
-
DATE,
|
|
292
|
+
CATEGORICAL2 as CATEGORICAL,
|
|
293
|
+
CONDITION2 as CONDITION,
|
|
294
|
+
DATE2 as DATE,
|
|
280
295
|
DEFAULT_SAMPLE_TYPE,
|
|
281
|
-
DNA_METHYLATION,
|
|
282
|
-
FLOAT,
|
|
283
|
-
GENE_EXPRESSION,
|
|
284
|
-
GENE_VARIANT,
|
|
285
|
-
INTEGER,
|
|
286
|
-
ISOFORM_EXPRESSION,
|
|
287
|
-
METABOLITE_INTENSITY,
|
|
288
|
-
MULTIVALUE,
|
|
296
|
+
DNA_METHYLATION2 as DNA_METHYLATION,
|
|
297
|
+
FLOAT2 as FLOAT,
|
|
298
|
+
GENE_EXPRESSION2 as GENE_EXPRESSION,
|
|
299
|
+
GENE_VARIANT2 as GENE_VARIANT,
|
|
300
|
+
INTEGER2 as INTEGER,
|
|
301
|
+
ISOFORM_EXPRESSION2 as ISOFORM_EXPRESSION,
|
|
302
|
+
METABOLITE_INTENSITY2 as METABOLITE_INTENSITY,
|
|
303
|
+
MULTIVALUE2 as MULTIVALUE,
|
|
289
304
|
NUMERIC_DICTIONARY_TERM,
|
|
290
305
|
NumericModes,
|
|
291
|
-
PROTEOME_ABUNDANCE,
|
|
292
|
-
PROTEOME_DAP,
|
|
306
|
+
PROTEOME_ABUNDANCE2 as PROTEOME_ABUNDANCE,
|
|
293
307
|
ROOT_SAMPLE_TYPE,
|
|
294
|
-
SAMPLELST,
|
|
295
|
-
SINGLECELL_CELLTYPE,
|
|
296
|
-
SINGLECELL_GENE_EXPRESSION,
|
|
297
|
-
SNP,
|
|
298
|
-
SNP_LIST,
|
|
299
|
-
SNP_LOCUS,
|
|
300
|
-
SSGSEA,
|
|
301
|
-
SURVIVAL,
|
|
302
|
-
TERM_COLLECTION,
|
|
308
|
+
SAMPLELST2 as SAMPLELST,
|
|
309
|
+
SINGLECELL_CELLTYPE2 as SINGLECELL_CELLTYPE,
|
|
310
|
+
SINGLECELL_GENE_EXPRESSION2 as SINGLECELL_GENE_EXPRESSION,
|
|
311
|
+
SNP2 as SNP,
|
|
312
|
+
SNP_LIST2 as SNP_LIST,
|
|
313
|
+
SNP_LOCUS2 as SNP_LOCUS,
|
|
314
|
+
SSGSEA2 as SSGSEA,
|
|
315
|
+
SURVIVAL2 as SURVIVAL,
|
|
316
|
+
TERM_COLLECTION2 as TERM_COLLECTION,
|
|
303
317
|
TermTypeGroups2 as TermTypeGroups,
|
|
304
|
-
TermTypes,
|
|
318
|
+
TermTypes2 as TermTypes,
|
|
305
319
|
TermTypes2Dt,
|
|
306
|
-
|
|
320
|
+
dictionaryNumericTypes,
|
|
307
321
|
dtTermTypes,
|
|
308
322
|
equals,
|
|
309
323
|
getBin,
|
|
@@ -319,6 +333,7 @@ export {
|
|
|
319
333
|
isNonDictionaryType,
|
|
320
334
|
isNumTermCollection,
|
|
321
335
|
isNumericTerm,
|
|
336
|
+
isParentType,
|
|
322
337
|
isSingleCellTerm,
|
|
323
338
|
numericTypes,
|
|
324
339
|
termType2label,
|
package/dist/src/terms.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/terms.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Term } from '#types'\nimport {\n\tdtgeneexpression,\n\tdtssgsea,\n\tdtdnamethylation,\n\tdtmetaboliteintensity,\n\tdtproteomeabundance,\n\tTermTypeGroups,\n\tdtTerms\n} from './common.js'\n\n// moved TermTypeGroups to `server/src/common.js`, so now has to re-export\nexport { TermTypeGroups } from './common.js'\n\n/*\nFor datasets with multiple types of samples the ROOT_SAMPLE_TYPE is used to represent the root sample type, for example, \nthe type patient, that has one or more samples associated to it. This should be the id used as sample_type, when generating the db to identify the root samples\nin sampleidmap or the terms annotating root samples in the terms table.\nThe samples associated to a patient have annotations that are specific to a timepoint, for example, the age of the patient,\nthe doses of the drugs the patient was taking at the time of the data collection, etc. These annotations are associated to a sample.\n*/\nexport const ROOT_SAMPLE_TYPE = 1\n\n//For datasets with one sample type the DEFAULT_SAMPLE_TYPE is used to represent the sample type\nexport const DEFAULT_SAMPLE_TYPE = 2\n\nexport const NumericModes = {\n\tcontinuous: 'continuous',\n\tdiscrete: 'discrete'\n}\n\nexport const CATEGORICAL = 'categorical'\nexport const CONDITION = 'condition'\nexport const DATE = 'date'\nexport const DNA_METHYLATION = 'dnaMethylation'\nexport const FLOAT = 'float'\nexport const GENE_VARIANT = 'geneVariant'\nexport const GENE_EXPRESSION = 'geneExpression'\nexport const ISOFORM_EXPRESSION = 'isoformExpression'\nexport const INTEGER = 'integer'\nexport const METABOLITE_INTENSITY = 'metaboliteIntensity'\nexport const MULTIVALUE = 'multivalue'\nexport const SAMPLELST = 'samplelst'\nexport const SINGLECELL_CELLTYPE = 'singleCellCellType'\nexport const SINGLECELL_GENE_EXPRESSION = 'singleCellGeneExpression'\nexport const SNP = 'snp'\nexport const SNP_LIST = 'snplst'\nexport const SNP_LOCUS = 'snplocus'\nexport const SSGSEA = 'ssGSEA'\nexport const SURVIVAL = 'survival'\nexport const TERM_COLLECTION = 'termCollection'\nexport const PROTEOME_ABUNDANCE = 'proteomeAbundance'\nexport const PROTEOME_DAP = 'proteomeDAP'\n\n//Term types should be used gradually using these constants instead of hardcoding the values,\n// eg: type == CATEGORICAL instead of type == 'categorical'\nexport const TermTypes: { [key: string]: string } = {\n\tGENE_VARIANT,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tCATEGORICAL,\n\tINTEGER,\n\tFLOAT,\n\tSNP,\n\tSNP_LIST,\n\tSNP_LOCUS,\n\tCONDITION,\n\tSURVIVAL,\n\tSAMPLELST,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_CELLTYPE,\n\tSINGLECELL_GENE_EXPRESSION,\n\tMULTIVALUE,\n\tDATE,\n\tTERM_COLLECTION\n}\nexport const dtTermTypes: Set<string> = new Set(dtTerms.map((t: any) => t.type))\nfor (const dtTermType of dtTermTypes) {\n\tTermTypes[dtTermType.toUpperCase()] = dtTermType\n}\n\nexport const NUMERIC_DICTIONARY_TERM = 'numericDictTerm'\n\nexport const TermTypes2Dt = {\n\t[GENE_EXPRESSION]: dtgeneexpression,\n\t[SSGSEA]: dtssgsea,\n\t[DNA_METHYLATION]: dtdnamethylation,\n\t[METABOLITE_INTENSITY]: dtmetaboliteintensity,\n\t[PROTEOME_ABUNDANCE]: dtproteomeabundance\n}\n\n// maps term type to group (as is shown as toggles in search ui)\nexport const typeGroup = {\n\t[CATEGORICAL]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[CONDITION]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[FLOAT]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[INTEGER]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[SAMPLELST]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[SURVIVAL]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[DATE]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[MULTIVALUE]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[GENE_VARIANT]: TermTypeGroups.MUTATION_CNV_FUSION,\n\t[SNP]: TermTypeGroups.SNP,\n\t[SNP_LIST]: TermTypeGroups.SNP_LIST,\n\t[SNP_LOCUS]: TermTypeGroups.SNP_LOCUS,\n\t[GENE_EXPRESSION]: TermTypeGroups.GENE_EXPRESSION,\n\t[ISOFORM_EXPRESSION]: TermTypeGroups.ISOFORM_EXPRESSION,\n\t[SSGSEA]: TermTypeGroups.SSGSEA,\n\t[DNA_METHYLATION]: TermTypeGroups.DNA_METHYLATION,\n\t[METABOLITE_INTENSITY]: TermTypeGroups.METABOLITE_INTENSITY,\n\t[PROTEOME_ABUNDANCE]: TermTypeGroups.PROTEOME_ABUNDANCE,\n\t[TERM_COLLECTION]: TermTypeGroups.TERM_COLLECTION,\n\t[SINGLECELL_CELLTYPE]: TermTypeGroups.SINGLECELL_CELLTYPE,\n\t[SINGLECELL_GENE_EXPRESSION]: TermTypeGroups.SINGLECELL_GENE_EXPRESSION\n}\n\nconst nonDictTypes = new Set([\n\tSNP,\n\tSNP_LIST,\n\tSNP_LOCUS,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tGENE_VARIANT,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_CELLTYPE,\n\tSINGLECELL_GENE_EXPRESSION\n])\n\nfor (const dtTermType of dtTermTypes) {\n\tnonDictTypes.add(TermTypes[dtTermType.toUpperCase()])\n}\n\nexport const numericTypes = new Set([\n\tINTEGER,\n\tFLOAT,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_GENE_EXPRESSION,\n\tDATE\n])\n\n// available termdb numeric table names used as anno_<term.type>,\n// for example anno_integer, anno_float, anno_date\nexport const annoNumericTypes = new Set([INTEGER, FLOAT, DATE])\n\nconst categoricalTypes = new Set([CATEGORICAL, SNP])\n\nconst singleCellTerms = new Set([SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION])\n\nexport function isSingleCellTerm(term: any) {\n\tif (!term) return false\n\treturn singleCellTerms.has(term.type)\n}\nexport function isNumericTerm(term: Term) {\n\tif (!term) return false\n\treturn numericTypes.has(term.type)\n}\nexport function isCategoricalTerm(term: Term) {\n\tif (!term) return false\n\treturn categoricalTypes.has(term.type)\n}\n\nexport function isDictionaryType(type: string) {\n\treturn !isNonDictionaryType(type)\n}\n\nexport function isNonDictionaryType(type: string) {\n\tif (!type) throw new Error('Type is not defined')\n\treturn nonDictTypes.has(type)\n}\n\nexport function isNumTermCollection(term: Term) {\n\tif (!term || !term.type) throw new Error('Term or term type is not defined')\n\t//Enable this check when memberType is added to term collection\n\t// return term.type === TERM_COLLECTION && term.memberType == 'numeric'\n\treturn term.type === TERM_COLLECTION\n}\n\nexport function equals(t1: any, t2: any) {\n\tif (!t1) throw new Error('First term is not defined ')\n\tif (!t2) throw new Error('Second term is not defined ')\n\tif (t1.type !== t2.type) return false //term types are different\n\tif (isDictionaryType(t1.type) && isDictionaryType(t2.type) && t1.type != SAMPLELST) return t1.id === t2.id\n\tswitch (t1.type) {\n\t\tcase GENE_EXPRESSION:\n\t\t\treturn t1.gene == t2.gene\n\t\tcase ISOFORM_EXPRESSION:\n\t\t\treturn t1.isoform == t2.isoform\n\t\tcase SSGSEA:\n\t\t\treturn t1.id == t2.id\n\t\tcase DNA_METHYLATION:\n\t\t\treturn t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop\n\t\tcase METABOLITE_INTENSITY:\n\t\tcase PROTEOME_ABUNDANCE:\n\t\t\treturn t1.name == t2.name\n\t\tcase GENE_VARIANT:\n\t\t\treturn t1.gene == t2.gene || (t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop)\n\n\t\t// TO DO: Add more cases\n\t\t// case SNP_LIST:\n\t\t// case SNP_LOCUS:\n\t\t// case SAMPLELST:\n\n\t\tdefault:\n\t\t\treturn false\n\t}\n}\n\nexport function getBin(lst: any[], value: number) {\n\tlet bin = lst.findIndex(\n\t\tb => (b.startunbounded && value < b.stop) || (b.startunbounded && b.stopinclusive && value == b.stop)\n\t)\n\tif (bin == -1)\n\t\tbin = lst.findIndex(\n\t\t\tb => (b.stopunbounded && value > b.start) || (b.stopunbounded && b.startinclusive && value == b.start)\n\t\t)\n\tif (bin == -1)\n\t\tbin = lst.findIndex(\n\t\t\tb =>\n\t\t\t\t(value > b.start && value < b.stop) ||\n\t\t\t\t(b.startinclusive && value == b.start) ||\n\t\t\t\t(b.stopinclusive && value == b.stop)\n\t\t)\n\treturn bin\n}\n//Terms may have a sample type associated to them, in datasets with multiple types of samples.\n//For example the gender is associated to the patient while the age is associated to the type sample. This function is used\n//for example when calling getData or getFilter, to return either the parent or the child samples, depending on the use case.\nexport function getSampleType(term: any, ds: any) {\n\tif (!term) return null\n\t//non dict terms annotate only samples, eg: gene expression, metabolite intensity, gene variant.\n\t//Their sample type is the default sample type that may or may not have a parent type, depending on the dataset\n\tif (term.type && isNonDictionaryType(term.type)) return DEFAULT_SAMPLE_TYPE\n\t//dictionary terms may annotate different types of samples, eg: patient and sample or mouse and crop.\n\tif (term.id) return ds.cohort.termdb.term2SampleType.get(term.id)\n\tif (term.type == 'samplelst') {\n\t\tconst key = Object.keys(term.values)[0]\n\t\tconst sampleId = term.values[key].list[0]?.sampleId\n\t\tif (sampleId) return ds.sampleId2Type.get(Number(sampleId) || sampleId)\n\t\telse return DEFAULT_SAMPLE_TYPE\n\t}\n\t// samplelst or non dict terms\n\treturn DEFAULT_SAMPLE_TYPE //later own term needs to know what type annotates based on the samples\n}\n\nexport function getParentType(types: Set<string>, ds: any) {\n\tif (Object.keys(ds.cohort.termdb.sampleTypes).length == 0) return null //dataset only has one type of sample\n\tconst ids = Array.from(types)\n\tif (!ids || ids.length == 0) return null\n\tfor (const id of ids) {\n\t\tconst typeObj = ds.cohort.termdb.sampleTypes[id]\n\t\tif (!typeObj) continue\n\t\tif (typeObj.parent_id == null) return id //this is the root type\n\t\t//if my parent is in the list, then I am not the parent\n\t\tif (ids.includes(typeObj.parent_id)) continue\n\t\telse return typeObj.parent_id //my parent is not in the list, so I am the parent\n\t}\n\treturn null //no parent found\n}\n\n//Returns human readable label for each term type; label is just for printing and not computing\nconst typeMap: { [key: string]: string } = {\n\tcategorical: 'Categorical',\n\tcondition: 'Condition',\n\tfloat: 'Numerical',\n\tinteger: 'Numerical',\n\tgeneExpression: 'Gene Expression',\n\tisoformExpression: 'Isoform Expression',\n\tssGSEA: 'Geneset Expression',\n\tdnaMethylation: 'DNA Methylation',\n\tgeneVariant: 'Gene Variant',\n\tmetaboliteIntensity: 'Metabolite Intensity',\n\tproteomeAbundance: 'Proteome Abundance',\n\tproteomeDAP: 'Proteome DAP',\n\tmultivalue: 'Multi Value',\n\tsingleCellGeneExpression: 'Single Cell, Gene Expression',\n\tsingleCellCellType: 'Single Cell, Cell Type',\n\tsnplocus: 'SNP Locus',\n\tsnp: 'SNP',\n\tsnplst: 'SNP List',\n\tnumericDictTerm: 'Numeric Dictionary Term',\n\ttermCollection: 'Term Collection'\n}\n\nexport function termType2label(type: string) {\n\treturn typeMap[type] || 'Unknown term type'\n}\n\nexport function getDateFromNumber(value: number) {\n\tconst year = Math.floor(value)\n\tconst january1st = new Date(year, 0, 1)\n\tconst totalDays = getDaysInYear(year)\n\tconst time = Math.round((value - year) * totalDays) * oneDayTime\n\tconst date = new Date(january1st.getTime() + time)\n\treturn date\n}\n/*\nValue is a decimal year.\nA decimal year is a way of expressing a date or time period as a year with a decimal part, where the decimal portion \nrepresents the fraction of the year that has elapsed. \nExample:\n2025.0 represents the beginning of the year 2025. \n2025.5 represents the middle of the year 2025. \n */\nconst oneDayTime = 24 * 60 * 60 * 1000\n\nexport function getDateStrFromNumber(value: number) {\n\tconst date = getDateFromNumber(value)\n\n\t//Omit day to deidentify the patients\n\treturn date.toLocaleDateString('en-US', {\n\t\tyear: 'numeric',\n\t\tmonth: 'long'\n\t})\n}\n\n//The value returned is a decimal year\n//A decimal year is a way of expressing a date or time period as a year with a decimal part, where the decimal portion\n//represents the fraction of the year that has elapsed.\nexport function getNumberFromDateStr(str: string) {\n\tconst date = new Date(str)\n\treturn getNumberFromDate(date)\n}\n\nexport function getNumberFromDate(date: Date) {\n\tconst year = date.getFullYear()\n\tconst january1st: Date = new Date(year, 0, 1)\n\tconst diffDays = (date.getTime() - january1st.getTime()) / oneDayTime\n\tconst daysTotal = getDaysInYear(year)\n\tconst decimal = diffDays / daysTotal\n\treturn year + decimal\n}\n\nexport function getDaysInYear(year: number) {\n\tconst isLeap = new Date(year, 1, 29).getMonth() === 1\n\tconst days = isLeap ? 366 : 365\n\treturn days\n}\n"],
|
|
5
|
-
"mappings": "AACA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;
|
|
6
|
-
"names": ["TermTypeGroups"]
|
|
4
|
+
"sourcesContent": ["import type { Term } from '#types'\nimport {\n\tdtgeneexpression,\n\tdtssgsea,\n\tdtdnamethylation,\n\tdtmetaboliteintensity,\n\tdtproteomeabundance,\n\tTermTypeGroups,\n\tdtTerms\n} from './common.js'\nimport {\n\tGENE_VARIANT,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tCATEGORICAL,\n\tINTEGER,\n\tFLOAT,\n\tSNP,\n\tSNP_LIST,\n\tSNP_LOCUS,\n\tCONDITION,\n\tSURVIVAL,\n\tSAMPLELST,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_CELLTYPE,\n\tSINGLECELL_GENE_EXPRESSION,\n\tMULTIVALUE,\n\tDATE,\n\tTERM_COLLECTION,\n\tTermTypes\n} from '#types'\n\n// legacy support - comsumers should import directly from #types (aka @sjcrh/proteinpaint-types)\nexport {\n\tGENE_VARIANT,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tCATEGORICAL,\n\tINTEGER,\n\tFLOAT,\n\tSNP,\n\tSNP_LIST,\n\tSNP_LOCUS,\n\tCONDITION,\n\tSURVIVAL,\n\tSAMPLELST,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_CELLTYPE,\n\tSINGLECELL_GENE_EXPRESSION,\n\tMULTIVALUE,\n\tDATE,\n\tTERM_COLLECTION,\n\tTermTypes\n} from '#types'\n\n// moved TermTypeGroups to `server/src/common.js`, so now has to re-export\nexport { TermTypeGroups } from './common.js'\n\n/*\nFor datasets with multiple types of samples the ROOT_SAMPLE_TYPE is used to represent the root sample type, for example, \nthe type patient, that has one or more samples associated to it. This should be the id used as sample_type, when generating the db to identify the root samples\nin sampleidmap or the terms annotating root samples in the terms table.\nThe samples associated to a patient have annotations that are specific to a timepoint, for example, the age of the patient,\nthe doses of the drugs the patient was taking at the time of the data collection, etc. These annotations are associated to a sample.\n*/\nexport const ROOT_SAMPLE_TYPE = 1\n\n//For datasets with one sample type the DEFAULT_SAMPLE_TYPE is used to represent the sample type\nexport const DEFAULT_SAMPLE_TYPE = 2\n\nexport const NumericModes = {\n\tcontinuous: 'continuous',\n\tdiscrete: 'discrete'\n}\n\nexport const dtTermTypes: Set<string> = new Set(dtTerms.map((t: any) => t.type))\nfor (const dtTermType of dtTermTypes) {\n\tTermTypes[dtTermType.toUpperCase()] = dtTermType\n}\n\nexport const NUMERIC_DICTIONARY_TERM = 'numericDictTerm'\n\nexport const TermTypes2Dt = {\n\t[GENE_EXPRESSION]: dtgeneexpression,\n\t[SSGSEA]: dtssgsea,\n\t[DNA_METHYLATION]: dtdnamethylation,\n\t[METABOLITE_INTENSITY]: dtmetaboliteintensity,\n\t[PROTEOME_ABUNDANCE]: dtproteomeabundance\n}\n\n// maps term type to group (as is shown as toggles in search ui)\nexport const typeGroup = {\n\t[CATEGORICAL]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[CONDITION]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[FLOAT]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[INTEGER]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[SAMPLELST]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[SURVIVAL]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[DATE]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[MULTIVALUE]: TermTypeGroups.DICTIONARY_VARIABLES,\n\t[GENE_VARIANT]: TermTypeGroups.MUTATION_CNV_FUSION,\n\t[SNP]: TermTypeGroups.SNP,\n\t[SNP_LIST]: TermTypeGroups.SNP_LIST,\n\t[SNP_LOCUS]: TermTypeGroups.SNP_LOCUS,\n\t[GENE_EXPRESSION]: TermTypeGroups.GENE_EXPRESSION,\n\t[ISOFORM_EXPRESSION]: TermTypeGroups.ISOFORM_EXPRESSION,\n\t[SSGSEA]: TermTypeGroups.SSGSEA,\n\t[DNA_METHYLATION]: TermTypeGroups.DNA_METHYLATION,\n\t[METABOLITE_INTENSITY]: TermTypeGroups.METABOLITE_INTENSITY,\n\t[PROTEOME_ABUNDANCE]: TermTypeGroups.PROTEOME_ABUNDANCE,\n\t[TERM_COLLECTION]: TermTypeGroups.TERM_COLLECTION,\n\t[SINGLECELL_CELLTYPE]: TermTypeGroups.SINGLECELL_CELLTYPE,\n\t[SINGLECELL_GENE_EXPRESSION]: TermTypeGroups.SINGLECELL_GENE_EXPRESSION\n}\n\nconst nonDictTypes = new Set([\n\tSNP,\n\tSNP_LIST,\n\tSNP_LOCUS,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tGENE_VARIANT,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_CELLTYPE,\n\tSINGLECELL_GENE_EXPRESSION\n])\n\nfor (const dtTermType of dtTermTypes) {\n\tnonDictTypes.add(TermTypes[dtTermType.toUpperCase()])\n}\n\nexport const numericTypes = new Set([\n\tINTEGER,\n\tFLOAT,\n\tGENE_EXPRESSION,\n\tISOFORM_EXPRESSION,\n\tSSGSEA,\n\tDNA_METHYLATION,\n\tMETABOLITE_INTENSITY,\n\tPROTEOME_ABUNDANCE,\n\tSINGLECELL_GENE_EXPRESSION,\n\tDATE\n])\n\n// dictionary numeric term types, exists in db tables, exclude non-dictionary term types\nexport const dictionaryNumericTypes = new Set([INTEGER, FLOAT, DATE])\n\nconst categoricalTypes = new Set([CATEGORICAL, SNP])\n\nconst singleCellTerms = new Set([SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION])\n\nexport function isSingleCellTerm(term: any) {\n\tif (!term) return false\n\treturn singleCellTerms.has(term.type)\n}\nexport function isNumericTerm(term: Term) {\n\tif (!term) return false\n\treturn numericTypes.has(term.type)\n}\nexport function isCategoricalTerm(term: Term) {\n\tif (!term) return false\n\treturn categoricalTypes.has(term.type)\n}\n\nexport function isDictionaryType(type: string) {\n\treturn !isNonDictionaryType(type)\n}\n\nexport function isNonDictionaryType(type: string) {\n\tif (!type) throw new Error('Type is not defined')\n\treturn nonDictTypes.has(type)\n}\n\nexport function isNumTermCollection(term: Term) {\n\tif (!term || !term.type) throw new Error('Term or term type is not defined')\n\t//Enable this check when memberType is added to term collection\n\t// return term.type === TERM_COLLECTION && term.memberType == 'numeric'\n\treturn term.type === TERM_COLLECTION\n}\n\nexport function equals(t1: any, t2: any) {\n\tif (!t1) throw new Error('First term is not defined ')\n\tif (!t2) throw new Error('Second term is not defined ')\n\tif (t1.type !== t2.type) return false //term types are different\n\tif (isDictionaryType(t1.type) && isDictionaryType(t2.type) && t1.type != SAMPLELST) return t1.id === t2.id\n\tswitch (t1.type) {\n\t\tcase GENE_EXPRESSION:\n\t\t\treturn t1.gene == t2.gene\n\t\tcase ISOFORM_EXPRESSION:\n\t\t\treturn t1.isoform == t2.isoform\n\t\tcase SSGSEA:\n\t\t\treturn t1.id == t2.id\n\t\tcase DNA_METHYLATION:\n\t\t\treturn t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop\n\t\tcase METABOLITE_INTENSITY:\n\t\tcase PROTEOME_ABUNDANCE:\n\t\t\treturn t1.name == t2.name\n\t\tcase GENE_VARIANT:\n\t\t\treturn t1.gene == t2.gene || (t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop)\n\n\t\t// TO DO: Add more cases\n\t\t// case SNP_LIST:\n\t\t// case SNP_LOCUS:\n\t\t// case SAMPLELST:\n\n\t\tdefault:\n\t\t\treturn false\n\t}\n}\n\nexport function getBin(lst: any[], value: number) {\n\tlet bin = lst.findIndex(\n\t\tb => (b.startunbounded && value < b.stop) || (b.startunbounded && b.stopinclusive && value == b.stop)\n\t)\n\tif (bin == -1)\n\t\tbin = lst.findIndex(\n\t\t\tb => (b.stopunbounded && value > b.start) || (b.stopunbounded && b.startinclusive && value == b.start)\n\t\t)\n\tif (bin == -1)\n\t\tbin = lst.findIndex(\n\t\t\tb =>\n\t\t\t\t(value > b.start && value < b.stop) ||\n\t\t\t\t(b.startinclusive && value == b.start) ||\n\t\t\t\t(b.stopinclusive && value == b.stop)\n\t\t)\n\treturn bin\n}\n//Terms may have a sample type associated to them, in datasets with multiple types of samples.\n//For example the gender is associated to the patient while the age is associated to the type sample. This function is used\n//for example when calling getData or getFilter, to return either the parent or the child samples, depending on the use case.\nexport function getSampleType(term: any, ds: any) {\n\tif (!term) return null\n\t//non dict terms annotate only samples, eg: gene expression, metabolite intensity, gene variant.\n\t//Their sample type is the default sample type that may or may not have a parent type, depending on the dataset\n\tif (term.type && isNonDictionaryType(term.type)) return DEFAULT_SAMPLE_TYPE\n\t//dictionary terms may annotate different types of samples, eg: patient and sample or mouse and crop.\n\tif (term.id) return ds.cohort.termdb.term2SampleType.get(term.id)\n\tif (term.type == 'samplelst') {\n\t\tconst key = Object.keys(term.values)[0]\n\t\tconst sampleId = term.values[key].list[0]?.sampleId\n\t\tif (sampleId) return ds.sampleId2Type.get(Number(sampleId) || sampleId)\n\t\telse return DEFAULT_SAMPLE_TYPE\n\t}\n\t// samplelst or non dict terms\n\treturn DEFAULT_SAMPLE_TYPE //later own term needs to know what type annotates based on the samples\n}\n\nexport function getParentType(types: Set<string>, ds: any) {\n\tif (Object.keys(ds.cohort.termdb.sampleTypes).length == 0) return null //dataset only has one type of sample\n\tconst ids = Array.from(types)\n\tif (!ids || ids.length == 0) return null\n\tfor (const id of ids) {\n\t\tconst typeObj = ds.cohort.termdb.sampleTypes[id]\n\t\tif (!typeObj) continue\n\t\tif (typeObj.parent_id == null) return id //this is the root type\n\t\t//if my parent is in the list, then I am not the parent\n\t\tif (ids.includes(typeObj.parent_id)) continue\n\t\telse return typeObj.parent_id //my parent is not in the list, so I am the parent\n\t}\n\treturn null //no parent found\n}\n\n// whether the term annotates parent samples\nexport function isParentType(term: any, ds: any) {\n\tif (!ds.cohort.termdb.hasSampleAncestry) return false\n\tconst sampleType = getSampleType(term, ds)\n\tif (!sampleType) throw 'sample type is not defined'\n\tconst sampleTypeObj = ds.cohort.termdb.sampleTypes[sampleType]\n\tif (!sampleTypeObj) throw 'invalid sample type'\n\tif (Number.isInteger(sampleTypeObj.parent_id)) {\n\t\t// sample type has parent, so it is child sample type\n\t\treturn false\n\t} else {\n\t\t// sample type does not have parent, so it is parent sample type\n\t\treturn true\n\t}\n}\n\n//Returns human readable label for each term type; label is just for printing and not computing\nconst typeMap: { [key: string]: string } = {\n\tcategorical: 'Categorical',\n\tcondition: 'Condition',\n\tfloat: 'Numerical',\n\tinteger: 'Numerical',\n\tgeneExpression: 'Gene Expression',\n\tisoformExpression: 'Isoform Expression',\n\tssGSEA: 'Geneset Expression',\n\tdnaMethylation: 'DNA Methylation',\n\tgeneVariant: 'Gene Variant',\n\tmetaboliteIntensity: 'Metabolite Intensity',\n\tproteomeAbundance: 'Proteome Abundance',\n\tproteomeDAP: 'Proteome DAP',\n\tmultivalue: 'Multi Value',\n\tsingleCellGeneExpression: 'Single Cell, Gene Expression',\n\tsingleCellCellType: 'Single Cell, Cell Type',\n\tsnplocus: 'SNP Locus',\n\tsnp: 'SNP',\n\tsnplst: 'SNP List',\n\tnumericDictTerm: 'Numeric Dictionary Term',\n\ttermCollection: 'Term Collection'\n}\n\nexport function termType2label(type: string) {\n\treturn typeMap[type] || 'Unknown term type'\n}\n\nexport function getDateFromNumber(value: number) {\n\tconst year = Math.floor(value)\n\tconst january1st = new Date(year, 0, 1)\n\tconst totalDays = getDaysInYear(year)\n\tconst time = Math.round((value - year) * totalDays) * oneDayTime\n\tconst date = new Date(january1st.getTime() + time)\n\treturn date\n}\n/*\nValue is a decimal year.\nA decimal year is a way of expressing a date or time period as a year with a decimal part, where the decimal portion \nrepresents the fraction of the year that has elapsed. \nExample:\n2025.0 represents the beginning of the year 2025. \n2025.5 represents the middle of the year 2025. \n */\nconst oneDayTime = 24 * 60 * 60 * 1000\n\nexport function getDateStrFromNumber(value: number) {\n\tconst date = getDateFromNumber(value)\n\n\t//Omit day to deidentify the patients\n\treturn date.toLocaleDateString('en-US', {\n\t\tyear: 'numeric',\n\t\tmonth: 'long'\n\t})\n}\n\n//The value returned is a decimal year\n//A decimal year is a way of expressing a date or time period as a year with a decimal part, where the decimal portion\n//represents the fraction of the year that has elapsed.\nexport function getNumberFromDateStr(str: string) {\n\tconst date = new Date(str)\n\treturn getNumberFromDate(date)\n}\n\nexport function getNumberFromDate(date: Date) {\n\tconst year = date.getFullYear()\n\tconst january1st: Date = new Date(year, 0, 1)\n\tconst diffDays = (date.getTime() - january1st.getTime()) / oneDayTime\n\tconst daysTotal = getDaysInYear(year)\n\tconst decimal = diffDays / daysTotal\n\treturn year + decimal\n}\n\nexport function getDaysInYear(year: number) {\n\tconst isLeap = new Date(year, 1, 29).getMonth() === 1\n\tconst days = isLeap ? 366 : 365\n\treturn days\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["GENE_VARIANT", "GENE_EXPRESSION", "ISOFORM_EXPRESSION", "SSGSEA", "DNA_METHYLATION", "CATEGORICAL", "INTEGER", "FLOAT", "SNP", "SNP_LIST", "SNP_LOCUS", "CONDITION", "SURVIVAL", "SAMPLELST", "METABOLITE_INTENSITY", "PROTEOME_ABUNDANCE", "SINGLECELL_CELLTYPE", "SINGLECELL_GENE_EXPRESSION", "MULTIVALUE", "DATE", "TERM_COLLECTION", "TermTypes", "TermTypeGroups"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,43 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-shared",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.190.0",
|
|
4
4
|
"description": "ProteinPaint code that is shared between server and client-side workspaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
7
7
|
"imports": {
|
|
8
8
|
"#types": "@sjcrh/proteinpaint-types",
|
|
9
|
-
"#types/*": "@sjcrh/proteinpaint-types/*"
|
|
10
|
-
"#types/checkers": "@sjcrh/proteinpaint-types/checkers"
|
|
9
|
+
"#types/*": "@sjcrh/proteinpaint-types/*"
|
|
11
10
|
},
|
|
12
|
-
"//": "all export aliases below are meant for runtime code, except for devTs-aliased
|
|
11
|
+
"//": "all export aliases below are meant for runtime code, except for the devTs-aliased subpath",
|
|
13
12
|
"exports": {
|
|
14
|
-
".":
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
".": {
|
|
14
|
+
"sjpp/dev": "./src/index.ts",
|
|
15
|
+
"default": "./dist/src/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./*.ts": {
|
|
18
|
+
"sjpp/dev": "./src/*.ts",
|
|
19
|
+
"default": "./*.ts_SHOULD_BE_js"
|
|
20
|
+
},
|
|
21
|
+
"./*": {
|
|
22
|
+
"sjpp/dev": "./src/*",
|
|
23
|
+
"default": "./dist/src/*"
|
|
24
|
+
}
|
|
21
25
|
},
|
|
22
26
|
"scripts": {
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
27
|
+
"ts2js": "esbuild src/*.* src/**/*.* --platform=node --outdir=dist/src --format=esm --sourcemap",
|
|
28
|
+
"build": "rm -rf dist && npm run ts2js && rm -rf dist/**/*.spec.* dist/**/test && tsc --sourcemap --skipLibCheck",
|
|
29
|
+
"prepack": "npm run build",
|
|
30
|
+
"dev0": "rm -rf dist && 'npx tsc --watch --skipLibCheck --preserveWatchOutput'",
|
|
31
|
+
"dev": "echo '--- now using raw shared/utils/src exports under conditions=sjpp/dev ---\n'",
|
|
26
32
|
"pretest": "mkdir -p test && node emitImports > test/internals-test.ts",
|
|
27
|
-
"test": "tsx test/internals-test.ts",
|
|
33
|
+
"test": "tsx --conditions=sjpp/dev test/internals-test.ts",
|
|
28
34
|
"test-x": "ls src/test/*.spec* | xargs -I % bash -c '{ tsx %; sleep 0.001; }'",
|
|
29
35
|
"spec:coverage": "node test/relevant.js"
|
|
30
36
|
},
|
|
31
37
|
"author": "",
|
|
32
38
|
"license": "ISC",
|
|
33
39
|
"files": [
|
|
34
|
-
"constants",
|
|
35
|
-
"devTs.ts",
|
|
36
40
|
"dist"
|
|
37
41
|
],
|
|
38
|
-
"devDependencies": {
|
|
39
|
-
"esbuild": "^0.25.9"
|
|
40
|
-
},
|
|
41
42
|
"repository": {
|
|
42
43
|
"type": "git",
|
|
43
44
|
"url": "https://github.com/stjude/proteinpaint",
|
package/constants/AiHisto.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export const FlagStatus = {
|
|
2
|
-
Normal: 0,
|
|
3
|
-
Skipped: 1,
|
|
4
|
-
Flagged: 2,
|
|
5
|
-
Deleted: 3
|
|
6
|
-
} as const
|
|
7
|
-
|
|
8
|
-
export type FlagStatusValues = (typeof FlagStatus)[keyof typeof FlagStatus]
|
|
9
|
-
|
|
10
|
-
export const FeaturePrefixes = {
|
|
11
|
-
Star: 'annotation-star-',
|
|
12
|
-
Square: 'annotation-square-',
|
|
13
|
-
Border: 'annotation-border-',
|
|
14
|
-
PredBorder: 'prediction-border-'
|
|
15
|
-
} as const
|
|
16
|
-
|
|
17
|
-
export type FeaturePrefixValues = (typeof FeaturePrefixes)[keyof typeof FeaturePrefixes]
|
|
18
|
-
|
|
19
|
-
export const SelectionPrefixes = {
|
|
20
|
-
TileSelection: 'ts_',
|
|
21
|
-
Prediction: 'pred_',
|
|
22
|
-
Annotation: 'anno_'
|
|
23
|
-
} as const
|
|
24
|
-
|
|
25
|
-
export type SelectionPrefixValues = (typeof SelectionPrefixes)[keyof typeof SelectionPrefixes]
|
|
26
|
-
//Didn't add Deleted to FlagStatusMessages because deleted annotations dont exist and deleted predictons are filtered out in /Users/jsimps98/dev/sjpp/proteinpaint/server/routes/aiProjectSelectedWSImages.ts line 119
|
|
27
|
-
export const FlagStatusMessages = {
|
|
28
|
-
[FlagStatus.Normal]: '',
|
|
29
|
-
[FlagStatus.Skipped]: '(Skipped)',
|
|
30
|
-
[FlagStatus.Flagged]: '(Flagged)'
|
|
31
|
-
}
|
package/constants/README.md
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Shared Constants
|
|
2
|
-
|
|
3
|
-
The goal of the `constants` code is to allow shared/types code to be able to import type definitions
|
|
4
|
-
from shared/utils with no bundling or tsc compilation issues. Ideally, there would be a separate
|
|
5
|
-
`shared/constants` workspace. However, due to time constraints and effort required to set up a
|
|
6
|
-
new workspace, this `shared/utils/constants` directory was created instead.
|
|
7
|
-
|
|
8
|
-
The code files in proteinpaint/shared/utils/constants:
|
|
9
|
-
- typescript files
|
|
10
|
-
- must have no imports from outside this folder, to prevent cyclical references/imports that crash bundling and/or tsc compilation
|
|
11
|
-
- must export constants that can be transitively exported to devTs.ts file and shared/utils/src/index.js
|
package/devTs.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export declare const FlagStatus: {
|
|
2
|
-
readonly Normal: 0;
|
|
3
|
-
readonly Skipped: 1;
|
|
4
|
-
readonly Flagged: 2;
|
|
5
|
-
readonly Deleted: 3;
|
|
6
|
-
};
|
|
7
|
-
export type FlagStatusValues = (typeof FlagStatus)[keyof typeof FlagStatus];
|
|
8
|
-
export declare const FeaturePrefixes: {
|
|
9
|
-
readonly Star: "annotation-star-";
|
|
10
|
-
readonly Square: "annotation-square-";
|
|
11
|
-
readonly Border: "annotation-border-";
|
|
12
|
-
readonly PredBorder: "prediction-border-";
|
|
13
|
-
};
|
|
14
|
-
export type FeaturePrefixValues = (typeof FeaturePrefixes)[keyof typeof FeaturePrefixes];
|
|
15
|
-
export declare const SelectionPrefixes: {
|
|
16
|
-
readonly TileSelection: "ts_";
|
|
17
|
-
readonly Prediction: "pred_";
|
|
18
|
-
readonly Annotation: "anno_";
|
|
19
|
-
};
|
|
20
|
-
export type SelectionPrefixValues = (typeof SelectionPrefixes)[keyof typeof SelectionPrefixes];
|
|
21
|
-
export declare const FlagStatusMessages: {
|
|
22
|
-
0: string;
|
|
23
|
-
1: string;
|
|
24
|
-
2: string;
|
|
25
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
const FlagStatus = {
|
|
2
|
-
Normal: 0,
|
|
3
|
-
Skipped: 1,
|
|
4
|
-
Flagged: 2,
|
|
5
|
-
Deleted: 3
|
|
6
|
-
};
|
|
7
|
-
const FeaturePrefixes = {
|
|
8
|
-
Star: "annotation-star-",
|
|
9
|
-
Square: "annotation-square-",
|
|
10
|
-
Border: "annotation-border-",
|
|
11
|
-
PredBorder: "prediction-border-"
|
|
12
|
-
};
|
|
13
|
-
const SelectionPrefixes = {
|
|
14
|
-
TileSelection: "ts_",
|
|
15
|
-
Prediction: "pred_",
|
|
16
|
-
Annotation: "anno_"
|
|
17
|
-
};
|
|
18
|
-
const FlagStatusMessages = {
|
|
19
|
-
[FlagStatus.Normal]: "",
|
|
20
|
-
[FlagStatus.Skipped]: "(Skipped)",
|
|
21
|
-
[FlagStatus.Flagged]: "(Flagged)"
|
|
22
|
-
};
|
|
23
|
-
export {
|
|
24
|
-
FeaturePrefixes,
|
|
25
|
-
FlagStatus,
|
|
26
|
-
FlagStatusMessages,
|
|
27
|
-
SelectionPrefixes
|
|
28
|
-
};
|
|
29
|
-
//# sourceMappingURL=AiHisto.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../constants/AiHisto.ts"],
|
|
4
|
-
"sourcesContent": ["export const FlagStatus = {\n\tNormal: 0,\n\tSkipped: 1,\n\tFlagged: 2,\n\tDeleted: 3\n} as const\n\nexport type FlagStatusValues = (typeof FlagStatus)[keyof typeof FlagStatus]\n\nexport const FeaturePrefixes = {\n\tStar: 'annotation-star-',\n\tSquare: 'annotation-square-',\n\tBorder: 'annotation-border-',\n\tPredBorder: 'prediction-border-'\n} as const\n\nexport type FeaturePrefixValues = (typeof FeaturePrefixes)[keyof typeof FeaturePrefixes]\n\nexport const SelectionPrefixes = {\n\tTileSelection: 'ts_',\n\tPrediction: 'pred_',\n\tAnnotation: 'anno_'\n} as const\n\nexport type SelectionPrefixValues = (typeof SelectionPrefixes)[keyof typeof SelectionPrefixes]\n//Didn't add Deleted to FlagStatusMessages because deleted annotations dont exist and deleted predictons are filtered out in /Users/jsimps98/dev/sjpp/proteinpaint/server/routes/aiProjectSelectedWSImages.ts line 119\nexport const FlagStatusMessages = {\n\t[FlagStatus.Normal]: '',\n\t[FlagStatus.Skipped]: '(Skipped)',\n\t[FlagStatus.Flagged]: '(Flagged)'\n}\n"],
|
|
5
|
-
"mappings": "AAAO,MAAM,aAAa;AAAA,EACzB,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AACV;AAIO,MAAM,kBAAkB;AAAA,EAC9B,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AACb;AAIO,MAAM,oBAAoB;AAAA,EAChC,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,YAAY;AACb;AAIO,MAAM,qBAAqB;AAAA,EACjC,CAAC,WAAW,MAAM,GAAG;AAAA,EACrB,CAAC,WAAW,OAAO,GAAG;AAAA,EACtB,CAAC,WAAW,OAAO,GAAG;AACvB;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/src/aiHisto.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type TileSelection } from '@sjcrh/proteinpaint-types';
|
|
2
|
-
import type { FeaturePrefixValues, SelectionPrefixValues } from '../constants/AiHisto.js';
|
|
3
|
-
export declare function createSelectionID(prefix: SelectionPrefixValues, coordinates: [number, number]): string;
|
|
4
|
-
export declare function checkSelectionType(tileSelection: TileSelection, suspectedPrefix: SelectionPrefixValues): boolean;
|
|
5
|
-
export declare function createFeatureID(featurePrefix: FeaturePrefixValues, coords: [number, number]): string;
|
package/dist/src/aiHisto.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
function createSelectionID(prefix, coordinates) {
|
|
2
|
-
return prefix + JSON.stringify(coordinates);
|
|
3
|
-
}
|
|
4
|
-
function checkSelectionType(tileSelection, suspectedPrefix) {
|
|
5
|
-
return tileSelection.id.startsWith(suspectedPrefix);
|
|
6
|
-
}
|
|
7
|
-
function createFeatureID(featurePrefix, coords) {
|
|
8
|
-
return featurePrefix + JSON.stringify(coords);
|
|
9
|
-
}
|
|
10
|
-
export {
|
|
11
|
-
checkSelectionType,
|
|
12
|
-
createFeatureID,
|
|
13
|
-
createSelectionID
|
|
14
|
-
};
|
|
15
|
-
//# sourceMappingURL=aiHisto.js.map
|
package/dist/src/aiHisto.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/aiHisto.ts"],
|
|
4
|
-
"sourcesContent": ["import { type TileSelection } from '@sjcrh/proteinpaint-types'\nimport type { FeaturePrefixValues, SelectionPrefixValues } from '../constants/AiHisto.js'\n\nexport function createSelectionID(prefix: SelectionPrefixValues, coordinates: [number, number]): string {\n\treturn prefix + JSON.stringify(coordinates)\n}\n\nexport function checkSelectionType(tileSelection: TileSelection, suspectedPrefix: SelectionPrefixValues): boolean {\n\treturn tileSelection.id.startsWith(suspectedPrefix)\n}\n\nexport function createFeatureID(featurePrefix: FeaturePrefixValues, coords: [number, number]) {\n\treturn featurePrefix + JSON.stringify(coords)\n}\n"],
|
|
5
|
-
"mappings": "AAGO,SAAS,kBAAkB,QAA+B,aAAuC;AACvG,SAAO,SAAS,KAAK,UAAU,WAAW;AAC3C;AAEO,SAAS,mBAAmB,eAA8B,iBAAiD;AACjH,SAAO,cAAc,GAAG,WAAW,eAAe;AACnD;AAEO,SAAS,gBAAgB,eAAoC,QAA0B;AAC7F,SAAO,gBAAgB,KAAK,UAAU,MAAM;AAC7C;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|