import { memo, useEffect, useMemo, useState, Fragment } from 'react'; import jsdocJson from '../../../../../doc.json'; import { Textbox } from '../textbox/Textbox'; const isValid = ({ name, description }) => name && !name.startsWith('_') && !!description; const availableFunctions = (() => { const seen = new Set(); // avoid repetition const functions = []; for (const doc of jsdocJson.docs) { if (!isValid(doc)) continue; if (seen.has(doc.name)) continue; // jsdoc also uses "tags" for when you use @something in the comments and it doesn't know what // @something is. We only want data from comments like `@tags fx, superdough` here. // If nothing is specified, we default to "untagged" for debugging doc.tags = doc.tags?.filter((t) => t && typeof t === 'string') || ['untagged']; functions.push(doc); const synonyms = doc.synonyms || []; seen.add(doc.name); for (const s of synonyms) { if (!s || seen.has(s)) continue; seen.add(s); // Swap `doc.name` in for `s` in the list of synonyms const synonymsWithDoc = [doc.name, ...synonyms].filter((x) => x && x !== s); functions.push({ ...doc, name: s, // update names for the synonym longname: s, synonyms: synonymsWithDoc, synonyms_text: synonymsWithDoc.join(', '), }); } } return functions.sort((a, b) => /* a.meta.filename.localeCompare(b.meta.filename) + */ a.name.localeCompare(b.name)); })(); const getInnerText = (html) => { var div = document.createElement('div'); div.innerHTML = html; return div.textContent || div.innerText || ''; }; export const Reference = memo(function Reference() { const [search, setSearch] = useState(''); const [selectedTag, setSelectedTag] = useState(null); const [selectedFunction, setSelectedFunction] = useState(null); const toggleTag = (tag) => { if (selectedTag === tag) { setSelectedTag(null); } else { setSelectedTag(tag); } }; const searchVisibleFunctions = useMemo(() => { return availableFunctions.filter((entry) => { if (selectedTag) { if (!(entry.tags || ['untagged']).includes(selectedTag)) { return false; } } if (!search) { return true; } const lowerCaseSearch = search.toLowerCase(); return ( entry.name.toLowerCase().includes(lowerCaseSearch) || (entry.synonyms?.some((s) => s.toLowerCase().includes(lowerCaseSearch)) ?? false) ); }); }, [search, selectedTag]); const detailVisibleFunctions = useMemo(() => { return searchVisibleFunctions.filter((x) => { if (selectedTag === null) { if (search) { return true; } return x.name === selectedFunction; } else { return true; } }); }, [searchVisibleFunctions, selectedFunction, selectedTag]); const tagCounts = {}; for (const doc of availableFunctions) { (doc.tags || ['untagged']).forEach((t) => { if (typeof t === 'string' && t) { tagCounts[t] = (tagCounts[t] || 0) + 1; } }); } const onSearchTagFilterClick = () => { setSelectedTag(null); setSelectedFunction(null); }; useEffect(() => { if (selectedFunction) { const el = document.getElementById(`doc-${selectedFunction}`); const container = document.getElementById('reference-container'); container.scrollTo(0, el.offsetTop); } }, [selectedFunction]); return (
{ setSelectedFunction(null); setSearch(e); }} />
{selectedTag && (
{selectedTag}
)}
{searchVisibleFunctions.map((entry, i) => ( { if (entry.name === selectedFunction) { setSelectedFunction(null); } else { setSelectedFunction(entry.name); } }} > {entry.name} {' '} ))}

API Reference

This is the long list of functions you can use. Remember that you don't need to remember all of those and that you can already make music with a small set of functions!

{Object.entries(tagCounts) .sort(([a], [b]) => a.localeCompare(b)) .map(([t, count]) => ( toggleTag(t)} > {t} ({count}) {' '} ))}
{detailVisibleFunctions.map((entry, i) => (

{entry.name}

{entry.tags && ( {entry.tags.join(', ')} )}
{!!entry.synonyms_text && (

Synonyms: {entry.synonyms_text}

)} {/* {entry.meta.filename} */}

    {entry.params?.map(({ name, type, description }, i) => (
  • {name} : {type?.names?.join(' | ')} {description ? <> - {getInnerText(description)} : ''}
  • ))}
{entry.examples?.map((example, j) => (
                  {example}
                
))}
)) ||

Searcb or select a tag to get started.

} {detailVisibleFunctions.length > 0 &&
}
); });