@rozenite/storage-plugin 1.8.1 → 1.9.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.
- package/CHANGELOG.md +19 -0
- package/README.md +23 -0
- package/dist/devtools/assets/panel-DVxtKLI9.css +1 -0
- package/dist/devtools/assets/panel-DnjbFMGo.js +22 -0
- package/dist/devtools/panel.html +2 -2
- package/dist/react-native/chunks/index.require.cjs +1 -1
- package/dist/react-native/chunks/index.require.js +9 -5
- package/dist/react-native/chunks/useRozeniteStoragePlugin.require.cjs +1 -1
- package/dist/react-native/chunks/useRozeniteStoragePlugin.require.js +253 -191
- package/dist/react-native/index.d.ts +29 -6
- package/dist/rozenite.json +1 -1
- package/dist/sdk/index.d.ts +1 -0
- package/package.json +6 -6
- package/src/react-native/__tests__/import.test.ts +182 -0
- package/src/react-native/adapters/__tests__/mmkv.test.ts +141 -0
- package/src/react-native/adapters/mmkv.ts +15 -0
- package/src/react-native/import.ts +67 -0
- package/src/react-native/storage-view.ts +16 -8
- package/src/react-native/useRozeniteStoragePlugin.ts +61 -36
- package/src/shared/__tests__/snapshot.test.ts +361 -0
- package/src/shared/messaging.ts +25 -1
- package/src/shared/snapshot.ts +276 -0
- package/src/shared/types.ts +1 -0
- package/src/ui/import-dialog.tsx +261 -0
- package/src/ui/panel.tsx +257 -57
- package/src/ui/utils.ts +30 -0
- package/dist/devtools/assets/panel-DMhXYHH4.css +0 -1
- package/dist/devtools/assets/panel-eGOuOVos.js +0 -22
package/dist/devtools/panel.html
CHANGED
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
<script>
|
|
23
23
|
var __ROZENITE_PANEL__ = true;
|
|
24
24
|
</script>
|
|
25
|
-
<script type="module" crossorigin src="../devtools/assets/panel-
|
|
26
|
-
<link rel="stylesheet" crossorigin href="../devtools/assets/panel-
|
|
25
|
+
<script type="module" crossorigin src="../devtools/assets/panel-DnjbFMGo.js"></script>
|
|
26
|
+
<link rel="stylesheet" crossorigin href="../devtools/assets/panel-DVxtKLI9.css">
|
|
27
27
|
</head>
|
|
28
28
|
<body>
|
|
29
29
|
<div id="root"></div>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./types.cjs"),l=require("./async-storage.require.cjs"),f=require("./secure-storage.require.cjs"),p=t=>!!(t.includes("�")||/[\u0000-\u001F\u007F-\u009F]/.test(t)||[...t].filter(n=>n>=" "&&n<="~").length/t.length<.7),g=t=>"remove"in t,A=t=>{if(Array.isArray(t)){if(t.some(g))throw new Error("[Rozenite] Storage Plugin: MMKV arrays are not supported for v4 storages. Pass a record of storage IDs and MMKV instances.");return Object.fromEntries(t.map(r=>[r.id,r]))}return t},S=t=>g(t)?{set:(e,r)=>t.set(e,r),getBoolean:e=>t.getBoolean(e),getString:e=>t.getString(e),getNumber:e=>t.getNumber(e),getBuffer:e=>t.getBuffer(e),delete:e=>t.remove(e),getAllKeys:()=>t.getAllKeys(),addOnValueChangedListener:e=>t.addOnValueChangedListener(e)}:{set:(e,r)=>t.set(e,r),getBoolean:e=>t.getBoolean(e),getString:e=>t.getString(e),getNumber:e=>t.getNumber(e),getBuffer:e=>t.getBuffer(e),delete:e=>t.delete(e),getAllKeys:()=>t.getAllKeys(),addOnValueChangedListener:e=>t.addOnValueChangedListener(e)},b=(t,e)=>{const r=t.getString(e);if(r!==void 0&&r.length>0)return p(r)?{key:e,type:"buffer",value:Array.from(new TextEncoder().encode(r))}:{key:e,type:"string",value:r};const n=t.getNumber(e);if(n!==void 0)return{key:e,type:"number",value:n};const s=t.getBoolean(e);if(s!==void 0)return{key:e,type:"boolean",value:s};const u=t.getBuffer(e);if(u!==void 0)return{key:e,type:"buffer",value:Array.from(new Uint8Array(u))}},y=(t,e)=>{if(e.type==="buffer"){t.set(e.key,new Uint8Array(e.value).buffer);return}t.set(e.key,e.value)},V=(t,e)=>{if(t)return t instanceof RegExp?t:t[e]},M=({adapterId:t="mmkv",adapterName:e="MMKV",storages:r,blacklist:n})=>{const s=A(r),u=Object.entries(s).map(([i,c])=>{const o=S(c);return{id:i,name:i,blacklist:V(n,i),capabilities:{supportedTypes:d.DEFAULT_SUPPORTED_TYPES},storage:{kind:"sync",getAllKeys:()=>o.getAllKeys(),get:a=>b(o,a),set:a=>y(o,a),delete:a=>o.delete(a),subscribe:a=>o.addOnValueChangedListener(a)}}});return{id:t,name:e,storages:u}};exports.createAsyncStorageAdapter=l.createAsyncStorageAdapter;exports.createExpoAsyncStorageAdapter=l.createExpoAsyncStorageAdapter;exports.createExpoSecureStorageAdapter=f.createExpoSecureStorageAdapter;exports.createMMKVStorageAdapter=
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./types.cjs"),l=require("./async-storage.require.cjs"),f=require("./secure-storage.require.cjs"),p=t=>!!(t.includes("�")||/[\u0000-\u001F\u007F-\u009F]/.test(t)||[...t].filter(n=>n>=" "&&n<="~").length/t.length<.7),g=t=>"remove"in t,A=t=>{if(Array.isArray(t)){if(t.some(g))throw new Error("[Rozenite] Storage Plugin: MMKV arrays are not supported for v4 storages. Pass a record of storage IDs and MMKV instances.");return Object.fromEntries(t.map(r=>[r.id,r]))}return t},S=t=>g(t)?{set:(e,r)=>t.set(e,r),getBoolean:e=>t.getBoolean(e),getString:e=>t.getString(e),getNumber:e=>t.getNumber(e),getBuffer:e=>t.getBuffer(e),delete:e=>t.remove(e),getAllKeys:()=>t.getAllKeys(),addOnValueChangedListener:e=>t.addOnValueChangedListener(e)}:{set:(e,r)=>t.set(e,r),getBoolean:e=>t.getBoolean(e),getString:e=>t.getString(e),getNumber:e=>t.getNumber(e),getBuffer:e=>t.getBuffer(e),delete:e=>t.delete(e),getAllKeys:()=>t.getAllKeys(),addOnValueChangedListener:e=>t.addOnValueChangedListener(e)},b=(t,e)=>{const r=t.getString(e);if(r!==void 0&&r.length>0)return p(r)?{key:e,type:"buffer",value:Array.from(new TextEncoder().encode(r))}:{key:e,type:"string",value:r};const n=t.getNumber(e);if(n!==void 0)return{key:e,type:"number",value:n};const s=t.getBoolean(e);if(s!==void 0)return{key:e,type:"boolean",value:s};const u=t.getBuffer(e);if(u!==void 0)return{key:e,type:"buffer",value:Array.from(new Uint8Array(u))}},y=(t,e)=>{if(e.type==="buffer"){t.set(e.key,new Uint8Array(e.value).buffer);return}t.set(e.key,e.value)},V=(t,e)=>{if(t)return t instanceof RegExp?t:t[e]},M=(t,e)=>{if(t instanceof RegExp)return r=>(t.lastIndex=0,t.test(`${e}:${r}`))},E=({adapterId:t="mmkv",adapterName:e="MMKV",storages:r,blacklist:n})=>{const s=A(r),u=Object.entries(s).map(([i,c])=>{const o=S(c);return{id:i,name:i,blacklist:V(n,i),shouldFilterKey:M(n,i),capabilities:{supportedTypes:d.DEFAULT_SUPPORTED_TYPES},storage:{kind:"sync",getAllKeys:()=>o.getAllKeys(),get:a=>b(o,a),set:a=>y(o,a),delete:a=>o.delete(a),subscribe:a=>o.addOnValueChangedListener(a)}}});return{id:t,name:e,storages:u}};exports.createAsyncStorageAdapter=l.createAsyncStorageAdapter;exports.createExpoAsyncStorageAdapter=l.createExpoAsyncStorageAdapter;exports.createExpoSecureStorageAdapter=f.createExpoSecureStorageAdapter;exports.createMMKVStorageAdapter=E;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { D as f } from "./types.js";
|
|
2
|
-
import { createAsyncStorageAdapter as
|
|
2
|
+
import { createAsyncStorageAdapter as B, createExpoAsyncStorageAdapter as E } from "./async-storage.require.js";
|
|
3
3
|
import { createExpoSecureStorageAdapter as O } from "./secure-storage.require.js";
|
|
4
4
|
const d = (t) => !!(t.includes("�") || /[\u0000-\u001F\u007F-\u009F]/.test(t) || [...t].filter((n) => n >= " " && n <= "~").length / t.length < 0.7), l = (t) => "remove" in t, c = (t) => {
|
|
5
5
|
if (Array.isArray(t)) {
|
|
@@ -72,7 +72,10 @@ const d = (t) => !!(t.includes("�") || /[\u0000-\u001F\u007F-\u009F]/.test(t)
|
|
|
72
72
|
}, S = (t, e) => {
|
|
73
73
|
if (t)
|
|
74
74
|
return t instanceof RegExp ? t : t[e];
|
|
75
|
-
}, y = ({
|
|
75
|
+
}, y = (t, e) => {
|
|
76
|
+
if (t instanceof RegExp)
|
|
77
|
+
return (r) => (t.lastIndex = 0, t.test(`${e}:${r}`));
|
|
78
|
+
}, h = ({
|
|
76
79
|
adapterId: t = "mmkv",
|
|
77
80
|
adapterName: e = "MMKV",
|
|
78
81
|
storages: r,
|
|
@@ -85,6 +88,7 @@ const d = (t) => !!(t.includes("�") || /[\u0000-\u001F\u007F-\u009F]/.test(t)
|
|
|
85
88
|
id: i,
|
|
86
89
|
name: i,
|
|
87
90
|
blacklist: S(n, i),
|
|
91
|
+
shouldFilterKey: y(n, i),
|
|
88
92
|
capabilities: {
|
|
89
93
|
supportedTypes: f
|
|
90
94
|
},
|
|
@@ -106,8 +110,8 @@ const d = (t) => !!(t.includes("�") || /[\u0000-\u001F\u007F-\u009F]/.test(t)
|
|
|
106
110
|
};
|
|
107
111
|
};
|
|
108
112
|
export {
|
|
109
|
-
|
|
110
|
-
|
|
113
|
+
B as createAsyncStorageAdapter,
|
|
114
|
+
E as createExpoAsyncStorageAdapter,
|
|
111
115
|
O as createExpoSecureStorageAdapter,
|
|
112
|
-
|
|
116
|
+
h as createMMKVStorageAdapter
|
|
113
117
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const k=require("@rozenite/plugin-bridge"),w=require("react"),P=require("./types.cjs"),g=require("@rozenite/agent-bridge"),p=require("@rozenite/agent-shared"),v=async(t,e,r)=>{const s=t.find(n=>n.target.adapterId===e.target.adapterId&&n.target.storageId===e.target.storageId);if(!s){r({type:"import-result",target:e.target,ok:!1,written:0,total:e.entries.length,error:"Target storage not found"});return}for(let n=0;n<e.entries.length;n++){const o=e.entries[n];try{await s.set(o)}catch(i){r({type:"import-result",target:e.target,ok:!1,written:n,total:e.entries.length,failedKey:o.key,error:i instanceof Error?i.message:String(i)});return}r({type:"set-entry",target:e.target,entry:o})}r({type:"import-result",target:e.target,ok:!0,written:e.entries.length,total:e.entries.length})},R=1500,I=t=>t.kind==="async",b=t=>t.type==="buffer"?`${t.type}:${t.value.join(",")}`:`${t.type}:${String(t.value)}`,z=t=>new Map(t.map(e=>[e.key,e])),m=(t,e)=>t.shouldFilterKey?.(e)?!0:t.blacklist?(t.blacklist.lastIndex=0,t.blacklist.test(e)):!1,M=(t,e,r)=>{if(!P.supportsType(t,e))throw new Error(`Type "${e}" is not supported by storage "${r.storageId}" in adapter "${r.adapterId}".`)},E=async t=>(I(t),t.getAllKeys()),S=async(t,e)=>(I(t),t.get(e)),x=async(t,e)=>{if(I(t)){await t.set(e);return}t.set(e)},N=async(t,e)=>{if(I(t)){await t.delete(e);return}t.delete(e)},$=async t=>{const e=await t();return z(e)},K=(t,e,r)=>{e.forEach((s,n)=>{const o=t.get(n);if(!o){r.onSet(s);return}b(o)!==b(s)&&r.onSet(s)}),t.forEach((s,n)=>{e.has(n)||r.onDelete(n)})},q=async(t,e)=>{let r=await $(t);const s=setInterval(async()=>{try{const n=await $(t);K(r,n,e),r=n}catch{}},R);return{remove:()=>{clearInterval(s)}}},j=(t,e)=>{const r=e.storage,s={adapterId:t.id,storageId:e.id},n=async i=>{if(!m(e,i))return S(r,i)},o=async()=>{const i=await E(r);return(await Promise.all(i.filter(d=>!m(e,d)).map(d=>S(r,d)))).filter(d=>!!d)};return{id:P.getStorageViewId(s),target:s,adapterName:t.name,storageName:e.name,capabilities:e.capabilities,blacklist:e.blacklist,get:n,set:async i=>{M(e.capabilities,i.type,s),await x(r,i)},delete:async i=>{await N(r,i)},getAllKeys:async()=>(await E(r)).filter(a=>!m(e,a)),getAllEntries:o,watch:async({onSet:i,onDelete:a})=>r.subscribe?r.subscribe(async d=>{try{const l=await n(d);if(!l){a(d);return}i(l)}catch{}}):q(o,{onSet:i,onDelete:a})}},C=t=>t.flatMap(e=>e.storages.map(r=>j(e,r))),f={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."}},u="@rozenite/storage-plugin",T=["string","number","boolean","buffer"],y={listStorages:p.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:p.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:{...f,offset:{type:"number",description:"Pagination offset. Defaults to 0."},limit:{type:"number",description:"Pagination size. Defaults to 100."}}}}),readEntry:p.defineAgentToolContract({name:"read-entry",description:"Read a single storage entry value by key.",inputSchema:{type:"object",properties:{...f,key:{type:"string",description:"Entry key."}},required:["key"]}}),createEntry:p.defineAgentToolContract({name:"create-entry",description:"Create a new storage entry. Fails if the key already exists.",inputSchema:{type:"object",properties:{...f,key:{type:"string",description:"Entry key."},type:{type:"string",enum:[...T],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:p.defineAgentToolContract({name:"edit-entry",description:"Edit an existing storage entry. Fails if the key does not exist.",inputSchema:{type:"object",properties:{...f,key:{type:"string",description:"Entry key."},type:{type:"string",enum:[...T],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:p.defineAgentToolContract({name:"remove-entry",description:"Remove a storage entry by key.",inputSchema:{type:"object",properties:{...f,key:{type:"string",description:"Entry key."}},required:["key"]}})},A=(t,e)=>{if(t==="string"){if(typeof e!="string")throw new Error("Expected string value for type=string");return e}if(t==="number"){if(typeof e!="number"||Number.isNaN(e))throw new Error("Expected number value for type=number");return e}if(t==="boolean"){if(typeof e!="boolean")throw new Error("Expected boolean value for type=boolean");return e}if(!Array.isArray(e)||!e.every(r=>Number.isInteger(r)))throw new Error("Expected number[] value for type=buffer");return e},h=t=>`${t.target.adapterId}/${t.target.storageId}`,F=t=>{const e=w.useCallback((r,s)=>{if(t.length===0)throw new Error("No storages are registered.");if(r!==void 0||s!==void 0){const n=t.find(o=>(r===void 0||o.target.adapterId===r)&&(s===void 0||o.target.storageId===s));if(!n){const o=[r&&`adapterId="${r}"`,s&&`storageId="${s}"`].filter(Boolean).join(", ");throw new Error(`No storage matched ${o}. Available: ${t.map(h).join(", ")}`)}return n}if(t.length>1)throw new Error(`Multiple storages detected. Provide adapterId and/or storageId. Available: ${t.map(h).join(", ")}`);return t[0]},[t]);g.useRozenitePluginAgentTool({pluginId:u,tool:y.listStorages,handler:async()=>({storages:await Promise.all(t.map(async r=>({adapterId:r.target.adapterId,storageId:r.target.storageId,adapterName:r.adapterName,storageName:r.storageName,supportedTypes:r.capabilities.supportedTypes,entryCount:(await r.getAllKeys()).length})))})}),g.useRozenitePluginAgentTool({pluginId:u,tool:y.listEntries,handler:async({adapterId:r,storageId:s,offset:n=0,limit:o=100})=>{const i=e(r,s),a=await i.getAllKeys(),d=Math.max(0,Math.floor(n)),l=Math.max(1,Math.floor(o)),c=a.slice(d,d+l);return{adapterId:i.target.adapterId,storageId:i.target.storageId,total:a.length,offset:d,limit:l,keys:c}}}),g.useRozenitePluginAgentTool({pluginId:u,tool:y.readEntry,handler:async({adapterId:r,storageId:s,key:n})=>{const o=e(r,s),i=await o.get(n);if(!i)throw new Error(`Key "${n}" not found in storage "${h(o)}".`);return{adapterId:o.target.adapterId,storageId:o.target.storageId,entry:i}}}),g.useRozenitePluginAgentTool({pluginId:u,tool:y.createEntry,handler:async({adapterId:r,storageId:s,key:n,type:o,value:i})=>{const a=e(r,s);if(await a.get(n))throw new Error(`Key "${n}" already exists in storage "${h(a)}". Use edit-entry instead.`);const l=A(o,i);return await a.set({key:n,type:o,value:l}),{adapterId:a.target.adapterId,storageId:a.target.storageId,created:!0,key:n}}}),g.useRozenitePluginAgentTool({pluginId:u,tool:y.editEntry,handler:async({adapterId:r,storageId:s,key:n,type:o,value:i})=>{const a=e(r,s);if(!await a.get(n))throw new Error(`Key "${n}" not found in storage "${h(a)}". Use create-entry instead.`);const l=A(o,i);return await a.set({key:n,type:o,value:l}),{adapterId:a.target.adapterId,storageId:a.target.storageId,edited:!0,key:n}}}),g.useRozenitePluginAgentTool({pluginId:u,tool:y.removeEntry,handler:async({adapterId:r,storageId:s,key:n})=>{const o=e(r,s),i=!!await o.get(n);return await o.delete(n),{adapterId:o.target.adapterId,storageId:o.target.storageId,removed:i,key:n}}})},V=({storages:t})=>{const e=w.useMemo(()=>C(t),[t]);F(e);const r=k.useRozeniteDevToolsClient({pluginId:"@rozenite/storage-plugin"});return w.useEffect(()=>{if(!r)return;const s=async a=>{const d=a?e.filter(l=>l.id===a):e;for(const l of d)try{const c=await l.getAllEntries();r.send("snapshot",{type:"snapshot",target:l.target,adapterName:l.adapterName,storageName:l.storageName,capabilities:l.capabilities,blacklist:l.blacklist?{source:l.blacklist.source,flags:l.blacklist.flags}:void 0,entries:c})}catch(c){console.warn(`[Rozenite] Storage Plugin: Failed to snapshot ${l.target.adapterId}/${l.target.storageId}.`,c)}};s();const n=[];let o=!1;Promise.all(e.map(async a=>{try{const d=await a.watch({onSet:l=>{r.send("set-entry",{type:"set-entry",target:a.target,entry:l})},onDelete:l=>{r.send("delete-entry",{type:"delete-entry",target:a.target,key:l})}});if(o){d.remove();return}n.push(d)}catch(d){console.warn(`[Rozenite] Storage Plugin: Failed to attach watcher for ${a.target.adapterId}/${a.target.storageId}.`,d)}}));const i=[r.onMessage("set-entry",async({target:a,entry:d})=>{const l=e.find(c=>c.target.adapterId===a.adapterId&&c.target.storageId===a.storageId);if(!l){console.warn(`[Rozenite] Storage Plugin: Storage target not found for ${a.adapterId}/${a.storageId}`);return}try{await l.set(d)}catch(c){console.warn(`[Rozenite] Storage Plugin: Failed to set entry in ${a.adapterId}/${a.storageId}.`,c)}}),r.onMessage("delete-entry",async({target:a,key:d})=>{const l=e.find(c=>c.target.adapterId===a.adapterId&&c.target.storageId===a.storageId);if(!l){console.warn(`[Rozenite] Storage Plugin: Storage target not found for ${a.adapterId}/${a.storageId}`);return}try{await l.delete(d)}catch(c){console.warn(`[Rozenite] Storage Plugin: Failed to delete entry in ${a.adapterId}/${a.storageId}.`,c)}}),r.onMessage("get-snapshot",async({target:a})=>{if(a==="all"){await s();return}await s(`${a.adapterId}:${a.storageId}`)}),r.onMessage("import-entries",async a=>{await v(e,a,d=>{d.type==="set-entry"?r.send("set-entry",d):r.send("import-result",d)})})];return()=>{o=!0,n.forEach(a=>a.remove()),i.forEach(a=>a.remove())}},[r,e]),r};exports.useRozeniteStoragePlugin=V;
|