@buoy-gg/redux 7.0.33 → 7.0.35
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/lib/commonjs/preset.js +14 -22
- package/lib/commonjs/redux/components/ReduxActionButton.js +1 -1
- package/lib/commonjs/redux/components/ReduxActionDetailContent.js +5 -5
- package/lib/commonjs/redux/components/ReduxActionDetailView.js +3 -3
- package/lib/commonjs/redux/components/ReduxActionInfoView.js +16 -68
- package/lib/commonjs/redux/components/ReduxActionItem.js +65 -119
- package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +15 -109
- package/lib/commonjs/redux/components/ReduxModal.js +25 -70
- package/lib/commonjs/redux/hooks/useReduxActions.js +16 -33
- package/lib/commonjs/redux/sync/reduxSyncAdapter.js +11 -29
- package/lib/commonjs/redux/utils/reduxActionStore.js +24 -94
- package/lib/commonjs/redux/utils/snapshotProvider.js +17 -80
- package/lib/module/preset.js +13 -20
- package/lib/module/redux/components/ReduxActionButton.js +2 -2
- package/lib/module/redux/components/ReduxActionDetailContent.js +6 -6
- package/lib/module/redux/components/ReduxActionDetailView.js +4 -4
- package/lib/module/redux/components/ReduxActionInfoView.js +9 -61
- package/lib/module/redux/components/ReduxActionItem.js +66 -120
- package/lib/module/redux/components/ReduxDetailViewToggle.js +17 -111
- package/lib/module/redux/components/ReduxModal.js +27 -72
- package/lib/module/redux/hooks/useReduxActions.js +17 -34
- package/lib/module/redux/sync/reduxSyncAdapter.js +12 -30
- package/lib/module/redux/utils/reduxActionStore.js +25 -95
- package/lib/module/redux/utils/snapshotProvider.js +18 -81
- package/lib/typescript/preset.d.ts +3 -9
- package/lib/typescript/preset.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxActionDetailContent.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxActionDetailView.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts +2 -1
- package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxModal.d.ts.map +1 -1
- package/lib/typescript/redux/hooks/useReduxActions.d.ts +3 -0
- package/lib/typescript/redux/hooks/useReduxActions.d.ts.map +1 -1
- package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts +68 -82
- package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts.map +1 -1
- package/lib/typescript/redux/utils/reduxActionStore.d.ts +2 -29
- package/lib/typescript/redux/utils/reduxActionStore.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -238,16 +238,9 @@ function extractMeta(action) {
|
|
|
238
238
|
// Redux Action Store
|
|
239
239
|
// ============================================
|
|
240
240
|
|
|
241
|
-
class ReduxActionStore {
|
|
242
|
-
actions = [];
|
|
243
|
-
listeners = new Set();
|
|
244
|
-
clearListeners = new Set();
|
|
245
|
-
maxActions = 200;
|
|
246
|
-
idCounter = 0;
|
|
247
|
-
isEnabled = true;
|
|
248
|
-
captureSuppressed = false;
|
|
241
|
+
class ReduxActionStore extends _sharedUi.ChangeLog {
|
|
249
242
|
addAction(action, prevState, nextState, duration) {
|
|
250
|
-
if (!this.
|
|
243
|
+
if (!this.canRecord()) {
|
|
251
244
|
return;
|
|
252
245
|
}
|
|
253
246
|
const actionType = action.type || "";
|
|
@@ -273,7 +266,7 @@ class ReduxActionStore {
|
|
|
273
266
|
const isSlowAction = (duration ?? 0) > 16; // Frame budget
|
|
274
267
|
|
|
275
268
|
const reduxAction = {
|
|
276
|
-
id:
|
|
269
|
+
id: this.nextId(),
|
|
277
270
|
type: actionType,
|
|
278
271
|
payload: action.payload,
|
|
279
272
|
action,
|
|
@@ -293,7 +286,7 @@ class ReduxActionStore {
|
|
|
293
286
|
changedKeysCount,
|
|
294
287
|
isSlowAction
|
|
295
288
|
};
|
|
296
|
-
this.
|
|
289
|
+
this.push(reduxAction);
|
|
297
290
|
|
|
298
291
|
// Bound raw-state retention. Every action holds prevState/nextState by
|
|
299
292
|
// reference; with structural sharing that's normally cheap, but when a
|
|
@@ -302,8 +295,8 @@ class ReduxActionStore {
|
|
|
302
295
|
// pinned by 50 slice-replacing actions, enough to OOM-kill enterprise
|
|
303
296
|
// apps. Detail view + time travel realistically use recent actions, so
|
|
304
297
|
// older ones keep their diff metadata but drop the raw trees.
|
|
305
|
-
for (let i = STATE_RETENTION_LIMIT; i < this.
|
|
306
|
-
const a = this.
|
|
298
|
+
for (let i = STATE_RETENTION_LIMIT; i < this.items.length; i++) {
|
|
299
|
+
const a = this.items[i];
|
|
307
300
|
if (a.prevState !== STATE_EVICTED) {
|
|
308
301
|
a.prevState = STATE_EVICTED;
|
|
309
302
|
a.nextState = STATE_EVICTED;
|
|
@@ -314,63 +307,26 @@ class ReduxActionStore {
|
|
|
314
307
|
this.notifyListeners();
|
|
315
308
|
}
|
|
316
309
|
getActions() {
|
|
317
|
-
return
|
|
310
|
+
return this.getAll();
|
|
318
311
|
}
|
|
319
312
|
getActionById(id) {
|
|
320
|
-
return this.
|
|
313
|
+
return this.getById(id);
|
|
321
314
|
}
|
|
322
315
|
clearActions() {
|
|
323
|
-
this.
|
|
324
|
-
this.notifyListeners();
|
|
325
|
-
this.clearListeners.forEach(listener => {
|
|
326
|
-
try {
|
|
327
|
-
listener();
|
|
328
|
-
} catch {
|
|
329
|
-
// Ignore listener errors
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Listen for clearActions() calls. Used in remote mirror mode to forward a
|
|
336
|
-
* clear performed in the dashboard UI to the synced device.
|
|
337
|
-
*/
|
|
338
|
-
onClear(listener) {
|
|
339
|
-
this.clearListeners.add(listener);
|
|
340
|
-
return () => {
|
|
341
|
-
this.clearListeners.delete(listener);
|
|
342
|
-
};
|
|
316
|
+
this.clear();
|
|
343
317
|
}
|
|
344
318
|
|
|
345
319
|
// ============================================
|
|
346
320
|
// Remote Mirror Mode
|
|
347
321
|
// ============================================
|
|
348
322
|
|
|
349
|
-
/**
|
|
350
|
-
* Permanently suppress local capture. Use when this store acts as a mirror
|
|
351
|
-
* of a remote device's actions (e.g. the desktop dashboard): actions arrive
|
|
352
|
-
* via replaceActions() and local instrumentation must never record.
|
|
353
|
-
*/
|
|
354
|
-
disableCapture() {
|
|
355
|
-
this.captureSuppressed = true;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Whether the store is in remote mirror mode (capture suppressed). The UI
|
|
360
|
-
* uses this to skip local-instrumentation affordances like the
|
|
361
|
-
* "react-redux not installed" banner.
|
|
362
|
-
*/
|
|
363
|
-
isCaptureSuppressed() {
|
|
364
|
-
return this.captureSuppressed;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
323
|
/**
|
|
368
324
|
* Replace the entire action list and notify listeners. Used in remote
|
|
369
325
|
* mirror mode where full snapshots arrive from a synced device. Respects
|
|
370
326
|
* the enabled flag so the UI's pause button freezes the mirror.
|
|
371
327
|
*/
|
|
372
328
|
replaceActions(actions) {
|
|
373
|
-
if (!this.
|
|
329
|
+
if (!this.getEnabled()) {
|
|
374
330
|
return;
|
|
375
331
|
}
|
|
376
332
|
// Preserve any trees a remote mirror already hydrated via
|
|
@@ -378,12 +334,12 @@ class ReduxActionStore {
|
|
|
378
334
|
// full snapshot arriving after a detail fetch must not blank the detail
|
|
379
335
|
// pane back out.
|
|
380
336
|
const hydrated = new Map();
|
|
381
|
-
for (const existing of this.
|
|
337
|
+
for (const existing of this.items) {
|
|
382
338
|
if (existing.prevState !== undefined && !isEvictedState(existing.prevState)) {
|
|
383
339
|
hydrated.set(existing.id, existing);
|
|
384
340
|
}
|
|
385
341
|
}
|
|
386
|
-
|
|
342
|
+
const merged = actions.slice(0, this.max).map(a => {
|
|
387
343
|
const h = hydrated.get(a.id);
|
|
388
344
|
if (!h || !isEvictedState(a.prevState)) return a;
|
|
389
345
|
return {
|
|
@@ -396,7 +352,7 @@ class ReduxActionStore {
|
|
|
396
352
|
error: isPayloadOnDevice(a.error) ? h.error : a.error
|
|
397
353
|
};
|
|
398
354
|
});
|
|
399
|
-
this.
|
|
355
|
+
this.setItems(merged);
|
|
400
356
|
}
|
|
401
357
|
|
|
402
358
|
/**
|
|
@@ -405,44 +361,18 @@ class ReduxActionStore {
|
|
|
405
361
|
* `getActionDetail` action. Remote-mirror (desktop) use only.
|
|
406
362
|
*/
|
|
407
363
|
hydrateAction(id, patch) {
|
|
408
|
-
|
|
409
|
-
if (index === -1) return;
|
|
410
|
-
this.actions = [...this.actions.slice(0, index), {
|
|
411
|
-
...this.actions[index],
|
|
412
|
-
...patch
|
|
413
|
-
}, ...this.actions.slice(index + 1)];
|
|
414
|
-
this.notifyListeners();
|
|
415
|
-
}
|
|
416
|
-
setEnabled(enabled) {
|
|
417
|
-
this.isEnabled = enabled;
|
|
418
|
-
}
|
|
419
|
-
getEnabled() {
|
|
420
|
-
return this.isEnabled;
|
|
421
|
-
}
|
|
422
|
-
subscribe(listener) {
|
|
423
|
-
this.listeners.add(listener);
|
|
424
|
-
return () => {
|
|
425
|
-
this.listeners.delete(listener);
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
notifyListeners() {
|
|
429
|
-
const actions = this.getActions();
|
|
430
|
-
this.listeners.forEach(listener => listener(actions));
|
|
364
|
+
this.hydrateById(id, patch);
|
|
431
365
|
}
|
|
432
366
|
setMaxActions(max) {
|
|
433
|
-
this.
|
|
434
|
-
if (this.actions.length > max) {
|
|
435
|
-
this.actions = this.actions.slice(0, max);
|
|
436
|
-
this.notifyListeners();
|
|
437
|
-
}
|
|
367
|
+
this.setMax(max);
|
|
438
368
|
}
|
|
439
369
|
getStats() {
|
|
440
|
-
const total = this.
|
|
441
|
-
const withChanges = this.
|
|
442
|
-
const actionTypes = new Set(this.
|
|
370
|
+
const total = this.items.length;
|
|
371
|
+
const withChanges = this.items.filter(a => a.hasStateChange).length;
|
|
372
|
+
const actionTypes = new Set(this.items.map(a => a.type));
|
|
443
373
|
|
|
444
374
|
// Calculate average duration
|
|
445
|
-
const durations = this.
|
|
375
|
+
const durations = this.items.filter(a => a.duration !== undefined).map(a => a.duration);
|
|
446
376
|
const avgDuration = durations.length > 0 ? durations.reduce((sum, d) => sum + d, 0) / durations.length : 0;
|
|
447
377
|
return {
|
|
448
378
|
totalActions: total,
|
|
@@ -453,7 +383,7 @@ class ReduxActionStore {
|
|
|
453
383
|
};
|
|
454
384
|
}
|
|
455
385
|
filterActions(filter) {
|
|
456
|
-
let filtered = [...this.
|
|
386
|
+
let filtered = [...this.items];
|
|
457
387
|
if (filter.searchText) {
|
|
458
388
|
const search = filter.searchText.toLowerCase();
|
|
459
389
|
filtered = filtered.filter(a => a.type.toLowerCase().includes(search));
|
|
@@ -467,14 +397,14 @@ class ReduxActionStore {
|
|
|
467
397
|
return filtered;
|
|
468
398
|
}
|
|
469
399
|
getUniqueActionTypes() {
|
|
470
|
-
return Array.from(new Set(this.
|
|
400
|
+
return Array.from(new Set(this.items.map(a => a.type))).sort();
|
|
471
401
|
}
|
|
472
402
|
|
|
473
403
|
/**
|
|
474
404
|
* Find related async actions by requestId
|
|
475
405
|
*/
|
|
476
406
|
getRelatedActions(requestId) {
|
|
477
|
-
return this.
|
|
407
|
+
return this.items.filter(a => a.meta?.requestId === requestId).sort((a, b) => a.timestamp - b.timestamp); // Sort chronologically
|
|
478
408
|
}
|
|
479
409
|
|
|
480
410
|
/**
|
|
@@ -490,7 +420,7 @@ class ReduxActionStore {
|
|
|
490
420
|
*/
|
|
491
421
|
getLinkedActionsCount(action) {
|
|
492
422
|
if (!action.meta?.requestId) return 0;
|
|
493
|
-
return this.
|
|
423
|
+
return this.items.filter(a => a.meta?.requestId === action.meta?.requestId).length;
|
|
494
424
|
}
|
|
495
425
|
|
|
496
426
|
/**
|
|
@@ -528,7 +458,7 @@ class ReduxActionStore {
|
|
|
528
458
|
getAsyncOperationIndex(requestId) {
|
|
529
459
|
// Get all unique requestIds with their first timestamp
|
|
530
460
|
const requestIdTimestamps = new Map();
|
|
531
|
-
for (const action of this.
|
|
461
|
+
for (const action of this.items) {
|
|
532
462
|
if (action.meta?.requestId && !requestIdTimestamps.has(action.meta.requestId)) {
|
|
533
463
|
requestIdTimestamps.set(action.meta.requestId, action.timestamp);
|
|
534
464
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
4
|
-
var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
5
4
|
var _activeStoreRegistry = require("./activeStoreRegistry");
|
|
6
5
|
var _buoyReduxMiddleware = require("./buoyReduxMiddleware");
|
|
7
6
|
/**
|
|
@@ -65,36 +64,19 @@ async function restore(data, options) {
|
|
|
65
64
|
const snapshot = data;
|
|
66
65
|
const store = (0, _activeStoreRegistry.getActiveStore)();
|
|
67
66
|
if (!store || snapshot === undefined || snapshot === null) {
|
|
68
|
-
return
|
|
69
|
-
ok: false,
|
|
70
|
-
applied: 0,
|
|
71
|
-
skipped: [{
|
|
72
|
-
id: "redux",
|
|
73
|
-
reason: store ? "empty redux snapshot" : "no Redux store instrumented"
|
|
74
|
-
}],
|
|
75
|
-
warnings: []
|
|
76
|
-
};
|
|
67
|
+
return (0, _sharedUi.skippedRestore)("redux", store ? "empty redux snapshot" : "no Redux store instrumented");
|
|
77
68
|
}
|
|
78
69
|
const {
|
|
79
70
|
mechanism
|
|
80
71
|
} = (0, _activeStoreRegistry.getInstrumentationStatus)();
|
|
81
72
|
if (mechanism === "patch") {
|
|
82
|
-
return {
|
|
83
|
-
ok: false,
|
|
84
|
-
applied: 0,
|
|
85
|
-
skipped: [{
|
|
86
|
-
id: "redux",
|
|
87
|
-
reason: `restore unavailable on auto-instrumented stores — ${ENABLE_HINT}`
|
|
88
|
-
}],
|
|
89
|
-
warnings: []
|
|
90
|
-
};
|
|
73
|
+
return (0, _sharedUi.skippedRestore)("redux", `restore unavailable on auto-instrumented stores — ${ENABLE_HINT}`);
|
|
91
74
|
}
|
|
92
75
|
// Untouched slices keep their LIVE values inside the jump payload, so the
|
|
93
76
|
// full-state replace leaves them alone. A slice is untouched when it's
|
|
94
77
|
// explicitly excluded OR outside the includeKeys scope.
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
const excluded = Object.keys(snapshot.state ?? {}).filter(k => excludedSet.has(k) || includedSet && !includedSet.has(k));
|
|
78
|
+
const scope = (0, _sharedUi.createRestoreScope)(options);
|
|
79
|
+
const excluded = Object.keys(snapshot.state ?? {}).filter(k => !scope.touch(k));
|
|
98
80
|
let payload = snapshot.state;
|
|
99
81
|
if (excluded.length > 0) {
|
|
100
82
|
const live = store.getState();
|
|
@@ -120,17 +102,8 @@ async function restore(data, options) {
|
|
|
120
102
|
warnings
|
|
121
103
|
};
|
|
122
104
|
}
|
|
123
|
-
return {
|
|
124
|
-
ok: false,
|
|
125
|
-
applied: 0,
|
|
126
|
-
skipped: [{
|
|
127
|
-
id: "redux",
|
|
128
|
-
reason: `store ignored the state jump — ${ENABLE_HINT}`
|
|
129
|
-
}],
|
|
130
|
-
warnings: []
|
|
131
|
-
};
|
|
105
|
+
return (0, _sharedUi.skippedRestore)("redux", `store ignored the state jump — ${ENABLE_HINT}`);
|
|
132
106
|
}
|
|
133
|
-
const ITEM_RENDER_BYTE_LIMIT = 256 * 1024;
|
|
134
107
|
|
|
135
108
|
/** Per-slice restore preview. `base` omitted = compare against the live store. */
|
|
136
109
|
async function previewItems(target, base) {
|
|
@@ -155,54 +128,18 @@ async function previewItems(target, base) {
|
|
|
155
128
|
}
|
|
156
129
|
const oldObj = baseState ?? {};
|
|
157
130
|
const newObj = targetState ?? {};
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
} else if (!inOld) {
|
|
171
|
-
item = {
|
|
172
|
-
key,
|
|
173
|
-
label: key,
|
|
174
|
-
verdict: "added",
|
|
175
|
-
newValue: newObj[key]
|
|
176
|
-
};
|
|
177
|
-
} else if ((0, _dataViewer.boundedDeepEqual)(oldObj[key], newObj[key])) {
|
|
178
|
-
item = {
|
|
179
|
-
key,
|
|
180
|
-
label: key,
|
|
181
|
-
verdict: "unchanged"
|
|
182
|
-
};
|
|
183
|
-
} else if ((0, _dataViewer.jsonLikelyLargerThan)(oldObj[key], ITEM_RENDER_BYTE_LIMIT) || (0, _dataViewer.jsonLikelyLargerThan)(newObj[key], ITEM_RENDER_BYTE_LIMIT)) {
|
|
184
|
-
item = {
|
|
185
|
-
key,
|
|
186
|
-
label: key,
|
|
187
|
-
verdict: "too-large",
|
|
188
|
-
reason: "slice too large to render a diff — restore still applies it"
|
|
189
|
-
};
|
|
190
|
-
} else {
|
|
191
|
-
item = {
|
|
192
|
-
key,
|
|
193
|
-
label: key,
|
|
194
|
-
verdict: "changed",
|
|
195
|
-
oldValue: oldObj[key],
|
|
196
|
-
newValue: newObj[key]
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
if (wontApplyReason && item.verdict !== "unchanged") {
|
|
200
|
-
item = {
|
|
201
|
-
...item,
|
|
202
|
-
verdict: "wont-apply",
|
|
203
|
-
reason: wontApplyReason
|
|
204
|
-
};
|
|
205
|
-
}
|
|
131
|
+
for (const key of (0, _sharedUi.unionKeys)(oldObj, newObj)) {
|
|
132
|
+
let item = (0, _sharedUi.classifyPreviewItem)({
|
|
133
|
+
key,
|
|
134
|
+
label: key,
|
|
135
|
+
oldValue: oldObj[key],
|
|
136
|
+
newValue: newObj[key],
|
|
137
|
+
inOld: Object.prototype.hasOwnProperty.call(oldObj, key),
|
|
138
|
+
inNew: Object.prototype.hasOwnProperty.call(newObj, key)
|
|
139
|
+
}, {
|
|
140
|
+
tooLargeReason: "slice too large to render a diff — restore still applies it"
|
|
141
|
+
});
|
|
142
|
+
if (wontApplyReason) item = (0, _sharedUi.wontApply)(item, wontApplyReason);
|
|
206
143
|
items.push(item);
|
|
207
144
|
}
|
|
208
145
|
if (wontApplyReason) notes.push(`Redux restore unavailable: ${wontApplyReason}`);
|
package/lib/module/preset.js
CHANGED
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
import { ReduxModal } from "./redux/components/ReduxModal";
|
|
36
36
|
import { ReduxIcon } from "./redux/components/ReduxIcon";
|
|
37
|
+
import { createToolFactory, defineToolPreset } from "@buoy-gg/shared-ui";
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
40
|
* Pre-configured Redux DevTools preset for FloatingDevTools.
|
|
@@ -44,7 +45,7 @@ import { ReduxIcon } from "./redux/components/ReduxIcon";
|
|
|
44
45
|
* - Filter by action type
|
|
45
46
|
*/
|
|
46
47
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
47
|
-
export const reduxToolPreset = {
|
|
48
|
+
export const reduxToolPreset = defineToolPreset({
|
|
48
49
|
id: "redux",
|
|
49
50
|
name: "REDUX",
|
|
50
51
|
description: "Redux action & state inspector",
|
|
@@ -58,7 +59,7 @@ export const reduxToolPreset = {
|
|
|
58
59
|
props: {
|
|
59
60
|
enableSharedModalDimensions: false
|
|
60
61
|
}
|
|
61
|
-
};
|
|
62
|
+
});
|
|
62
63
|
|
|
63
64
|
/**
|
|
64
65
|
* Create a custom Redux DevTools configuration.
|
|
@@ -74,21 +75,13 @@ export const reduxToolPreset = {
|
|
|
74
75
|
* });
|
|
75
76
|
* ```
|
|
76
77
|
*/
|
|
77
|
-
export
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
color: options?.iconColor
|
|
88
|
-
}),
|
|
89
|
-
component: ReduxModal,
|
|
90
|
-
props: {
|
|
91
|
-
enableSharedModalDimensions: options?.enableSharedModalDimensions !== undefined ? options.enableSharedModalDimensions : false
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
}
|
|
78
|
+
export const createReduxTool = createToolFactory(reduxToolPreset, options => ({
|
|
79
|
+
enableSharedModalDimensions: options.enableSharedModalDimensions ?? false
|
|
80
|
+
}), options => ({
|
|
81
|
+
icon: ({
|
|
82
|
+
size
|
|
83
|
+
}) => /*#__PURE__*/_jsx(ReduxIcon, {
|
|
84
|
+
size: size,
|
|
85
|
+
color: options.iconColor
|
|
86
|
+
})
|
|
87
|
+
}));
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { TouchableOpacity, Text, View, StyleSheet } from "react-native";
|
|
11
|
-
import { night } from "@buoy-gg/shared-ui";
|
|
11
|
+
import { night, monoFont } from "@buoy-gg/shared-ui";
|
|
12
12
|
|
|
13
13
|
// Button color configurations matching React Query pattern
|
|
14
14
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -122,7 +122,7 @@ const styles = StyleSheet.create({
|
|
|
122
122
|
fontWeight: "600",
|
|
123
123
|
letterSpacing: 0.5,
|
|
124
124
|
textTransform: "uppercase",
|
|
125
|
-
fontFamily:
|
|
125
|
+
fontFamily: monoFont,
|
|
126
126
|
height: 12
|
|
127
127
|
}
|
|
128
128
|
});
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { View, Text, StyleSheet, ScrollView } from "react-native";
|
|
13
13
|
import { useState, useCallback, useMemo } from "react";
|
|
14
|
-
import { macOSColors, night, EventStepperFooter, formatRelativeTime, parseValue } from "@buoy-gg/shared-ui";
|
|
14
|
+
import { macOSColors, night, EventStepperFooter, formatRelativeTime, parseValue, monoFont } from "@buoy-gg/shared-ui";
|
|
15
15
|
import { DataViewer, SplitDiffViewer, TreeDiffViewer, diffThemes } from "@buoy-gg/shared-ui/dataViewer";
|
|
16
16
|
import { ReduxDetailViewToggle } from "./ReduxDetailViewToggle";
|
|
17
17
|
import { ReduxActionInfoView } from "./ReduxActionInfoView";
|
|
@@ -355,7 +355,7 @@ const styles = StyleSheet.create({
|
|
|
355
355
|
valueLabel: {
|
|
356
356
|
fontSize: 10,
|
|
357
357
|
color: night.color.textSecondary,
|
|
358
|
-
fontFamily:
|
|
358
|
+
fontFamily: monoFont,
|
|
359
359
|
letterSpacing: 0.5,
|
|
360
360
|
fontWeight: "600"
|
|
361
361
|
},
|
|
@@ -372,7 +372,7 @@ const styles = StyleSheet.create({
|
|
|
372
372
|
actionText: {
|
|
373
373
|
fontSize: 9,
|
|
374
374
|
fontWeight: "700",
|
|
375
|
-
fontFamily:
|
|
375
|
+
fontFamily: monoFont,
|
|
376
376
|
letterSpacing: 0.3
|
|
377
377
|
},
|
|
378
378
|
typeBadge: {
|
|
@@ -385,7 +385,7 @@ const styles = StyleSheet.create({
|
|
|
385
385
|
fontSize: 9,
|
|
386
386
|
fontWeight: "600",
|
|
387
387
|
color: night.color.textTertiary,
|
|
388
|
-
fontFamily:
|
|
388
|
+
fontFamily: monoFont
|
|
389
389
|
},
|
|
390
390
|
valueBox: {
|
|
391
391
|
// Inset code box — darker than the card, the night track color.
|
|
@@ -403,7 +403,7 @@ const styles = StyleSheet.create({
|
|
|
403
403
|
valueText: {
|
|
404
404
|
fontSize: 12,
|
|
405
405
|
color: night.color.text,
|
|
406
|
-
fontFamily:
|
|
406
|
+
fontFamily: monoFont,
|
|
407
407
|
lineHeight: 18
|
|
408
408
|
},
|
|
409
409
|
// Diff view styles
|
|
@@ -423,7 +423,7 @@ const styles = StyleSheet.create({
|
|
|
423
423
|
actionTextSmall: {
|
|
424
424
|
fontSize: 8,
|
|
425
425
|
fontWeight: "700",
|
|
426
|
-
fontFamily:
|
|
426
|
+
fontFamily: monoFont
|
|
427
427
|
},
|
|
428
428
|
dataViewerContainer: {
|
|
429
429
|
marginTop: -12,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { useState } from "react";
|
|
8
8
|
import { View, Text, StyleSheet, ScrollView } from "react-native";
|
|
9
|
-
import { macOSColors, night, TabSelector, DataInspector, CollapsibleSection, CopyButton } from "@buoy-gg/shared-ui";
|
|
9
|
+
import { macOSColors, night, TabSelector, DataInspector, CollapsibleSection, CopyButton, monoFont } from "@buoy-gg/shared-ui";
|
|
10
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
11
|
export function ReduxActionDetailView({
|
|
12
12
|
action
|
|
@@ -298,7 +298,7 @@ const styles = StyleSheet.create({
|
|
|
298
298
|
fontSize: 14,
|
|
299
299
|
fontWeight: "600",
|
|
300
300
|
color: night.color.text,
|
|
301
|
-
fontFamily:
|
|
301
|
+
fontFamily: monoFont,
|
|
302
302
|
marginBottom: 6
|
|
303
303
|
},
|
|
304
304
|
headerMeta: {
|
|
@@ -313,7 +313,7 @@ const styles = StyleSheet.create({
|
|
|
313
313
|
durationText: {
|
|
314
314
|
fontSize: 11,
|
|
315
315
|
color: night.color.textTertiary,
|
|
316
|
-
fontFamily:
|
|
316
|
+
fontFamily: monoFont
|
|
317
317
|
},
|
|
318
318
|
changeBadge: {
|
|
319
319
|
backgroundColor: macOSColors.semantic.warningBackground,
|
|
@@ -379,7 +379,7 @@ const styles = StyleSheet.create({
|
|
|
379
379
|
diffPath: {
|
|
380
380
|
fontSize: 12,
|
|
381
381
|
color: night.color.text,
|
|
382
|
-
fontFamily:
|
|
382
|
+
fontFamily: monoFont
|
|
383
383
|
},
|
|
384
384
|
diffValues: {
|
|
385
385
|
padding: 8,
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import React, { memo, useMemo, useCallback, useState, useEffect } from "react";
|
|
14
14
|
import { View, Text, StyleSheet, ScrollView, TouchableOpacity } from "react-native";
|
|
15
|
-
import { buoyColors, night, Clock, AlertTriangle, Zap, Hash, Info, Box, AlertCircle, FileText, parseValue, ProUpgradeModal, copyToClipboard } from "@buoy-gg/shared-ui";
|
|
15
|
+
import { buoyColors, night, Clock, AlertTriangle, Zap, Hash, Info, Box, AlertCircle, FileText, parseValue, ProUpgradeModal, copyToClipboard, InfoRow, monoFont } from "@buoy-gg/shared-ui";
|
|
16
16
|
import { useIsPro } from "@buoy-gg/license";
|
|
17
17
|
import { DataViewer } from "@buoy-gg/shared-ui/dataViewer";
|
|
18
18
|
import { reduxActionStore, isEvictedState } from "../utils/reduxActionStore";
|
|
@@ -104,37 +104,6 @@ function SectionHeader({
|
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
/**
|
|
108
|
-
* Info row component for key-value display
|
|
109
|
-
*/
|
|
110
|
-
function InfoRow({
|
|
111
|
-
label,
|
|
112
|
-
value,
|
|
113
|
-
valueColor,
|
|
114
|
-
mono = false,
|
|
115
|
-
testID
|
|
116
|
-
}) {
|
|
117
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
118
|
-
style: styles.infoRow,
|
|
119
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
120
|
-
style: styles.infoLabel,
|
|
121
|
-
children: label
|
|
122
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
123
|
-
style: [styles.infoValue, mono && styles.infoValueMono, valueColor && {
|
|
124
|
-
color: valueColor
|
|
125
|
-
}]
|
|
126
|
-
// `ellipsizeMode="middle"` truncates the RENDERED text and iOS reports
|
|
127
|
-
// the truncated string back, so anything a test reads off one of these
|
|
128
|
-
// rows has to be short enough to fit on the line.
|
|
129
|
-
,
|
|
130
|
-
numberOfLines: 1,
|
|
131
|
-
ellipsizeMode: "middle",
|
|
132
|
-
testID: testID,
|
|
133
|
-
children: value
|
|
134
|
-
})]
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
107
|
/**
|
|
139
108
|
* Format timestamp for display
|
|
140
109
|
*/
|
|
@@ -598,33 +567,12 @@ const styles = StyleSheet.create({
|
|
|
598
567
|
fontWeight: "600",
|
|
599
568
|
letterSpacing: 0.5,
|
|
600
569
|
color: night.color.accent,
|
|
601
|
-
fontFamily:
|
|
570
|
+
fontFamily: monoFont
|
|
602
571
|
},
|
|
603
572
|
cardContent: {
|
|
604
573
|
padding: 14,
|
|
605
574
|
gap: 10
|
|
606
575
|
},
|
|
607
|
-
infoRow: {
|
|
608
|
-
flexDirection: "row",
|
|
609
|
-
alignItems: "center",
|
|
610
|
-
justifyContent: "space-between"
|
|
611
|
-
},
|
|
612
|
-
infoLabel: {
|
|
613
|
-
fontSize: 11,
|
|
614
|
-
color: night.color.textTertiary,
|
|
615
|
-
fontWeight: "500"
|
|
616
|
-
},
|
|
617
|
-
infoValue: {
|
|
618
|
-
fontSize: 11,
|
|
619
|
-
color: night.color.text,
|
|
620
|
-
fontWeight: "500",
|
|
621
|
-
flex: 1,
|
|
622
|
-
textAlign: "right",
|
|
623
|
-
marginLeft: 12
|
|
624
|
-
},
|
|
625
|
-
infoValueMono: {
|
|
626
|
-
fontFamily: "monospace"
|
|
627
|
-
},
|
|
628
576
|
badgeRow: {
|
|
629
577
|
flexDirection: "row",
|
|
630
578
|
flexWrap: "wrap",
|
|
@@ -657,7 +605,7 @@ const styles = StyleSheet.create({
|
|
|
657
605
|
fontSize: 9,
|
|
658
606
|
fontWeight: "600",
|
|
659
607
|
color: night.color.textSecondary,
|
|
660
|
-
fontFamily:
|
|
608
|
+
fontFamily: monoFont
|
|
661
609
|
},
|
|
662
610
|
durationTextSlow: {
|
|
663
611
|
color: buoyColors.error
|
|
@@ -697,7 +645,7 @@ const styles = StyleSheet.create({
|
|
|
697
645
|
fontSize: 8,
|
|
698
646
|
fontWeight: "600",
|
|
699
647
|
color: night.color.textTertiary,
|
|
700
|
-
fontFamily:
|
|
648
|
+
fontFamily: monoFont
|
|
701
649
|
},
|
|
702
650
|
dataViewerContainer: {
|
|
703
651
|
backgroundColor: night.color.bg,
|
|
@@ -722,7 +670,7 @@ const styles = StyleSheet.create({
|
|
|
722
670
|
argValue: {
|
|
723
671
|
fontSize: 11,
|
|
724
672
|
color: night.color.text,
|
|
725
|
-
fontFamily:
|
|
673
|
+
fontFamily: monoFont,
|
|
726
674
|
padding: 10
|
|
727
675
|
},
|
|
728
676
|
errorBadge: {
|
|
@@ -740,7 +688,7 @@ const styles = StyleSheet.create({
|
|
|
740
688
|
errorText: {
|
|
741
689
|
fontSize: 12,
|
|
742
690
|
color: buoyColors.error,
|
|
743
|
-
fontFamily:
|
|
691
|
+
fontFamily: monoFont,
|
|
744
692
|
padding: 14
|
|
745
693
|
},
|
|
746
694
|
// Async Operation / Related Actions styles
|
|
@@ -760,7 +708,7 @@ const styles = StyleSheet.create({
|
|
|
760
708
|
fontSize: 12,
|
|
761
709
|
fontWeight: "600",
|
|
762
710
|
color: night.color.text,
|
|
763
|
-
fontFamily:
|
|
711
|
+
fontFamily: monoFont,
|
|
764
712
|
marginBottom: 8
|
|
765
713
|
},
|
|
766
714
|
totalDurationRow: {
|
|
@@ -781,7 +729,7 @@ const styles = StyleSheet.create({
|
|
|
781
729
|
fontSize: 14,
|
|
782
730
|
fontWeight: "700",
|
|
783
731
|
color: buoyColors.success,
|
|
784
|
-
fontFamily:
|
|
732
|
+
fontFamily: monoFont
|
|
785
733
|
},
|
|
786
734
|
timeline: {
|
|
787
735
|
gap: 0
|
|
@@ -847,7 +795,7 @@ const styles = StyleSheet.create({
|
|
|
847
795
|
timelineTime: {
|
|
848
796
|
fontSize: 10,
|
|
849
797
|
color: night.color.textTertiary,
|
|
850
|
-
fontFamily:
|
|
798
|
+
fontFamily: monoFont
|
|
851
799
|
},
|
|
852
800
|
// Action footer - matches React Query DevTools
|
|
853
801
|
actionFooter: {
|