mirror of
https://github.com/hsjobeki/noogle.git
synced 2024-09-11 12:59:09 +03:00
some small fixes & refactoring
This commit is contained in:
parent
1a9dddb549
commit
4f268a851c
@ -29,7 +29,7 @@ const getKey = (item: DocItem) => `${item.category}/${item.name}`;
|
||||
|
||||
export default function FunctionItem(props: FunctionItemProps) {
|
||||
const { name, docItem, selected, handleClose } = props;
|
||||
const { fn_type, category, description } = docItem;
|
||||
const { fn_type, category, description, id } = docItem;
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const [favorites, setfavorites] = useLocalStorage<string[]>(
|
||||
"personal-favorite",
|
||||
@ -104,12 +104,7 @@ export default function FunctionItem(props: FunctionItemProps) {
|
||||
<Box sx={{ float: "right", position: "absolute", right: 4 }}>
|
||||
{isFavorit && <StarIcon />}
|
||||
</Box>
|
||||
<ListItemText
|
||||
primary={`${
|
||||
category.includes(".nix") ? "lib" : "builtins"
|
||||
}.${name}`}
|
||||
secondary={category}
|
||||
/>
|
||||
<ListItemText primary={`${id}`} secondary={category} />
|
||||
<ListItemText secondary={descriptionPreview} />
|
||||
<Typography
|
||||
sx={{
|
||||
|
@ -23,6 +23,7 @@ import styles from "./preview.module.css";
|
||||
import rehypeHighlight from "rehype-highlight";
|
||||
import nix from "highlight.js/lib/languages/nix";
|
||||
import Link from "next/link";
|
||||
import { idText } from "typescript";
|
||||
|
||||
// import "highlight.js/styles/github-dark.css";
|
||||
// import "highlight.js/styles/github.css";
|
||||
@ -35,7 +36,7 @@ interface PreviewProps {
|
||||
|
||||
export const Preview = (props: PreviewProps) => {
|
||||
const { docItem, handleClose, closeComponent = undefined } = props;
|
||||
const { name, description, category, example, fn_type } = docItem;
|
||||
const { name, description, category, example, fn_type, id } = docItem;
|
||||
const theme = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
@ -72,7 +73,9 @@ export const Preview = (props: PreviewProps) => {
|
||||
<Typography
|
||||
variant="h4"
|
||||
sx={{ wordWrap: "normal", lineBreak: "anywhere" }}
|
||||
>{`${prefix}.${name}`}</Typography>
|
||||
>
|
||||
{`${id}`}
|
||||
</Typography>
|
||||
{closeComponent || (
|
||||
<Tooltip title="close details">
|
||||
<IconButton
|
||||
@ -89,13 +92,18 @@ export const Preview = (props: PreviewProps) => {
|
||||
</Tooltip>
|
||||
)}
|
||||
</Box>
|
||||
{
|
||||
<Box sx={{ my: 1 }}>
|
||||
<Typography variant="subtitle1">{`short form: lib.${name}`}</Typography>
|
||||
</Box>
|
||||
}
|
||||
<List sx={{ width: "100%" }} disablePadding>
|
||||
<ListItem sx={{ flexDirection: { xs: "column", sm: "row" }, px: 0 }}>
|
||||
<ListItemIcon>
|
||||
<Tooltip title={"read docs"}>
|
||||
<MuiLink sx={{ m: "auto", color: "primary.light" }}>
|
||||
<Link
|
||||
href={prefix != "builtins" ? libDocsRef : builtinsDocsRef}
|
||||
href={!id.includes("builtins") ? libDocsRef : builtinsDocsRef}
|
||||
>
|
||||
<LocalLibraryIcon sx={{ m: "auto" }} />
|
||||
</Link>
|
||||
@ -120,7 +128,7 @@ export const Preview = (props: PreviewProps) => {
|
||||
component: "div",
|
||||
}}
|
||||
primary={
|
||||
prefix !== "builtins" ? (
|
||||
!id.includes("builtins") ? (
|
||||
<Tooltip title={"browse source code"}>
|
||||
<MuiLink>
|
||||
<Link
|
||||
@ -147,7 +155,7 @@ export const Preview = (props: PreviewProps) => {
|
||||
}}
|
||||
maxWidth="md"
|
||||
>
|
||||
{typeof description === "object"
|
||||
{Array.isArray(description)
|
||||
? description.map((d, idx) => (
|
||||
<ReactMarkdown
|
||||
key={idx}
|
||||
|
@ -263,11 +263,11 @@
|
||||
"rust-overlay": "rust-overlay"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1670665290,
|
||||
"narHash": "sha256-VkuPWVA+DF1AYx4hdw7JUxrJOdHP/cLhyL+t+xH9UsU=",
|
||||
"lastModified": 1673188789,
|
||||
"narHash": "sha256-Oj6blvGWqut923D3N+xb2iO/j6fl0ZJMbxAQ8FR3xv4=",
|
||||
"owner": "hsjobeki",
|
||||
"repo": "nixdoc",
|
||||
"rev": "f9377fac1265f1e02329343aaff573dff68f9402",
|
||||
"rev": "c8fd16629e40956b9839f7aa4df0d70dbb351f3f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
File diff suppressed because one or more lines are too long
2575
models/lib.json
2575
models/lib.json
File diff suppressed because one or more lines are too long
143
package-lock.json
generated
143
package-lock.json
generated
@ -16,7 +16,6 @@
|
||||
"@types/node": "18.11.9",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "18.0.8",
|
||||
"beautiful-react-hooks": "^3.11.2",
|
||||
"eslint": "8.27.0",
|
||||
"eslint-config-next": "13.0.2",
|
||||
"highlight.js": "^11.7.0",
|
||||
@ -1264,15 +1263,6 @@
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.5.tgz",
|
||||
"integrity": "sha512-my0Mycd+jruq/1lQuO5LBB6WTlL/e8DTCYWp44DfMTDcXz8DcTlgF0ISaLsGewt+ctHN+yA8xMq3q/N7uWJPug==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@rushstack/eslint-patch": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
|
||||
@ -1668,21 +1658,6 @@
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/beautiful-react-hooks": {
|
||||
"version": "3.11.2",
|
||||
"resolved": "https://registry.npmjs.org/beautiful-react-hooks/-/beautiful-react-hooks-3.11.2.tgz",
|
||||
"integrity": "sha512-g3pIIZhYfvk1btovwojdMOZ/UjqHi5jqv0TPG0AbQ9B8N8qmGgfgMHPPShelwWevSy7b4VVTmWr1VUJ+QnDR+A==",
|
||||
"dependencies": {
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.throttle": "^4.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.0.0",
|
||||
"react-dom": ">=16.0.0",
|
||||
"react-router-dom": ">=5.0.0",
|
||||
"rxjs": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
@ -3281,21 +3256,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"node_modules/lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
@ -4361,38 +4326,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.4.5.tgz",
|
||||
"integrity": "sha512-1RQJ8bM70YEumHIlNUYc6mFfUDoWa5EgPDenK/fq0bxD8DYpQUi/S6Zoft+9DBrh2xmtg92N5HMAJgGWDhKJ5Q==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.4.5.tgz",
|
||||
"integrity": "sha512-a7HsgikBR0wNfroBHcZUCd9+mLRqZS8R5U1Z1mzLWxFXEkUT3vR1XXmSIVoVpxVX8Bar0nQYYYc9Yipq8dWwAA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.0.5",
|
||||
"react-router": "6.4.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
@ -4554,21 +4487,6 @@
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
|
||||
"integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs/node_modules/tslib": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
|
||||
"integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/sade": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
|
||||
@ -6004,12 +5922,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
|
||||
"integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw=="
|
||||
},
|
||||
"@remix-run/router": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.5.tgz",
|
||||
"integrity": "sha512-my0Mycd+jruq/1lQuO5LBB6WTlL/e8DTCYWp44DfMTDcXz8DcTlgF0ISaLsGewt+ctHN+yA8xMq3q/N7uWJPug==",
|
||||
"peer": true
|
||||
},
|
||||
"@rushstack/eslint-patch": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
|
||||
@ -6303,15 +6215,6 @@
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"beautiful-react-hooks": {
|
||||
"version": "3.11.2",
|
||||
"resolved": "https://registry.npmjs.org/beautiful-react-hooks/-/beautiful-react-hooks-3.11.2.tgz",
|
||||
"integrity": "sha512-g3pIIZhYfvk1btovwojdMOZ/UjqHi5jqv0TPG0AbQ9B8N8qmGgfgMHPPShelwWevSy7b4VVTmWr1VUJ+QnDR+A==",
|
||||
"requires": {
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.throttle": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
@ -7451,21 +7354,11 @@
|
||||
"p-locate": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||
},
|
||||
"lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
@ -8104,25 +7997,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "6.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.4.5.tgz",
|
||||
"integrity": "sha512-1RQJ8bM70YEumHIlNUYc6mFfUDoWa5EgPDenK/fq0bxD8DYpQUi/S6Zoft+9DBrh2xmtg92N5HMAJgGWDhKJ5Q==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@remix-run/router": "1.0.5"
|
||||
}
|
||||
},
|
||||
"react-router-dom": {
|
||||
"version": "6.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.4.5.tgz",
|
||||
"integrity": "sha512-a7HsgikBR0wNfroBHcZUCd9+mLRqZS8R5U1Z1mzLWxFXEkUT3vR1XXmSIVoVpxVX8Bar0nQYYYc9Yipq8dWwAA==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"@remix-run/router": "1.0.5",
|
||||
"react-router": "6.4.5"
|
||||
}
|
||||
},
|
||||
"react-transition-group": {
|
||||
"version": "4.4.5",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||
@ -8223,23 +8097,6 @@
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "7.8.0",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
|
||||
"integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
|
||||
"integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"sade": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
|
||||
|
@ -4,96 +4,7 @@ import { Box } from "@mui/material";
|
||||
import FunctionItem from "../components/functionItem/functionItem";
|
||||
import { NixType, nixTypes, MetaData, DocItem } from "../types/nix";
|
||||
import { data } from "../models/data";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
function pipe<T>(...fns: ((arr: T) => T)[]) {
|
||||
return (x: T) => fns.reduce((v, f) => f(v), x);
|
||||
}
|
||||
|
||||
const search =
|
||||
(term: string) =>
|
||||
(data: MetaData): MetaData => {
|
||||
return data.filter((item) => {
|
||||
return Object.values(item).some((value) => {
|
||||
if (value) {
|
||||
if (typeof value === "object" && value.length > 0) {
|
||||
return value.join("\n").toLowerCase().includes(term.toLowerCase());
|
||||
}
|
||||
const valueAsString = value.toString();
|
||||
return valueAsString.toLowerCase().includes(term.toLowerCase());
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function getTypes(
|
||||
fnName: string,
|
||||
fnType: string | undefined
|
||||
): { args: NixType[]; types: NixType[] } {
|
||||
if (fnType) {
|
||||
let cleanType = fnType.replace(/ /g, "").replace(`${fnName}::`, "");
|
||||
const tokens = cleanType
|
||||
.split(/(::|->|\[|\]|\{|\}|\(|\))/gm)
|
||||
.filter(Boolean);
|
||||
const lastArrowIdx = tokens.lastIndexOf("->");
|
||||
if (lastArrowIdx) {
|
||||
// Function has at least on return value
|
||||
const interpretToken = (token: string) => {
|
||||
if (token === "(" || token === ")") {
|
||||
return "function" as NixType;
|
||||
} else if (token === "[" || token === "]") {
|
||||
return "list" as NixType;
|
||||
} else if (token === "{" || token === "}") {
|
||||
return "attrset" as NixType;
|
||||
} else if (nixTypes.includes(token.toLowerCase() as NixType)) {
|
||||
return token.toLowerCase() as NixType;
|
||||
} else if (
|
||||
token.length === 1 &&
|
||||
["a", "b", "c", "d", "e"].includes(token)
|
||||
) {
|
||||
return "any" as NixType;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
const returnValueTokens = tokens.slice(lastArrowIdx + 1);
|
||||
const types = returnValueTokens
|
||||
.map(interpretToken)
|
||||
.filter(Boolean)
|
||||
.filter((e, i, s) => s.indexOf(e) === i);
|
||||
const args = tokens
|
||||
.slice(0, lastArrowIdx)
|
||||
.map(interpretToken)
|
||||
.filter(Boolean)
|
||||
.filter((e, i, s) => s.indexOf(e) === i);
|
||||
return { args, types } as { args: NixType[]; types: NixType[] };
|
||||
}
|
||||
}
|
||||
return { args: ["any"], types: ["any"] };
|
||||
}
|
||||
|
||||
const filterByType =
|
||||
({ to, from }: { to: NixType; from: NixType }) =>
|
||||
(data: MetaData): MetaData => {
|
||||
if (to === "any" && from === "any") {
|
||||
return data;
|
||||
} else {
|
||||
return data.filter(
|
||||
// TODO: Implement proper type matching
|
||||
({ name, fn_type }) => {
|
||||
if (fn_type) {
|
||||
const parsedType = getTypes(name, fn_type);
|
||||
return (
|
||||
parsedType.args.includes(from) && parsedType.types.includes(to)
|
||||
);
|
||||
} else {
|
||||
return to === "any" && from === "any";
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
import { byQuery, byType, pipe } from "../queries";
|
||||
|
||||
export default function FunctionsPage() {
|
||||
const [selected, setSelected] = useState<string | null>(null);
|
||||
@ -102,7 +13,6 @@ export default function FunctionsPage() {
|
||||
to: "any",
|
||||
from: "any",
|
||||
});
|
||||
const router = useRouter();
|
||||
|
||||
const handleSelect = (key: string) => {
|
||||
console.log({ key });
|
||||
@ -116,7 +26,7 @@ export default function FunctionsPage() {
|
||||
};
|
||||
|
||||
const filteredData = useMemo(
|
||||
() => pipe(filterByType(filter), search(term))(data),
|
||||
() => pipe(byType(filter), byQuery(term))(data),
|
||||
[filter, term]
|
||||
);
|
||||
|
||||
|
39
queries/byQuery.ts
Normal file
39
queries/byQuery.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { DocItem, MetaData } from "../types/nix";
|
||||
|
||||
export const byQuery =
|
||||
(rawTerm: string) =>
|
||||
(data: MetaData): MetaData => {
|
||||
const term = rawTerm.toLowerCase();
|
||||
return data.reduce((results: (DocItem & {relevance: number})[], docItem: DocItem)=>{
|
||||
const matchesOn = Object.keys(docItem).filter(key=>{
|
||||
const rawValue = docItem[key as keyof DocItem];
|
||||
if(rawValue === null || rawValue === undefined){
|
||||
return false;
|
||||
}
|
||||
const value = Array.isArray(rawValue) ? rawValue.join("\n").toLowerCase() : rawValue.toLowerCase()
|
||||
if(value.includes(term)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})
|
||||
if(matchesOn?.length){
|
||||
results.push({...docItem, relevance: getRelevance(matchesOn as (keyof DocItem)[]) })
|
||||
}
|
||||
return results;
|
||||
},[]).sort((a,b)=> b.relevance - a.relevance)
|
||||
};
|
||||
|
||||
const getRelevance = (matchesOn: (keyof DocItem)[]): number => {
|
||||
const relevanceMap = {
|
||||
id: 10,
|
||||
name: 5,
|
||||
fn_type: 4,
|
||||
category: 3,
|
||||
example: 2,
|
||||
description: 1,
|
||||
}
|
||||
return matchesOn.reduce((count,key)=>{
|
||||
return count + relevanceMap[key]
|
||||
},0);
|
||||
|
||||
}
|
24
queries/byType.ts
Normal file
24
queries/byType.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { MetaData, NixType } from "../types/nix";
|
||||
import { getTypes } from "./lib";
|
||||
|
||||
export const byType =
|
||||
({ to, from }: { to: NixType; from: NixType }) =>
|
||||
(data: MetaData): MetaData => {
|
||||
if (to === "any" && from === "any") {
|
||||
return data;
|
||||
} else {
|
||||
return data.filter(
|
||||
// TODO: Implement proper type matching
|
||||
({ name, fn_type }) => {
|
||||
if (fn_type) {
|
||||
const parsedType = getTypes(name, fn_type);
|
||||
return (
|
||||
parsedType.args.includes(from) && parsedType.types.includes(to)
|
||||
);
|
||||
} else {
|
||||
return to === "any" && from === "any";
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
3
queries/index.ts
Normal file
3
queries/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export {byQuery} from "./byQuery";
|
||||
export {byType} from "./byType";
|
||||
export {pipe} from "./lib"
|
52
queries/lib.ts
Normal file
52
queries/lib.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { NixType, nixTypes } from "../types/nix";
|
||||
|
||||
export function pipe<T>(...fns: ((arr: T) => T)[]) {
|
||||
return (x: T) => fns.reduce((v, f) => f(v), x);
|
||||
}
|
||||
|
||||
export function getTypes(
|
||||
fnName: string,
|
||||
fnType: string | undefined
|
||||
): { args: NixType[]; types: NixType[] } {
|
||||
if (fnType) {
|
||||
let cleanType = fnType.replace(/ /g, "").replace(`${fnName}::`, "");
|
||||
const tokens = cleanType
|
||||
.split(/(::|->|\[|\]|\{|\}|\(|\))/gm)
|
||||
.filter(Boolean);
|
||||
const lastArrowIdx = tokens.lastIndexOf("->");
|
||||
if (lastArrowIdx) {
|
||||
// Function has at least on return value
|
||||
const interpretToken = (token: string) => {
|
||||
if (token === "(" || token === ")") {
|
||||
return "function" as NixType;
|
||||
} else if (token === "[" || token === "]") {
|
||||
return "list" as NixType;
|
||||
} else if (token === "{" || token === "}") {
|
||||
return "attrset" as NixType;
|
||||
} else if (nixTypes.includes(token.toLowerCase() as NixType)) {
|
||||
return token.toLowerCase() as NixType;
|
||||
} else if (
|
||||
token.length === 1 &&
|
||||
["a", "b", "c", "d", "e"].includes(token)
|
||||
) {
|
||||
return "any" as NixType;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
const returnValueTokens = tokens.slice(lastArrowIdx + 1);
|
||||
const types = returnValueTokens
|
||||
.map(interpretToken)
|
||||
.filter(Boolean)
|
||||
.filter((e, i, s) => s.indexOf(e) === i);
|
||||
const args = tokens
|
||||
.slice(0, lastArrowIdx)
|
||||
.map(interpretToken)
|
||||
.filter(Boolean)
|
||||
.filter((e, i, s) => s.indexOf(e) === i);
|
||||
return { args, types } as { args: NixType[]; types: NixType[] };
|
||||
}
|
||||
}
|
||||
return { args: ["any"], types: ["any"] };
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ const info = Object.entries(builtins).map(([name, meta]) => {
|
||||
const fn_type = types[name]?.fn_type || null;
|
||||
const { args, arity, doc } = meta;
|
||||
return {
|
||||
id: `builtins.${name}`,
|
||||
category: "builtins",
|
||||
fn_type,
|
||||
name,
|
||||
|
@ -9,6 +9,7 @@ export const nixTypes: NixType[] = [
|
||||
];
|
||||
|
||||
export type DocItem = {
|
||||
id: string;
|
||||
category: string;
|
||||
name: string;
|
||||
fn_type?: string;
|
||||
|
Loading…
Reference in New Issue
Block a user