tauri_plugin_persistence/
lib.rs

1//! High-level abstractions for project contexts & database access for Tauri applications.
2//! 
3//! Primary features:
4//! - Database creation & management with PoloDB
5//! - Management of open file handles
6//! - Basic filesystem operations within the context
7//! - Automatic prevention of context escapes
8
9
10use std::collections::HashMap;
11use tauri::{
12    plugin::{Builder, TauriPlugin},
13    Manager, Runtime,
14};
15
16mod api;
17mod commands;
18#[cfg(desktop)]
19mod desktop;
20
21pub use api::{Collection, Context, Database, Error, FileHandle, Result, Transaction, types};
22pub(crate) use api::state;
23
24#[cfg(desktop)]
25pub use desktop::Persistence;
26use tauri_specta::collect_commands;
27use tokio::sync::Mutex;
28
29/// Extensions to [`tauri::App`], [`tauri::AppHandle`] and [`tauri::Window`] to access the persistence APIs.
30pub trait PersistenceExt<R: Runtime> {
31    /// Gets a reference to the [Persistence] API
32    fn persistence(&self) -> &Persistence<R>;
33}
34
35impl<R: Runtime, T: Manager<R>> crate::PersistenceExt<R> for T {
36    fn persistence(&self) -> &Persistence<R> {
37        self.state::<Persistence<R>>().inner()
38    }
39}
40
41#[doc(hidden)]
42fn builder() -> tauri_specta::Builder<tauri::Wry> {
43    tauri_specta::Builder::<tauri::Wry>::new()
44    .plugin_name("persistence")
45    .commands(collect_commands![
46        commands::context,
47        commands::database,
48        commands::file_handle,
49        commands::database_get_collections,
50        commands::database_close,
51        commands::database_start_transaction,
52        commands::database_commit_transaction,
53        commands::database_rollback_transaction,
54        commands::collection_count_documents,
55        commands::collection_update_documents,
56        commands::collection_delete_documents,
57        commands::collection_create_index,
58        commands::collection_drop_index,
59        commands::collection_drop,
60        commands::collection_insert_documents,
61        commands::collection_find_many_documents,
62        commands::collection_find_one_document,
63        commands::file_close,
64        commands::file_write_text,
65        commands::file_write_bytes,
66        commands::file_read_text,
67        commands::file_read_bytes,
68        commands::get_context_base_path,
69        commands::get_absolute_path_to,
70        commands::create_directory,
71        commands::remove_directory,
72        commands::remove_file,
73        commands::file_metadata,
74        commands::list_directory,
75        commands::close_context,
76        commands::cleanup
77    ])
78}
79
80/// Initializes the plugin.
81pub fn init() -> TauriPlugin<tauri::Wry> {
82    let builder = builder();
83
84    Builder::new("persistence")
85        .invoke_handler(builder.invoke_handler())
86        .setup(move |app, api| {
87            #[cfg(desktop)]
88            let persistence = desktop::init(app, api)?;
89            app.manage(persistence);
90            app.manage::<state::PluginState>(Mutex::new(HashMap::new()));
91            builder.mount_events(app);
92            Ok(())
93        })
94        .build()
95}
96
97#[cfg(test)]
98mod test {
99    use super::*;
100
101    #[test]
102    fn export_types() {
103        builder()
104            .export(
105                specta_typescript::Typescript::default()
106                    .formatter(specta_typescript::formatter::prettier)
107                    .bigint(specta_typescript::BigIntExportBehavior::Number),
108                "./guest-js/commands.ts",
109            )
110            .expect("failed to export specta types");
111    }
112}