Data Persistence
Relevant source files
The following files were used as context for generating this wiki page:Data persistence in Scripty is handled by saving the application's state to a local JSON file. This ensures that user-created scripts and tags are not lost between sessions. The mechanism leverages the zustand state management library on the frontend, combined with its persist middleware, which is configured to use a custom storage interface. This interface utilizes the @tauri-apps/plugin-fs Tauri plugin to read from and write to the user's local application data directory.
The core of this system is the useListStore hook, which defines the application's state, the actions to modify it, and the persistence configuration. Only specific parts of the state, namely items (the scripts) and tags, are selected for persistence to keep the storage lean and focused on user-generated data.
Architecture Overview
The persistence architecture is a collaboration between the React frontend and the Tauri backend. The frontend manages the state in-memory using Zustand, while the Tauri runtime provides the necessary file system access through a dedicated plugin. When the state changes, the Zustand persist middleware triggers a custom storage handler that calls Tauri's file system API to write the updated state to a JSON file.
The following diagram illustrates the high-level flow of data from a UI interaction to the physical file on disk.
This diagram shows the architectural layers involved in persisting application state.
Sources: src/Hooks/useListStore.js:2-4, src-tauri/src/lib.rs:55-57
Frontend State Management (Zustand)
The application's state is managed by a Zustand store defined in useListStore.js. This store is wrapped with persist middleware to automatically handle saving and rehydrating the state.
Sources: src/Hooks/useListStore.js
Store Definition
The useListStore is created using Zustand's create function. It defines the initial state, which includes items, tags, selectedItem, and filterTag, along with actions to manipulate this state like addItem, addTag, and removeItem.
Sources: src/Hooks/useListStore.js:28-76
Persistence Middleware
The persist middleware is configured with a name and a custom storage implementation.
name: The key used for storage, set to"scriptStorage".partialize: A function that selects which parts of the state to persist. In this case, onlyitemsandtagsare saved, while transient state likeselectedItemis excluded.storage: A custom storage engine that uses Tauri's FS plugin.
Sources: src/Hooks/useListStore.js:77-85
The following table details the state properties that are persisted.
| State Property | Description |
|---|---|
items | An array of script objects created by the user. |
tags | An array of strings representing all available tags. |
Sources: src/Hooks/useListStore.js:79-82
Filesystem Interaction (Tauri FS Plugin)
Direct interaction with the filesystem is abstracted away into a fileStorage object that conforms to the StateStorage interface required by Zustand's persist middleware. This object uses functions from the @tauri-apps/plugin-fs package.
Sources: src/Hooks/useListStore.js:10-25
Storage Location
The data is stored in a single JSON file named scriptStorage.json. The exact location is determined at runtime by calling appDataDir() from @tauri-apps/api/path, which resolves to the standard application data directory for the current operating system.
Sources: src/Hooks/useListStore.js:6-9
Custom Storage Implementation
The fileStorage object implements three key methods for interacting with the filesystem.
| Method | Description | Tauri Functions Used |
|---|---|---|
getItem | Asynchronously reads the content of scriptStorage.json. Returns null if the file does not exist. | exists, readTextFile |
setItem | Asynchronously writes the provided value (a serialized JSON string of the state) to scriptStorage.json. | writeTextFile |
removeItem | Asynchronously clears the content of scriptStorage.json by writing an empty string to it. | writeTextFile |
Sources: src/Hooks/useListStore.js:10-25
Data Persistence Flow
The sequence diagram below shows the process of adding a new script and persisting the change to the filesystem.
This diagram illustrates the sequence of events when a new item is added, leading to a file write operation.
Sources: src/components/Form/Form.jsx:43-51, src/Hooks/useListStore.js:16-19, 37-40
Configuration and Permissions
For the application to be able to write to the filesystem, the tauri-plugin-fs must be included as a dependency and properly configured with the necessary permissions.
Plugin Initialization
The FS plugin is initialized in the Rust backend during the application startup.
// src-tauri/src/lib.rs:55-57
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_opener::init())
Sources: src-tauri/src/lib.rs:55-57
The plugin is also listed as a dependency in both src-tauri/Cargo.toml and package.json.
Sources: src-tauri/Cargo.toml:26, package.json:20
Filesystem Permissions
The application's capabilities, defined in src-tauri/capabilities/default.json, grant specific permissions for filesystem access. The persistence mechanism relies on the ability to write to the application data directory.
The following permissions are key for data persistence:
| Permission | Description |
|---|---|
fs:default | A general permission set for the FS plugin. |
fs:allow-appdata-write | Allows writing files to the application's data directory. |
fs:allow-write-text-file | Explicitly allows the writeTextFile API call used by the storage engine. |
Sources: src-tauri/capabilities/default.json:17, 25, 59
Data Model
The data persisted to scriptStorage.json consists of two top-level keys: items and tags.
Item Object Structure
Each object in the items array represents a script and has the following structure, as created in the Form.jsx component.
| Field | Type | Description |
|---|---|---|
id | string | A unique identifier generated by crypto.randomUUID(). |
title | string | The name of the script. |
content | string | The actual content of the PowerShell script. |
tags | array | An array of strings associated with the script. |
date | string | The date the script was added. |
Sources: src/components/Form/Form.jsx:43-51
Data Relationship
The diagram below shows the entity relationship within the persisted JSON data.
This ER diagram shows that a SCRIPT_ITEM can have zero or more TAGs associated with it.
Sources: src/Hooks/useListStore.js:30, 32