@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.
Files changed (40) hide show
  1. package/lib/commonjs/preset.js +14 -22
  2. package/lib/commonjs/redux/components/ReduxActionButton.js +1 -1
  3. package/lib/commonjs/redux/components/ReduxActionDetailContent.js +5 -5
  4. package/lib/commonjs/redux/components/ReduxActionDetailView.js +3 -3
  5. package/lib/commonjs/redux/components/ReduxActionInfoView.js +16 -68
  6. package/lib/commonjs/redux/components/ReduxActionItem.js +65 -119
  7. package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +15 -109
  8. package/lib/commonjs/redux/components/ReduxModal.js +25 -70
  9. package/lib/commonjs/redux/hooks/useReduxActions.js +16 -33
  10. package/lib/commonjs/redux/sync/reduxSyncAdapter.js +11 -29
  11. package/lib/commonjs/redux/utils/reduxActionStore.js +24 -94
  12. package/lib/commonjs/redux/utils/snapshotProvider.js +17 -80
  13. package/lib/module/preset.js +13 -20
  14. package/lib/module/redux/components/ReduxActionButton.js +2 -2
  15. package/lib/module/redux/components/ReduxActionDetailContent.js +6 -6
  16. package/lib/module/redux/components/ReduxActionDetailView.js +4 -4
  17. package/lib/module/redux/components/ReduxActionInfoView.js +9 -61
  18. package/lib/module/redux/components/ReduxActionItem.js +66 -120
  19. package/lib/module/redux/components/ReduxDetailViewToggle.js +17 -111
  20. package/lib/module/redux/components/ReduxModal.js +27 -72
  21. package/lib/module/redux/hooks/useReduxActions.js +17 -34
  22. package/lib/module/redux/sync/reduxSyncAdapter.js +12 -30
  23. package/lib/module/redux/utils/reduxActionStore.js +25 -95
  24. package/lib/module/redux/utils/snapshotProvider.js +18 -81
  25. package/lib/typescript/preset.d.ts +3 -9
  26. package/lib/typescript/preset.d.ts.map +1 -1
  27. package/lib/typescript/redux/components/ReduxActionDetailContent.d.ts.map +1 -1
  28. package/lib/typescript/redux/components/ReduxActionDetailView.d.ts.map +1 -1
  29. package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +1 -1
  30. package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +1 -1
  31. package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts +2 -1
  32. package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +1 -1
  33. package/lib/typescript/redux/components/ReduxModal.d.ts.map +1 -1
  34. package/lib/typescript/redux/hooks/useReduxActions.d.ts +3 -0
  35. package/lib/typescript/redux/hooks/useReduxActions.d.ts.map +1 -1
  36. package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts +68 -82
  37. package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts.map +1 -1
  38. package/lib/typescript/redux/utils/reduxActionStore.d.ts +2 -29
  39. package/lib/typescript/redux/utils/reduxActionStore.d.ts.map +1 -1
  40. package/package.json +4 -4
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.ReduxDetailViewToggle = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
- var _reactNative = require("react-native");
9
8
  var _sharedUi = require("@buoy-gg/shared-ui");
10
9
  var _jsxRuntime = require("react/jsx-runtime");
11
10
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
@@ -13,132 +12,39 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
13
12
  * ReduxDetailViewToggle
14
13
  *
15
14
  * Three-card toggle for switching between Action, State, and Diff views.
16
- * Redux-specific component for the enhanced detail view.
15
+ * The cards themselves are the shared `DetailViewToggle`; this file owns
16
+ * the redux view list and testID prefix.
17
17
  */
18
18
 
19
- const VIEW_CONFIGS = [{
19
+ // Active-card chrome takes the single night accent (the per-view
20
+ // warning/info/success tints were selection chrome, not data).
21
+ const VIEWS = [{
20
22
  key: "action",
21
23
  label: "ACTION",
22
24
  description: "View action details",
23
- icon: _sharedUi.FileText,
24
- // Active-card chrome takes the single night accent (the per-view
25
- // warning/info/success tints were selection chrome, not data).
26
- activeColor: _sharedUi.night.color.accent
25
+ icon: _sharedUi.FileText
27
26
  }, {
28
27
  key: "state",
29
28
  label: "STATE",
30
29
  description: "View current state",
31
- icon: _sharedUi.Database,
32
- activeColor: _sharedUi.night.color.accent
30
+ icon: _sharedUi.Database
33
31
  }, {
34
32
  key: "diff",
35
33
  label: "DIFF",
36
34
  description: "Compare changes",
37
- icon: _sharedUi.GitBranch,
38
- activeColor: _sharedUi.night.color.accent
35
+ icon: _sharedUi.GitBranch
39
36
  }];
37
+ const DIFF_DISABLED = ["diff"];
40
38
  const ReduxDetailViewToggle = exports.ReduxDetailViewToggle = /*#__PURE__*/(0, _react.memo)(function ReduxDetailViewToggle({
41
39
  activeView,
42
40
  onViewChange,
43
41
  diffDisabled = false
44
42
  }) {
45
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
46
- style: styles.container,
47
- children: VIEW_CONFIGS.map(config => {
48
- const isActive = activeView === config.key;
49
- const isDisabled = config.key === "diff" && diffDisabled;
50
- const IconComponent = config.icon;
51
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
52
- style: [styles.card, isActive && [styles.cardActive, {
53
- borderColor: config.activeColor
54
- }], isDisabled && styles.cardDisabled],
55
- onPress: () => !isDisabled && onViewChange(config.key),
56
- activeOpacity: isDisabled ? 1 : 0.8,
57
- disabled: isDisabled,
58
- testID: `buoy-redux-view-${config.key}`,
59
- accessibilityRole: "button",
60
- accessibilityLabel: config.label,
61
- accessibilityState: {
62
- selected: isActive,
63
- disabled: isDisabled
64
- },
65
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
66
- style: styles.cardContent,
67
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(IconComponent, {
68
- size: 14,
69
- color: isActive ? config.activeColor : isDisabled ? _sharedUi.night.color.textTertiary : _sharedUi.night.color.textSecondary
70
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
71
- style: [styles.cardLabel, isActive && [styles.cardLabelActive, {
72
- color: config.activeColor
73
- }], isDisabled && styles.cardLabelDisabled],
74
- children: config.label
75
- })]
76
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
77
- style: [styles.cardDescription, isActive && styles.cardDescriptionActive, isDisabled && styles.cardDescriptionDisabled],
78
- children: config.description
79
- })]
80
- }, config.key);
81
- })
43
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.DetailViewToggle, {
44
+ views: VIEWS,
45
+ activeView: activeView,
46
+ onViewChange: onViewChange,
47
+ disabledKeys: diffDisabled ? DIFF_DISABLED : undefined,
48
+ testIDPrefix: "buoy-redux"
82
49
  });
83
- });
84
- const styles = _reactNative.StyleSheet.create({
85
- container: {
86
- flexDirection: "row",
87
- gap: 8,
88
- padding: 14,
89
- // Transparent so the night sheet's star field shows through.
90
- backgroundColor: "transparent"
91
- },
92
- card: {
93
- flex: 1,
94
- backgroundColor: _sharedUi.night.color.surface,
95
- borderRadius: 12,
96
- borderWidth: 1,
97
- borderColor: _sharedUi.night.color.border,
98
- padding: 10,
99
- gap: 4
100
- },
101
- cardActive: {
102
- borderWidth: 1.5,
103
- backgroundColor: _sharedUi.night.color.accentSoft,
104
- shadowColor: _sharedUi.night.color.accent,
105
- shadowOffset: {
106
- width: 0,
107
- height: 2
108
- },
109
- shadowOpacity: 0.1,
110
- shadowRadius: 8,
111
- elevation: 3
112
- },
113
- cardDisabled: {
114
- opacity: 0.5
115
- },
116
- cardContent: {
117
- flexDirection: "row",
118
- alignItems: "center",
119
- gap: 6
120
- },
121
- cardLabel: {
122
- fontSize: 10,
123
- fontWeight: "700",
124
- letterSpacing: 0.5,
125
- color: _sharedUi.night.color.textSecondary
126
- },
127
- cardLabelActive: {
128
- color: _sharedUi.night.color.text
129
- },
130
- cardLabelDisabled: {
131
- color: _sharedUi.night.color.textTertiary
132
- },
133
- cardDescription: {
134
- fontSize: 9,
135
- color: _sharedUi.night.color.textTertiary,
136
- lineHeight: 12
137
- },
138
- cardDescriptionActive: {
139
- color: _sharedUi.night.color.textSecondary
140
- },
141
- cardDescriptionDisabled: {
142
- color: _sharedUi.night.color.textTertiary
143
- }
144
50
  });
@@ -271,49 +271,29 @@ function ReduxModal({
271
271
  onBack: onBack
272
272
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Content, {
273
273
  title: "",
274
- children: isSearchActive ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
275
- style: styles.headerSearchContainer,
276
- testID: `${_testIDs.REDUX_TEST_ID}-search`,
277
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Search, {
278
- size: 14,
279
- color: _sharedUi.night.color.textSecondary
280
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
281
- ref: searchInputRef,
282
- testID: `${_testIDs.REDUX_TEST_ID}-search-field`,
283
- style: styles.headerSearchInput,
284
- placeholder: "Search action types...",
285
- placeholderTextColor: _sharedUi.night.color.textTertiary,
286
- value: searchText,
287
- onChangeText: handleSearch,
288
- onSubmitEditing: () => searchInputRef.current?.blur()
289
- // Stay open while the query still filters the list.
290
- //
291
- // Collapsing it on blur hid the reason rows were missing: the
292
- // header went back to its chips — which count the WHOLE
293
- // capture, not the filtered list — while the list stayed
294
- // narrowed, so the tool showed "4 actions" above a single row
295
- // and offered nothing to explain the gap. The only way back
296
- // was to reopen a field the user had no reason to think was
297
- // still armed.
298
- ,
299
- onBlur: () => {
300
- if (searchText.length === 0) setIsSearchActive(false);
301
- },
302
- accessibilityLabel: "Search action types",
303
- autoCapitalize: "none",
304
- autoCorrect: false,
305
- returnKeyType: "search"
306
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
307
- onPress: closeSearch,
308
- style: styles.headerSearchClear,
309
- testID: `${_testIDs.REDUX_TEST_ID}-search-clear`,
310
- accessibilityRole: "button",
311
- accessibilityLabel: "Close search",
312
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.X, {
313
- size: 14,
314
- color: _sharedUi.night.color.textSecondary
315
- })
316
- })]
274
+ children: isSearchActive ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Search, {
275
+ value: searchText,
276
+ onChangeText: handleSearch,
277
+ onCancel: closeSearch,
278
+ placeholder: "Search action types...",
279
+ accessibilityLabel: "Search action types",
280
+ iconSize: 14,
281
+ testID: `${_testIDs.REDUX_TEST_ID}-search-field`,
282
+ containerTestID: `${_testIDs.REDUX_TEST_ID}-search`,
283
+ clearTestID: `${_testIDs.REDUX_TEST_ID}-search-clear`
284
+ // Stay open while the query still filters the list.
285
+ //
286
+ // Collapsing it on blur hid the reason rows were missing: the
287
+ // header went back to its chips — which count the WHOLE
288
+ // capture, not the filtered list — while the list stayed
289
+ // narrowed, so the tool showed "4 actions" above a single row
290
+ // and offered nothing to explain the gap. The only way back
291
+ // was to reopen a field the user had no reason to think was
292
+ // still armed.
293
+ ,
294
+ onBlur: () => {
295
+ if (searchText.length === 0) setIsSearchActive(false);
296
+ }
317
297
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
318
298
  style: styles.headerChipRow,
319
299
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
@@ -508,11 +488,7 @@ function ReduxModal({
508
488
  keyExtractor: keyExtractor,
509
489
  contentContainerStyle: styles.listContent,
510
490
  showsVerticalScrollIndicator: true,
511
- removeClippedSubviews: true,
512
- initialNumToRender: 12,
513
- maxToRenderPerBatch: 8,
514
- windowSize: 5,
515
- updateCellsBatchingPeriod: 50
491
+ ..._sharedUi.EVENT_LIST_PRESET
516
492
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyState, {
517
493
  isEnabled: isEnabled,
518
494
  query: searchText,
@@ -598,27 +574,6 @@ const styles = _reactNative.StyleSheet.create({
598
574
  // Transparent so JsModal's ToolBackground shows through (the modal paints opaque base beneath it).
599
575
  backgroundColor: "transparent"
600
576
  },
601
- headerSearchContainer: {
602
- flexDirection: "row",
603
- alignItems: "center",
604
- backgroundColor: _sharedUi.night.color.surfaceElevated,
605
- borderRadius: 10,
606
- borderWidth: 1,
607
- borderColor: _sharedUi.night.color.border,
608
- paddingHorizontal: 12,
609
- paddingVertical: 5
610
- },
611
- headerSearchInput: {
612
- flex: 1,
613
- color: _sharedUi.night.color.text,
614
- fontSize: 13,
615
- marginLeft: 6,
616
- paddingVertical: 2
617
- },
618
- headerSearchClear: {
619
- marginLeft: 6,
620
- padding: 4
621
- },
622
577
  headerChipRow: {
623
578
  flexDirection: "row",
624
579
  alignItems: "center",
@@ -648,7 +603,7 @@ const styles = _reactNative.StyleSheet.create({
648
603
  headerChipValue: {
649
604
  fontSize: 12,
650
605
  fontWeight: "600",
651
- fontFamily: "monospace"
606
+ fontFamily: _sharedUi.monoFont
652
607
  },
653
608
  headerActionButton: {
654
609
  width: 32,
@@ -5,41 +5,31 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.useReduxActions = useReduxActions;
7
7
  var _react = require("react");
8
+ var _sharedUi = require("@buoy-gg/shared-ui");
8
9
  var _reduxActionStore = require("../utils/reduxActionStore");
9
10
  /**
10
11
  * Hook for consuming Redux actions from the store
12
+ *
13
+ * The subscribe / filter / pause / clear plumbing is shared `useChangeLog`;
14
+ * this file owns the redux-specific stats, action types and selection.
11
15
  */
12
16
 
17
+ const filterActions = (_actions, filter) => _reduxActionStore.reduxActionStore.filterActions(filter);
13
18
  function useReduxActions() {
14
- const [actions, setActions] = (0, _react.useState)(() => _reduxActionStore.reduxActionStore.getActions());
15
- const [filter, setFilter] = (0, _react.useState)({});
16
- const [isEnabled, setIsEnabled] = (0, _react.useState)(() => _reduxActionStore.reduxActionStore.getEnabled());
19
+ const log = (0, _sharedUi.useChangeLog)(_reduxActionStore.reduxActionStore, {
20
+ filterItems: filterActions
21
+ });
17
22
  const [selectedAction, setSelectedAction] = (0, _react.useState)(null);
18
23
 
19
- // Subscribe to store changes
20
- (0, _react.useEffect)(() => {
21
- const unsubscribe = _reduxActionStore.reduxActionStore.subscribe(newActions => {
22
- setActions(newActions);
23
- });
24
- return () => {
25
- unsubscribe();
26
- };
27
- }, []);
28
-
29
- // Filter actions based on current filter
30
- const filteredActions = (0, _react.useMemo)(() => {
31
- return _reduxActionStore.reduxActionStore.filterActions(filter);
32
- }, [actions, filter]);
33
-
34
24
  // Get stats
35
25
  const stats = (0, _react.useMemo)(() => {
36
26
  return _reduxActionStore.reduxActionStore.getStats();
37
- }, [actions]);
27
+ }, [log.items]);
38
28
 
39
29
  // Get unique action types
40
30
  const actionTypes = (0, _react.useMemo)(() => {
41
31
  return _reduxActionStore.reduxActionStore.getUniqueActionTypes();
42
- }, [actions]);
32
+ }, [log.items]);
43
33
 
44
34
  // Clear actions
45
35
  const clearActions = (0, _react.useCallback)(() => {
@@ -47,26 +37,19 @@ function useReduxActions() {
47
37
  setSelectedAction(null);
48
38
  }, []);
49
39
 
50
- // Toggle capture
51
- const toggleCapture = (0, _react.useCallback)(() => {
52
- const newEnabled = !isEnabled;
53
- _reduxActionStore.reduxActionStore.setEnabled(newEnabled);
54
- setIsEnabled(newEnabled);
55
- }, [isEnabled]);
56
-
57
40
  // Get action by ID
58
41
  const getActionById = (0, _react.useCallback)(id => {
59
42
  return _reduxActionStore.reduxActionStore.getActionById(id);
60
43
  }, []);
61
44
  return {
62
- actions,
63
- filteredActions,
64
- filter,
65
- setFilter,
45
+ actions: log.items,
46
+ filteredActions: log.filteredItems,
47
+ filter: log.filter,
48
+ setFilter: log.setFilter,
66
49
  stats,
67
50
  clearActions,
68
- isEnabled,
69
- toggleCapture,
51
+ isEnabled: log.isEnabled,
52
+ toggleCapture: log.toggleCapture,
70
53
  actionTypes,
71
54
  getActionById,
72
55
  selectedAction,
@@ -7,19 +7,8 @@ exports.reduxSyncAdapter = void 0;
7
7
  var _reduxActionStore = require("../utils/reduxActionStore");
8
8
  var _sharedUi = require("@buoy-gg/shared-ui");
9
9
  var _autoInstrument = require("../utils/autoInstrument");
10
- /**
11
- * Upper bound for one on-demand action-detail response. Generous — this is a
12
- * single explicit fetch, not a per-action stream — but still guarded so a
13
- * pathological tree can't OOM the device through the reply emit.
14
- */
15
- const MAX_ACTION_DETAIL_BYTES = 8 * 1024 * 1024;
16
-
17
10
  /** Per-action budget for `payload`/`action`/`meta.arg`/`error` on the snapshot wire. */
18
- const MAX_WIRE_PAYLOAD_BYTES = 16 * 1024;
19
- function toWireValue(value) {
20
- if (value === undefined) return value;
21
- return (0, _sharedUi.isOverWireBudget)(value, MAX_WIRE_PAYLOAD_BYTES) ? _reduxActionStore.PAYLOAD_ON_DEVICE : value;
22
- }
11
+ const toWireValue = value => (0, _sharedUi.toWire)(value, _reduxActionStore.PAYLOAD_ON_DEVICE);
23
12
 
24
13
  /**
25
14
  * Per-action wire cache. `reduxActionStore` never mutates an action in place —
@@ -28,10 +17,7 @@ function toWireValue(value) {
28
17
  * `action`, `meta.arg` and `error` in the list is re-measured on all ~5
29
18
  * snapshots per second for as long as it stays in the list.
30
19
  */
31
- const wireCache = new WeakMap();
32
- function toWireAction(a) {
33
- const cached = wireCache.get(a);
34
- if (cached) return cached;
20
+ const toWireAction = (0, _sharedUi.memoByIdentity)(a => {
35
21
  const wire = (0, _reduxActionStore.isEvictedState)(a.prevState) ? {
36
22
  ...a
37
23
  } : {
@@ -54,9 +40,8 @@ function toWireAction(a) {
54
40
  arg
55
41
  };
56
42
  }
57
- wireCache.set(a, wire);
58
43
  return wire;
59
- }
44
+ });
60
45
  /** Top-level slice names of the state tree, for the compact (no-values) view. */
61
46
  function topLevelKeys(state) {
62
47
  return state && typeof state === "object" && !Array.isArray(state) ? Object.keys(state) : [];
@@ -93,7 +78,7 @@ function unavailable() {
93
78
  * dispatch actions — redux is action-based, so the *current state* isn't in the
94
79
  * action-log snapshot.
95
80
  */
96
- const reduxSyncAdapter = exports.reduxSyncAdapter = {
81
+ const reduxSyncAdapter = exports.reduxSyncAdapter = (0, _sharedUi.createSyncAdapter)({
97
82
  version: 2,
98
83
  /**
99
84
  * WIRE-FORM snapshot: actions WITHOUT raw prevState/nextState trees.
@@ -118,7 +103,7 @@ const reduxSyncAdapter = exports.reduxSyncAdapter = {
118
103
  getActionDetail: params => {
119
104
  const {
120
105
  id
121
- } = params ?? {};
106
+ } = (0, _sharedUi.readParams)(params);
122
107
  if (!id) return {
123
108
  found: false,
124
109
  reason: "missing id"
@@ -138,11 +123,7 @@ const reduxSyncAdapter = exports.reduxSyncAdapter = {
138
123
  }
139
124
  // Per-field cap: oversized fields degrade individually instead of
140
125
  // failing the whole detail (a giant payload shouldn't hide the trees).
141
- const cappedNote = {
142
- __buoyTruncated: true,
143
- note: `Exceeds the ${MAX_ACTION_DETAIL_BYTES / (1024 * 1024)}MB detail limit — inspect it on-device.`
144
- };
145
- const cap = value => (0, _sharedUi.isOverWireBudget)(value, MAX_ACTION_DETAIL_BYTES) ? cappedNote : value;
126
+ const cap = value => (0, _sharedUi.capDetail)(value, _sharedUi.WIRE_DETAIL_LIMIT_BYTES);
146
127
  const capMeta = meta => {
147
128
  if (!meta) return meta;
148
129
  const arg = cap(meta.arg);
@@ -169,7 +150,7 @@ const reduxSyncAdapter = exports.reduxSyncAdapter = {
169
150
  getState: params => {
170
151
  const {
171
152
  includeValues = false
172
- } = params ?? {};
153
+ } = (0, _sharedUi.readParams)(params);
173
154
  const store = (0, _autoInstrument.getActiveStore)();
174
155
  if (!store) {
175
156
  return unavailable();
@@ -191,7 +172,7 @@ const reduxSyncAdapter = exports.reduxSyncAdapter = {
191
172
  dispatch: params => {
192
173
  const {
193
174
  action
194
- } = params;
175
+ } = (0, _sharedUi.readParams)(params);
195
176
  const store = (0, _autoInstrument.getActiveStore)();
196
177
  if (!store) {
197
178
  return {
@@ -199,11 +180,12 @@ const reduxSyncAdapter = exports.reduxSyncAdapter = {
199
180
  ...unavailable()
200
181
  };
201
182
  }
183
+ if (!action) throw new Error("dispatch requires an `action`");
202
184
  store.dispatch(action);
203
185
  return {
204
186
  dispatched: true,
205
- type: action?.type
187
+ type: action.type
206
188
  };
207
189
  }
208
190
  }
209
- };
191
+ });