@avasapp/agent-bridge 0.4.2 → 0.6.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/README.md +36 -14
- package/dist/adapters/ably.cjs +79 -3
- package/dist/adapters/ably.d.cts +2 -1
- package/dist/adapters/async-storage.cjs +158 -0
- package/dist/adapters/async-storage.d.cts +14 -0
- package/dist/adapters/device.cjs +1110 -0
- package/dist/adapters/device.d.cts +49 -0
- package/dist/adapters/expo-router.cjs +112 -6
- package/dist/adapters/expo-router.d.cts +1 -1
- package/dist/adapters/jotai.cjs +266 -0
- package/dist/adapters/jotai.d.cts +19 -0
- package/dist/adapters/react-native-mmkv.cjs +80 -0
- package/dist/adapters/react-native-mmkv.d.cts +3 -1
- package/dist/adapters/react-native-webview.d.cts +1 -1
- package/dist/adapters/react-navigation.cjs +293 -0
- package/dist/adapters/react-navigation.d.cts +55 -0
- package/dist/adapters/redux.cjs +322 -0
- package/dist/adapters/redux.d.cts +28 -0
- package/dist/adapters/secure-store.cjs +169 -0
- package/dist/adapters/secure-store.d.cts +28 -0
- package/dist/adapters/socket-io.cjs +77 -3
- package/dist/adapters/socket-io.d.cts +2 -1
- package/dist/adapters/tanstack-query.cjs +3 -0
- package/dist/adapters/tanstack-query.d.cts +13 -4
- package/dist/adapters/zustand.cjs +193 -22
- package/dist/adapters/zustand.d.cts +11 -15
- package/dist/{chunk-TA2OLPPT.js → chunk-Y6QFU5ON.js} +477 -165
- package/dist/cli.js +2370 -103
- package/dist/client/index.cjs +441 -136
- package/dist/client/index.d.ts +67 -4
- package/dist/client/index.js +5 -3
- package/dist/expo/index.d.cts +1 -1
- package/dist/network/index.cjs +320 -73
- package/dist/network/index.d.cts +18 -3
- package/dist/noop/async-storage.cjs +26 -0
- package/dist/noop/device.cjs +26 -0
- package/dist/noop/jotai.cjs +26 -0
- package/dist/noop/react-navigation.cjs +26 -0
- package/dist/noop/realtime.cjs +6 -1
- package/dist/noop/redux.cjs +28 -0
- package/dist/noop/secure-store.cjs +26 -0
- package/dist/realtime/index.cjs +71 -4
- package/dist/realtime/index.d.cts +21 -2
- package/dist/runtime/index.cjs +838 -128
- package/dist/runtime/index.d.cts +4 -2
- package/dist/store-common-j0cHHvBr.d.cts +23 -0
- package/dist/{types-BmpykP1P.d.cts → types-qlwdcGjt.d.cts} +22 -0
- package/entries/async-storage.cjs +9 -0
- package/entries/device.cjs +9 -0
- package/entries/jotai.cjs +9 -0
- package/entries/react-navigation.cjs +9 -0
- package/entries/redux.cjs +9 -0
- package/entries/secure-store.cjs +9 -0
- package/package.json +34 -2
- package/skills/agent-bridge/SKILL.md +70 -22
- package/skills/agent-bridge/references/device.md +21 -0
- package/skills/agent-bridge/references/flows.md +19 -8
- package/skills/agent-bridge/references/large-data.md +6 -6
- package/skills/agent-bridge/references/network.md +25 -7
- package/skills/agent-bridge/references/realtime.md +5 -5
- package/skills/agent-bridge/references/restore.md +25 -7
- package/skills/agent-bridge/references/screen.md +25 -11
- package/skills/agent-bridge/references/state.md +31 -11
- package/skills/agent-bridge/references/webview.md +9 -9
- package/skills/agent-bridge/references/writing-scenarios.md +3 -3
|
@@ -43,8 +43,7 @@ function toJson(value) {
|
|
|
43
43
|
return text === void 0 ? null : JSON.parse(text);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
// src/adapters/
|
|
47
|
-
var snapshots = /* @__PURE__ */ new WeakMap();
|
|
46
|
+
// src/adapters/store-common.ts
|
|
48
47
|
var isObject = (value) => typeof value === "object" && value !== null;
|
|
49
48
|
function toPath(part) {
|
|
50
49
|
if (typeof part === "string") return part === "" ? [] : part.split(".");
|
|
@@ -52,7 +51,7 @@ function toPath(part) {
|
|
|
52
51
|
if (Array.isArray(part) && part.every((p) => typeof p === "string" || typeof p === "number"))
|
|
53
52
|
return part;
|
|
54
53
|
throw new Error(
|
|
55
|
-
`A
|
|
54
|
+
`A path is a dotted string or an array of segments, got ${JSON.stringify(part)}`
|
|
56
55
|
);
|
|
57
56
|
}
|
|
58
57
|
function at(value, path) {
|
|
@@ -62,7 +61,7 @@ function at(value, path) {
|
|
|
62
61
|
);
|
|
63
62
|
}
|
|
64
63
|
var kindOf = (v) => v === null ? "null" : Array.isArray(v) ? "array" : typeof v;
|
|
65
|
-
function readState(state, given) {
|
|
64
|
+
function readState(state, given, tool = "store.get") {
|
|
66
65
|
const args = given.filter((a) => a != null);
|
|
67
66
|
const last = args.at(-1);
|
|
68
67
|
const isOptions = isObject(last) && !Array.isArray(last);
|
|
@@ -70,12 +69,12 @@ function readState(state, given) {
|
|
|
70
69
|
const unknown = Object.keys(options).filter((k) => k !== "pick" && k !== "keys");
|
|
71
70
|
if (unknown.length)
|
|
72
71
|
throw new Error(
|
|
73
|
-
`Unknown
|
|
72
|
+
`Unknown ${tool} option ${unknown.map((k) => `"${k}"`).join(", ")}. Options: pick, keys`
|
|
74
73
|
);
|
|
75
74
|
const value = at(state, (isOptions ? args.slice(0, -1) : args).flatMap(toPath));
|
|
76
75
|
if (options.pick !== void 0) {
|
|
77
76
|
if (!Array.isArray(options.pick))
|
|
78
|
-
throw new Error(
|
|
77
|
+
throw new Error(`${tool} pick is an array of paths`);
|
|
79
78
|
return Object.fromEntries(
|
|
80
79
|
options.pick.map((p) => [
|
|
81
80
|
Array.isArray(p) ? p.join(".") : String(p),
|
|
@@ -87,17 +86,6 @@ function readState(state, given) {
|
|
|
87
86
|
return isObject(value) ? Object.fromEntries(Object.entries(value).map(([k, v]) => [k, kindOf(v)])) : kindOf(value);
|
|
88
87
|
return value;
|
|
89
88
|
}
|
|
90
|
-
function restore(store, snapshot) {
|
|
91
|
-
const current = store.getState();
|
|
92
|
-
if (!isObject(snapshot) || !isObject(current)) {
|
|
93
|
-
store.setState(snapshot, true);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const actions = Object.fromEntries(
|
|
97
|
-
Object.entries(current).filter(([, v]) => typeof v === "function")
|
|
98
|
-
);
|
|
99
|
-
store.setState({ ...snapshot, ...actions }, true);
|
|
100
|
-
}
|
|
101
89
|
var PREVIEW = 200;
|
|
102
90
|
function preview(value) {
|
|
103
91
|
try {
|
|
@@ -109,10 +97,11 @@ function preview(value) {
|
|
|
109
97
|
return "[unserializable]";
|
|
110
98
|
}
|
|
111
99
|
}
|
|
112
|
-
function differences(snapshot, current, show) {
|
|
100
|
+
function differences(snapshot, current, show, only) {
|
|
113
101
|
if (!isObject(snapshot) || !isObject(current)) return {};
|
|
114
102
|
const out = {};
|
|
115
103
|
for (const k of /* @__PURE__ */ new Set([...Object.keys(snapshot), ...Object.keys(current)])) {
|
|
104
|
+
if (only && !only.has(k)) continue;
|
|
116
105
|
const a = snapshot[k];
|
|
117
106
|
const b = current[k];
|
|
118
107
|
if (typeof a === "function" || typeof b === "function") continue;
|
|
@@ -137,6 +126,79 @@ function redactValue(redact, name, value, path, seen = []) {
|
|
|
137
126
|
]);
|
|
138
127
|
return Array.isArray(value) ? entries.map(([, v]) => v) : Object.fromEntries(entries);
|
|
139
128
|
}
|
|
129
|
+
|
|
130
|
+
// src/adapters/zustand.ts
|
|
131
|
+
var HYDRATION_WAIT_MS = 2e3;
|
|
132
|
+
var rev = 0;
|
|
133
|
+
function survivesJson(v, depth = 0) {
|
|
134
|
+
if (v === null || typeof v === "string" || typeof v === "boolean") return true;
|
|
135
|
+
if (typeof v === "number") return Number.isFinite(v);
|
|
136
|
+
if (depth > 50 || !isObject(v)) return false;
|
|
137
|
+
if (Array.isArray(v)) return v.every((x) => survivesJson(x, depth + 1));
|
|
138
|
+
const proto = Object.getPrototypeOf(v);
|
|
139
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
140
|
+
return Object.values(v).every((x) => x === void 0 || survivesJson(x, depth + 1));
|
|
141
|
+
}
|
|
142
|
+
var ok = (v) => v === void 0 || survivesJson(v);
|
|
143
|
+
var has = (x, k) => x[k] !== void 0;
|
|
144
|
+
function persisted(store, state) {
|
|
145
|
+
try {
|
|
146
|
+
const partialize = store.persist?.getOptions?.().partialize;
|
|
147
|
+
const part = partialize ? partialize(state) : state;
|
|
148
|
+
if (!isObject(part) || Array.isArray(part)) return void 0;
|
|
149
|
+
const raw = Object.fromEntries(Object.entries(part).filter(([, v]) => typeof v !== "function"));
|
|
150
|
+
const refused = /* @__PURE__ */ new Set();
|
|
151
|
+
if (partialize && isObject(state)) {
|
|
152
|
+
for (const [k, v] of Object.entries(raw)) if (!(k in state) || !Object.is(state[k], v)) refused.add(k);
|
|
153
|
+
}
|
|
154
|
+
return { raw, refused };
|
|
155
|
+
} catch {
|
|
156
|
+
return void 0;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
var differs = (a, b) => ok(a) && ok(b) ? !same(a, b) : !Object.is(a, b);
|
|
160
|
+
var json = (v) => JSON.parse(JSON.stringify(v));
|
|
161
|
+
var same = (a, b) => {
|
|
162
|
+
if (Object.is(a, b)) return true;
|
|
163
|
+
if (!isObject(a) || !isObject(b) || Array.isArray(a) !== Array.isArray(b)) return false;
|
|
164
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
165
|
+
return [...keys].every((k) => same(a[k], b[k]));
|
|
166
|
+
};
|
|
167
|
+
async function hydrated(store) {
|
|
168
|
+
const p = store.persist;
|
|
169
|
+
if (!p?.hasHydrated || p.hasHydrated()) return true;
|
|
170
|
+
return new Promise((resolve) => {
|
|
171
|
+
const off = p.onFinishHydration?.(() => finish(true));
|
|
172
|
+
const timer = setTimeout(() => finish(false), HYDRATION_WAIT_MS);
|
|
173
|
+
function finish(ok2) {
|
|
174
|
+
clearTimeout(timer);
|
|
175
|
+
off?.();
|
|
176
|
+
resolve(ok2);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
var snapshots = /* @__PURE__ */ new WeakMap();
|
|
181
|
+
var adoptedKeys = /* @__PURE__ */ new WeakMap();
|
|
182
|
+
function restore(store, snapshot, only) {
|
|
183
|
+
const current = store.getState();
|
|
184
|
+
if (only && isObject(snapshot) && isObject(current)) {
|
|
185
|
+
const next = { ...current };
|
|
186
|
+
for (const k of only) {
|
|
187
|
+
if (k in snapshot) next[k] = snapshot[k];
|
|
188
|
+
else delete next[k];
|
|
189
|
+
}
|
|
190
|
+
store.setState(next, true);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (!isObject(snapshot) || !isObject(current)) {
|
|
194
|
+
store.setState(snapshot, true);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const actions = Object.fromEntries(
|
|
198
|
+
Object.entries(current).filter(([, v]) => typeof v === "function")
|
|
199
|
+
);
|
|
200
|
+
store.setState({ ...snapshot, ...actions }, true);
|
|
201
|
+
}
|
|
140
202
|
function storeTools(stores, options = {}) {
|
|
141
203
|
const out = (name, value, path = "") => redactValue(options.redact, name, value, path);
|
|
142
204
|
const get = (name) => {
|
|
@@ -147,8 +209,26 @@ function storeTools(stores, options = {}) {
|
|
|
147
209
|
);
|
|
148
210
|
return store;
|
|
149
211
|
};
|
|
212
|
+
const hidden = (name, k, ...values) => {
|
|
213
|
+
const { redact } = options;
|
|
214
|
+
if (!redact) return false;
|
|
215
|
+
if (typeof redact !== "function")
|
|
216
|
+
return !!redact[name]?.some((p) => p === k || p.startsWith(`${k}.`) || k.startsWith(`${p}.`));
|
|
217
|
+
return values.some((v) => !same(redactValue(redact, name, v, k), v));
|
|
218
|
+
};
|
|
150
219
|
const beforeChange = (store) => {
|
|
151
|
-
|
|
220
|
+
rev += 1;
|
|
221
|
+
const only = adoptedKeys.get(store);
|
|
222
|
+
if (only) {
|
|
223
|
+
const next = { ...store.getState() };
|
|
224
|
+
const saved = snapshots.get(store);
|
|
225
|
+
for (const k of only) {
|
|
226
|
+
if (k in saved) next[k] = saved[k];
|
|
227
|
+
else delete next[k];
|
|
228
|
+
}
|
|
229
|
+
snapshots.set(store, next);
|
|
230
|
+
adoptedKeys.delete(store);
|
|
231
|
+
} else if (!snapshots.has(store)) snapshots.set(store, store.getState());
|
|
152
232
|
};
|
|
153
233
|
return {
|
|
154
234
|
"store.list": {
|
|
@@ -183,7 +263,12 @@ function storeTools(stores, options = {}) {
|
|
|
183
263
|
throw new Error(`Store "${name}" has no action "${action}"`);
|
|
184
264
|
beforeChange(store);
|
|
185
265
|
const before = store.getState();
|
|
186
|
-
|
|
266
|
+
let result;
|
|
267
|
+
try {
|
|
268
|
+
result = await fn(...args);
|
|
269
|
+
} finally {
|
|
270
|
+
rev += 1;
|
|
271
|
+
}
|
|
187
272
|
const after = store.getState();
|
|
188
273
|
if (result !== void 0 && result !== before && result !== after) {
|
|
189
274
|
const key = isObject(after) ? Object.keys(after).find((k) => after[k] === result) : void 0;
|
|
@@ -203,6 +288,8 @@ function storeTools(stores, options = {}) {
|
|
|
203
288
|
description: "Keep a store as it is now: drops its pending snapshot, so bridge.restore leaves it alone and the next store.set or store.call snapshots again from this state. Use it after repairing a value that was already wrong when the snapshot was taken. Returns { store, committed } (committed: false when nothing was pending).",
|
|
204
289
|
run: (name) => {
|
|
205
290
|
const store = get(name);
|
|
291
|
+
rev += 1;
|
|
292
|
+
adoptedKeys.delete(store);
|
|
206
293
|
return { store: name, committed: snapshots.delete(store) };
|
|
207
294
|
}
|
|
208
295
|
},
|
|
@@ -210,6 +297,87 @@ function storeTools(stores, options = {}) {
|
|
|
210
297
|
maxArgs: 0,
|
|
211
298
|
// Per store, its snapshot against now (secrets redacted), so an agent can
|
|
212
299
|
// tell what a restore will put back before it does.
|
|
300
|
+
journalRev: () => rev,
|
|
301
|
+
// Persisted stores only: others are rebuilt from scratch on reload.
|
|
302
|
+
journal: () => {
|
|
303
|
+
const out2 = {};
|
|
304
|
+
for (const [name, store] of Object.entries(stores)) {
|
|
305
|
+
if (!store.persist || !snapshots.has(store)) continue;
|
|
306
|
+
const before = persisted(store, snapshots.get(store));
|
|
307
|
+
const now = persisted(store, store.getState());
|
|
308
|
+
if (!before || !now) continue;
|
|
309
|
+
const entry = { original: {}, after: {} };
|
|
310
|
+
const skipped = [];
|
|
311
|
+
const only = adoptedKeys.get(store);
|
|
312
|
+
for (const k of /* @__PURE__ */ new Set([...Object.keys(before.raw), ...Object.keys(now.raw)])) {
|
|
313
|
+
if (only && !only.has(k)) continue;
|
|
314
|
+
const a = before.raw[k];
|
|
315
|
+
const b = now.raw[k];
|
|
316
|
+
if (!differs(a, b)) continue;
|
|
317
|
+
if (before.refused.has(k) || now.refused.has(k) || !ok(a) || !ok(b) || hidden(name, k, a, b)) {
|
|
318
|
+
skipped.push(k);
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (has(before.raw, k)) entry.original[k] = json(a);
|
|
322
|
+
if (has(now.raw, k)) entry.after[k] = json(b);
|
|
323
|
+
}
|
|
324
|
+
if (skipped.length) entry.skipped = skipped;
|
|
325
|
+
if (skipped.length || Object.keys(entry.original).length || Object.keys(entry.after).length) out2[name] = entry;
|
|
326
|
+
}
|
|
327
|
+
return Object.keys(out2).length ? out2 : void 0;
|
|
328
|
+
},
|
|
329
|
+
adopt: async (raw) => {
|
|
330
|
+
const data = isObject(raw) && !Array.isArray(raw) ? raw : {};
|
|
331
|
+
const result = { adopted: [], already: [], changed: [] };
|
|
332
|
+
const retry = {};
|
|
333
|
+
const ready = await Promise.all(
|
|
334
|
+
Object.keys(data).map((n) => stores[n] ? hydrated(stores[n]) : false)
|
|
335
|
+
);
|
|
336
|
+
const names = Object.keys(data);
|
|
337
|
+
for (const [name, entry] of Object.entries(data)) {
|
|
338
|
+
const store = stores[name];
|
|
339
|
+
const skipped = entry?.skipped;
|
|
340
|
+
if (!isObject(entry) || !isObject(entry.original) || !isObject(entry.after) || skipped !== void 0 && !(Array.isArray(skipped) && skipped.every((k) => typeof k === "string"))) {
|
|
341
|
+
(result.invalid ?? (result.invalid = [])).push(name);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (!store || !ready[names.indexOf(name)]) {
|
|
345
|
+
retry[name] = entry;
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
for (const k of skipped ?? []) (result.notKept ?? (result.notKept = [])).push(`${name}:${k}`);
|
|
349
|
+
const now = persisted(store, store.getState());
|
|
350
|
+
const saved = snapshots.has(store) && !adoptedKeys.has(store) ? persisted(store, snapshots.get(store)) : void 0;
|
|
351
|
+
const eq = (x, y, k) => has(x, k) === has(y, k) && (!has(x, k) || same(x[k], y[k]));
|
|
352
|
+
const back = [];
|
|
353
|
+
for (const k of /* @__PURE__ */ new Set([...Object.keys(entry.original), ...Object.keys(entry.after)])) {
|
|
354
|
+
const label = `${name}:${k}`;
|
|
355
|
+
if (!now || now.refused.has(k) || !ok(now.raw[k])) {
|
|
356
|
+
(result.notKept ?? (result.notKept = [])).push(label);
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
const savedFake = !!saved && ok(saved.raw[k]) && eq(saved.raw, entry.after, k);
|
|
360
|
+
if (!savedFake && eq(now.raw, entry.original, k)) result.already.push(label);
|
|
361
|
+
else if (savedFake || eq(now.raw, entry.after, k)) {
|
|
362
|
+
back.push(k);
|
|
363
|
+
result.adopted.push(label);
|
|
364
|
+
} else result.changed.push(label);
|
|
365
|
+
}
|
|
366
|
+
if (back.length) {
|
|
367
|
+
if (!snapshots.has(store)) adoptedKeys.set(store, /* @__PURE__ */ new Set());
|
|
368
|
+
const next = { ...snapshots.get(store) ?? store.getState() };
|
|
369
|
+
for (const k of back) {
|
|
370
|
+
if (k in entry.original) next[k] = entry.original[k];
|
|
371
|
+
else delete next[k];
|
|
372
|
+
adoptedKeys.get(store)?.add(k);
|
|
373
|
+
}
|
|
374
|
+
snapshots.set(store, next);
|
|
375
|
+
rev += 1;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
if (Object.keys(retry).length) result.retry = retry;
|
|
379
|
+
return result;
|
|
380
|
+
},
|
|
213
381
|
pending: ({ detail } = {}) => {
|
|
214
382
|
const changed = Object.entries(stores).filter(([, s]) => snapshots.has(s));
|
|
215
383
|
if (!changed.length) return false;
|
|
@@ -220,7 +388,8 @@ function storeTools(stores, options = {}) {
|
|
|
220
388
|
differences(
|
|
221
389
|
snapshots.get(store),
|
|
222
390
|
store.getState(),
|
|
223
|
-
(key, value) => out(name, value, key)
|
|
391
|
+
(key, value) => out(name, value, key),
|
|
392
|
+
adoptedKeys.get(store)
|
|
224
393
|
)
|
|
225
394
|
])
|
|
226
395
|
);
|
|
@@ -228,8 +397,10 @@ function storeTools(stores, options = {}) {
|
|
|
228
397
|
description: "Undo the agent: put back each store changed with store.set or store.call, to its state at the first of those (store.commit drops a snapshot). Returns their names.",
|
|
229
398
|
run: () => Object.entries(stores).flatMap(([name, store]) => {
|
|
230
399
|
if (!snapshots.has(store)) return [];
|
|
231
|
-
|
|
400
|
+
rev += 1;
|
|
401
|
+
restore(store, snapshots.get(store), adoptedKeys.get(store));
|
|
232
402
|
snapshots.delete(store);
|
|
403
|
+
adoptedKeys.delete(store);
|
|
233
404
|
return [name];
|
|
234
405
|
})
|
|
235
406
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { T as Tools } from '../types-
|
|
1
|
+
import { T as Tools } from '../types-qlwdcGjt.cjs';
|
|
2
|
+
import { R as Redact } from '../store-common-j0cHHvBr.cjs';
|
|
2
3
|
|
|
3
4
|
/** Anything with zustand's store shape. */
|
|
4
5
|
type StoreLike = {
|
|
@@ -8,24 +9,19 @@ type StoreLike = {
|
|
|
8
9
|
* syntax, so zustand's overloads (replace: false | true) still fit.
|
|
9
10
|
*/
|
|
10
11
|
setState(partial: Record<string, unknown>, replace?: boolean): void;
|
|
12
|
+
/** Present on stores made with zustand's `persist` middleware. */
|
|
13
|
+
persist?: {
|
|
14
|
+
getOptions?: () => {
|
|
15
|
+
partialize?: (state: never) => unknown;
|
|
16
|
+
};
|
|
17
|
+
hasHydrated?: () => boolean;
|
|
18
|
+
onFinishHydration?: (fn: () => void) => () => void;
|
|
19
|
+
};
|
|
11
20
|
};
|
|
12
|
-
/**
|
|
13
|
-
* Keeps secrets out of what store.* prints. Either dotted paths per store
|
|
14
|
-
* (`{ auth: ['accessToken', 'user.phone'] }`), or a hook called for the store
|
|
15
|
-
* value and every nested value with its dotted path; what it returns is
|
|
16
|
-
* printed instead.
|
|
17
|
-
*
|
|
18
|
-
* Paths are store paths. A `store.call` result that is a piece of the store's
|
|
19
|
-
* state (same object, e.g. `() => get().user`) is matched by where it lives; a
|
|
20
|
-
* copy or derived value (`() => ({ ...get().user })`) is not, so its paths are
|
|
21
|
-
* matched relative to the result and store paths like `user.phone` won't apply.
|
|
22
|
-
* Use the hook, or don't return secrets from actions.
|
|
23
|
-
*/
|
|
24
|
-
type Redact = Record<string, string[]> | ((store: string, path: string, value: unknown) => unknown);
|
|
25
21
|
type StoreToolsOptions = {
|
|
26
22
|
redact?: Redact;
|
|
27
23
|
};
|
|
28
24
|
/** Read, merge into, and call actions on named stores. */
|
|
29
25
|
declare function storeTools(stores: Record<string, StoreLike>, options?: StoreToolsOptions): Tools;
|
|
30
26
|
|
|
31
|
-
export {
|
|
27
|
+
export { Redact, type StoreLike, type StoreToolsOptions, storeTools };
|