git.fiddlerwoaroof.com
Browse code

Refactoring

Max Summe authored on 05/02/2020 18:39:24
Showing 3 changed files
... ...
@@ -11,8 +11,9 @@ function mostSpecificRouteMatch(match1, match2) {
11 11
 
12 12
   const paramLength1 = match1.routeParams.length;
13 13
   const paramLength2 = match2.routeParams.length;
14
+
14 15
   let findWildcard = R.compose(
15
-    R.findIndex.bind(R, isWildcard),
16
+    R.findIndex(isWildcard),
16 17
     pathSplit
17 18
   );
18 19
 
... ...
@@ -39,8 +40,7 @@ function mostSpecificRouteMatch(match1, match2) {
39 40
 function matchRoute(loc, matchers) {
40 41
   const inputPath = loc.pathname;
41 42
 
42
-  const buildMatch = (extractedParams, route) =>
43
-    Object.assign({ extractedParams }, route);
43
+  const buildMatch = (extractedParams, route) => ({ extractedParams, ...route });
44 44
 
45 45
   return R.toPairs(matchers).reduce(
46 46
     (match, [_, { type: matcherType, route }]) => {
... ...
@@ -69,7 +69,7 @@ function mostSpecificActionMatch(match1, match2) {
69 69
     return match2;
70 70
   }
71 71
 
72
-  let countExtraParams = ({ extraParams: obj }) => Object.keys(obj).length;
72
+  let countExtraParams = ({ extraParams: obj }) => R.keys(obj).length;
73 73
   return countExtraParams(match1) >= countExtraParams(match2) ? match1 : match2;
74 74
 }
75 75
 
... ...
@@ -88,15 +88,15 @@ function matchAction(action, matchers) {
88 88
 
89 89
   for (const { type: matcherType, route } of routes) {
90 90
     if (matcherType === "exact" && R.equals(route.extraParams, args)) {
91
-      match = Object.assign({ extractedParams: {} }, route);
91
+      match = { extractedParams: {}, ...route};
92 92
       // case 3
93 93
       break; // most specific
94 94
     } else if (matcherType === "wildcard") {
95 95
       // case 1+2
96 96
 
97 97
       const unallocatedArgKeys = R.difference(
98
-        Object.keys(args),
99
-        Object.keys(route.extraParams)
98
+        R.keys(args),
99
+        R.keys(route.extraParams)
100 100
       );
101 101
       // if all keys ^ are equal to all keys in route
102 102
       const intersectCount = R.intersection(
... ...
@@ -109,7 +109,7 @@ function matchAction(action, matchers) {
109 109
         const extractedParams = R.pick(unallocatedArgKeys, args);
110 110
         match = mostSpecificActionMatch(
111 111
           match,
112
-          Object.assign({ extractedParams }, route)
112
+          { extractedParams, ...route }
113 113
         );
114 114
       }
115 115
     }
... ...
@@ -143,26 +143,27 @@ function extractParams(path) {
143 143
 }
144 144
 
145 145
 function normalizePathParts(path) {
146
-  const rawPathParts = R.split("/", path);
147
-  const normalizedPathParts = R.filter(p => p !== "", rawPathParts);
148
-  return normalizedPathParts;
146
+  const splitAndFilterEmpty = R.pipe(
147
+    R.split('/'),
148
+    R.filter(p => p !== "")
149
+  );
150
+
151
+  return splitAndFilterEmpty(path);
149 152
 }
150 153
 
151 154
 function makeRoute(path, action, extraParams) {
152
-  let type = "exact";
153
-  if (path.indexOf(":") !== -1) {
154
-    type = "wildcard";
155
-  }
155
+  const type = (R.includes(':', path) ? 'wildcard': 'exact');
156 156
 
157 157
   const normalizedPathParts = normalizePathParts(path);
158 158
 
159 159
   const updateWildcard = (wildcards, match, input) => {
160 160
     const wildcardName = match.replace(":", "");
161
-    return Object.assign(wildcards, { [wildcardName]: input });
161
+    return {...wildcards, [wildcardName]: input};
162 162
   };
163 163
 
164 164
   const routeMatcher = function(inputPath) {
165 165
     let result = null;
166
+
166 167
     const normMatchPath = normalizedPathParts;
167 168
     const normInputPath = normalizePathParts(inputPath);
168 169
 
... ...
@@ -230,7 +231,7 @@ function routeAlreadyExists(compiledRouteMatchers, path) {
230 231
     );
231 232
     const pathParts = normalizingSplit(path);
232 233
 
233
-    for (const otherPath of Object.keys(compiledRouteMatchers)) {
234
+    for (const otherPath of R.keys(compiledRouteMatchers)) {
234 235
       const otherPathParts = normalizingSplit(otherPath);
235 236
       if (R.equals(pathParts, otherPathParts)) {
236 237
         throw new Error(
... ...
@@ -244,8 +245,8 @@ function routeAlreadyExists(compiledRouteMatchers, path) {
244 245
 }
245 246
 
246 247
 function compileRoutes(routesConfig) {
247
-  let compiledActionMatchers = {};
248
-  let compiledRouteMatchers = {};
248
+  const compiledActionMatchers = {};
249
+  const compiledRouteMatchers = {};
249 250
 
250 251
   for (let [path, action, extraParams] of routesConfig) {
251 252
     if (typeof path !== "string" || typeof action !== "string") {
... ...
@@ -305,26 +306,37 @@ function createActionDispatcher(routesConfig, window) {
305 306
     return match ? constructPath(match) : null;
306 307
   }
307 308
 
309
+  function actionForLocation(location) {
310
+    const match = matchRoute(location, compiledRouteMatchers);
311
+    return match ? constructAction(match) : null;
312
+  }
313
+
308 314
   let actionDispatcher = {
309 315
     currentLocation: null,
310
-
311 316
     store: null,
317
+
312 318
     activateDispatcher(store) {
313 319
       window.addEventListener("urlchanged", this);
314 320
       this.store = store;
315 321
     },
322
+
316 323
     enhanceStore(nextStoreCreator) {
317 324
       let middleware = buildMiddleware(this);
325
+
318 326
       return (reducer, finalInitialState, enhancer) => {
319 327
         let theStore = nextStoreCreator(reducer, finalInitialState, enhancer);
328
+
320 329
         this.activateDispatcher(theStore);
330
+
321 331
         theStore.pathForAction = pathForAction;
332
+
322 333
         theStore.dispatch = middleware(theStore)(
323 334
           theStore.dispatch.bind(theStore)
324 335
         );
325 336
         return theStore;
326 337
       };
327 338
     },
339
+
328 340
     handleEvent(ev) {
329 341
       if (!this.store) {
330 342
         throw new Error(
... ...
@@ -337,31 +349,27 @@ function createActionDispatcher(routesConfig, window) {
337 349
     },
338 350
 
339 351
     onLocationChanged(newLoc, cb) {
340
-      let result = undefined;
341
-
342 352
       if (this.currentLocation !== newLoc) {
343 353
         this.currentLocation = newLoc;
344
-        result = cb();
354
+        cb();
345 355
       }
346
-
347
-      return result;
348 356
     },
349 357
 
350 358
     receiveLocation(location) {
351 359
       this.onLocationChanged(location.pathname, () => {
352
-        const match = matchRoute(location, compiledRouteMatchers);
353
-        if (match) {
354
-          const action = constructAction(match);
355 360
 
361
+        const action = actionForLocation(location);
362
+
363
+        if (action) {
356 364
           this.store.dispatch(action);
357 365
         }
358 366
       });
359 367
     },
360 368
 
361 369
     receiveAction(action) {
362
-      let matcher = matchAction(action, compiledActionMatchers);
363
-      if (matcher) {
364
-        let path = constructPath(matcher);
370
+      const path = pathForAction(action);
371
+
372
+      if (path) {
365 373
         this.onLocationChanged(path, () => {
366 374
           window.history.pushState({}, "", path);
367 375
         });
... ...
@@ -4,7 +4,7 @@ export function wrapEvent(target, name, obj) {
4 4
   target.addEventListener(name, obj);
5 5
 }
6 6
 
7
-function debounce(object, flag, cb) {
7
+function runOnceFor(object, flag, cb) {
8 8
   if (!object[flag]) {
9 9
     object[flag] = true;
10 10
     cb();
... ...
@@ -13,7 +13,7 @@ function debounce(object, flag, cb) {
13 13
 
14 14
 let MISSING_CHANGE_URL = Symbol("missing_change_url");
15 15
 export default function addChangeUrlEvent(window) {
16
-  debounce(window, MISSING_CHANGE_URL, () => {
16
+  runOnceFor(window, MISSING_CHANGE_URL, () => {
17 17
     const changeUrlEventCreator = {
18 18
       lastLocation: null,
19 19
       handleEvent(_) {
... ...
@@ -18,7 +18,7 @@ function polyfillCustomEvent() {
18 18
   window.CustomEvent = CustomEvent;
19 19
 }
20 20
 
21
-function debounce(object, flag, cb) {
21
+function runOnceFor(object, flag, cb) {
22 22
   if (!object[flag]) {
23 23
     object[flag] = true;
24 24
     cb();
... ...
@@ -27,7 +27,7 @@ function debounce(object, flag, cb) {
27 27
 
28 28
 let MISSING_HISTORY = Symbol("missing_history");
29 29
 export default function addMissingHistoryEvents(window, history) {
30
-  debounce(history, MISSING_HISTORY, () => {
30
+  runOnceFor(history, MISSING_HISTORY, () => {
31 31
     const pushState = history.pushState.bind(history);
32 32
     const replaceState = history.replaceState.bind(history);
33 33