@rozenite/storage-plugin 1.13.0 → 2.1.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 +46 -0
- package/README.md +6 -1
- package/dist/devtools/assets/panel-BlDRXgVW.js +32 -0
- package/dist/devtools/assets/panel-DBweZnW5.css +1 -0
- package/dist/devtools/panel.html +2 -2
- package/dist/react-native/chunks/async-storage.require.cjs +1 -1
- package/dist/react-native/chunks/async-storage.require.js +8 -7
- package/dist/react-native/chunks/index.require.cjs +1 -1
- package/dist/react-native/chunks/index.require.js +70 -66
- package/dist/react-native/chunks/secure-storage.require.cjs +1 -1
- package/dist/react-native/chunks/secure-storage.require.js +17 -13
- package/dist/react-native/chunks/useRozeniteStoragePlugin.require.cjs +1 -1
- package/dist/react-native/chunks/useRozeniteStoragePlugin.require.js +863 -344
- package/dist/react-native/index.d.ts +166 -18
- package/dist/rozenite.json +1 -1
- package/dist/sdk/index.cjs +1 -1
- package/dist/sdk/index.d.ts +13 -5
- package/dist/sdk/index.js +21 -12
- package/package.json +35 -37
- package/react-native.ts +12 -22
- package/rozenite.config.ts +74 -0
- package/sdk.ts +1 -5
- package/src/react-native/__tests__/entry-preview-pagination.test.ts +234 -0
- package/src/react-native/__tests__/export-snapshot.test.ts +138 -0
- package/src/react-native/__tests__/full-entry-request.test.ts +143 -0
- package/src/react-native/__tests__/import.test.ts +174 -11
- package/src/react-native/__tests__/storage-discovery.test.ts +144 -0
- package/src/react-native/__tests__/storage-view.test.ts +172 -0
- package/src/react-native/__tests__/stress-verification.test.ts +140 -0
- package/src/react-native/__tests__/use-storage-agent-tools.test.ts +221 -0
- package/src/react-native/adapters/__tests__/mmkv.test.ts +20 -30
- package/src/react-native/adapters/async-storage.ts +8 -9
- package/src/react-native/adapters/index.ts +2 -8
- package/src/react-native/adapters/mmkv.ts +12 -24
- package/src/react-native/adapters/secure-storage.ts +4 -0
- package/src/react-native/entry-preview-pagination.ts +261 -0
- package/src/react-native/export-snapshot.ts +88 -0
- package/src/react-native/full-entry-request.ts +91 -0
- package/src/react-native/import.ts +179 -16
- package/src/react-native/storage-discovery.ts +92 -0
- package/src/react-native/storage-view.ts +47 -109
- package/src/react-native/useRozeniteStoragePlugin.ts +153 -129
- package/src/react-native/useStorageAgentTools.ts +196 -91
- package/src/shared/__tests__/entry-preview.test.ts +99 -0
- package/src/shared/__tests__/snapshot.test.ts +31 -32
- package/src/shared/agent-tools.ts +33 -38
- package/src/shared/entry-preview.ts +54 -0
- package/src/shared/messaging.ts +140 -21
- package/src/shared/snapshot.ts +12 -18
- package/src/shared/types.ts +21 -4
- package/src/ui/__tests__/binary-value-editor-state.test.ts +16 -13
- package/src/ui/__tests__/binary.test.ts +31 -33
- package/src/ui/__tests__/large-value-viewer-state.test.ts +21 -0
- package/src/ui/__tests__/large-value-viewer.test.tsx +54 -0
- package/src/ui/__tests__/panel.test.tsx +382 -0
- package/src/ui/__tests__/storage-groups.test.ts +88 -0
- package/src/ui/__tests__/type-conversion.test.ts +8 -24
- package/src/ui/__tests__/use-storage-entries.test.tsx +337 -0
- package/src/ui/add-entry-dialog.tsx +66 -117
- package/src/ui/binary-value-editor-state.ts +16 -25
- package/src/ui/binary-value-editor.tsx +59 -47
- package/src/ui/binary.ts +54 -15
- package/src/ui/edit-entry-dialog.tsx +68 -104
- package/src/ui/editor-switcher.tsx +9 -16
- package/src/ui/entry-detail-dialog.tsx +62 -181
- package/src/ui/format-value.tsx +25 -0
- package/src/ui/globals.css +1 -123
- package/src/ui/import-dialog.tsx +72 -109
- package/src/ui/large-value-viewer-state.ts +25 -0
- package/src/ui/large-value-viewer.tsx +65 -0
- package/src/ui/panel.tsx +649 -509
- package/src/ui/query-client.tsx +23 -0
- package/src/ui/storage-groups.ts +66 -0
- package/src/ui/type-conversion.ts +2 -5
- package/src/ui/typed-value-editor.tsx +15 -20
- package/src/ui/use-storage-entries.ts +192 -0
- package/src/ui/utils.ts +1 -4
- package/tsconfig.json +5 -1
- package/dist/devtools/assets/panel-Bm-SWF7d.js +0 -33
- package/dist/devtools/assets/panel-DIqI4WSp.css +0 -1
- package/postcss.config.js +0 -6
- package/src/ui/confirm-dialog.tsx +0 -100
- package/src/ui/editable-table.tsx +0 -300
- package/tailwind.config.ts +0 -94
|
@@ -1,143 +1,619 @@
|
|
|
1
|
-
import { useRozeniteDevToolsClient as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { useRozenitePluginAgentTool as
|
|
5
|
-
import { defineAgentToolContract as
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { useRozeniteDevToolsClient as V } from "@rozenite/plugin-bridge";
|
|
2
|
+
import { useMemo as z, useEffect as G } from "react";
|
|
3
|
+
import { s as $, D as N, g as B } from "./types.js";
|
|
4
|
+
import { useRozenitePluginAgentTool as I } from "@rozenite/agent-bridge";
|
|
5
|
+
import { defineAgentToolContract as b, definePaginatedAgentToolContract as Y, DEFAULT_PAGE_LIMIT as Q, MAX_PAGE_LIMIT as J } from "@rozenite/agent-shared";
|
|
6
|
+
const W = "@rozenite/storage-plugin", T = 1;
|
|
7
|
+
class p extends Error {
|
|
8
|
+
constructor(t, r) {
|
|
9
|
+
super(r), this.path = t;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const y = (e) => e === null ? "null" : Array.isArray(e) ? "array" : typeof e, X = (e) => typeof e == "object" && e !== null && !Array.isArray(e), S = (e, t) => {
|
|
13
|
+
if (!X(e))
|
|
14
|
+
throw new p(t, `Expected object, got ${y(e)}`);
|
|
15
|
+
return e;
|
|
16
|
+
}, f = (e, t) => {
|
|
17
|
+
if (typeof e != "string")
|
|
18
|
+
throw new p(t, `Expected string, got ${y(e)}`);
|
|
19
|
+
return e;
|
|
20
|
+
}, C = (e, t) => {
|
|
21
|
+
if (!Array.isArray(e))
|
|
22
|
+
throw new p(t, `Expected array, got ${y(e)}`);
|
|
23
|
+
return e;
|
|
24
|
+
}, K = (e, t) => {
|
|
25
|
+
if (typeof e != "string" || !N.includes(e))
|
|
26
|
+
throw new p(
|
|
27
|
+
t,
|
|
28
|
+
`Expected one of ${N.join(", ")}, got ${y(e)}`
|
|
29
|
+
);
|
|
30
|
+
return e;
|
|
31
|
+
}, H = (e, t) => {
|
|
32
|
+
const r = S(e, t);
|
|
33
|
+
return { supportedTypes: C(r.supportedTypes, `${t}.supportedTypes`).map(
|
|
34
|
+
(a, i) => K(a, `${t}.supportedTypes[${i}]`)
|
|
35
|
+
) };
|
|
36
|
+
}, Z = (e) => {
|
|
37
|
+
const t = S(e, "storage");
|
|
38
|
+
return {
|
|
39
|
+
adapterId: f(t.adapterId, "storage.adapterId"),
|
|
40
|
+
storageId: f(t.storageId, "storage.storageId"),
|
|
41
|
+
adapterName: f(t.adapterName, "storage.adapterName"),
|
|
42
|
+
storageName: f(t.storageName, "storage.storageName"),
|
|
43
|
+
capabilities: H(t.capabilities, "storage.capabilities")
|
|
44
|
+
};
|
|
45
|
+
}, ee = (e, t) => {
|
|
46
|
+
const r = S(e, t), o = f(r.key, `${t}.key`), n = K(r.type, `${t}.type`), a = `${t}.value`;
|
|
47
|
+
switch (n) {
|
|
48
|
+
case "string": {
|
|
49
|
+
const i = r.value;
|
|
50
|
+
if (typeof i != "string")
|
|
51
|
+
throw new p(
|
|
52
|
+
a,
|
|
53
|
+
`Expected string for type "string", got ${y(i)}`
|
|
54
|
+
);
|
|
55
|
+
return { key: o, type: "string", value: i };
|
|
56
|
+
}
|
|
57
|
+
case "number": {
|
|
58
|
+
const i = r.value;
|
|
59
|
+
if (typeof i != "number" || !Number.isFinite(i))
|
|
60
|
+
throw new p(
|
|
61
|
+
a,
|
|
62
|
+
`Expected finite number for type "number", got ${y(i)}`
|
|
63
|
+
);
|
|
64
|
+
return { key: o, type: "number", value: i };
|
|
65
|
+
}
|
|
66
|
+
case "boolean": {
|
|
67
|
+
const i = r.value;
|
|
68
|
+
if (typeof i != "boolean")
|
|
69
|
+
throw new p(
|
|
70
|
+
a,
|
|
71
|
+
`Expected boolean for type "boolean", got ${y(i)}`
|
|
72
|
+
);
|
|
73
|
+
return { key: o, type: "boolean", value: i };
|
|
74
|
+
}
|
|
75
|
+
case "buffer": {
|
|
76
|
+
const i = r.value;
|
|
77
|
+
if (!Array.isArray(i))
|
|
78
|
+
throw new p(
|
|
79
|
+
a,
|
|
80
|
+
`Expected number[] for type "buffer", got ${y(i)}`
|
|
81
|
+
);
|
|
82
|
+
const s = i.map((c, d) => {
|
|
83
|
+
if (typeof c != "number" || !Number.isInteger(c) || c < 0 || c > 255)
|
|
84
|
+
throw new p(
|
|
85
|
+
`${a}[${d}]`,
|
|
86
|
+
`Expected uint8 (integer 0-255), got ${y(c)}`
|
|
87
|
+
);
|
|
88
|
+
return c;
|
|
89
|
+
});
|
|
90
|
+
return { key: o, type: "buffer", value: s };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}, te = (e) => {
|
|
94
|
+
try {
|
|
95
|
+
const t = S(e, "$"), r = t.version;
|
|
96
|
+
if (r !== T)
|
|
97
|
+
throw new p(
|
|
98
|
+
"version",
|
|
99
|
+
`Unsupported snapshot version: ${y(r)} (this build supports version ${T})`
|
|
100
|
+
);
|
|
101
|
+
const o = f(t.plugin, "plugin"), n = f(t.createdAt, "createdAt"), a = Z(t.storage), s = C(t.entries, "entries").map((c, d) => ee(c, `entries[${d}]`));
|
|
102
|
+
return {
|
|
103
|
+
ok: !0,
|
|
104
|
+
snapshot: {
|
|
105
|
+
version: T,
|
|
106
|
+
plugin: o,
|
|
107
|
+
createdAt: n,
|
|
108
|
+
storage: a,
|
|
109
|
+
entries: s
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
} catch (t) {
|
|
113
|
+
if (t instanceof p)
|
|
114
|
+
return { ok: !1, error: { path: t.path, message: t.message } };
|
|
115
|
+
throw t;
|
|
116
|
+
}
|
|
117
|
+
}, re = (e) => ({
|
|
118
|
+
version: 1,
|
|
119
|
+
plugin: W,
|
|
120
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
121
|
+
storage: {
|
|
122
|
+
adapterId: e.target.adapterId,
|
|
123
|
+
storageId: e.target.storageId,
|
|
124
|
+
adapterName: e.adapterName,
|
|
125
|
+
storageName: e.storageName,
|
|
126
|
+
capabilities: e.capabilities
|
|
127
|
+
},
|
|
128
|
+
entries: e.entries
|
|
129
|
+
}), se = (e, t) => {
|
|
130
|
+
const r = [], o = [], n = [], a = [], i = [];
|
|
131
|
+
for (const [c, d] of e.entries.entries()) {
|
|
132
|
+
if (!$(t.capabilities, d.type)) {
|
|
133
|
+
a.push({ key: d.key, type: d.type });
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (t.isBlacklisted(d.key)) {
|
|
137
|
+
n.push({ key: d.key, reason: "blacklist" });
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
t.entryKeys.has(d.key) ? o.push(d.key) : r.push(d.key), i.push(c), t.entryKeys.add(d.key);
|
|
141
|
+
}
|
|
142
|
+
const s = e.storage.adapterId !== t.target.adapterId || e.storage.storageId !== t.target.storageId;
|
|
143
|
+
return {
|
|
144
|
+
newKeys: r,
|
|
145
|
+
overwriteKeys: o,
|
|
146
|
+
skippedKeys: n,
|
|
147
|
+
unsupportedTypes: a,
|
|
148
|
+
acceptedEntryIndexes: i,
|
|
149
|
+
metadataMismatch: s
|
|
150
|
+
};
|
|
151
|
+
}, ne = (e, t) => e.adapterId === t.adapterId && e.storageId === t.storageId, R = (e) => typeof e == "object" && e != null && !Array.isArray(e) && typeof e.adapterId == "string" && e.adapterId.trim().length > 0 && typeof e.storageId == "string" && e.storageId.trim().length > 0, M = (e) => typeof e == "object" && e != null && !Array.isArray(e) && typeof e.requestId == "string" ? e.requestId : "", oe = (e) => {
|
|
152
|
+
if (typeof e != "object" || e == null || Array.isArray(e))
|
|
153
|
+
return !1;
|
|
154
|
+
const t = e;
|
|
155
|
+
return typeof t.key != "string" ? !1 : t.type === "string" ? typeof t.value == "string" : t.type === "number" ? typeof t.value == "number" : t.type === "boolean" ? typeof t.value == "boolean" : t.type === "buffer" && Array.isArray(t.value) && t.value.every(
|
|
156
|
+
(r) => typeof r == "number" && Number.isInteger(r) && r >= 0 && r <= 255
|
|
9
157
|
);
|
|
10
|
-
|
|
158
|
+
}, O = (e, t) => e.blacklist ? (e.blacklist.lastIndex = 0, e.blacklist.test(t)) : !1, U = (e, t) => e.find((r) => ne(r.target, t)), ae = async (e, t) => {
|
|
159
|
+
const r = M(t), o = t, n = te(o.snapshot);
|
|
160
|
+
if (typeof o != "object" || o == null || o.type !== "preview-import" || typeof o.requestId != "string" || o.requestId.trim().length === 0 || !R(o.target) || !n.ok)
|
|
161
|
+
return {
|
|
162
|
+
type: "storage-request-error",
|
|
163
|
+
requestId: r,
|
|
164
|
+
code: "INVALID_REQUEST",
|
|
165
|
+
message: "Import preview requests require a valid target, request ID, and snapshot."
|
|
166
|
+
};
|
|
167
|
+
const a = U(e, o.target);
|
|
168
|
+
if (!a)
|
|
169
|
+
return {
|
|
170
|
+
type: "storage-request-error",
|
|
171
|
+
requestId: r,
|
|
172
|
+
code: "TARGET_NOT_FOUND",
|
|
173
|
+
message: "The requested storage target was not found."
|
|
174
|
+
};
|
|
175
|
+
try {
|
|
176
|
+
const i = new Set(await a.getAllKeys());
|
|
177
|
+
return {
|
|
178
|
+
type: "import-preview",
|
|
179
|
+
requestId: r,
|
|
180
|
+
target: a.target,
|
|
181
|
+
preview: se(n.snapshot, {
|
|
182
|
+
target: a.target,
|
|
183
|
+
capabilities: a.capabilities,
|
|
184
|
+
entryKeys: i,
|
|
185
|
+
isBlacklisted: (s) => O(a, s)
|
|
186
|
+
})
|
|
187
|
+
};
|
|
188
|
+
} catch {
|
|
189
|
+
return {
|
|
190
|
+
type: "storage-request-error",
|
|
191
|
+
requestId: r,
|
|
192
|
+
code: "READ_FAILED",
|
|
193
|
+
message: "Failed to inspect the requested storage for import."
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}, ie = async (e, t, r) => {
|
|
197
|
+
const o = M(t), n = t;
|
|
198
|
+
if (typeof n != "object" || n == null || n.type !== "import-entries" || typeof n.requestId != "string" || n.requestId.trim().length === 0 || !R(n.target) || !Array.isArray(n.entries) || !n.entries.every(oe)) {
|
|
11
199
|
r({
|
|
12
200
|
type: "import-result",
|
|
13
|
-
|
|
201
|
+
requestId: o,
|
|
202
|
+
target: R(n.target) ? n.target : { adapterId: "", storageId: "" },
|
|
14
203
|
ok: !1,
|
|
15
204
|
written: 0,
|
|
16
|
-
total:
|
|
205
|
+
total: 0,
|
|
206
|
+
error: "Import requests require a valid target, request ID, and entries."
|
|
207
|
+
});
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const a = U(e, n.target);
|
|
211
|
+
if (!a) {
|
|
212
|
+
r({
|
|
213
|
+
type: "import-result",
|
|
214
|
+
requestId: n.requestId,
|
|
215
|
+
target: n.target,
|
|
216
|
+
ok: !1,
|
|
217
|
+
written: 0,
|
|
218
|
+
total: n.entries.length,
|
|
17
219
|
error: "Target storage not found"
|
|
18
220
|
});
|
|
19
221
|
return;
|
|
20
222
|
}
|
|
21
|
-
|
|
22
|
-
|
|
223
|
+
const i = n.entries.filter(
|
|
224
|
+
(s) => $(a.capabilities, s.type) && !O(a, s.key)
|
|
225
|
+
);
|
|
226
|
+
for (let s = 0; s < i.length; s++) {
|
|
227
|
+
const c = i[s];
|
|
23
228
|
try {
|
|
24
|
-
await
|
|
25
|
-
} catch (
|
|
229
|
+
await a.set(c);
|
|
230
|
+
} catch (d) {
|
|
231
|
+
if (s > 0) {
|
|
232
|
+
const g = (await a.getAllKeys()).length;
|
|
233
|
+
r({
|
|
234
|
+
type: "storage-invalidated",
|
|
235
|
+
target: n.target,
|
|
236
|
+
operation: "import",
|
|
237
|
+
entryCount: g
|
|
238
|
+
});
|
|
239
|
+
}
|
|
26
240
|
r({
|
|
27
241
|
type: "import-result",
|
|
28
|
-
|
|
242
|
+
requestId: n.requestId,
|
|
243
|
+
target: n.target,
|
|
29
244
|
ok: !1,
|
|
30
|
-
written:
|
|
31
|
-
total:
|
|
32
|
-
failedKey:
|
|
33
|
-
error:
|
|
245
|
+
written: s,
|
|
246
|
+
total: i.length,
|
|
247
|
+
failedKey: c.key,
|
|
248
|
+
error: d instanceof Error ? d.message : String(d)
|
|
34
249
|
});
|
|
35
250
|
return;
|
|
36
251
|
}
|
|
37
252
|
r({
|
|
38
|
-
type: "
|
|
39
|
-
|
|
40
|
-
|
|
253
|
+
type: "import-progress",
|
|
254
|
+
requestId: n.requestId,
|
|
255
|
+
target: n.target,
|
|
256
|
+
written: s + 1,
|
|
257
|
+
total: i.length
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
if (i.length > 0) {
|
|
261
|
+
const s = (await a.getAllKeys()).length;
|
|
262
|
+
r({
|
|
263
|
+
type: "storage-invalidated",
|
|
264
|
+
target: n.target,
|
|
265
|
+
operation: "import",
|
|
266
|
+
entryCount: s
|
|
41
267
|
});
|
|
42
268
|
}
|
|
43
269
|
r({
|
|
44
270
|
type: "import-result",
|
|
45
|
-
|
|
271
|
+
requestId: n.requestId,
|
|
272
|
+
target: n.target,
|
|
46
273
|
ok: !0,
|
|
47
|
-
written:
|
|
48
|
-
total:
|
|
274
|
+
written: i.length,
|
|
275
|
+
total: i.length
|
|
276
|
+
});
|
|
277
|
+
}, ce = (e) => typeof e == "object" && e != null && !Array.isArray(e) && typeof e.requestId == "string" ? e.requestId : "", de = (e) => typeof e == "object" && e != null && !Array.isArray(e) && e.type === "discover-storages" && typeof e.requestId == "string" && e.requestId.trim().length > 0, ge = async (e) => ({
|
|
278
|
+
target: e.target,
|
|
279
|
+
adapterName: e.adapterName,
|
|
280
|
+
storageName: e.storageName,
|
|
281
|
+
entryCount: (await e.getAllKeys()).length,
|
|
282
|
+
capabilities: e.capabilities,
|
|
283
|
+
supportsSubscriptions: e.supportsSubscriptions
|
|
284
|
+
}), pe = (e) => {
|
|
285
|
+
const t = /* @__PURE__ */ new Set();
|
|
286
|
+
return e.some(({ target: r }) => {
|
|
287
|
+
const o = `${r.adapterId}:${r.storageId}`;
|
|
288
|
+
return t.has(o) ? !0 : (t.add(o), !1);
|
|
49
289
|
});
|
|
50
|
-
},
|
|
51
|
-
|
|
290
|
+
}, ue = async (e, t) => {
|
|
291
|
+
const r = ce(t);
|
|
292
|
+
if (!de(t))
|
|
293
|
+
return {
|
|
294
|
+
type: "storage-request-error",
|
|
295
|
+
requestId: r,
|
|
296
|
+
code: "INVALID_REQUEST",
|
|
297
|
+
message: "Storage discovery requires a non-empty request ID."
|
|
298
|
+
};
|
|
299
|
+
try {
|
|
300
|
+
if (pe(e))
|
|
301
|
+
return {
|
|
302
|
+
type: "storage-request-error",
|
|
303
|
+
requestId: r,
|
|
304
|
+
code: "INVALID_REQUEST",
|
|
305
|
+
message: "Configured storages must have unique targets."
|
|
306
|
+
};
|
|
307
|
+
const o = await Promise.all(e.map(ge));
|
|
308
|
+
return { type: "storage-descriptors", requestId: r, storages: o };
|
|
309
|
+
} catch {
|
|
310
|
+
return {
|
|
311
|
+
type: "storage-request-error",
|
|
312
|
+
requestId: r,
|
|
313
|
+
code: "READ_FAILED",
|
|
314
|
+
message: "Failed to discover configured storages."
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
}, ye = 256, k = 16, le = (e) => e.toString(16).toUpperCase().padStart(2, "0"), fe = (e) => {
|
|
318
|
+
let t = "", r = 0;
|
|
319
|
+
for (const o of e) {
|
|
320
|
+
if (r === ye)
|
|
321
|
+
return { preview: t, isTruncated: !0 };
|
|
322
|
+
t += o, r += 1;
|
|
323
|
+
}
|
|
324
|
+
return { preview: t, isTruncated: !1 };
|
|
325
|
+
}, Ie = (e) => {
|
|
326
|
+
if (e.type === "string")
|
|
327
|
+
return {
|
|
328
|
+
key: e.key,
|
|
329
|
+
type: e.type,
|
|
330
|
+
...fe(e.value),
|
|
331
|
+
// JavaScript strings expose their length in UTF-16 code units.
|
|
332
|
+
valueSize: e.value.length
|
|
333
|
+
};
|
|
334
|
+
if (e.type === "buffer") {
|
|
335
|
+
const r = e.value.slice(0, k);
|
|
336
|
+
return {
|
|
337
|
+
key: e.key,
|
|
338
|
+
type: e.type,
|
|
339
|
+
preview: r.map(le).join(" "),
|
|
340
|
+
valueSize: e.value.length,
|
|
341
|
+
isTruncated: e.value.length > k
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
const t = String(e.value);
|
|
345
|
+
return {
|
|
346
|
+
key: e.key,
|
|
347
|
+
type: e.type,
|
|
348
|
+
preview: t,
|
|
349
|
+
valueSize: t.length,
|
|
350
|
+
isTruncated: !1
|
|
351
|
+
};
|
|
352
|
+
}, me = 100, he = 4, we = (e) => typeof e == "object" && e != null && !Array.isArray(e) && typeof e.requestId == "string" ? e.requestId : "", L = (e) => typeof e == "object" && e != null && !Array.isArray(e) && typeof e.adapterId == "string" && e.adapterId.trim().length > 0 && typeof e.storageId == "string" && e.storageId.trim().length > 0, be = (e) => (e ?? "").trim().toLowerCase(), Ee = (e) => {
|
|
353
|
+
if (typeof e != "object" || e == null || Array.isArray(e) || e.type !== "list-entry-previews" || typeof e.requestId != "string" || e.requestId.trim().length === 0 || !L(e.target) || e.search !== void 0 && typeof e.search != "string" || e.cursor !== void 0 && typeof e.cursor != "string" || !Number.isFinite(e.limit) || !Number.isInteger(e.limit) || e.limit < 1)
|
|
354
|
+
return;
|
|
355
|
+
const t = e.keySortDirection;
|
|
356
|
+
if (t !== void 0 && t !== "ascending" && t !== "descending")
|
|
357
|
+
return;
|
|
358
|
+
const r = e;
|
|
359
|
+
return {
|
|
360
|
+
...r,
|
|
361
|
+
search: be(r.search),
|
|
362
|
+
keySortDirection: t ?? "ascending",
|
|
363
|
+
limit: Math.min(r.limit, me)
|
|
364
|
+
};
|
|
365
|
+
}, D = (e) => btoa(encodeURIComponent(JSON.stringify(e))), Ae = (e) => {
|
|
366
|
+
try {
|
|
367
|
+
const t = JSON.parse(decodeURIComponent(atob(e)));
|
|
368
|
+
return typeof t != "object" || t == null || Array.isArray(t) || t.version !== 1 || !L(t.target) || typeof t.search != "string" || t.keySortDirection !== "ascending" && t.keySortDirection !== "descending" || typeof t.boundaryKey != "string" || t.direction !== "next" && t.direction !== "previous" ? void 0 : t;
|
|
369
|
+
} catch {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
}, x = (e, t) => e.adapterId === t.adapterId && e.storageId === t.storageId, qe = (e, t) => e < t ? -1 : e > t ? 1 : 0, Se = async (e, t) => {
|
|
373
|
+
const r = new Array(t.length);
|
|
374
|
+
let o = 0;
|
|
375
|
+
const n = async () => {
|
|
376
|
+
for (; o < t.length; ) {
|
|
377
|
+
const a = o;
|
|
378
|
+
o += 1;
|
|
379
|
+
const i = await e.get(t[a]);
|
|
380
|
+
i && (r[a] = Ie(i));
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
return await Promise.all(
|
|
384
|
+
Array.from({ length: Math.min(he, t.length) }, n)
|
|
385
|
+
), r.filter((a) => a != null);
|
|
386
|
+
}, ve = async (e, t) => {
|
|
387
|
+
const r = we(t), o = Ee(t);
|
|
388
|
+
if (!o)
|
|
389
|
+
return {
|
|
390
|
+
type: "storage-request-error",
|
|
391
|
+
requestId: r,
|
|
392
|
+
code: "INVALID_REQUEST",
|
|
393
|
+
message: "Entry preview requests require a valid target, request ID, and positive integer limit."
|
|
394
|
+
};
|
|
395
|
+
const n = e.find((i) => x(i.target, o.target));
|
|
396
|
+
if (!n)
|
|
397
|
+
return {
|
|
398
|
+
type: "storage-request-error",
|
|
399
|
+
requestId: r,
|
|
400
|
+
code: "TARGET_NOT_FOUND",
|
|
401
|
+
message: "The requested storage target was not found."
|
|
402
|
+
};
|
|
403
|
+
let a;
|
|
404
|
+
if (o.cursor !== void 0 && (a = Ae(o.cursor), !a || !x(a.target, o.target) || a.search !== o.search || a.keySortDirection !== o.keySortDirection))
|
|
405
|
+
return {
|
|
406
|
+
type: "storage-request-error",
|
|
407
|
+
requestId: r,
|
|
408
|
+
code: "INVALID_CURSOR",
|
|
409
|
+
message: "The entry preview cursor is invalid or belongs to a different query.",
|
|
410
|
+
resetPagination: !0
|
|
411
|
+
};
|
|
412
|
+
try {
|
|
413
|
+
const i = (await n.getAllKeys()).filter((l) => l.toLowerCase().includes(o.search)).sort(qe);
|
|
414
|
+
o.keySortDirection === "descending" && i.reverse();
|
|
415
|
+
let s = 0;
|
|
416
|
+
if (a) {
|
|
417
|
+
const l = i.indexOf(a.boundaryKey);
|
|
418
|
+
if (l === -1)
|
|
419
|
+
return {
|
|
420
|
+
type: "storage-request-error",
|
|
421
|
+
requestId: r,
|
|
422
|
+
code: "INVALID_CURSOR",
|
|
423
|
+
message: "The entry preview cursor is stale after storage changes.",
|
|
424
|
+
resetPagination: !0
|
|
425
|
+
};
|
|
426
|
+
s = a.direction === "next" ? l + 1 : Math.max(0, l - o.limit);
|
|
427
|
+
}
|
|
428
|
+
const c = i.slice(s, s + o.limit), d = await Se(n, c), g = s + c.length, u = {
|
|
429
|
+
version: 1,
|
|
430
|
+
target: o.target,
|
|
431
|
+
search: o.search,
|
|
432
|
+
keySortDirection: o.keySortDirection
|
|
433
|
+
};
|
|
434
|
+
return {
|
|
435
|
+
type: "entry-previews",
|
|
436
|
+
requestId: r,
|
|
437
|
+
target: o.target,
|
|
438
|
+
items: d,
|
|
439
|
+
...g < i.length && c.length > 0 ? {
|
|
440
|
+
nextCursor: D({
|
|
441
|
+
...u,
|
|
442
|
+
boundaryKey: c.at(-1),
|
|
443
|
+
direction: "next"
|
|
444
|
+
})
|
|
445
|
+
} : {},
|
|
446
|
+
...s > 0 && c.length > 0 ? {
|
|
447
|
+
previousCursor: D({
|
|
448
|
+
...u,
|
|
449
|
+
boundaryKey: c[0],
|
|
450
|
+
direction: "previous"
|
|
451
|
+
})
|
|
452
|
+
} : {}
|
|
453
|
+
};
|
|
454
|
+
} catch {
|
|
455
|
+
return {
|
|
456
|
+
type: "storage-request-error",
|
|
457
|
+
requestId: r,
|
|
458
|
+
code: "READ_FAILED",
|
|
459
|
+
message: "Failed to read entry previews from the requested storage."
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
}, Te = (e) => typeof e == "object" && e != null && !Array.isArray(e) && typeof e.requestId == "string" ? e.requestId : "", Re = (e) => typeof e == "object" && e != null && !Array.isArray(e) && typeof e.adapterId == "string" && e.adapterId.trim().length > 0 && typeof e.storageId == "string" && e.storageId.trim().length > 0, $e = (e, t) => e.adapterId === t.adapterId && e.storageId === t.storageId, Ne = (e) => typeof e == "object" && e != null && !Array.isArray(e) && e.type === "get-entry" && typeof e.requestId == "string" && e.requestId.trim().length > 0 && Re(e.target) && typeof e.key == "string", ke = async (e, t) => {
|
|
463
|
+
const r = Te(t);
|
|
464
|
+
if (!Ne(t))
|
|
465
|
+
return {
|
|
466
|
+
type: "storage-request-error",
|
|
467
|
+
requestId: r,
|
|
468
|
+
code: "INVALID_REQUEST",
|
|
469
|
+
message: "Full entry requests require a valid target, request ID, and string key."
|
|
470
|
+
};
|
|
471
|
+
const o = e.find((n) => $e(n.target, t.target));
|
|
472
|
+
if (!o)
|
|
473
|
+
return {
|
|
474
|
+
type: "storage-request-error",
|
|
475
|
+
requestId: r,
|
|
476
|
+
code: "TARGET_NOT_FOUND",
|
|
477
|
+
message: "The requested storage target was not found."
|
|
478
|
+
};
|
|
479
|
+
try {
|
|
480
|
+
const n = await o.get(t.key);
|
|
481
|
+
return n ? {
|
|
482
|
+
type: "entry",
|
|
483
|
+
requestId: r,
|
|
484
|
+
target: o.target,
|
|
485
|
+
entry: n
|
|
486
|
+
} : {
|
|
487
|
+
type: "storage-request-error",
|
|
488
|
+
requestId: r,
|
|
489
|
+
code: "ENTRY_NOT_FOUND",
|
|
490
|
+
message: "The requested storage entry was not found."
|
|
491
|
+
};
|
|
492
|
+
} catch {
|
|
493
|
+
return {
|
|
494
|
+
type: "storage-request-error",
|
|
495
|
+
requestId: r,
|
|
496
|
+
code: "READ_FAILED",
|
|
497
|
+
message: "Failed to read the requested storage entry."
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
}, De = (e) => typeof e == "object" && e != null && !Array.isArray(e) && typeof e.requestId == "string" ? e.requestId : "", xe = (e) => typeof e == "object" && e != null && !Array.isArray(e) && typeof e.adapterId == "string" && e.adapterId.trim().length > 0 && typeof e.storageId == "string" && e.storageId.trim().length > 0, _e = (e, t) => e.adapterId === t.adapterId && e.storageId === t.storageId, Pe = (e) => typeof e == "object" && e != null && !Array.isArray(e) && e.type === "export-snapshot" && typeof e.requestId == "string" && e.requestId.trim().length > 0 && xe(e.target), je = async (e, t) => {
|
|
501
|
+
const r = De(t);
|
|
502
|
+
if (!Pe(t))
|
|
503
|
+
return {
|
|
504
|
+
type: "storage-request-error",
|
|
505
|
+
requestId: r,
|
|
506
|
+
code: "INVALID_REQUEST",
|
|
507
|
+
message: "Export requests require a valid target and request ID."
|
|
508
|
+
};
|
|
509
|
+
const o = e.find((n) => _e(n.target, t.target));
|
|
510
|
+
if (!o)
|
|
511
|
+
return {
|
|
512
|
+
type: "storage-request-error",
|
|
513
|
+
requestId: r,
|
|
514
|
+
code: "TARGET_NOT_FOUND",
|
|
515
|
+
message: "The requested storage target was not found."
|
|
516
|
+
};
|
|
517
|
+
try {
|
|
518
|
+
const n = await o.getAllEntries();
|
|
519
|
+
return {
|
|
520
|
+
type: "export-snapshot-result",
|
|
521
|
+
requestId: r,
|
|
522
|
+
target: o.target,
|
|
523
|
+
snapshot: re({
|
|
524
|
+
target: o.target,
|
|
525
|
+
adapterName: o.adapterName,
|
|
526
|
+
storageName: o.storageName,
|
|
527
|
+
capabilities: o.capabilities,
|
|
528
|
+
entries: n
|
|
529
|
+
})
|
|
530
|
+
};
|
|
531
|
+
} catch {
|
|
532
|
+
return {
|
|
533
|
+
type: "storage-request-error",
|
|
534
|
+
requestId: r,
|
|
535
|
+
code: "READ_FAILED",
|
|
536
|
+
message: "Failed to export the requested storage."
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
}, v = (e) => e.kind === "async", q = (e, t) => e.shouldFilterKey?.(t) ? !0 : e.blacklist ? (e.blacklist.lastIndex = 0, e.blacklist.test(t)) : !1, Fe = (e, t, r) => {
|
|
540
|
+
if (!$(e, t))
|
|
52
541
|
throw new Error(
|
|
53
|
-
`Type "${
|
|
542
|
+
`Type "${t}" is not supported by storage "${r.storageId}" in adapter "${r.adapterId}".`
|
|
54
543
|
);
|
|
55
|
-
},
|
|
56
|
-
if (
|
|
57
|
-
await
|
|
544
|
+
}, _ = async (e) => (v(e), e.getAllKeys()), P = async (e, t) => (v(e), e.get(t)), Ce = async (e, t) => {
|
|
545
|
+
if (v(e)) {
|
|
546
|
+
await e.set(t);
|
|
58
547
|
return;
|
|
59
548
|
}
|
|
60
|
-
|
|
61
|
-
},
|
|
62
|
-
if (
|
|
63
|
-
await
|
|
549
|
+
e.set(t);
|
|
550
|
+
}, Ke = async (e, t) => {
|
|
551
|
+
if (v(e)) {
|
|
552
|
+
await e.delete(t);
|
|
64
553
|
return;
|
|
65
554
|
}
|
|
66
|
-
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
});
|
|
81
|
-
}, _ = async (t, e) => {
|
|
82
|
-
let r = await S(t);
|
|
83
|
-
const o = setInterval(async () => {
|
|
84
|
-
try {
|
|
85
|
-
const n = await S(t);
|
|
86
|
-
V(r, n, e), r = n;
|
|
87
|
-
} catch {
|
|
88
|
-
}
|
|
89
|
-
}, N);
|
|
90
|
-
return {
|
|
91
|
-
remove: () => {
|
|
92
|
-
clearInterval(o);
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
}, D = (t, e) => {
|
|
96
|
-
const r = e.storage, o = {
|
|
97
|
-
adapterId: t.id,
|
|
98
|
-
storageId: e.id
|
|
99
|
-
}, n = async (i) => {
|
|
100
|
-
if (!I(e, i))
|
|
101
|
-
return E(r, i);
|
|
102
|
-
}, s = async () => {
|
|
103
|
-
const i = await b(r);
|
|
555
|
+
e.delete(t);
|
|
556
|
+
}, Me = async (e) => {
|
|
557
|
+
await e.clear();
|
|
558
|
+
}, Oe = (e, t) => {
|
|
559
|
+
const r = t.storage, o = r.subscribe, n = /* @__PURE__ */ new Set();
|
|
560
|
+
let a = !1;
|
|
561
|
+
const i = {
|
|
562
|
+
adapterId: e.id,
|
|
563
|
+
storageId: t.id
|
|
564
|
+
}, s = async (d) => {
|
|
565
|
+
if (!q(t, d))
|
|
566
|
+
return P(r, d);
|
|
567
|
+
}, c = async () => {
|
|
568
|
+
const d = await _(r);
|
|
104
569
|
return (await Promise.all(
|
|
105
|
-
|
|
106
|
-
)).filter((
|
|
570
|
+
d.filter((u) => !q(t, u)).map((u) => P(r, u))
|
|
571
|
+
)).filter((u) => !!u);
|
|
107
572
|
};
|
|
108
573
|
return {
|
|
109
|
-
id:
|
|
110
|
-
target:
|
|
111
|
-
adapterName:
|
|
112
|
-
storageName:
|
|
113
|
-
capabilities:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
574
|
+
id: B(i),
|
|
575
|
+
target: i,
|
|
576
|
+
adapterName: e.name,
|
|
577
|
+
storageName: t.name,
|
|
578
|
+
capabilities: t.capabilities,
|
|
579
|
+
supportsSubscriptions: o != null,
|
|
580
|
+
blacklist: t.blacklist,
|
|
581
|
+
get: s,
|
|
582
|
+
set: async (d) => {
|
|
583
|
+
Fe(t.capabilities, d.type, i), n.add(d.key);
|
|
584
|
+
try {
|
|
585
|
+
await Ce(r, d);
|
|
586
|
+
} finally {
|
|
587
|
+
n.delete(d.key);
|
|
588
|
+
}
|
|
118
589
|
},
|
|
119
|
-
delete: async (
|
|
120
|
-
|
|
590
|
+
delete: async (d) => {
|
|
591
|
+
n.add(d);
|
|
592
|
+
try {
|
|
593
|
+
await Ke(r, d);
|
|
594
|
+
} finally {
|
|
595
|
+
n.delete(d);
|
|
596
|
+
}
|
|
121
597
|
},
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
watch: async ({ onSet: i, onDelete: a }) => r.subscribe ? r.subscribe(async (l) => {
|
|
598
|
+
purge: async () => {
|
|
599
|
+
a = !0;
|
|
125
600
|
try {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
i(d);
|
|
132
|
-
} catch {
|
|
601
|
+
await Me(r);
|
|
602
|
+
} finally {
|
|
603
|
+
a = !1;
|
|
133
604
|
}
|
|
134
|
-
}
|
|
605
|
+
},
|
|
606
|
+
getAllKeys: async () => (await _(r)).filter((g) => !q(t, g)),
|
|
607
|
+
getAllEntries: c,
|
|
608
|
+
...o ? {
|
|
609
|
+
watch: async (d) => o((g) => {
|
|
610
|
+
!a && !n.has(g) && !q(t, g) && d(g);
|
|
611
|
+
})
|
|
612
|
+
} : {}
|
|
135
613
|
};
|
|
136
|
-
},
|
|
137
|
-
(
|
|
138
|
-
|
|
139
|
-
)
|
|
140
|
-
), f = {
|
|
614
|
+
}, Ue = (e) => e.flatMap(
|
|
615
|
+
(t) => t.storages.map((r) => Oe(t, r))
|
|
616
|
+
), E = {
|
|
141
617
|
adapterId: {
|
|
142
618
|
type: "string",
|
|
143
619
|
description: "Storage adapter ID. Required when multiple adapters are configured."
|
|
@@ -146,58 +622,67 @@ const x = async (t, e, r) => {
|
|
|
146
622
|
type: "string",
|
|
147
623
|
description: "Storage node ID within the adapter. Required when multiple storages are configured."
|
|
148
624
|
}
|
|
149
|
-
},
|
|
625
|
+
}, m = "@rozenite/storage-plugin", j = [
|
|
150
626
|
"string",
|
|
151
627
|
"number",
|
|
152
628
|
"boolean",
|
|
153
629
|
"buffer"
|
|
154
|
-
],
|
|
155
|
-
listStorages:
|
|
630
|
+
], h = {
|
|
631
|
+
listStorages: b({
|
|
156
632
|
name: "list-storages",
|
|
157
|
-
description: "List all storage adapters and their storage nodes currently available on the device, including supported entry types
|
|
633
|
+
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.",
|
|
158
634
|
inputSchema: { type: "object", properties: {} }
|
|
159
635
|
}),
|
|
160
|
-
listEntries:
|
|
636
|
+
listEntries: Y({
|
|
161
637
|
name: "list-entries",
|
|
162
638
|
description: "List keys in a storage. This call intentionally does not return entry values to keep responses token-efficient.",
|
|
163
639
|
inputSchema: {
|
|
164
640
|
type: "object",
|
|
165
641
|
properties: {
|
|
166
|
-
...
|
|
167
|
-
|
|
642
|
+
...E,
|
|
643
|
+
limit: {
|
|
168
644
|
type: "number",
|
|
169
|
-
description: "Pagination
|
|
645
|
+
description: "Pagination size. Defaults to 20 and is capped at 100."
|
|
170
646
|
},
|
|
171
|
-
|
|
647
|
+
cursor: {
|
|
648
|
+
type: "string",
|
|
649
|
+
description: "Opaque pagination cursor from a previous list-entries call."
|
|
650
|
+
},
|
|
651
|
+
offset: {
|
|
172
652
|
type: "number",
|
|
173
|
-
description: "
|
|
653
|
+
description: "Deprecated initial pagination offset. Must be a non-negative integer and cannot be combined with cursor."
|
|
174
654
|
}
|
|
175
655
|
}
|
|
656
|
+
},
|
|
657
|
+
pagination: {
|
|
658
|
+
kind: "cursor",
|
|
659
|
+
fields: ["key"],
|
|
660
|
+
defaultFields: ["key"]
|
|
176
661
|
}
|
|
177
662
|
}),
|
|
178
|
-
readEntry:
|
|
663
|
+
readEntry: b({
|
|
179
664
|
name: "read-entry",
|
|
180
665
|
description: "Read a single storage entry value by key.",
|
|
181
666
|
inputSchema: {
|
|
182
667
|
type: "object",
|
|
183
668
|
properties: {
|
|
184
|
-
...
|
|
669
|
+
...E,
|
|
185
670
|
key: { type: "string", description: "Entry key." }
|
|
186
671
|
},
|
|
187
672
|
required: ["key"]
|
|
188
673
|
}
|
|
189
674
|
}),
|
|
190
|
-
createEntry:
|
|
675
|
+
createEntry: b({
|
|
191
676
|
name: "create-entry",
|
|
192
677
|
description: "Create a new storage entry. Fails if the key already exists.",
|
|
193
678
|
inputSchema: {
|
|
194
679
|
type: "object",
|
|
195
680
|
properties: {
|
|
196
|
-
...
|
|
681
|
+
...E,
|
|
197
682
|
key: { type: "string", description: "Entry key." },
|
|
198
683
|
type: {
|
|
199
684
|
type: "string",
|
|
200
|
-
enum: [
|
|
685
|
+
enum: [...j],
|
|
201
686
|
description: "Entry value type. Must be one of the supported types for the target storage (see list-storages)."
|
|
202
687
|
},
|
|
203
688
|
value: {
|
|
@@ -207,17 +692,17 @@ const x = async (t, e, r) => {
|
|
|
207
692
|
required: ["key", "type", "value"]
|
|
208
693
|
}
|
|
209
694
|
}),
|
|
210
|
-
editEntry:
|
|
695
|
+
editEntry: b({
|
|
211
696
|
name: "edit-entry",
|
|
212
697
|
description: "Edit an existing storage entry. Fails if the key does not exist.",
|
|
213
698
|
inputSchema: {
|
|
214
699
|
type: "object",
|
|
215
700
|
properties: {
|
|
216
|
-
...
|
|
701
|
+
...E,
|
|
217
702
|
key: { type: "string", description: "Entry key." },
|
|
218
703
|
type: {
|
|
219
704
|
type: "string",
|
|
220
|
-
enum: [
|
|
705
|
+
enum: [...j],
|
|
221
706
|
description: "Entry value type. Must be one of the supported types for the target storage (see list-storages)."
|
|
222
707
|
},
|
|
223
708
|
value: {
|
|
@@ -227,292 +712,326 @@ const x = async (t, e, r) => {
|
|
|
227
712
|
required: ["key", "type", "value"]
|
|
228
713
|
}
|
|
229
714
|
}),
|
|
230
|
-
removeEntry:
|
|
715
|
+
removeEntry: b({
|
|
231
716
|
name: "remove-entry",
|
|
232
717
|
description: "Remove a storage entry by key.",
|
|
233
718
|
inputSchema: {
|
|
234
719
|
type: "object",
|
|
235
720
|
properties: {
|
|
236
|
-
...
|
|
721
|
+
...E,
|
|
237
722
|
key: { type: "string", description: "Entry key." }
|
|
238
723
|
},
|
|
239
724
|
required: ["key"]
|
|
240
725
|
}
|
|
241
726
|
})
|
|
242
|
-
},
|
|
243
|
-
if (
|
|
244
|
-
if (typeof
|
|
727
|
+
}, F = (e, t) => {
|
|
728
|
+
if (e === "string") {
|
|
729
|
+
if (typeof t != "string")
|
|
245
730
|
throw new Error("Expected string value for type=string");
|
|
246
|
-
return
|
|
731
|
+
return t;
|
|
247
732
|
}
|
|
248
|
-
if (
|
|
249
|
-
if (typeof
|
|
733
|
+
if (e === "number") {
|
|
734
|
+
if (typeof t != "number" || Number.isNaN(t))
|
|
250
735
|
throw new Error("Expected number value for type=number");
|
|
251
|
-
return
|
|
736
|
+
return t;
|
|
252
737
|
}
|
|
253
|
-
if (
|
|
254
|
-
if (typeof
|
|
738
|
+
if (e === "boolean") {
|
|
739
|
+
if (typeof t != "boolean")
|
|
255
740
|
throw new Error("Expected boolean value for type=boolean");
|
|
256
|
-
return
|
|
741
|
+
return t;
|
|
257
742
|
}
|
|
258
|
-
if (!Array.isArray(
|
|
743
|
+
if (!Array.isArray(t) || !t.every((r) => Number.isInteger(r)))
|
|
259
744
|
throw new Error("Expected number[] value for type=buffer");
|
|
260
|
-
return
|
|
261
|
-
},
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
745
|
+
return t;
|
|
746
|
+
}, w = (e) => `${e.target.adapterId}/${e.target.storageId}`, Le = (e, t) => e.adapterId === t.adapterId && e.storageId === t.storageId, Ve = (e) => btoa(encodeURIComponent(JSON.stringify(e))), ze = (e) => {
|
|
747
|
+
try {
|
|
748
|
+
const t = JSON.parse(decodeURIComponent(atob(e)));
|
|
749
|
+
if (typeof t != "object" || t == null || Array.isArray(t) || t.version !== 1 || typeof t.target?.adapterId != "string" || typeof t.target?.storageId != "string" || !Number.isSafeInteger(t.offset) || t.offset < 0)
|
|
750
|
+
throw new Error("Invalid cursor");
|
|
751
|
+
return t;
|
|
752
|
+
} catch {
|
|
753
|
+
throw new Error(
|
|
754
|
+
"Invalid cursor. Run list-entries again without a cursor to restart pagination."
|
|
755
|
+
);
|
|
756
|
+
}
|
|
757
|
+
}, Ge = (e) => typeof e != "number" || !Number.isFinite(e) || !Number.isInteger(e) || e < 1 ? Q : Math.min(e, J), Be = (e) => typeof e != "number" || !Number.isFinite(e) || !Number.isSafeInteger(e) || e < 0 ? 0 : e, A = (e, t, r) => {
|
|
758
|
+
if (e.length === 0)
|
|
759
|
+
throw new Error("No storages are registered.");
|
|
760
|
+
if (t !== void 0 || r !== void 0) {
|
|
761
|
+
const o = e.filter(
|
|
762
|
+
(a) => (t === void 0 || a.target.adapterId === t) && (r === void 0 || a.target.storageId === r)
|
|
763
|
+
), n = [
|
|
764
|
+
t !== void 0 && `adapterId="${t}"`,
|
|
765
|
+
r !== void 0 && `storageId="${r}"`
|
|
766
|
+
].filter(Boolean).join(", ");
|
|
767
|
+
if (o.length === 0)
|
|
768
|
+
throw new Error(
|
|
769
|
+
`No storage matched ${n}. Available: ${e.map(w).join(", ")}`
|
|
770
|
+
);
|
|
771
|
+
if (o.length > 1)
|
|
772
|
+
throw new Error(
|
|
773
|
+
`Multiple storages matched ${n}. Provide both adapterId and storageId. Available: ${o.map(w).join(", ")}`
|
|
774
|
+
);
|
|
775
|
+
return o[0];
|
|
776
|
+
}
|
|
777
|
+
if (e.length > 1)
|
|
778
|
+
throw new Error(
|
|
779
|
+
`Multiple storages detected. Provide adapterId and/or storageId. Available: ${e.map(w).join(", ")}`
|
|
780
|
+
);
|
|
781
|
+
return e[0];
|
|
782
|
+
}, Ye = async (e, t) => {
|
|
783
|
+
const r = Ge(t.limit);
|
|
784
|
+
if (t.cursor !== void 0 && t.offset !== void 0)
|
|
785
|
+
throw new Error("Provide either cursor or offset, not both.");
|
|
786
|
+
const o = t.cursor === void 0 ? void 0 : ze(t.cursor);
|
|
787
|
+
if (o && !Le(o.target, e.target))
|
|
788
|
+
throw new Error(
|
|
789
|
+
"Cursor does not match the requested storage. Run list-entries again without a cursor to restart pagination."
|
|
790
|
+
);
|
|
791
|
+
const n = await e.getAllKeys(), a = o?.offset ?? Be(t.offset), i = Math.min(a + r, n.length);
|
|
792
|
+
return {
|
|
793
|
+
adapterId: e.target.adapterId,
|
|
794
|
+
storageId: e.target.storageId,
|
|
795
|
+
total: n.length,
|
|
796
|
+
items: n.slice(a, i).map((s) => ({ key: s })),
|
|
797
|
+
page: {
|
|
798
|
+
limit: r,
|
|
799
|
+
hasMore: i < n.length,
|
|
800
|
+
...i < n.length ? {
|
|
801
|
+
nextCursor: Ve({
|
|
802
|
+
version: 1,
|
|
803
|
+
target: e.target,
|
|
804
|
+
offset: i
|
|
805
|
+
})
|
|
806
|
+
} : {}
|
|
317
807
|
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
808
|
+
};
|
|
809
|
+
}, Qe = (e) => ({
|
|
810
|
+
listStorages: async () => ({
|
|
811
|
+
storages: e.map((t) => ({
|
|
812
|
+
adapterId: t.target.adapterId,
|
|
813
|
+
storageId: t.target.storageId,
|
|
814
|
+
adapterName: t.adapterName,
|
|
815
|
+
storageName: t.storageName,
|
|
816
|
+
supportedTypes: t.capabilities.supportedTypes
|
|
817
|
+
}))
|
|
818
|
+
}),
|
|
819
|
+
listEntries: async (t) => {
|
|
820
|
+
const r = A(e, t.adapterId, t.storageId);
|
|
821
|
+
return Ye(r, t);
|
|
822
|
+
},
|
|
823
|
+
readEntry: async ({
|
|
824
|
+
adapterId: t,
|
|
825
|
+
storageId: r,
|
|
826
|
+
key: o
|
|
827
|
+
}) => {
|
|
828
|
+
const n = A(e, t, r), a = await n.get(o);
|
|
829
|
+
if (!a)
|
|
830
|
+
throw new Error(`Key "${o}" not found in storage "${w(n)}".`);
|
|
831
|
+
return {
|
|
832
|
+
adapterId: n.target.adapterId,
|
|
833
|
+
storageId: n.target.storageId,
|
|
834
|
+
entry: a
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
}), Je = (e) => {
|
|
838
|
+
const t = Qe(e);
|
|
839
|
+
I({
|
|
840
|
+
pluginId: m,
|
|
841
|
+
tool: h.listStorages,
|
|
842
|
+
handler: t.listStorages
|
|
843
|
+
}), I({
|
|
844
|
+
pluginId: m,
|
|
845
|
+
tool: h.listEntries,
|
|
846
|
+
handler: t.listEntries
|
|
847
|
+
}), I({
|
|
848
|
+
pluginId: m,
|
|
849
|
+
tool: h.readEntry,
|
|
850
|
+
handler: t.readEntry
|
|
851
|
+
}), I({
|
|
852
|
+
pluginId: m,
|
|
853
|
+
tool: h.createEntry,
|
|
854
|
+
handler: async ({ adapterId: r, storageId: o, key: n, type: a, value: i }) => {
|
|
855
|
+
const s = A(e, r, o);
|
|
856
|
+
if (await s.get(n))
|
|
324
857
|
throw new Error(
|
|
325
|
-
`Key "${n}"
|
|
858
|
+
`Key "${n}" already exists in storage "${w(s)}". Use edit-entry instead.`
|
|
326
859
|
);
|
|
327
|
-
|
|
860
|
+
const d = F(a, i);
|
|
861
|
+
return await s.set({ key: n, type: a, value: d }), {
|
|
328
862
|
adapterId: s.target.adapterId,
|
|
329
863
|
storageId: s.target.storageId,
|
|
330
|
-
entry: i
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
}), p({
|
|
334
|
-
pluginId: u,
|
|
335
|
-
tool: y.createEntry,
|
|
336
|
-
handler: async ({ adapterId: r, storageId: o, key: n, type: s, value: i }) => {
|
|
337
|
-
const a = e(r, o);
|
|
338
|
-
if (await a.get(n))
|
|
339
|
-
throw new Error(
|
|
340
|
-
`Key "${n}" already exists in storage "${h(a)}". Use edit-entry instead.`
|
|
341
|
-
);
|
|
342
|
-
const d = k(s, i);
|
|
343
|
-
return await a.set({ key: n, type: s, value: d }), {
|
|
344
|
-
adapterId: a.target.adapterId,
|
|
345
|
-
storageId: a.target.storageId,
|
|
346
864
|
created: !0,
|
|
347
865
|
key: n
|
|
348
866
|
};
|
|
349
867
|
}
|
|
350
|
-
}),
|
|
351
|
-
pluginId:
|
|
352
|
-
tool:
|
|
353
|
-
handler: async ({ adapterId: r, storageId: o, key: n, type:
|
|
354
|
-
const
|
|
355
|
-
if (!await
|
|
868
|
+
}), I({
|
|
869
|
+
pluginId: m,
|
|
870
|
+
tool: h.editEntry,
|
|
871
|
+
handler: async ({ adapterId: r, storageId: o, key: n, type: a, value: i }) => {
|
|
872
|
+
const s = A(e, r, o);
|
|
873
|
+
if (!await s.get(n))
|
|
356
874
|
throw new Error(
|
|
357
|
-
`Key "${n}" not found in storage "${
|
|
875
|
+
`Key "${n}" not found in storage "${w(s)}". Use create-entry instead.`
|
|
358
876
|
);
|
|
359
|
-
const d =
|
|
360
|
-
return await
|
|
361
|
-
adapterId:
|
|
362
|
-
storageId:
|
|
877
|
+
const d = F(a, i);
|
|
878
|
+
return await s.set({ key: n, type: a, value: d }), {
|
|
879
|
+
adapterId: s.target.adapterId,
|
|
880
|
+
storageId: s.target.storageId,
|
|
363
881
|
edited: !0,
|
|
364
882
|
key: n
|
|
365
883
|
};
|
|
366
884
|
}
|
|
367
|
-
}),
|
|
368
|
-
pluginId:
|
|
369
|
-
tool:
|
|
885
|
+
}), I({
|
|
886
|
+
pluginId: m,
|
|
887
|
+
tool: h.removeEntry,
|
|
370
888
|
handler: async ({ adapterId: r, storageId: o, key: n }) => {
|
|
371
|
-
const
|
|
372
|
-
return await
|
|
373
|
-
adapterId:
|
|
374
|
-
storageId:
|
|
889
|
+
const a = A(e, r, o), i = !!await a.get(n);
|
|
890
|
+
return await a.delete(n), {
|
|
891
|
+
adapterId: a.target.adapterId,
|
|
892
|
+
storageId: a.target.storageId,
|
|
375
893
|
removed: i,
|
|
376
894
|
key: n
|
|
377
895
|
};
|
|
378
896
|
}
|
|
379
897
|
});
|
|
380
|
-
},
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const
|
|
384
|
-
L(e);
|
|
385
|
-
const r = v({
|
|
898
|
+
}, tt = ({ storages: e }) => {
|
|
899
|
+
const t = z(() => Ue(e), [e]);
|
|
900
|
+
Je(t);
|
|
901
|
+
const r = V({
|
|
386
902
|
pluginId: "@rozenite/storage-plugin"
|
|
387
903
|
});
|
|
388
|
-
return
|
|
904
|
+
return G(() => {
|
|
389
905
|
if (!r)
|
|
390
906
|
return;
|
|
391
|
-
const o =
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
});
|
|
405
|
-
} catch (c) {
|
|
406
|
-
console.warn(
|
|
407
|
-
`[Rozenite] Storage Plugin: Failed to snapshot ${d.target.adapterId}/${d.target.storageId}.`,
|
|
408
|
-
c
|
|
409
|
-
);
|
|
410
|
-
}
|
|
907
|
+
const o = [];
|
|
908
|
+
let n = !1;
|
|
909
|
+
const a = async (s, c, d) => {
|
|
910
|
+
const g = t.find(
|
|
911
|
+
(l) => l.target.adapterId === s.adapterId && l.target.storageId === s.storageId
|
|
912
|
+
), u = g ? (await g.getAllKeys()).length : 0;
|
|
913
|
+
r.send("storage-invalidated", {
|
|
914
|
+
type: "storage-invalidated",
|
|
915
|
+
target: s,
|
|
916
|
+
key: c,
|
|
917
|
+
operation: d,
|
|
918
|
+
entryCount: u
|
|
919
|
+
});
|
|
411
920
|
};
|
|
412
|
-
o();
|
|
413
|
-
const n = [];
|
|
414
|
-
let s = !1;
|
|
415
921
|
Promise.all(
|
|
416
|
-
|
|
922
|
+
t.filter((s) => s.supportsSubscriptions && s.watch).map(async (s) => {
|
|
417
923
|
try {
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
entry: d
|
|
424
|
-
});
|
|
425
|
-
},
|
|
426
|
-
onDelete: (d) => {
|
|
427
|
-
r.send("delete-entry", {
|
|
428
|
-
type: "delete-entry",
|
|
429
|
-
target: a.target,
|
|
430
|
-
key: d
|
|
431
|
-
});
|
|
432
|
-
}
|
|
924
|
+
const c = s.watch;
|
|
925
|
+
if (!c)
|
|
926
|
+
return;
|
|
927
|
+
const d = await c((g) => {
|
|
928
|
+
a(s.target, g);
|
|
433
929
|
});
|
|
434
|
-
if (
|
|
435
|
-
|
|
930
|
+
if (n) {
|
|
931
|
+
d.remove();
|
|
436
932
|
return;
|
|
437
933
|
}
|
|
438
|
-
|
|
439
|
-
} catch (
|
|
934
|
+
o.push(d);
|
|
935
|
+
} catch (c) {
|
|
440
936
|
console.warn(
|
|
441
|
-
`[Rozenite] Storage Plugin: Failed to attach watcher for ${
|
|
442
|
-
|
|
937
|
+
`[Rozenite] Storage Plugin: Failed to attach watcher for ${s.target.adapterId}/${s.target.storageId}.`,
|
|
938
|
+
c
|
|
443
939
|
);
|
|
444
940
|
}
|
|
445
941
|
})
|
|
446
942
|
);
|
|
447
943
|
const i = [
|
|
448
|
-
r.onMessage(
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
944
|
+
r.onMessage("set-entry", async ({ target: s, entry: c }) => {
|
|
945
|
+
const d = t.find(
|
|
946
|
+
(g) => g.target.adapterId === s.adapterId && g.target.storageId === s.storageId
|
|
947
|
+
);
|
|
948
|
+
if (!d) {
|
|
949
|
+
console.warn(
|
|
950
|
+
`[Rozenite] Storage Plugin: Storage target not found for ${s.adapterId}/${s.storageId}`
|
|
453
951
|
);
|
|
454
|
-
|
|
455
|
-
console.warn(
|
|
456
|
-
`[Rozenite] Storage Plugin: Storage target not found for ${a.adapterId}/${a.storageId}`
|
|
457
|
-
);
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
try {
|
|
461
|
-
await d.set(l);
|
|
462
|
-
} catch (c) {
|
|
463
|
-
console.warn(
|
|
464
|
-
`[Rozenite] Storage Plugin: Failed to set entry in ${a.adapterId}/${a.storageId}.`,
|
|
465
|
-
c
|
|
466
|
-
);
|
|
467
|
-
}
|
|
952
|
+
return;
|
|
468
953
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
954
|
+
try {
|
|
955
|
+
await d.set(c), await a(d.target, c.key, "set");
|
|
956
|
+
} catch (g) {
|
|
957
|
+
console.warn(
|
|
958
|
+
`[Rozenite] Storage Plugin: Failed to set entry in ${s.adapterId}/${s.storageId}.`,
|
|
959
|
+
g
|
|
475
960
|
);
|
|
476
|
-
if (!d) {
|
|
477
|
-
console.warn(
|
|
478
|
-
`[Rozenite] Storage Plugin: Storage target not found for ${a.adapterId}/${a.storageId}`
|
|
479
|
-
);
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
try {
|
|
483
|
-
await d.delete(l);
|
|
484
|
-
} catch (c) {
|
|
485
|
-
console.warn(
|
|
486
|
-
`[Rozenite] Storage Plugin: Failed to delete entry in ${a.adapterId}/${a.storageId}.`,
|
|
487
|
-
c
|
|
488
|
-
);
|
|
489
|
-
}
|
|
490
961
|
}
|
|
491
|
-
),
|
|
492
|
-
r.onMessage(
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
962
|
+
}),
|
|
963
|
+
r.onMessage("delete-entry", async ({ target: s, key: c }) => {
|
|
964
|
+
const d = t.find(
|
|
965
|
+
(g) => g.target.adapterId === s.adapterId && g.target.storageId === s.storageId
|
|
966
|
+
);
|
|
967
|
+
if (!d) {
|
|
968
|
+
console.warn(
|
|
969
|
+
`[Rozenite] Storage Plugin: Storage target not found for ${s.adapterId}/${s.storageId}`
|
|
970
|
+
);
|
|
971
|
+
return;
|
|
500
972
|
}
|
|
501
|
-
|
|
973
|
+
try {
|
|
974
|
+
await d.delete(c), await a(d.target, c, "delete");
|
|
975
|
+
} catch (g) {
|
|
976
|
+
console.warn(
|
|
977
|
+
`[Rozenite] Storage Plugin: Failed to delete entry in ${s.adapterId}/${s.storageId}.`,
|
|
978
|
+
g
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
}),
|
|
982
|
+
r.onMessage("purge-storage", async ({ target: s }) => {
|
|
983
|
+
const c = t.find(
|
|
984
|
+
(d) => d.target.adapterId === s.adapterId && d.target.storageId === s.storageId
|
|
985
|
+
);
|
|
986
|
+
if (!c) {
|
|
987
|
+
console.warn(
|
|
988
|
+
`[Rozenite] Storage Plugin: Storage target not found for ${s.adapterId}/${s.storageId}`
|
|
989
|
+
);
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
try {
|
|
993
|
+
await c.purge(), await a(c.target, void 0, "purge");
|
|
994
|
+
} catch (d) {
|
|
995
|
+
console.warn(
|
|
996
|
+
`[Rozenite] Storage Plugin: Failed to purge storage in ${s.adapterId}/${s.storageId}.`,
|
|
997
|
+
d
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
}),
|
|
1001
|
+
r.onMessage("discover-storages", async (s) => {
|
|
1002
|
+
const c = await ue(t, s);
|
|
1003
|
+
r.send(c.type, c);
|
|
1004
|
+
}),
|
|
502
1005
|
r.onMessage(
|
|
503
|
-
"
|
|
504
|
-
async (
|
|
505
|
-
await
|
|
506
|
-
|
|
507
|
-
});
|
|
1006
|
+
"list-entry-previews",
|
|
1007
|
+
async (s) => {
|
|
1008
|
+
const c = await ve(t, s);
|
|
1009
|
+
r.send(c.type, c);
|
|
508
1010
|
}
|
|
509
|
-
)
|
|
1011
|
+
),
|
|
1012
|
+
r.onMessage("get-entry", async (s) => {
|
|
1013
|
+
const c = await ke(t, s);
|
|
1014
|
+
r.send(c.type, c);
|
|
1015
|
+
}),
|
|
1016
|
+
r.onMessage("export-snapshot", async (s) => {
|
|
1017
|
+
const c = await je(t, s);
|
|
1018
|
+
r.send(c.type, c);
|
|
1019
|
+
}),
|
|
1020
|
+
r.onMessage("preview-import", async (s) => {
|
|
1021
|
+
const c = await ae(t, s);
|
|
1022
|
+
r.send(c.type, c);
|
|
1023
|
+
}),
|
|
1024
|
+
r.onMessage("import-entries", async (s) => {
|
|
1025
|
+
await ie(t, s, (c) => {
|
|
1026
|
+
r.send(c.type, c);
|
|
1027
|
+
});
|
|
1028
|
+
})
|
|
510
1029
|
];
|
|
511
|
-
return () => {
|
|
512
|
-
|
|
1030
|
+
return r.send("device-ready", { type: "device-ready" }), () => {
|
|
1031
|
+
n = !0, o.forEach((s) => s.remove()), i.forEach((s) => s.remove());
|
|
513
1032
|
};
|
|
514
|
-
}, [r,
|
|
1033
|
+
}, [r, t]), r;
|
|
515
1034
|
};
|
|
516
1035
|
export {
|
|
517
|
-
|
|
1036
|
+
tt as useRozeniteStoragePlugin
|
|
518
1037
|
};
|