Source: registry.js

  1. /**
  2. * Internal. This is the core of react-cmf.
  3. * The registry will register everything from a react component to redux action.
  4. * @module react-cmf/lib/registry
  5. */
  6. /* eslint no-underscore-dangle: ["error", {"allow": ["_registry", "_isLocked"] }] */
  7. /**
  8. * @typedef {Object<string, *>} Registry
  9. */
  10. /**
  11. * The registry that will have the singleton
  12. * - getRegistry() -> the registry which is a simple key/value POJO
  13. * @type {Registry}
  14. */
  15. const Registry = {
  16. _registry: {},
  17. _isLocked: false,
  18. getRegistry() {
  19. return this._registry;
  20. },
  21. lock() {
  22. this._isLocked = true;
  23. },
  24. isLocked() {
  25. return this._isLocked;
  26. },
  27. };
  28. /**
  29. * Returns the global registry if no context found. If count is found it returns
  30. * the context.registry
  31. * @param {object} context React context
  32. * @return {Registry} the registry singleton instance
  33. */
  34. function getRegistry(context) {
  35. if (context && context.registry) {
  36. return context.registry;
  37. }
  38. return Registry.getRegistry();
  39. }
  40. /**
  41. * Internal. Call this one to add anything you want into the registry.
  42. * It will be added only if not locked.
  43. * Be warned any existing content will be overridden.
  44. * You should use this to add a new configurable concept to CMF.
  45. * By default it's internally used to register expression, component and actionCreator
  46. * @param {string} id Where you want it to store in the registry to get it later
  47. * @param {any} item Everything you want, a function, an object or whatever
  48. */
  49. function addToRegistry(id, item, context) {
  50. if (Registry.isLocked()) {
  51. throw new Error(
  52. `CMF: The registry is locked, you cannot therefore add '${id}' in it. ` +
  53. 'Please check your CMF configuration, it should not move after the initial ' +
  54. 'configuration before bootstrap.',
  55. );
  56. }
  57. const registry = getRegistry(context);
  58. if (registry[id]) {
  59. // eslint-disable-next-line no-console
  60. console.warn(
  61. `CMF: The '${id}' object is registered, overriding an existing '${id}' object. ` +
  62. 'Please check your CMF configuration, you might not want that.',
  63. );
  64. }
  65. if (item === undefined) {
  66. throw new Error(
  67. `CMF: you can't register undefined in '${id}'.
  68. You may have an import error in your configuration`,
  69. );
  70. }
  71. registry[id] = item;
  72. }
  73. /**
  74. * Internal: return element registred under the ID.
  75. * @param {string} id the object's id in the registry you want to get
  76. * @param {object} context cmf context
  77. * @return {any} the object you are looking for
  78. */
  79. function getFromRegistry(id, context) {
  80. return getRegistry(context)[id];
  81. }
  82. /**
  83. * This function is a curry that return a generic function to register components in registry
  84. * @param {function} registerFn a function that register a item in the registry
  85. */
  86. function getRegisterMany(registerFn) {
  87. return (itemsToRegister, context) => {
  88. Object.keys(itemsToRegister).forEach(key => {
  89. registerFn(key, itemsToRegister[key], context);
  90. });
  91. };
  92. }
  93. const registerMany = getRegisterMany(addToRegistry);
  94. /**
  95. * Lock the registry
  96. */
  97. function lock() {
  98. Registry.lock();
  99. }
  100. export default {
  101. Registry,
  102. addToRegistry,
  103. getRegistry,
  104. getFromRegistry,
  105. getRegisterMany,
  106. lock,
  107. registerMany,
  108. };