jevstrudel.git / website / src / jev / reference.mjs

The reference tab's functions (repl/components/panel/Reference.jsx), out of jsdoc's doc.json, as data both it and the MCP's api_reference read: the tab renders referenceFunctions, and pages/jev/reference.json.js writes referenceData for the Worker (worker/src/reference.ts).

What the tab lists: named, not internal, described, and not only for an engine other than superdough.

8const isValid = ({ name, description, tags = [] }) => {
9  const isSupradoughOnly = tags.includes('supradough') && !tags.includes('superdough');
10  const isSuperdirtOnly = tags.includes('superdirt') && !tags.includes('superdough');
11  return name && !name.startsWith('_') && !!description && !isSupradoughOnly && !isSuperdirtOnly;
12};

Each function once, under its first name; a synonym another function already took is dropped. tags only jsdoc's @tags strings ('untagged' when none), synonyms the names left, allNames all of them.

17export function referenceFunctions(docs) {
18  const seen = new Set();
19  const functions = [];
20  for (const doc of docs) {
21    if (!isValid(doc) || seen.has(doc.name)) continue;
22    const tags = doc.tags?.filter((t) => t && typeof t === 'string') || ['untagged'];
23    const names = [doc.name];
24    seen.add(doc.name);
25    for (const s of doc.synonyms || []) {
26      if (!s || seen.has(s)) continue;
27      names.push(s);
28      seen.add(s);
29    }
30    functions.push({ ...doc, tags, allNames: names.join(' '), synonyms: names.slice(1) });
31  }
32  return functions.sort((a, b) => a.name.localeCompare(b.name));
33}
35const ENTITIES = { amp: '&', lt: '<', gt: '>', quot: '"', '#39': "'", apos: "'", nbsp: ' ' };

jsdoc's HTML as plain text: paragraphs as blank lines, list items as '- ' lines, no tags.

39export function htmlText(html) {
40  return String(html ?? '')
41    .replace(/<\/p>\s*<p>/g, '\n\n')
42    .replace(/<br\s*\/?>/g, '\n')
43    .replace(/<li>\s*/g, '- ')
44    .replace(/<[^>]*>/g, '')
45    .replace(/&(amp|lt|gt|quot|#39|apos|nbsp);/g, (_, e) => ENTITIES[e])
46    .replace(/[ \t]+/g, ' ')
47    .replace(/\n{3,}/g, '\n\n')
48    .trim();
49}

What api_reference serves: every function the tab lists, as text.

52export function referenceData(docs) {
53  return referenceFunctions(docs).map((f) => ({
54    name: f.name,
55    synonyms: f.synonyms,
56    tags: f.tags.filter((t) => !['supradough', 'superdirt'].includes(t)),
57    description: htmlText(f.description),
58    params: (f.params ?? []).map((p) => ({
59      name: String(p.name ?? ''),
60      type: (p.type?.names ?? []).join(' | '),
61      description: htmlText(p.description),
62    })),
63    examples: (f.examples ?? []).filter((e) => typeof e === 'string'),
64  }));
65}