UNPKG

1.58 kBJavaScriptView Raw
1import Route from 'houkou'
2
3// sorting mechanism for matched candidates
4const FORWARD_SLASHES_REGEX = /\//g
5const complexity = pattern => pattern.match(FORWARD_SLASHES_REGEX).length
6function compare(a, b) {
7 return complexity(b.pattern) - complexity(a.pattern)
8}
9
10// cache the app's patterns as routes ready to be matched
11const getPatterns = lookup =>
12 lookup.map(def => {
13 const { pattern, ...config } = typeof def === 'string'
14 ? { pattern: def }
15 : def
16
17 return {
18 pattern,
19 route: new Route(pattern, config),
20 }
21 })
22
23// define a matcher in case we need to work with a dynamic panel
24const match = (path, lookup) =>
25 getPatterns(lookup)
26 .map(({ pattern, route }) => {
27 const params = route.match(path)
28
29 if (params) {
30 return {
31 params,
32 pattern,
33 }
34 } else {
35 return false
36 }
37 })
38 .filter(Boolean)
39 .sort(compare)[0]
40
41export default function createFindPanel(panels, lookup = []) {
42 // return our grand matcher
43 return function findPanel(path) {
44 // the panel might be static...
45 let panel = panels[path]
46 let props
47
48 // TODO is there any case in which the panel's function should always be called if it's a
49 // dynamic match?
50 if (typeof panel === 'undefined') {
51 // ...or dynamic
52 const matchedPath = match(path, lookup)
53
54 if (matchedPath) {
55 panel = panels[matchedPath.pattern]
56 props = matchedPath.params
57 }
58 } else {
59 props = panel.props || {}
60 }
61
62 return {
63 panel,
64 props,
65 }
66 }
67}