@buoy-gg/redux 7.0.17 → 7.0.18

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.
@@ -82,10 +82,11 @@ function ReduxActionDetailContent({
82
82
  actions,
83
83
  selectedIndex,
84
84
  onIndexChange,
85
- disableInternalFooter = false
85
+ disableInternalFooter = false,
86
+ initialView = "action"
86
87
  }) {
87
- // View state
88
- const [activeView, setActiveView] = (0, _react.useState)("action");
88
+ // View state (initialView seeds it once; taps own it afterwards)
89
+ const [activeView, setActiveView] = (0, _react.useState)(initialView);
89
90
  const [diffMode, setDiffMode] = (0, _react.useState)("tree");
90
91
  const totalActions = actions.length;
91
92
  const actionColor = getActionColor(action.type);
@@ -49,7 +49,9 @@ function ReduxModal({
49
49
  onMinimize,
50
50
  enableSharedModalDimensions = false,
51
51
  inline = false,
52
- onActionSelect
52
+ onActionSelect,
53
+ initialSelectedActionId,
54
+ initialDetailView
53
55
  }) {
54
56
  const isPro = (0, _license.useIsPro)();
55
57
  const [showProModal, setShowProModal] = (0, _react.useState)(false);
@@ -105,6 +107,19 @@ function ReduxModal({
105
107
  lastNotifiedSelectionRef.current = id;
106
108
  onActionSelect(selectedAction);
107
109
  }, [selectedAction, onActionSelect]);
110
+
111
+ // Deep link into an action's detail (see initialSelectedActionId). Applied
112
+ // at most once per id, so the list re-rendering — or the user pressing Back
113
+ // — never re-opens it.
114
+ const appliedInitialSelectionRef = (0, _react.useRef)(null);
115
+ (0, _react.useEffect)(() => {
116
+ if (!initialSelectedActionId) return;
117
+ if (appliedInitialSelectionRef.current === initialSelectedActionId) return;
118
+ const index = visibleActions.findIndex(a => a.id === initialSelectedActionId);
119
+ if (index < 0) return;
120
+ appliedInitialSelectionRef.current = initialSelectedActionId;
121
+ setSelectedActionIndex(index);
122
+ }, [initialSelectedActionId, visibleActions]);
108
123
  const [searchText, setSearchText] = (0, _react.useState)("");
109
124
  const [isSearchActive, setIsSearchActive] = (0, _react.useState)(false);
110
125
  const searchInputRef = (0, _react.useRef)(null);
@@ -307,7 +322,8 @@ function ReduxModal({
307
322
  actions: visibleActions,
308
323
  selectedIndex: selectedActionIndex,
309
324
  onIndexChange: handleIndexChange,
310
- disableInternalFooter: true
325
+ disableInternalFooter: true,
326
+ initialView: initialDetailView
311
327
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
312
328
  children: [instrumentError && !isInstrumented && !_reduxActionStore.reduxActionStore.isCaptureSuppressed() && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
313
329
  style: styles.errorBanner,
@@ -13,8 +13,17 @@ var _autoInstrument = require("../utils/autoInstrument");
13
13
  */
14
14
  const MAX_ACTION_DETAIL_BYTES = 8 * 1024 * 1024;
15
15
 
16
- /** Per-action budget for `payload`/`action` on the snapshot wire. */
16
+ /** Per-action budget for `payload`/`action`/`meta.arg`/`error` on the snapshot wire. */
17
17
  const MAX_WIRE_PAYLOAD_BYTES = 16 * 1024;
18
+ function toWireValue(value) {
19
+ if (value === undefined) return value;
20
+ try {
21
+ JSON.stringify(value);
22
+ } catch {
23
+ return _reduxActionStore.PAYLOAD_ON_DEVICE;
24
+ }
25
+ return (0, _reduxActionStore.jsonLongerThan)(value, MAX_WIRE_PAYLOAD_BYTES) ? _reduxActionStore.PAYLOAD_ON_DEVICE : value;
26
+ }
18
27
  /** Top-level slice names of the state tree, for the compact (no-values) view. */
19
28
  function topLevelKeys(state) {
20
29
  return state && typeof state === "object" && !Array.isArray(state) ? Object.keys(state) : [];
@@ -72,12 +81,20 @@ const reduxSyncAdapter = exports.reduxSyncAdapter = {
72
81
  };
73
82
  // A dispatched payload can itself be huge (rehydration actions carry
74
83
  // whole state trees). The list view renders payloadPreview anyway —
75
- // oversized payload/action values stay on-device behind markers.
76
- if ((0, _reduxActionStore.jsonLongerThan)(wire.payload, MAX_WIRE_PAYLOAD_BYTES)) {
77
- wire.payload = _reduxActionStore.PAYLOAD_ON_DEVICE;
78
- }
79
- if ((0, _reduxActionStore.jsonLongerThan)(wire.action, MAX_WIRE_PAYLOAD_BYTES)) {
80
- wire.action = _reduxActionStore.PAYLOAD_ON_DEVICE;
84
+ // oversized / unserializable values stay on-device behind markers.
85
+ // `meta.arg` is a leftover: RTK copies the thunk argument there, and
86
+ // capping `action` still left the extracted copy on the wire.
87
+ wire.payload = toWireValue(wire.payload);
88
+ wire.action = toWireValue(wire.action);
89
+ wire.error = toWireValue(wire.error);
90
+ if (wire.meta) {
91
+ const arg = toWireValue(wire.meta.arg);
92
+ if (arg !== wire.meta.arg) {
93
+ wire.meta = {
94
+ ...wire.meta,
95
+ arg
96
+ };
97
+ }
81
98
  }
82
99
  return wire;
83
100
  }),
@@ -118,14 +135,31 @@ const reduxSyncAdapter = exports.reduxSyncAdapter = {
118
135
  __buoyTruncated: true,
119
136
  note: `Exceeds the ${MAX_ACTION_DETAIL_BYTES / (1024 * 1024)}MB detail limit — inspect it on-device.`
120
137
  };
121
- const cap = value => (0, _reduxActionStore.jsonLongerThan)(value, MAX_ACTION_DETAIL_BYTES) ? cappedNote : value;
138
+ const cap = value => {
139
+ try {
140
+ JSON.stringify(value);
141
+ } catch {
142
+ return cappedNote;
143
+ }
144
+ return (0, _reduxActionStore.jsonLongerThan)(value, MAX_ACTION_DETAIL_BYTES) ? cappedNote : value;
145
+ };
146
+ const capMeta = meta => {
147
+ if (!meta) return meta;
148
+ const arg = cap(meta.arg);
149
+ return arg === meta.arg ? meta : {
150
+ ...meta,
151
+ arg
152
+ };
153
+ };
122
154
  return {
123
155
  found: true,
124
156
  id,
125
157
  prevState: cap(action.prevState),
126
158
  nextState: cap(action.nextState),
127
159
  payload: cap(action.payload),
128
- action: cap(action.action)
160
+ action: cap(action.action),
161
+ meta: capMeta(action.meta),
162
+ error: cap(action.error)
129
163
  };
130
164
  },
131
165
  /**
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.STATE_RETENTION_LIMIT = exports.STATE_ON_DEVICE = exports.STATE_EVICTED = exports.PAYLOAD_ON_DEVICE = void 0;
7
7
  exports.isEvictedState = isEvictedState;
8
+ exports.isPayloadOnDevice = isPayloadOnDevice;
8
9
  exports.jsonLongerThan = jsonLongerThan;
9
10
  exports.reduxActionStore = void 0;
10
11
  /**
@@ -52,6 +53,11 @@ const PAYLOAD_ON_DEVICE = exports.PAYLOAD_ON_DEVICE = Object.freeze({
52
53
  note: "Payload stays on the device — fetched on demand via getActionDetail."
53
54
  });
54
55
 
56
+ /** True when a wire-form value is the payload-on-device sentinel. */
57
+ function isPayloadOnDevice(value) {
58
+ return typeof value === "object" && value !== null && value.__buoyPayloadOnDevice === true;
59
+ }
60
+
55
61
  /**
56
62
  * True when a value is one of the state sentinels (evicted or on-device) —
57
63
  * guards time travel and any consumer that needs a REAL tree.
@@ -399,11 +405,16 @@ class ReduxActionStore {
399
405
  }
400
406
  this.actions = actions.slice(0, this.maxActions).map(a => {
401
407
  const h = hydrated.get(a.id);
402
- return h && isEvictedState(a.prevState) ? {
408
+ if (!h || !isEvictedState(a.prevState)) return a;
409
+ return {
403
410
  ...a,
404
411
  prevState: h.prevState,
405
- nextState: h.nextState
406
- } : a;
412
+ nextState: h.nextState,
413
+ payload: isPayloadOnDevice(a.payload) ? h.payload : a.payload,
414
+ action: isPayloadOnDevice(a.action) ? h.action : a.action,
415
+ meta: isPayloadOnDevice(a.meta?.arg) ? h.meta : a.meta,
416
+ error: isPayloadOnDevice(a.error) ? h.error : a.error
417
+ };
407
418
  });
408
419
  this.notifyListeners();
409
420
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  var _sharedUi = require("@buoy-gg/shared-ui");
4
+ var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
4
5
  var _activeStoreRegistry = require("./activeStoreRegistry");
5
6
  var _buoyReduxMiddleware = require("./buoyReduxMiddleware");
6
7
  /**
@@ -60,7 +61,7 @@ async function capture() {
60
61
  warnings: []
61
62
  };
62
63
  }
63
- async function restore(data) {
64
+ async function restore(data, options) {
64
65
  const snapshot = data;
65
66
  const store = (0, _activeStoreRegistry.getActiveStore)();
66
67
  if (!store || snapshot === undefined || snapshot === null) {
@@ -88,7 +89,21 @@ async function restore(data) {
88
89
  warnings: []
89
90
  };
90
91
  }
91
- const payload = snapshot.state;
92
+ // Untouched slices keep their LIVE values inside the jump payload, so the
93
+ // full-state replace leaves them alone. A slice is untouched when it's
94
+ // explicitly excluded OR outside the includeKeys scope.
95
+ const excludedSet = new Set(options?.excludeKeys ?? []);
96
+ const includedSet = options?.includeKeys ? new Set(options.includeKeys) : null;
97
+ const excluded = Object.keys(snapshot.state ?? {}).filter(k => excludedSet.has(k) || includedSet && !includedSet.has(k));
98
+ let payload = snapshot.state;
99
+ if (excluded.length > 0) {
100
+ const live = store.getState();
101
+ const merged = {
102
+ ...snapshot.state
103
+ };
104
+ for (const slice of excluded) merged[slice] = live?.[slice];
105
+ payload = merged;
106
+ }
92
107
  store.dispatch({
93
108
  type: _buoyReduxMiddleware.BUOY_JUMP_TO_STATE,
94
109
  payload
@@ -97,11 +112,12 @@ async function restore(data) {
97
112
  // identity proves the jump was actually handled (and not silently ignored
98
113
  // by an unwrapped middleware-path reducer).
99
114
  if (store.getState() === payload) {
115
+ const warnings = excluded.length > 0 ? [`${excluded.length} slice(s) excluded by you`] : [];
100
116
  return {
101
117
  ok: true,
102
118
  applied: 1,
103
119
  skipped: [],
104
- warnings: []
120
+ warnings
105
121
  };
106
122
  }
107
123
  return {
@@ -114,10 +130,92 @@ async function restore(data) {
114
130
  warnings: []
115
131
  };
116
132
  }
133
+ const ITEM_RENDER_BYTE_LIMIT = 256 * 1024;
134
+
135
+ /** Per-slice restore preview. `base` omitted = compare against the live store. */
136
+ async function previewItems(target, base) {
137
+ const targetState = target?.state;
138
+ const liveMode = base === undefined;
139
+ const store = (0, _activeStoreRegistry.getActiveStore)();
140
+ const baseState = liveMode ? store?.getState() : base?.state;
141
+ const items = [];
142
+ const notes = [];
143
+
144
+ // Restore-capability gate — a diff restore can't apply must say so, not
145
+ // render as a green change.
146
+ let wontApplyReason;
147
+ if (liveMode) {
148
+ const {
149
+ mechanism,
150
+ hasStore
151
+ } = (0, _activeStoreRegistry.getInstrumentationStatus)();
152
+ if (!hasStore) wontApplyReason = "no Redux store instrumented";else if (mechanism === "patch") {
153
+ wontApplyReason = `auto-instrumented store cannot be restored — ${ENABLE_HINT}`;
154
+ }
155
+ }
156
+ const oldObj = baseState ?? {};
157
+ const newObj = targetState ?? {};
158
+ const keys = new Set([...Object.keys(oldObj), ...Object.keys(newObj)]);
159
+ for (const key of keys) {
160
+ const inOld = Object.prototype.hasOwnProperty.call(oldObj, key);
161
+ const inNew = Object.prototype.hasOwnProperty.call(newObj, key);
162
+ let item;
163
+ if (!inNew) {
164
+ item = {
165
+ key,
166
+ label: key,
167
+ verdict: "removed",
168
+ oldValue: oldObj[key]
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
+ }
206
+ items.push(item);
207
+ }
208
+ if (wontApplyReason) notes.push(`Redux restore unavailable: ${wontApplyReason}`);
209
+ return {
210
+ items,
211
+ notes
212
+ };
213
+ }
117
214
  (0, _sharedUi.registerStateSnapshotProvider)({
118
215
  id: "redux",
119
216
  label: "Redux",
120
217
  status,
121
218
  capture,
122
- restore
219
+ restore,
220
+ previewItems
123
221
  });
@@ -78,10 +78,11 @@ export function ReduxActionDetailContent({
78
78
  actions,
79
79
  selectedIndex,
80
80
  onIndexChange,
81
- disableInternalFooter = false
81
+ disableInternalFooter = false,
82
+ initialView = "action"
82
83
  }) {
83
- // View state
84
- const [activeView, setActiveView] = useState("action");
84
+ // View state (initialView seeds it once; taps own it afterwards)
85
+ const [activeView, setActiveView] = useState(initialView);
85
86
  const [diffMode, setDiffMode] = useState("tree");
86
87
  const totalActions = actions.length;
87
88
  const actionColor = getActionColor(action.type);
@@ -43,7 +43,9 @@ export function ReduxModal({
43
43
  onMinimize,
44
44
  enableSharedModalDimensions = false,
45
45
  inline = false,
46
- onActionSelect
46
+ onActionSelect,
47
+ initialSelectedActionId,
48
+ initialDetailView
47
49
  }) {
48
50
  const isPro = useIsPro();
49
51
  const [showProModal, setShowProModal] = useState(false);
@@ -99,6 +101,19 @@ export function ReduxModal({
99
101
  lastNotifiedSelectionRef.current = id;
100
102
  onActionSelect(selectedAction);
101
103
  }, [selectedAction, onActionSelect]);
104
+
105
+ // Deep link into an action's detail (see initialSelectedActionId). Applied
106
+ // at most once per id, so the list re-rendering — or the user pressing Back
107
+ // — never re-opens it.
108
+ const appliedInitialSelectionRef = useRef(null);
109
+ useEffect(() => {
110
+ if (!initialSelectedActionId) return;
111
+ if (appliedInitialSelectionRef.current === initialSelectedActionId) return;
112
+ const index = visibleActions.findIndex(a => a.id === initialSelectedActionId);
113
+ if (index < 0) return;
114
+ appliedInitialSelectionRef.current = initialSelectedActionId;
115
+ setSelectedActionIndex(index);
116
+ }, [initialSelectedActionId, visibleActions]);
102
117
  const [searchText, setSearchText] = useState("");
103
118
  const [isSearchActive, setIsSearchActive] = useState(false);
104
119
  const searchInputRef = useRef(null);
@@ -301,7 +316,8 @@ export function ReduxModal({
301
316
  actions: visibleActions,
302
317
  selectedIndex: selectedActionIndex,
303
318
  onIndexChange: handleIndexChange,
304
- disableInternalFooter: true
319
+ disableInternalFooter: true,
320
+ initialView: initialDetailView
305
321
  }) : /*#__PURE__*/_jsxs(_Fragment, {
306
322
  children: [instrumentError && !isInstrumented && !reduxActionStore.isCaptureSuppressed() && /*#__PURE__*/_jsxs(View, {
307
323
  style: styles.errorBanner,
@@ -10,8 +10,17 @@ import { getActiveStore, getInstrumentationStatus } from "../utils/autoInstrumen
10
10
  */
11
11
  const MAX_ACTION_DETAIL_BYTES = 8 * 1024 * 1024;
12
12
 
13
- /** Per-action budget for `payload`/`action` on the snapshot wire. */
13
+ /** Per-action budget for `payload`/`action`/`meta.arg`/`error` on the snapshot wire. */
14
14
  const MAX_WIRE_PAYLOAD_BYTES = 16 * 1024;
15
+ function toWireValue(value) {
16
+ if (value === undefined) return value;
17
+ try {
18
+ JSON.stringify(value);
19
+ } catch {
20
+ return PAYLOAD_ON_DEVICE;
21
+ }
22
+ return jsonLongerThan(value, MAX_WIRE_PAYLOAD_BYTES) ? PAYLOAD_ON_DEVICE : value;
23
+ }
15
24
  /** Top-level slice names of the state tree, for the compact (no-values) view. */
16
25
  function topLevelKeys(state) {
17
26
  return state && typeof state === "object" && !Array.isArray(state) ? Object.keys(state) : [];
@@ -69,12 +78,20 @@ export const reduxSyncAdapter = {
69
78
  };
70
79
  // A dispatched payload can itself be huge (rehydration actions carry
71
80
  // whole state trees). The list view renders payloadPreview anyway —
72
- // oversized payload/action values stay on-device behind markers.
73
- if (jsonLongerThan(wire.payload, MAX_WIRE_PAYLOAD_BYTES)) {
74
- wire.payload = PAYLOAD_ON_DEVICE;
75
- }
76
- if (jsonLongerThan(wire.action, MAX_WIRE_PAYLOAD_BYTES)) {
77
- wire.action = PAYLOAD_ON_DEVICE;
81
+ // oversized / unserializable values stay on-device behind markers.
82
+ // `meta.arg` is a leftover: RTK copies the thunk argument there, and
83
+ // capping `action` still left the extracted copy on the wire.
84
+ wire.payload = toWireValue(wire.payload);
85
+ wire.action = toWireValue(wire.action);
86
+ wire.error = toWireValue(wire.error);
87
+ if (wire.meta) {
88
+ const arg = toWireValue(wire.meta.arg);
89
+ if (arg !== wire.meta.arg) {
90
+ wire.meta = {
91
+ ...wire.meta,
92
+ arg
93
+ };
94
+ }
78
95
  }
79
96
  return wire;
80
97
  }),
@@ -115,14 +132,31 @@ export const reduxSyncAdapter = {
115
132
  __buoyTruncated: true,
116
133
  note: `Exceeds the ${MAX_ACTION_DETAIL_BYTES / (1024 * 1024)}MB detail limit — inspect it on-device.`
117
134
  };
118
- const cap = value => jsonLongerThan(value, MAX_ACTION_DETAIL_BYTES) ? cappedNote : value;
135
+ const cap = value => {
136
+ try {
137
+ JSON.stringify(value);
138
+ } catch {
139
+ return cappedNote;
140
+ }
141
+ return jsonLongerThan(value, MAX_ACTION_DETAIL_BYTES) ? cappedNote : value;
142
+ };
143
+ const capMeta = meta => {
144
+ if (!meta) return meta;
145
+ const arg = cap(meta.arg);
146
+ return arg === meta.arg ? meta : {
147
+ ...meta,
148
+ arg
149
+ };
150
+ };
119
151
  return {
120
152
  found: true,
121
153
  id,
122
154
  prevState: cap(action.prevState),
123
155
  nextState: cap(action.nextState),
124
156
  payload: cap(action.payload),
125
- action: cap(action.action)
157
+ action: cap(action.action),
158
+ meta: capMeta(action.meta),
159
+ error: cap(action.error)
126
160
  };
127
161
  },
128
162
  /**
@@ -45,6 +45,11 @@ export const PAYLOAD_ON_DEVICE = Object.freeze({
45
45
  note: "Payload stays on the device — fetched on demand via getActionDetail."
46
46
  });
47
47
 
48
+ /** True when a wire-form value is the payload-on-device sentinel. */
49
+ export function isPayloadOnDevice(value) {
50
+ return typeof value === "object" && value !== null && value.__buoyPayloadOnDevice === true;
51
+ }
52
+
48
53
  /**
49
54
  * True when a value is one of the state sentinels (evicted or on-device) —
50
55
  * guards time travel and any consumer that needs a REAL tree.
@@ -392,11 +397,16 @@ class ReduxActionStore {
392
397
  }
393
398
  this.actions = actions.slice(0, this.maxActions).map(a => {
394
399
  const h = hydrated.get(a.id);
395
- return h && isEvictedState(a.prevState) ? {
400
+ if (!h || !isEvictedState(a.prevState)) return a;
401
+ return {
396
402
  ...a,
397
403
  prevState: h.prevState,
398
- nextState: h.nextState
399
- } : a;
404
+ nextState: h.nextState,
405
+ payload: isPayloadOnDevice(a.payload) ? h.payload : a.payload,
406
+ action: isPayloadOnDevice(a.action) ? h.action : a.action,
407
+ meta: isPayloadOnDevice(a.meta?.arg) ? h.meta : a.meta,
408
+ error: isPayloadOnDevice(a.error) ? h.error : a.error
409
+ };
400
410
  });
401
411
  this.notifyListeners();
402
412
  }
@@ -15,6 +15,7 @@
15
15
  * - patch path: never handled; restore is reported as unavailable up front.
16
16
  */
17
17
  import { registerStateSnapshotProvider } from "@buoy-gg/shared-ui";
18
+ import { boundedDeepEqual, jsonLikelyLargerThan } from "@buoy-gg/shared-ui/dataViewer";
18
19
  import { getActiveStore, getInstrumentationStatus } from "./activeStoreRegistry";
19
20
  import { BUOY_JUMP_TO_STATE } from "./buoyReduxMiddleware";
20
21
  const ENABLE_HINT = "enable restore by using the Buoy enhancer or wrapping your root reducer in withBuoyDevTools()";
@@ -59,7 +60,7 @@ async function capture() {
59
60
  warnings: []
60
61
  };
61
62
  }
62
- async function restore(data) {
63
+ async function restore(data, options) {
63
64
  const snapshot = data;
64
65
  const store = getActiveStore();
65
66
  if (!store || snapshot === undefined || snapshot === null) {
@@ -87,7 +88,21 @@ async function restore(data) {
87
88
  warnings: []
88
89
  };
89
90
  }
90
- const payload = snapshot.state;
91
+ // Untouched slices keep their LIVE values inside the jump payload, so the
92
+ // full-state replace leaves them alone. A slice is untouched when it's
93
+ // 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));
97
+ let payload = snapshot.state;
98
+ if (excluded.length > 0) {
99
+ const live = store.getState();
100
+ const merged = {
101
+ ...snapshot.state
102
+ };
103
+ for (const slice of excluded) merged[slice] = live?.[slice];
104
+ payload = merged;
105
+ }
91
106
  store.dispatch({
92
107
  type: BUOY_JUMP_TO_STATE,
93
108
  payload
@@ -96,11 +111,12 @@ async function restore(data) {
96
111
  // identity proves the jump was actually handled (and not silently ignored
97
112
  // by an unwrapped middleware-path reducer).
98
113
  if (store.getState() === payload) {
114
+ const warnings = excluded.length > 0 ? [`${excluded.length} slice(s) excluded by you`] : [];
99
115
  return {
100
116
  ok: true,
101
117
  applied: 1,
102
118
  skipped: [],
103
- warnings: []
119
+ warnings
104
120
  };
105
121
  }
106
122
  return {
@@ -113,10 +129,92 @@ async function restore(data) {
113
129
  warnings: []
114
130
  };
115
131
  }
132
+ const ITEM_RENDER_BYTE_LIMIT = 256 * 1024;
133
+
134
+ /** Per-slice restore preview. `base` omitted = compare against the live store. */
135
+ async function previewItems(target, base) {
136
+ const targetState = target?.state;
137
+ const liveMode = base === undefined;
138
+ const store = getActiveStore();
139
+ const baseState = liveMode ? store?.getState() : base?.state;
140
+ const items = [];
141
+ const notes = [];
142
+
143
+ // Restore-capability gate — a diff restore can't apply must say so, not
144
+ // render as a green change.
145
+ let wontApplyReason;
146
+ if (liveMode) {
147
+ const {
148
+ mechanism,
149
+ hasStore
150
+ } = getInstrumentationStatus();
151
+ if (!hasStore) wontApplyReason = "no Redux store instrumented";else if (mechanism === "patch") {
152
+ wontApplyReason = `auto-instrumented store cannot be restored — ${ENABLE_HINT}`;
153
+ }
154
+ }
155
+ const oldObj = baseState ?? {};
156
+ 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
+ }
205
+ items.push(item);
206
+ }
207
+ if (wontApplyReason) notes.push(`Redux restore unavailable: ${wontApplyReason}`);
208
+ return {
209
+ items,
210
+ notes
211
+ };
212
+ }
116
213
  registerStateSnapshotProvider({
117
214
  id: "redux",
118
215
  label: "Redux",
119
216
  status,
120
217
  capture,
121
- restore
218
+ restore,
219
+ previewItems
122
220
  });
@@ -7,6 +7,7 @@
7
7
  * - DIFF: Compare prev vs next state
8
8
  */
9
9
  import type { ReduxAction } from "../types";
10
+ import { type ReduxDetailViewMode } from "./ReduxDetailViewToggle";
10
11
  interface ReduxActionDetailContentProps {
11
12
  /** The selected action to display */
12
13
  action: ReduxAction;
@@ -18,8 +19,15 @@ interface ReduxActionDetailContentProps {
18
19
  onIndexChange: (index: number) => void;
19
20
  /** If true, do not render the internal footer */
20
21
  disableInternalFooter?: boolean;
22
+ /**
23
+ * Which of the three views the detail opens on (default "action"). Hosts
24
+ * that deep-link into a specific view — the docs live tour, and any future
25
+ * "show me the diff for this action" entry point — set it at mount; the
26
+ * user's own toggle taps take over from there.
27
+ */
28
+ initialView?: ReduxDetailViewMode;
21
29
  }
22
- export declare function ReduxActionDetailContent({ action, actions, selectedIndex, onIndexChange, disableInternalFooter, }: ReduxActionDetailContentProps): import("react").JSX.Element;
30
+ export declare function ReduxActionDetailContent({ action, actions, selectedIndex, onIndexChange, disableInternalFooter, initialView, }: ReduxActionDetailContentProps): import("react").JSX.Element;
23
31
  /**
24
32
  * External footer component for modal use
25
33
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ReduxActionDetailContent.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxActionDetailContent.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiBH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ5C,UAAU,6BAA6B;IACrC,qCAAqC;IACrC,MAAM,EAAE,WAAW,CAAC;IACpB,iCAAiC;IACjC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,qCAAqC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,iDAAiD;IACjD,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAwDD,wBAAgB,wBAAwB,CAAC,EACvC,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,EACb,qBAA6B,GAC9B,EAAE,6BAA6B,+BA0M/B;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,GACd,EAAE;IACD,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,sCAiBA"}
1
+ {"version":3,"file":"ReduxActionDetailContent.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxActionDetailContent.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiBH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAIjC,UAAU,6BAA6B;IACrC,qCAAqC;IACrC,MAAM,EAAE,WAAW,CAAC;IACpB,iCAAiC;IACjC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,qCAAqC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,iDAAiD;IACjD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC;AAwDD,wBAAgB,wBAAwB,CAAC,EACvC,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,EACb,qBAA6B,EAC7B,WAAsB,GACvB,EAAE,6BAA6B,+BA0M/B;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,MAAM,EACN,OAAO,EACP,aAAa,EACb,aAAa,GACd,EAAE;IACD,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,sCAiBA"}
@@ -4,6 +4,7 @@
4
4
  * This component auto-instruments the Redux store when it mounts,
5
5
  * providing zero-config action capture for the DevTools.
6
6
  */
7
+ import type { ReduxDetailViewMode } from "./ReduxDetailViewToggle";
7
8
  import type { ReduxAction } from "../types";
8
9
  /** Free tier limit for action history */
9
10
  export declare const FREE_TIER_ACTION_LIMIT = 25;
@@ -26,8 +27,19 @@ interface ReduxModalProps {
26
27
  * on demand — wire-form snapshots carry markers instead of trees.
27
28
  */
28
29
  onActionSelect?: (action: ReduxAction) => void;
30
+ /**
31
+ * Open straight into this action's detail view, by action id. Applied once
32
+ * the id appears in the visible list (the list can arrive after mount when
33
+ * actions are mirrored in), then left alone — Back closes the detail and it
34
+ * stays closed. The counterpart to `onActionSelect`, for hosts that deep-link
35
+ * INTO an action (the docs live tour; a future MCP/desktop "show me this
36
+ * action" jump). Null/undefined means "don't touch the selection".
37
+ */
38
+ initialSelectedActionId?: string | null;
39
+ /** Which detail view that deep-link opens on. See ReduxActionDetailContent. */
40
+ initialDetailView?: ReduxDetailViewMode;
29
41
  }
30
- export declare function ReduxModal({ visible, onClose, onBack, onMinimize, enableSharedModalDimensions, inline, onActionSelect, }: ReduxModalProps): import("react").JSX.Element | null;
42
+ export declare function ReduxModal({ visible, onClose, onBack, onMinimize, enableSharedModalDimensions, inline, onActionSelect, initialSelectedActionId, initialDetailView, }: ReduxModalProps): import("react").JSX.Element | null;
31
43
  /**
32
44
  * The same Redux tool as `ReduxModal`, rendered INLINE for hosts that place
33
45
  * tools in a panel rather than a modal. Exists so there is exactly one
@@ -1 +1 @@
1
- {"version":3,"file":"ReduxModal.d.ts","sourceRoot":"","sources":["../../../../src/redux/components/ReduxModal.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyCH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,yCAAyC;AACzC,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,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;CAChD;AAgBD,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,EACnC,MAAc,EACd,cAAc,GACf,EAAE,eAAe,sCAmbjB;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;AAyCH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,yCAAyC;AACzC,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,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;AAgBD,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,EACnC,MAAc,EACd,cAAc,EACd,uBAAuB,EACvB,iBAAiB,GAClB,EAAE,eAAe,sCAmcjB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,GAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAM,+BAGpE"}
@@ -1,3 +1,4 @@
1
+ import type { ActionMeta } from "../types";
1
2
  /**
2
3
  * Sync adapter for the redux tool, consumed by @buoy-gg/external-sync's
3
4
  * `useExternalSync` (structurally matches its ToolSyncAdapter interface so
@@ -38,7 +39,7 @@ export declare const reduxSyncAdapter: {
38
39
  category: import("../types").ActionCategory;
39
40
  sliceName: string | null;
40
41
  actionName: string;
41
- meta?: import("../types").ActionMeta;
42
+ meta?: ActionMeta;
42
43
  error?: unknown;
43
44
  payloadPreview: string;
44
45
  diffSummary: string;
@@ -62,6 +63,8 @@ export declare const reduxSyncAdapter: {
62
63
  nextState?: undefined;
63
64
  payload?: undefined;
64
65
  action?: undefined;
66
+ meta?: undefined;
67
+ error?: undefined;
65
68
  } | {
66
69
  found: true;
67
70
  id: string;
@@ -71,6 +74,8 @@ export declare const reduxSyncAdapter: {
71
74
  nextState?: undefined;
72
75
  payload?: undefined;
73
76
  action?: undefined;
77
+ meta?: undefined;
78
+ error?: undefined;
74
79
  } | {
75
80
  found: true;
76
81
  id: string;
@@ -78,6 +83,8 @@ export declare const reduxSyncAdapter: {
78
83
  nextState: unknown;
79
84
  payload: unknown;
80
85
  action: unknown;
86
+ meta: ActionMeta | undefined;
87
+ error: unknown;
81
88
  reason?: undefined;
82
89
  evicted?: undefined;
83
90
  };
@@ -1 +1 @@
1
- {"version":3,"file":"reduxSyncAdapter.d.ts","sourceRoot":"","sources":["../../../../src/redux/sync/reduxSyncAdapter.ts"],"names":[],"mappings":"AAsDA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,gBAAgB;;IAE3B;;;;;;;;OAQG;;;;;;;;;;;;;;;;;;;;;0BAiBmB,MAAM,IAAI;;;QAK9B;;;;WAIG;kCACuB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA8BjC;;;WAGG;2BACgB,OAAO;;oBA7FZ,MAAM,EAAE;YACtB,4DAA4D;;;;;;YAwGxD,wEAAwE;;;;QAM5E,gEAAgE;2BAC7C,OAAO;;oBAhHZ,MAAM,EAAE;YACtB,4DAA4D;;;;;;;;;CAyH/D,CAAC"}
1
+ {"version":3,"file":"reduxSyncAdapter.d.ts","sourceRoot":"","sources":["../../../../src/redux/sync/reduxSyncAdapter.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AA4D3C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,gBAAgB;;IAE3B;;;;;;;;OAQG;;;;;;;;;;;;;;;;;;;;;0BAsBmB,MAAM,IAAI;;;QAK9B;;;;WAIG;kCACuB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6CjC;;;WAGG;2BACgB,OAAO;;oBAjHZ,MAAM,EAAE;YACtB,4DAA4D;;;;;;YA4HxD,wEAAwE;;;;QAM5E,gEAAgE;2BAC7C,OAAO;;oBApIZ,MAAM,EAAE;YACtB,4DAA4D;;;;;;;;;CA6I/D,CAAC"}
@@ -39,6 +39,8 @@ export declare const PAYLOAD_ON_DEVICE: Readonly<{
39
39
  __buoyPayloadOnDevice: true;
40
40
  note: "Payload stays on the device — fetched on demand via getActionDetail.";
41
41
  }>;
42
+ /** True when a wire-form value is the payload-on-device sentinel. */
43
+ export declare function isPayloadOnDevice(value: unknown): boolean;
42
44
  /**
43
45
  * True when a value is one of the state sentinels (evicted or on-device) —
44
46
  * guards time travel and any consumer that needs a REAL tree.
@@ -1 +1 @@
1
- {"version":3,"file":"reduxActionStore.d.ts","sourceRoot":"","sources":["../../../../src/redux/utils/reduxActionStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAA8B,MAAM,UAAU,CAAC;AAErF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,aAAa;;;EAGxB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;EAG1B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;EAG5B,CAAC;AAEH;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAItD;AAwDD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CA2BrE;AA8HD,cAAM,gBAAgB;IACpB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAoD;IACrE,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,iBAAiB,CAAS;IAElC,SAAS,CACP,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,OAAO,EAClB,SAAS,EAAE,OAAO,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI;IAyEP,UAAU,IAAI,WAAW,EAAE;IAI3B,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIlD,YAAY,IAAI,IAAI;IAYpB;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAWzC;;;;OAIG;IACH,cAAc,IAAI,IAAI;IAItB;;;;OAIG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;;;OAIG;IACH,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;IAuB5C;;;;OAIG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAW5D,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,UAAU,IAAI,OAAO;IAIrB,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAOjE,OAAO,CAAC,eAAe;IAKvB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQhC,QAAQ;;;;;;;IAuBR,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE;IAmBjD,oBAAoB,IAAI,MAAM,EAAE;IAIhC;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE;IAMnD;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE;IAKpD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAOlD;;OAEG;IACH,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAe3D;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAWvC;;;OAGG;IACH,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAkBlD;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
1
+ {"version":3,"file":"reduxActionStore.d.ts","sourceRoot":"","sources":["../../../../src/redux/utils/reduxActionStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAA8B,MAAM,UAAU,CAAC;AAErF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC;;;GAGG;AACH,eAAO,MAAM,aAAa;;;EAGxB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;EAG1B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;EAG5B,CAAC;AAEH,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAMzD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAItD;AAwDD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CA2BrE;AA8HD,cAAM,gBAAgB;IACpB,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,SAAS,CAAoD;IACrE,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,iBAAiB,CAAS;IAElC,SAAS,CACP,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,SAAS,EAAE,OAAO,EAClB,SAAS,EAAE,OAAO,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI;IAyEP,UAAU,IAAI,WAAW,EAAE;IAI3B,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIlD,YAAY,IAAI,IAAI;IAYpB;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAWzC;;;;OAIG;IACH,cAAc,IAAI,IAAI;IAItB;;;;OAIG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;;;OAIG;IACH,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;IA8B5C;;;;OAIG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAW5D,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,UAAU,IAAI,OAAO;IAIrB,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAOjE,OAAO,CAAC,eAAe;IAKvB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQhC,QAAQ;;;;;;;IAuBR,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE;IAmBjD,oBAAoB,IAAI,MAAM,EAAE;IAIhC;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE;IAMnD;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE;IAKpD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAOlD;;OAEG;IACH,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAe3D;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAWvC;;;OAGG;IACH,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAkBlD;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/redux",
3
- "version": "7.0.17",
3
+ "version": "7.0.18",
4
4
  "description": "Redux DevTools inside your React Native app — action log, state diffs & time travel with zero store changes. Part of Buoy devtools.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -31,9 +31,9 @@
31
31
  "**/snapshotProvider.ts"
32
32
  ],
33
33
  "dependencies": {
34
- "@buoy-gg/shared-ui": "^7.0.17",
35
- "@buoy-gg/license": "^7.0.17",
36
- "@buoy-gg/floating-tools-core": "^7.0.17"
34
+ "@buoy-gg/shared-ui": "^7.0.18",
35
+ "@buoy-gg/license": "^7.0.18",
36
+ "@buoy-gg/floating-tools-core": "^7.0.18"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@reduxjs/toolkit": ">=1.9.0",