entity_graph_tauri/
types.rs

1//! types.rs
2//!
3//! Serde + specta::Type annotated payload and event shapes for the
4//! entity-graph Tauri plugin. Tauri Specta generates the TypeScript command
5//! surface from these types via the package's `build:bindings` script.
6
7use serde::{Deserialize, Serialize};
8#[cfg(feature = "generate-bindings")]
9use specta::Type;
10#[cfg(feature = "generate-bindings")]
11use specta_typescript::Unknown;
12use std::collections::HashMap;
13
14/// Opaque JSON value used for entity data fields.
15pub type JsonObject = HashMap<String, serde_json::Value>;
16
17/// Returned by the native desktop/Android/iOS smoke command.
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
19#[cfg_attr(feature = "generate-bindings", derive(Type))]
20#[serde(rename_all = "camelCase")]
21pub struct PlatformPing {
22    pub plugin: String,
23    pub platform: String,
24}
25
26// ── Command payloads ──────────────────────────────────────────────────────────
27
28/// Payload for the `graph_upsert_entity` command.
29#[derive(Debug, Clone, Serialize, Deserialize)]
30#[cfg_attr(feature = "generate-bindings", derive(Type))]
31#[serde(rename_all = "camelCase")]
32pub struct UpsertEntityPayload {
33    pub entity_type: String,
34    pub entity_id: String,
35    #[cfg_attr(feature = "generate-bindings", specta(type = HashMap<String, Unknown>))]
36    pub data: JsonObject,
37}
38
39/// Payload for the `graph_remove_entity` command.
40#[derive(Debug, Clone, Serialize, Deserialize)]
41#[cfg_attr(feature = "generate-bindings", derive(Type))]
42#[serde(rename_all = "camelCase")]
43pub struct RemoveEntityPayload {
44    pub entity_type: String,
45    pub entity_id: String,
46}
47
48/// Payload for the `graph_patch_entity` command (UI-only overlay — not stored
49/// in the canonical entity table, but tracked by the plugin for devtools).
50#[derive(Debug, Clone, Serialize, Deserialize)]
51#[cfg_attr(feature = "generate-bindings", derive(Type))]
52#[serde(rename_all = "camelCase")]
53pub struct PatchEntityPayload {
54    pub entity_type: String,
55    pub entity_id: String,
56    #[cfg_attr(feature = "generate-bindings", specta(type = HashMap<String, Unknown>))]
57    pub patch: JsonObject,
58}
59
60/// Payload for the `graph_set_list` command.
61#[derive(Debug, Clone, Serialize, Deserialize)]
62#[cfg_attr(feature = "generate-bindings", derive(Type))]
63#[serde(rename_all = "camelCase")]
64pub struct SetListPayload {
65    pub query_key: String,
66    pub ids: Vec<String>,
67    pub total: Option<i64>,
68    pub next_cursor: Option<String>,
69    pub has_next_page: bool,
70}
71
72/// Payload for `graph_persist_snapshot` — serialised graph state sent from TS.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74#[cfg_attr(feature = "generate-bindings", derive(Type))]
75#[serde(rename_all = "camelCase")]
76pub struct PersistSnapshotPayload {
77    pub storage_key: Option<String>,
78    /// JSON-serialised `GraphSnapshotPayload` produced by the TS layer.
79    pub snapshot: String,
80}
81
82/// Payload for `graph_restore_snapshot` — requests Rust to return stored data.
83#[derive(Debug, Clone, Serialize, Deserialize)]
84#[cfg_attr(feature = "generate-bindings", derive(Type))]
85#[serde(rename_all = "camelCase")]
86pub struct RestoreSnapshotPayload {
87    pub storage_key: Option<String>,
88}
89
90/// Returned by `graph_restore_snapshot` with the raw snapshot string.
91#[derive(Debug, Clone, Serialize, Deserialize)]
92#[cfg_attr(feature = "generate-bindings", derive(Type))]
93#[serde(rename_all = "camelCase")]
94pub struct RestoreSnapshotResult {
95    pub snapshot: Option<String>,
96}
97
98/// Returned by `graph_get_entity`.
99#[derive(Debug, Clone, Serialize, Deserialize)]
100#[cfg_attr(feature = "generate-bindings", derive(Type))]
101#[serde(rename_all = "camelCase")]
102pub struct GetEntityResult {
103    #[cfg_attr(
104        feature = "generate-bindings",
105        specta(type = Option<HashMap<String, Unknown>>)
106    )]
107    pub data: Option<JsonObject>,
108}
109
110/// Returned by `graph_get_list`.
111#[derive(Debug, Clone, Serialize, Deserialize)]
112#[cfg_attr(feature = "generate-bindings", derive(Type))]
113#[serde(rename_all = "camelCase")]
114pub struct GetListResult {
115    pub ids: Vec<String>,
116    pub total: Option<i64>,
117}
118
119// ── Event payloads (Rust → TS) ────────────────────────────────────────────────
120
121/// Emitted when an entity is mutated on
122/// the Rust side (e.g. by an IPC command from another window, or a background
123/// task).
124#[derive(Debug, Clone, Serialize, Deserialize)]
125#[cfg_attr(feature = "generate-bindings", derive(Type, tauri_specta::Event))]
126#[serde(rename_all = "camelCase")]
127#[cfg_attr(
128    feature = "generate-bindings",
129    tauri_specta(event_name = "entity-changed")
130)]
131pub struct EntityChangedEvent {
132    pub entity_type: String,
133    pub entity_id: String,
134    pub operation: EntityOperation,
135    #[cfg_attr(
136        feature = "generate-bindings",
137        specta(type = Option<HashMap<String, Unknown>>)
138    )]
139    pub data: Option<JsonObject>,
140}
141
142/// The three mutation kinds that can arrive over the event channel.
143#[derive(Debug, Clone, Serialize, Deserialize)]
144#[cfg_attr(feature = "generate-bindings", derive(Type))]
145#[serde(rename_all = "lowercase")]
146pub enum EntityOperation {
147    Upsert,
148    Remove,
149    Patch,
150}
151
152/// Emitted after a successful `graph_persist_snapshot`.
153#[derive(Debug, Clone, Serialize, Deserialize)]
154#[cfg_attr(feature = "generate-bindings", derive(Type, tauri_specta::Event))]
155#[serde(rename_all = "camelCase")]
156#[cfg_attr(
157    feature = "generate-bindings",
158    tauri_specta(event_name = "snapshot-persisted")
159)]
160pub struct SnapshotPersistedEvent {
161    pub storage_key: String,
162    /// ISO-8601 timestamp.
163    pub persisted_at: String,
164    pub byte_size: usize,
165}
166
167/// Emitted after a successful `graph_restore_snapshot`.
168#[derive(Debug, Clone, Serialize, Deserialize)]
169#[cfg_attr(feature = "generate-bindings", derive(Type, tauri_specta::Event))]
170#[serde(rename_all = "camelCase")]
171#[cfg_attr(
172    feature = "generate-bindings",
173    tauri_specta(event_name = "snapshot-restored")
174)]
175pub struct SnapshotRestoredEvent {
176    pub storage_key: String,
177    /// ISO-8601 timestamp.
178    pub restored_at: String,
179}
180
181/// Emitted on plugin-level errors.
182#[derive(Debug, Clone, Serialize, Deserialize)]
183#[cfg_attr(feature = "generate-bindings", derive(Type, tauri_specta::Event))]
184#[serde(rename_all = "camelCase")]
185#[cfg_attr(feature = "generate-bindings", tauri_specta(event_name = "error"))]
186pub struct GraphPluginErrorEvent {
187    pub code: String,
188    pub message: String,
189    #[cfg_attr(
190        feature = "generate-bindings",
191        specta(type = Option<HashMap<String, Unknown>>)
192    )]
193    pub context: Option<JsonObject>,
194}