Skip to content

Commit ebedf6d

Browse files
committed
feat: save data in session storage
1 parent ae1a068 commit ebedf6d

File tree

4 files changed

+168
-107
lines changed

4 files changed

+168
-107
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const STORAGE_KEY = "msw-dev-tool-storage";

packages/msw-dev-tool/src/lib/handlerStore.ts

Lines changed: 126 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
import { OnChangeFn, RowSelectionState } from "@tanstack/react-table";
1313
import isFunction from "lodash/isFunction";
1414
import { setupWorker as _setupWorker } from "../utils/mswBrowser";
15+
import { createJSONStorage, persist } from "zustand/middleware";
16+
import { STORAGE_KEY } from "./const";
1517

1618
export interface HandlerStoreState {
1719
/**
@@ -34,121 +36,140 @@ export interface HandlerStoreState {
3436
getHandlerBehavior: (id: string) => HttpHandlerBehavior | undefined;
3537
setHandlerBehavior: (id: string, behavior: HttpHandlerBehavior) => void;
3638
}
37-
export const useHandlerStore = create<HandlerStoreState>((set, get) => ({
38-
flattenHandlers: [],
39-
worker: null,
40-
restHandlers: [],
41-
handlerRowSelection: {},
42-
setupDevToolWorker: async (...handlers: Handler[]) => {
43-
const _handlers = handlers.map((handler) => {
44-
if (!isHttpHandler(handler)) {
45-
return handler;
46-
}
4739

48-
const originalResolver = handler.resolver;
49-
handler.resolver = async (args) => {
50-
const id = getRowId({
51-
path: handler.info.path.toString(),
52-
method: handler.info.method.toString(),
40+
export const useHandlerStore = create<HandlerStoreState>()(
41+
persist(
42+
(set, get) => ({
43+
flattenHandlers: [],
44+
worker: null,
45+
restHandlers: [],
46+
handlerRowSelection: {},
47+
setupDevToolWorker: async (...handlers: Handler[]) => {
48+
const _handlers = handlers.map((handler) => {
49+
if (!isHttpHandler(handler)) {
50+
return handler;
51+
}
52+
53+
const originalResolver = handler.resolver;
54+
handler.resolver = async (args) => {
55+
const id = getRowId({
56+
path: handler.info.path.toString(),
57+
method: handler.info.method.toString(),
58+
});
59+
const behavior = get().getHandlerBehavior(id);
60+
61+
return await getHandlerResponseByBehavior(behavior, () =>
62+
originalResolver(args)
63+
);
64+
};
65+
return handler;
5366
});
54-
const behavior = get().getHandlerBehavior(id);
5567

56-
return await getHandlerResponseByBehavior(behavior, () =>
57-
originalResolver(args)
58-
);
59-
};
60-
return handler;
61-
});
68+
const setupWorker = await _setupWorker;
69+
if (!setupWorker) {
70+
throw new Error(
71+
"Fail to import 'msw/browser'. Is environment is not browser?"
72+
);
73+
}
74+
const worker = setupWorker(..._handlers);
6275

63-
const setupWorker = await _setupWorker;
64-
if (!setupWorker) {
65-
throw new Error(
66-
"Fail to import 'msw/browser'. Is environment is not browser?"
67-
);
68-
}
69-
const worker = setupWorker?.(..._handlers);
76+
const { flattenHandlers, handlerRowSelection, unsupportedHandlers } =
77+
initMSWDevToolStore(worker);
78+
set({
79+
worker,
80+
flattenHandlers,
81+
handlerRowSelection,
82+
restHandlers: unsupportedHandlers,
83+
});
84+
85+
const totalEnableHandlers = getTotalEnableHandlers(
86+
flattenHandlers,
87+
unsupportedHandlers
88+
);
89+
updateEnableHandlers(worker, totalEnableHandlers);
7090

71-
const { flattenHandlers, handlerRowSelection, unsupportedHandlers } =
72-
initMSWDevToolStore(worker);
73-
set({
74-
worker,
75-
flattenHandlers,
76-
handlerRowSelection,
77-
restHandlers: unsupportedHandlers,
78-
});
91+
return worker;
92+
},
93+
resetMSWDevTool: () => {
94+
const _worker = get().getWorker();
95+
_worker.resetHandlers();
7996

80-
return worker;
81-
},
82-
resetMSWDevTool: () => {
83-
const _worker = get().getWorker();
84-
_worker.resetHandlers();
97+
const {
98+
worker,
99+
flattenHandlers,
100+
handlerRowSelection,
101+
unsupportedHandlers,
102+
} = initMSWDevToolStore(_worker);
85103

86-
const {
87-
worker,
88-
flattenHandlers,
89-
handlerRowSelection,
90-
unsupportedHandlers,
91-
} = initMSWDevToolStore(_worker);
104+
set({
105+
worker,
106+
flattenHandlers,
107+
handlerRowSelection,
108+
restHandlers: unsupportedHandlers,
109+
});
110+
},
111+
handleHandlerRowSelectionChange: (updater) => {
112+
const worker = get().getWorker();
92113

93-
set({
94-
worker,
95-
flattenHandlers,
96-
handlerRowSelection,
97-
restHandlers: unsupportedHandlers,
98-
});
99-
},
100-
handleHandlerRowSelectionChange: (updater) => {
101-
const worker = get().getWorker();
114+
if (isFunction(updater)) {
115+
set(({ handlerRowSelection }) => {
116+
const next = updater(handlerRowSelection);
117+
const current = get().flattenHandlers.map((handler) =>
118+
next[handler.id]
119+
? { ...handler, enabled: true }
120+
: { ...handler, enabled: false }
121+
);
122+
return { handlerRowSelection: next, flattenHandlers: current };
123+
});
124+
} else {
125+
const current = get().flattenHandlers.map((handler) =>
126+
updater[handler.id]
127+
? { ...handler, enabled: true }
128+
: { ...handler, enabled: false }
129+
);
130+
set({ handlerRowSelection: updater, flattenHandlers: current });
131+
}
102132

103-
if (isFunction(updater)) {
104-
set(({ handlerRowSelection }) => {
105-
const next = updater(handlerRowSelection);
106-
const current = get().flattenHandlers.map((handler) =>
107-
next[handler.id]
108-
? { ...handler, enabled: true }
109-
: { ...handler, enabled: false }
133+
const flattenHandlers = get().flattenHandlers;
134+
const restHandlers = get().restHandlers;
135+
const totalEnableHandlers = getTotalEnableHandlers(
136+
flattenHandlers,
137+
restHandlers
110138
);
111-
return { handlerRowSelection: next, flattenHandlers: current };
112-
});
113-
} else {
114-
const current = get().flattenHandlers.map((handler) =>
115-
updater[handler.id]
116-
? { ...handler, enabled: true }
117-
: { ...handler, enabled: false }
118-
);
119-
set({ handlerRowSelection: updater, flattenHandlers: current });
139+
updateEnableHandlers(worker, totalEnableHandlers);
140+
},
141+
getWorker: () => {
142+
const worker = get().worker;
143+
if (!worker) throw new Error("Worker is not initialized");
144+
return worker;
145+
},
146+
getFlattenHandlerById: (id: string) => {
147+
return get().flattenHandlers.find((handler) => handler.id === id);
148+
},
149+
getHandlerBehavior: (id: string) => {
150+
const handler = get().getFlattenHandlerById(id);
151+
if (!handler) return undefined;
152+
return handler.behavior;
153+
},
154+
setHandlerBehavior: (id: string, behavior: HttpHandlerBehavior) => {
155+
set({
156+
flattenHandlers: get().flattenHandlers.map((handler) => {
157+
if (handler.id === id) {
158+
return { ...handler, behavior };
159+
}
160+
return handler;
161+
}),
162+
});
163+
},
164+
}),
165+
{
166+
name: STORAGE_KEY,
167+
storage: createJSONStorage(() => sessionStorage),
168+
partialize: (state) => ({
169+
flattenHandlers: state.flattenHandlers,
170+
}),
120171
}
172+
)
173+
);
121174

122-
const flattenHandlers = get().flattenHandlers;
123-
const restHandlers = get().restHandlers;
124-
const totalEnableHandlers = getTotalEnableHandlers(
125-
flattenHandlers,
126-
restHandlers
127-
);
128-
updateEnableHandlers(worker, totalEnableHandlers);
129-
},
130-
getWorker: () => {
131-
const worker = get().worker;
132-
if (!worker) throw new Error("Worker is not initialized");
133-
return worker;
134-
},
135-
getFlattenHandlerById: (id: string) => {
136-
return get().flattenHandlers.find((handler) => handler.id === id);
137-
},
138-
getHandlerBehavior: (id: string) => {
139-
const handler = get().getFlattenHandlerById(id);
140-
if (!handler) return undefined;
141-
return handler.behavior;
142-
},
143-
setHandlerBehavior: (id: string, behavior: HttpHandlerBehavior) => {
144-
set({
145-
flattenHandlers: get().flattenHandlers.map((handler) => {
146-
if (handler.id === id) {
147-
return { ...handler, behavior };
148-
}
149-
return handler;
150-
}),
151-
});
152-
},
153-
}));
154175
export const setupDevToolWorker = useHandlerStore.getState().setupDevToolWorker;

packages/msw-dev-tool/src/lib/type.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,7 @@ export type FlattenHandler = {
7171
};
7272

7373
export type Handler = RequestHandler | WebSocketHandler;
74+
75+
export interface StorageData {
76+
flattenHandlers: FlattenHandler[];
77+
}

packages/msw-dev-tool/src/lib/util.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import {
55
HttpHandler,
66
HttpHandlerBehavior,
77
HttpStatusCode,
8+
StorageData,
89
} from "./type";
910
import { dummyHandler } from "../const/handler";
1011
import { SetupWorker } from "msw/lib/browser";
1112
import { RowSelectionState } from "@tanstack/react-table";
1213
import { AsyncResponseResolverReturnType, delay, HttpResponse } from "msw";
14+
import { STORAGE_KEY } from "./const";
1315

1416
export const getRowId = ({ path, method }: { path: string; method: string }) =>
1517
JSON.stringify({
@@ -75,7 +77,11 @@ export const updateEnableHandlers = (
7577

7678
export const initMSWDevToolStore = (worker: SetupWorker) => {
7779
const handlers = worker.listHandlers() as Handler[];
78-
const { flattenHandlers, unsupportedHandlers } = convertHandlers(handlers);
80+
const { flattenHandlers: newFlattenHandlers, unsupportedHandlers } =
81+
convertHandlers(handlers);
82+
const { flattenHandlers } = mergeStorageData({
83+
flattenHandlers: newFlattenHandlers,
84+
});
7985
const handlerRowSelection = flattenHandlers.reduce((acc, handler) => {
8086
acc[handler.id] = handler.enabled;
8187
return acc;
@@ -104,7 +110,7 @@ export const getHandlerResponseByBehavior = async (
104110
}
105111

106112
if (behavior === CustomBehavior.RETURN_NULL) {
107-
return HttpResponse.json(null, { status: 200 });;
113+
return HttpResponse.json(null, { status: 200 });
108114
}
109115

110116
if (behavior === CustomBehavior.NETWORK_ERROR) {
@@ -122,3 +128,32 @@ export const getHandlerResponseByBehavior = async (
122128

123129
return originalResolverCallback();
124130
};
131+
132+
export const getStorageData = (): StorageData => {
133+
const storage = sessionStorage.getItem(STORAGE_KEY);
134+
if (!storage) return { flattenHandlers: [] };
135+
return JSON.parse(storage).state;
136+
};
137+
138+
export const mergeStorageData = ({
139+
flattenHandlers: newFlattenHandlers,
140+
}: StorageData) => {
141+
const { flattenHandlers: savedFlattenHandlers } = getStorageData();
142+
143+
// Merge with saved and new element based on worker's handlers
144+
const flattenHandlers = newFlattenHandlers.map((newHandler) => {
145+
const savedHandler = savedFlattenHandlers.find(
146+
(h) => h.id === newHandler.id
147+
);
148+
if (savedHandler) {
149+
return {
150+
...newHandler,
151+
enabled: savedHandler.enabled,
152+
behavior: savedHandler.behavior,
153+
};
154+
}
155+
return newHandler;
156+
});
157+
158+
return { flattenHandlers };
159+
};

0 commit comments

Comments
 (0)