@rozenite/storage-plugin 1.13.0 → 2.0.0

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 (79) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +6 -1
  3. package/dist/devtools/assets/panel-B6Wp0eie.css +1 -0
  4. package/dist/devtools/assets/panel-D7MFc4HG.js +32 -0
  5. package/dist/devtools/panel.html +2 -2
  6. package/dist/react-native/chunks/async-storage.require.cjs +1 -1
  7. package/dist/react-native/chunks/async-storage.require.js +8 -7
  8. package/dist/react-native/chunks/index.require.cjs +1 -1
  9. package/dist/react-native/chunks/index.require.js +70 -64
  10. package/dist/react-native/chunks/secure-storage.require.cjs +1 -1
  11. package/dist/react-native/chunks/secure-storage.require.js +22 -14
  12. package/dist/react-native/chunks/useRozeniteStoragePlugin.require.cjs +1 -1
  13. package/dist/react-native/chunks/useRozeniteStoragePlugin.require.js +863 -315
  14. package/dist/react-native/index.d.ts +154 -18
  15. package/dist/react-native/index.js +10 -2
  16. package/dist/rozenite.json +1 -1
  17. package/dist/sdk/index.cjs +1 -1
  18. package/dist/sdk/index.d.ts +13 -5
  19. package/dist/sdk/index.js +21 -12
  20. package/package.json +13 -15
  21. package/react-native.ts +29 -14
  22. package/rozenite.config.ts +78 -0
  23. package/src/react-native/__tests__/entry-preview-pagination.test.ts +262 -0
  24. package/src/react-native/__tests__/export-snapshot.test.ts +142 -0
  25. package/src/react-native/__tests__/full-entry-request.test.ts +155 -0
  26. package/src/react-native/__tests__/import.test.ts +172 -10
  27. package/src/react-native/__tests__/storage-discovery.test.ts +155 -0
  28. package/src/react-native/__tests__/storage-view.test.ts +172 -0
  29. package/src/react-native/__tests__/stress-verification.test.ts +153 -0
  30. package/src/react-native/__tests__/use-storage-agent-tools.test.ts +231 -0
  31. package/src/react-native/adapters/async-storage.ts +9 -7
  32. package/src/react-native/adapters/mmkv.ts +5 -0
  33. package/src/react-native/adapters/secure-storage.ts +9 -1
  34. package/src/react-native/entry-preview-pagination.ts +277 -0
  35. package/src/react-native/export-snapshot.ts +94 -0
  36. package/src/react-native/full-entry-request.ts +96 -0
  37. package/src/react-native/import.ts +190 -16
  38. package/src/react-native/storage-discovery.ts +96 -0
  39. package/src/react-native/storage-view.ts +45 -103
  40. package/src/react-native/useRozeniteStoragePlugin.ts +108 -72
  41. package/src/react-native/useStorageAgentTools.ts +207 -86
  42. package/src/shared/__tests__/entry-preview.test.ts +117 -0
  43. package/src/shared/__tests__/snapshot.test.ts +21 -0
  44. package/src/shared/agent-tools.ts +27 -11
  45. package/src/shared/entry-preview.ts +59 -0
  46. package/src/shared/messaging.ts +136 -21
  47. package/src/shared/snapshot.ts +8 -1
  48. package/src/shared/types.ts +20 -1
  49. package/src/ui/__tests__/binary-value-editor-state.test.ts +13 -0
  50. package/src/ui/__tests__/binary.test.ts +18 -0
  51. package/src/ui/__tests__/large-value-viewer-state.test.ts +21 -0
  52. package/src/ui/__tests__/large-value-viewer.test.tsx +63 -0
  53. package/src/ui/__tests__/panel.test.tsx +409 -0
  54. package/src/ui/__tests__/storage-groups.test.ts +91 -0
  55. package/src/ui/__tests__/use-storage-entries.test.tsx +353 -0
  56. package/src/ui/add-entry-dialog.tsx +65 -105
  57. package/src/ui/binary-value-editor-state.ts +10 -1
  58. package/src/ui/binary-value-editor.tsx +57 -33
  59. package/src/ui/binary.ts +56 -4
  60. package/src/ui/edit-entry-dialog.tsx +71 -99
  61. package/src/ui/editor-switcher.tsx +7 -5
  62. package/src/ui/entry-detail-dialog.tsx +69 -179
  63. package/src/ui/format-value.tsx +32 -0
  64. package/src/ui/globals.css +1 -123
  65. package/src/ui/import-dialog.tsx +66 -91
  66. package/src/ui/large-value-viewer-state.ts +32 -0
  67. package/src/ui/large-value-viewer.tsx +71 -0
  68. package/src/ui/panel.tsx +724 -496
  69. package/src/ui/query-client.tsx +34 -0
  70. package/src/ui/storage-groups.ts +66 -0
  71. package/src/ui/typed-value-editor.tsx +14 -15
  72. package/src/ui/use-storage-entries.ts +207 -0
  73. package/tsconfig.json +5 -1
  74. package/dist/devtools/assets/panel-Bm-SWF7d.js +0 -33
  75. package/dist/devtools/assets/panel-DIqI4WSp.css +0 -1
  76. package/postcss.config.js +0 -6
  77. package/src/ui/confirm-dialog.tsx +0 -100
  78. package/src/ui/editable-table.tsx +0 -300
  79. package/tailwind.config.ts +0 -94
@@ -1,6 +1,6 @@
1
1
  import { MMKV as MMKV_2 } from 'react-native-mmkv-v3';
2
2
  import { MMKV as MMKV_3 } from 'react-native-mmkv-v4';
3
- import { RozeniteDevToolsClient } from '@rozenite/plugin-bridge';
3
+ import { RozeniteDevToolsRequestClient } from '@rozenite/plugin-bridge';
4
4
 
5
5
  export declare type AsyncStorage = {
6
6
  kind: 'async';
@@ -8,6 +8,7 @@ export declare type AsyncStorage = {
8
8
  get: (key: string) => Promise<StorageEntry | undefined>;
9
9
  set: (entry: StorageEntry) => Promise<void>;
10
10
  delete: (key: string) => Promise<void>;
11
+ clear: () => Promise<void>;
11
12
  subscribe?: (callback: (key: string) => void) => StorageSubscription;
12
13
  };
13
14
 
@@ -22,6 +23,7 @@ export declare type AsyncStorageLike = {
22
23
  getItem: (key: string) => Promise<string | null>;
23
24
  setItem: (key: string, value: string) => Promise<void>;
24
25
  removeItem: (key: string) => Promise<void>;
26
+ clear: () => Promise<void>;
25
27
  };
26
28
 
27
29
  export declare let createAsyncStorageAdapter: typeof createAsyncStorageAdapter_2;
@@ -64,6 +66,21 @@ export declare type CreateMMKVStorageAdapterOptions = {
64
66
  blacklist?: MMKVBlacklistConfig;
65
67
  };
66
68
 
69
+ declare type ImportPreview = {
70
+ newKeys: string[];
71
+ overwriteKeys: string[];
72
+ skippedKeys: {
73
+ key: string;
74
+ reason: 'blacklist';
75
+ }[];
76
+ unsupportedTypes: {
77
+ key: string;
78
+ type: StorageEntryType;
79
+ }[];
80
+ acceptedEntryIndexes: number[];
81
+ metadataMismatch: boolean;
82
+ };
83
+
67
84
  declare type KeySource = string[] | (() => Promise<string[]>);
68
85
 
69
86
  declare type MMKV = MMKV_2 | MMKV_3;
@@ -86,11 +103,6 @@ export declare type SecureStorageLike = {
86
103
  deleteItemAsync: (key: string) => Promise<void>;
87
104
  };
88
105
 
89
- declare type SerializedBlacklist = {
90
- source: string;
91
- flags: string;
92
- };
93
-
94
106
  declare type SingleStorageOptions = {
95
107
  storage: AsyncStorageLike;
96
108
  adapterId?: string;
@@ -116,6 +128,26 @@ declare type StorageDeleteEntryEvent = {
116
128
  key: string;
117
129
  };
118
130
 
131
+ declare type StorageDescriptor = {
132
+ target: StorageTarget;
133
+ adapterName: string;
134
+ storageName: string;
135
+ entryCount: number;
136
+ capabilities: StorageCapabilities;
137
+ supportsSubscriptions: boolean;
138
+ };
139
+
140
+ declare type StorageDiscoverStoragesRequestEvent = {
141
+ type: 'discover-storages';
142
+ requestId: string;
143
+ };
144
+
145
+ declare type StorageDiscoverStoragesResponseEvent = {
146
+ type: 'storage-descriptors';
147
+ requestId: string;
148
+ storages: StorageDescriptor[];
149
+ };
150
+
119
151
  export declare type StorageEntry = {
120
152
  key: string;
121
153
  type: 'string';
@@ -134,11 +166,19 @@ export declare type StorageEntry = {
134
166
  value: number[];
135
167
  };
136
168
 
169
+ declare type StorageEntryPreview = {
170
+ key: string;
171
+ type: StorageEntryType;
172
+ preview: string;
173
+ valueSize: number;
174
+ isTruncated: boolean;
175
+ };
176
+
137
177
  export declare type StorageEntryType = StorageEntry['type'];
138
178
 
139
179
  export declare type StorageEntryValue = StorageEntry['value'];
140
180
 
141
- declare type StorageEvent_2 = StorageSnapshotEvent | StorageSetEntryEvent | StorageDeleteEntryEvent | StorageGetSnapshotEvent | StorageImportEntriesEvent | StorageImportResultEvent;
181
+ declare type StorageEvent_2 = StorageSetEntryEvent | StorageDeleteEntryEvent | StoragePurgeEvent | StorageInvalidatedEvent | StorageDiscoverStoragesRequestEvent | StorageDiscoverStoragesResponseEvent | StorageListEntryPreviewsRequestEvent | StorageListEntryPreviewsResponseEvent | StorageGetEntryRequestEvent | StorageGetEntryResponseEvent | StorageExportSnapshotRequestEvent | StorageExportSnapshotResponseEvent | StorageImportPreviewRequestEvent | StorageImportPreviewResponseEvent | StorageRequestErrorEvent | StorageImportEntriesEvent | StorageImportProgressEvent | StorageImportResultEvent;
142
182
 
143
183
  declare type StorageEventMap = {
144
184
  [K in StorageEvent_2['type']]: Extract<StorageEvent_2, {
@@ -146,19 +186,65 @@ declare type StorageEventMap = {
146
186
  }>;
147
187
  };
148
188
 
149
- declare type StorageGetSnapshotEvent = {
150
- type: 'get-snapshot';
151
- target: StorageTarget | 'all';
189
+ declare type StorageExportSnapshotRequestEvent = {
190
+ type: 'export-snapshot';
191
+ requestId: string;
192
+ target: StorageTarget;
193
+ };
194
+
195
+ declare type StorageExportSnapshotResponseEvent = {
196
+ type: 'export-snapshot-result';
197
+ requestId: string;
198
+ target: StorageTarget;
199
+ snapshot: StorageSnapshotV1;
200
+ };
201
+
202
+ declare type StorageGetEntryRequestEvent = {
203
+ type: 'get-entry';
204
+ requestId: string;
205
+ target: StorageTarget;
206
+ key: string;
207
+ };
208
+
209
+ declare type StorageGetEntryResponseEvent = {
210
+ type: 'entry';
211
+ requestId: string;
212
+ target: StorageTarget;
213
+ entry: StorageEntry;
152
214
  };
153
215
 
154
216
  declare type StorageImportEntriesEvent = {
155
217
  type: 'import-entries';
218
+ requestId: string;
156
219
  target: StorageTarget;
157
220
  entries: StorageEntry[];
158
221
  };
159
222
 
223
+ declare type StorageImportPreviewRequestEvent = {
224
+ type: 'preview-import';
225
+ requestId: string;
226
+ target: StorageTarget;
227
+ snapshot: StorageSnapshotV1;
228
+ };
229
+
230
+ declare type StorageImportPreviewResponseEvent = {
231
+ type: 'import-preview';
232
+ requestId: string;
233
+ target: StorageTarget;
234
+ preview: ImportPreview;
235
+ };
236
+
237
+ declare type StorageImportProgressEvent = {
238
+ type: 'import-progress';
239
+ requestId: string;
240
+ target: StorageTarget;
241
+ written: number;
242
+ total: number;
243
+ };
244
+
160
245
  declare type StorageImportResultEvent = {
161
246
  type: 'import-result';
247
+ requestId: string;
162
248
  target: StorageTarget;
163
249
  ok: boolean;
164
250
  written: number;
@@ -167,6 +253,35 @@ declare type StorageImportResultEvent = {
167
253
  error?: string;
168
254
  };
169
255
 
256
+ declare type StorageInvalidatedEvent = {
257
+ type: 'storage-invalidated';
258
+ target: StorageTarget;
259
+ /** Native subscriptions only expose a key, not the operation. */
260
+ key?: string;
261
+ operation?: StorageInvalidationOperation;
262
+ };
263
+
264
+ declare type StorageInvalidationOperation = 'set' | 'delete' | 'import' | 'purge';
265
+
266
+ declare type StorageListEntryPreviewsRequestEvent = {
267
+ type: 'list-entry-previews';
268
+ requestId: string;
269
+ target: StorageTarget;
270
+ search?: string;
271
+ keySortDirection?: 'ascending' | 'descending';
272
+ cursor?: string;
273
+ limit: number;
274
+ };
275
+
276
+ declare type StorageListEntryPreviewsResponseEvent = {
277
+ type: 'entry-previews';
278
+ requestId: string;
279
+ target: StorageTarget;
280
+ items: StorageEntryPreview[];
281
+ nextCursor?: string;
282
+ previousCursor?: string;
283
+ };
284
+
170
285
  export declare type StorageNode = {
171
286
  id: string;
172
287
  name: string;
@@ -176,19 +291,39 @@ export declare type StorageNode = {
176
291
  shouldFilterKey?: (key: string) => boolean;
177
292
  };
178
293
 
294
+ declare type StoragePurgeEvent = {
295
+ type: 'purge-storage';
296
+ target: StorageTarget;
297
+ };
298
+
299
+ declare type StorageRequestError = {
300
+ requestId: string;
301
+ code: 'TARGET_NOT_FOUND' | 'ENTRY_NOT_FOUND' | 'INVALID_CURSOR' | 'INVALID_REQUEST' | 'READ_FAILED' | 'WRITE_FAILED';
302
+ message: string;
303
+ resetPagination?: boolean;
304
+ };
305
+
306
+ declare type StorageRequestErrorEvent = StorageRequestError & {
307
+ type: 'storage-request-error';
308
+ };
309
+
179
310
  declare type StorageSetEntryEvent = {
180
311
  type: 'set-entry';
181
312
  target: StorageTarget;
182
313
  entry: StorageEntry;
183
314
  };
184
315
 
185
- declare type StorageSnapshotEvent = {
186
- type: 'snapshot';
187
- target: StorageTarget;
188
- adapterName: string;
189
- storageName: string;
190
- capabilities: StorageCapabilities;
191
- blacklist?: SerializedBlacklist;
316
+ declare type StorageSnapshotV1 = {
317
+ version: 1;
318
+ plugin: string;
319
+ createdAt: string;
320
+ storage: {
321
+ adapterId: string;
322
+ storageId: string;
323
+ adapterName: string;
324
+ storageName: string;
325
+ capabilities: StorageCapabilities;
326
+ };
192
327
  entries: StorageEntry[];
193
328
  };
194
329
 
@@ -207,11 +342,12 @@ export declare type SyncStorage = {
207
342
  get: (key: string) => StorageEntry | undefined;
208
343
  set: (entry: StorageEntry) => void;
209
344
  delete: (key: string) => void;
345
+ clear: () => void;
210
346
  subscribe?: (callback: (key: string) => void) => StorageSubscription;
211
347
  };
212
348
 
213
349
  export declare let useRozeniteStoragePlugin: typeof useRozeniteStoragePlugin_2;
214
350
 
215
- declare const useRozeniteStoragePlugin_2: ({ storages, }: RozeniteStoragePluginOptions) => RozeniteDevToolsClient<StorageEventMap> | null;
351
+ declare const useRozeniteStoragePlugin_2: ({ storages, }: RozeniteStoragePluginOptions) => RozeniteDevToolsRequestClient<StorageEventMap> | null;
216
352
 
217
353
  export { }
@@ -13,10 +13,18 @@ if (!i || u)
13
13
  e,
14
14
  "expo-secure-store",
15
15
  "Expo SecureStore"
16
- )), s = ((e) => t(e, "mmkv", "MMKV")), p = () => null;
16
+ )), s = ((e) => t(
17
+ e,
18
+ "mmkv",
19
+ "MMKV"
20
+ )), p = () => null;
17
21
  else if (d) {
18
22
  const e = require("./chunks/async-storage.require.js"), a = require("./chunks/secure-storage.require.js");
19
- r = e.createAsyncStorageAdapter, c = e.createExpoAsyncStorageAdapter, n = a.createExpoSecureStorageAdapter, s = ((o) => t(o, "mmkv", "MMKV")), p = require("./chunks/useRozeniteStoragePlugin.require.js").useRozeniteStoragePlugin;
23
+ r = e.createAsyncStorageAdapter, c = e.createExpoAsyncStorageAdapter, n = a.createExpoSecureStorageAdapter, s = ((o) => t(
24
+ o,
25
+ "mmkv",
26
+ "MMKV"
27
+ )), p = require("./chunks/useRozeniteStoragePlugin.require.js").useRozeniteStoragePlugin;
20
28
  } else
21
29
  r = require("./chunks/index.require.js").createAsyncStorageAdapter, c = require("./chunks/index.require.js").createExpoAsyncStorageAdapter, n = require("./chunks/index.require.js").createExpoSecureStorageAdapter, s = require("./chunks/index.require.js").createMMKVStorageAdapter, p = require("./chunks/useRozeniteStoragePlugin.require.js").useRozeniteStoragePlugin;
22
30
  export {
@@ -1 +1 @@
1
- {"name":"@rozenite/storage-plugin","version":"1.13.0","description":"Generic Storage Inspector for Rozenite.","panels":[{"name":"Storage","source":"/devtools/panel.html"}]}
1
+ {"name":"@rozenite/storage-plugin","version":"2.0.0","description":"Generic Storage Inspector for Rozenite.","panels":[{"name":"Storage","source":"/devtools/panel.html"}]}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@rozenite/agent-shared"),t={adapterId:{type:"string",description:"Storage adapter ID. Required when multiple adapters are configured."},storageId:{type:"string",description:"Storage node ID within the adapter. Required when multiple storages are configured."}},n="@rozenite/storage-plugin",r=["string","number","boolean","buffer"],i={listStorages:e.defineAgentToolContract({name:"list-storages",description:"List all storage adapters and their storage nodes currently available on the device, including supported entry types and entry counts.",inputSchema:{type:"object",properties:{}}}),listEntries:e.defineAgentToolContract({name:"list-entries",description:"List keys in a storage. This call intentionally does not return entry values to keep responses token-efficient.",inputSchema:{type:"object",properties:{...t,offset:{type:"number",description:"Pagination offset. Defaults to 0."},limit:{type:"number",description:"Pagination size. Defaults to 100."}}}}),readEntry:e.defineAgentToolContract({name:"read-entry",description:"Read a single storage entry value by key.",inputSchema:{type:"object",properties:{...t,key:{type:"string",description:"Entry key."}},required:["key"]}}),createEntry:e.defineAgentToolContract({name:"create-entry",description:"Create a new storage entry. Fails if the key already exists.",inputSchema:{type:"object",properties:{...t,key:{type:"string",description:"Entry key."},type:{type:"string",enum:[...r],description:"Entry value type. Must be one of the supported types for the target storage (see list-storages)."},value:{description:"Entry value matching the provided type."}},required:["key","type","value"]}}),editEntry:e.defineAgentToolContract({name:"edit-entry",description:"Edit an existing storage entry. Fails if the key does not exist.",inputSchema:{type:"object",properties:{...t,key:{type:"string",description:"Entry key."},type:{type:"string",enum:[...r],description:"Entry value type. Must be one of the supported types for the target storage (see list-storages)."},value:{description:"Entry value matching the provided type."}},required:["key","type","value"]}}),removeEntry:e.defineAgentToolContract({name:"remove-entry",description:"Remove a storage entry by key.",inputSchema:{type:"object",properties:{...t,key:{type:"string",description:"Entry key."}},required:["key"]}})},o=e.defineAgentToolDescriptors(n,i);exports.STORAGE_AGENT_ENTRY_TYPES=r;exports.STORAGE_AGENT_PLUGIN_ID=n;exports.storageToolDefinitions=i;exports.storageTools=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@rozenite/agent-shared"),t={adapterId:{type:"string",description:"Storage adapter ID. Required when multiple adapters are configured."},storageId:{type:"string",description:"Storage node ID within the adapter. Required when multiple storages are configured."}},n="@rozenite/storage-plugin",r=["string","number","boolean","buffer"],i={listStorages:e.defineAgentToolContract({name:"list-storages",description:"List all storage adapters and their storage nodes currently available on the device, including supported entry types. Entry counts are omitted to avoid enumerating every storage.",inputSchema:{type:"object",properties:{}}}),listEntries:e.definePaginatedAgentToolContract({name:"list-entries",description:"List keys in a storage. This call intentionally does not return entry values to keep responses token-efficient.",inputSchema:{type:"object",properties:{...t,limit:{type:"number",description:"Pagination size. Defaults to 20 and is capped at 100."},cursor:{type:"string",description:"Opaque pagination cursor from a previous list-entries call."},offset:{type:"number",description:"Deprecated initial pagination offset. Must be a non-negative integer and cannot be combined with cursor."}}},pagination:{kind:"cursor",fields:["key"],defaultFields:["key"]}}),readEntry:e.defineAgentToolContract({name:"read-entry",description:"Read a single storage entry value by key.",inputSchema:{type:"object",properties:{...t,key:{type:"string",description:"Entry key."}},required:["key"]}}),createEntry:e.defineAgentToolContract({name:"create-entry",description:"Create a new storage entry. Fails if the key already exists.",inputSchema:{type:"object",properties:{...t,key:{type:"string",description:"Entry key."},type:{type:"string",enum:[...r],description:"Entry value type. Must be one of the supported types for the target storage (see list-storages)."},value:{description:"Entry value matching the provided type."}},required:["key","type","value"]}}),editEntry:e.defineAgentToolContract({name:"edit-entry",description:"Edit an existing storage entry. Fails if the key does not exist.",inputSchema:{type:"object",properties:{...t,key:{type:"string",description:"Entry key."},type:{type:"string",enum:[...r],description:"Entry value type. Must be one of the supported types for the target storage (see list-storages)."},value:{description:"Entry value matching the provided type."}},required:["key","type","value"]}}),removeEntry:e.defineAgentToolContract({name:"remove-entry",description:"Remove a storage entry by key.",inputSchema:{type:"object",properties:{...t,key:{type:"string",description:"Entry key."}},required:["key"]}})},o=e.defineAgentToolDescriptors(n,i);exports.STORAGE_AGENT_ENTRY_TYPES=r;exports.STORAGE_AGENT_PLUGIN_ID=n;exports.storageToolDefinitions=i;exports.storageTools=o;
@@ -7,6 +7,7 @@ declare type AsyncStorage = {
7
7
  get: (key: string) => Promise<StorageEntry | undefined>;
8
8
  set: (entry: StorageEntry) => Promise<void>;
9
9
  delete: (key: string) => Promise<void>;
10
+ clear: () => Promise<void>;
10
11
  subscribe?: (callback: (key: string) => void) => StorageSubscription;
11
12
  };
12
13
 
@@ -65,17 +66,24 @@ export declare type StorageEntryType = StorageEntry['type'];
65
66
  export declare type StorageEntryValue = StorageEntry['value'];
66
67
 
67
68
  export declare type StorageListEntriesArgs = StorageSelection & {
68
- offset?: number;
69
69
  limit?: number;
70
+ cursor?: string;
71
+ /** @deprecated Use the opaque cursor returned by a previous page. */
72
+ offset?: number;
70
73
  };
71
74
 
72
75
  export declare type StorageListEntriesResult = {
73
76
  adapterId: string;
74
77
  storageId: string;
75
78
  total: number;
76
- offset: number;
77
- limit: number;
78
- keys: string[];
79
+ items: Array<{
80
+ key: string;
81
+ }>;
82
+ page: {
83
+ limit: number;
84
+ hasMore: boolean;
85
+ nextCursor?: string;
86
+ };
79
87
  };
80
88
 
81
89
  export declare type StorageListStoragesArgs = undefined;
@@ -85,7 +93,6 @@ export declare type StorageListStoragesItem = {
85
93
  storageId: string;
86
94
  adapterName: string;
87
95
  storageName: string;
88
- entryCount: number;
89
96
  supportedTypes: StorageEntryType[];
90
97
  };
91
98
 
@@ -192,6 +199,7 @@ declare type SyncStorage = {
192
199
  get: (key: string) => StorageEntry | undefined;
193
200
  set: (entry: StorageEntry) => void;
194
201
  delete: (key: string) => void;
202
+ clear: () => void;
195
203
  subscribe?: (callback: (key: string) => void) => StorageSubscription;
196
204
  };
197
205
 
package/dist/sdk/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { defineAgentToolContract as e, defineAgentToolDescriptors as i } from "@rozenite/agent-shared";
1
+ import { defineAgentToolContract as e, definePaginatedAgentToolContract as i, defineAgentToolDescriptors as n } from "@rozenite/agent-shared";
2
2
  const t = {
3
3
  adapterId: {
4
4
  type: "string",
@@ -8,7 +8,7 @@ const t = {
8
8
  type: "string",
9
9
  description: "Storage node ID within the adapter. Required when multiple storages are configured."
10
10
  }
11
- }, n = "@rozenite/storage-plugin", r = [
11
+ }, o = "@rozenite/storage-plugin", r = [
12
12
  "string",
13
13
  "number",
14
14
  "boolean",
@@ -16,25 +16,34 @@ const t = {
16
16
  ], s = {
17
17
  listStorages: e({
18
18
  name: "list-storages",
19
- description: "List all storage adapters and their storage nodes currently available on the device, including supported entry types and entry counts.",
19
+ description: "List all storage adapters and their storage nodes currently available on the device, including supported entry types. Entry counts are omitted to avoid enumerating every storage.",
20
20
  inputSchema: { type: "object", properties: {} }
21
21
  }),
22
- listEntries: e({
22
+ listEntries: i({
23
23
  name: "list-entries",
24
24
  description: "List keys in a storage. This call intentionally does not return entry values to keep responses token-efficient.",
25
25
  inputSchema: {
26
26
  type: "object",
27
27
  properties: {
28
28
  ...t,
29
- offset: {
29
+ limit: {
30
30
  type: "number",
31
- description: "Pagination offset. Defaults to 0."
31
+ description: "Pagination size. Defaults to 20 and is capped at 100."
32
32
  },
33
- limit: {
33
+ cursor: {
34
+ type: "string",
35
+ description: "Opaque pagination cursor from a previous list-entries call."
36
+ },
37
+ offset: {
34
38
  type: "number",
35
- description: "Pagination size. Defaults to 100."
39
+ description: "Deprecated initial pagination offset. Must be a non-negative integer and cannot be combined with cursor."
36
40
  }
37
41
  }
42
+ },
43
+ pagination: {
44
+ kind: "cursor",
45
+ fields: ["key"],
46
+ defaultFields: ["key"]
38
47
  }
39
48
  }),
40
49
  readEntry: e({
@@ -101,13 +110,13 @@ const t = {
101
110
  required: ["key"]
102
111
  }
103
112
  })
104
- }, a = i(
105
- n,
113
+ }, p = n(
114
+ o,
106
115
  s
107
116
  );
108
117
  export {
109
118
  r as STORAGE_AGENT_ENTRY_TYPES,
110
- n as STORAGE_AGENT_PLUGIN_ID,
119
+ o as STORAGE_AGENT_PLUGIN_ID,
111
120
  s as storageToolDefinitions,
112
- a as storageTools
121
+ p as storageTools
113
122
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rozenite/storage-plugin",
3
- "version": "1.13.0",
3
+ "version": "2.0.0",
4
4
  "description": "Generic Storage Inspector for Rozenite.",
5
5
  "type": "module",
6
6
  "main": "./dist/react-native/index.cjs",
@@ -15,34 +15,32 @@
15
15
  "url": "https://github.com/callstackincubator/rozenite.git"
16
16
  },
17
17
  "dependencies": {
18
- "@rozenite/agent-shared": "1.13.0",
19
- "@rozenite/agent-bridge": "1.13.0",
20
- "@rozenite/plugin-bridge": "1.13.0"
18
+ "@rozenite/agent-shared": "2.0.0",
19
+ "@rozenite/agent-bridge": "2.0.0",
20
+ "@rozenite/plugin-bridge": "2.0.0",
21
+ "@rozenite/ui": "2.0.0"
21
22
  },
22
23
  "devDependencies": {
23
24
  "@codemirror/commands": "^6.10.3",
24
25
  "@codemirror/state": "^6.6.0",
25
26
  "@codemirror/view": "^6.40.0",
27
+ "@tanstack/react-query": "^5.0.0",
26
28
  "@tanstack/react-table": "^8.21.3",
27
- "@types/react": "~19.2.2",
28
- "autoprefixer": "^10.4.21",
29
+ "@types/react": "~19.2.3",
29
30
  "lucide-react": "^0.263.1",
30
- "postcss": "^8.5.6",
31
- "react": "19.2.0",
32
- "react-dom": "19.2.0",
33
- "react-json-tree": "^0.20.0",
34
- "react-native": "0.83.1",
31
+ "react": "19.2.3",
32
+ "react-dom": "19.2.3",
33
+ "react-native": "0.86.0",
35
34
  "react-native-mmkv": "^3.3.0",
36
35
  "react-native-mmkv-v3": "npm:react-native-mmkv@^3.0.0",
37
36
  "react-native-mmkv-v4": "npm:react-native-mmkv@^4.0.0",
38
37
  "react-native-nitro-modules": "*",
39
38
  "react-native-web": "^0.21.2",
40
- "tailwindcss": "^3.4.17",
41
- "tailwindcss-animate": "^1.0.7",
39
+ "react-virtuoso": "^4.14.1",
42
40
  "typescript": "~5.9.3",
43
41
  "vite": "^7.3.1",
44
- "@rozenite/vite-plugin": "1.13.0",
45
- "rozenite": "1.13.0"
42
+ "@rozenite/vite-plugin": "2.0.0",
43
+ "rozenite": "2.0.0"
46
44
  },
47
45
  "peerDependencies": {
48
46
  "@react-native-async-storage/async-storage": "*",
package/react-native.ts CHANGED
@@ -33,7 +33,7 @@ const isServer = typeof window === 'undefined';
33
33
  const createNoopStorageAdapter = (
34
34
  options: { adapterId?: string; adapterName?: string } | undefined,
35
35
  defaultId: string,
36
- defaultName: string
36
+ defaultName: string,
37
37
  ) => ({
38
38
  id: options?.adapterId ?? defaultId,
39
39
  name: options?.adapterName ?? defaultName,
@@ -41,13 +41,14 @@ const createNoopStorageAdapter = (
41
41
  });
42
42
 
43
43
  if (!isDev || isServer) {
44
- createAsyncStorageAdapter = ((
45
- options: { adapterId?: string; adapterName?: string }
46
- ) =>
44
+ createAsyncStorageAdapter = ((options: {
45
+ adapterId?: string;
46
+ adapterName?: string;
47
+ }) =>
47
48
  createNoopStorageAdapter(
48
49
  options,
49
50
  'async-storage',
50
- 'AsyncStorage'
51
+ 'AsyncStorage',
51
52
  )) as typeof createAsyncStorageAdapter;
52
53
  createExpoAsyncStorageAdapter = createAsyncStorageAdapter;
53
54
  createExpoSecureStorageAdapter = ((options: {
@@ -57,22 +58,36 @@ if (!isDev || isServer) {
57
58
  createNoopStorageAdapter(
58
59
  options,
59
60
  'expo-secure-store',
60
- 'Expo SecureStore'
61
+ 'Expo SecureStore',
61
62
  )) as typeof createExpoSecureStorageAdapter;
62
- createMMKVStorageAdapter = ((
63
- options: { adapterId?: string; adapterName?: string }
64
- ) => createNoopStorageAdapter(options, 'mmkv', 'MMKV')) as typeof createMMKVStorageAdapter;
63
+ createMMKVStorageAdapter = ((options: {
64
+ adapterId?: string;
65
+ adapterName?: string;
66
+ }) =>
67
+ createNoopStorageAdapter(
68
+ options,
69
+ 'mmkv',
70
+ 'MMKV',
71
+ )) as typeof createMMKVStorageAdapter;
65
72
  useRozeniteStoragePlugin = () => null;
66
73
  } else if (isWeb) {
67
74
  const asyncStorageModule = require('./src/react-native/adapters/async-storage');
68
75
  const secureStorageModule = require('./src/react-native/adapters/secure-storage');
69
76
 
70
77
  createAsyncStorageAdapter = asyncStorageModule.createAsyncStorageAdapter;
71
- createExpoAsyncStorageAdapter = asyncStorageModule.createExpoAsyncStorageAdapter;
72
- createExpoSecureStorageAdapter = secureStorageModule.createExpoSecureStorageAdapter;
73
- createMMKVStorageAdapter = ((
74
- options: { adapterId?: string; adapterName?: string }
75
- ) => createNoopStorageAdapter(options, 'mmkv', 'MMKV')) as typeof createMMKVStorageAdapter;
78
+ createExpoAsyncStorageAdapter =
79
+ asyncStorageModule.createExpoAsyncStorageAdapter;
80
+ createExpoSecureStorageAdapter =
81
+ secureStorageModule.createExpoSecureStorageAdapter;
82
+ createMMKVStorageAdapter = ((options: {
83
+ adapterId?: string;
84
+ adapterName?: string;
85
+ }) =>
86
+ createNoopStorageAdapter(
87
+ options,
88
+ 'mmkv',
89
+ 'MMKV',
90
+ )) as typeof createMMKVStorageAdapter;
76
91
  useRozeniteStoragePlugin =
77
92
  require('./src/react-native/useRozeniteStoragePlugin').useRozeniteStoragePlugin;
78
93
  } else {
@@ -1,3 +1,55 @@
1
+ type DevFlowContext = {
2
+ send: (type: string, payload: unknown) => void;
3
+ waitForMessage: (
4
+ matcher: { type?: string; direction?: 'in' | 'out' },
5
+ options?: { timeoutMs?: number },
6
+ ) => Promise<{ payload: unknown }>;
7
+ };
8
+
9
+ const storageFixtures = [
10
+ {
11
+ type: 'snapshot',
12
+ target: { adapterId: 'async-storage', storageId: 'default' },
13
+ adapterName: 'AsyncStorage',
14
+ storageName: 'Default Storage',
15
+ capabilities: { supportedTypes: ['string'] },
16
+ entries: [
17
+ {
18
+ key: 'welcome-message',
19
+ type: 'string',
20
+ value: 'Hello from AsyncStorage',
21
+ },
22
+ ],
23
+ },
24
+ {
25
+ type: 'snapshot',
26
+ target: { adapterId: 'expo-secure-store', storageId: 'default' },
27
+ adapterName: 'Expo SecureStore',
28
+ storageName: 'Default Secure Storage',
29
+ capabilities: { supportedTypes: ['string'] },
30
+ entries: [
31
+ {
32
+ key: 'access-token',
33
+ type: 'string',
34
+ value: 'secure-token-fixture',
35
+ },
36
+ ],
37
+ },
38
+ {
39
+ type: 'snapshot',
40
+ target: { adapterId: 'mmkv', storageId: 'default' },
41
+ adapterName: 'MMKV',
42
+ storageName: 'default',
43
+ capabilities: { supportedTypes: ['string', 'number', 'boolean', 'buffer'] },
44
+ entries: [
45
+ { key: 'display-name', type: 'string', value: 'Rozenite' },
46
+ { key: 'launch-count', type: 'number', value: 42 },
47
+ { key: 'onboarding-complete', type: 'boolean', value: true },
48
+ { key: 'binary-token', type: 'buffer', value: [82, 78, 68, 101, 118] },
49
+ ],
50
+ },
51
+ ];
52
+
1
53
  export default {
2
54
  panels: [
3
55
  {
@@ -5,4 +57,30 @@ export default {
5
57
  source: './src/ui/panel.tsx',
6
58
  },
7
59
  ],
60
+ dev: {
61
+ flows: [
62
+ {
63
+ name: 'Initialize storage fixtures',
64
+ autoRun: true,
65
+ run: async ({ send, waitForMessage }: DevFlowContext) => {
66
+ await waitForMessage(
67
+ { type: 'get-snapshot', direction: 'out' },
68
+ { timeoutMs: 10000 },
69
+ );
70
+
71
+ storageFixtures.forEach((snapshot) => send('snapshot', snapshot));
72
+
73
+ return {
74
+ message:
75
+ 'Initialized AsyncStorage, Expo SecureStore, and MMKV fixtures.',
76
+ storages: storageFixtures.length,
77
+ entries: storageFixtures.reduce(
78
+ (total, snapshot) => total + snapshot.entries.length,
79
+ 0,
80
+ ),
81
+ };
82
+ },
83
+ },
84
+ ],
85
+ },
8
86
  };