| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- /* @flow */
-
- import { Component } from 'react';
-
- /**
- * Object describing application route.
- *
- * @typedef {Object} Route
- * @property {Component} component - React Component constructor.
- * @property {string} path - URL route, required for web routing.
- */
- type Route = {
- component: Class<Component<*>>, // eslint-disable-line no-undef
- path: string
- };
-
- /**
- * A registry for Navigator routes, allowing features to register themselves
- * without needing to create additional inter-feature dependencies.
- */
- class RouteRegistry {
- _elements: Array<Route>;
-
- /**
- * Initializes a new RouteRegistry instance.
- */
- constructor() {
- /**
- * The set of registered routes.
- *
- * @private
- * @type {Route[]}
- */
- this._elements = [];
- }
-
- /**
- * Determines whether two specific Routes are equal i.e. they describe one
- * and the same abstract route.
- *
- * @param {Object} a - The Route to compare to b.
- * @param {Object} b - The Route to compare to a.
- * @returns {boolean} True if the specified a and b describe one and the
- * same abstract route; otherwise, false.
- */
- areRoutesEqual(a: Route, b: Route) {
- if (a === b) { // reflexive
- return true;
- }
- if (!a) {
- return !b;
- }
- if (!b) {
- return !a;
- }
-
- const aKeys = Object.keys(a);
- const bKeys = Object.keys(b);
-
- return (
- aKeys.length === bKeys.length /* symmetric */
- && aKeys.every(key => a[key] === b[key]));
- }
-
- /**
- * Returns all registered routes.
- *
- * @returns {Route[]}
- */
- getRoutes() {
- // We use the destructuring operator to 'clone' the route object to
- // prevent modifications from outside (e.g. React Native's Navigator
- // extends it with additional properties).
- return this._elements.map(r => {
- return { ...r };
- });
- }
-
- /* eslint-disable no-undef */
-
- /**
- * Returns registered route by name if any.
- *
- * @param {Component} component - The React Component (class) of the route
- * to retrieve.
- * @returns {Route|null}
- */
- getRouteByComponent(component: Class<Component<*>>) {
-
- /* eslint-enable no-undef */
-
- const route = this._elements.find(r => r.component === component);
-
- // We use destructuring operator to 'clone' route object to prevent
- // modifications from outside (e.g. React Native's Navigator extends
- // it with some additional properties).
- return route ? { ...route } : null;
- }
-
- /**
- * Adds a route to this registry.
- *
- * @param {Route} route - Route definition object.
- * @returns {void}
- */
- register(route: Route) {
- if (this._elements.includes(route)) {
- throw new Error(
- `Route ${String(route.component)} is registered already!`);
- }
-
- this._elements.push(route);
- }
- }
-
- /**
- * The public singleton instance of the RouteRegistry class.
- */
- export default new RouteRegistry();
|