effect-start 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/package.json +8 -9
  2. package/src/Commander.test.ts +507 -245
  3. package/src/ContentNegotiation.test.ts +500 -0
  4. package/src/ContentNegotiation.ts +535 -0
  5. package/src/FileRouter.ts +16 -12
  6. package/src/{FileRouterCodegen.test.ts → FileRouterCodegen.todo.ts} +384 -219
  7. package/src/FileRouterCodegen.ts +6 -6
  8. package/src/FileRouterPattern.test.ts +93 -62
  9. package/src/FileRouter_files.test.ts +5 -5
  10. package/src/FileRouter_path.test.ts +121 -69
  11. package/src/FileRouter_tree.test.ts +62 -56
  12. package/src/FileSystemExtra.test.ts +46 -30
  13. package/src/Http.test.ts +24 -0
  14. package/src/Http.ts +25 -0
  15. package/src/HttpAppExtra.test.ts +39 -20
  16. package/src/HttpAppExtra.ts +0 -1
  17. package/src/HttpUtils.test.ts +35 -18
  18. package/src/HttpUtils.ts +2 -0
  19. package/src/PathPattern.test.ts +648 -0
  20. package/src/PathPattern.ts +483 -0
  21. package/src/Route.ts +258 -1073
  22. package/src/RouteBody.test.ts +182 -0
  23. package/src/RouteBody.ts +106 -0
  24. package/src/RouteHook.test.ts +40 -0
  25. package/src/RouteHook.ts +105 -0
  26. package/src/RouteHttp.test.ts +443 -0
  27. package/src/RouteHttp.ts +219 -0
  28. package/src/RouteMount.test.ts +468 -0
  29. package/src/RouteMount.ts +313 -0
  30. package/src/RouteSchema.test.ts +81 -0
  31. package/src/RouteSchema.ts +44 -0
  32. package/src/RouteTree.test.ts +346 -0
  33. package/src/RouteTree.ts +165 -0
  34. package/src/RouteTrie.test.ts +322 -0
  35. package/src/RouteTrie.ts +224 -0
  36. package/src/RouterPattern.test.ts +569 -548
  37. package/src/RouterPattern.ts +7 -7
  38. package/src/Start.ts +3 -3
  39. package/src/TuplePathPattern.ts +64 -0
  40. package/src/Values.ts +16 -0
  41. package/src/bun/BunBundle.test.ts +36 -42
  42. package/src/bun/BunBundle.ts +2 -2
  43. package/src/bun/BunBundle_imports.test.ts +4 -6
  44. package/src/bun/BunHttpServer.test.ts +183 -6
  45. package/src/bun/BunHttpServer.ts +56 -32
  46. package/src/bun/BunHttpServer_web.ts +18 -6
  47. package/src/bun/BunImportTrackerPlugin.test.ts +3 -3
  48. package/src/bun/BunRoute.ts +29 -210
  49. package/src/{BundleHttp.test.ts → bundler/BundleHttp.test.ts} +34 -60
  50. package/src/{BundleHttp.ts → bundler/BundleHttp.ts} +1 -2
  51. package/src/client/index.ts +1 -1
  52. package/src/{Effect_HttpRouter.test.ts → effect/HttpRouter.test.ts} +69 -90
  53. package/src/experimental/EncryptedCookies.test.ts +125 -64
  54. package/src/experimental/SseHttpResponse.ts +0 -1
  55. package/src/hyper/Hyper.ts +89 -0
  56. package/src/{HyperHtml.test.ts → hyper/HyperHtml.test.ts} +13 -13
  57. package/src/{HyperHtml.ts → hyper/HyperHtml.ts} +2 -2
  58. package/src/{jsx.d.ts → hyper/jsx.d.ts} +1 -1
  59. package/src/index.ts +2 -4
  60. package/src/middlewares/BasicAuthMiddleware.test.ts +29 -19
  61. package/src/{NodeFileSystem.ts → node/FileSystem.ts} +6 -2
  62. package/src/testing/TestHttpClient.test.ts +26 -26
  63. package/src/testing/TestLogger.test.ts +27 -11
  64. package/src/x/datastar/Datastar.test.ts +47 -48
  65. package/src/x/datastar/Datastar.ts +1 -1
  66. package/src/x/tailwind/TailwindPlugin.test.ts +56 -58
  67. package/src/x/tailwind/plugin.ts +1 -1
  68. package/src/FileHttpRouter.test.ts +0 -239
  69. package/src/FileHttpRouter.ts +0 -194
  70. package/src/Hyper.ts +0 -194
  71. package/src/Route.test.ts +0 -1370
  72. package/src/RouteRender.ts +0 -40
  73. package/src/Router.test.ts +0 -375
  74. package/src/Router.ts +0 -255
  75. package/src/bun/BunRoute.test.ts +0 -480
  76. package/src/bun/BunRoute_bundles.test.ts +0 -219
  77. /package/src/{Bundle.ts → bundler/Bundle.ts} +0 -0
  78. /package/src/{BundleFiles.ts → bundler/BundleFiles.ts} +0 -0
  79. /package/src/{HyperNode.ts → hyper/HyperNode.ts} +0 -0
  80. /package/src/{jsx-runtime.ts → hyper/jsx-runtime.ts} +0 -0
  81. /package/src/{NodeUtils.ts → node/Utils.ts} +0 -0
@@ -0,0 +1,535 @@
1
+ /**
2
+ * RFC 7231 Content Negotiation compatible with Express/Node.js ecosystem.
3
+ * Based on {@link https://github.com/jshttp/negotiator}
4
+ */
5
+
6
+ import type * as Headers from "@effect/platform/Headers"
7
+
8
+ interface ParsedSpec {
9
+ value: string
10
+ q: number
11
+ s: number
12
+ o: number
13
+ i: number
14
+ }
15
+
16
+ const simpleMediaTypeRegExp = /^\s*([^\s\/;]+)\/([^;\s]+)\s*(?:;(.*))?$/
17
+ const simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/
18
+ const simpleEncodingRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/
19
+ const simpleCharsetRegExp = /^\s*([^\s;]+)\s*(?:;(.*))?$/
20
+
21
+ function parseQuality(params: string | undefined): number {
22
+ if (!params) return 1
23
+ const match = params.match(/q\s*=\s*([0-9.]+)/)
24
+ if (!match) return 1
25
+ const q = parseFloat(match[1])
26
+ return isNaN(q) ? 1 : Math.min(Math.max(q, 0), 1)
27
+ }
28
+
29
+ function splitMediaTypeParams(
30
+ params: string,
31
+ ): { params: Record<string, string>; q: number } {
32
+ const result: Record<string, string> = {}
33
+ let q = 1
34
+
35
+ const parts = params.split(";")
36
+ for (const part of parts) {
37
+ const trimmed = part.trim()
38
+ const eqIndex = trimmed.indexOf("=")
39
+ if (eqIndex === -1) continue
40
+
41
+ const key = trimmed.slice(0, eqIndex).trim().toLowerCase()
42
+ let value = trimmed.slice(eqIndex + 1).trim()
43
+
44
+ if (value.startsWith("\"") && value.endsWith("\"")) {
45
+ value = value.slice(1, -1)
46
+ }
47
+
48
+ if (key === "q") {
49
+ q = parseFloat(value)
50
+ if (isNaN(q)) q = 1
51
+ q = Math.min(Math.max(q, 0), 1)
52
+ } else {
53
+ result[key] = value
54
+ }
55
+ }
56
+
57
+ return { params: result, q }
58
+ }
59
+
60
+ function parseAccept(
61
+ accept: string,
62
+ ): Array<
63
+ {
64
+ type: string
65
+ subtype: string
66
+ params: Record<string, string>
67
+ q: number
68
+ o: number
69
+ }
70
+ > {
71
+ const specs: Array<{
72
+ type: string
73
+ subtype: string
74
+ params: Record<string, string>
75
+ q: number
76
+ o: number
77
+ }> = []
78
+ const parts = accept.split(",")
79
+
80
+ for (let o = 0; o < parts.length; o++) {
81
+ const part = parts[o].trim()
82
+ if (!part) continue
83
+
84
+ const match = simpleMediaTypeRegExp.exec(part)
85
+ if (!match) continue
86
+
87
+ const type = match[1].toLowerCase()
88
+ const subtype = match[2].toLowerCase()
89
+ const { params, q } = match[3]
90
+ ? splitMediaTypeParams(match[3])
91
+ : { params: {}, q: 1 }
92
+
93
+ if (q > 0) {
94
+ specs.push({ type, subtype, params, q, o })
95
+ }
96
+ }
97
+
98
+ return specs
99
+ }
100
+
101
+ function specifyMediaType(
102
+ type: string,
103
+ subtype: string,
104
+ params: Record<string, string>,
105
+ spec: {
106
+ type: string
107
+ subtype: string
108
+ params: Record<string, string>
109
+ q: number
110
+ o: number
111
+ },
112
+ ): { q: number; s: number; o: number } | null {
113
+ let s = 0
114
+
115
+ if (spec.type === type) {
116
+ s |= 4
117
+ } else if (spec.type !== "*") {
118
+ return null
119
+ }
120
+
121
+ if (spec.subtype === subtype) {
122
+ s |= 2
123
+ } else if (spec.subtype !== "*") {
124
+ return null
125
+ }
126
+
127
+ const specParams = Object.keys(spec.params)
128
+ if (specParams.length > 0) {
129
+ if (
130
+ specParams.every(
131
+ (key) =>
132
+ spec.params[key].toLowerCase() === (params[key] || "").toLowerCase(),
133
+ )
134
+ ) {
135
+ s |= 1
136
+ } else {
137
+ return null
138
+ }
139
+ }
140
+
141
+ return { q: spec.q, s, o: spec.o }
142
+ }
143
+
144
+ function getMediaTypePriority(
145
+ mediaType: string,
146
+ accepted: Array<
147
+ {
148
+ type: string
149
+ subtype: string
150
+ params: Record<string, string>
151
+ q: number
152
+ o: number
153
+ }
154
+ >,
155
+ index: number,
156
+ ): ParsedSpec {
157
+ let best: { q: number; s: number; o: number } | null = null
158
+
159
+ const match = simpleMediaTypeRegExp.exec(mediaType)
160
+ if (!match) {
161
+ return { value: mediaType, q: 0, s: 0, o: -1, i: index }
162
+ }
163
+
164
+ const type = match[1].toLowerCase()
165
+ const subtype = match[2].toLowerCase()
166
+ const { params } = match[3]
167
+ ? splitMediaTypeParams(match[3])
168
+ : { params: {} }
169
+
170
+ for (const spec of accepted) {
171
+ const result = specifyMediaType(type, subtype, params, spec)
172
+ if (
173
+ result
174
+ && (best === null
175
+ || result.s > best.s
176
+ || (result.s === best.s && result.q > best.q)
177
+ || (result.s === best.s && result.q === best.q && result.o < best.o))
178
+ ) {
179
+ best = result
180
+ }
181
+ }
182
+
183
+ return {
184
+ value: mediaType,
185
+ q: best?.q ?? 0,
186
+ s: best?.s ?? 0,
187
+ o: best?.o ?? -1,
188
+ i: index,
189
+ }
190
+ }
191
+
192
+ function parseAcceptLanguage(
193
+ accept: string,
194
+ ): Array<{ prefix: string; suffix: string | undefined; q: number; o: number }> {
195
+ const specs: Array<{
196
+ prefix: string
197
+ suffix: string | undefined
198
+ q: number
199
+ o: number
200
+ }> = []
201
+ const parts = accept.split(",")
202
+
203
+ for (let o = 0; o < parts.length; o++) {
204
+ const part = parts[o].trim()
205
+ if (!part) continue
206
+
207
+ const match = simpleLanguageRegExp.exec(part)
208
+ if (!match) continue
209
+
210
+ const prefix = match[1].toLowerCase()
211
+ const suffix = match[2]?.toLowerCase()
212
+ const q = parseQuality(match[3])
213
+
214
+ if (q > 0) {
215
+ specs.push({ prefix, suffix, q, o })
216
+ }
217
+ }
218
+
219
+ return specs
220
+ }
221
+
222
+ function specifyLanguage(
223
+ language: string,
224
+ spec: { prefix: string; suffix: string | undefined; q: number; o: number },
225
+ ): { q: number; s: number; o: number } | null {
226
+ const match = simpleLanguageRegExp.exec(language)
227
+ if (!match) return null
228
+
229
+ const prefix = match[1].toLowerCase()
230
+ const suffix = match[2]?.toLowerCase()
231
+
232
+ if (spec.prefix === "*") {
233
+ return { q: spec.q, s: 0, o: spec.o }
234
+ }
235
+
236
+ if (spec.prefix !== prefix) {
237
+ return null
238
+ }
239
+
240
+ if (spec.suffix === undefined) {
241
+ return { q: spec.q, s: suffix ? 2 : 4, o: spec.o }
242
+ }
243
+
244
+ if (spec.suffix === suffix) {
245
+ return { q: spec.q, s: 4, o: spec.o }
246
+ }
247
+
248
+ return null
249
+ }
250
+
251
+ function getLanguagePriority(
252
+ language: string,
253
+ accepted: Array<
254
+ { prefix: string; suffix: string | undefined; q: number; o: number }
255
+ >,
256
+ index: number,
257
+ ): ParsedSpec {
258
+ let best: { q: number; s: number; o: number } | null = null
259
+
260
+ for (const spec of accepted) {
261
+ const result = specifyLanguage(language, spec)
262
+ if (
263
+ result
264
+ && (best === null
265
+ || result.s > best.s
266
+ || (result.s === best.s && result.q > best.q)
267
+ || (result.s === best.s && result.q === best.q && result.o < best.o))
268
+ ) {
269
+ best = result
270
+ }
271
+ }
272
+
273
+ return {
274
+ value: language,
275
+ q: best?.q ?? 0,
276
+ s: best?.s ?? 0,
277
+ o: best?.o ?? -1,
278
+ i: index,
279
+ }
280
+ }
281
+
282
+ function parseAcceptEncoding(
283
+ accept: string,
284
+ ): Array<{ encoding: string; q: number; o: number }> {
285
+ const specs: Array<{ encoding: string; q: number; o: number }> = []
286
+ const parts = accept.split(",")
287
+ let hasIdentity = false
288
+
289
+ for (let o = 0; o < parts.length; o++) {
290
+ const part = parts[o].trim()
291
+ if (!part) continue
292
+
293
+ const match = simpleEncodingRegExp.exec(part)
294
+ if (!match) continue
295
+
296
+ const encoding = match[1].toLowerCase()
297
+ const q = parseQuality(match[2])
298
+
299
+ if (encoding === "identity") hasIdentity = true
300
+ if (encoding === "*") hasIdentity = true
301
+
302
+ if (q > 0) {
303
+ specs.push({ encoding, q, o })
304
+ }
305
+ }
306
+
307
+ if (!hasIdentity) {
308
+ specs.push({ encoding: "identity", q: 0.0001, o: specs.length })
309
+ }
310
+
311
+ return specs
312
+ }
313
+
314
+ function specifyEncoding(
315
+ encoding: string,
316
+ spec: { encoding: string; q: number; o: number },
317
+ ): { q: number; s: number; o: number } | null {
318
+ const e = encoding.toLowerCase()
319
+ const s = spec.encoding
320
+
321
+ if (s === "*" || s === e) {
322
+ return { q: spec.q, s: s === e ? 1 : 0, o: spec.o }
323
+ }
324
+
325
+ return null
326
+ }
327
+
328
+ function getEncodingPriority(
329
+ encoding: string,
330
+ accepted: Array<{ encoding: string; q: number; o: number }>,
331
+ index: number,
332
+ ): ParsedSpec {
333
+ let best: { q: number; s: number; o: number } | null = null
334
+
335
+ for (const spec of accepted) {
336
+ const result = specifyEncoding(encoding, spec)
337
+ if (
338
+ result
339
+ && (best === null
340
+ || result.s > best.s
341
+ || (result.s === best.s && result.q > best.q)
342
+ || (result.s === best.s && result.q === best.q && result.o < best.o))
343
+ ) {
344
+ best = result
345
+ }
346
+ }
347
+
348
+ return {
349
+ value: encoding,
350
+ q: best?.q ?? 0,
351
+ s: best?.s ?? 0,
352
+ o: best?.o ?? -1,
353
+ i: index,
354
+ }
355
+ }
356
+
357
+ function parseAcceptCharset(
358
+ accept: string,
359
+ ): Array<{ charset: string; q: number; o: number }> {
360
+ const specs: Array<{ charset: string; q: number; o: number }> = []
361
+ const parts = accept.split(",")
362
+
363
+ for (let o = 0; o < parts.length; o++) {
364
+ const part = parts[o].trim()
365
+ if (!part) continue
366
+
367
+ const match = simpleCharsetRegExp.exec(part)
368
+ if (!match) continue
369
+
370
+ const charset = match[1].toLowerCase()
371
+ const q = parseQuality(match[2])
372
+
373
+ if (q > 0) {
374
+ specs.push({ charset, q, o })
375
+ }
376
+ }
377
+
378
+ return specs
379
+ }
380
+
381
+ function specifyCharset(
382
+ charset: string,
383
+ spec: { charset: string; q: number; o: number },
384
+ ): { q: number; s: number; o: number } | null {
385
+ const c = charset.toLowerCase()
386
+ const s = spec.charset
387
+
388
+ if (s === "*" || s === c) {
389
+ return { q: spec.q, s: s === c ? 1 : 0, o: spec.o }
390
+ }
391
+
392
+ return null
393
+ }
394
+
395
+ function getCharsetPriority(
396
+ charset: string,
397
+ accepted: Array<{ charset: string; q: number; o: number }>,
398
+ index: number,
399
+ ): ParsedSpec {
400
+ let best: { q: number; s: number; o: number } | null = null
401
+
402
+ for (const spec of accepted) {
403
+ const result = specifyCharset(charset, spec)
404
+ if (
405
+ result
406
+ && (best === null
407
+ || result.s > best.s
408
+ || (result.s === best.s && result.q > best.q)
409
+ || (result.s === best.s && result.q === best.q && result.o < best.o))
410
+ ) {
411
+ best = result
412
+ }
413
+ }
414
+
415
+ return {
416
+ value: charset,
417
+ q: best?.q ?? 0,
418
+ s: best?.s ?? 0,
419
+ o: best?.o ?? -1,
420
+ i: index,
421
+ }
422
+ }
423
+
424
+ function compareSpecs(a: ParsedSpec, b: ParsedSpec): number {
425
+ return (
426
+ b.q - a.q
427
+ || b.s - a.s
428
+ || a.o - b.o
429
+ || a.i - b.i
430
+ )
431
+ }
432
+
433
+ export function media(accept: string, available?: string[]): string[] {
434
+ const parsed = parseAccept(accept)
435
+ if (parsed.length === 0) {
436
+ return []
437
+ }
438
+
439
+ if (!available) {
440
+ return parsed.sort((a, b) => b.q - a.q || a.o - b.o).map((p) =>
441
+ `${p.type}/${p.subtype}`
442
+ )
443
+ }
444
+
445
+ const priorities = available.map((t, i) => getMediaTypePriority(t, parsed, i))
446
+ const sorted = priorities.filter((p) => p.q > 0).sort(compareSpecs)
447
+
448
+ return sorted.map((p) => p.value)
449
+ }
450
+
451
+ export function language(accept: string, available?: string[]): string[] {
452
+ const parsed = parseAcceptLanguage(accept)
453
+ if (parsed.length === 0) {
454
+ return []
455
+ }
456
+
457
+ if (!available) {
458
+ return parsed.sort((a, b) => b.q - a.q || a.o - b.o).map((p) =>
459
+ p.suffix ? `${p.prefix}-${p.suffix}` : p.prefix
460
+ )
461
+ }
462
+
463
+ const priorities = available.map((l, i) => getLanguagePriority(l, parsed, i))
464
+ const sorted = priorities.filter((p) => p.q > 0).sort(compareSpecs)
465
+
466
+ return sorted.map((p) => p.value)
467
+ }
468
+
469
+ export function encoding(accept: string, available?: string[]): string[] {
470
+ const parsed = parseAcceptEncoding(accept)
471
+ if (parsed.length === 0) {
472
+ return []
473
+ }
474
+
475
+ if (!available) {
476
+ return parsed.sort((a, b) => b.q - a.q || a.o - b.o).map((p) => p.encoding)
477
+ }
478
+
479
+ const priorities = available.map((e, i) => getEncodingPriority(e, parsed, i))
480
+ const sorted = priorities.filter((p) => p.q > 0).sort(compareSpecs)
481
+
482
+ return sorted.map((p) => p.value)
483
+ }
484
+
485
+ export function charset(accept: string, available?: string[]): string[] {
486
+ const parsed = parseAcceptCharset(accept)
487
+ if (parsed.length === 0) {
488
+ return []
489
+ }
490
+
491
+ if (!available) {
492
+ return parsed.sort((a, b) => b.q - a.q || a.o - b.o).map((p) => p.charset)
493
+ }
494
+
495
+ const priorities = available.map((c, i) => getCharsetPriority(c, parsed, i))
496
+ const sorted = priorities.filter((p) => p.q > 0).sort(compareSpecs)
497
+
498
+ return sorted.map((p) => p.value)
499
+ }
500
+
501
+ export function headerMedia(
502
+ headers: Headers.Headers,
503
+ available?: string[],
504
+ ): string[] {
505
+ const accept = headers["accept"]
506
+ if (!accept) return []
507
+ return media(accept, available)
508
+ }
509
+
510
+ export function headerLanguage(
511
+ headers: Headers.Headers,
512
+ available?: string[],
513
+ ): string[] {
514
+ const accept = headers["accept-language"]
515
+ if (!accept) return []
516
+ return language(accept, available)
517
+ }
518
+
519
+ export function headerEncoding(
520
+ headers: Headers.Headers,
521
+ available?: string[],
522
+ ): string[] {
523
+ const accept = headers["accept-encoding"]
524
+ if (!accept) return []
525
+ return encoding(accept, available)
526
+ }
527
+
528
+ export function headerCharset(
529
+ headers: Headers.Headers,
530
+ available?: string[],
531
+ ): string[] {
532
+ const accept = headers["accept-charset"]
533
+ if (!accept) return []
534
+ return charset(accept, available)
535
+ }
package/src/FileRouter.ts CHANGED
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  import type { PlatformError } from "@effect/platform/Error"
2
3
  import * as FileSystem from "@effect/platform/FileSystem"
3
4
  import * as Array from "effect/Array"
@@ -12,11 +13,9 @@ import * as NUrl from "node:url"
12
13
  import * as FileRouterCodegen from "./FileRouterCodegen.ts"
13
14
  import * as FileRouterPattern from "./FileRouterPattern.ts"
14
15
  import * as FileSystemExtra from "./FileSystemExtra.ts"
15
- import * as Route from "./Route.ts"
16
- import * as Router from "./Router.ts"
17
16
 
18
17
  export type RouteModule = {
19
- default: Route.RouteSet.Default
18
+ default: RouteSet.RouteSet.Default
20
19
  }
21
20
 
22
21
  export type LazyRoute = {
@@ -187,7 +186,9 @@ export function fromManifest(
187
186
  manifest: Manifest,
188
187
  ): Effect.Effect<Router.Router.Any> {
189
188
  return Effect.gen(function*() {
190
- const loadedEntries = yield* Effect.forEach(
189
+ const mounts: Record<`/${string}`, RouteSet.RouteSet.Default> = {}
190
+
191
+ yield* Effect.forEach(
191
192
  manifest.routes,
192
193
  (lazyRoute) =>
193
194
  Effect.gen(function*() {
@@ -199,19 +200,22 @@ export function fromManifest(
199
200
  )
200
201
  : []
201
202
 
202
- const layers = layerModules
203
- .map((m: any) => m.default)
204
- .filter(Route.isRouteLayer)
203
+ // Start with the route from the route module
204
+ let mergedRouteSet: RouteSet.RouteSet.Default = routeModule.default
205
205
 
206
- return {
207
- path: lazyRoute.path,
208
- route: routeModule.default,
209
- layers,
206
+ // Concatenate each layer's routes into the routeSet
207
+ for (const m of layerModules) {
208
+ const layerRouteSet = (m as any).default
209
+ if (RouteSet.isRouteSet(layerRouteSet)) {
210
+ mergedRouteSet = Route.merge(layerRouteSet, mergedRouteSet)
211
+ }
210
212
  }
213
+
214
+ mounts[lazyRoute.path] = mergedRouteSet
211
215
  }),
212
216
  )
213
217
 
214
- return Router.make(loadedEntries, [])
218
+ return Router.make(mounts, RouteSet.make())
215
219
  })
216
220
  }
217
221