@buoy-gg/redux 2.1.11 → 2.1.13

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 (63) hide show
  1. package/LICENSE +58 -0
  2. package/lib/commonjs/index.js +1 -179
  3. package/lib/commonjs/preset.js +1 -98
  4. package/lib/commonjs/redux/components/ReduxActionButton.js +1 -129
  5. package/lib/commonjs/redux/components/ReduxActionDetailContent.js +1 -380
  6. package/lib/commonjs/redux/components/ReduxActionDetailView.js +1 -401
  7. package/lib/commonjs/redux/components/ReduxActionInfoView.js +1 -838
  8. package/lib/commonjs/redux/components/ReduxActionItem.js +1 -366
  9. package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +1 -134
  10. package/lib/commonjs/redux/components/ReduxIcon.js +1 -18
  11. package/lib/commonjs/redux/components/ReduxModal.js +1 -530
  12. package/lib/commonjs/redux/components/index.js +1 -52
  13. package/lib/commonjs/redux/hooks/index.js +1 -25
  14. package/lib/commonjs/redux/hooks/useAutoInstrumentRedux.js +1 -197
  15. package/lib/commonjs/redux/hooks/useReduxActions.js +1 -75
  16. package/lib/commonjs/redux/index.js +1 -49
  17. package/lib/commonjs/redux/utils/autoInstrument.js +1 -270
  18. package/lib/commonjs/redux/utils/buoyReduxMiddleware.js +1 -166
  19. package/lib/commonjs/redux/utils/createReduxHistoryAdapter.js +1 -146
  20. package/lib/commonjs/redux/utils/index.js +1 -111
  21. package/lib/commonjs/redux/utils/reduxActionStore.js +1 -358
  22. package/lib/module/index.js +1 -87
  23. package/lib/module/preset.js +1 -94
  24. package/lib/module/redux/components/ReduxActionButton.js +1 -126
  25. package/lib/module/redux/components/ReduxActionDetailContent.js +1 -376
  26. package/lib/module/redux/components/ReduxActionDetailView.js +1 -397
  27. package/lib/module/redux/components/ReduxActionInfoView.js +1 -833
  28. package/lib/module/redux/components/ReduxActionItem.js +1 -362
  29. package/lib/module/redux/components/ReduxDetailViewToggle.js +1 -129
  30. package/lib/module/redux/components/ReduxIcon.js +1 -8
  31. package/lib/module/redux/components/ReduxModal.js +1 -525
  32. package/lib/module/redux/components/index.js +1 -7
  33. package/lib/module/redux/hooks/index.js +1 -4
  34. package/lib/module/redux/hooks/useAutoInstrumentRedux.js +1 -193
  35. package/lib/module/redux/hooks/useReduxActions.js +1 -71
  36. package/lib/module/redux/index.js +1 -13
  37. package/lib/module/redux/utils/autoInstrument.js +1 -260
  38. package/lib/module/redux/utils/buoyReduxMiddleware.js +1 -157
  39. package/lib/module/redux/utils/createReduxHistoryAdapter.js +1 -142
  40. package/lib/module/redux/utils/index.js +1 -8
  41. package/lib/module/redux/utils/reduxActionStore.js +1 -354
  42. package/package.json +12 -12
  43. package/lib/typescript/index.d.ts.map +0 -1
  44. package/lib/typescript/preset.d.ts.map +0 -1
  45. package/lib/typescript/redux/components/ReduxActionButton.d.ts.map +0 -1
  46. package/lib/typescript/redux/components/ReduxActionDetailContent.d.ts.map +0 -1
  47. package/lib/typescript/redux/components/ReduxActionDetailView.d.ts.map +0 -1
  48. package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +0 -1
  49. package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +0 -1
  50. package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +0 -1
  51. package/lib/typescript/redux/components/ReduxIcon.d.ts.map +0 -1
  52. package/lib/typescript/redux/components/ReduxModal.d.ts.map +0 -1
  53. package/lib/typescript/redux/components/index.d.ts.map +0 -1
  54. package/lib/typescript/redux/hooks/index.d.ts.map +0 -1
  55. package/lib/typescript/redux/hooks/useAutoInstrumentRedux.d.ts.map +0 -1
  56. package/lib/typescript/redux/hooks/useReduxActions.d.ts.map +0 -1
  57. package/lib/typescript/redux/index.d.ts.map +0 -1
  58. package/lib/typescript/redux/types/index.d.ts.map +0 -1
  59. package/lib/typescript/redux/utils/autoInstrument.d.ts.map +0 -1
  60. package/lib/typescript/redux/utils/buoyReduxMiddleware.d.ts.map +0 -1
  61. package/lib/typescript/redux/utils/createReduxHistoryAdapter.d.ts.map +0 -1
  62. package/lib/typescript/redux/utils/index.d.ts.map +0 -1
  63. package/lib/typescript/redux/utils/reduxActionStore.d.ts.map +0 -1
@@ -1,193 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * React hook for auto-instrumenting Redux stores
5
- *
6
- * This hook automatically patches the Redux store when the component mounts,
7
- * providing zero-config action capture for the Redux DevTools.
8
- *
9
- * Usage:
10
- * - The hook attempts to use react-redux's useStore() to get the store
11
- * - If successful, it instruments the store automatically
12
- * - If react-redux is not available or not in a Provider, it fails gracefully
13
- *
14
- * @example
15
- * ```tsx
16
- * function ReduxDevTools() {
17
- * const { isInstrumented, error } = useAutoInstrumentRedux();
18
- *
19
- * if (error) {
20
- * return <Text>Redux not available: {error}</Text>;
21
- * }
22
- *
23
- * return <ReduxActionList />;
24
- * }
25
- * ```
26
- */
27
-
28
- import { useEffect, useState, useRef, useCallback } from "react";
29
- import { instrumentStore, uninstrumentStore, isStoreInstrumented } from "../utils/autoInstrument";
30
-
31
- // ============================================
32
- // Safe Module Loading
33
- // ============================================
34
-
35
- /**
36
- * Safely attempt to load react-redux and get useStore hook
37
- */
38
- function getReactReduxUseStore() {
39
- try {
40
- // Dynamic require to handle cases where react-redux isn't installed
41
- // eslint-disable-next-line @typescript-eslint/no-var-requires
42
- const reactRedux = require("react-redux");
43
- return reactRedux.useStore;
44
- } catch {
45
- // react-redux not available
46
- return null;
47
- }
48
- }
49
-
50
- // ============================================
51
- // Hook Types
52
- // ============================================
53
-
54
- // ============================================
55
- // Main Hook
56
- // ============================================
57
-
58
- /**
59
- * Hook to automatically instrument Redux store for DevTools
60
- *
61
- * This provides zero-config Redux action capture by:
62
- * 1. Using react-redux's useStore() to get the Redux store
63
- * 2. Automatically patching store.dispatch to capture actions
64
- * 3. Cleaning up when the component unmounts
65
- */
66
- export function useAutoInstrumentRedux(options = {}) {
67
- const {
68
- autoStart = true,
69
- ...instrumentOptions
70
- } = options;
71
- const [isInstrumented, setIsInstrumented] = useState(false);
72
- const [isLoading, setIsLoading] = useState(true);
73
- const [error, setError] = useState(null);
74
- const [store, setStore] = useState(null);
75
- const cleanupRef = useRef(null);
76
-
77
- // Check if react-redux is available
78
- const useStoreHook = getReactReduxUseStore();
79
- const isReactReduxAvailable = useStoreHook !== null;
80
-
81
- // Try to get the store using react-redux's useStore
82
- // This must be called unconditionally due to hooks rules
83
- let reduxStore = null;
84
- let storeError = null;
85
- if (useStoreHook) {
86
- try {
87
- // eslint-disable-next-line react-hooks/rules-of-hooks
88
- reduxStore = useStoreHook();
89
- } catch (e) {
90
- // Not inside a Provider or other error
91
- storeError = e instanceof Error ? e.message : "Failed to access Redux store. Make sure your app is wrapped in a Redux Provider.";
92
- }
93
- } else {
94
- storeError = "react-redux is not installed or not available";
95
- }
96
-
97
- // Function to start instrumentation
98
- const startInstrumentation = useCallback(() => {
99
- if (!reduxStore) {
100
- setError(storeError || "No Redux store available");
101
- setIsLoading(false);
102
- return;
103
- }
104
-
105
- // Check if already instrumented
106
- if (isStoreInstrumented(reduxStore)) {
107
- setIsInstrumented(true);
108
- setStore(reduxStore);
109
- setIsLoading(false);
110
- setError(null);
111
- return;
112
- }
113
- try {
114
- // Instrument the store
115
- const cleanup = instrumentStore(reduxStore, instrumentOptions);
116
- cleanupRef.current = cleanup;
117
- setIsInstrumented(true);
118
- setStore(reduxStore);
119
- setError(null);
120
- } catch (e) {
121
- setError(e instanceof Error ? e.message : "Failed to instrument Redux store");
122
- setIsInstrumented(false);
123
- } finally {
124
- setIsLoading(false);
125
- }
126
- }, [reduxStore, storeError, instrumentOptions]);
127
-
128
- // Function to stop instrumentation
129
- const stopInstrumentation = useCallback(() => {
130
- if (cleanupRef.current) {
131
- cleanupRef.current();
132
- cleanupRef.current = null;
133
- }
134
- if (store) {
135
- uninstrumentStore(store);
136
- }
137
- setIsInstrumented(false);
138
- setStore(null);
139
- }, [store]);
140
-
141
- // Auto-start instrumentation on mount
142
- useEffect(() => {
143
- if (autoStart) {
144
- startInstrumentation();
145
- } else {
146
- setIsLoading(false);
147
- }
148
-
149
- // Cleanup on unmount
150
- return () => {
151
- // Note: We intentionally DON'T uninstrument on unmount
152
- // This allows actions to continue being captured even when
153
- // the DevTools modal is closed. The instrumentation persists
154
- // for the lifetime of the app, similar to network/storage tools.
155
- };
156
- }, [autoStart, startInstrumentation]);
157
- return {
158
- isInstrumented,
159
- isLoading,
160
- error,
161
- isReactReduxAvailable,
162
- startInstrumentation,
163
- stopInstrumentation,
164
- store
165
- };
166
- }
167
-
168
- /**
169
- * Lightweight hook to just check if Redux is available
170
- * without auto-instrumenting
171
- */
172
- export function useReduxAvailability() {
173
- const useStoreHook = getReactReduxUseStore();
174
- if (!useStoreHook) {
175
- return {
176
- isAvailable: false,
177
- error: "react-redux is not installed"
178
- };
179
- }
180
- try {
181
- // eslint-disable-next-line react-hooks/rules-of-hooks
182
- const store = useStoreHook();
183
- return {
184
- isAvailable: store !== null && store !== undefined,
185
- error: null
186
- };
187
- } catch (e) {
188
- return {
189
- isAvailable: false,
190
- error: e instanceof Error ? e.message : "Not inside a Redux Provider"
191
- };
192
- }
193
- }
1
+ "use strict";import{useEffect,useState,useRef,useCallback}from"react";import{instrumentStore,uninstrumentStore,isStoreInstrumented}from"../utils/autoInstrument";function getReactReduxUseStore(){try{return require("react-redux").useStore}catch{return null}}export function useAutoInstrumentRedux(e={}){const{autoStart:t=!0,...r}=e,[u,n]=useState(!1),[s,a]=useState(!0),[l,o]=useState(null),[i,c]=useState(null),d=useRef(null),f=getReactReduxUseStore(),m=null!==f;let R=null,x=null;if(f)try{R=f()}catch(e){x=e instanceof Error?e.message:"Failed to access Redux store. Make sure your app is wrapped in a Redux Provider."}else x="react-redux is not installed or not available";const S=useCallback(()=>{if(!R)return o(x||"No Redux store available"),void a(!1);if(isStoreInstrumented(R))return n(!0),c(R),a(!1),void o(null);try{const e=instrumentStore(R,r);d.current=e,n(!0),c(R),o(null)}catch(e){o(e instanceof Error?e.message:"Failed to instrument Redux store"),n(!1)}finally{a(!1)}},[R,x,r]),v=useCallback(()=>{d.current&&(d.current(),d.current=null),i&&uninstrumentStore(i),n(!1),c(null)},[i]);return useEffect(()=>(t?S():a(!1),()=>{}),[t,S]),{isInstrumented:u,isLoading:s,error:l,isReactReduxAvailable:m,startInstrumentation:S,stopInstrumentation:v,store:i}}export 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,71 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Hook for consuming Redux actions from the store
5
- */
6
-
7
- import { useState, useEffect, useMemo, useCallback } from "react";
8
- import { reduxActionStore } from "../utils/reduxActionStore";
9
- export function useReduxActions() {
10
- const [actions, setActions] = useState(() => reduxActionStore.getActions());
11
- const [filter, setFilter] = useState({});
12
- const [isEnabled, setIsEnabled] = useState(() => reduxActionStore.getEnabled());
13
- const [selectedAction, setSelectedAction] = useState(null);
14
-
15
- // Subscribe to store changes
16
- useEffect(() => {
17
- const unsubscribe = reduxActionStore.subscribe(newActions => {
18
- setActions(newActions);
19
- });
20
- return () => {
21
- unsubscribe();
22
- };
23
- }, []);
24
-
25
- // Filter actions based on current filter
26
- const filteredActions = useMemo(() => {
27
- return reduxActionStore.filterActions(filter);
28
- }, [actions, filter]);
29
-
30
- // Get stats
31
- const stats = useMemo(() => {
32
- return reduxActionStore.getStats();
33
- }, [actions]);
34
-
35
- // Get unique action types
36
- const actionTypes = useMemo(() => {
37
- return reduxActionStore.getUniqueActionTypes();
38
- }, [actions]);
39
-
40
- // Clear actions
41
- const clearActions = useCallback(() => {
42
- reduxActionStore.clearActions();
43
- setSelectedAction(null);
44
- }, []);
45
-
46
- // Toggle capture
47
- const toggleCapture = useCallback(() => {
48
- const newEnabled = !isEnabled;
49
- reduxActionStore.setEnabled(newEnabled);
50
- setIsEnabled(newEnabled);
51
- }, [isEnabled]);
52
-
53
- // Get action by ID
54
- const getActionById = useCallback(id => {
55
- return reduxActionStore.getActionById(id);
56
- }, []);
57
- return {
58
- actions,
59
- filteredActions,
60
- filter,
61
- setFilter,
62
- stats,
63
- clearActions,
64
- isEnabled,
65
- toggleCapture,
66
- actionTypes,
67
- getActionById,
68
- selectedAction,
69
- setSelectedAction
70
- };
71
- }
1
+ "use strict";import{useState,useEffect,useMemo,useCallback}from"react";import{reduxActionStore}from"../utils/reduxActionStore";export function useReduxActions(){const[e,t]=useState(()=>reduxActionStore.getActions()),[o,c]=useState({}),[s,r]=useState(()=>reduxActionStore.getEnabled()),[n,u]=useState(null);useEffect(()=>{const e=reduxActionStore.subscribe(e=>{t(e)});return()=>{e()}},[]);const i=useMemo(()=>reduxActionStore.filterActions(o),[e,o]),l=useMemo(()=>reduxActionStore.getStats(),[e]),a=useMemo(()=>reduxActionStore.getUniqueActionTypes(),[e]),A=useCallback(()=>{reduxActionStore.clearActions(),u(null)},[]),d=useCallback(()=>{const e=!s;reduxActionStore.setEnabled(e),r(e)},[s]),S=useCallback(e=>reduxActionStore.getActionById(e),[]);return{actions:e,filteredActions:i,filter:o,setFilter:c,stats:l,clearActions:A,isEnabled:s,toggleCapture:d,actionTypes:a,getActionById:S,selectedAction:n,setSelectedAction:u}}
@@ -1,13 +1 @@
1
- "use strict";
2
-
3
- // Types
4
- export * from "./types";
5
-
6
- // Utils
7
- export * from "./utils";
8
-
9
- // Hooks
10
- export * from "./hooks";
11
-
12
- // Components
13
- export * from "./components";
1
+ "use strict";export*from"./types";export*from"./utils";export*from"./hooks";export*from"./components";
@@ -1,260 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Auto-instrumentation for Redux stores
5
- *
6
- * This module provides zero-config Redux DevTools integration by automatically
7
- * patching the store's dispatch method when the DevTools component mounts.
8
- *
9
- * Similar to how @buoy-gg/network patches globalThis.fetch, this patches
10
- * store.dispatch to capture all Redux actions without requiring manual
11
- * middleware configuration.
12
- */
13
-
14
- import { reduxActionStore } from "./reduxActionStore";
15
- import { BUOY_JUMP_TO_STATE, isMiddlewareActive } from "./buoyReduxMiddleware";
16
-
17
- // ============================================
18
- // Store Tracking
19
- // ============================================
20
-
21
- /** Symbol to mark stores that have been instrumented */
22
- const INSTRUMENTED_SYMBOL = Symbol.for("@@buoy/instrumented");
23
-
24
- /** Symbol to store original dispatch reference */
25
- const ORIGINAL_DISPATCH_SYMBOL = Symbol.for("@@buoy/originalDispatch");
26
-
27
- /** Symbol to store original reducer reference */
28
- const ORIGINAL_REDUCER_SYMBOL = Symbol.for("@@buoy/originalReducer");
29
-
30
- /** Reference to the active store for time-travel operations */
31
- let activeStore = null;
32
-
33
- /** Track if store has been enhanced for time-travel */
34
- let timeTravelEnabled = false;
35
-
36
- // ============================================
37
- // Type Definitions
38
- // ============================================
39
-
40
- // ============================================
41
- // Core Instrumentation
42
- // ============================================
43
-
44
- /**
45
- * Check if a store has already been instrumented
46
- */
47
- export function isStoreInstrumented(store) {
48
- return store[INSTRUMENTED_SYMBOL] === true;
49
- }
50
-
51
- /**
52
- * Instrument a Redux store for action capture
53
- *
54
- * This function patches store.dispatch to capture all actions without
55
- * requiring the user to configure middleware manually.
56
- *
57
- * @param store - The Redux store to instrument
58
- * @param options - Configuration options
59
- * @returns Cleanup function to restore original dispatch
60
- */
61
- export function instrumentStore(store, options = {}) {
62
- const instrumentedStore = store;
63
-
64
- // Skip if middleware is already handling action capture
65
- // This prevents duplicate recording when both mechanisms are active
66
- if (isMiddlewareActive()) {
67
- activeStore = store;
68
- return () => {};
69
- }
70
-
71
- // Skip if already instrumented
72
- if (instrumentedStore[INSTRUMENTED_SYMBOL]) {
73
- // Update active store reference even if already instrumented
74
- activeStore = store;
75
- return () => {};
76
- }
77
- const {
78
- enableTimeTravel = false,
79
- maxActions = 200,
80
- ignoreActions = []
81
- } = options;
82
-
83
- // Configure store
84
- reduxActionStore.setMaxActions(maxActions);
85
-
86
- // Store original dispatch
87
- const originalDispatch = store.dispatch.bind(store);
88
- instrumentedStore[ORIGINAL_DISPATCH_SYMBOL] = originalDispatch;
89
-
90
- // Create instrumented dispatch
91
- const instrumentedDispatch = action => {
92
- // Skip if action is not a plain object with a type property
93
- // This filters out thunk functions, promises, and other non-action dispatches
94
- if (typeof action !== "object" || action === null || typeof action.type !== "string") {
95
- return originalDispatch(action);
96
- }
97
- const actionType = action.type;
98
-
99
- // Don't record devtools internal actions
100
- if (actionType.startsWith("@@buoy/")) {
101
- return originalDispatch(action);
102
- }
103
-
104
- // Don't record Redux internal actions
105
- if (actionType.startsWith("@@redux/")) {
106
- return originalDispatch(action);
107
- }
108
-
109
- // Check ignore list
110
- if (ignoreActions.includes(actionType)) {
111
- return originalDispatch(action);
112
- }
113
-
114
- // Capture timing and state
115
- const startTime = performance.now();
116
- const prevState = store.getState();
117
- const result = originalDispatch(action);
118
- const nextState = store.getState();
119
- const duration = performance.now() - startTime;
120
-
121
- // Record the action
122
- reduxActionStore.addAction(action, prevState, nextState, duration);
123
- return result;
124
- };
125
-
126
- // Replace dispatch
127
- store.dispatch = instrumentedDispatch;
128
- instrumentedStore[INSTRUMENTED_SYMBOL] = true;
129
- activeStore = store;
130
-
131
- // Enable time-travel if requested and store supports replaceReducer
132
- if (enableTimeTravel && typeof store.replaceReducer === "function") {
133
- enableTimeTravelSupport(store);
134
- }
135
-
136
- // Return cleanup function
137
- return () => {
138
- uninstrumentStore(store);
139
- };
140
- }
141
-
142
- /**
143
- * Remove instrumentation from a store
144
- */
145
- export function uninstrumentStore(store) {
146
- const instrumentedStore = store;
147
- if (!instrumentedStore[INSTRUMENTED_SYMBOL]) {
148
- return;
149
- }
150
-
151
- // Restore original dispatch
152
- const originalDispatch = instrumentedStore[ORIGINAL_DISPATCH_SYMBOL];
153
- if (originalDispatch) {
154
- store.dispatch = originalDispatch;
155
- }
156
-
157
- // Restore original reducer if time-travel was enabled
158
- const originalReducer = instrumentedStore[ORIGINAL_REDUCER_SYMBOL];
159
- if (originalReducer && typeof store.replaceReducer === "function") {
160
- store.replaceReducer(originalReducer);
161
- timeTravelEnabled = false;
162
- }
163
-
164
- // Clean up symbols
165
- delete instrumentedStore[INSTRUMENTED_SYMBOL];
166
- delete instrumentedStore[ORIGINAL_DISPATCH_SYMBOL];
167
- delete instrumentedStore[ORIGINAL_REDUCER_SYMBOL];
168
-
169
- // Clear active store reference
170
- if (activeStore === store) {
171
- activeStore = null;
172
- }
173
- }
174
-
175
- // ============================================
176
- // Time-Travel Support
177
- // ============================================
178
-
179
- /**
180
- * Enable time-travel support by wrapping the store's reducer
181
- *
182
- * This uses store.replaceReducer to inject our time-travel wrapper
183
- * dynamically, without requiring users to manually wrap their reducer.
184
- */
185
- function enableTimeTravelSupport(store) {
186
- const instrumentedStore = store;
187
-
188
- // Get current reducer by dispatching a probe action
189
- // Note: This is a workaround since there's no store.getReducer()
190
- // We'll wrap whatever reducer is currently active
191
- const currentState = store.getState();
192
-
193
- // Create a time-travel enabled reducer wrapper
194
- const timeTravelReducer = (state = currentState, action) => {
195
- // Handle jump to state action
196
- if (action.type === BUOY_JUMP_TO_STATE) {
197
- return action.payload;
198
- }
199
-
200
- // Get the result from the original dispatch flow
201
- // Since we've already wrapped dispatch, we need to be careful here
202
- // The state will be updated by the store's internal reducer
203
- return state;
204
- };
205
-
206
- // Store reference (we can't actually get the original reducer directly)
207
- // This approach has limitations - full time-travel works better with
208
- // the explicit withBuoyDevTools wrapper
209
- instrumentedStore[ORIGINAL_REDUCER_SYMBOL] = timeTravelReducer;
210
- timeTravelEnabled = true;
211
- }
212
-
213
- /**
214
- * Jump to a specific state (time-travel)
215
- *
216
- * For full time-travel support, users should use withBuoyDevTools.
217
- * This limited version attempts to work with auto-instrumentation.
218
- */
219
- export function jumpToState(state) {
220
- if (activeStore) {
221
- activeStore.dispatch({
222
- type: BUOY_JUMP_TO_STATE,
223
- payload: state
224
- });
225
- } else {
226
- console.warn("[BuoyRedux] Cannot jump to state - no store instrumented");
227
- }
228
- }
229
-
230
- /**
231
- * Replay an action (dispatch it again)
232
- */
233
- export function replayAction(action) {
234
- if (activeStore) {
235
- activeStore.dispatch(action);
236
- } else {
237
- console.warn("[BuoyRedux] Cannot replay action - no store instrumented");
238
- }
239
- }
240
-
241
- /**
242
- * Get the currently active (instrumented) store
243
- */
244
- export function getActiveStore() {
245
- return activeStore;
246
- }
247
-
248
- /**
249
- * Check if auto-instrumentation is active
250
- */
251
- export function isAutoInstrumentActive() {
252
- return activeStore !== null && isStoreInstrumented(activeStore);
253
- }
254
-
255
- /**
256
- * Check if time-travel support is enabled
257
- */
258
- export function isTimeTravelEnabled() {
259
- return timeTravelEnabled;
260
- }
1
+ "use strict";import{reduxActionStore}from"./reduxActionStore";import{BUOY_JUMP_TO_STATE,isMiddlewareActive}from"./buoyReduxMiddleware";const INSTRUMENTED_SYMBOL=Symbol.for("@@buoy/instrumented"),ORIGINAL_DISPATCH_SYMBOL=Symbol.for("@@buoy/originalDispatch"),ORIGINAL_REDUCER_SYMBOL=Symbol.for("@@buoy/originalReducer");let activeStore=null,timeTravelEnabled=!1;export function isStoreInstrumented(e){return!0===e[INSTRUMENTED_SYMBOL]}export function instrumentStore(e,t={}){const r=e;if(isMiddlewareActive())return activeStore=e,()=>{};if(r[INSTRUMENTED_SYMBOL])return activeStore=e,()=>{};const{enableTimeTravel:o=!1,maxActions:n=200,ignoreActions:i=[]}=t;reduxActionStore.setMaxActions(n);const c=e.dispatch.bind(e);return r[ORIGINAL_DISPATCH_SYMBOL]=c,e.dispatch=t=>{if("object"!=typeof t||null===t||"string"!=typeof t.type)return c(t);const r=t.type;if(r.startsWith("@@buoy/"))return c(t);if(r.startsWith("@@redux/"))return c(t);if(i.includes(r))return c(t);const o=performance.now(),n=e.getState(),a=c(t),u=e.getState(),S=performance.now()-o;return reduxActionStore.addAction(t,n,u,S),a},r[INSTRUMENTED_SYMBOL]=!0,activeStore=e,o&&"function"==typeof e.replaceReducer&&enableTimeTravelSupport(e),()=>{uninstrumentStore(e)}}export function uninstrumentStore(e){const t=e;if(!t[INSTRUMENTED_SYMBOL])return;const r=t[ORIGINAL_DISPATCH_SYMBOL];r&&(e.dispatch=r);const o=t[ORIGINAL_REDUCER_SYMBOL];o&&"function"==typeof e.replaceReducer&&(e.replaceReducer(o),timeTravelEnabled=!1),delete t[INSTRUMENTED_SYMBOL],delete t[ORIGINAL_DISPATCH_SYMBOL],delete t[ORIGINAL_REDUCER_SYMBOL],activeStore===e&&(activeStore=null)}function enableTimeTravelSupport(e){const t=e,r=e.getState();t[ORIGINAL_REDUCER_SYMBOL]=(e=r,t)=>t.type===BUOY_JUMP_TO_STATE?t.payload:e,timeTravelEnabled=!0}export function jumpToState(e){activeStore?activeStore.dispatch({type:BUOY_JUMP_TO_STATE,payload:e}):console.warn("[BuoyRedux] Cannot jump to state - no store instrumented")}export function replayAction(e){activeStore?activeStore.dispatch(e):console.warn("[BuoyRedux] Cannot replay action - no store instrumented")}export function getActiveStore(){return activeStore}export function isAutoInstrumentActive(){return null!==activeStore&&isStoreInstrumented(activeStore)}export function isTimeTravelEnabled(){return timeTravelEnabled}