You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RouteRegistry.js 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /**
  2. * Object describing application route.
  3. *
  4. * @typedef {Object} Route
  5. * @property {Component} component - React Component constructor.
  6. * @property {string} path - URL route, required for web routing.
  7. */
  8. /**
  9. * A registry for Navigator routes, allowing features to register themselves
  10. * without needing to create additional inter-feature dependencies.
  11. */
  12. class RouteRegistry {
  13. /**
  14. * Initializes a new RouteRegistry instance.
  15. */
  16. constructor() {
  17. /**
  18. * The set of registered routes.
  19. *
  20. * @private
  21. */
  22. this._routeRegistry = new Set();
  23. }
  24. /**
  25. * Determines whether two specific Routes are equal i.e. they describe one
  26. * and the same abstract route.
  27. *
  28. * @param {Object} a - The Route to compare to b.
  29. * @param {Object} b - The Route to compare to a.
  30. * @returns {boolean} True if the specified a and b describe one and the
  31. * same abstract route; otherwise, false.
  32. */
  33. areRoutesEqual(a, b) {
  34. if (a === b) { // reflexive
  35. return true;
  36. }
  37. if (!a) {
  38. return !b;
  39. }
  40. if (!b) {
  41. return !a;
  42. }
  43. return (
  44. Object.keys(a).every(key => a[key] === b[key])
  45. && /* symmetric */ this.areRoutesEqual(b, a));
  46. }
  47. /**
  48. * Returns all registered routes.
  49. *
  50. * @returns {Route[]}
  51. */
  52. getRoutes() {
  53. // We use the destructuring operator to 'clone' the route object to
  54. // prevent modifications from outside (e.g. React Native's Navigator
  55. // extends it with additional properties).
  56. return [ ...this._routeRegistry ].map(r => {
  57. return { ...r };
  58. });
  59. }
  60. /**
  61. * Returns registered route by name if any.
  62. *
  63. * @param {Object} component - The React Component (class) of the route to
  64. * retrieve.
  65. * @returns {Route|null}
  66. */
  67. getRouteByComponent(component) {
  68. const route
  69. = [ ...this._routeRegistry ].find(r => r.component === component);
  70. // We use destructuring operator to 'clone' route object to prevent
  71. // modifications from outside (e.g. React Native's Navigator extends
  72. // it with some additional properties).
  73. return route ? { ...route } : null;
  74. }
  75. /**
  76. * Adds a route to this registry.
  77. *
  78. * @param {Route} route - Route definition object.
  79. * @returns {void}
  80. */
  81. register(route) {
  82. if (this._routeRegistry.has(route)) {
  83. throw new Error(`Route ${route.component} is registered already!`);
  84. }
  85. this._routeRegistry.add(route);
  86. }
  87. }
  88. /**
  89. * The public singleton instance of the RouteRegistry class.
  90. */
  91. export default new RouteRegistry();