@buoy-gg/storage 5.0.0 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +45 -572
  2. package/lib/commonjs/index.js +13 -0
  3. package/lib/commonjs/storage/components/GameUIStorageBrowser.js +21 -18
  4. package/lib/commonjs/storage/components/SelectionActionBar.js +8 -0
  5. package/lib/commonjs/storage/components/StorageEventCard.js +3 -2
  6. package/lib/commonjs/storage/components/StorageFilterCards.js +1 -2
  7. package/lib/commonjs/storage/components/StorageKeyRow.js +8 -3
  8. package/lib/commonjs/storage/hooks/useMMKVInstances.js +9 -20
  9. package/lib/commonjs/storage/hooks/useMMKVKeys.js +12 -21
  10. package/lib/commonjs/storage/hooks/useSecureStoreKeys.js +104 -0
  11. package/lib/commonjs/storage/hooks/useStorageEvents.js +25 -11
  12. package/lib/commonjs/storage/sync/storageSyncAdapter.js +82 -1
  13. package/lib/commonjs/storage/utils/SecureStoreRegistry.js +149 -0
  14. package/lib/module/index.js +5 -0
  15. package/lib/module/storage/components/GameUIStorageBrowser.js +20 -18
  16. package/lib/module/storage/components/SelectionActionBar.js +8 -0
  17. package/lib/module/storage/components/StorageEventCard.js +4 -3
  18. package/lib/module/storage/components/StorageFilterCards.js +1 -2
  19. package/lib/module/storage/components/StorageKeyRow.js +7 -2
  20. package/lib/module/storage/hooks/useMMKVInstances.js +6 -18
  21. package/lib/module/storage/hooks/useMMKVKeys.js +7 -18
  22. package/lib/module/storage/hooks/useSecureStoreKeys.js +101 -0
  23. package/lib/module/storage/hooks/useStorageEvents.js +25 -11
  24. package/lib/module/storage/sync/storageSyncAdapter.js +83 -1
  25. package/lib/module/storage/utils/SecureStoreRegistry.js +143 -0
  26. package/lib/typescript/index.d.ts +2 -0
  27. package/lib/typescript/index.d.ts.map +1 -1
  28. package/lib/typescript/storage/components/GameUIStorageBrowser.d.ts.map +1 -1
  29. package/lib/typescript/storage/components/SelectionActionBar.d.ts.map +1 -1
  30. package/lib/typescript/storage/components/StorageEventCard.d.ts.map +1 -1
  31. package/lib/typescript/storage/components/StorageFilterCards.d.ts.map +1 -1
  32. package/lib/typescript/storage/components/StorageKeyRow.d.ts +1 -1
  33. package/lib/typescript/storage/components/StorageKeyRow.d.ts.map +1 -1
  34. package/lib/typescript/storage/hooks/useMMKVInstances.d.ts.map +1 -1
  35. package/lib/typescript/storage/hooks/useMMKVKeys.d.ts.map +1 -1
  36. package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts +18 -0
  37. package/lib/typescript/storage/hooks/useSecureStoreKeys.d.ts.map +1 -0
  38. package/lib/typescript/storage/hooks/useStorageEvents.d.ts.map +1 -1
  39. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts +24 -0
  40. package/lib/typescript/storage/sync/storageSyncAdapter.d.ts.map +1 -1
  41. package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts +115 -0
  42. package/lib/typescript/storage/utils/SecureStoreRegistry.d.ts.map +1 -0
  43. package/package.json +6 -6
package/README.md CHANGED
@@ -1,607 +1,80 @@
1
- # @buoy/storage
1
+ # @buoy-gg/storage
2
2
 
3
- [![npm](https://img.shields.io/npm/v/@buoy%2Fstorage)](https://www.npmjs.com/package/@buoy/storage)
3
+ [![npm version](https://img.shields.io/npm/v/@buoy-gg/storage?style=flat-square&labelColor=1c1c1c&color=10B981)](https://www.npmjs.com/package/@buoy-gg/storage) [![npm downloads](https://img.shields.io/npm/dm/@buoy-gg/storage?style=flat-square&labelColor=1c1c1c&color=10B981)](https://www.npmjs.com/package/@buoy-gg/storage)
4
4
 
5
- Storage browser and monitoring tool for React Native development. Supports both AsyncStorage and MMKV.
5
+ **Browse and edit every key-value pair your React Native app persists — AsyncStorage, MMKV, and SecureStore in one explorer with real-time updates.**
6
6
 
7
- ## Features
7
+ Part of [Buoy](https://github.com/Buoy-gg/buoy) — devtools that live inside your React Native app. Install it and it auto-appears in the floating menu from [`@buoy-gg/core`](https://www.npmjs.com/package/@buoy-gg/core).
8
8
 
9
- - **Storage Browser**: Browse all AsyncStorage and MMKV keys and values
10
- - **MMKV Support**: Monitor and debug MMKV instances (including encrypted storage)
11
- - **Multiple Storage Types**: Support for AsyncStorage, MMKV, and multiple MMKV instances
12
- - **Live Event Monitoring**: Track all storage operations in real-time
13
- - **Edit & Delete**: Modify or remove storage items directly
14
- - **Add New Items**: Create new storage entries
15
- - **Required Key Validation**: Define and validate required storage keys
16
- - **Type Checking**: Validate storage value types
17
- - **Value Validation**: Check if values match expected patterns
18
- - **Search & Filter**: Search through keys and filter by status
19
- - **Copy Functionality**: Easily copy keys and values
20
- - **Beautiful UI**: Modern, game-themed interface matching other React Buoy tools
9
+ ![Storage Explorer demo](https://github.com/user-attachments/assets/80ef1c60-d20c-4d8b-97e6-f37b21b315ea)
21
10
 
22
- ## Installation
23
-
24
- This package is part of the React Buoy monorepo and is automatically available to other packages and the example app.
25
-
26
- For external projects:
27
-
28
- ```bash
29
- # Required: Core storage package and AsyncStorage
30
- npm install @buoy/storage @react-native-async-storage/async-storage
31
-
32
- # Optional: MMKV support (recommended for better performance)
33
- npm install react-native-mmkv
34
- ```
35
-
36
- Or with pnpm/yarn:
11
+ ## Install
37
12
 
38
13
  ```bash
39
- # Required
40
- pnpm add @buoy/storage @react-native-async-storage/async-storage
41
-
42
- # Optional: MMKV support
43
- pnpm add react-native-mmkv
44
- ```
45
-
46
- ## Quick Start
47
-
48
- ### Simplest Setup - Just 1 Line!
49
-
50
- **Import the preset and add it to your tools array. Done!**
51
-
52
- ```typescript
53
- import { storageToolPreset } from '@buoy/storage';
54
- import { FloatingDevTools } from '@buoy/core';
55
-
56
- const installedApps = [
57
- storageToolPreset, // That's it! One line.
58
- // ...your other tools
59
- ];
60
-
61
- function App() {
62
- return (
63
- <FloatingDevTools
64
- apps={installedApps}
65
- environment="local"
66
- userRole="admin"
67
- />
68
- );
69
- }
70
- ```
71
-
72
- **Done!** The preset automatically:
73
- - ✅ Browses all AsyncStorage keys
74
- - ✅ Monitors storage operations
75
- - ✅ Provides edit/delete/add functionality
76
- - ✅ No configuration required
77
-
78
- ### Custom Configuration
79
-
80
- If you need to validate specific storage keys:
81
-
82
- ```typescript
83
- import { createStorageTool } from '@buoy/storage';
84
-
85
- const requiredStorageKeys = [
86
- {
87
- key: "@app/session",
88
- expectedType: "string",
89
- description: "User session token",
90
- storageType: "async",
91
- },
92
- {
93
- key: "@app/settings:theme",
94
- expectedValue: "dark",
95
- description: "Preferred theme",
96
- storageType: "async",
97
- },
98
- ];
99
-
100
- const myStorageTool = createStorageTool({
101
- requiredStorageKeys,
102
- colorPreset: "purple",
103
- enableSharedModalDimensions: true,
104
- });
105
-
106
- const installedApps = [
107
- myStorageTool,
108
- // ...other tools
109
- ];
14
+ npm install @buoy-gg/core @buoy-gg/storage
110
15
  ```
111
16
 
112
- ### Alternative: Manual Setup
113
-
114
- If you're not using FloatingDevTools or want more control:
17
+ ## Quick start
115
18
 
116
- ```typescript
117
- import { StorageModalWithTabs } from '@buoy/storage';
19
+ AsyncStorage works out of the box. Render the floating menu once — the Storage Explorer is auto-discovered as soon as this package is installed:
118
20
 
119
- const requiredStorageKeys = [
120
- {
121
- key: "@app/session",
122
- expectedType: "string",
123
- description: "User session token",
124
- storageType: "async",
125
- },
126
- ];
127
-
128
- function App() {
129
- const [showStorage, setShowStorage] = useState(false);
21
+ ```tsx
22
+ import { FloatingDevTools } from "@buoy-gg/core";
130
23
 
24
+ export default function App() {
131
25
  return (
132
26
  <>
133
- <Button onPress={() => setShowStorage(true)}>
134
- Open Storage Browser
135
- </Button>
136
-
137
- <StorageModalWithTabs
138
- visible={showStorage}
139
- onClose={() => setShowStorage(false)}
140
- requiredStorageKeys={requiredStorageKeys}
141
- />
27
+ {/* your app */}
28
+ <FloatingDevTools />
142
29
  </>
143
30
  );
144
31
  }
145
32
  ```
146
33
 
147
- ## MMKV Support
148
-
149
- React Buoy Storage fully supports [react-native-mmkv](https://github.com/mrousavy/react-native-mmkv), a fast, efficient storage solution for React Native.
150
-
151
- ### Why MMKV?
152
-
153
- - **10x faster** than AsyncStorage
154
- - **Synchronous API** - no async/await needed
155
- - **Encryption support** - built-in AES encryption
156
- - **Multi-process support** - share data between extensions
157
- - **Small bundle size** - ~30KB
158
-
159
- ### Setup Requirements
160
-
161
- **⚠️ IMPORTANT:** Manual registration is **required** for MMKV v4. Auto-detection is not possible due to Metro bundler and ES6 module limitations.
162
-
163
- You must call `registerMMKVInstance()` for each MMKV instance you want to monitor in the DevTools.
164
-
165
- ### Basic MMKV Setup
166
-
167
- ```typescript
168
- import { createMMKV } from 'react-native-mmkv';
169
- import { registerMMKVInstance } from '@buoy/storage';
170
-
171
- // 1. Create your MMKV instance
172
- export const storage = createMMKV({
173
- id: 'mmkv.default'
174
- });
175
-
176
- // 2. Register it with DevTools (required!)
177
- registerMMKVInstance('mmkv.default', storage);
178
- ```
179
-
180
- **That's it!** Your MMKV instance is now visible in the Storage DevTools.
181
-
182
- ### Encrypted MMKV Setup
183
-
184
- ```typescript
185
- import { createMMKV } from 'react-native-mmkv';
186
- import { registerMMKVInstance } from '@buoy/storage';
187
-
188
- // Create encrypted instance
189
- export const secureStorage = createMMKV({
190
- id: 'secure-storage',
191
- encryptionKey: 'my-encryption-key'
192
- });
193
-
194
- // Register with encrypted flag
195
- registerMMKVInstance('secure-storage', secureStorage, {
196
- encrypted: true
197
- });
198
- ```
199
-
200
- ### Multiple MMKV Instances
201
-
202
- You can create and monitor multiple MMKV instances for different purposes:
203
-
204
- ```typescript
205
- import { createMMKV } from 'react-native-mmkv';
206
- import { registerMMKVInstance } from '@buoy/storage';
207
-
208
- // User preferences
209
- export const userPrefs = createMMKV({ id: 'user-prefs' });
210
- registerMMKVInstance('user-prefs', userPrefs);
211
-
212
- // API cache
213
- export const apiCache = createMMKV({ id: 'api-cache' });
214
- registerMMKVInstance('api-cache', apiCache);
215
-
216
- // Secure auth storage
217
- export const authStorage = createMMKV({
218
- id: 'auth',
219
- encryptionKey: process.env.ENCRYPTION_KEY
220
- });
221
- registerMMKVInstance('auth', authStorage, { encrypted: true });
222
- ```
223
-
224
- ### MMKV with FloatingDevTools
225
-
226
- Once registered, MMKV instances automatically appear in the Storage Browser:
227
-
228
- ```typescript
229
- import { FloatingDevTools } from '@buoy/core';
230
- import { storageToolPreset } from '@buoy/storage';
231
- import './mmkv-setup'; // Import your MMKV setup file
232
-
233
- function App() {
234
- return (
235
- <FloatingDevTools
236
- apps={[storageToolPreset]}
237
- environment="local"
238
- userRole="admin"
239
- />
240
- );
241
- }
242
- ```
243
-
244
- The Storage Browser will show:
245
- - All your MMKV instances (default, user-prefs, api-cache, auth, etc.)
246
- - All AsyncStorage keys
247
- - Real-time updates when data changes
248
- - Ability to edit, delete, and add keys
249
-
250
- ### MMKV Registration API
251
-
252
- #### `registerMMKVInstance(id, instance, config?)`
253
-
254
- Register an MMKV instance with DevTools for monitoring and debugging.
255
-
256
- **Parameters:**
257
- - `id` (string) - Unique identifier for this instance (should match the `id` used in `createMMKV`)
258
- - `instance` (MMKV) - The MMKV instance returned from `createMMKV()`
259
- - `config` (optional) - Configuration object
260
- - `encrypted` (boolean) - Set to `true` if instance uses encryption
261
-
262
- **Returns:** `void`
263
-
264
- **Example:**
265
- ```typescript
266
- import { createMMKV } from 'react-native-mmkv';
267
- import { registerMMKVInstance } from '@buoy/storage';
268
-
269
- const storage = createMMKV({ id: 'my-storage' });
270
- registerMMKVInstance('my-storage', storage);
271
- ```
272
-
273
- #### `unregisterMMKVInstance(id)`
274
-
275
- Unregister an MMKV instance from DevTools monitoring. Typically not needed unless you're dynamically creating/destroying instances.
276
-
277
- **Parameters:**
278
- - `id` (string) - The instance ID to unregister
279
-
280
- **Returns:** `void`
281
-
282
- **Example:**
283
- ```typescript
284
- import { unregisterMMKVInstance } from '@buoy/storage';
285
-
286
- unregisterMMKVInstance('my-storage');
287
- ```
288
-
289
- ### Why Manual Registration?
290
-
291
- Auto-detection is fundamentally impossible for MMKV v4 due to:
292
-
293
- 1. **ES6 Module Exports are Sealed** - Cannot monkey-patch `createMMKV` function
294
- 2. **Metro Bundler Limitations** - No access to `require.cache` or module interception
295
- 3. **Nitro Modules Architecture** - MMKV instances created in native C++ layer
296
-
297
- Manual registration is a simple one-line call per instance and provides explicit control over what's monitored.
298
-
299
- ### MMKV Best Practices
300
-
301
- **Recommended structure:**
302
-
303
- ```typescript
304
- // utils/storage.ts
305
- import { createMMKV } from 'react-native-mmkv';
306
- import { registerMMKVInstance } from '@buoy/storage';
307
-
308
- export const storage = createMMKV({ id: 'mmkv.default' });
309
- export const secureStorage = createMMKV({
310
- id: 'secure',
311
- encryptionKey: 'your-key'
312
- });
313
-
314
- if (__DEV__) {
315
- registerMMKVInstance('mmkv.default', storage);
316
- registerMMKVInstance('secure', secureStorage, { encrypted: true });
317
- }
318
- ```
319
-
320
- Then import in your app:
321
-
322
- ```typescript
323
- import { storage, secureStorage } from './utils/storage';
324
-
325
- // Use anywhere in your app
326
- storage.set('user.name', 'John Doe');
327
- secureStorage.set('auth.token', 'secret-token');
328
- ```
329
-
330
- ## API Reference
331
-
332
- ### Presets
333
-
334
- #### `storageToolPreset`
335
-
336
- Pre-configured AsyncStorage browser tool ready to use with FloatingDevTools.
337
-
338
- **Example:**
339
- ```typescript
340
- import { storageToolPreset } from '@buoy/storage';
341
-
342
- const installedApps = [storageToolPreset];
343
- ```
344
-
345
- #### `createStorageTool(options?)`
346
-
347
- Create a custom AsyncStorage browser tool configuration.
348
-
349
- **Options:**
350
- ```typescript
351
- {
352
- /** Tool name (default: "STORAGE") */
353
- name?: string;
354
- /** Tool description */
355
- description?: string;
356
- /** Icon color preset (default: "green") */
357
- colorPreset?: "orange" | "cyan" | "purple" | "pink" | "yellow" | "green";
358
- /** Custom tool ID (default: "storage") */
359
- id?: string;
360
- /** Array of required storage keys to validate */
361
- requiredStorageKeys?: RequiredStorageKey[];
362
- /** Enable shared modal dimensions */
363
- enableSharedModalDimensions?: boolean;
364
- }
365
- ```
366
-
367
- **Example:**
368
- ```typescript
369
- import { createStorageTool } from '@buoy/storage';
370
-
371
- const requiredStorageKeys = [
372
- {
373
- key: "@app/session",
374
- expectedType: "string",
375
- description: "User session token",
376
- storageType: "async",
377
- },
378
- ];
379
-
380
- const myStorageTool = createStorageTool({
381
- name: "APP STORAGE",
382
- requiredStorageKeys,
383
- colorPreset: "cyan",
384
- enableSharedModalDimensions: true,
385
- });
386
- ```
387
-
388
- ### Components
389
-
390
- #### `StorageModalWithTabs`
391
-
392
- Main modal component with two tabs: Browser and Events.
393
-
394
- **Props:**
395
- ```typescript
396
- interface StorageModalWithTabsProps {
397
- /** Whether the modal is visible */
398
- visible: boolean;
399
- /** Callback when modal is closed */
400
- onClose: () => void;
401
- /** Optional back button handler */
402
- onBack?: () => void;
403
- /** Whether to use shared modal dimensions */
404
- enableSharedModalDimensions?: boolean;
405
- /** Array of required storage keys to validate */
406
- requiredStorageKeys?: RequiredStorageKey[];
407
- }
408
- ```
409
-
410
- **Example:**
411
- ```typescript
412
- <StorageModalWithTabs
413
- visible={isVisible}
414
- onClose={handleClose}
415
- requiredStorageKeys={requiredKeys}
416
- enableSharedModalDimensions={true}
417
- />
418
- ```
419
-
420
- ### Types
421
-
422
- #### `RequiredStorageKey`
423
-
424
- ```typescript
425
- interface RequiredStorageKey {
426
- /** Storage key to validate */
427
- key: string;
428
- /** Optional description of the key */
429
- description?: string;
430
- /** Expected value type */
431
- expectedType?: "string" | "number" | "boolean" | "object" | "array";
432
- /** Expected value */
433
- expectedValue?: any;
434
- /** Storage type: "async" for AsyncStorage, "mmkv" for MMKV, "secure" for Secure Storage */
435
- storageType: "async" | "mmkv" | "secure";
436
- /** Whether the key is required */
437
- required?: boolean;
438
- }
439
- ```
440
-
441
- #### `AsyncStorageEvent`
442
-
443
- ```typescript
444
- interface AsyncStorageEvent {
445
- /** Unique event ID */
446
- id: string;
447
- /** Event type (set, get, remove, clear, etc.) */
448
- type: "set" | "get" | "remove" | "clear" | "multiGet" | "multiSet" | "multiRemove";
449
- /** Storage key(s) involved */
450
- key?: string | string[];
451
- /** Value (for set operations) */
452
- value?: any;
453
- /** Timestamp of the event */
454
- timestamp: number;
455
- /** Whether the operation succeeded */
456
- success: boolean;
457
- /** Error message if operation failed */
458
- error?: string;
459
- }
460
- ```
461
-
462
- ## Use Cases
463
-
464
- ### Session Management
465
-
466
- Monitor and validate user session storage:
467
-
468
- ```typescript
469
- import { createStorageTool } from '@buoy/storage';
470
-
471
- const requiredStorageKeys = [
472
- {
473
- key: "@app/session:token",
474
- expectedType: "string",
475
- description: "JWT auth token",
476
- storageType: "async",
477
- required: true,
478
- },
479
- {
480
- key: "@app/session:userId",
481
- expectedType: "string",
482
- description: "Current user ID",
483
- storageType: "async",
484
- required: true,
485
- },
486
- ];
487
-
488
- const storageTool = createStorageTool({ requiredStorageKeys });
489
- ```
490
-
491
- ### App Settings
34
+ **MMKV** — register each instance once so the explorer can see it (required for MMKV v4; Metro can't auto-detect instances):
492
35
 
493
- Validate app configuration storage:
36
+ ```ts
37
+ import { createMMKV } from "react-native-mmkv";
38
+ import { registerMMKVInstance } from "@buoy-gg/storage";
494
39
 
495
- ```typescript
496
- const requiredStorageKeys = [
497
- {
498
- key: "@app/settings:theme",
499
- expectedValue: "dark",
500
- description: "UI theme preference",
501
- storageType: "async",
502
- },
503
- {
504
- key: "@app/settings:notifications",
505
- expectedType: "boolean",
506
- description: "Notifications enabled",
507
- storageType: "async",
508
- },
509
- {
510
- key: "@app/settings:language",
511
- expectedType: "string",
512
- description: "User language preference",
513
- storageType: "async",
514
- },
515
- ];
40
+ export const storage = createMMKV({ id: "mmkv.default" });
41
+ registerMMKVInstance("mmkv.default", storage);
516
42
  ```
517
43
 
518
- ### Cache Management
44
+ **SecureStore** — the iOS Keychain / Android KeyStore has no key-listing API, so register the keys you want visible:
519
45
 
520
- Monitor cached data:
46
+ ```ts
47
+ import * as SecureStore from "expo-secure-store";
48
+ import { registerSecureStoreKeys } from "@buoy-gg/storage";
521
49
 
522
- ```typescript
523
- const requiredStorageKeys = [
524
- {
525
- key: "@app/cache:userData",
526
- expectedType: "object",
527
- description: "Cached user profile data",
528
- storageType: "async",
529
- },
530
- {
531
- key: "@app/cache:timestamp",
532
- expectedType: "number",
533
- description: "Cache timestamp",
534
- storageType: "async",
535
- },
536
- ];
50
+ registerSecureStoreKeys(SecureStore, [
51
+ "auth.accessToken",
52
+ { key: "session", keychainService: "com.myapp.auth" },
53
+ // Biometric-protected keys are listed but never auto-read (no surprise Face ID prompts)
54
+ { key: "pin", requireAuthentication: true },
55
+ ]);
537
56
  ```
538
57
 
539
- ## Features in Detail
58
+ ## What you get
540
59
 
541
- ### Browser Tab
60
+ - **Three backends, one explorer** — AsyncStorage, MMKV (multiple instances, including encrypted), and Expo SecureStore, with per-instance key counts and an instance switcher.
61
+ - **Edit in place** — modify, delete, and add keys directly; bulk-select to delete or export many at once.
62
+ - **Live events** — watch storage reads and writes stream in as your app runs.
63
+ - **Pin and hide** — pin the keys you're watching to the top (persists across sessions); one tap hides noisy keys non-destructively.
64
+ - **Inline previews** — short values show on the card (`number · 42`, `string · "en"`), booleans get color-coded true/false badges, and valid JSON is auto pretty-printed.
65
+ - **Biometric keys stay safe** — SecureStore keys behind Face ID / fingerprint are listed but never auto-read.
66
+ - **Required-key validation** — declare keys with expected types or values via `createStorageTool({ requiredStorageKeys })` and see what's missing or wrong.
542
67
 
543
- - **View All Keys**: See all AsyncStorage keys and their values
544
- - **Search**: Search through keys by name
545
- - **Filter**: Filter by validation status (all, missing, issues)
546
- - **Edit**: Modify existing values directly
547
- - **Delete**: Remove storage entries
548
- - **Add**: Create new storage entries
549
- - **Copy**: Copy keys and values to clipboard
550
- - **Validation**: See which required keys are missing or invalid
551
-
552
- ### Events Tab
553
-
554
- - **Live Monitoring**: Watch all storage operations in real-time
555
- - **Event Types**: Track set, get, remove, clear, and multi-operations
556
- - **Filtering**: Filter events by type or key
557
- - **Search**: Search through event history
558
- - **Timeline**: See chronological order of operations
559
- - **Pause/Resume**: Control event capture
560
- - **Clear**: Clear event history
561
-
562
- ### Validation
563
-
564
- Required storage keys can be validated for:
565
- - **Existence**: Check if the key exists
566
- - **Type**: Validate the value type (string, number, boolean, object, array)
567
- - **Value**: Check if the value matches an expected value
568
- - **Custom Validation**: Implement custom validation logic
569
-
570
- ## Dependencies
571
-
572
- - `@buoy/shared-ui` - Common UI components and utilities
573
- - `@react-native-async-storage/async-storage` - AsyncStorage implementation (peer dependency; supports v2 and v3 — `^2.0.0 || ^3.1.0`. Avoid 3.0.x, which has an Android build issue fixed upstream in 3.1.0.)
574
- - `react-native-mmkv` - MMKV storage implementation (optional peer dependency)
575
- - React and React Native (peer dependencies)
576
-
577
- ## Development
578
-
579
- ### Building
580
-
581
- ```bash
582
- pnpm build
583
- ```
584
-
585
- ### Type Checking
586
-
587
- ```bash
588
- pnpm typecheck
589
- ```
590
-
591
- ### Clean Build
592
-
593
- ```bash
594
- pnpm clean
595
- ```
68
+ ## Desktop & AI
596
69
 
597
- ## License
70
+ The same live session streams to [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop) (free, macOS/Windows/Linux) and to Claude Code or Cursor via the [Buoy MCP server](https://buoy.gg/buoy/latest/docs/mcp).
598
71
 
599
- MIT
72
+ ## Free vs Pro
600
73
 
601
- ## Contributing
74
+ Every tool is free. [Pro](https://buoy.gg/pricing) unlocks production builds, the MCP server, and unlimited capture. Every weekend, Pro features unlock free for everyone.
602
75
 
603
- See the main repository [CONTRIBUTING.md](../../CONTRIBUTING.md) for contribution guidelines.
76
+ ---
604
77
 
605
- ## Support
78
+ 📚 [Full docs](https://buoy.gg/buoy/latest/docs/tools/storage) · [All Buoy tools](https://github.com/Buoy-gg/buoy)
606
79
 
607
- For issues and feature requests, please visit the [GitHub repository](https://github.com/LovesWorking/react-native-buoy/issues).
80
+ Proprietary software. © Buoy LLC. [Terms](https://buoy.gg/terms)
@@ -147,6 +147,12 @@ Object.defineProperty(exports, "registerMMKVInstance", {
147
147
  return _MMKVInstanceRegistry.registerMMKVInstance;
148
148
  }
149
149
  });
150
+ Object.defineProperty(exports, "registerSecureStoreKeys", {
151
+ enumerable: true,
152
+ get: function () {
153
+ return _SecureStoreRegistry.registerSecureStoreKeys;
154
+ }
155
+ });
150
156
  Object.defineProperty(exports, "storageEventStore", {
151
157
  enumerable: true,
152
158
  get: function () {
@@ -177,6 +183,12 @@ Object.defineProperty(exports, "unregisterMMKVInstance", {
177
183
  return _MMKVInstanceRegistry.unregisterMMKVInstance;
178
184
  }
179
185
  });
186
+ Object.defineProperty(exports, "unregisterSecureStoreKey", {
187
+ enumerable: true,
188
+ get: function () {
189
+ return _SecureStoreRegistry.unregisterSecureStoreKey;
190
+ }
191
+ });
180
192
  Object.defineProperty(exports, "useAsyncStorageKeys", {
181
193
  enumerable: true,
182
194
  get: function () {
@@ -240,5 +252,6 @@ var _mmkvAvailability = require("./storage/utils/mmkvAvailability");
240
252
  var _mmkvTypeDetection = require("./storage/utils/mmkvTypeDetection");
241
253
  var _storageTimeTravelUtils = require("./storage/utils/storageTimeTravelUtils");
242
254
  var _MMKVInstanceRegistry = require("./storage/utils/MMKVInstanceRegistry");
255
+ var _SecureStoreRegistry = require("./storage/utils/SecureStoreRegistry");
243
256
  var _storageSyncAdapter = require("./storage/sync/storageSyncAdapter");
244
257
  var _storageEventStore = require("./storage/stores/storageEventStore");