app/kb/registry/search-inputs.mjs
92 lines and 8 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| registrySearchUid | 11 to 14 | 1 | 100% | OkCRAP 1 | No data: no mutants in this code |
| primerBody | 23 to 42 | 5 | 0% | WatchCRAP 30 | No data: no mutants in this code |
| strainBody | 50 to 53 | 1 | 100% | OkCRAP 1 | No data: no mutants in this code |
| reagentBody | 61 to 66 | 2 | 100% | OkCRAP 2 | No data: no mutants in this code |
| equipmentBody | 69 to 72 | 1 | 100% | OkCRAP 1 | No data: no mutants in this code |
| registrySearchInput | 88 to 92 | 3 | 100% | OkCRAP 3 | No data: no mutants in this code |
| registrySearchInputs | 95 to 101 | 1 | 50% | OkCRAP 1.1 | No data: no mutants in this code |
| <anonymous:96> | 96 to 100 | 3 | 0% | WatchCRAP 12 | No data: no mutants in this code |
Imports
It imports app/kb/registry/catalog.mjs, app/kb/registry/primer.mjs, app/kb/registry/strain.mjs. Imported by app/kb/registry/save.server.ts.
Source
// What the site's search finds for a registry item (docs/REGISTRY.md): one record per published item, so a search for a primer's
// sequence, its target, its reference or the paper that prints it finds the primer's own page as well as the protocols that use
// it. The record is derived from the item and nothing else, so a save, sync_registry and sync:content write the same text, and a
// draft has none. Like a paper's, it is one record with no deep links: an item has no sections to link to.
import { itemPath, primerRow, siteText } from "./catalog.mjs";
import { stated } from "./primer.mjs";
import { designationOf } from "./strain.mjs";
/** The item's search uid: a removal needs it to find the item's record. @param {string} kind @param {string} id */
export function registrySearchUid(kind, id) {
// The registry: namespace keeps these uids separable from hand-authored pages and papers when search_docs is pruned.
return `registry:${kind}/${id}`;
}
/**
* The words a primer is searched by: what it is, its sequence and reverse complement (a sequence search finds either strand),
* where it binds, and the paper that prints it. Only facts the record states or computes; a fact that could not be found is
* not a word to find.
*
* @param {import("./kinds.mjs").RegistryItem} item
*/
function primerBody(item) {
const row = primerRow(item);
return [
row.name,
row.direction ? `${row.direction} primer` : "primer",
row.sequence,
row.reverseComplement,
row.target,
row.set,
row.length ? `${row.length} nt` : null,
row.placement ? `${row.placement.reference.id} ${row.placement.reference.description}` : null,
...(row.placement ? row.placement.sites.map(siteText) : []),
row.publishedIn,
row.publishedDoi,
row.publishedName,
row.publishedSequence,
]
.filter(Boolean)
.join(" ");
}
/**
* The words a strain is searched by: its organism, designation, collection and number. The phages isolated on it are the
* phages table's own records and are not copied into this one.
*
* @param {import("./kinds.mjs").RegistryItem} item
*/
function strainBody(item) {
const f = /** @type {Record<string, unknown>} */ (item.fields);
return [item.name, "strain", "host", stated(f.organism), designationOf(f), stated(f.collection), stated(f.collection_number)].filter(Boolean).join(" ");
}
/**
* The words a reagent is searched by: its name, what a protocol calls it or makes it of, and where it comes from. A gap is not a
* word to find.
*
* @param {import("./kinds.mjs").RegistryItem} item
*/
function reagentBody(item) {
const f = /** @type {Record<string, unknown>} */ (item.fields);
return [item.name, "reagent", stated(f.abbreviation), stated(f.contents), f.prepared_in_lab === true ? "prepared in the lab" : null, stated(f.supplier), stated(f.catalog_number)]
.filter(Boolean)
.join(" ");
}
/** The words an item of equipment is searched by: its name, who makes it and a centrifuge's rotor. @param {import("./kinds.mjs").RegistryItem} item */
function equipmentBody(item) {
const f = /** @type {Record<string, unknown>} */ (item.fields);
return [item.name, "equipment", stated(f.manufacturer), stated(f.rotor)].filter(Boolean).join(" ");
}
/** Each kind's search words. A kind with none is not indexed, so a kind added later is not indexed by accident. */
const BODIES = /** @type {Record<string, (item: import("./kinds.mjs").RegistryItem) => string>} */ ({
primer: primerBody,
strain: strainBody,
reagent: reagentBody,
equipment: equipmentBody,
});
/**
* The record input of one item, or null for a kind with no search body yet (so a kind added later is not indexed by accident).
*
* @param {import("./kinds.mjs").RegistryItem} item
* @returns {{ uid: string, url: string, title: string, body: string } | null}
*/
export function registrySearchInput(item) {
const body = BODIES[item.kind]?.(item) ?? null;
if (body === null) return null;
return { uid: registrySearchUid(item.kind, item.id), url: itemPath(item.kind, item.id), title: item.name, body };
}
/** The inputs of every published item that has one, for the build's search artifact. @param {import("./kinds.mjs").RegistryItem[]} items */
export function registrySearchInputs(items) {
return items.flatMap((item) => {
if (item.status === "draft") return [];
const input = registrySearchInput(item);
return input ? [input] : [];
});
}