@buoy-gg/redux 7.0.33 → 7.0.34

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.
Files changed (32) hide show
  1. package/lib/commonjs/preset.js +14 -22
  2. package/lib/commonjs/redux/components/ReduxActionInfoView.js +8 -60
  3. package/lib/commonjs/redux/components/ReduxActionItem.js +64 -118
  4. package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +15 -109
  5. package/lib/commonjs/redux/components/ReduxModal.js +24 -69
  6. package/lib/commonjs/redux/hooks/useReduxActions.js +16 -33
  7. package/lib/commonjs/redux/sync/reduxSyncAdapter.js +11 -29
  8. package/lib/commonjs/redux/utils/reduxActionStore.js +24 -94
  9. package/lib/commonjs/redux/utils/snapshotProvider.js +17 -80
  10. package/lib/module/preset.js +13 -20
  11. package/lib/module/redux/components/ReduxActionInfoView.js +1 -53
  12. package/lib/module/redux/components/ReduxActionItem.js +65 -119
  13. package/lib/module/redux/components/ReduxDetailViewToggle.js +17 -111
  14. package/lib/module/redux/components/ReduxModal.js +26 -71
  15. package/lib/module/redux/hooks/useReduxActions.js +17 -34
  16. package/lib/module/redux/sync/reduxSyncAdapter.js +12 -30
  17. package/lib/module/redux/utils/reduxActionStore.js +25 -95
  18. package/lib/module/redux/utils/snapshotProvider.js +18 -81
  19. package/lib/typescript/preset.d.ts +3 -9
  20. package/lib/typescript/preset.d.ts.map +1 -1
  21. package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +1 -1
  22. package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +1 -1
  23. package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts +2 -1
  24. package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +1 -1
  25. package/lib/typescript/redux/components/ReduxModal.d.ts.map +1 -1
  26. package/lib/typescript/redux/hooks/useReduxActions.d.ts +3 -0
  27. package/lib/typescript/redux/hooks/useReduxActions.d.ts.map +1 -1
  28. package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts +68 -82
  29. package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts.map +1 -1
  30. package/lib/typescript/redux/utils/reduxActionStore.d.ts +2 -29
  31. package/lib/typescript/redux/utils/reduxActionStore.d.ts.map +1 -1
  32. package/package.json +4 -4
@@ -1,22 +1,11 @@
1
1
  "use strict";
2
2
 
3
3
  import { reduxActionStore, STATE_ON_DEVICE, PAYLOAD_ON_DEVICE, isEvictedState } from "../utils/reduxActionStore";
4
- import { isOverWireBudget } from "@buoy-gg/shared-ui";
4
+ import { WIRE_DETAIL_LIMIT_BYTES, capDetail, createSyncAdapter, memoByIdentity, readParams, toWire } from "@buoy-gg/shared-ui";
5
5
  import { getActiveStore, getInstrumentationStatus } from "../utils/autoInstrument";
6
6
 
7
- /**
8
- * Upper bound for one on-demand action-detail response. Generous — this is a
9
- * single explicit fetch, not a per-action stream — but still guarded so a
10
- * pathological tree can't OOM the device through the reply emit.
11
- */
12
- const MAX_ACTION_DETAIL_BYTES = 8 * 1024 * 1024;
13
-
14
7
  /** Per-action budget for `payload`/`action`/`meta.arg`/`error` on the snapshot wire. */
15
- const MAX_WIRE_PAYLOAD_BYTES = 16 * 1024;
16
- function toWireValue(value) {
17
- if (value === undefined) return value;
18
- return isOverWireBudget(value, MAX_WIRE_PAYLOAD_BYTES) ? PAYLOAD_ON_DEVICE : value;
19
- }
8
+ const toWireValue = value => toWire(value, PAYLOAD_ON_DEVICE);
20
9
 
21
10
  /**
22
11
  * Per-action wire cache. `reduxActionStore` never mutates an action in place —
@@ -25,10 +14,7 @@ function toWireValue(value) {
25
14
  * `action`, `meta.arg` and `error` in the list is re-measured on all ~5
26
15
  * snapshots per second for as long as it stays in the list.
27
16
  */
28
- const wireCache = new WeakMap();
29
- function toWireAction(a) {
30
- const cached = wireCache.get(a);
31
- if (cached) return cached;
17
+ const toWireAction = memoByIdentity(a => {
32
18
  const wire = isEvictedState(a.prevState) ? {
33
19
  ...a
34
20
  } : {
@@ -51,9 +37,8 @@ function toWireAction(a) {
51
37
  arg
52
38
  };
53
39
  }
54
- wireCache.set(a, wire);
55
40
  return wire;
56
- }
41
+ });
57
42
  /** Top-level slice names of the state tree, for the compact (no-values) view. */
58
43
  function topLevelKeys(state) {
59
44
  return state && typeof state === "object" && !Array.isArray(state) ? Object.keys(state) : [];
@@ -90,7 +75,7 @@ function unavailable() {
90
75
  * dispatch actions — redux is action-based, so the *current state* isn't in the
91
76
  * action-log snapshot.
92
77
  */
93
- export const reduxSyncAdapter = {
78
+ export const reduxSyncAdapter = createSyncAdapter({
94
79
  version: 2,
95
80
  /**
96
81
  * WIRE-FORM snapshot: actions WITHOUT raw prevState/nextState trees.
@@ -115,7 +100,7 @@ export const reduxSyncAdapter = {
115
100
  getActionDetail: params => {
116
101
  const {
117
102
  id
118
- } = params ?? {};
103
+ } = readParams(params);
119
104
  if (!id) return {
120
105
  found: false,
121
106
  reason: "missing id"
@@ -135,11 +120,7 @@ export const reduxSyncAdapter = {
135
120
  }
136
121
  // Per-field cap: oversized fields degrade individually instead of
137
122
  // failing the whole detail (a giant payload shouldn't hide the trees).
138
- const cappedNote = {
139
- __buoyTruncated: true,
140
- note: `Exceeds the ${MAX_ACTION_DETAIL_BYTES / (1024 * 1024)}MB detail limit — inspect it on-device.`
141
- };
142
- const cap = value => isOverWireBudget(value, MAX_ACTION_DETAIL_BYTES) ? cappedNote : value;
123
+ const cap = value => capDetail(value, WIRE_DETAIL_LIMIT_BYTES);
143
124
  const capMeta = meta => {
144
125
  if (!meta) return meta;
145
126
  const arg = cap(meta.arg);
@@ -166,7 +147,7 @@ export const reduxSyncAdapter = {
166
147
  getState: params => {
167
148
  const {
168
149
  includeValues = false
169
- } = params ?? {};
150
+ } = readParams(params);
170
151
  const store = getActiveStore();
171
152
  if (!store) {
172
153
  return unavailable();
@@ -188,7 +169,7 @@ export const reduxSyncAdapter = {
188
169
  dispatch: params => {
189
170
  const {
190
171
  action
191
- } = params;
172
+ } = readParams(params);
192
173
  const store = getActiveStore();
193
174
  if (!store) {
194
175
  return {
@@ -196,11 +177,12 @@ export const reduxSyncAdapter = {
196
177
  ...unavailable()
197
178
  };
198
179
  }
180
+ if (!action) throw new Error("dispatch requires an `action`");
199
181
  store.dispatch(action);
200
182
  return {
201
183
  dispatched: true,
202
- type: action?.type
184
+ type: action.type
203
185
  };
204
186
  }
205
187
  }
206
- };
188
+ });
@@ -4,7 +4,7 @@
4
4
  * Redux action store - captures and stores Redux Toolkit actions
5
5
  */
6
6
 
7
- import { approxJsonSize } from "@buoy-gg/shared-ui";
7
+ import { ChangeLog, approxJsonSize } from "@buoy-gg/shared-ui";
8
8
  /**
9
9
  * How many of the most-recent actions keep their raw prevState/nextState
10
10
  * trees. Older actions keep all diff metadata but their trees are replaced
@@ -230,16 +230,9 @@ function extractMeta(action) {
230
230
  // Redux Action Store
231
231
  // ============================================
232
232
 
233
- class ReduxActionStore {
234
- actions = [];
235
- listeners = new Set();
236
- clearListeners = new Set();
237
- maxActions = 200;
238
- idCounter = 0;
239
- isEnabled = true;
240
- captureSuppressed = false;
233
+ class ReduxActionStore extends ChangeLog {
241
234
  addAction(action, prevState, nextState, duration) {
242
- if (!this.isEnabled || this.captureSuppressed) {
235
+ if (!this.canRecord()) {
243
236
  return;
244
237
  }
245
238
  const actionType = action.type || "";
@@ -265,7 +258,7 @@ class ReduxActionStore {
265
258
  const isSlowAction = (duration ?? 0) > 16; // Frame budget
266
259
 
267
260
  const reduxAction = {
268
- id: `${Date.now()}-${++this.idCounter}`,
261
+ id: this.nextId(),
269
262
  type: actionType,
270
263
  payload: action.payload,
271
264
  action,
@@ -285,7 +278,7 @@ class ReduxActionStore {
285
278
  changedKeysCount,
286
279
  isSlowAction
287
280
  };
288
- this.actions = [reduxAction, ...this.actions].slice(0, this.maxActions);
281
+ this.push(reduxAction);
289
282
 
290
283
  // Bound raw-state retention. Every action holds prevState/nextState by
291
284
  // reference; with structural sharing that's normally cheap, but when a
@@ -294,8 +287,8 @@ class ReduxActionStore {
294
287
  // pinned by 50 slice-replacing actions, enough to OOM-kill enterprise
295
288
  // apps. Detail view + time travel realistically use recent actions, so
296
289
  // older ones keep their diff metadata but drop the raw trees.
297
- for (let i = STATE_RETENTION_LIMIT; i < this.actions.length; i++) {
298
- const a = this.actions[i];
290
+ for (let i = STATE_RETENTION_LIMIT; i < this.items.length; i++) {
291
+ const a = this.items[i];
299
292
  if (a.prevState !== STATE_EVICTED) {
300
293
  a.prevState = STATE_EVICTED;
301
294
  a.nextState = STATE_EVICTED;
@@ -306,63 +299,26 @@ class ReduxActionStore {
306
299
  this.notifyListeners();
307
300
  }
308
301
  getActions() {
309
- return [...this.actions];
302
+ return this.getAll();
310
303
  }
311
304
  getActionById(id) {
312
- return this.actions.find(a => a.id === id);
305
+ return this.getById(id);
313
306
  }
314
307
  clearActions() {
315
- this.actions = [];
316
- this.notifyListeners();
317
- this.clearListeners.forEach(listener => {
318
- try {
319
- listener();
320
- } catch {
321
- // Ignore listener errors
322
- }
323
- });
324
- }
325
-
326
- /**
327
- * Listen for clearActions() calls. Used in remote mirror mode to forward a
328
- * clear performed in the dashboard UI to the synced device.
329
- */
330
- onClear(listener) {
331
- this.clearListeners.add(listener);
332
- return () => {
333
- this.clearListeners.delete(listener);
334
- };
308
+ this.clear();
335
309
  }
336
310
 
337
311
  // ============================================
338
312
  // Remote Mirror Mode
339
313
  // ============================================
340
314
 
341
- /**
342
- * Permanently suppress local capture. Use when this store acts as a mirror
343
- * of a remote device's actions (e.g. the desktop dashboard): actions arrive
344
- * via replaceActions() and local instrumentation must never record.
345
- */
346
- disableCapture() {
347
- this.captureSuppressed = true;
348
- }
349
-
350
- /**
351
- * Whether the store is in remote mirror mode (capture suppressed). The UI
352
- * uses this to skip local-instrumentation affordances like the
353
- * "react-redux not installed" banner.
354
- */
355
- isCaptureSuppressed() {
356
- return this.captureSuppressed;
357
- }
358
-
359
315
  /**
360
316
  * Replace the entire action list and notify listeners. Used in remote
361
317
  * mirror mode where full snapshots arrive from a synced device. Respects
362
318
  * the enabled flag so the UI's pause button freezes the mirror.
363
319
  */
364
320
  replaceActions(actions) {
365
- if (!this.isEnabled) {
321
+ if (!this.getEnabled()) {
366
322
  return;
367
323
  }
368
324
  // Preserve any trees a remote mirror already hydrated via
@@ -370,12 +326,12 @@ class ReduxActionStore {
370
326
  // full snapshot arriving after a detail fetch must not blank the detail
371
327
  // pane back out.
372
328
  const hydrated = new Map();
373
- for (const existing of this.actions) {
329
+ for (const existing of this.items) {
374
330
  if (existing.prevState !== undefined && !isEvictedState(existing.prevState)) {
375
331
  hydrated.set(existing.id, existing);
376
332
  }
377
333
  }
378
- this.actions = actions.slice(0, this.maxActions).map(a => {
334
+ const merged = actions.slice(0, this.max).map(a => {
379
335
  const h = hydrated.get(a.id);
380
336
  if (!h || !isEvictedState(a.prevState)) return a;
381
337
  return {
@@ -388,7 +344,7 @@ class ReduxActionStore {
388
344
  error: isPayloadOnDevice(a.error) ? h.error : a.error
389
345
  };
390
346
  });
391
- this.notifyListeners();
347
+ this.setItems(merged);
392
348
  }
393
349
 
394
350
  /**
@@ -397,44 +353,18 @@ class ReduxActionStore {
397
353
  * `getActionDetail` action. Remote-mirror (desktop) use only.
398
354
  */
399
355
  hydrateAction(id, patch) {
400
- const index = this.actions.findIndex(a => a.id === id);
401
- if (index === -1) return;
402
- this.actions = [...this.actions.slice(0, index), {
403
- ...this.actions[index],
404
- ...patch
405
- }, ...this.actions.slice(index + 1)];
406
- this.notifyListeners();
407
- }
408
- setEnabled(enabled) {
409
- this.isEnabled = enabled;
410
- }
411
- getEnabled() {
412
- return this.isEnabled;
413
- }
414
- subscribe(listener) {
415
- this.listeners.add(listener);
416
- return () => {
417
- this.listeners.delete(listener);
418
- };
419
- }
420
- notifyListeners() {
421
- const actions = this.getActions();
422
- this.listeners.forEach(listener => listener(actions));
356
+ this.hydrateById(id, patch);
423
357
  }
424
358
  setMaxActions(max) {
425
- this.maxActions = max;
426
- if (this.actions.length > max) {
427
- this.actions = this.actions.slice(0, max);
428
- this.notifyListeners();
429
- }
359
+ this.setMax(max);
430
360
  }
431
361
  getStats() {
432
- const total = this.actions.length;
433
- const withChanges = this.actions.filter(a => a.hasStateChange).length;
434
- const actionTypes = new Set(this.actions.map(a => a.type));
362
+ const total = this.items.length;
363
+ const withChanges = this.items.filter(a => a.hasStateChange).length;
364
+ const actionTypes = new Set(this.items.map(a => a.type));
435
365
 
436
366
  // Calculate average duration
437
- const durations = this.actions.filter(a => a.duration !== undefined).map(a => a.duration);
367
+ const durations = this.items.filter(a => a.duration !== undefined).map(a => a.duration);
438
368
  const avgDuration = durations.length > 0 ? durations.reduce((sum, d) => sum + d, 0) / durations.length : 0;
439
369
  return {
440
370
  totalActions: total,
@@ -445,7 +375,7 @@ class ReduxActionStore {
445
375
  };
446
376
  }
447
377
  filterActions(filter) {
448
- let filtered = [...this.actions];
378
+ let filtered = [...this.items];
449
379
  if (filter.searchText) {
450
380
  const search = filter.searchText.toLowerCase();
451
381
  filtered = filtered.filter(a => a.type.toLowerCase().includes(search));
@@ -459,14 +389,14 @@ class ReduxActionStore {
459
389
  return filtered;
460
390
  }
461
391
  getUniqueActionTypes() {
462
- return Array.from(new Set(this.actions.map(a => a.type))).sort();
392
+ return Array.from(new Set(this.items.map(a => a.type))).sort();
463
393
  }
464
394
 
465
395
  /**
466
396
  * Find related async actions by requestId
467
397
  */
468
398
  getRelatedActions(requestId) {
469
- return this.actions.filter(a => a.meta?.requestId === requestId).sort((a, b) => a.timestamp - b.timestamp); // Sort chronologically
399
+ return this.items.filter(a => a.meta?.requestId === requestId).sort((a, b) => a.timestamp - b.timestamp); // Sort chronologically
470
400
  }
471
401
 
472
402
  /**
@@ -482,7 +412,7 @@ class ReduxActionStore {
482
412
  */
483
413
  getLinkedActionsCount(action) {
484
414
  if (!action.meta?.requestId) return 0;
485
- return this.actions.filter(a => a.meta?.requestId === action.meta?.requestId).length;
415
+ return this.items.filter(a => a.meta?.requestId === action.meta?.requestId).length;
486
416
  }
487
417
 
488
418
  /**
@@ -520,7 +450,7 @@ class ReduxActionStore {
520
450
  getAsyncOperationIndex(requestId) {
521
451
  // Get all unique requestIds with their first timestamp
522
452
  const requestIdTimestamps = new Map();
523
- for (const action of this.actions) {
453
+ for (const action of this.items) {
524
454
  if (action.meta?.requestId && !requestIdTimestamps.has(action.meta.requestId)) {
525
455
  requestIdTimestamps.set(action.meta.requestId, action.timestamp);
526
456
  }
@@ -14,8 +14,7 @@
14
14
  * object itself).
15
15
  * - patch path: never handled; restore is reported as unavailable up front.
16
16
  */
17
- import { registerStateSnapshotProvider } from "@buoy-gg/shared-ui";
18
- import { boundedDeepEqual, jsonLikelyLargerThan } from "@buoy-gg/shared-ui/dataViewer";
17
+ import { classifyPreviewItem, createRestoreScope, registerStateSnapshotProvider, skippedRestore, unionKeys, wontApply } from "@buoy-gg/shared-ui";
19
18
  import { getActiveStore, getInstrumentationStatus } from "./activeStoreRegistry";
20
19
  import { BUOY_JUMP_TO_STATE } from "./buoyReduxMiddleware";
21
20
  const ENABLE_HINT = "enable restore by using the Buoy enhancer or wrapping your root reducer in withBuoyDevTools()";
@@ -64,36 +63,19 @@ async function restore(data, options) {
64
63
  const snapshot = data;
65
64
  const store = getActiveStore();
66
65
  if (!store || snapshot === undefined || snapshot === null) {
67
- return {
68
- ok: false,
69
- applied: 0,
70
- skipped: [{
71
- id: "redux",
72
- reason: store ? "empty redux snapshot" : "no Redux store instrumented"
73
- }],
74
- warnings: []
75
- };
66
+ return skippedRestore("redux", store ? "empty redux snapshot" : "no Redux store instrumented");
76
67
  }
77
68
  const {
78
69
  mechanism
79
70
  } = getInstrumentationStatus();
80
71
  if (mechanism === "patch") {
81
- return {
82
- ok: false,
83
- applied: 0,
84
- skipped: [{
85
- id: "redux",
86
- reason: `restore unavailable on auto-instrumented stores — ${ENABLE_HINT}`
87
- }],
88
- warnings: []
89
- };
72
+ return skippedRestore("redux", `restore unavailable on auto-instrumented stores — ${ENABLE_HINT}`);
90
73
  }
91
74
  // Untouched slices keep their LIVE values inside the jump payload, so the
92
75
  // full-state replace leaves them alone. A slice is untouched when it's
93
76
  // explicitly excluded OR outside the includeKeys scope.
94
- const excludedSet = new Set(options?.excludeKeys ?? []);
95
- const includedSet = options?.includeKeys ? new Set(options.includeKeys) : null;
96
- const excluded = Object.keys(snapshot.state ?? {}).filter(k => excludedSet.has(k) || includedSet && !includedSet.has(k));
77
+ const scope = createRestoreScope(options);
78
+ const excluded = Object.keys(snapshot.state ?? {}).filter(k => !scope.touch(k));
97
79
  let payload = snapshot.state;
98
80
  if (excluded.length > 0) {
99
81
  const live = store.getState();
@@ -119,17 +101,8 @@ async function restore(data, options) {
119
101
  warnings
120
102
  };
121
103
  }
122
- return {
123
- ok: false,
124
- applied: 0,
125
- skipped: [{
126
- id: "redux",
127
- reason: `store ignored the state jump — ${ENABLE_HINT}`
128
- }],
129
- warnings: []
130
- };
104
+ return skippedRestore("redux", `store ignored the state jump — ${ENABLE_HINT}`);
131
105
  }
132
- const ITEM_RENDER_BYTE_LIMIT = 256 * 1024;
133
106
 
134
107
  /** Per-slice restore preview. `base` omitted = compare against the live store. */
135
108
  async function previewItems(target, base) {
@@ -154,54 +127,18 @@ async function previewItems(target, base) {
154
127
  }
155
128
  const oldObj = baseState ?? {};
156
129
  const newObj = targetState ?? {};
157
- const keys = new Set([...Object.keys(oldObj), ...Object.keys(newObj)]);
158
- for (const key of keys) {
159
- const inOld = Object.prototype.hasOwnProperty.call(oldObj, key);
160
- const inNew = Object.prototype.hasOwnProperty.call(newObj, key);
161
- let item;
162
- if (!inNew) {
163
- item = {
164
- key,
165
- label: key,
166
- verdict: "removed",
167
- oldValue: oldObj[key]
168
- };
169
- } else if (!inOld) {
170
- item = {
171
- key,
172
- label: key,
173
- verdict: "added",
174
- newValue: newObj[key]
175
- };
176
- } else if (boundedDeepEqual(oldObj[key], newObj[key])) {
177
- item = {
178
- key,
179
- label: key,
180
- verdict: "unchanged"
181
- };
182
- } else if (jsonLikelyLargerThan(oldObj[key], ITEM_RENDER_BYTE_LIMIT) || jsonLikelyLargerThan(newObj[key], ITEM_RENDER_BYTE_LIMIT)) {
183
- item = {
184
- key,
185
- label: key,
186
- verdict: "too-large",
187
- reason: "slice too large to render a diff — restore still applies it"
188
- };
189
- } else {
190
- item = {
191
- key,
192
- label: key,
193
- verdict: "changed",
194
- oldValue: oldObj[key],
195
- newValue: newObj[key]
196
- };
197
- }
198
- if (wontApplyReason && item.verdict !== "unchanged") {
199
- item = {
200
- ...item,
201
- verdict: "wont-apply",
202
- reason: wontApplyReason
203
- };
204
- }
130
+ for (const key of unionKeys(oldObj, newObj)) {
131
+ let item = classifyPreviewItem({
132
+ key,
133
+ label: key,
134
+ oldValue: oldObj[key],
135
+ newValue: newObj[key],
136
+ inOld: Object.prototype.hasOwnProperty.call(oldObj, key),
137
+ inNew: Object.prototype.hasOwnProperty.call(newObj, key)
138
+ }, {
139
+ tooLargeReason: "slice too large to render a diff — restore still applies it"
140
+ });
141
+ if (wontApplyReason) item = wontApply(item, wontApplyReason);
205
142
  items.push(item);
206
143
  }
207
144
  if (wontApplyReason) notes.push(`Redux restore unavailable: ${wontApplyReason}`);
@@ -65,18 +65,12 @@ export declare const reduxToolPreset: {
65
65
  * });
66
66
  * ```
67
67
  */
68
- export declare function createReduxTool(options?: {
69
- /** Tool name (default: "REDUX") */
70
- name?: string;
71
- /** Tool description */
72
- description?: string;
73
- /** Custom tool ID (default: "redux") */
74
- id?: string;
75
- /** Icon color (default: Redux purple #764ABC) */
68
+ export declare const createReduxTool: (options?: ({
69
+ /** Icon color */
76
70
  iconColor?: string;
77
71
  /** Enable shared modal dimensions */
78
72
  enableSharedModalDimensions?: boolean;
79
- }): {
73
+ } & import("@buoy-gg/shared-ui").ToolPresetOverrides) | undefined) => {
80
74
  id: string;
81
75
  name: string;
82
76
  description: string;
@@ -1 +1 @@
1
- {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/preset.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAG3D;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;;qBAKT;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;;;;;CAKlC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE;IACxC,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;;;;;qBAMoB;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;;;;;EAWpC"}
1
+ {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/preset.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;;qBAKT;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;;;;;CAKjC,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe;IAGxB,iBAAiB;gBACL,MAAM;IAClB,qCAAqC;kCACP,OAAO;;;;;;qBA3BtB;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;;;;;CAoClC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ReduxActionInfoView.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxActionInfoView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAA0D,MAAM,OAAO,CAAC;AAmB/E,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,UAAU,CAAC;AAU5D,UAAU,wBAAwB;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;CACpD;AA4ID,eAAO,MAAM,mBAAmB,sDAsgB9B,CAAC"}
1
+ {"version":3,"file":"ReduxActionInfoView.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxActionInfoView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAA0D,MAAM,OAAO,CAAC;AAoB/E,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,UAAU,CAAC;AAU5D,UAAU,wBAAwB;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;CACpD;AAsGD,eAAO,MAAM,mBAAmB,sDAsgB9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ReduxActionItem.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxActionItem.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,UAAU,CAAC;AAG5D,UAAU,oBAAoB;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAmKD,eAAO,MAAM,eAAe,4DAiI1B,CAAC"}
1
+ {"version":3,"file":"ReduxActionItem.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxActionItem.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,UAAU,CAAC;AAG5D,UAAU,oBAAoB;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAmKD,eAAO,MAAM,eAAe,4DAqF1B,CAAC"}
@@ -2,7 +2,8 @@
2
2
  * ReduxDetailViewToggle
3
3
  *
4
4
  * Three-card toggle for switching between Action, State, and Diff views.
5
- * Redux-specific component for the enhanced detail view.
5
+ * The cards themselves are the shared `DetailViewToggle`; this file owns
6
+ * the redux view list and testID prefix.
6
7
  */
7
8
  import React from "react";
8
9
  export type ReduxDetailViewMode = "action" | "state" | "diff";
@@ -1 +1 @@
1
- {"version":3,"file":"ReduxDetailViewToggle.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxDetailViewToggle.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAe,MAAM,OAAO,CAAC;AAIpC,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAW9D,UAAU,0BAA0B;IAClC,UAAU,EAAE,mBAAmB,CAAC;IAChC,YAAY,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AA4BD,eAAO,MAAM,qBAAqB,wDAkEhC,CAAC"}
1
+ {"version":3,"file":"ReduxDetailViewToggle.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxDetailViewToggle.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAe,MAAM,OAAO,CAAC;AASpC,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9D,UAAU,0BAA0B;IAClC,UAAU,EAAE,mBAAmB,CAAC;IAChC,YAAY,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAYD,eAAO,MAAM,qBAAqB,wDAchC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ReduxModal.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxModal.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+CH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,QAAoC,CAAC;AAExE,UAAU,eAAe;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAC/C;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAoCD,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,EACnC,MAAc,EACd,cAAc,EACd,uBAAuB,EACvB,iBAAiB,GAClB,EAAE,eAAe,sCA0lBjB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,GAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAM,+BAGpE"}
1
+ {"version":3,"file":"ReduxModal.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxModal.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgDH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,QAAoC,CAAC;AAExE,UAAU,eAAe;IACvB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAC/C;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAoCD,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,EACnC,MAAc,EACd,cAAc,EACd,uBAAuB,EACvB,iBAAiB,GAClB,EAAE,eAAe,sCAokBjB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,GAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAM,+BAGpE"}
@@ -1,5 +1,8 @@
1
1
  /**
2
2
  * Hook for consuming Redux actions from the store
3
+ *
4
+ * The subscribe / filter / pause / clear plumbing is shared `useChangeLog`;
5
+ * this file owns the redux-specific stats, action types and selection.
3
6
  */
4
7
  import type { ReduxAction, ReduxFilter } from "../types";
5
8
  export interface UseReduxActionsResult {
@@ -1 +1 @@
1
- {"version":3,"file":"useReduxActions.d.ts","sourceRoot":"","sources":["../../../../src/redux/hooks/useReduxActions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGzD,MAAM,WAAW,qBAAqB;IACpC,2BAA2B;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,+CAA+C;IAC/C,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,8BAA8B;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,6BAA6B;IAC7B,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7D,wCAAwC;IACxC,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,qBAAqB,EAAE,MAAM,CAAC;QAC9B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,iCAAiC;IACjC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,mCAAmC;IACnC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uBAAuB;IACvB,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IACvD,gDAAgD;IAChD,cAAc,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,0BAA0B;IAC1B,iBAAiB,EAAE,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;CACzD;AAED,wBAAgB,eAAe,IAAI,qBAAqB,CAsEvD"}
1
+ {"version":3,"file":"useReduxActions.d.ts","sourceRoot":"","sources":["../../../../src/redux/hooks/useReduxActions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGzD,MAAM,WAAW,qBAAqB;IACpC,2BAA2B;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,+CAA+C;IAC/C,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,8BAA8B;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,6BAA6B;IAC7B,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC;IAC7D,wCAAwC;IACxC,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,qBAAqB,EAAE,MAAM,CAAC;QAC9B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,iCAAiC;IACjC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,mCAAmC;IACnC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uBAAuB;IACvB,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC;IACvD,gDAAgD;IAChD,cAAc,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,0BAA0B;IAC1B,iBAAiB,EAAE,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;CACzD;AAKD,wBAAgB,eAAe,IAAI,qBAAqB,CA2CvD"}