diff --git a/.github/scripts/gen-algolia-data.ts b/.github/scripts/gen-algolia-data.ts new file mode 100755 index 0000000..b83b110 --- /dev/null +++ b/.github/scripts/gen-algolia-data.ts @@ -0,0 +1,43 @@ +#!/usr/bin/env -S pkgx deno run --allow-read=. --allow-net + +import * as yaml from "https://deno.land/std@0.204.0/yaml/mod.ts"; +import { isArray, isString } from "https://deno.land/x/is_what@v4.1.15/src/index.ts"; +import get_pkg_name from "./utils/get-name.ts" + +interface Package { + project: string + description: string + brief: string + displayName: string + programs: string[] +} + +export async function getKettleRemoteMetadata() { + const headers = { Authorization: 'public' } + const rsp = await fetch(`https://app.pkgx.dev/v1/packages/`, {headers}) + const data = await rsp.json() as (Package & { short_description: string })[] + /// just pick out the fields we want + return data.map(({ project, description, short_description }) => ({ project, description, brief: short_description })) +} + +function get_name(yml: any, project: string) { + return get_pkg_name({ project, display_name: yml['display_name'], provides: yml['provides'] }) +} + + +const rv = await getKettleRemoteMetadata() + +for (const obj of rv as Package[]) { + const yaml_path = `./projects/${obj.project}/package.yml` + const txt = await Deno.readTextFileSync(yaml_path) + const yml = await yaml.parse(txt) as Record + + const node = yml['provides'] + const provides: string[] = isArray(node) ? node : isString(node) ? [node] : [] + + obj.displayName = get_name(yaml_path, obj.project) + obj.programs = provides.map(x => x.slice(4)) +} + +console.log(JSON.stringify(rv, null, 2)) + diff --git a/.github/scripts/gen-index.json.ts b/.github/scripts/gen-index.json.ts index 6713095..ab0d1c3 100755 --- a/.github/scripts/gen-index.json.ts +++ b/.github/scripts/gen-index.json.ts @@ -14,7 +14,7 @@ export async function getKettleRemoteMetadata() { const headers = { Authorization: 'public' } const rsp = await fetch(`https://app.pkgx.dev/v1/packages/`, {headers}) const foo = await rsp.json() as {project: string, short_description: string}[] - return foo.reduce((acc, {project, short_description}) => { + return foo.reduce((acc, {project, short_description, description}) => { acc[project] = short_description return acc }, {} as Record) @@ -75,18 +75,12 @@ console.log(JSON.stringify(pkgs, null, 2)); ////////////////////////////////////////////////////// import { parse } from "https://deno.land/std@0.204.0/yaml/mod.ts"; import { isArray } from "https://deno.land/x/is_what@v4.1.15/src/index.ts"; -import get_pkg_name from "../../src/utils/pkg-name.ts"; +import get_pkg_name from "./utils/get-name.ts"; async function get_name(path: string, project: string): Promise { const txt = await Deno.readTextFileSync(path) const yml = await parse(txt) as Record - if (yml['display-name']) { - return yml['display-name'] - } else if (isArray(yml.provides) && yml.provides.length == 1) { - return yml.provides[0].slice(4) - } else { - return get_pkg_name(project) - } + return get_pkg_name({ project, display_name: yml['display_name'], provides: yml['provides'] }) } import { parse_pkgs_node } from "https://deno.land/x/libpkgx@v0.15.1/src/hooks/usePantry.ts" diff --git a/.github/scripts/utils/get-name.ts b/.github/scripts/utils/get-name.ts new file mode 100644 index 0000000..7e4f689 --- /dev/null +++ b/.github/scripts/utils/get-name.ts @@ -0,0 +1,15 @@ +import get_name_base from '../../../src/utils/pkg-name.ts' +import { isArray, isString } from "https://deno.land/x/is_what@v4.1.15/src/index.ts"; + +export default function get_name(opts: {display_name?: string, provides?: (string[] | string), project: string}): string { + const { display_name, provides, project } = opts + if (display_name) { + return display_name + } else if (isArray(provides) && provides?.length == 1) { + return provides[0].slice(4) + } else if (isString(provides)) { + return (provides as string)!.slice(4) + } else { + return get_name_base(project) + } +} diff --git a/.github/workflows/indexer.yml b/.github/workflows/indexer.yml index 1469252..823d880 100644 --- a/.github/workflows/indexer.yml +++ b/.github/workflows/indexer.yml @@ -60,3 +60,27 @@ jobs: create-invalidation --distribution-id E15VQ3SI584CSG --paths /pkgs /pkgs/ /pkgs/* + + algolia: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + repository: pkgxdev/pantry + fetch-depth: 0 # needed to get git metadata for ordering purposes + + - uses: actions/checkout@v4 + with: + path: utils + + - uses: pkgxdev/setup@v2 + + - run: utils/.github/scripts/gen-algolia-data.ts > algolia.json + + # FIXME replace with something that cares about versioning :-/ + - uses: wangchucheng/algolia-uploader@master + with: + app_id: UUTLHX01W7 + admin_key: ${{ secrets.ALGOLIA_ADMIN_KEY }} + index_name: pkgs + index_file_path: ./algolia.json diff --git a/package-lock.json b/package-lock.json index 31f9809..34e8f00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,12 +13,15 @@ "@emotion/styled": "latest", "@mui/icons-material": "latest", "@mui/material": "latest", + "algoliasearch": "^4.20.0", "is-what": "^4.1.16", "libpkgx": "^0.15.1", "mui-markdown": "^1.1.9", "react": "latest", "react-dom": "latest", - "react-router-dom": "^6.16.0", + "react-instantsearch": "^7.3.0", + "react-instantsearch-dom": "^6.40.4", + "react-router-dom": "^6.18.0", "react-use": "^17.4.0", "react-window": "^1.8.9", "showdown": "^2.1.0", @@ -35,6 +38,140 @@ "vite": "latest" } }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.20.0.tgz", + "integrity": "sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ==", + "dependencies": { + "@algolia/cache-common": "4.20.0" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.20.0.tgz", + "integrity": "sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ==" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.20.0.tgz", + "integrity": "sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg==", + "dependencies": { + "@algolia/cache-common": "4.20.0" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.20.0.tgz", + "integrity": "sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q==", + "dependencies": { + "@algolia/client-common": "4.20.0", + "@algolia/client-search": "4.20.0", + "@algolia/transporter": "4.20.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.20.0.tgz", + "integrity": "sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug==", + "dependencies": { + "@algolia/client-common": "4.20.0", + "@algolia/client-search": "4.20.0", + "@algolia/requester-common": "4.20.0", + "@algolia/transporter": "4.20.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.20.0.tgz", + "integrity": "sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ==", + "dependencies": { + "@algolia/requester-common": "4.20.0", + "@algolia/transporter": "4.20.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.20.0.tgz", + "integrity": "sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ==", + "dependencies": { + "@algolia/client-common": "4.20.0", + "@algolia/requester-common": "4.20.0", + "@algolia/transporter": "4.20.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.20.0.tgz", + "integrity": "sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg==", + "dependencies": { + "@algolia/client-common": "4.20.0", + "@algolia/requester-common": "4.20.0", + "@algolia/transporter": "4.20.0" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + }, + "node_modules/@algolia/logger-common": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.20.0.tgz", + "integrity": "sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ==" + }, + "node_modules/@algolia/logger-console": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.20.0.tgz", + "integrity": "sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA==", + "dependencies": { + "@algolia/logger-common": "4.20.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.20.0.tgz", + "integrity": "sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw==", + "dependencies": { + "@algolia/requester-common": "4.20.0" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.20.0.tgz", + "integrity": "sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng==" + }, + "node_modules/@algolia/requester-node-http": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.20.0.tgz", + "integrity": "sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng==", + "dependencies": { + "@algolia/requester-common": "4.20.0" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.20.0.tgz", + "integrity": "sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg==", + "dependencies": { + "@algolia/cache-common": "4.20.0", + "@algolia/logger-common": "4.20.0", + "@algolia/requester-common": "4.20.0" + } + }, + "node_modules/@algolia/ui-components-highlight-vdom": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@algolia/ui-components-highlight-vdom/-/ui-components-highlight-vdom-1.2.2.tgz", + "integrity": "sha512-/+7jh7cd5rR2yQC7ME4SDcnAMiD1Ofn5Qq+E7afTJx9XSMOHkLR77/o6YcuJ60TfD1S+9lr7yjBLACon8gOuzQ==", + "dependencies": { + "@algolia/ui-components-shared": "1.2.2", + "@babel/runtime": "^7.0.0" + } + }, + "node_modules/@algolia/ui-components-shared": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@algolia/ui-components-shared/-/ui-components-shared-1.2.2.tgz", + "integrity": "sha512-FYwEG5sbr8p4V8mqP0iUaKgmWfcrMXRXwp7e6iBuB65P/7QyL8pT4I6/iGb85Q5mNH+UtYYSmLZhKjEblllKEQ==" + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -1984,9 +2121,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.9.0.tgz", - "integrity": "sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.11.0.tgz", + "integrity": "sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ==", "engines": { "node": ">=14.0.0" } @@ -2607,6 +2744,21 @@ "node": ">=14.0.0" } }, + "node_modules/@types/dom-speech-recognition": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@types/dom-speech-recognition/-/dom-speech-recognition-0.0.1.tgz", + "integrity": "sha512-udCxb8DvjcDKfk1WTBzDsxFbLgYxmQGKrE/ricoMqHRNjSlSUCcamVTA5lIQqzY10mY5qCY0QDwBfFEwhfoDPw==" + }, + "node_modules/@types/google.maps": { + "version": "3.54.7", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.54.7.tgz", + "integrity": "sha512-L4OlEOw7GMdPJb5/eVXH7ZRBILPFaGbthRSOJtnnmDVEBV3Z8Y631whvAuahJyjpld460TuachEftDPXuqSD9A==" + }, + "node_modules/@types/hogan.js": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hogan.js/-/hogan.js-3.0.4.tgz", + "integrity": "sha512-iUOe7UP0TQDwcdwmIggFJqU7kWo+PQP93D6YaJOEENa9YgbI5qfwYvKBvVAVFgyinCGbm1GZdziTM85FyhiRLg==" + }, "node_modules/@types/js-cookie": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", @@ -2634,6 +2786,11 @@ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, + "node_modules/@types/qs": { + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz", + "integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==" + }, "node_modules/@types/react": { "version": "18.2.21", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.21.tgz", @@ -2704,6 +2861,43 @@ "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/algoliasearch": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.20.0.tgz", + "integrity": "sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.20.0", + "@algolia/cache-common": "4.20.0", + "@algolia/cache-in-memory": "4.20.0", + "@algolia/client-account": "4.20.0", + "@algolia/client-analytics": "4.20.0", + "@algolia/client-common": "4.20.0", + "@algolia/client-personalization": "4.20.0", + "@algolia/client-search": "4.20.0", + "@algolia/logger-common": "4.20.0", + "@algolia/logger-console": "4.20.0", + "@algolia/requester-browser-xhr": "4.20.0", + "@algolia/requester-common": "4.20.0", + "@algolia/requester-node-http": "4.20.0", + "@algolia/transporter": "4.20.0" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.15.0.tgz", + "integrity": "sha512-DGUnK3TGtDQsaUE4ayF/LjSN0DGsuYThB8WBgnnDY0Wq04K6lNVruO3LfqJOgSfDiezp+Iyt8Tj4YKHi+/ivSA==", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -2815,6 +3009,11 @@ "node": ">=0.8.0" } }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, "node_modules/clsx": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", @@ -3125,6 +3324,18 @@ "node": ">=4" } }, + "node_modules/hogan.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", + "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==", + "dependencies": { + "mkdirp": "0.3.0", + "nopt": "1.0.10" + }, + "bin": { + "hulk": "bin/hulk" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -3138,6 +3349,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/htm": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz", + "integrity": "sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==" + }, "node_modules/hyphenate-style-name": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", @@ -3167,6 +3383,29 @@ "fast-loops": "^1.1.3" } }, + "node_modules/instantsearch.js": { + "version": "4.60.0", + "resolved": "https://registry.npmjs.org/instantsearch.js/-/instantsearch.js-4.60.0.tgz", + "integrity": "sha512-u/xeCT1DaxPioJnSm3hV4lNAojlhbjGrpX5fHO6+RJjpDFv/MgYxiIOdaIRowmt5F0v/3QCm+Un5f4jy1/+emA==", + "dependencies": { + "@algolia/events": "^4.0.1", + "@algolia/ui-components-highlight-vdom": "^1.2.2", + "@algolia/ui-components-shared": "^1.2.2", + "@types/dom-speech-recognition": "^0.0.1", + "@types/google.maps": "^3.45.3", + "@types/hogan.js": "^3.0.0", + "@types/qs": "^6.5.3", + "algoliasearch-helper": "3.15.0", + "hogan.js": "^3.0.2", + "htm": "^3.0.0", + "preact": "^10.10.0", + "qs": "^6.5.1 < 6.10", + "search-insights": "^2.6.0" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -3305,6 +3544,15 @@ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" }, + "node_modules/mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -3370,6 +3618,20 @@ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3458,6 +3720,15 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/preact": { + "version": "10.18.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.18.2.tgz", + "integrity": "sha512-X/K43vocUHDg0XhWVmTTMbec4LT/iBMh+csCEqJk+pJqegaXsvjdqN80ZZ3L+93azWCnWCZ+WGwYb8SplxeNjA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prism-react-renderer": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.0.6.tgz", @@ -3505,6 +3776,17 @@ "signal-exit": "^3.0.2" } }, + "node_modules/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -3528,6 +3810,86 @@ "react": "^18.2.0" } }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "node_modules/react-instantsearch": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/react-instantsearch/-/react-instantsearch-7.3.0.tgz", + "integrity": "sha512-X0ZKDMP7DDKkRqnM99JbpsqASXDBVCUSpEYmPPhDx/PFGUzOu9yAFNCBkpJxfIf2A3nL/Z1QQDXuUYRdBgVCsg==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "instantsearch.js": "4.60.0", + "react-instantsearch-core": "7.3.0" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 5", + "react": ">= 16.8.0 < 19", + "react-dom": ">= 16.8.0 < 19" + } + }, + "node_modules/react-instantsearch-core": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/react-instantsearch-core/-/react-instantsearch-core-7.3.0.tgz", + "integrity": "sha512-v66mG+Io/Mmd5LQaoQXxGD/acHnLIM1Cq/uzlcC0VbFji7JXoJhChRPUcA+z5fGDaidBxdJOPRtQjJpTQ+/h8g==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "algoliasearch-helper": "3.15.0", + "instantsearch.js": "4.60.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 5", + "react": ">= 16.8.0 < 19" + } + }, + "node_modules/react-instantsearch-dom": { + "version": "6.40.4", + "resolved": "https://registry.npmjs.org/react-instantsearch-dom/-/react-instantsearch-dom-6.40.4.tgz", + "integrity": "sha512-Oy8EKEOg/dfTE8tHc7GZRlzUdbZY4Mxas1x2OtvSNui+YAbIWafIf1g98iOGyVTB2qI5WH91YyUJTLPNfLrs6Q==", + "deprecated": "package has moved to react-instantsearch", + "dependencies": { + "@babel/runtime": "^7.1.2", + "algoliasearch-helper": "3.14.0", + "classnames": "^2.2.5", + "prop-types": "^15.6.2", + "react-fast-compare": "^3.0.0", + "react-instantsearch-core": "6.40.4" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 5", + "react": ">= 16.3.0 < 19", + "react-dom": ">= 16.3.0 < 19" + } + }, + "node_modules/react-instantsearch-dom/node_modules/algoliasearch-helper": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.14.0.tgz", + "integrity": "sha512-gXDXzsSS0YANn5dHr71CUXOo84cN4azhHKUbg71vAWnH+1JBiR4jf7to3t3JHXknXkbV0F7f055vUSBKrltHLQ==", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/react-instantsearch-dom/node_modules/react-instantsearch-core": { + "version": "6.40.4", + "resolved": "https://registry.npmjs.org/react-instantsearch-core/-/react-instantsearch-core-6.40.4.tgz", + "integrity": "sha512-sEOgRU2MKL8edO85sNHvKlZ5yq9OFw++CDsEqYpHJvbWLE/2J2N49XAUY90kior09I2kBkbgowBbov+Py1AubQ==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "algoliasearch-helper": "3.14.0", + "prop-types": "^15.6.2", + "react-fast-compare": "^3.0.0" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 5", + "react": ">= 16.3.0 < 19" + } + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -3543,11 +3905,11 @@ } }, "node_modules/react-router": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.16.0.tgz", - "integrity": "sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.18.0.tgz", + "integrity": "sha512-vk2y7Dsy8wI02eRRaRmOs9g2o+aE72YCx5q9VasT1N9v+lrdB79tIqrjMfByHiY5+6aYkH2rUa5X839nwWGPDg==", "dependencies": { - "@remix-run/router": "1.9.0" + "@remix-run/router": "1.11.0" }, "engines": { "node": ">=14.0.0" @@ -3557,12 +3919,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.16.0.tgz", - "integrity": "sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg==", + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.18.0.tgz", + "integrity": "sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw==", "dependencies": { - "@remix-run/router": "1.9.0", - "react-router": "6.16.0" + "@remix-run/router": "1.11.0", + "react-router": "6.18.0" }, "engines": { "node": ">=14.0.0" @@ -3722,6 +4084,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/search-insights": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.9.0.tgz", + "integrity": "sha512-bkWW9nIHOFkLwjQ1xqVaMbjjO5vhP26ERsH9Y3pKr8imthofEFIxlnOabkmGcw6ksRj9jWidcI65vvjJH/nTGg==" + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -3939,6 +4306,14 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", diff --git a/package.json b/package.json index 822271b..a20eab7 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,15 @@ "@emotion/styled": "latest", "@mui/icons-material": "latest", "@mui/material": "latest", + "algoliasearch": "^4.20.0", "is-what": "^4.1.16", "libpkgx": "^0.15.1", "mui-markdown": "^1.1.9", "react": "latest", "react-dom": "latest", - "react-router-dom": "^6.16.0", + "react-instantsearch": "^7.3.0", + "react-instantsearch-dom": "^6.40.4", + "react-router-dom": "^6.18.0", "react-use": "^17.4.0", "react-window": "^1.8.9", "showdown": "^2.1.0", @@ -34,5 +37,6 @@ "@vitejs/plugin-react": "latest", "typescript": "latest", "vite": "latest" - } + }, + "pkgx": "deno^1.35" } diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 2b3bd50..607acc8 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -1,8 +1,32 @@ -import { InputAdornment, TextField, useMediaQuery, useTheme } from "@mui/material"; +import { Fade, Grow, InputAdornment, List, ListItem, ListItemButton, ListItemText, Paper, Popper, Skeleton, TextField, Typography } from '@mui/material'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import { useHits, useSearchBox } from 'react-instantsearch'; -export default function() { - const theme = useTheme(); - const isxs = useMediaQuery(theme.breakpoints.down('md')); +export default function Search() { + const memoizedSearch = useCallback((query: any, search: (arg0: string) => void) => { + search(query); + }, []); + const { refine } = useSearchBox({ + queryHook: memoizedSearch, + }); + const inputRef = useRef(null); + useEffect(() => { + const searchHandler = (event: KeyboardEvent) => { + if (event.key === "k" && event.metaKey) { + if (document.activeElement != inputRef.current) { + inputRef.current!.focus(); + } else { + inputRef.current!.blur(); + } + } + }; + document.addEventListener("keydown", searchHandler); + return () => { + document.removeEventListener("keydown", searchHandler); + }; + }, []); + const [isopen, setopen] = useState(false) + const [has_text, set_has_text] = useState(false) return <> setopen(true)} + onBlur={() => setopen(false)} + onChange={e => { + set_has_text(!!e.target.value); + refine(e.target.value); + }} + inputRef={inputRef} InputProps={{ endAdornment: ⌘K, }} /> + {/* always open so fade away works */} + + + + {has_text && } + + + } + + +function SearchResults() { + const { hits } = useHits() + + if (hits.length) { + return + {hits.map(fu)} + + } else { + No results + } + + function fu(input: any) { + const {project, displayName, brief} = input + return + + + + + } +} \ No newline at end of file diff --git a/src/pkgx.dev.tsx b/src/pkgx.dev.tsx index c55121a..3a45e9f 100644 --- a/src/pkgx.dev.tsx +++ b/src/pkgx.dev.tsx @@ -17,6 +17,9 @@ import TermsOfUse from './pkgx.dev/TermsOfUse'; import theme from './utils/theme'; import React from "react"; import './assets/main.css'; +import Search from './components/Search'; +import { InstantSearch } from 'react-instantsearch'; +import algoliasearch from 'algoliasearch/lite'; ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( @@ -42,17 +45,22 @@ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( , ); +const searchClient = algoliasearch('UUTLHX01W7', '819a841ca219754c38918b8bcbbbfea7'); + function PackageListingFrame({children}: {children: React.ReactNode}) { const path = useLocation().pathname; const href = path.startsWith('/pkgs') ? 'pantry' : 'pkgx' - return - - - - - {children} -