-
-
Notifications
You must be signed in to change notification settings - Fork 4k
/
hookStore.tsx
118 lines (105 loc) · 3.51 KB
/
hookStore.tsx
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import Reflux from 'reflux';
import isUndefined from 'lodash/isUndefined';
import * as Sentry from '@sentry/react';
import {Hooks, HookName} from 'app/types/hooks';
/**
* See types/hooks for hook usage reference.
*/
const validHookNames = new Set<HookName>([
'_',
'analytics:event',
'analytics:init-user',
'analytics:track-adhoc-event',
'analytics:track-event',
'analytics:log-experiment',
'component:header-date-range',
'component:header-selector-items',
'feature-disabled:custom-inbound-filters',
'feature-disabled:custom-symbol-sources',
'feature-disabled:data-forwarding',
'feature-disabled:discard-groups',
'feature-disabled:discover-page',
'feature-disabled:discover-saved-query-create',
'feature-disabled:discover-sidebar-item',
'feature-disabled:discover2-page',
'feature-disabled:discover2-sidebar-item',
'feature-disabled:events-page',
'feature-disabled:events-sidebar-item',
'feature-disabled:grid-editable-actions',
'feature-disabled:performance-page',
'feature-disabled:performance-sidebar-item',
'feature-disabled:project-selector-checkbox',
'feature-disabled:rate-limits',
'feature-disabled:sso-basic',
'feature-disabled:sso-rippling',
'feature-disabled:sso-saml2',
'footer',
'integrations:feature-gates',
'member-invite-modal:customization',
'metrics:event',
'onboarding:extra-chrome',
'onboarding:invite-members',
'onboarding-wizard:skip-help',
'organization:header',
'routes',
'routes:admin',
'routes:organization',
'routes:organization-root',
'settings:organization-general-settings',
'settings:organization-navigation',
'settings:organization-navigation-config',
'sidebar:bottom-items',
'sidebar:help-menu',
'sidebar:item-label',
'sidebar:organization-dropdown-menu',
]);
type HookStoreInterface = {
// XXX(epurkhiser): We could type this as {[H in HookName]?:
// Array<Hooks[H]>}, however this causes typescript to produce a complex
// union that it complains is 'too complex'
hooks: any;
add<H extends HookName>(hookName: H, callback: Hooks[H]): void;
remove<H extends HookName>(hookName: H, callback: Hooks[H]): void;
get<H extends HookName>(hookName: H): Array<Hooks[H]>;
};
const hookStoreConfig: Reflux.StoreDefinition & HookStoreInterface = {
hooks: {},
init() {
this.hooks = {};
},
add(hookName, callback) {
// Gracefully error on invalid hooks, but maintain registration
// TODO(ts): With typescript we can rmeove this in the future
if (!validHookNames.has(hookName)) {
// eslint-disable-next-line no-console
console.error('Invalid hook name: ' + hookName);
Sentry.withScope(scope => {
scope.setExtra('hookName', hookName);
Sentry.captureException(new Error('Invalid hook name'));
});
}
if (isUndefined(this.hooks[hookName])) {
this.hooks[hookName] = [];
}
this.hooks[hookName]!.push(callback);
this.trigger(hookName, this.hooks[hookName]);
},
remove(hookName, callback) {
if (isUndefined(this.hooks[hookName])) {
return;
}
this.hooks[hookName] = this.hooks[hookName]!.filter(cb => cb !== callback);
this.trigger(hookName, this.hooks[hookName]);
},
get(hookName) {
return this.hooks[hookName]! || [];
},
};
type HookStore = Reflux.Store & HookStoreInterface;
/**
* HookStore is used to allow extensibility into Sentry's frontend via
* registration of 'hook functions'.
*
* This functionality is primarily used by the SASS sentry.io product.
*/
export default Reflux.createStore(hookStoreConfig) as HookStore;