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::*;