Skip to content

Commit 655ea3c

Browse files
Implement pagefind plugin with indexing and search integration (#2704)
* Add pagefind plugin scaffolding with search and index commands Co-Authored-By: yujonglee <[email protected]> * Add pagefind plugin registration in desktop app Co-Authored-By: yujonglee <[email protected]> * Implement Pagefind indexing and search integration - Add Pagefind Rust API for building search indexes - Store index files in app data directory - Add TypeScript search module using Pagefind JS API - Commands: buildIndex, getBundlePath, clearIndex - Search functions: search, debouncedSearch, getFilters, preload Co-Authored-By: yujonglee <[email protected]> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: yujonglee <[email protected]>
1 parent 1b0ad70 commit 655ea3c

File tree

24 files changed

+1770
-89
lines changed

24 files changed

+1770
-89
lines changed

Cargo.lock

Lines changed: 730 additions & 89 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ tauri-plugin-network = { path = "plugins/network" }
150150
tauri-plugin-notification = { path = "plugins/notification" }
151151
tauri-plugin-notify = { path = "plugins/notify" }
152152
tauri-plugin-overlay = { path = "plugins/overlay" }
153+
tauri-plugin-pagefind = { path = "plugins/pagefind" }
153154
tauri-plugin-path2 = { path = "plugins/path2" }
154155
tauri-plugin-pdf = { path = "plugins/pdf" }
155156
tauri-plugin-permissions = { path = "plugins/permissions" }

apps/desktop/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"@hypr/plugin-notification": "workspace:*",
5050
"@hypr/plugin-notify": "workspace:*",
5151
"@hypr/plugin-overlay": "workspace:*",
52+
"@hypr/plugin-pagefind": "workspace:*",
5253
"@hypr/plugin-path2": "workspace:*",
5354
"@hypr/plugin-pdf": "workspace:*",
5455
"@hypr/plugin-permissions": "workspace:*",

apps/desktop/src-tauri/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ tauri-plugin-notify = { workspace = true }
5151
tauri-plugin-opener = { workspace = true }
5252
tauri-plugin-os = { workspace = true }
5353
tauri-plugin-overlay = { workspace = true }
54+
tauri-plugin-pagefind = { workspace = true }
5455
tauri-plugin-path2 = { workspace = true }
5556
tauri-plugin-pdf = { workspace = true }
5657
tauri-plugin-permissions = { workspace = true }

apps/desktop/src-tauri/capabilities/default.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@
173173
"notification:default",
174174
"notify:default",
175175
"overlay:default",
176+
"pagefind:default",
176177
"shell:allow-open",
177178
{
178179
"identifier": "shell:allow-execute",

apps/desktop/src-tauri/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ pub async fn main() {
106106
.plugin(tauri_plugin_extensions::init())
107107
.plugin(tauri_plugin_notification::init())
108108
.plugin(tauri_plugin_overlay::init())
109+
.plugin(tauri_plugin_pagefind::init())
109110
.plugin(tauri_plugin_clipboard_manager::init())
110111
.plugin(tauri_plugin_tray::init())
111112
.plugin(tauri_plugin_store::Builder::default().build())

plugins/pagefind/.gitignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/.vs
2+
.DS_Store
3+
.Thumbs.db
4+
*.sublime*
5+
.idea/
6+
debug.log
7+
package-lock.json
8+
.vscode/settings.json
9+
yarn.lock
10+
11+
/.tauri
12+
/target
13+
Cargo.lock
14+
node_modules/
15+
16+
dist-js
17+
dist

plugins/pagefind/Cargo.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[package]
2+
name = "tauri-plugin-pagefind"
3+
version = "0.1.0"
4+
authors = ["You"]
5+
edition = "2024"
6+
exclude = ["/js", "/node_modules"]
7+
links = "tauri-plugin-pagefind"
8+
description = ""
9+
10+
[build-dependencies]
11+
tauri-plugin = { workspace = true, features = ["build"] }
12+
13+
[dev-dependencies]
14+
specta-typescript = { workspace = true }
15+
tokio = { workspace = true, features = ["macros", "sync"] }
16+
17+
[dependencies]
18+
pagefind = "1.4.0"
19+
20+
tauri = { workspace = true, features = ["test"] }
21+
tauri-specta = { workspace = true, features = ["derive", "typescript"] }
22+
23+
serde = { workspace = true }
24+
specta = { workspace = true }
25+
26+
anyhow = { workspace = true }
27+
thiserror = { workspace = true }
28+
tokio = { workspace = true, features = ["sync"] }

plugins/pagefind/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const COMMANDS: &[&str] = &["search", "index"];
2+
3+
fn main() {
4+
tauri_plugin::Builder::new(COMMANDS).build();
5+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// @ts-nocheck
2+
3+
// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually.
4+
5+
/** user-defined commands **/
6+
7+
8+
export const commands = {
9+
async buildIndex(records: IndexRecord[]) : Promise<Result<null, string>> {
10+
try {
11+
return { status: "ok", data: await TAURI_INVOKE("plugin:pagefind|build_index", { records }) };
12+
} catch (e) {
13+
if(e instanceof Error) throw e;
14+
else return { status: "error", error: e as any };
15+
}
16+
},
17+
async getBundlePath() : Promise<Result<string, string>> {
18+
try {
19+
return { status: "ok", data: await TAURI_INVOKE("plugin:pagefind|get_bundle_path") };
20+
} catch (e) {
21+
if(e instanceof Error) throw e;
22+
else return { status: "error", error: e as any };
23+
}
24+
},
25+
async clearIndex() : Promise<Result<null, string>> {
26+
try {
27+
return { status: "ok", data: await TAURI_INVOKE("plugin:pagefind|clear_index") };
28+
} catch (e) {
29+
if(e instanceof Error) throw e;
30+
else return { status: "error", error: e as any };
31+
}
32+
}
33+
}
34+
35+
/** user-defined events **/
36+
37+
38+
39+
/** user-defined constants **/
40+
41+
42+
43+
/** user-defined types **/
44+
45+
export type IndexRecord = { url: string; content: string; title: string | null }
46+
47+
/** tauri-specta globals **/
48+
49+
import {
50+
invoke as TAURI_INVOKE,
51+
Channel as TAURI_CHANNEL,
52+
} from "@tauri-apps/api/core";
53+
import * as TAURI_API_EVENT from "@tauri-apps/api/event";
54+
import { type WebviewWindow as __WebviewWindow__ } from "@tauri-apps/api/webviewWindow";
55+
56+
type __EventObj__<T> = {
57+
listen: (
58+
cb: TAURI_API_EVENT.EventCallback<T>,
59+
) => ReturnType<typeof TAURI_API_EVENT.listen<T>>;
60+
once: (
61+
cb: TAURI_API_EVENT.EventCallback<T>,
62+
) => ReturnType<typeof TAURI_API_EVENT.once<T>>;
63+
emit: null extends T
64+
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
65+
: (payload: T) => ReturnType<typeof TAURI_API_EVENT.emit>;
66+
};
67+
68+
export type Result<T, E> =
69+
| { status: "ok"; data: T }
70+
| { status: "error"; error: E };
71+
72+
function __makeEvents__<T extends Record<string, any>>(
73+
mappings: Record<keyof T, string>,
74+
) {
75+
return new Proxy(
76+
{} as unknown as {
77+
[K in keyof T]: __EventObj__<T[K]> & {
78+
(handle: __WebviewWindow__): __EventObj__<T[K]>;
79+
};
80+
},
81+
{
82+
get: (_, event) => {
83+
const name = mappings[event as keyof T];
84+
85+
return new Proxy((() => {}) as any, {
86+
apply: (_, __, [window]: [__WebviewWindow__]) => ({
87+
listen: (arg: any) => window.listen(name, arg),
88+
once: (arg: any) => window.once(name, arg),
89+
emit: (arg: any) => window.emit(name, arg),
90+
}),
91+
get: (_, command: keyof __EventObj__<any>) => {
92+
switch (command) {
93+
case "listen":
94+
return (arg: any) => TAURI_API_EVENT.listen(name, arg);
95+
case "once":
96+
return (arg: any) => TAURI_API_EVENT.once(name, arg);
97+
case "emit":
98+
return (arg: any) => TAURI_API_EVENT.emit(name, arg);
99+
}
100+
},
101+
});
102+
},
103+
},
104+
);
105+
}

0 commit comments

Comments
 (0)