mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-23 00:48:11 -07:00
67 lines
1.9 KiB
JavaScript
67 lines
1.9 KiB
JavaScript
import { brk } from "../../utils/client.js";
|
|
import { relevance } from "./text.js";
|
|
|
|
/** @type {Promise<any[]> | undefined} */
|
|
let catalogPromise;
|
|
|
|
/** @param {any} node @param {string[]} breadcrumbs */
|
|
function record(node, breadcrumbs) {
|
|
if (!node.chart) return undefined;
|
|
const series = node.chart.series.flatMap((/** @type {any} */ entry) => {
|
|
try {
|
|
const metric = entry.metric(brk);
|
|
return metric?.name
|
|
? [{ name: metric.name, label: entry.label }]
|
|
: [];
|
|
} catch {
|
|
return [];
|
|
}
|
|
});
|
|
return {
|
|
title: node.chart.title ?? node.title,
|
|
sectionTitle: node.title,
|
|
breadcrumbs,
|
|
description: node.description ?? "",
|
|
unit: node.chart.unit?.id,
|
|
series,
|
|
};
|
|
}
|
|
|
|
/** @param {any[]} nodes @param {string[]} ancestors @param {any[]} output */
|
|
function walk(nodes, ancestors, output) {
|
|
for (const node of nodes) {
|
|
const breadcrumbs = [...ancestors, node.title];
|
|
const item = record(node, breadcrumbs);
|
|
if (item) output.push(item);
|
|
if (node.children) walk(node.children, breadcrumbs, output);
|
|
}
|
|
}
|
|
|
|
async function learnCatalog() {
|
|
catalogPromise ??= import("../../learn/data/index.js").then(({ sections }) => {
|
|
/** @type {any[]} */
|
|
const output = [];
|
|
walk(sections, [], output);
|
|
return output;
|
|
});
|
|
return catalogPromise;
|
|
}
|
|
|
|
/** @param {string} query @param {number} [limit] */
|
|
export async function searchLearn(query, limit = 12) {
|
|
return (await learnCatalog())
|
|
.map((/** @type {any} */ item) => ({
|
|
...item,
|
|
score:
|
|
relevance(query, `${item.title} ${item.sectionTitle}`) * 3 +
|
|
relevance(query, item.breadcrumbs.join(" ")) * 2 +
|
|
relevance(
|
|
query,
|
|
`${item.description} ${item.series.flatMap((/** @type {any} */ series) => [series.label, series.name]).join(" ")}`,
|
|
),
|
|
}))
|
|
.filter(({ score }) => score >= 16)
|
|
.sort((left, right) => right.score - left.score)
|
|
.slice(0, limit);
|
|
}
|