hookStore.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import isUndefined from 'lodash/isUndefined';
  2. import {createStore, StoreDefinition} from 'reflux';
  3. import {HookName, Hooks} from 'sentry/types/hooks';
  4. import {makeSafeRefluxStore} from 'sentry/utils/makeSafeRefluxStore';
  5. interface Internals {
  6. // XXX(epurkhiser): We could type this as {[H in HookName]?:
  7. // Array<Hooks[H]>}, however this causes typescript to produce a complex
  8. // union that it complains is 'too complex'
  9. hooks: any;
  10. }
  11. interface HookStoreDefinition extends StoreDefinition, Internals {
  12. add<H extends HookName>(hookName: H, callback: Hooks[H]): void;
  13. get<H extends HookName>(hookName: H): Array<Hooks[H]>;
  14. remove<H extends HookName>(hookName: H, callback: Hooks[H]): void;
  15. }
  16. const storeConfig: HookStoreDefinition = {
  17. hooks: {},
  18. init() {
  19. this.hooks = {};
  20. },
  21. add(hookName, callback) {
  22. if (isUndefined(this.hooks[hookName])) {
  23. this.hooks[hookName] = [];
  24. }
  25. this.hooks[hookName].push(callback);
  26. this.trigger(hookName, this.hooks[hookName]);
  27. },
  28. remove(hookName, callback) {
  29. if (isUndefined(this.hooks[hookName])) {
  30. return;
  31. }
  32. this.hooks[hookName] = this.hooks[hookName]!.filter(cb => cb !== callback);
  33. this.trigger(hookName, this.hooks[hookName]);
  34. },
  35. get(hookName) {
  36. return this.hooks[hookName]! || [];
  37. },
  38. };
  39. /**
  40. * HookStore is used to allow extensibility into Sentry's frontend via
  41. * registration of 'hook functions'.
  42. *
  43. * This functionality is primarily used by the SASS sentry.io product.
  44. */
  45. const HookStore = createStore(makeSafeRefluxStore(storeConfig));
  46. export default HookStore;