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