-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
61 lines (52 loc) · 1.68 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import type { StateCreator, StoreMutatorIdentifier } from 'zustand';
import * as Sentry from '@sentry/browser';
type PopArgument<T extends (...a: never[]) => unknown> = T extends (
...a: [...infer A, infer _]
) => infer R
? (...a: A) => R
: never;
interface SentryMiddlewareConfig<T> {
/**
* A function that takes the current state as parameter and return the state that will be stored on Sentry.
*/
stateTransformer?: (state: T) => object;
}
type SentryMiddleware = <
T extends object,
Mps extends [StoreMutatorIdentifier, unknown][] = [],
Mcs extends [StoreMutatorIdentifier, unknown][] = [],
>(
f: StateCreator<T, Mps, Mcs>,
config?: SentryMiddlewareConfig<T>,
) => StateCreator<T, Mps, Mcs>;
type SentryMiddlewareImpl = <T extends object>(
f: PopArgument<StateCreator<T>>,
config?: SentryMiddlewareConfig<T>,
) => PopArgument<StateCreator<T>>;
/**
* A Sentry middleware for zustand that will store the latest state in Sentry's context.
*/
const baseSentryMiddleware: SentryMiddlewareImpl = (config, sentryConfig) => (set, get, api) =>
config(
(...args) => {
set(...args);
const newState = get();
const currentScope = Sentry.getCurrentScope();
const transformedState = sentryConfig?.stateTransformer
? sentryConfig.stateTransformer(newState)
: newState;
currentScope.setContext('state', {
state: {
type: 'zustand',
value: transformedState,
},
});
},
get,
api,
);
/**
* A Sentry middleware for zustand that will store the latest state in Sentry's context.
*/
const sentryMiddleware = baseSentryMiddleware as unknown as SentryMiddleware;
export default sentryMiddleware;