@buoy-gg/redux 7.0.36 → 7.0.38

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 (69) hide show
  1. package/README.md +37 -9
  2. package/lib/commonjs/index.js +1 -256
  3. package/lib/commonjs/preset.js +1 -90
  4. package/lib/commonjs/redux/components/ReduxActionButton.js +1 -131
  5. package/lib/commonjs/redux/components/ReduxActionDetailContent.js +1 -437
  6. package/lib/commonjs/redux/components/ReduxActionDetailView.js +1 -401
  7. package/lib/commonjs/redux/components/ReduxActionInfoView.js +1 -836
  8. package/lib/commonjs/redux/components/ReduxActionItem.js +1 -334
  9. package/lib/commonjs/redux/components/ReduxAutoInstrument.js +1 -20
  10. package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +1 -50
  11. package/lib/commonjs/redux/components/ReduxIcon.js +1 -18
  12. package/lib/commonjs/redux/components/ReduxModal.js +1 -703
  13. package/lib/commonjs/redux/hooks/useAutoInstrumentRedux.js +1 -187
  14. package/lib/commonjs/redux/hooks/useReduxActions.js +1 -58
  15. package/lib/commonjs/redux/sync/reduxSyncAdapter.js +1 -191
  16. package/lib/commonjs/redux/utils/activeStoreRegistry.js +1 -104
  17. package/lib/commonjs/redux/utils/autoInstrument.js +1 -231
  18. package/lib/commonjs/redux/utils/buoyReduxMiddleware.js +1 -202
  19. package/lib/commonjs/redux/utils/createReduxHistoryAdapter.js +1 -146
  20. package/lib/commonjs/redux/utils/devtoolsHook.js +1 -152
  21. package/lib/commonjs/redux/utils/reduxActionStore.js +1 -473
  22. package/lib/commonjs/redux/utils/snapshotProvider.js +1 -158
  23. package/lib/commonjs/redux/utils/testIDs.js +1 -75
  24. package/lib/module/index.js +1 -125
  25. package/lib/module/preset.js +1 -87
  26. package/lib/module/redux/components/ReduxActionButton.js +1 -128
  27. package/lib/module/redux/components/ReduxActionDetailContent.js +1 -433
  28. package/lib/module/redux/components/ReduxActionDetailView.js +1 -397
  29. package/lib/module/redux/components/ReduxActionInfoView.js +1 -831
  30. package/lib/module/redux/components/ReduxActionItem.js +1 -330
  31. package/lib/module/redux/components/ReduxAutoInstrument.js +1 -17
  32. package/lib/module/redux/components/ReduxDetailViewToggle.js +1 -45
  33. package/lib/module/redux/components/ReduxIcon.js +1 -8
  34. package/lib/module/redux/components/ReduxModal.js +1 -698
  35. package/lib/module/redux/hooks/useAutoInstrumentRedux.js +1 -183
  36. package/lib/module/redux/hooks/useReduxActions.js +1 -54
  37. package/lib/module/redux/sync/reduxSyncAdapter.js +1 -188
  38. package/lib/module/redux/utils/activeStoreRegistry.js +1 -92
  39. package/lib/module/redux/utils/autoInstrument.js +1 -201
  40. package/lib/module/redux/utils/buoyReduxMiddleware.js +1 -188
  41. package/lib/module/redux/utils/createReduxHistoryAdapter.js +1 -142
  42. package/lib/module/redux/utils/devtoolsHook.js +1 -145
  43. package/lib/module/redux/utils/reduxActionStore.js +1 -465
  44. package/lib/module/redux/utils/snapshotProvider.js +1 -157
  45. package/lib/module/redux/utils/testIDs.js +1 -68
  46. package/package.json +5 -5
  47. package/lib/typescript/index.d.ts.map +0 -1
  48. package/lib/typescript/preset.d.ts.map +0 -1
  49. package/lib/typescript/redux/components/ReduxActionButton.d.ts.map +0 -1
  50. package/lib/typescript/redux/components/ReduxActionDetailContent.d.ts.map +0 -1
  51. package/lib/typescript/redux/components/ReduxActionDetailView.d.ts.map +0 -1
  52. package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +0 -1
  53. package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +0 -1
  54. package/lib/typescript/redux/components/ReduxAutoInstrument.d.ts.map +0 -1
  55. package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +0 -1
  56. package/lib/typescript/redux/components/ReduxIcon.d.ts.map +0 -1
  57. package/lib/typescript/redux/components/ReduxModal.d.ts.map +0 -1
  58. package/lib/typescript/redux/hooks/useAutoInstrumentRedux.d.ts.map +0 -1
  59. package/lib/typescript/redux/hooks/useReduxActions.d.ts.map +0 -1
  60. package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts.map +0 -1
  61. package/lib/typescript/redux/types/index.d.ts.map +0 -1
  62. package/lib/typescript/redux/utils/activeStoreRegistry.d.ts.map +0 -1
  63. package/lib/typescript/redux/utils/autoInstrument.d.ts.map +0 -1
  64. package/lib/typescript/redux/utils/buoyReduxMiddleware.d.ts.map +0 -1
  65. package/lib/typescript/redux/utils/createReduxHistoryAdapter.d.ts.map +0 -1
  66. package/lib/typescript/redux/utils/devtoolsHook.d.ts.map +0 -1
  67. package/lib/typescript/redux/utils/reduxActionStore.d.ts.map +0 -1
  68. package/lib/typescript/redux/utils/snapshotProvider.d.ts.map +0 -1
  69. package/lib/typescript/redux/utils/testIDs.d.ts.map +0 -1
@@ -1,187 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useAutoInstrumentRedux = useAutoInstrumentRedux;
7
- exports.useReduxAvailability = useReduxAvailability;
8
- var _react = require("react");
9
- var _autoInstrument = require("../utils/autoInstrument");
10
- var _activeStoreRegistry = require("../utils/activeStoreRegistry");
11
- /**
12
- * React hook for auto-instrumenting Redux stores
13
- *
14
- * Mounted for the app's lifetime by FloatingDevTools (via ReduxAutoInstrument)
15
- * and also called by the Redux modal. Binds Buoy to the store from react-redux
16
- * context:
17
- * - If the store was created through the devtools-hook enhancer, capture is
18
- * already live — this just keeps the registry pointed at it.
19
- * - Otherwise it applies the dispatch-patch fallback (top-level-only capture).
20
- * - If react-redux is missing or there's no Provider above, it fails
21
- * gracefully and records WHY (surfaced by the sync adapter / MCP).
22
- *
23
- * Re-instruments when the store INSTANCE changes (hosts that rebuild their
24
- * store at runtime), so the registry never pins a dead store.
25
- */
26
-
27
- // ============================================
28
- // Safe Module Loading
29
- // ============================================
30
-
31
- /**
32
- * Safely attempt to load react-redux and get useStore hook
33
- */
34
- function getReactReduxUseStore() {
35
- try {
36
- // Dynamic require to handle cases where react-redux isn't installed
37
- // eslint-disable-next-line @typescript-eslint/no-var-requires
38
- const reactRedux = require("react-redux");
39
- return reactRedux.useStore;
40
- } catch {
41
- // react-redux not available
42
- return null;
43
- }
44
- }
45
-
46
- // ============================================
47
- // Hook Types
48
- // ============================================
49
-
50
- // ============================================
51
- // Main Hook
52
- // ============================================
53
-
54
- function useAutoInstrumentRedux(options = {}) {
55
- const {
56
- autoStart = true
57
- } = options;
58
-
59
- // Options live in a ref: this hook is app-lifetime-mounted, and a fresh
60
- // `{...rest}` object every render would churn startInstrumentation's
61
- // identity and re-run the effect on every render.
62
- const optionsRef = (0, _react.useRef)(options);
63
- optionsRef.current = options;
64
- const [isInstrumented, setIsInstrumented] = (0, _react.useState)(false);
65
- const [isLoading, setIsLoading] = (0, _react.useState)(true);
66
- const [error, setError] = (0, _react.useState)(null);
67
- const [store, setStore] = (0, _react.useState)(null);
68
- const cleanupRef = (0, _react.useRef)(null);
69
-
70
- // Check if react-redux is available
71
- const useStoreHook = getReactReduxUseStore();
72
- const isReactReduxAvailable = useStoreHook !== null;
73
-
74
- // Try to get the store using react-redux's useStore
75
- // This must be called unconditionally due to hooks rules
76
- let reduxStore = null;
77
- let storeError = null;
78
- let storeDiagnostic = null;
79
- if (useStoreHook) {
80
- try {
81
- // eslint-disable-next-line react-hooks/rules-of-hooks
82
- reduxStore = useStoreHook();
83
- } catch (e) {
84
- // Not inside a Provider or other error
85
- storeDiagnostic = "no-provider";
86
- storeError = e instanceof Error ? e.message : "Failed to access Redux store. Make sure your app is wrapped in a Redux Provider.";
87
- }
88
- } else {
89
- storeDiagnostic = "no-react-redux";
90
- storeError = "react-redux is not installed or not available";
91
- }
92
-
93
- // Function to start instrumentation
94
- const startInstrumentation = (0, _react.useCallback)(() => {
95
- if (!reduxStore) {
96
- // Record the failure reason for non-React surfaces (sync adapter/MCP).
97
- (0, _activeStoreRegistry.setReduxDiagnostic)(storeDiagnostic);
98
- setError(storeError || "No Redux store available");
99
- setIsLoading(false);
100
- return;
101
- }
102
- try {
103
- // Instrument the store. Idempotent per store: enhancer-created and
104
- // already-patched stores just get (re)registered, so a store SWAP at
105
- // runtime re-binds the registry to the new instance.
106
- const cleanup = (0, _autoInstrument.instrumentStore)(reduxStore, optionsRef.current);
107
- cleanupRef.current = cleanup;
108
- setIsInstrumented(true);
109
- setStore(reduxStore);
110
- setError(null);
111
- } catch (e) {
112
- setError(e instanceof Error ? e.message : "Failed to instrument Redux store");
113
- setIsInstrumented(false);
114
- } finally {
115
- setIsLoading(false);
116
- }
117
- // eslint-disable-next-line react-hooks/exhaustive-deps -- storeError/storeDiagnostic derive from reduxStore
118
- }, [reduxStore]);
119
-
120
- // Function to stop instrumentation
121
- const stopInstrumentation = (0, _react.useCallback)(() => {
122
- if (cleanupRef.current) {
123
- cleanupRef.current();
124
- cleanupRef.current = null;
125
- }
126
- if (store) {
127
- (0, _autoInstrument.uninstrumentStore)(store);
128
- }
129
- setIsInstrumented(false);
130
- setStore(null);
131
- }, [store]);
132
-
133
- // Auto-start instrumentation on mount, and again whenever the store
134
- // INSTANCE changes (hosts that rebuild their store re-point the registry).
135
- (0, _react.useEffect)(() => {
136
- if (autoStart) {
137
- startInstrumentation();
138
- } else {
139
- setIsLoading(false);
140
- }
141
-
142
- // Cleanup on unmount
143
- return () => {
144
- // Note: We intentionally DON'T uninstrument on unmount
145
- // This allows actions to continue being captured even when
146
- // the DevTools modal is closed. The instrumentation persists
147
- // for the lifetime of the app, similar to network/storage tools.
148
- };
149
- }, [autoStart, startInstrumentation]);
150
- return {
151
- isInstrumented,
152
- isLoading,
153
- error,
154
- isReactReduxAvailable,
155
- captureMechanism: (0, _autoInstrument.getInstrumentationStatus)().mechanism,
156
- startInstrumentation,
157
- stopInstrumentation,
158
- store
159
- };
160
- }
161
-
162
- /**
163
- * Lightweight hook to just check if Redux is available
164
- * without auto-instrumenting
165
- */
166
- function useReduxAvailability() {
167
- const useStoreHook = getReactReduxUseStore();
168
- if (!useStoreHook) {
169
- return {
170
- isAvailable: false,
171
- error: "react-redux is not installed"
172
- };
173
- }
174
- try {
175
- // eslint-disable-next-line react-hooks/rules-of-hooks
176
- const store = useStoreHook();
177
- return {
178
- isAvailable: store !== null && store !== undefined,
179
- error: null
180
- };
181
- } catch (e) {
182
- return {
183
- isAvailable: false,
184
- error: e instanceof Error ? e.message : "Not inside a Redux Provider"
185
- };
186
- }
187
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.useAutoInstrumentRedux=useAutoInstrumentRedux,exports.useReduxAvailability=useReduxAvailability;var _react=require("react"),_autoInstrument=require("../utils/autoInstrument"),_activeStoreRegistry=require("../utils/activeStoreRegistry");function getReactReduxUseStore(){try{return require("react-redux").useStore}catch{return null}}function useAutoInstrumentRedux(e={}){const{autoStart:t=!0}=e,r=(0,_react.useRef)(e);r.current=e;const[u,n]=(0,_react.useState)(!1),[a,s]=(0,_react.useState)(!0),[i,o]=(0,_react.useState)(null),[l,c]=(0,_react.useState)(null),d=(0,_react.useRef)(null),R=getReactReduxUseStore(),x=null!==R;let m=null,v=null,_=null;if(R)try{m=R()}catch(e){_="no-provider",v=e instanceof Error?e.message:"Failed to access Redux store. Make sure your app is wrapped in a Redux Provider."}else _="no-react-redux",v="react-redux is not installed or not available";const f=(0,_react.useCallback)(()=>{if(!m)return(0,_activeStoreRegistry.setReduxDiagnostic)(_),o(v||"No Redux store available"),void s(!1);try{const e=(0,_autoInstrument.instrumentStore)(m,r.current);d.current=e,n(!0),c(m),o(null)}catch(e){o(e instanceof Error?e.message:"Failed to instrument Redux store"),n(!1)}finally{s(!1)}},[m]),S=(0,_react.useCallback)(()=>{d.current&&(d.current(),d.current=null),l&&(0,_autoInstrument.uninstrumentStore)(l),n(!1),c(null)},[l]);return(0,_react.useEffect)(()=>(t?f():s(!1),()=>{}),[t,f]),{isInstrumented:u,isLoading:a,error:i,isReactReduxAvailable:x,captureMechanism:(0,_autoInstrument.getInstrumentationStatus)().mechanism,startInstrumentation:f,stopInstrumentation:S,store:l}}function useReduxAvailability(){const e=getReactReduxUseStore();if(!e)return{isAvailable:!1,error:"react-redux is not installed"};try{return{isAvailable:null!=e(),error:null}}catch(e){return{isAvailable:!1,error:e instanceof Error?e.message:"Not inside a Redux Provider"}}}
@@ -1,58 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useReduxActions = useReduxActions;
7
- var _react = require("react");
8
- var _sharedUi = require("@buoy-gg/shared-ui");
9
- var _reduxActionStore = require("../utils/reduxActionStore");
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.
15
- */
16
-
17
- const filterActions = (_actions, filter) => _reduxActionStore.reduxActionStore.filterActions(filter);
18
- function useReduxActions() {
19
- const log = (0, _sharedUi.useChangeLog)(_reduxActionStore.reduxActionStore, {
20
- filterItems: filterActions
21
- });
22
- const [selectedAction, setSelectedAction] = (0, _react.useState)(null);
23
-
24
- // Get stats
25
- const stats = (0, _react.useMemo)(() => {
26
- return _reduxActionStore.reduxActionStore.getStats();
27
- }, [log.items]);
28
-
29
- // Get unique action types
30
- const actionTypes = (0, _react.useMemo)(() => {
31
- return _reduxActionStore.reduxActionStore.getUniqueActionTypes();
32
- }, [log.items]);
33
-
34
- // Clear actions
35
- const clearActions = (0, _react.useCallback)(() => {
36
- _reduxActionStore.reduxActionStore.clearActions();
37
- setSelectedAction(null);
38
- }, []);
39
-
40
- // Get action by ID
41
- const getActionById = (0, _react.useCallback)(id => {
42
- return _reduxActionStore.reduxActionStore.getActionById(id);
43
- }, []);
44
- return {
45
- actions: log.items,
46
- filteredActions: log.filteredItems,
47
- filter: log.filter,
48
- setFilter: log.setFilter,
49
- stats,
50
- clearActions,
51
- isEnabled: log.isEnabled,
52
- toggleCapture: log.toggleCapture,
53
- actionTypes,
54
- getActionById,
55
- selectedAction,
56
- setSelectedAction
57
- };
58
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.useReduxActions=useReduxActions;var _react=require("react"),_sharedUi=require("@buoy-gg/shared-ui"),_reduxActionStore=require("../utils/reduxActionStore");const filterActions=(e,t)=>_reduxActionStore.reduxActionStore.filterActions(t);function useReduxActions(){const e=(0,_sharedUi.useChangeLog)(_reduxActionStore.reduxActionStore,{filterItems:filterActions}),[t,r]=(0,_react.useState)(null),o=(0,_react.useMemo)(()=>_reduxActionStore.reduxActionStore.getStats(),[e.items]),i=(0,_react.useMemo)(()=>_reduxActionStore.reduxActionStore.getUniqueActionTypes(),[e.items]),c=(0,_react.useCallback)(()=>{_reduxActionStore.reduxActionStore.clearActions(),r(null)},[]),s=(0,_react.useCallback)(e=>_reduxActionStore.reduxActionStore.getActionById(e),[]);return{actions:e.items,filteredActions:e.filteredItems,filter:e.filter,setFilter:e.setFilter,stats:o,clearActions:c,isEnabled:e.isEnabled,toggleCapture:e.toggleCapture,actionTypes:i,getActionById:s,selectedAction:t,setSelectedAction:r}}
@@ -1,191 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.reduxSyncAdapter = void 0;
7
- var _reduxActionStore = require("../utils/reduxActionStore");
8
- var _sharedUi = require("@buoy-gg/shared-ui");
9
- var _autoInstrument = require("../utils/autoInstrument");
10
- /** Per-action budget for `payload`/`action`/`meta.arg`/`error` on the snapshot wire. */
11
- const toWireValue = value => (0, _sharedUi.toWire)(value, _reduxActionStore.PAYLOAD_ON_DEVICE);
12
-
13
- /**
14
- * Per-action wire cache. `reduxActionStore` never mutates an action in place —
15
- * it prepends, and `replaceActions` maps to fresh objects — so keying on
16
- * identity is correct and self-invalidating. Without it, every payload,
17
- * `action`, `meta.arg` and `error` in the list is re-measured on all ~5
18
- * snapshots per second for as long as it stays in the list.
19
- */
20
- const toWireAction = (0, _sharedUi.memoByIdentity)(a => {
21
- const wire = (0, _reduxActionStore.isEvictedState)(a.prevState) ? {
22
- ...a
23
- } : {
24
- ...a,
25
- prevState: _reduxActionStore.STATE_ON_DEVICE,
26
- nextState: _reduxActionStore.STATE_ON_DEVICE
27
- };
28
- // A dispatched payload can itself be huge (rehydration actions carry whole
29
- // state trees). The list view renders payloadPreview anyway — oversized /
30
- // unserializable values stay on-device behind markers. `meta.arg` is a
31
- // leftover: RTK copies the thunk argument there, and capping `action` still
32
- // left the extracted copy on the wire.
33
- wire.payload = toWireValue(wire.payload);
34
- wire.action = toWireValue(wire.action);
35
- wire.error = toWireValue(wire.error);
36
- if (wire.meta) {
37
- const arg = toWireValue(wire.meta.arg);
38
- if (arg !== wire.meta.arg) wire.meta = {
39
- ...wire.meta,
40
- arg
41
- };
42
- }
43
- return wire;
44
- });
45
- /** Top-level slice names of the state tree, for the compact (no-values) view. */
46
- function topLevelKeys(state) {
47
- return state && typeof state === "object" && !Array.isArray(state) ? Object.keys(state) : [];
48
- }
49
-
50
- /**
51
- * Why there's no bound store, in a shape remote drivers (MCP/desktop) can turn
52
- * into a SPECIFIC remedy instead of a generic "check your setup".
53
- */
54
- function unavailable() {
55
- const status = (0, _autoInstrument.getInstrumentationStatus)();
56
- const reason = status.diagnostic ?? "not-instrumented";
57
- return {
58
- available: false,
59
- slices: [],
60
- /** 'no-react-redux' | 'no-provider' | 'not-instrumented' */
61
- reason
62
- };
63
- }
64
-
65
- /**
66
- * Sync adapter for the redux tool, consumed by @buoy-gg/external-sync's
67
- * `useExternalSync` (structurally matches its ToolSyncAdapter interface so
68
- * this package doesn't need a dependency on it).
69
- *
70
- * Actions are captured from app startup — by the store-creation enhancer or
71
- * the explicit middleware (full capture), or by the dispatch-patch fallback
72
- * mounted with FloatingDevTools (top-level-only) — independent of whether a
73
- * dashboard is watching. Subscribing here only streams what's already
74
- * recorded.
75
- *
76
- * `getState`/`dispatch` read & drive the live instrumented store (via
77
- * getActiveStore()) so a remote driver (MCP/LLM) can inspect current state and
78
- * dispatch actions — redux is action-based, so the *current state* isn't in the
79
- * action-log snapshot.
80
- */
81
- const reduxSyncAdapter = exports.reduxSyncAdapter = (0, _sharedUi.createSyncAdapter)({
82
- version: 2,
83
- /**
84
- * WIRE-FORM snapshot: actions WITHOUT raw prevState/nextState trees.
85
- * Shipping the trees serialized up to 25×2 full state trees through
86
- * socket.emit per action — no guard on that path — which froze and
87
- * native-OOM-crashed enterprise-scale apps whenever a dashboard was
88
- * connected (root cause confirmed by patch-and-retest). Dashboards fetch
89
- * trees on demand via `getActionDetail`; already-evicted entries keep the
90
- * eviction sentinel so consumers can distinguish "fetchable" from "gone".
91
- */
92
- getSnapshot: () => _reduxActionStore.reduxActionStore.getActions().map(toWireAction),
93
- subscribe: onChange => _reduxActionStore.reduxActionStore.subscribe(onChange),
94
- actions: {
95
- clearEvents: () => {
96
- _reduxActionStore.reduxActionStore.clearActions();
97
- },
98
- /**
99
- * On-demand detail: one action's real prevState/nextState trees.
100
- * The per-snapshot stream stays tree-free; this is the explicit,
101
- * size-guarded channel for the detail pane.
102
- */
103
- getActionDetail: params => {
104
- const {
105
- id
106
- } = (0, _sharedUi.readParams)(params);
107
- if (!id) return {
108
- found: false,
109
- reason: "missing id"
110
- };
111
- const action = _reduxActionStore.reduxActionStore.getActionById(id);
112
- if (!action) return {
113
- found: false,
114
- reason: "unknown id"
115
- };
116
- if ((0, _reduxActionStore.isEvictedState)(action.prevState)) {
117
- return {
118
- found: true,
119
- id,
120
- evicted: true,
121
- reason: `Raw state was evicted (retained for recent actions only).`
122
- };
123
- }
124
- // Per-field cap: oversized fields degrade individually instead of
125
- // failing the whole detail (a giant payload shouldn't hide the trees).
126
- const cap = value => (0, _sharedUi.capDetail)(value, _sharedUi.WIRE_DETAIL_LIMIT_BYTES);
127
- const capMeta = meta => {
128
- if (!meta) return meta;
129
- const arg = cap(meta.arg);
130
- return arg === meta.arg ? meta : {
131
- ...meta,
132
- arg
133
- };
134
- };
135
- return {
136
- found: true,
137
- id,
138
- prevState: cap(action.prevState),
139
- nextState: cap(action.nextState),
140
- payload: cap(action.payload),
141
- action: cap(action.action),
142
- meta: capMeta(action.meta),
143
- error: cap(action.error)
144
- };
145
- },
146
- /**
147
- * Compact current-state reader: the instrumented store's slice names, and
148
- * the full state tree only when `includeValues` is set (heavy).
149
- */
150
- getState: params => {
151
- const {
152
- includeValues = false
153
- } = (0, _sharedUi.readParams)(params);
154
- const store = (0, _autoInstrument.getActiveStore)();
155
- if (!store) {
156
- return unavailable();
157
- }
158
- const state = store.getState();
159
- const status = (0, _autoInstrument.getInstrumentationStatus)();
160
- return {
161
- available: true,
162
- slices: topLevelKeys(state),
163
- /** 'full' | 'top-level-only' — what the live capture mechanism sees. */
164
- capture: status.capture,
165
- mechanism: status.mechanism,
166
- ...(includeValues ? {
167
- state
168
- } : {})
169
- };
170
- },
171
- /** Dispatch a plain action object to the instrumented store. */
172
- dispatch: params => {
173
- const {
174
- action
175
- } = (0, _sharedUi.readParams)(params);
176
- const store = (0, _autoInstrument.getActiveStore)();
177
- if (!store) {
178
- return {
179
- dispatched: false,
180
- ...unavailable()
181
- };
182
- }
183
- if (!action) throw new Error("dispatch requires an `action`");
184
- store.dispatch(action);
185
- return {
186
- dispatched: true,
187
- type: action.type
188
- };
189
- }
190
- }
191
- });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.reduxSyncAdapter=void 0;var _reduxActionStore=require("../utils/reduxActionStore"),_sharedUi=require("@buoy-gg/shared-ui"),_autoInstrument=require("../utils/autoInstrument");const toWireValue=e=>(0,_sharedUi.toWire)(e,_reduxActionStore.PAYLOAD_ON_DEVICE),toWireAction=(0,_sharedUi.memoByIdentity)(e=>{const t=(0,_reduxActionStore.isEvictedState)(e.prevState)?{...e}:{...e,prevState:_reduxActionStore.STATE_ON_DEVICE,nextState:_reduxActionStore.STATE_ON_DEVICE};if(t.payload=toWireValue(t.payload),t.action=toWireValue(t.action),t.error=toWireValue(t.error),t.meta){const e=toWireValue(t.meta.arg);e!==t.meta.arg&&(t.meta={...t.meta,arg:e})}return t});function topLevelKeys(e){return e&&"object"==typeof e&&!Array.isArray(e)?Object.keys(e):[]}function unavailable(){return{available:!1,slices:[],reason:(0,_autoInstrument.getInstrumentationStatus)().diagnostic??"not-instrumented"}}const reduxSyncAdapter=exports.reduxSyncAdapter=(0,_sharedUi.createSyncAdapter)({version:2,getSnapshot:()=>_reduxActionStore.reduxActionStore.getActions().map(toWireAction),subscribe:e=>_reduxActionStore.reduxActionStore.subscribe(e),actions:{clearEvents:()=>{_reduxActionStore.reduxActionStore.clearActions()},getActionDetail:e=>{const{id:t}=(0,_sharedUi.readParams)(e);if(!t)return{found:!1,reason:"missing id"};const r=_reduxActionStore.reduxActionStore.getActionById(t);if(!r)return{found:!1,reason:"unknown id"};if((0,_reduxActionStore.isEvictedState)(r.prevState))return{found:!0,id:t,evicted:!0,reason:"Raw state was evicted (retained for recent actions only)."};const a=e=>(0,_sharedUi.capDetail)(e,_sharedUi.WIRE_DETAIL_LIMIT_BYTES);return{found:!0,id:t,prevState:a(r.prevState),nextState:a(r.nextState),payload:a(r.payload),action:a(r.action),meta:(e=>{if(!e)return e;const t=a(e.arg);return t===e.arg?e:{...e,arg:t}})(r.meta),error:a(r.error)}},getState:e=>{const{includeValues:t=!1}=(0,_sharedUi.readParams)(e),r=(0,_autoInstrument.getActiveStore)();if(!r)return unavailable();const a=r.getState(),n=(0,_autoInstrument.getInstrumentationStatus)();return{available:!0,slices:topLevelKeys(a),capture:n.capture,mechanism:n.mechanism,...t?{state:a}:{}}},dispatch:e=>{const{action:t}=(0,_sharedUi.readParams)(e),r=(0,_autoInstrument.getActiveStore)();if(!r)return{dispatched:!1,...unavailable()};if(!t)throw new Error("dispatch requires an `action`");return r.dispatch(t),{dispatched:!0,type:t.type}}}});
@@ -1,104 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.ENHANCER_SYMBOL = void 0;
7
- exports.getActiveStore = getActiveStore;
8
- exports.getCaptureMechanism = getCaptureMechanism;
9
- exports.getInstrumentationStatus = getInstrumentationStatus;
10
- exports.isTimeTravelAvailable = isTimeTravelAvailable;
11
- exports.markTimeTravelReducer = markTimeTravelReducer;
12
- exports.registerActiveStore = registerActiveStore;
13
- exports.setReduxDiagnostic = setReduxDiagnostic;
14
- exports.unregisterActiveStore = unregisterActiveStore;
15
- /**
16
- * Shared registry for the one live Redux store Buoy is bound to, plus how it
17
- * got bound (the capture mechanism) and why binding failed when it did.
18
- *
19
- * Lives in its own module so the three capture paths (devtools-hook enhancer,
20
- * explicit middleware, dispatch-patch fallback) and the sync adapter can all
21
- * import it without cycles.
22
- */
23
-
24
- /** The minimum store surface Buoy needs (middleware storeApi satisfies this). */
25
-
26
- /**
27
- * How the store got instrumented:
28
- * - `enhancer` — store-creation-time enhancer via the Redux DevTools global.
29
- * FULL capture (thunk-internal & RTK Query actions included).
30
- * - `middleware` — user-added buoyReduxMiddleware. FULL capture.
31
- * - `patch` — store.dispatch patched after creation (auto-instrumentation
32
- * fallback). TOP-LEVEL-ONLY capture: actions dispatched from
33
- * inside middleware/thunks bypass the patch.
34
- */
35
-
36
- /** Why there is no bound store, when there isn't one. */
37
-
38
- /** Marks stores created through the Buoy devtools-hook enhancer. */
39
- const ENHANCER_SYMBOL = exports.ENHANCER_SYMBOL = Symbol.for("@@buoy/enhancerInstrumented");
40
- let activeStore = null;
41
- let mechanism = null;
42
- let diagnostic = null;
43
- let timeTravelReducer = false;
44
- function registerActiveStore(store, mech) {
45
- activeStore = store;
46
- mechanism = mech;
47
- diagnostic = null;
48
- }
49
- function unregisterActiveStore(store) {
50
- if (activeStore === store) {
51
- activeStore = null;
52
- mechanism = null;
53
- }
54
- }
55
- function getActiveStore() {
56
- return activeStore;
57
- }
58
- function getCaptureMechanism() {
59
- return mechanism;
60
- }
61
-
62
- /**
63
- * Record that a reducer able to serve `BUOY_JUMP_TO_STATE` is in the store.
64
- *
65
- * Called by the devtools-hook enhancer and by `withBuoyDevTools` — the only
66
- * two things that wrap the root reducer. Capture and time travel are separate
67
- * capabilities and they are wired separately: a store can be fully captured
68
- * through `buoyReduxMiddleware` and still have no way to restore a state,
69
- * because middleware sits ABOVE the reducer and cannot replace what it
70
- * returns.
71
- */
72
- function markTimeTravelReducer() {
73
- timeTravelReducer = true;
74
- }
75
-
76
- /**
77
- * Whether pressing JUMP can actually do anything.
78
- *
79
- * Worth a first-class answer rather than a try-and-see, because the failure is
80
- * invisible: `jumpToState` dispatches into a store that simply does not
81
- * recognise the action, the reducer returns the state it already had, and the
82
- * screen does not move. From the outside that is indistinguishable from a
83
- * devtool that is broken.
84
- */
85
- function isTimeTravelAvailable() {
86
- return timeTravelReducer && activeStore !== null;
87
- }
88
-
89
- /**
90
- * Recorded by the auto-instrument hook so non-React surfaces (sync adapter,
91
- * MCP) can report WHY there's no store instead of a generic failure.
92
- */
93
- function setReduxDiagnostic(d) {
94
- diagnostic = d;
95
- }
96
- function getInstrumentationStatus() {
97
- return {
98
- mechanism,
99
- capture: mechanism === "enhancer" || mechanism === "middleware" ? "full" : mechanism === "patch" ? "top-level-only" : "none",
100
- hasStore: activeStore !== null,
101
- timeTravel: isTimeTravelAvailable(),
102
- diagnostic
103
- };
104
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ENHANCER_SYMBOL=void 0,exports.getActiveStore=getActiveStore,exports.getCaptureMechanism=getCaptureMechanism,exports.getInstrumentationStatus=getInstrumentationStatus,exports.isTimeTravelAvailable=isTimeTravelAvailable,exports.markTimeTravelReducer=markTimeTravelReducer,exports.registerActiveStore=registerActiveStore,exports.setReduxDiagnostic=setReduxDiagnostic,exports.unregisterActiveStore=unregisterActiveStore;const ENHANCER_SYMBOL=exports.ENHANCER_SYMBOL=Symbol.for("@@buoy/enhancerInstrumented");let activeStore=null,mechanism=null,diagnostic=null,timeTravelReducer=!1;function registerActiveStore(e,t){activeStore=e,mechanism=t,diagnostic=null}function unregisterActiveStore(e){activeStore===e&&(activeStore=null,mechanism=null)}function getActiveStore(){return activeStore}function getCaptureMechanism(){return mechanism}function markTimeTravelReducer(){timeTravelReducer=!0}function isTimeTravelAvailable(){return timeTravelReducer&&null!==activeStore}function setReduxDiagnostic(e){diagnostic=e}function getInstrumentationStatus(){return{mechanism:mechanism,capture:"enhancer"===mechanism||"middleware"===mechanism?"full":"patch"===mechanism?"top-level-only":"none",hasStore:null!==activeStore,timeTravel:isTimeTravelAvailable(),diagnostic:diagnostic}}