ark_api_ffi/ffi/
storage_v1.rs

1define_api_id!(0x2110_e04a_32df_fab1, "storage-v1");
2
3use crate::FFIResult;
4
5/// Handle to a store
6pub type StoreHandle = u64;
7/// Handle to a async get operation on a store
8pub type AsyncGetHandle = u64;
9
10#[ark_api_macros::ark_bindgen(imports = "ark-storage-v1")]
11mod storage {
12    use super::*;
13
14    /// Storage realm, where a store exists.
15    #[repr(u32)]
16    #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
17    pub enum StoreRealm {
18        /// Store is not persisted and only available while open in the current module instance.
19        ///
20        /// This is mostly useful for testing purposes, or possibly to be able to "swap" out and
21        /// use more than 2 GB of memory in a Wasm module.
22        ModuleInstance = 1,
23
24        /// Store is persisted only on the local device, store names are device-wide for any module
25        /// to access.
26        ///
27        /// This is useful, for instance, for testing purposes before creating a global cache, as
28        /// well as for keeping some local caches in modules.
29        DeviceShared = 2,
30
31        /// Store is persisted only on the local device, store names are device-wide for any module
32        /// to access.
33        ///
34        /// This is useful, for instance, for testing purposes before creating a global cache, as
35        /// well as for keeping some local caches in modules.
36        DeviceUser = 4,
37
38        /// Store is persisted on the local device and asynchronously and automatically
39        /// synchronized globally for other users.
40        GlobalShared = 3,
41
42        /// Store is specific to a single user, is persisted on the local device as well
43        /// as asynchronously automatically synchronized globally.
44        ///
45        /// This means that each user will get their own version of a store with the same name
46        GlobalUser = 5,
47    }
48
49    /// Is this store sync or async?
50    #[repr(u32)]
51    #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
52    pub enum StoreMode {
53        /// All the store methods are sync. Upon creation, there's an initial refresh of all the
54        /// keys *and* values, spawned in the background. The first method call will block on this
55        /// initial refresh being done.
56        ///
57        /// As a matter of fact, this will fetch all the values, which can be quite slow for large
58        /// stores. It is recommended to only use this for small stores, and to request open them
59        /// as soon as possible in the applet's life cycle, e.g. in the `ark_initialize`
60        /// entrypoint.
61        ///
62        /// Individual values are expected to be obtained through `immediate_get`.
63        /// Using `async_get` on such a store will work fine, but add unnecessary overhead in terms
64        /// of performance and it will be more tedious.
65        Sync,
66
67        /// The store provides an `async get` method, and all other methods are sync. Upon
68        /// creation, there's an initial refresh of all the keys only, spawned in the background.
69        /// The first method call will block on this initial refresh being done.
70        ///
71        /// Individual values are expected to be obtained through `async_get`. Using
72        /// `immediate_get` on such a store will block the main thread until the value is done
73        /// downloading.
74        Async,
75    }
76
77    extern "C" {
78        /// Open a store and make it available for the module
79        ///
80        /// This can be a very expensive operation for [`StoreRealm::Global]` as it will synchronize and download latest data.
81        /// Prefer to call this early in module initialization
82        #[deprecated_infallible]
83        pub fn store_open(realm: StoreRealm, name: &str) -> StoreHandle;
84
85        /// Open a store and make it available for the module
86        ///
87        /// This can be a very expensive operation for [`StoreRealm::Global]` as it will synchronize and download latest data.
88        /// Prefer to call this early in module initialization
89        ///
90        /// Note: This does not support [`StoreRealm::DeviceUser`] or [`StoreRealm::GlobalUser`], use `store_open3` for that
91        pub fn store_open2(realm: StoreRealm, mode: StoreMode, name: &str) -> StoreHandle;
92
93        /// Open a store and make it available for the module
94        ///
95        /// This can be a very expensive operation for [`StoreRealm::Global]` as it will synchronize and download latest data.
96        /// Prefer to call this early in module initialization
97        pub fn store_open3(
98            realm: StoreRealm,
99            realm_user_id: &[u8],
100            mode: StoreMode,
101            name: &str,
102        ) -> StoreHandle;
103
104        /// Close a store
105        #[deprecated_infallible]
106        pub fn store_close(handle: StoreHandle);
107
108        /// Set a key value in a store
109        ///
110        /// This is a fast call that updates the store in-memory or on-disk
111        #[deprecated_infallible]
112        pub fn immediate_insert(store: StoreHandle, key: &[u8], value: &[u8]);
113
114        /// Remove key value in a store
115        ///
116        /// This is a fast call that updates the store in-memory or on-disk
117        #[deprecated_infallible]
118        pub fn immediate_remove(store: StoreHandle, key: &[u8]);
119
120        /// Get the value of a key, for a store opened in `StoreMode::Sync` mode.
121        ///
122        /// This is a fast call, as a sync store synchronizes all the data in real-time in the
123        /// background.
124        ///
125        /// Using this method with a store opened in `StoreMode::Async` mode will block the main
126        /// thread, waiting for the value to be downloaded if it is not present in the local cache.
127        /// It is recommended to use `async_get` for such stores.
128        ///
129        /// # Return
130        ///
131        /// If a key is found, will return a vector filled with the entry encoded as plain bytes.
132        /// If a key is not found, will fail with `NotFound`.
133        pub fn immediate_get(store: StoreHandle, key: &[u8]) -> FFIResult<Vec<u8>>;
134
135        /// Get list of all keys in a single byte buffer
136        ///
137        /// This can be a potentially quite large list although only contains the keys, not the values.
138        ///
139        /// # Return
140        ///
141        /// The list of all the keys is returned in a binary blob.
142        /// The data is formatted in a single binary buffer that starts with a `u32` count of keys and then each
143        /// key is following with a `u32` length of the key and then the contents of the key
144        #[deprecated_infallible]
145        pub fn immediate_list(store: StoreHandle) -> Vec<u8>;
146
147        /// Get the value of a key, for a store opened in `StoreMode::Async` mode.
148        ///
149        /// This returns a handle to an asynchronous operation that will first try to retrieve a
150        /// cached version of the value, or fetch it from a remote store if not found.
151        ///
152        /// The final value may be retrieved with `async_get_is_ready`.
153        ///
154        /// Using this method with a store opened in `StoreMode::Sync` mode will work just fine,
155        /// but add unnecessary overhead and is more tedious; prefer using `immediate_get` for such
156        /// stores.
157        pub fn async_get(store: StoreHandle, key: &[u8]) -> AsyncGetHandle;
158
159        /// Attempts to read the value requested by a previous `async_get` call.
160        ///
161        /// # Return
162        ///
163        /// If the async request is done:
164        ///
165        /// - If a key is found, will return a vector filled with the entry encoded as plain bytes.
166        /// - If a key is not found, will fail with `NotFound`.
167        ///
168        /// If the async request is not done yet, will fail with `Unavailable`.
169        pub fn async_get_ready(handle: AsyncGetHandle) -> FFIResult<Vec<u8>>;
170    }
171}
172
173pub use storage::*;