@@ -6,25 +6,29 @@ export type PathNode = {
6
6
7
7
export type PathTrie = Record < string , PathNode > ;
8
8
9
+ const isTerminal = ( node : PathNode ) : boolean => {
10
+ return Object . keys ( node ) . length === 0 ;
11
+ } ;
12
+
9
13
/**
10
- * Insert a URL into the trie, mutating `pathTrie` in place .
11
- * - If an ancestor path already exists as a terminal ({}), do nothing.
12
- * - If inserting an ancestor of existing entries, prune descendants by setting that node to {} .
13
- * - If no path segments exist (bare host or "/"), do nothing .
14
+ * Insert a URL into the trie.
15
+ *
16
+ * @param url - The URL to insert into the trie .
17
+ * @param pathTrie - The trie to insert the URL into .
14
18
*/
15
19
export const insertToTrie = ( url : string , pathTrie : PathTrie ) => {
16
- var { hostname, pathComponents } = getHostnameAndPathComponents ( url ) ;
20
+ const { hostname, pathComponents } = getHostnameAndPathComponents ( url ) ;
17
21
18
22
if ( pathComponents . length === 0 || ! hostname ) {
19
23
return ;
20
24
}
21
25
22
- hostname = hostname . toLowerCase ( ) ;
23
- if ( ! pathTrie [ hostname ] ) {
24
- pathTrie [ hostname ] = { } as PathNode ;
26
+ const lowerHostname = hostname . toLowerCase ( ) ;
27
+ if ( ! pathTrie [ lowerHostname ] ) {
28
+ pathTrie [ lowerHostname ] = { } as PathNode ;
25
29
}
26
30
27
- let curr : PathNode = pathTrie [ hostname ] ;
31
+ let curr : PathNode = pathTrie [ lowerHostname ] ;
28
32
for ( let i = 0 ; i < pathComponents . length ; i ++ ) {
29
33
const pathComponent = pathComponents [ i ] ;
30
34
const isLast = i === pathComponents . length - 1 ;
@@ -56,20 +60,25 @@ export const insertToTrie = (url: string, pathTrie: PathTrie) => {
56
60
}
57
61
} ;
58
62
63
+ /**
64
+ * Delete a URL from the trie.
65
+ *
66
+ * @param url - The URL to delete from the trie.
67
+ * @param pathTrie - The trie to delete the URL from.
68
+ */
59
69
export const deleteFromTrie = ( url : string , pathTrie : PathTrie ) => {
60
- var { hostname, pathComponents } = getHostnameAndPathComponents ( url ) ;
70
+ const { hostname, pathComponents } = getHostnameAndPathComponents ( url ) ;
61
71
62
- if ( pathComponents . length === 0 || ! pathTrie [ hostname ] ) {
72
+ const lowerHostname = hostname . toLowerCase ( ) ;
73
+ if ( pathComponents . length === 0 || ! pathTrie [ lowerHostname ] ) {
63
74
return ;
64
75
}
65
76
66
77
const pathToNode : { node : PathNode ; key : string } [ ] = [
67
- { node : pathTrie , key : hostname } ,
78
+ { node : pathTrie , key : lowerHostname } ,
68
79
] ;
69
- let curr : PathNode = pathTrie [ hostname ] ;
70
- for ( let i = 0 ; i < pathComponents . length ; i ++ ) {
71
- const pathComponent = pathComponents [ i ] ;
72
-
80
+ let curr : PathNode = pathTrie [ lowerHostname ] ;
81
+ for ( const pathComponent of pathComponents ) {
73
82
if ( ! curr [ pathComponent ] ) {
74
83
return ;
75
84
}
@@ -90,25 +99,27 @@ export const deleteFromTrie = (url: string, pathTrie: PathTrie) => {
90
99
}
91
100
} ;
92
101
102
+ /**
103
+ * Check if a URL is a terminal path i.e. the last path component is a terminal node.
104
+ *
105
+ * @param url - The URL to check.
106
+ * @param pathTrie - The trie to check the URL in.
107
+ * @returns True if the URL is a terminal path, false otherwise.
108
+ */
93
109
export const isTerminalPath = ( url : string , pathTrie : PathTrie ) : boolean => {
94
- var { hostname, pathComponents } = getHostnameAndPathComponents ( url ) ;
110
+ const { hostname, pathComponents } = getHostnameAndPathComponents ( url ) ;
95
111
96
- hostname = hostname . toLowerCase ( ) ;
97
- if ( pathComponents . length === 0 || ! hostname || ! pathTrie [ hostname ] ) {
112
+ const lowerHostname = hostname . toLowerCase ( ) ;
113
+ if ( pathComponents . length === 0 || ! hostname || ! pathTrie [ lowerHostname ] ) {
98
114
return false ;
99
115
}
100
116
101
- let curr : PathNode = pathTrie [ hostname ] ;
102
- for ( let i = 0 ; i < pathComponents . length ; i ++ ) {
103
- const pathComponent = pathComponents [ i ] ;
117
+ let curr : PathNode = pathTrie [ lowerHostname ] ;
118
+ for ( const pathComponent of pathComponents ) {
104
119
if ( ! curr [ pathComponent ] ) {
105
120
return false ;
106
121
}
107
122
curr = curr [ pathComponent ] ;
108
123
}
109
124
return isTerminal ( curr ) ;
110
125
} ;
111
-
112
- const isTerminal = ( node : PathNode ) : boolean => {
113
- return Object . keys ( node ) . length === 0 ;
114
- } ;
0 commit comments