@buoy-gg/redux 3.0.1 → 3.0.2

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 (68) hide show
  1. package/lib/commonjs/index.js +186 -1
  2. package/lib/commonjs/preset.js +98 -1
  3. package/lib/commonjs/redux/components/ReduxActionButton.js +129 -1
  4. package/lib/commonjs/redux/components/ReduxActionDetailContent.js +380 -1
  5. package/lib/commonjs/redux/components/ReduxActionDetailView.js +401 -1
  6. package/lib/commonjs/redux/components/ReduxActionInfoView.js +838 -1
  7. package/lib/commonjs/redux/components/ReduxActionItem.js +366 -1
  8. package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +134 -1
  9. package/lib/commonjs/redux/components/ReduxIcon.js +18 -1
  10. package/lib/commonjs/redux/components/ReduxModal.js +531 -1
  11. package/lib/commonjs/redux/components/index.js +52 -1
  12. package/lib/commonjs/redux/hooks/index.js +25 -1
  13. package/lib/commonjs/redux/hooks/useAutoInstrumentRedux.js +197 -1
  14. package/lib/commonjs/redux/hooks/useReduxActions.js +75 -1
  15. package/lib/commonjs/redux/index.js +49 -1
  16. package/lib/commonjs/redux/sync/reduxSyncAdapter.js +26 -0
  17. package/lib/commonjs/redux/utils/autoInstrument.js +270 -1
  18. package/lib/commonjs/redux/utils/buoyReduxMiddleware.js +166 -1
  19. package/lib/commonjs/redux/utils/createReduxHistoryAdapter.js +146 -1
  20. package/lib/commonjs/redux/utils/index.js +111 -1
  21. package/lib/commonjs/redux/utils/reduxActionStore.js +413 -1
  22. package/lib/module/index.js +92 -1
  23. package/lib/module/preset.js +94 -1
  24. package/lib/module/redux/components/ReduxActionButton.js +126 -1
  25. package/lib/module/redux/components/ReduxActionDetailContent.js +376 -1
  26. package/lib/module/redux/components/ReduxActionDetailView.js +397 -1
  27. package/lib/module/redux/components/ReduxActionInfoView.js +833 -1
  28. package/lib/module/redux/components/ReduxActionItem.js +362 -1
  29. package/lib/module/redux/components/ReduxDetailViewToggle.js +129 -1
  30. package/lib/module/redux/components/ReduxIcon.js +8 -1
  31. package/lib/module/redux/components/ReduxModal.js +526 -1
  32. package/lib/module/redux/components/index.js +7 -1
  33. package/lib/module/redux/hooks/index.js +4 -1
  34. package/lib/module/redux/hooks/useAutoInstrumentRedux.js +193 -1
  35. package/lib/module/redux/hooks/useReduxActions.js +71 -1
  36. package/lib/module/redux/index.js +13 -1
  37. package/lib/module/redux/sync/reduxSyncAdapter.js +23 -0
  38. package/lib/module/redux/utils/autoInstrument.js +260 -1
  39. package/lib/module/redux/utils/buoyReduxMiddleware.js +157 -1
  40. package/lib/module/redux/utils/createReduxHistoryAdapter.js +142 -1
  41. package/lib/module/redux/utils/index.js +8 -1
  42. package/lib/module/redux/utils/reduxActionStore.js +409 -1
  43. package/lib/typescript/index.d.ts +1 -0
  44. package/lib/typescript/index.d.ts.map +1 -0
  45. package/lib/typescript/preset.d.ts.map +1 -0
  46. package/lib/typescript/redux/components/ReduxActionButton.d.ts.map +1 -0
  47. package/lib/typescript/redux/components/ReduxActionDetailContent.d.ts.map +1 -0
  48. package/lib/typescript/redux/components/ReduxActionDetailView.d.ts.map +1 -0
  49. package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +1 -0
  50. package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +1 -0
  51. package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +1 -0
  52. package/lib/typescript/redux/components/ReduxIcon.d.ts.map +1 -0
  53. package/lib/typescript/redux/components/ReduxModal.d.ts.map +1 -0
  54. package/lib/typescript/redux/components/index.d.ts.map +1 -0
  55. package/lib/typescript/redux/hooks/index.d.ts.map +1 -0
  56. package/lib/typescript/redux/hooks/useAutoInstrumentRedux.d.ts.map +1 -0
  57. package/lib/typescript/redux/hooks/useReduxActions.d.ts.map +1 -0
  58. package/lib/typescript/redux/index.d.ts.map +1 -0
  59. package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts +18 -0
  60. package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts.map +1 -0
  61. package/lib/typescript/redux/types/index.d.ts.map +1 -0
  62. package/lib/typescript/redux/utils/autoInstrument.d.ts.map +1 -0
  63. package/lib/typescript/redux/utils/buoyReduxMiddleware.d.ts.map +1 -0
  64. package/lib/typescript/redux/utils/createReduxHistoryAdapter.d.ts.map +1 -0
  65. package/lib/typescript/redux/utils/index.d.ts.map +1 -0
  66. package/lib/typescript/redux/utils/reduxActionStore.d.ts +25 -0
  67. package/lib/typescript/redux/utils/reduxActionStore.d.ts.map +1 -0
  68. package/package.json +4 -4
@@ -1 +1,157 @@
1
- "use strict";import{reduxActionStore}from"./reduxActionStore";let middlewareActive=!1;export function isMiddlewareActive(){return middlewareActive}export const BUOY_JUMP_TO_STATE="@@buoy/JUMP_TO_STATE";export const BUOY_REPLAY_ACTION="@@buoy/REPLAY_ACTION";let storeDispatch=null;export function jumpToState(t){storeDispatch?storeDispatch({type:BUOY_JUMP_TO_STATE,payload:t}):console.warn("[BuoyRedux] Cannot jump to state - middleware not initialized")}export function replayAction(t){storeDispatch?storeDispatch(t):console.warn("[BuoyRedux] Cannot replay action - middleware not initialized")}export function withBuoyDevTools(t){return(e,o)=>o.type===BUOY_JUMP_TO_STATE?o.payload:t(e,o)}export const buoyReduxMiddleware=t=>(middlewareActive=!0,storeDispatch=t.dispatch,e=>o=>{const r=o,n=r.type;if(n?.startsWith("@@buoy/"))return e(o);const i=performance.now(),a=t.getState(),c=e(o),s=t.getState(),d=performance.now()-i;return reduxActionStore.addAction(r,a,s,d),c});export function createBuoyReduxMiddleware(t={}){const{maxActions:e=200,ignoreActions:o=[]}=t;return reduxActionStore.setMaxActions(e),t=>(middlewareActive=!0,storeDispatch=t.dispatch,e=>r=>{const n=r,i=n.type||"";if(i?.startsWith("@@buoy/"))return e(r);if(o.includes(i))return e(r);const a=performance.now(),c=t.getState(),s=e(r),d=t.getState(),u=performance.now()-a;return reduxActionStore.addAction(n,c,d,u),s})}
1
+ "use strict";
2
+
3
+ /**
4
+ * Buoy Redux Middleware for Redux Toolkit
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { configureStore } from '@reduxjs/toolkit';
9
+ * import { buoyReduxMiddleware, withBuoyDevTools } from '@buoy-gg/redux';
10
+ *
11
+ * const store = configureStore({
12
+ * reducer: withBuoyDevTools(rootReducer), // Enable time-travel
13
+ * middleware: (getDefaultMiddleware) =>
14
+ * getDefaultMiddleware().concat(buoyReduxMiddleware),
15
+ * });
16
+ * ```
17
+ */
18
+
19
+ import { reduxActionStore } from "./reduxActionStore";
20
+
21
+ // ============================================
22
+ // Middleware Active Tracking
23
+ // ============================================
24
+
25
+ /** Flag to indicate middleware is handling action capture */
26
+ let middlewareActive = false;
27
+
28
+ /**
29
+ * Check if the explicit middleware is active
30
+ * Used by auto-instrument to avoid duplicate capture
31
+ */
32
+ export function isMiddlewareActive() {
33
+ return middlewareActive;
34
+ }
35
+
36
+ // ============================================
37
+ // Time-Travel Action Types
38
+ // ============================================
39
+
40
+ export const BUOY_JUMP_TO_STATE = "@@buoy/JUMP_TO_STATE";
41
+ export const BUOY_REPLAY_ACTION = "@@buoy/REPLAY_ACTION";
42
+ // Store reference to dispatch for time-travel
43
+ let storeDispatch = null;
44
+
45
+ /**
46
+ * Jump to a specific state (time-travel)
47
+ */
48
+ export function jumpToState(state) {
49
+ if (storeDispatch) {
50
+ storeDispatch({
51
+ type: BUOY_JUMP_TO_STATE,
52
+ payload: state
53
+ });
54
+ } else {
55
+ console.warn("[BuoyRedux] Cannot jump to state - middleware not initialized");
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Replay an action (dispatch it again)
61
+ */
62
+ export function replayAction(action) {
63
+ if (storeDispatch) {
64
+ // Dispatch the original action directly
65
+ storeDispatch(action);
66
+ } else {
67
+ console.warn("[BuoyRedux] Cannot replay action - middleware not initialized");
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Wrap your root reducer to enable time-travel support
73
+ *
74
+ * @example
75
+ * ```tsx
76
+ * const store = configureStore({
77
+ * reducer: withBuoyDevTools(rootReducer),
78
+ * middleware: (getDefault) => getDefault().concat(buoyReduxMiddleware),
79
+ * });
80
+ * ```
81
+ */
82
+ export function withBuoyDevTools(reducer) {
83
+ return (state, action) => {
84
+ // Handle jump to state action
85
+ if (action.type === BUOY_JUMP_TO_STATE) {
86
+ const jumpAction = action;
87
+ return jumpAction.payload;
88
+ }
89
+
90
+ // Pass through to original reducer
91
+ return reducer(state, action);
92
+ };
93
+ }
94
+
95
+ /**
96
+ * Default middleware - just add to your store!
97
+ */
98
+ export const buoyReduxMiddleware = storeApi => {
99
+ // Mark middleware as active so auto-instrument knows to skip
100
+ middlewareActive = true;
101
+
102
+ // Store dispatch reference for time-travel
103
+ storeDispatch = storeApi.dispatch;
104
+ return next => action => {
105
+ const actionObj = action;
106
+ const actionType = actionObj.type;
107
+
108
+ // Don't record devtools internal actions
109
+ if (actionType?.startsWith("@@buoy/")) {
110
+ return next(action);
111
+ }
112
+ const startTime = performance.now();
113
+ const prevState = storeApi.getState();
114
+ const result = next(action);
115
+ const nextState = storeApi.getState();
116
+ const duration = performance.now() - startTime;
117
+ reduxActionStore.addAction(actionObj, prevState, nextState, duration);
118
+ return result;
119
+ };
120
+ };
121
+
122
+ /**
123
+ * Create middleware with custom options
124
+ */
125
+ export function createBuoyReduxMiddleware(options = {}) {
126
+ const {
127
+ maxActions = 200,
128
+ ignoreActions = []
129
+ } = options;
130
+ reduxActionStore.setMaxActions(maxActions);
131
+ return storeApi => {
132
+ // Mark middleware as active so auto-instrument knows to skip
133
+ middlewareActive = true;
134
+
135
+ // Store dispatch reference for time-travel
136
+ storeDispatch = storeApi.dispatch;
137
+ return next => action => {
138
+ const actionObj = action;
139
+ const actionType = actionObj.type || "";
140
+
141
+ // Don't record devtools internal actions
142
+ if (actionType?.startsWith("@@buoy/")) {
143
+ return next(action);
144
+ }
145
+ if (ignoreActions.includes(actionType)) {
146
+ return next(action);
147
+ }
148
+ const startTime = performance.now();
149
+ const prevState = storeApi.getState();
150
+ const result = next(action);
151
+ const nextState = storeApi.getState();
152
+ const duration = performance.now() - startTime;
153
+ reduxActionStore.addAction(actionObj, prevState, nextState, duration);
154
+ return result;
155
+ };
156
+ };
157
+ }
@@ -1 +1,142 @@
1
- "use strict";import{reduxActionStore}from"./reduxActionStore";import{ReduxIcon}from"../components/ReduxIcon";const REDUX_CAPABILITIES={timeTravel:!1,toggle:!1,edit:!1,diff:!0,export:!0,import:!1,reset:!0,recording:!0};function toHistoryEntry(t,e,r){return{id:t.id,label:t.type,timestamp:t.timestamp,data:t.payload??t.action,prevState:t.prevState,nextState:t.nextState,hasStateChange:t.hasStateChange,duration:t.duration,source:"redux",isCurrent:0===e,isInFuture:!1,isSkipped:!1,meta:{fullAction:t.action}}}export function createReduxHistoryAdapter(t){const{icon:e=ReduxIcon,color:r="#764ABC",name:n="Redux"}=t??{};let o=0;return{id:"redux",name:n,icon:e,color:r,capabilities:REDUX_CAPABILITIES,subscribe:t=>reduxActionStore.subscribe(()=>{t()}),getEntries:()=>{const t=reduxActionStore.getActions();return t.map((e,r)=>toHistoryEntry(e,r,t.length))},getEntryCount:()=>reduxActionStore.getActions().length,getCurrentState:()=>{const t=reduxActionStore.getActions();if(0!==t.length)return t[0].nextState},getStateAtEntry:t=>{const e=reduxActionStore.getActionById(String(t));return e?.nextState},get currentIndex(){return o},jumpTo:t=>{const e=reduxActionStore.getActions().findIndex(e=>e.id===String(t));-1!==e&&(o=e)},get isRecording(){return reduxActionStore.getEnabled()},setRecording:t=>{reduxActionStore.setEnabled(t)},reset:()=>{reduxActionStore.clearActions(),o=0},exportHistory:()=>{const t=reduxActionStore.getActions();return JSON.stringify(t,null,2)}}}export const reduxHistoryAdapter=createReduxHistoryAdapter();
1
+ "use strict";
2
+
3
+ /**
4
+ * Redux History Adapter
5
+ *
6
+ * Wraps the existing reduxActionStore to implement the universal HistoryAdapter interface.
7
+ */
8
+
9
+ import { reduxActionStore } from "./reduxActionStore";
10
+ import { ReduxIcon } from "../components/ReduxIcon";
11
+
12
+ /**
13
+ * Redux adapter capabilities
14
+ * Note: Full time-travel requires the instrument() pattern from redux-devtools.
15
+ * This adapter provides history viewing with basic navigation.
16
+ */
17
+ const REDUX_CAPABILITIES = {
18
+ timeTravel: false,
19
+ // Would need instrument() for true time travel
20
+ toggle: false,
21
+ // Would need instrument() for skip/toggle
22
+ edit: false,
23
+ diff: true,
24
+ // We have prevState/nextState
25
+ export: true,
26
+ import: false,
27
+ reset: true,
28
+ recording: true
29
+ };
30
+
31
+ /**
32
+ * Convert ReduxAction to HistoryEntry
33
+ */
34
+ function toHistoryEntry(action, index, _total) {
35
+ return {
36
+ id: action.id,
37
+ label: action.type,
38
+ timestamp: action.timestamp,
39
+ data: action.payload ?? action.action,
40
+ prevState: action.prevState,
41
+ nextState: action.nextState,
42
+ hasStateChange: action.hasStateChange,
43
+ duration: action.duration,
44
+ source: "redux",
45
+ isCurrent: index === 0,
46
+ // Most recent is current
47
+ isInFuture: false,
48
+ isSkipped: false,
49
+ meta: {
50
+ fullAction: action.action
51
+ }
52
+ };
53
+ }
54
+
55
+ /**
56
+ * Options for creating a Redux history adapter
57
+ */
58
+
59
+ /**
60
+ * Create a Redux history adapter
61
+ *
62
+ * @param options - Optional configuration
63
+ * @returns HistoryAdapter instance
64
+ */
65
+ export function createReduxHistoryAdapter(options) {
66
+ const {
67
+ icon = ReduxIcon,
68
+ color = "#764ABC",
69
+ // Redux purple
70
+ name = "Redux"
71
+ } = options ?? {};
72
+ let currentIndex = 0;
73
+ const adapter = {
74
+ // === Identity ===
75
+ id: "redux",
76
+ name,
77
+ icon,
78
+ color,
79
+ capabilities: REDUX_CAPABILITIES,
80
+ // === Subscription ===
81
+ subscribe: callback => {
82
+ return reduxActionStore.subscribe(() => {
83
+ callback();
84
+ });
85
+ },
86
+ // === Data Access ===
87
+ getEntries: () => {
88
+ const actions = reduxActionStore.getActions();
89
+ return actions.map((action, index) => toHistoryEntry(action, index, actions.length));
90
+ },
91
+ getEntryCount: () => {
92
+ return reduxActionStore.getActions().length;
93
+ },
94
+ getCurrentState: () => {
95
+ const actions = reduxActionStore.getActions();
96
+ if (actions.length === 0) return undefined;
97
+ // Most recent action's nextState is current state
98
+ return actions[0].nextState;
99
+ },
100
+ getStateAtEntry: entryId => {
101
+ const action = reduxActionStore.getActionById(String(entryId));
102
+ return action?.nextState;
103
+ },
104
+ // === Navigation ===
105
+ get currentIndex() {
106
+ return currentIndex;
107
+ },
108
+ jumpTo: entryId => {
109
+ const actions = reduxActionStore.getActions();
110
+ const index = actions.findIndex(a => a.id === String(entryId));
111
+ if (index !== -1) {
112
+ currentIndex = index;
113
+ // Note: This doesn't actually change app state without instrument()
114
+ // It just updates which entry is "selected" for viewing
115
+ }
116
+ },
117
+ // === Recording ===
118
+ get isRecording() {
119
+ return reduxActionStore.getEnabled();
120
+ },
121
+ setRecording: enabled => {
122
+ reduxActionStore.setEnabled(enabled);
123
+ },
124
+ // === Reset ===
125
+ reset: () => {
126
+ reduxActionStore.clearActions();
127
+ currentIndex = 0;
128
+ },
129
+ // === Export ===
130
+ exportHistory: () => {
131
+ const actions = reduxActionStore.getActions();
132
+ return JSON.stringify(actions, null, 2);
133
+ }
134
+ };
135
+ return adapter;
136
+ }
137
+
138
+ /**
139
+ * Default Redux adapter instance
140
+ * Use this if you only have one Redux store
141
+ */
142
+ export const reduxHistoryAdapter = createReduxHistoryAdapter();
@@ -1 +1,8 @@
1
- "use strict";export{reduxActionStore}from"./reduxActionStore";export{buoyReduxMiddleware,createBuoyReduxMiddleware,withBuoyDevTools,jumpToState,replayAction,BUOY_JUMP_TO_STATE,BUOY_REPLAY_ACTION}from"./buoyReduxMiddleware";export{createReduxHistoryAdapter,reduxHistoryAdapter}from"./createReduxHistoryAdapter";export{instrumentStore,uninstrumentStore,isStoreInstrumented,isAutoInstrumentActive,getActiveStore,jumpToState as autoJumpToState,replayAction as autoReplayAction}from"./autoInstrument";
1
+ "use strict";
2
+
3
+ export { reduxActionStore } from "./reduxActionStore";
4
+ export { buoyReduxMiddleware, createBuoyReduxMiddleware, withBuoyDevTools, jumpToState, replayAction, BUOY_JUMP_TO_STATE, BUOY_REPLAY_ACTION } from "./buoyReduxMiddleware";
5
+ export { createReduxHistoryAdapter, reduxHistoryAdapter } from "./createReduxHistoryAdapter";
6
+
7
+ // Auto-instrumentation (zero-config)
8
+ export { instrumentStore, uninstrumentStore, isStoreInstrumented, isAutoInstrumentActive, getActiveStore, jumpToState as autoJumpToState, replayAction as autoReplayAction } from "./autoInstrument";