-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
refactor(router-core): Process routeTree into segment tree instead of flatRoutes [WIP] #5722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
Sheraff
wants to merge
81
commits into
main
Choose a base branch
from
refactor-router-core-process-route-tree-into-segment-tree
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 20 commits
Commits
Show all changes
81 commits
Select commit
Hold shift + click to select a range
31aad1d
refactor(router-core): Process routeTree into segment tree instead of…
Sheraff df389c6
foo
Sheraff 23bacf4
bar
Sheraff f3236f2
PoC works
Sheraff 627e017
faster
Sheraff dd1e3e3
faster
Sheraff e274212
remove node key, each object is a node
Sheraff baa2764
handle optional and wildcard
Sheraff bb4f022
there can be multiple wildcard children on a node because of prefix/s…
Sheraff adbcdd5
use index for skipping instead of the node itself
Sheraff 8c886b8
fix node collision by param name only
Sheraff 5b784fd
fix init of routesById and routesByPath
Sheraff 9bf39da
some early tests
Sheraff 484fc81
just comments
Sheraff e2339cc
use bitmask instead of array for skipped nodes during match
Sheraff f190778
start replacing in path.ts
Sheraff d6db54e
minor
Sheraff a60faa8
depth
Sheraff d15c9d9
fuzzy matching
Sheraff 1a6a969
better sort function
Sheraff 7c91a68
dynamic and optional matches use the stack
Sheraff 4cd8726
no regex during matching yields 2x perf
Sheraff 48f59ce
simplify interpolatePath and matchId
Sheraff c034ec2
Merge branch 'main' into refactor-router-core-process-route-tree-into…
Sheraff 3fd5fd1
clean resolvePath
Sheraff 54c14b9
optimize parseSegment
Sheraff 4413339
support processing flat route tree for route masks matching
Sheraff 82ae4d4
support routeMasks option as a flat tree
Sheraff ff17ea8
deprecate MatchRouteOptions 'caseSensitive' option
Sheraff 88cd231
support deprecated single route match, slight performance penalty, st…
Sheraff 56808aa
plug it into actual router
Sheraff 14007cb
remove ai context
Sheraff a6f379c
ci: apply automated fixes
autofix-ci[bot] eb140cd
fix build
Sheraff 162a3d7
ci: apply automated fixes
autofix-ci[bot] 58baf3e
typos
Sheraff 4dab29f
fix plugin HMR
Sheraff 66a38b2
remove flatRoutes from devtools
Sheraff b40c320
wildcard suffix can include slashes
Sheraff 3c10a6c
explore all branches before returning
Sheraff d20010e
some unit tests
Sheraff ba4cc90
hmr plugin prettify
Sheraff 5f6236c
init route before processing
Sheraff 3751534
more unit
Sheraff 9f60967
remove commented out
Sheraff caa7fe1
_splat and *
Sheraff dfa98e9
prettier
Sheraff e518239
fix single match and flat match
Sheraff b8c1c2e
misc optims
Sheraff 7e2ef5d
prettier
Sheraff 58775f7
cache resolvePath
Sheraff bde9344
resolvePath: improve cache hit rate, add common path skips
Sheraff 89bf3be
restore some matching tests
Sheraff cd9f4dc
restore some more tests
Sheraff 8110b6e
update unit tests to new segment format (not a fix)
Sheraff 92093b8
some segment parsing fixes
Sheraff f1a0b7d
fix curly-braced required param without prefix/suffix
Sheraff 2c5d4b1
skipped params are not included at all in the params object
Sheraff f04d540
fix multi-segment wildcard suffix
Sheraff b8aead3
add failing match test
Sheraff 3e26bcd
skipped optional nodes can match beyond the end of the path
Sheraff 5c7e8c1
add failing case sensitivity test
Sheraff c6daad9
Merge branch 'main' into refactor-router-core-process-route-tree-into…
Sheraff bd59a1e
remove 2nd while loop, everything through the stack, bye bye performance
Sheraff cd8bd06
add cache to matching methods
Sheraff 9f92e6b
fix build
Sheraff f3e5a80
fix fuzzy rest argument leading slash
Sheraff 4b2df33
add more test cases
Sheraff 0ca25b1
batch push in stack (will refactor, but at least this works)
Sheraff 4647f9d
remove batch stack append, iterate backwards instead
Sheraff e9489e1
comments
Sheraff a46ce08
some more unit tests
Sheraff 947b47e
add comment about skipped bitmask being limited to 32
Sheraff 3785a2e
match wildcards beyond last segment
Sheraff 435f4e9
remove deprecated test file
Sheraff c2342ef
Merge branch 'main' into refactor-router-core-process-route-tree-into…
Sheraff 20c5b1f
wip test
Sheraff aafbcd3
include caseSensitivity in dynamic node sort function
Sheraff 320cdbd
more unit tests
Sheraff 896956e
code comment
Sheraff a30e03d
segments without text cannot be case-sensitive
Sheraff File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
|
|
||
| <main-question> | ||
| What are the different ways / data structures / algorithms to fullfil the following requirements? | ||
| </main-question> | ||
|
|
||
| <answer-expectations> | ||
| - all code should be javascript / typescript | ||
| - ask any questions you might need to answer accurately | ||
| - start by listing all the best approaches with a smal blurb, pros and cons, and I'll tell you which I want to delve into | ||
| - do NOT look at the existing codebase | ||
| </answer-expectations> | ||
|
|
||
| <routing-requirements> | ||
| A route is made of segments. There are several types of segments: | ||
| - Static segments: match exact string, e.g. 'home', 'about', 'users' | ||
| - Dynamic segments: match any string, e.g. '$userId', '$postId' | ||
| - Optional dynamic segments: match any string or nothing, e.g. '{-$userId}', '{-$postId}' | ||
| - Wildcard segments (splat): match anything to the end, must be last, e.g. `$` | ||
|
|
||
| Non-static segments can have prefixes and suffixes | ||
| - prefix: e.g. 'user{$id}', 'post{-$id}', 'file{$}' | ||
| - suffix: e.g. '{$id}profile', '{-$id}edit', '{$}details' | ||
| - both: e.g. 'user{$id}profile', 'post{-$id}edit', 'file{$}details' | ||
|
|
||
| In the future we might want to add more segment types: | ||
| - optional static segments: match exact string or nothing, e.g. '{home}' (or with prefix/suffix: 'pre{home}suf') | ||
|
|
||
| When the app starts, we receive all routes as an unordered tree: | ||
| Route: { | ||
| id: string // unique identifier, | ||
| fullPath: string // full path from the root, | ||
| children?: Route[] // child routes, | ||
| parentRoute?: Route // parent route, | ||
| } | ||
|
|
||
| When matching a route, we need to extract the parameters from the path. | ||
| - dynamic segments ('$userId' => { userId: '123' }) | ||
| - optional dynamic segments ('{-$userId}' => { userId: '123' } or { }) | ||
| - wildcard segments ('$' => { '*': 'some/long/path' }) | ||
|
|
||
| When the app is live, we need 2 abilities: | ||
| - know whether a path matches a specific route (i.e. match(route: Route, path: string): Params | false) | ||
| - find which route (if any) is matching a given path (i.e. findRoute(path: string): {route: Route, params: Params} | null) | ||
|
|
||
| To optimize these operations, we pre-process the route tree. Both pre-processing and matching should be highly performant in the browser. | ||
| </routing-requirements> | ||
|
|
||
| <some-details> | ||
| - scale: we expect to have between 2 and 2000 routes (approximately) | ||
| - all routes are known at app start time, no dynamic route addition/removal | ||
| - memory is not an issue, don't hesitate to use more memory to gain speed | ||
| - routes can be nested from 1 to 10 levels deep (approximately) | ||
| - we have no preference for certain patterns, we are open to rewriting everything | ||
| - matching must be deterministic | ||
| - we always favor a more specific route over a less specific one (e.g. /users/123/profile over /users/$userId/$) | ||
| - each segment can be case sensitive or case insensitive, it can be different for each segment. We know this at pre-processing time. | ||
| - we cannot pre-process at build time, all pre-processing must happen at app start time in the browser | ||
| </some-details> | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.