Merge branch 'feature/mappers-integrated-with-model' into develop
20
.gitignore
vendored
@@ -1,10 +1,12 @@
|
||||
.DS_Store
|
||||
.vite-ssg-dist
|
||||
.vite-ssg-temp
|
||||
**/.DS_Store
|
||||
**/.vite-ssg-dist
|
||||
**/.vite-ssg-temp
|
||||
*.local
|
||||
dist
|
||||
bin
|
||||
dist-ssr
|
||||
node_modules
|
||||
.idea/
|
||||
*.log
|
||||
**/dist
|
||||
**/bin
|
||||
**/dist-ssr
|
||||
**/node_modules
|
||||
**/.idea/
|
||||
**/*.log
|
||||
**/.do-devops.json
|
||||
**/*.env
|
||||
@@ -2,17 +2,17 @@ services:
|
||||
# We are not using the scraper for anything currently but keeping it here
|
||||
# for now in case we decide to
|
||||
|
||||
# scraper:
|
||||
# image: getmeili/docs-scraper:latest
|
||||
# container_name: scraper
|
||||
# command: pipenv run ./docs_scraper config.json -d
|
||||
# depends_on:
|
||||
# - search
|
||||
# environment:
|
||||
# - MEILISEARCH_HOST_URL=localhost:7700
|
||||
# - MEILISEARCH_API_KEY=""
|
||||
# volumes:
|
||||
# - ./scraper:/data.ms
|
||||
scraper:
|
||||
image: getmeili/docs-scraper:latest
|
||||
container_name: scraper
|
||||
command: pipenv run ./docs_scraper config.json -d
|
||||
depends_on:
|
||||
- search
|
||||
environment:
|
||||
- MEILISEARCH_HOST_URL=localhost:7700
|
||||
- MEILISEARCH_API_KEY=""
|
||||
volumes:
|
||||
- ./scraper:/data.ms
|
||||
|
||||
search:
|
||||
image: getmeili/meilisearch:latest
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useSearch } from "~/modules/search";
|
||||
const s = useSearch();
|
||||
const indexPossibilites = ["repo", "prose", "TS API", "RS API"];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col rounded-md bg-gray-100/25 dark:bg-gray-900/25">
|
||||
<div class="flex flex-col space-y-2 rounded-t-md overflow-hidden">
|
||||
|
||||
<div class="font-bold text-lg px-4 py-3 bg-gray-900/10 dark:bg-gray-100/10">
|
||||
ACTIONS
|
||||
</div>
|
||||
|
||||
<div class="p-4 flex flex-col space-y-2">
|
||||
|
||||
<div v-for="idx in indexPossibilites" :key="idx" class=" rounded cursor-pointer p-1 flex">
|
||||
<div class="actions flex flex-row space-x-1 items-center text-gray-100 dark:text-gray-700 transition-colors duration-200">
|
||||
<carbon:next-filled class="flex hover:text-green-500" />
|
||||
<carbon:error-filled class="flex hover:text-orange-500" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row ml-2">
|
||||
<span class="font-medium">{{idx}} </span>
|
||||
<span class="font-light">pipeline</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.btn {
|
||||
@apply text-xs ;
|
||||
}
|
||||
</style>
|
||||
@@ -1,66 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { PropType } from "vue";
|
||||
import { GenericDoc } from "~/types/meilisearch";
|
||||
|
||||
const props = defineProps({
|
||||
document: {
|
||||
type: Object as PropType<GenericDoc>, required: true}
|
||||
});
|
||||
|
||||
const doc = computed(() => props.document);
|
||||
const showDetails = ref(false);
|
||||
|
||||
const apiKind = computed(() => {
|
||||
if(doc.value._idx !== "api") {
|
||||
return "";
|
||||
}
|
||||
switch(doc.value.kind) {
|
||||
case "Function":
|
||||
return "fn";
|
||||
case "Namespace":
|
||||
return "module";
|
||||
case "Interface":
|
||||
return "interface";
|
||||
default:
|
||||
return doc.value?.kind ? String(doc.value?.kind).toLowerCase() : "";
|
||||
}
|
||||
});
|
||||
|
||||
const details = () => {
|
||||
showDetails.value = !showDetails.value;
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col border-1 rounded px-2 py-1 border-gray-500 hover:bg-gray-100 dark:hover:bg-gray-700 ">
|
||||
<div class="flex flex-row space-x-1 items-center place-content-center cursor-pointer" @click="details">
|
||||
<mdi:github v-if="doc._idx === 'repo'" class="flex flex-shrink-0" />
|
||||
<vscode-icons:file-type-typescript-official v-if="doc._idx === 'api' && doc.language === 'typescript'" class="flex flex-shrink-0" />
|
||||
<vscode-icons:file-type-rust v-if="doc._idx === 'api' && doc.language === 'rust'" class="flex" />
|
||||
<ant-design:file-markdown-outlined v-if="doc._idx === 'prose'" class="flex" />
|
||||
<div class="flex flex-shrink-0">{{doc.name}}</div>
|
||||
|
||||
<div class="flex flex-grow ml-1 font-light text-xs italic truncate">
|
||||
{{doc.description}}
|
||||
</div>
|
||||
|
||||
<div v-if="doc._idx === 'api'" class="flex text-xs font-medium px-1 py-0.5 bg-blue-500 dark:bg-blue-600 text-gray-50 rounded">
|
||||
{{apiKind}}
|
||||
</div>
|
||||
<div class="flex px-1 hover:text-green-600 hover:font-bold ">
|
||||
<a :href="doc.url" target="_new">
|
||||
<ph:link-light class="flex" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div v-if="showDetails" class="items-start">
|
||||
<div v-for="key in Object.keys(doc)" :key="key" class="flex flex-row">
|
||||
<span class="flex font-bold">{{key}}:</span>
|
||||
<span class="flex ml-1">{{doc[key]}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,42 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useSearch } from "~/modules/search";
|
||||
const s = useSearch();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="search-stats flex flex-col rounded-md bg-gray-100/25 dark:bg-gray-800/25">
|
||||
|
||||
<div class="rounded-t-md overflow-hidden">
|
||||
<div class="font-bold text-lg rounded-t-md bg-gray-900/10 dark:bg-gray-100/10 py-3 px-4">
|
||||
INDEXES
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="s.$state.health" class="text-xs mt-2" >
|
||||
<div class="text-green-500">MeiliSearch Service Healthy!</div>
|
||||
<div class="db-size">db size: {{s.dbSize}}</div>
|
||||
</div>
|
||||
<span v-else class="text-red-500 ">
|
||||
Meilisearch is not available locally!
|
||||
</span>
|
||||
<div class="p-4">
|
||||
<div
|
||||
v-for="idx in s.$state.indexes"
|
||||
:key="idx.uid"
|
||||
class="index flex flex-row w-full py-2 border-1 rounded border-gray-500 p-4 mt-4"
|
||||
>
|
||||
<span class="index-name flex flex-grow font-medium">{{idx.name}}</span>
|
||||
<v-tooltip >
|
||||
<span class="index-name font-light cursor-pointer">
|
||||
{{s.indexInfo(idx.name)?.numberOfDocuments}}
|
||||
</span>
|
||||
<template #popper>
|
||||
<span class="dark:text-gray-300">
|
||||
# of Docs
|
||||
</span>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,30 +0,0 @@
|
||||
// register vue composition api globally
|
||||
import { ViteSSG } from 'vite-ssg'
|
||||
import generatedRoutes from 'virtual:generated-pages'
|
||||
import { setupLayouts } from 'virtual:generated-layouts'
|
||||
import FloatingVue from 'floating-vue'
|
||||
import 'floating-vue/dist/style.css'
|
||||
import App from './App.vue'
|
||||
|
||||
// windicss layers
|
||||
import 'virtual:windi-base.css'
|
||||
import 'virtual:windi-components.css'
|
||||
// your custom styles here
|
||||
import './styles/main.css'
|
||||
// windicss utilities should be the last style import
|
||||
import 'virtual:windi-utilities.css'
|
||||
// windicss devtools support (dev only)
|
||||
import 'virtual:windi-devtools'
|
||||
|
||||
const routes = setupLayouts(generatedRoutes)
|
||||
|
||||
// https://github.com/antfu/vite-ssg
|
||||
export const createApp = ViteSSG(
|
||||
App,
|
||||
{ routes, base: import.meta.env.BASE_URL },
|
||||
(ctx) => {
|
||||
// install all modules under `modules/`
|
||||
Object.values(import.meta.globEager('./modules/*.ts')).map(i => i.install?.(ctx))
|
||||
ctx.app.use(FloatingVue)
|
||||
},
|
||||
)
|
||||
@@ -1,13 +0,0 @@
|
||||
import NProgress from 'nprogress'
|
||||
import type { UserModule } from '~/types'
|
||||
|
||||
export const install: UserModule = ({ isClient, router }) => {
|
||||
if (isClient) {
|
||||
router.beforeEach(() => {
|
||||
NProgress.start()
|
||||
})
|
||||
router.afterEach(() => {
|
||||
NProgress.done()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
# Getting Started
|
||||
|
||||
+++ Install Dependencies and Start Docs Site (_looks like you already did_)
|
||||
```bash
|
||||
# 1. installs deps for both CLI and Docs
|
||||
# 2. starts Docs server (in dev mode with HMR), opens in browser
|
||||
# 3. starts Meilisearch server in Docker
|
||||
pnpm run start
|
||||
```
|
||||
|
||||
> A browser window should now have opened to [`http://localhost:3333`](http://localhost:3333).
|
||||
|
||||
You are now up and running with the documentation site -- and assuming you have Docker installed -- a local [search server](./meilisearch) which you can interact with.
|
||||
|
||||
### Already installed Deps?
|
||||
|
||||
If you've already installed all the deps and want more granular control you can choose from the various script targets or just choose _watch_ to look at docs with active editing capability:
|
||||
|
||||
```bash
|
||||
# turn on watcher mode for both CLI and Docs
|
||||
pnpm run watch
|
||||
```
|
||||
+++
|
||||
+++ Ways to Consume this library
|
||||
- **Search Development** - if you are updating docs, index definitions, etc. you'll run this in _watch_ mode (aka., `pnpm run start` (first time) or `pnpm run watch`)
|
||||
- **Deployment** - When an _upstream_ dependency is updated this repo should be trigged by a Netlify build hook. For instance:
|
||||
- `tauri` has a new release to production branch, as a `postbuild` step in Netlify build process, it will call Netlify's API and ask for a rebuild of this repo.
|
||||
- we care about picking up the two AST files to build the API docs (`ts-docs.json`, `rust.json`)
|
||||
- `tauri-docs` releases new docs, again a `postbuild` hook on Netlify is called to it requests a rebuild from this repo
|
||||
- here we need to pickup the directly or MD files
|
||||
- `NPM Dependency` - the `Models` you've defined along with all of the _types_ defined are available as an NPM dependency
|
||||
```ts
|
||||
import { ProseModel } from "tauri-search";
|
||||
import type { MeiliSearchResponse } from "tauri-search";
|
||||
```
|
||||
+++
|
||||
|
||||
|
||||
## Sitemap
|
||||
|
||||
Use the Nav bar at the top to navigation to the various sections:
|
||||
|
||||
- MeiliSearch Info
|
||||
- Search Bar Info
|
||||
- Docker Info
|
||||
|
||||
Then we move into the core content types:
|
||||
|
||||
- Typescript API Content
|
||||
- Rust API Content
|
||||
- Prose Content
|
||||
|
||||
|
||||
## External Resources
|
||||
- General Documentation
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [MeiliSearch Website Docs](https://docs.meilisearch.com/learn/what_is_meilisearch/)
|
||||
- API Docs
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [Open API for MeiliSearch](https://bump.sh/doc/meilisearch)
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [API Docs from MeiliSearch Website](https://docs.meilisearch.com/reference/api/)
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [Postman Collection of MeiliSearch API](https://docs.meilisearch.com/postman/meilisearch-collection.json)
|
||||
- Interactive
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [MeiliSearch Dashboard](http://localhost:7700/)
|
||||
347
fx
@@ -1,347 +0,0 @@
|
||||
[
|
||||
{
|
||||
id: 'module::app::app.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'app',
|
||||
name: 'app',
|
||||
fileName: 'app.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.app` when `tauri.conf.json > build > withGlobalTauri` is set to true.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/app'
|
||||
},
|
||||
{
|
||||
id: 'module::cli::cli.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'cli',
|
||||
name: 'cli',
|
||||
fileName: 'cli.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.cli` when `tauri.conf.json > build > withGlobalTauri` is set to true.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/cli'
|
||||
},
|
||||
{
|
||||
id: 'module::clipboard::clipboard.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'clipboard',
|
||||
name: 'clipboard',
|
||||
fileName: 'clipboard.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.clipboard` when `tauri.conf.json > build > withGlobalTauri` is set to true.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/clipboard'
|
||||
},
|
||||
{
|
||||
id: 'module::dialog::dialog.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'dialog',
|
||||
name: 'dialog',
|
||||
fileName: 'dialog.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.dialog` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n' +
|
||||
'\n' +
|
||||
'The APIs must be allowlisted on `tauri.conf.json`:\n' +
|
||||
'```json\n' +
|
||||
'{\n' +
|
||||
' "tauri": {\n' +
|
||||
' "allowlist": {\n' +
|
||||
' "dialog": {\n' +
|
||||
' "all": true, // enable all dialog APIs\n' +
|
||||
' "open": true, // enable file open API\n' +
|
||||
' "save": true // enable file save API\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
'}\n' +
|
||||
'```\n' +
|
||||
'It is recommended to allowlist only the APIs you use for optimal bundle size and security.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/dialog'
|
||||
},
|
||||
{
|
||||
id: 'module::event::event.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'event',
|
||||
name: 'event',
|
||||
fileName: 'event.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.event` when `tauri.conf.json > build > withGlobalTauri` is set to true.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/event'
|
||||
},
|
||||
{
|
||||
id: 'module::fs::fs.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'fs',
|
||||
name: 'fs',
|
||||
fileName: 'fs.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.fs` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n' +
|
||||
'\n' +
|
||||
'The APIs must be allowlisted on `tauri.conf.json`:\n' +
|
||||
'```json\n' +
|
||||
'{\n' +
|
||||
' "tauri": {\n' +
|
||||
' "allowlist": {\n' +
|
||||
' "fs": {\n' +
|
||||
' "all": true, // enable all FS APIs\n' +
|
||||
' "readTextFile": true,\n' +
|
||||
' "readBinaryFile": true,\n' +
|
||||
' "writeFile": true,\n' +
|
||||
' "writeBinaryFile": true,\n' +
|
||||
' "readDir": true,\n' +
|
||||
' "copyFile": true,\n' +
|
||||
' "createDir": true,\n' +
|
||||
' "removeDir": true,\n' +
|
||||
' "removeFile": true,\n' +
|
||||
' "renameFile": true\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
'}\n' +
|
||||
'```\n' +
|
||||
'It is recommended to allowlist only the APIs you use for optimal bundle size and security.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/fs'
|
||||
},
|
||||
{
|
||||
id: 'module::globalShortcut::globalShortcut.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'globalShortcut',
|
||||
name: 'globalShortcut',
|
||||
fileName: 'globalShortcut.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.globalShortcut` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n' +
|
||||
'\n' +
|
||||
'The APIs must be allowlisted on `tauri.conf.json`:\n' +
|
||||
'```json\n' +
|
||||
'{\n' +
|
||||
' "tauri": {\n' +
|
||||
' "allowlist": {\n' +
|
||||
' "globalShortcut": {\n' +
|
||||
' "all": true // enable all global shortcut APIs\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
'}\n' +
|
||||
'```\n' +
|
||||
'It is recommended to allowlist only the APIs you use for optimal bundle size and security.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/globalShortcut'
|
||||
},
|
||||
{
|
||||
id: 'module::http::http.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'http',
|
||||
name: 'http',
|
||||
fileName: 'http.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.http` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n' +
|
||||
'\n' +
|
||||
'The APIs must be allowlisted on `tauri.conf.json`:\n' +
|
||||
'```json\n' +
|
||||
'{\n' +
|
||||
' "tauri": {\n' +
|
||||
' "allowlist": {\n' +
|
||||
' "http": {\n' +
|
||||
' "all": true, // enable all http APIs\n' +
|
||||
' "request": true // enable HTTP request API\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
'}\n' +
|
||||
'```\n' +
|
||||
'It is recommended to allowlist only the APIs you use for optimal bundle size and security.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/http'
|
||||
},
|
||||
{
|
||||
id: 'module::notification::notification.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'notification',
|
||||
name: 'notification',
|
||||
fileName: 'notification.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.notification` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n' +
|
||||
'\n' +
|
||||
'The APIs must be allowlisted on `tauri.conf.json`:\n' +
|
||||
'```json\n' +
|
||||
'{\n' +
|
||||
' "tauri": {\n' +
|
||||
' "allowlist": {\n' +
|
||||
' "notification": {\n' +
|
||||
' "all": true // enable all notification APIs\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
'}\n' +
|
||||
'```\n' +
|
||||
'It is recommended to allowlist only the APIs you use for optimal bundle size and security.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/notification'
|
||||
},
|
||||
{
|
||||
id: 'module::os::os.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'os',
|
||||
name: 'os',
|
||||
fileName: 'os.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.fs` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n' +
|
||||
'\n' +
|
||||
'The APIs must be allowlisted on `tauri.conf.json`:\n' +
|
||||
'```json\n' +
|
||||
'{\n' +
|
||||
' "tauri": {\n' +
|
||||
' "allowlist": {\n' +
|
||||
' "os": {\n' +
|
||||
' "all": true, // enable all Os APIs\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
'}\n' +
|
||||
'```\n' +
|
||||
'It is recommended to allowlist only the APIs you use for optimal bundle size and security.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/os'
|
||||
},
|
||||
{
|
||||
id: 'module::path::path.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'path',
|
||||
name: 'path',
|
||||
fileName: 'path.ts',
|
||||
comments: undefined,
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/path'
|
||||
},
|
||||
{
|
||||
id: 'module::process::process.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'process',
|
||||
name: 'process',
|
||||
fileName: 'process.ts',
|
||||
comments: undefined,
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/process'
|
||||
},
|
||||
{
|
||||
id: 'module::shell::shell.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'shell',
|
||||
name: 'shell',
|
||||
fileName: 'shell.ts',
|
||||
comments: undefined,
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/shell'
|
||||
},
|
||||
{
|
||||
id: 'module::tauri::tauri.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'tauri',
|
||||
name: 'tauri',
|
||||
fileName: 'tauri.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.tauri` when `tauri.conf.json > build > withGlobalTauri` is set to true.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/tauri'
|
||||
},
|
||||
{
|
||||
id: 'module::updater::updater.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'updater',
|
||||
name: 'updater',
|
||||
fileName: 'updater.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.updater` when `tauri.conf.json > build > withGlobalTauri` is set to true.',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/updater'
|
||||
},
|
||||
{
|
||||
id: 'module::window::window.ts',
|
||||
language: 'typescript',
|
||||
kind: 'Namespace',
|
||||
module: 'window',
|
||||
name: 'window',
|
||||
fileName: 'window.ts',
|
||||
comments: 'This package is also accessible with `window.__TAURI__.window` when `tauri.conf.json > build > withGlobalTauri` is set to true.\n' +
|
||||
'\n' +
|
||||
'The APIs must be allowlisted on `tauri.conf.json`:\n' +
|
||||
'```json\n' +
|
||||
'{\n' +
|
||||
' "tauri": {\n' +
|
||||
' "allowlist": {\n' +
|
||||
' "window": {\n' +
|
||||
' "all": true, // enable all window APIs\n' +
|
||||
' "create": true // enable window creation\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
'}\n' +
|
||||
'```\n' +
|
||||
'It is recommended to allowlist only the APIs you use for optimal bundle size and security.\n' +
|
||||
'\n' +
|
||||
'# Window events\n' +
|
||||
'\n' +
|
||||
'Events can be listened using `appWindow.listen`:\n' +
|
||||
'```typescript\n' +
|
||||
"import { appWindow } from '@tauri-apps/api/window'\n" +
|
||||
"appWindow.listen('tauri://move', ({ event, payload }) => {\n" +
|
||||
' const { x, y } = payload // payload here is a `PhysicalPosition`\n' +
|
||||
'})\n' +
|
||||
'```\n' +
|
||||
'\n' +
|
||||
'Window-specific events emitted by the backend:\n' +
|
||||
'\n' +
|
||||
"#### 'tauri://resize'\n" +
|
||||
'Emitted when the size of the window has changed.\n' +
|
||||
'*EventPayload*:\n' +
|
||||
'```typescript\n' +
|
||||
'type ResizePayload = PhysicalSize\n' +
|
||||
'```\n' +
|
||||
'\n' +
|
||||
"#### 'tauri://move'\n" +
|
||||
'Emitted when the position of the window has changed.\n' +
|
||||
'*EventPayload*:\n' +
|
||||
'```typescript\n' +
|
||||
'type MovePayload = PhysicalPosition\n' +
|
||||
'```\n' +
|
||||
'\n' +
|
||||
"#### 'tauri://close-requested'\n" +
|
||||
'Emitted when the user requests the window to be closed.\n' +
|
||||
"If a listener is registered for this event, Tauri won't close the window so you must call `appWindow.close()` manually.\n" +
|
||||
'\n' +
|
||||
"#### 'tauri://focus'\n" +
|
||||
'Emitted when the window gains focus.\n' +
|
||||
'\n' +
|
||||
"#### 'tauri://blur'\n" +
|
||||
'Emitted when the window loses focus.\n' +
|
||||
'\n' +
|
||||
"#### 'tauri://scale-change'\n" +
|
||||
"Emitted when the window's scale factor has changed.\n" +
|
||||
'The following user actions can cause DPI changes:\n' +
|
||||
"- Changing the display's resolution.\n" +
|
||||
"- Changing the display's scale factor (e.g. in Control Panel on Windows).\n" +
|
||||
'- Moving the window to a display with a different scale factor.\n' +
|
||||
'*Event payload*:\n' +
|
||||
'```typescript\n' +
|
||||
'interface ScaleFactorChanged {\n' +
|
||||
' scaleFactor: number\n' +
|
||||
' size: PhysicalSize\n' +
|
||||
'}\n' +
|
||||
'```\n' +
|
||||
'\n' +
|
||||
"#### 'tauri://menu'\n" +
|
||||
'Emitted when a menu item is clicked.\n' +
|
||||
'*EventPayload*:\n' +
|
||||
'```typescript\n' +
|
||||
'type MenuClicked = string\n' +
|
||||
'```\n',
|
||||
tags: undefined,
|
||||
url: 'https://tauri.studio/docs/api/js/modules/window'
|
||||
}
|
||||
]
|
||||
@@ -1,20 +0,0 @@
|
||||
/* eslint-disable unicorn/import-style */
|
||||
import type { Config } from "@jest/types";
|
||||
import { resolve } from "path";
|
||||
|
||||
const config: Config.InitialOptions = {
|
||||
verbose: true,
|
||||
// roots: ["tests", "src"],
|
||||
transform: {
|
||||
"^.+\\.ts$": "ts-jest",
|
||||
},
|
||||
testPathIgnorePatterns: ["/node_modules/", "/docs/"],
|
||||
moduleNameMapper: {
|
||||
"^[/]{0,1}~/(.*)$": resolve(process.cwd(), "src", "$1"),
|
||||
},
|
||||
testMatch: ["**/?(*[-.])+(spec|test).ts"],
|
||||
setupFilesAfterEnv: ["jest-extended"],
|
||||
testEnvironment: "node",
|
||||
};
|
||||
|
||||
export default config;
|
||||
91
package.json
@@ -1,86 +1,49 @@
|
||||
{
|
||||
"name": "tauri-search",
|
||||
"version": "0.1.0",
|
||||
"description": "Search Engine for Tauri website",
|
||||
"name": "tauri-search-monorepo",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"author": "Ken Snyder<ken@ken.net>",
|
||||
"bin": {
|
||||
"ts-ast": "./bin/ts-ast.cjs",
|
||||
"ts-ast-overview": "./bin/ts-ast-overview.cjs"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "pnpm -C docs dev",
|
||||
"clean": "pnpm run --filter ./packages run clean",
|
||||
"start": "pnpm -r install && pnpm run start:tauri-search && pnpm run start:docs && pnpm run up",
|
||||
"start:tauri-search": "pnpm -C ./packages/tauri-search run watch",
|
||||
"start:docs": "pnpm -C ./packages/docs run watch",
|
||||
"build:cli": "pnpm -C ./packages/tauri-search run build:cli",
|
||||
"build:npm": "pnpm -C ./packages/tauri-search run build:npm",
|
||||
"watch": "run-s watch:prep watch:rest",
|
||||
"watch:prep": "pnpm -C ./packages/tauri-search run build:npm",
|
||||
"watch:rest": "run-p watch:tauri-search watch:docs",
|
||||
"watch:tauri-search": "pnpm -C ./packages/tauri-search run watch",
|
||||
"watch:docs": "pnpm -C ./packages/docs run watch",
|
||||
"test": "pnpm -C ./packages/docs run test && pnpm -C ./packages/tauri-search run test",
|
||||
"test:watch": "pnpm -C ./packages/tauri-search run test:watch",
|
||||
"current-indexes": "pnpm -C ./packages/tauri-search run current-indexes",
|
||||
"create-indexes": "pnpm -C ./packages/tauri-search run create-indexes",
|
||||
"refresh-prose": "pnpm -C ./packages/tauri-search run refresh-prose",
|
||||
"push-prose": "pnpm -C ./packages/tauri-search run push-prose",
|
||||
"up": "docker compose up -d",
|
||||
"down": "docker compose down",
|
||||
"into:scraper": "docker exec -it scraper bash",
|
||||
"into:search": "docker exec -it search bash",
|
||||
"lint": "eslint src --ext ts,js,tsx,jsx --fix --no-error-on-unmatched-pattern",
|
||||
"ping": "http GET localhost:7700/health",
|
||||
"prep": "run-p start:*",
|
||||
"lint": "pnpm -r eslint src --ext ts,js,tsx,jsx --fix --no-error-on-unmatched-pattern",
|
||||
"lint:docs": "pnpm -C docs run lint",
|
||||
"ping": "npx http GET localhost:7700/health --timeout 2",
|
||||
"prune": "docker system prune",
|
||||
"restart": "docker compose restart",
|
||||
"start": "run-s prep watch",
|
||||
"start:cli": "pnpm install",
|
||||
"start:docker": "run-s up",
|
||||
"start:docs": "pnpm -C docs start",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"ts-ast": "node ./bin/ts-ast.js",
|
||||
"ts-ast-overview": "node ./bin/ts-ast-overview.js",
|
||||
"up": "docker compose up -d",
|
||||
"vol:create": "run-s vol:create:*",
|
||||
"vol:create:scraper": "docker volume create scraper",
|
||||
"vol:create:search": "docker volume create search_db",
|
||||
"vol:inspect": "run-s vol:inspect:*",
|
||||
"vol:inspect:scraper": "docker volume inspect scraper",
|
||||
"vol:inspect:search": "docker volume inspect search_db",
|
||||
"watch": "run-p watch:*",
|
||||
"watch:cli": "tsup src/cli/*.ts --format=esm,cjs --clean --sourcemap -d bin --watch",
|
||||
"watch:npm": "tsup src/models/*.ts src/type/*.ts --format=esm,cjs --clean --sourcemap -d dist --dts --watch",
|
||||
"watch:docs": "pnpm -C docs dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"cheerio": "^1.0.0-rc.10",
|
||||
"gray-matter": "^4.0.3",
|
||||
"inferred-types": "^0.18.4",
|
||||
"native-dash": "^1.21.5",
|
||||
"node-fetch": "^3.2.0",
|
||||
"simple-markdown": "^0.7.3",
|
||||
"ts-morph": "^13.0.3",
|
||||
"xxhash-wasm": "^1.0.1"
|
||||
"docs": "pnpm -C ./packages/docs run dev",
|
||||
"npm": "pnpm -C ./packages/tauri-search run watch:npm",
|
||||
"npm:test": "pnpm -C ./packages/tauri-search run test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/types": "^27.4.2",
|
||||
"@octokit/types": "^6.34.0",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/markdown-it": "^12.2.3",
|
||||
"@types/node": "^14.18.9",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||
"@typescript-eslint/parser": "^5.10.0",
|
||||
"changeset": "^0.2.6",
|
||||
"eslint": "^8.7.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"eslint-plugin-jest": "^25.7.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-promise": "^6.0.0",
|
||||
"fx": "^20.0.2",
|
||||
"husky": "^7.0.4",
|
||||
"jest": "^27.4.7",
|
||||
"jest-extended": "^1.2.0",
|
||||
"markdown-it": "^12.3.2",
|
||||
"markdown-it-anchor": "^8.4.1",
|
||||
"markdown-it-attrs": "^4.1.3",
|
||||
"markdown-it-video": "^0.6.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^27.1.3",
|
||||
"ts-node": "^10.4.0",
|
||||
"tsup": "^5.11.11",
|
||||
"typescript": "^4.6.0-dev.20220124"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14",
|
||||
"pnpm": ">=3"
|
||||
"npm-run-all": "^4.1.5"
|
||||
}
|
||||
}
|
||||
|
||||
3
packages/docs/.eslintrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../.eslintrc"
|
||||
}
|
||||
5
packages/docs/cypress/fixtures/example.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
||||
22
packages/docs/cypress/plugins/index.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
}
|
||||
25
packages/docs/cypress/support/commands.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
20
packages/docs/cypress/support/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
@@ -16,3 +16,8 @@ home:
|
||||
search: Suche
|
||||
desc: Spielplatz für die Tauri-Suche
|
||||
whats-your-name: Suchen Sie nach etwas
|
||||
ask-for-search: Suchen Sie nach etwas
|
||||
nav:
|
||||
indexing: Indizierung
|
||||
toggle_langs: Sprachen ändern
|
||||
toggle_dark: Dunkelmodus umschalten
|
||||
@@ -15,3 +15,9 @@ not-found: No se ha encontrado
|
||||
home:
|
||||
search: Búsqueda
|
||||
whats-your-name: buscar algo
|
||||
ask-for-search: buscar algo
|
||||
desc: Documentación y Patio Interactivo
|
||||
nav:
|
||||
indexing: Indexación
|
||||
toggle_dark: Alternar modo oscuro
|
||||
toggle_langs: Cambiar idiomas
|
||||
@@ -16,3 +16,8 @@ home:
|
||||
desc: Aire de jeux pour Tauri Search
|
||||
search: Chercher
|
||||
whats-your-name: Rechercher quelque chose
|
||||
ask-for-search: Rechercher quelque chose
|
||||
nav:
|
||||
indexing: Indexage
|
||||
toggle_dark: Basculer en mode sombre
|
||||
toggle_langs: Changer de langue
|
||||
@@ -1,40 +1,48 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "pnpm install",
|
||||
"clean": "rimraf dist/*",
|
||||
"start": "pnpm run dev",
|
||||
"build": "vite-ssg build",
|
||||
"dev": "vite --port 3333 --open",
|
||||
"lint": "eslint \"**/*.{vue,ts,js}\"",
|
||||
"lint": "run-s lint:*",
|
||||
"lint:eslint": "eslint \"**/*.{vue,ts,js}\"",
|
||||
"lint:tsc": "vue-tsc --noEmit",
|
||||
"preview": "vite preview",
|
||||
"preview-https": "serve dist",
|
||||
"test": "vitest",
|
||||
"test": "vitest run",
|
||||
"test:e2e": "cypress open",
|
||||
"test:unit": "vitest",
|
||||
"typecheck": "vue-tsc --noEmit"
|
||||
"test:dev": "vitest dev",
|
||||
"test:watch": "vitest watch",
|
||||
"watch": "pnpm run dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vueuse/core": "^7.5.4",
|
||||
"@vueuse/core": "^7.5.5",
|
||||
"@vueuse/head": "^0.7.5",
|
||||
"date-fns": "^2.28.0",
|
||||
"floating-vue": "^2.0.0-beta.3",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.9",
|
||||
"pinia": "^2.0.11",
|
||||
"prism-theme-vars": "^0.2.2",
|
||||
"tauri-search": "workspace:*",
|
||||
"ts-morph": "^13.0.3",
|
||||
"vue": "^3.2.28",
|
||||
"vue": "^3.2.29",
|
||||
"vue-demi": "^0.12.1",
|
||||
"vue-i18n": "^9.1.9",
|
||||
"vue-router": "^4.0.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^0.16.0",
|
||||
"@antfu/eslint-config": "^0.16.1",
|
||||
"@iconify-json/ant-design": "^1.0.2",
|
||||
"@iconify-json/bx": "^1.0.3",
|
||||
"@iconify-json/carbon": "^1.0.14",
|
||||
"@iconify-json/cib": "^1.0.1",
|
||||
"@iconify-json/fluent": "^1.0.15",
|
||||
"@iconify-json/fluent": "^1.0.16",
|
||||
"@iconify-json/ic": "^1.0.8",
|
||||
"@iconify-json/mdi": "^1.0.12",
|
||||
"@iconify-json/iconoir": "^1.0.5",
|
||||
"@iconify-json/mdi": "^1.0.15",
|
||||
"@iconify-json/octicon": "^1.0.9",
|
||||
"@iconify-json/ph": "^1.0.4",
|
||||
"@iconify-json/tabler": "^1.0.12",
|
||||
"@iconify-json/teenyicons": "^1.0.1",
|
||||
@@ -43,32 +51,32 @@
|
||||
"@types/markdown-it-link-attributes": "^3.0.1",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@vitejs/plugin-vue": "^2.1.0",
|
||||
"@vue/compiler-sfc": "^3.2.28",
|
||||
"@vue/server-renderer": "^3.2.28",
|
||||
"@vue/compiler-sfc": "^3.2.29",
|
||||
"@vue/server-renderer": "^3.2.29",
|
||||
"@vue/test-utils": "^2.0.0-rc.18",
|
||||
"critters": "^0.0.16",
|
||||
"cross-env": "^7.0.3",
|
||||
"cypress": "^9.3.1",
|
||||
"eslint": "^8.7.0",
|
||||
"eslint": "^8.8.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"https-localhost": "^4.7.0",
|
||||
"jsdom": "^19.0.0",
|
||||
"markdown-it-collapsible": "^1.0.0",
|
||||
"markdown-it-link-attributes": "^4.0.0",
|
||||
"markdown-it-prism": "^2.2.2",
|
||||
"typescript": "^4.5.5",
|
||||
"unplugin-auto-import": "^0.5.11",
|
||||
"unplugin-icons": "^0.13.0",
|
||||
"unplugin-vue-components": "^0.17.14",
|
||||
"unplugin-vue-components": "^0.17.15",
|
||||
"vite": "^2.7.13",
|
||||
"vite-plugin-inspect": "^0.3.13",
|
||||
"vite-plugin-md": "^0.11.7",
|
||||
"vite-plugin-pages": "^0.20.0",
|
||||
"vite-plugin-pages": "^0.20.1",
|
||||
"vite-plugin-pwa": "^0.11.13",
|
||||
"vite-plugin-vue-layouts": "^0.5.0",
|
||||
"vite-plugin-windicss": "^1.6.3",
|
||||
"vite-ssg": "^0.17.6",
|
||||
"vite-ssg": "^0.17.9",
|
||||
"vitepress": "^0.21.6",
|
||||
"vitest": "^0.1.27",
|
||||
"vitest": "^0.2.5",
|
||||
"vue-tsc": "^0.31.1"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 347 B |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
@@ -183,6 +183,7 @@ declare global {
|
||||
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
|
||||
const useStorage: typeof import('@vueuse/core')['useStorage']
|
||||
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
|
||||
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
|
||||
const useSwipe: typeof import('@vueuse/core')['useSwipe']
|
||||
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
|
||||
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
|
||||
@@ -4,26 +4,40 @@
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
'AntDesign:fileMarkdownOutlined': typeof import('~icons/ant-design/file-markdown-outlined')['default']
|
||||
'Bx:bxCheckbox': typeof import('~icons/bx/bx-checkbox')['default']
|
||||
'Bx:bxCheckboxChecked': typeof import('~icons/bx/bx-checkbox-checked')['default']
|
||||
'Bx:bxCheckboxMinus': typeof import('~icons/bx/bx-checkbox-minus')['default']
|
||||
'Bx:bxSearchAlt': typeof import('~icons/bx/bx-search-alt')['default']
|
||||
'Carbon:document': typeof import('~icons/carbon/document')['default']
|
||||
'Carbon:listDropdown': typeof import('~icons/carbon/list-dropdown')['default']
|
||||
CarbonLanguage: typeof import('~icons/carbon/language')['default']
|
||||
CarbonMoon: typeof import('~icons/carbon/moon')['default']
|
||||
CarbonSun: typeof import('~icons/carbon/sun')['default']
|
||||
Checkbox: typeof import('./components/Checkbox.vue')['default']
|
||||
Counter: typeof import('./components/Counter.vue')['default']
|
||||
CurrentIndex: typeof import('./components/CurrentIndex.vue')['default']
|
||||
'Fluent:databaseSearch24Regular': typeof import('~icons/fluent/database-search24-regular')['default']
|
||||
Footer: typeof import('./components/Footer.vue')['default']
|
||||
'Iconoir:download': typeof import('~icons/iconoir/download')['default']
|
||||
'Mdi:folderHome': typeof import('~icons/mdi/folder-home')['default']
|
||||
'Mdi:github': typeof import('~icons/mdi/github')['default']
|
||||
'Mdi:languageRust': typeof import('~icons/mdi/language-rust')['default']
|
||||
'Mdi:languageTypescript': typeof import('~icons/mdi/language-typescript')['default']
|
||||
MissingIndex: typeof import('./components/MissingIndex.vue')['default']
|
||||
'Octicon:trash16': typeof import('~icons/octicon/trash16')['default']
|
||||
'Ph:info': typeof import('~icons/ph/info')['default']
|
||||
'Ph:linkLight': typeof import('~icons/ph/link-light')['default']
|
||||
README: typeof import('./components/README.md')['default']
|
||||
SearchActions: typeof import('./components/SearchActions.vue')['default']
|
||||
SearchHit: typeof import('./components/SearchHit.vue')['default']
|
||||
SearchIndexes: typeof import('./components/SearchIndexes.vue')['default']
|
||||
SearchResults: typeof import('./components/SearchResults.vue')['default']
|
||||
SearchStats: typeof import('./components/SearchStats.vue')['default']
|
||||
SimpleCard: typeof import('./components/SimpleCard.vue')['default']
|
||||
'Tabler:databaseImport': typeof import('~icons/tabler/database-import')['default']
|
||||
'Teenyicons:dockerOutline': typeof import('~icons/teenyicons/docker-outline')['default']
|
||||
'Teenyicons:textDocumentSolid': typeof import('~icons/teenyicons/text-document-solid')['default']
|
||||
'VscodeIcons:fileTypeRust': typeof import('~icons/vscode-icons/file-type-rust')['default']
|
||||
'VscodeIcons:fileTypeTypescriptOfficial': typeof import('~icons/vscode-icons/file-type-typescript-official')['default']
|
||||
}
|
||||
}
|
||||
|
||||
19
packages/docs/src/components/Checkbox.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<script setup lang="ts">import { PropType } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
value: {type: Boolean as PropType<boolean | undefined>, default: undefined, required: true}
|
||||
});
|
||||
|
||||
const toggle = () => {
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="checkbox text-xl mr-1">
|
||||
<bx:bx-checkbox-minus v-if="props.value === undefined" class="flex cursor-default text-gray-500/50" />
|
||||
<bx:bx-checkbox v-if="props.value=== false" class="flex cursor-pointer text-gray-500/75" @click="toggle" />
|
||||
<bx:bx-checkbox-checked v-if="props.value===true" class="flex cursor-pointer text-gray-800/95 dark:text-gray-100/90" @click="toggle" />
|
||||
|
||||
</div>
|
||||
</template>
|
||||
112
packages/docs/src/components/CurrentIndex.vue
Normal file
@@ -0,0 +1,112 @@
|
||||
<script setup lang="ts">
|
||||
/* eslint-disable no-console */
|
||||
import { useSearch } from "~/modules/search";
|
||||
import { format } from "date-fns";
|
||||
import { PropType } from "vue";
|
||||
import { MeiliSearchInterface } from "~/types/meilisearch";
|
||||
import { ApiModel } from "tauri-search";
|
||||
const s = useSearch();
|
||||
const props = defineProps({
|
||||
idx: {type: Object as PropType<MeiliSearchInterface>, required: true},
|
||||
unknown: {type: Boolean, default: false, required: false}
|
||||
});
|
||||
const indexName = computed(() => props.idx.name as "api" | "repo" | "prose");
|
||||
|
||||
const remove = async () => {
|
||||
// just using ApiModel at random, as we can state which index to remove
|
||||
await ApiModel.query.deleteIndex(indexName.value);
|
||||
};
|
||||
|
||||
const pushCache = async() => {
|
||||
// console.group(`downloading cached docs for "${indexName.value}"`);
|
||||
// const docs = await getCache(indexName.value);
|
||||
// console.info(`${docs.length} docs downloaded, now calling Meilisearch API to add each doc`);
|
||||
// const tasks = await pushDocs(docs);
|
||||
// console.info(`all documents have been sent to the MeiliSearch API where they will be processed in a task queu`);
|
||||
// console.log(`The tasks in queue are:`, tasks);
|
||||
// console.groupEnd();
|
||||
};
|
||||
|
||||
const usedInSearch = computed(() => s.indexIsUsed(indexName.value));
|
||||
|
||||
// async function pushCache() {
|
||||
// const docs = await
|
||||
// }
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="index flex flex-row w-full py-2 px-3 border-1 rounded border-gray-500 mt-4 cursor-default items-center justify-center"
|
||||
:class="props.unknown ? 'unknown' : ''"
|
||||
>
|
||||
<checkbox :value="usedInSearch" @click="s.toggleUseOfIndex(indexName)" />
|
||||
<span class="index-name flex flex-grow font-medium">{{indexName}}</span>
|
||||
<div class="flex flex-row items-center">
|
||||
<!-- Right Content -->
|
||||
<v-tooltip v-if="s.indexInfo(indexName)?.numberOfDocuments === 0 && !props.unknown" class="cursor-pointer text-sm flex flex-grow-0 mr-3 text-gray-500 hover:text-green-800 dark:hover:text-green-500">
|
||||
<iconoir:download class="" @click="pushCache" />
|
||||
<template #popper>Push documents in cache into<br/>local MeiliSearch server</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip>
|
||||
<octicon:trash-16
|
||||
class="cursor-pointer text-sm flex flex-grow-0 mr-3 text-gray-500 hover:text-red-800 dark:hover:text-red-500"
|
||||
@click="remove"
|
||||
/>
|
||||
<template #popper>remove "{{indexName}}" index<span v-if="s.indexInfo(indexName)?.numberOfDocuments || 0 > 0">; including all documents.</span></template>
|
||||
</v-tooltip>
|
||||
<span class="index-count flex flex-grow-0 font-light items-baseline ">
|
||||
<span class="flex">{{s.indexInfo(indexName)?.numberOfDocuments}}</span>
|
||||
|
||||
<span class="flex italic font-light text-xs">docs</span>
|
||||
</span>
|
||||
<v-tooltip placement="right" >
|
||||
<ph:info
|
||||
class=" flex flex-grow-0 ml-2 dark:text-gray-500/75 hover:text-opacity-100 "
|
||||
/>
|
||||
<template #popper>
|
||||
<div class="w-56 text-sm">
|
||||
<div class="font-bold text-lg">
|
||||
{{indexName}}
|
||||
|
||||
<span class="font-light">index</span>
|
||||
</div>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td class="font-normal">created:</td>
|
||||
<td class="font-light" align="right">{{format(new Date(props.idx.createdAt), "do MMM, yyyy")}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="font-normal">updated:</td>
|
||||
<td class="font-light justify-end" align="right" >{{format(new Date(props.idx.updatedAt), "do MMM, yyyy")}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>stop words</td>
|
||||
<td>[]</td>
|
||||
</tr>
|
||||
<tr v-if="s.indexInfo(indexName)?.numberOfDocuments || 0 > 0" class="text-xs">
|
||||
<td>Prop<br/>Distribution</td>
|
||||
<td>
|
||||
<table width="100%">
|
||||
<tr v-for="k in Object.keys(s.$state.stats?.indexes[indexName].fieldDistribution|| {}) " :key="k">
|
||||
<td>{{ k }}</td>
|
||||
<td>{{ s.$state.stats?.indexes[indexName].fieldDistribution[k]}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.unknown {
|
||||
@apply border-orange-500/50
|
||||
}
|
||||
</style>
|
||||
41
packages/docs/src/components/MissingIndex.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<script setup lang="ts">
|
||||
import { ApiModel, ConsolidatedModel, ProseModel, RepoModel } from "tauri-search";
|
||||
import { PropType } from "vue";
|
||||
import { useSearch } from "~/modules/search";
|
||||
const s = useSearch();
|
||||
const props = defineProps({
|
||||
idx: {type: String as PropType<"api" | "prose" | "repo" | "consolidated">, required: true}
|
||||
});
|
||||
const models = {
|
||||
api: ApiModel,
|
||||
prose: ProseModel,
|
||||
repo: RepoModel,
|
||||
consolidated: ConsolidatedModel
|
||||
};
|
||||
|
||||
async function addIndex() {
|
||||
const model = models[props.idx];
|
||||
await model.query.createIndex();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-tooltip class="w-full" placement="right" :delay="8000">
|
||||
<div
|
||||
class="index flex flex-row w-full py-2 px-3 border-1 rounded border-dashed border-gray-300 dark:border-gray-700 mt-4 cursor-default"
|
||||
>
|
||||
<span class="index-name flex flex-grow font-medium">{{idx}}</span>
|
||||
<span class="index-count flex flex-grow-0 font-light cursor-pointer items-baseline">
|
||||
<v-tooltip :delay="750" placement="right">
|
||||
<button class="text-xs italic px-2 py-1 bg-gray-300/75 hover:bg-green-300/75 dark:hover:bg-green-700/75 dark:bg-gray-700/75 rounded-md" @click="addIndex">add index</button>
|
||||
<template #popper>will create an empty index for "{{idx}}"</template>
|
||||
</v-tooltip>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
<template #popper>
|
||||
The <span class="tag">{{idx}}</span> index is defined as a MODEL but doesn't yet exist in MeiliSearch as an index.
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</template>
|
||||
|
||||
101
packages/docs/src/components/SearchHit.vue
Normal file
@@ -0,0 +1,101 @@
|
||||
<script setup lang="ts">
|
||||
import { PropType } from "vue";
|
||||
import { GenericDoc } from "~/types/meilisearch";
|
||||
|
||||
const props = defineProps({
|
||||
document: {
|
||||
type: Object as PropType<GenericDoc>, required: true}
|
||||
});
|
||||
|
||||
const doc = computed(() => props.document);
|
||||
const showDetails = ref(false);
|
||||
|
||||
const apiKind = computed(() => {
|
||||
if(doc.value._idx !== "api") {
|
||||
return "";
|
||||
}
|
||||
switch(doc.value.kind) {
|
||||
case "Function":
|
||||
return "fn";
|
||||
case "Namespace":
|
||||
return "module";
|
||||
case "Interface":
|
||||
return "interface";
|
||||
default:
|
||||
return doc.value?.kind ? String(doc.value?.kind).toLowerCase() : "";
|
||||
}
|
||||
});
|
||||
|
||||
const details = () => {
|
||||
showDetails.value = !showDetails.value;
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col border-1 rounded px-2 py-1 border-gray-500 hover:bg-gray-100/50 dark:hover:bg-gray-700/50 ">
|
||||
<div class="flex flex-row space-x-1 items-center place-content-center cursor-pointer" @click="details">
|
||||
<div v-if="doc._idx === 'repo'" class="flex flex-row flex-grow space-x-1 items-center place-items-center">
|
||||
<mdi:github class="flex flex-shrink-0" />
|
||||
<div class="name font-semibold flex-shrink-0 pr-2">{{doc.name}}</div>
|
||||
<div class="description flex flex-grow font-light text-sm truncate text-gray-500">{{doc.description}}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="doc._idx === 'api'" class="flex flex-row flex-grow space-x-2 place-items-center items-center">
|
||||
<vscode-icons:file-type-typescript-official v-if="doc.language === 'typescript'" class="flex flex-shrink-0" />
|
||||
<vscode-icons:file-type-rust v-if="doc.language === 'rust'" class="flex" />
|
||||
<span class="flex">{{ doc.name }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="doc._idx === 'prose'" class="flex flex-row flex-grow space-x-2 place-items-center items-center">
|
||||
<ant-design:file-markdown-outlined class="flex" />
|
||||
<div class="name">{{doc.title}}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="doc._idx === 'consolidated'" class="w-full">
|
||||
<div v-if="doc.from === 'api'" class="flex flex-row flex-grow space-x-2 place-items-center items-center">
|
||||
<vscode-icons:file-type-rust v-if="doc.language === 'rust'" class="flex" />
|
||||
<vscode-icons:file-type-typescript-official v-else class="flex" />
|
||||
|
||||
<div class="symbolName font-semibold">{{doc.lvl0}}</div>
|
||||
<div class="text-sm font-light">{{doc.symbol}}</div>
|
||||
</div>
|
||||
|
||||
<!-- PROSE -->
|
||||
<div v-if="doc.from === 'prose'" class="flex flex-row flex-grow space-x-2 place-items-center items-center">
|
||||
<teenyicons:text-document-solid class="flex" />
|
||||
<div class="title font-semibold flex-shrink-0">{{doc.lvl0}}</div>
|
||||
<div class="title font-light truncate text-gray-500">{{doc.lvl1}}</div>
|
||||
</div>
|
||||
|
||||
<!-- REPOs -->
|
||||
<div v-if="doc.from === 'repo'" class="flex flex-row flex-grow space-x-2 place-items-center items-center">
|
||||
<mdi:github class="flex flex-shrink-0" />
|
||||
<div class="name font-semibold flex-shrink-0">{{doc.lvl0}}</div>
|
||||
<div class="description truncate flex-shrink text-gray-500 font-light">{{doc.lvl1}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div v-if="doc._idx === 'api'" class="flex text-xs font-medium px-1 py-0.5 bg-blue-500 dark:bg-blue-600 text-gray-50 rounded">
|
||||
{{apiKind}}
|
||||
</div>
|
||||
<div class="flex px-1 hover:text-green-600 hover:font-bold ">
|
||||
<a :href="doc.url" target="_new">
|
||||
<ph:link-light class="flex" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div v-if="showDetails" class="items-start">
|
||||
<div v-for="key in Object.keys(doc)" :key="key" class="flex flex-row">
|
||||
<span class="flex font-bold">{{key}}:</span>
|
||||
<span class="flex ml-1">{{doc[key]}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
50
packages/docs/src/components/SearchIndexes.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<script setup lang="ts">
|
||||
import { useSearch } from "~/modules/search";
|
||||
const search = useSearch();
|
||||
|
||||
/**
|
||||
* this allows all expected indexes to be shown and in a sensible order
|
||||
*/
|
||||
const knownIndexes = ["api", "prose", "repo", "consolidated"];
|
||||
/** the name of the indexes current known by MeiliSearch */
|
||||
const currentIndexes = computed(() => search.$state.indexes.map(i => i.name));
|
||||
|
||||
/**
|
||||
* we do want to see ANY index that exists though too
|
||||
*/
|
||||
const unknownIndexes = computed(() => {
|
||||
return search.$state.indexes.filter(i => !knownIndexes.includes(i.name));
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="search-indexes flex flex-col flex-grow rounded-md bg-gray-100/25 dark:bg-gray-800/25">
|
||||
|
||||
<div class="rounded-t-md overflow-hidden">
|
||||
<div class="font-bold text-lg rounded-t-md bg-gray-900/10 dark:bg-gray-100/10 py-3 px-4">
|
||||
INDEXES
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="search.$state.health" class="text-xs mt-2" >
|
||||
<div class="text-green-500">MeiliSearch Service Healthy!</div>
|
||||
<div class="db-size">db size: {{search.dbSize}}</div>
|
||||
</div>
|
||||
<span v-else class="text-red-500 ">
|
||||
Meilisearch is not available locally!
|
||||
</span>
|
||||
|
||||
<div class="index-list p-4 w-full flex flex-col ">
|
||||
<template v-for="idx in knownIndexes" :key="idx">
|
||||
<current-index v-if="currentIndexes.includes(idx)" :idx="search.$state.indexes.find(i => i.name === idx)"/>
|
||||
<missing-index v-else :idx="idx" />
|
||||
</template>
|
||||
<template v-for="idx in unknownIndexes" :key="idx">
|
||||
<current-index :idx="idx" :unknown="true" />
|
||||
</template>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,17 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { useSearch } from "~/modules/search";
|
||||
const props = defineProps({
|
||||
query: {type: String, default: ""}
|
||||
});
|
||||
import { useSearch } from "~/modules/search";
|
||||
const s = useSearch();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="search-stats flex flex-col rounded-md h-full">
|
||||
<div class="search-stats flex flex-col rounded-md h-full min-h-128">
|
||||
|
||||
<div class="rounded-t-md overflow-hidden">
|
||||
<div class="font-bold text-lg rounded-t-md bg-gray-900/10 dark:bg-gray-100/10 py-3 px-4">
|
||||
Results
|
||||
<div class="grid grid-cols-3 rounded-t-md bg-gray-900/10 dark:bg-gray-100/10 py-3 px-4 ">
|
||||
<div class="block text-sm font-light place-self-start self-center">
|
||||
{{s.$state.searchUsing.length}} <span class="italic">index(s) searched</span>
|
||||
</div>
|
||||
<div class="block font-bold text-lg place-self-center self-center">
|
||||
Results
|
||||
</div>
|
||||
<div class="block text-sm font-light place-self-end self-center">
|
||||
{{s.$state.searchResults.length}} <span class="italic">docs found</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n();
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="text-center text-gray-700 dark:text-gray-200 flex items-center justify-center flex-col ">
|
||||
<main class="text-center text-gray-700 dark:text-gray-200 flex flex-col items-center justify-center flex-col min-h-full ">
|
||||
<!-- HEADER -->
|
||||
<div class="flex flex-col justify-center bg-blue-900 text-gray-100 dark:bg-blue-800/50 w-full space-y-4 align-middle items-center justify-center py-2">
|
||||
<div class="flex flex-col ">
|
||||
@@ -18,8 +19,8 @@ const { t } = useI18n()
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
<!-- MAIN CONTENt -->
|
||||
<div class="flex max-w-4xl h-auto min-h-full dark:bg-black/25 p-4 rounded-lg w-4xl">
|
||||
<!-- MAIN CONTENT -->
|
||||
<div class="flex flex-grow max-w-6xl h-auto min-h-full dark:bg-black/25 p-4 rounded-lg w-6xl">
|
||||
<router-view />
|
||||
</div>
|
||||
</main>
|
||||
33
packages/docs/src/main.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
// register vue composition api globally
|
||||
import { ViteSSG } from "vite-ssg";
|
||||
import generatedRoutes from "virtual:generated-pages";
|
||||
import { setupLayouts } from "virtual:generated-layouts";
|
||||
import FloatingVue from "floating-vue";
|
||||
|
||||
import "floating-vue/dist/style.css";
|
||||
import App from "./App.vue";
|
||||
|
||||
// windicss layers
|
||||
import "virtual:windi-base.css";
|
||||
import "virtual:windi-components.css";
|
||||
// your custom styles here
|
||||
import "./styles/main.css";
|
||||
// windicss utilities should be the last style import
|
||||
import "virtual:windi-utilities.css";
|
||||
// windicss devtools support (dev only)
|
||||
import "virtual:windi-devtools";
|
||||
|
||||
const routes = setupLayouts(generatedRoutes);
|
||||
|
||||
// https://github.com/antfu/vite-ssg
|
||||
export const createApp = ViteSSG(
|
||||
App,
|
||||
{ routes, base: import.meta.env.BASE_URL },
|
||||
(ctx) => {
|
||||
// install all modules under `modules/`
|
||||
Object.values(import.meta.globEager("./modules/*.ts")).map(i => i.install?.(ctx));
|
||||
ctx.app.use(FloatingVue);
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import type { UserModule } from '~/types'
|
||||
import { createI18n } from "vue-i18n";
|
||||
import type { UserModule } from "~/types";
|
||||
|
||||
// Import i18n resources
|
||||
// https://vitejs.dev/guide/features.html#glob-import
|
||||
//
|
||||
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
|
||||
const messages = Object.fromEntries(
|
||||
Object.entries(import.meta.globEager('../../locales/*.y(a)?ml')).map(([key, value]) => {
|
||||
const yaml = key.endsWith('.yaml')
|
||||
return [key.slice(14, yaml ? -5 : -4), value.default]
|
||||
Object.entries(import.meta.globEager("../../locales/*.y(a)?ml")).map(([key, value]) => {
|
||||
const yaml = key.endsWith(".yaml");
|
||||
return [key.slice(14, yaml ? -5 : -4), value.default];
|
||||
}),
|
||||
)
|
||||
);
|
||||
|
||||
export const install: UserModule = ({ app }) => {
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
locale: "en",
|
||||
messages,
|
||||
})
|
||||
});
|
||||
|
||||
app.use(i18n)
|
||||
}
|
||||
app.use(i18n);
|
||||
};
|
||||
13
packages/docs/src/modules/nprogress.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import NProgress from "nprogress";
|
||||
import type { UserModule } from "~/types";
|
||||
|
||||
export const install: UserModule = ({ isClient, router }) => {
|
||||
if (isClient) {
|
||||
router.beforeEach(() => {
|
||||
NProgress.start();
|
||||
});
|
||||
router.afterEach(() => {
|
||||
NProgress.done();
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,14 +1,14 @@
|
||||
import { createPinia } from 'pinia'
|
||||
import type { UserModule } from '~/types'
|
||||
import { createPinia } from "pinia";
|
||||
import type { UserModule } from "~/types";
|
||||
|
||||
// Setup Pinia
|
||||
// https://pinia.esm.dev/
|
||||
export const install: UserModule = ({ isClient, initialState, app }) => {
|
||||
const pinia = createPinia()
|
||||
app.use(pinia)
|
||||
const pinia = createPinia();
|
||||
app.use(pinia);
|
||||
// Refer to
|
||||
// https://github.com/antfu/vite-ssg/blob/main/README.md#state-serialization
|
||||
// for other serialization strategies.
|
||||
if (isClient) pinia.state.value = initialState.pinia || {}
|
||||
else initialState.pinia = pinia.state.value
|
||||
}
|
||||
if (isClient) pinia.state.value = initialState.pinia || {};
|
||||
else initialState.pinia = pinia.state.value;
|
||||
};
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { UserModule } from '~/types'
|
||||
import type { UserModule } from "~/types";
|
||||
|
||||
// https://github.com/antfu/vite-plugin-pwa#automatic-reload-when-new-content-available
|
||||
export const install: UserModule = ({ isClient, router }) => {
|
||||
if (!isClient) return
|
||||
if (!isClient) return;
|
||||
|
||||
router.isReady().then(async() => {
|
||||
const { registerSW } = await import('virtual:pwa-register')
|
||||
registerSW({ immediate: true })
|
||||
})
|
||||
}
|
||||
const { registerSW } = await import("virtual:pwa-register");
|
||||
registerSW({ immediate: true });
|
||||
});
|
||||
};
|
||||
@@ -3,6 +3,8 @@
|
||||
import { acceptHMRUpdate, defineStore } from "pinia";
|
||||
import type { UserModule } from "~/types";
|
||||
import { MeiliSearchHealth, MeiliSearchIndex, MeiliSearchInterface, MeiliSearchResponse, MeiliSearchStats } from "~/types/meilisearch";
|
||||
import { IMeilisearchIndexSettings } from "tauri-search";
|
||||
|
||||
|
||||
//#region STORE
|
||||
export interface SearchState {
|
||||
@@ -12,9 +14,15 @@ export interface SearchState {
|
||||
/** the indexes which are defined on MeiliSearch */
|
||||
indexes: MeiliSearchInterface[];
|
||||
|
||||
/** indexes to use when searching */
|
||||
searchUsing: string[];
|
||||
|
||||
/** database stats for MeiliSearch */
|
||||
stats?: MeiliSearchStats;
|
||||
|
||||
/** index settings */
|
||||
indexSettings: Record<string, IMeilisearchIndexSettings<any>>;
|
||||
|
||||
searchStatus: "ready" | "searching" | "error" | "not-ready";
|
||||
|
||||
searchResults: {id: string; _idx: string; [key: string]: unknown}[];
|
||||
@@ -24,19 +32,19 @@ export const useSearch = defineStore("search", ({
|
||||
state: () => ({
|
||||
health: "initializing",
|
||||
indexes: [],
|
||||
indexSettings: {},
|
||||
searchUsing: ["consolidated"],
|
||||
stats: undefined,
|
||||
searchStatus: "not-ready",
|
||||
searchResults: [],
|
||||
}) as SearchState,
|
||||
actions: {
|
||||
async search(text: string, indexes?: string[]) {
|
||||
async search(text: string) {
|
||||
if(text.trim()==="") {
|
||||
this.$state.searchResults = [];
|
||||
return;
|
||||
}
|
||||
if(!indexes) {
|
||||
indexes = this.$state.indexes.map(i => i.uid);
|
||||
}
|
||||
const indexes = this.$state.searchUsing;
|
||||
console.group(`searching for: "${text}"`);
|
||||
console.info(`search on ${indexes.length} indexes`, indexes);
|
||||
console.time("search");
|
||||
@@ -71,6 +79,13 @@ export const useSearch = defineStore("search", ({
|
||||
|
||||
return results;
|
||||
},
|
||||
toggleUseOfIndex(idx: string) {
|
||||
if(this.$state.searchUsing.includes(idx)) {
|
||||
this.$state.searchUsing = this.$state.searchUsing.filter(i => i !== idx);
|
||||
} else {
|
||||
this.$state.searchUsing = [...this.$state.searchUsing, idx];
|
||||
}
|
||||
},
|
||||
statsUpdate(s: MeiliSearchStats) {
|
||||
this.$state.stats = s;
|
||||
},
|
||||
@@ -78,10 +93,17 @@ export const useSearch = defineStore("search", ({
|
||||
this.$state.health = h;
|
||||
},
|
||||
indexUpdate(idx: MeiliSearchInterface[]) {
|
||||
const current = this.$state.indexes.map(i => i.name);
|
||||
const newList = idx.map(i => i.name);
|
||||
if(current.length === newList.length && newList.every(i => current.includes(i))) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$state.indexes = idx;
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
indexIsUsed: (state) => (idx: string) => state.searchUsing.includes(idx),
|
||||
dbSize: (state) => state.stats?.databaseSize || 0,
|
||||
indexInfo: (state) => (idx: string): MeiliSearchIndex | undefined => state.stats?.indexes[idx]
|
||||
}
|
||||
@@ -118,8 +140,11 @@ export const install: UserModule = ({ isClient }) => {
|
||||
s.healthUpdate(h);
|
||||
s.$state.searchStatus = !h ? "not-ready": "ready";
|
||||
|
||||
if(h === true && !isActive) resume();
|
||||
if(h === false && isActive) pause();
|
||||
if(h === true && !isActive.value) {
|
||||
createIndexes();
|
||||
resume();
|
||||
};
|
||||
if(h === false && isActive.value) pause();
|
||||
}, 1000, {immediate: true});
|
||||
|
||||
}
|
||||
@@ -157,10 +182,14 @@ function api(base: string = "http://localhost:7700") {
|
||||
}
|
||||
|
||||
async function health(): Promise<boolean> {
|
||||
const response = await (
|
||||
await fetch(api().health)
|
||||
).json() as MeiliSearchHealth;
|
||||
return response.status === "available";
|
||||
try {
|
||||
const response = await (
|
||||
await fetch(api().health)
|
||||
).json() as MeiliSearchHealth;
|
||||
return response.status === "available";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function indexes() {
|
||||
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
103
packages/docs/src/pages/index.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Getting Started
|
||||
|
||||
+++ Install Dependencies and Start Docs Site (_looks like you already did_)
|
||||
```bash
|
||||
# 1. installs deps for both CLI and Docs
|
||||
# 2. starts Docs server (in dev mode with HMR), opens in browser
|
||||
# 3. starts Meilisearch server in Docker
|
||||
pnpm run start
|
||||
```
|
||||
|
||||
> A browser window should now have opened to [`http://localhost:3333`](http://localhost:3333).
|
||||
|
||||
You are now up and running with the documentation site -- and assuming you have Docker installed -- a local [search server](./meilisearch) which you can interact with.
|
||||
|
||||
### Already installed Deps?
|
||||
|
||||
If you've already installed all the deps and want more granular control you can choose from the various script targets or just choose _watch_ to look at docs with active editing capability:
|
||||
|
||||
```bash
|
||||
# turn on watcher mode for both CLI and Docs
|
||||
pnpm run watch
|
||||
```
|
||||
+++
|
||||
+++ Ways to Consume this library
|
||||
- **Search Development** - if you are updating docs, index definitions, etc. you'll run this in _watch_ mode (aka., `pnpm run start` (first time) or `pnpm run watch`)
|
||||
- **Deployment** - When an _upstream_ dependency is updated this repo should be trigged by a Netlify build hook. For instance:
|
||||
- `tauri` has a new release to production branch, as a `postbuild` step in Netlify build process, it will call Netlify's API and ask for a rebuild of this repo.
|
||||
- we care about picking up the two AST files to build the API docs (`ts-docs.json`, `rust.json`)
|
||||
- `tauri-docs` releases new docs, again a `postbuild` hook on Netlify is called to it requests a rebuild from this repo
|
||||
- here we need to pickup the directly or MD files
|
||||
- **NPM Dependency** - the `Models` you've defined along with all of the _types_ defined are available as an NPM dependency
|
||||
```ts
|
||||
import { ProseModel } from "tauri-search";
|
||||
import type { MeiliSearchResponse } from "tauri-search";
|
||||
```
|
||||
+++
|
||||
|
||||
## Models
|
||||
|
||||
Central to using this library to build and refresh your search indexes is understanding the concept of `Model`.
|
||||
- A Model has a `1:1` relationship with search indexes (or at least _potential_ indexes)
|
||||
- A Model is intended to represent:
|
||||
- the **document structure** that will be used for docs in the index
|
||||
- allows for **configuring the index** itself (e.g., stop words, synonyms, etc.)
|
||||
- allows you to embed data mappers which map from one document structure to another
|
||||
+++ Take a look at the examples here to get a better bearing:
|
||||
- +++ define the model:
|
||||
```ts
|
||||
/** structure for documents in the Prose index */
|
||||
export interface IProse {
|
||||
title: string; section: string;
|
||||
lastUpdated: number; url: string;
|
||||
}
|
||||
/** structure for the input data structure */
|
||||
export interface IMarkdownAst {
|
||||
h1: string; h2: string; h3: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
/** create the Prose model */
|
||||
const Prose = createModel("prose", c => c //
|
||||
.synonomys({ js: ["javascript"], javascript: ["js"]})
|
||||
.addMapper("markdown").mapDefn<IMarkdownAst>(i => {
|
||||
title: i.h1,
|
||||
section: i.h2,
|
||||
lastUpdated: i.lastUpdated,
|
||||
url: i.url
|
||||
})
|
||||
)
|
||||
```
|
||||
- +++ use the model to call the MeiliSearch API
|
||||
```ts
|
||||
import { Prose } from "./models";
|
||||
// create an index
|
||||
await Prose.api.createIndex();
|
||||
// get index stats
|
||||
await Prose.api.stats();
|
||||
// search on index
|
||||
await Prose.api.search("foobar");
|
||||
```
|
||||
- +++ leverage mappers embedded in the model
|
||||
```ts
|
||||
import { Prose } from "./models";
|
||||
|
||||
// map from Input structure to expected document structure
|
||||
const doc: IProse = Prose.mapWith("markdown", data);
|
||||
|
||||
// using mapping to perform an update on the index
|
||||
await Prose.updateWith("markdown", data);
|
||||
```
|
||||
> note: in the examples we're supposing `data` to be a single Node/Record but
|
||||
> you can actually pass in either a single record or a list and it will manage
|
||||
> both
|
||||
|
||||
## External Resources
|
||||
- General Documentation
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [MeiliSearch Website Docs](https://docs.meilisearch.com/learn/what_is_meilisearch/)
|
||||
- API Docs
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [Open API for MeiliSearch](https://bump.sh/doc/meilisearch)
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [API Docs from MeiliSearch Website](https://docs.meilisearch.com/reference/api/)
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [Postman Collection of MeiliSearch API](https://docs.meilisearch.com/postman/meilisearch-collection.json)
|
||||
- Interactive
|
||||
- <span class="bg-green-500 rounded px-2 py-1 text-white">GET</span> - [MeiliSearch Dashboard](http://localhost:7700/)
|
||||
@@ -24,7 +24,7 @@ onStartTyping(() => {
|
||||
<template>
|
||||
<div class="py-3 w-full h-full">
|
||||
<h1 class="text-xl mb-4">
|
||||
Meilisearch Playground
|
||||
MeiliSearch Playground
|
||||
</h1>
|
||||
|
||||
<input
|
||||
@@ -44,8 +44,7 @@ onStartTyping(() => {
|
||||
|
||||
<div class="results-area grid grid-cols-3 gap-4 h-full mt-8 mx-4">
|
||||
<div class="flex flex-col col-span-1 space-y-4">
|
||||
<search-actions />
|
||||
<search-stats class="mt-4" />
|
||||
<search-indexes class="" />
|
||||
</div>
|
||||
|
||||
<div class="col-span-2 rounded-md bg-gray-100/25 dark:bg-gray-900/25">
|
||||
@@ -23,5 +23,5 @@
|
||||
}
|
||||
},
|
||||
"include": ["src", "test", "vite.config.ts"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
"exclude": ["dist", "node_modules",]
|
||||
}
|
||||
@@ -165,7 +165,7 @@ export default defineConfig({
|
||||
include: ["test/**/*.test.ts"],
|
||||
environment: "jsdom",
|
||||
api: {
|
||||
port: 5555,
|
||||
port: 4444,
|
||||
host: "0.0.0.0",
|
||||
|
||||
},
|
||||
3
packages/tauri-search/.eslintrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../.eslintrc"
|
||||
}
|
||||