effect-start 0.20.1 → 0.22.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 (105) hide show
  1. package/README.md +1 -4
  2. package/dist/Cookies.js +392 -0
  3. package/dist/FileSystem.js +131 -0
  4. package/dist/Socket.js +37 -0
  5. package/package.json +39 -40
  6. package/src/Commander.ts +73 -130
  7. package/src/ContentNegotiation.ts +68 -100
  8. package/src/Cookies.ts +408 -0
  9. package/src/Development.ts +48 -63
  10. package/src/Effectify.ts +222 -206
  11. package/src/Entity.ts +59 -86
  12. package/src/FilePathPattern.ts +5 -5
  13. package/src/FileRouter.ts +38 -63
  14. package/src/FileRouterCodegen.ts +64 -56
  15. package/src/FileSystem.ts +390 -0
  16. package/src/Http.ts +17 -50
  17. package/src/PathPattern.ts +33 -41
  18. package/src/PlatformError.ts +29 -50
  19. package/src/PlatformRuntime.ts +39 -47
  20. package/src/Route.ts +68 -187
  21. package/src/RouteBody.ts +45 -161
  22. package/src/RouteHook.ts +22 -45
  23. package/src/RouteHttp.ts +88 -142
  24. package/src/RouteHttpTracer.ts +25 -26
  25. package/src/RouteMount.ts +100 -238
  26. package/src/RouteSchema.ts +67 -201
  27. package/src/RouteSse.ts +28 -82
  28. package/src/RouteTree.ts +31 -79
  29. package/src/RouteTrie.ts +13 -32
  30. package/src/SchemaExtra.ts +3 -5
  31. package/src/Socket.ts +51 -0
  32. package/src/Start.ts +20 -21
  33. package/src/StreamExtra.ts +93 -96
  34. package/src/TuplePathPattern.ts +54 -43
  35. package/src/Unique.ts +9 -15
  36. package/src/Values.ts +26 -30
  37. package/src/bun/BunBundle.ts +27 -73
  38. package/src/bun/BunImportTrackerPlugin.ts +67 -65
  39. package/src/bun/BunRoute.ts +12 -31
  40. package/src/bun/BunRuntime.ts +3 -10
  41. package/src/bun/BunServer.ts +50 -60
  42. package/src/bun/BunVirtualFilesPlugin.ts +1 -4
  43. package/src/bun/_BunEnhancedResolve.ts +17 -42
  44. package/src/bun/_empty.html +0 -1
  45. package/src/bundler/Bundle.ts +20 -36
  46. package/src/bundler/BundleFiles.ts +36 -56
  47. package/src/client/Overlay.ts +1 -2
  48. package/src/client/ScrollState.ts +5 -9
  49. package/src/client/index.ts +10 -13
  50. package/src/datastar/actions/fetch.ts +29 -48
  51. package/src/datastar/actions/peek.ts +1 -5
  52. package/src/datastar/actions/setAll.ts +2 -2
  53. package/src/datastar/actions/toggleAll.ts +2 -2
  54. package/src/datastar/attributes/attr.ts +17 -18
  55. package/src/datastar/attributes/bind.ts +41 -61
  56. package/src/datastar/attributes/class.ts +2 -5
  57. package/src/datastar/attributes/computed.ts +2 -10
  58. package/src/datastar/attributes/effect.ts +1 -2
  59. package/src/datastar/attributes/indicator.ts +2 -8
  60. package/src/datastar/attributes/init.ts +2 -10
  61. package/src/datastar/attributes/jsonSignals.ts +1 -6
  62. package/src/datastar/attributes/on.ts +4 -13
  63. package/src/datastar/attributes/onIntersect.ts +10 -22
  64. package/src/datastar/attributes/onInterval.ts +2 -10
  65. package/src/datastar/attributes/onSignalPatch.ts +18 -28
  66. package/src/datastar/attributes/ref.ts +1 -2
  67. package/src/datastar/attributes/show.ts +1 -2
  68. package/src/datastar/attributes/signals.ts +1 -5
  69. package/src/datastar/attributes/style.ts +6 -12
  70. package/src/datastar/attributes/text.ts +1 -2
  71. package/src/datastar/engine.ts +102 -158
  72. package/src/datastar/index.ts +2 -2
  73. package/src/datastar/utils.ts +16 -51
  74. package/src/datastar/watchers/patchElements.ts +35 -93
  75. package/src/datastar/watchers/patchSignals.ts +1 -2
  76. package/src/experimental/EncryptedCookies.ts +81 -175
  77. package/src/experimental/index.ts +0 -1
  78. package/src/hyper/Hyper.ts +14 -33
  79. package/src/hyper/HyperHtml.ts +13 -10
  80. package/src/hyper/HyperNode.ts +2 -7
  81. package/src/hyper/HyperRoute.ts +2 -5
  82. package/src/hyper/jsx-runtime.ts +2 -10
  83. package/src/hyper/jsx.d.ts +171 -440
  84. package/src/lint/plugin.js +276 -0
  85. package/src/node/NodeFileSystem.ts +140 -202
  86. package/src/node/NodeUtils.ts +1 -3
  87. package/src/testing/TestLogger.ts +9 -22
  88. package/src/testing/index.ts +0 -1
  89. package/src/testing/utils.ts +30 -31
  90. package/src/x/cloudflare/CloudflareTunnel.ts +53 -65
  91. package/src/x/datastar/Datastar.ts +3 -10
  92. package/src/x/datastar/index.ts +1 -3
  93. package/src/x/datastar/jsx-datastar.d.ts +1 -4
  94. package/src/x/tailwind/TailwindPlugin.ts +119 -112
  95. package/src/x/tailwind/compile.ts +10 -33
  96. package/src/x/tailwind/plugin.ts +2 -2
  97. package/src/HttpAppExtra.ts +0 -478
  98. package/src/HttpUtils.ts +0 -17
  99. package/src/bun/BunPlatformHttpServer.ts +0 -88
  100. package/src/bun/BunServerRequest.ts +0 -396
  101. package/src/bundler/BundleHttp.ts +0 -259
  102. package/src/experimental/SseHttpResponse.ts +0 -55
  103. package/src/middlewares/BasicAuthMiddleware.ts +0 -36
  104. package/src/middlewares/index.ts +0 -1
  105. package/src/testing/TestHttpClient.ts +0 -148
package/src/Entity.ts CHANGED
@@ -24,10 +24,7 @@ export type Headers = {
24
24
  [header: string]: string | null | undefined
25
25
  }
26
26
 
27
- export interface Entity<
28
- T = unknown,
29
- E = never,
30
- > extends Pipeable.Pipeable {
27
+ export interface Entity<T = unknown, E = never> extends Pipeable.Pipeable {
31
28
  readonly [TypeId]: TypeId
32
29
  readonly body: T
33
30
  readonly headers: Headers
@@ -39,18 +36,21 @@ export interface Entity<
39
36
  */
40
37
  readonly url: string | undefined
41
38
  readonly status: number | undefined
42
- readonly text: T extends string ? Effect.Effect<T, ParseResult.ParseError | E>
39
+ readonly text: T extends string
40
+ ? Effect.Effect<T, ParseResult.ParseError | E>
43
41
  : Effect.Effect<string, ParseResult.ParseError | E>
44
- readonly json: [T] extends [Effect.Effect<infer A, any, any>] ? Effect.Effect<
45
- A extends string | Uint8Array | ArrayBuffer ? unknown : A,
46
- ParseResult.ParseError | E
47
- >
42
+ readonly json: [T] extends [Effect.Effect<infer A, any, any>]
43
+ ? Effect.Effect<
44
+ A extends string | Uint8Array | ArrayBuffer ? unknown : A,
45
+ ParseResult.ParseError | E
46
+ >
48
47
  : [T] extends [Stream.Stream<any, any, any>]
49
48
  ? Effect.Effect<unknown, ParseResult.ParseError | E>
50
- : [T] extends [string | Uint8Array | ArrayBuffer]
51
- ? Effect.Effect<unknown, ParseResult.ParseError | E>
52
- : [T] extends [Values.Json] ? Effect.Effect<T, ParseResult.ParseError | E>
53
- : Effect.Effect<unknown, ParseResult.ParseError | E>
49
+ : [T] extends [string | Uint8Array | ArrayBuffer]
50
+ ? Effect.Effect<unknown, ParseResult.ParseError | E>
51
+ : [T] extends [Values.Json]
52
+ ? Effect.Effect<T, ParseResult.ParseError | E>
53
+ : Effect.Effect<unknown, ParseResult.ParseError | E>
54
54
  readonly bytes: Effect.Effect<Uint8Array, ParseResult.ParseError | E>
55
55
  readonly stream: T extends Stream.Stream<infer A, infer E1, any>
56
56
  ? Stream.Stream<A, ParseResult.ParseError | E | E1>
@@ -82,9 +82,7 @@ function getText(
82
82
  ): Effect.Effect<string, ParseResult.ParseError | unknown> {
83
83
  const v = self.body
84
84
  if (StreamExtra.isStream(v)) {
85
- return Stream.mkString(
86
- Stream.decodeText(v as Stream.Stream<Uint8Array, unknown, never>),
87
- )
85
+ return Stream.mkString(Stream.decodeText(v as Stream.Stream<Uint8Array, unknown, never>))
88
86
  }
89
87
  if (Effect.isEffect(v)) {
90
88
  return Effect.flatMap(
@@ -201,63 +199,53 @@ function getBytes(
201
199
  function getStream<A, E1, E2>(
202
200
  self: Entity<Stream.Stream<A, E1, never>, E2>,
203
201
  ): Stream.Stream<A, ParseResult.ParseError | E1 | E2>
204
- function getStream<T, E>(
205
- self: Entity<T, E>,
206
- ): Stream.Stream<Uint8Array, ParseResult.ParseError | E>
207
- function getStream(
208
- self: Entity<unknown, unknown>,
209
- ): Stream.Stream<unknown, unknown> {
202
+ function getStream<T, E>(self: Entity<T, E>): Stream.Stream<Uint8Array, ParseResult.ParseError | E>
203
+ function getStream(self: Entity<unknown, unknown>): Stream.Stream<unknown, unknown> {
210
204
  const v = self.body
211
205
  if (StreamExtra.isStream(v)) {
212
206
  return v as Stream.Stream<unknown, unknown, never>
213
207
  }
214
208
  if (Effect.isEffect(v)) {
215
209
  return Stream.unwrap(
216
- Effect.map(
217
- v as Effect.Effect<unknown, unknown, never>,
218
- (inner) => {
219
- if (isEntity(inner)) {
220
- return inner.stream
221
- }
222
- return Stream.fromEffect(getBytes(make(inner)))
223
- },
224
- ),
210
+ Effect.map(v as Effect.Effect<unknown, unknown, never>, (inner) => {
211
+ if (isEntity(inner)) {
212
+ return inner.stream
213
+ }
214
+ return Stream.fromEffect(getBytes(make(inner)))
215
+ }),
225
216
  )
226
217
  }
227
218
  return Stream.fromEffect(getBytes(self))
228
219
  }
229
220
 
230
- const Proto: Proto = Object.defineProperties(
231
- Object.create(null),
232
- {
233
- [TypeId]: { value: TypeId },
234
- pipe: {
235
- value: function(this: Entity) {
236
- return Pipeable.pipeArguments(this, arguments)
237
- },
221
+ const Proto: Proto = Object.defineProperties(Object.create(null), {
222
+ [TypeId]: { value: TypeId },
223
+ pipe: {
224
+ value: function (this: Entity) {
225
+ return Pipeable.pipeArguments(this, arguments)
238
226
  },
239
- text: {
240
- get(this: Entity<unknown, unknown>) {
241
- return getText(this)
242
- },
227
+ },
228
+ text: {
229
+ get(this: Entity<unknown, unknown>) {
230
+ return getText(this)
243
231
  },
244
- json: {
245
- get(this: Entity<unknown, unknown>) {
246
- return getJson(this)
247
- },
232
+ },
233
+ json: {
234
+ get(this: Entity<unknown, unknown>) {
235
+ return getJson(this)
248
236
  },
249
- bytes: {
250
- get(this: Entity<unknown, unknown>) {
251
- return getBytes(this)
252
- },
237
+ },
238
+ bytes: {
239
+ get(this: Entity<unknown, unknown>) {
240
+ return getBytes(this)
253
241
  },
254
- stream: {
255
- get(this: Entity<unknown, unknown>) {
256
- return getStream(this)
257
- },
242
+ },
243
+ stream: {
244
+ get(this: Entity<unknown, unknown>) {
245
+ return getStream(this)
258
246
  },
259
247
  },
260
- )
248
+ })
261
249
 
262
250
  export function isEntity(input: unknown): input is Entity {
263
251
  return Predicate.hasProperty(input, TypeId)
@@ -278,42 +266,30 @@ export function make<A extends Uint8Array | string, E>(
278
266
  options?: Options,
279
267
  ): Entity<Stream.Stream<A, E, never>, E>
280
268
  export function make<T>(body: T, options?: Options): Entity<T, never>
281
- export function make(
282
- body: unknown,
283
- options?: Options,
284
- ): Entity<unknown, unknown> {
285
- return Object.assign(
286
- Object.create(Proto),
287
- {
288
- body,
289
- headers: options?.headers ?? {},
290
- url: options?.url,
291
- status: options?.status,
292
- },
293
- )
269
+ export function make(body: unknown, options?: Options): Entity<unknown, unknown> {
270
+ return Object.assign(Object.create(Proto), {
271
+ body,
272
+ headers: options?.headers ?? {},
273
+ url: options?.url,
274
+ status: options?.status,
275
+ })
294
276
  }
295
277
 
296
- export function effect<A, E, R>(
297
- body: Effect.Effect<Entity<A> | A, E, R>,
298
- ): Entity<A, E> {
278
+ export function effect<A, E, R>(body: Effect.Effect<Entity<A> | A, E, R>): Entity<A, E> {
299
279
  return make(body) as unknown as Entity<A, E>
300
280
  }
301
281
 
302
- export function resolve<A, E>(
303
- entity: Entity<A, E>,
304
- ): Effect.Effect<Entity<A, E>, E, never> {
282
+ export function resolve<A, E>(entity: Entity<A, E>): Effect.Effect<Entity<A, E>, E, never> {
305
283
  const body = entity.body
306
284
  if (Effect.isEffect(body)) {
307
- return Effect.map(
308
- body as Effect.Effect<Entity<A> | A, E, never>,
309
- (inner) =>
310
- isEntity(inner)
311
- ? inner as Entity<A, E>
312
- : make(inner as A, {
285
+ return Effect.map(body as Effect.Effect<Entity<A> | A, E, never>, (inner) =>
286
+ isEntity(inner)
287
+ ? (inner as Entity<A, E>)
288
+ : (make(inner as A, {
313
289
  status: entity.status,
314
290
  headers: entity.headers,
315
291
  url: entity.url,
316
- }) as Entity<A, E>,
292
+ }) as Entity<A, E>),
317
293
  )
318
294
  }
319
295
  return Effect.succeed(entity)
@@ -349,10 +325,7 @@ export function length(self: Entity): number | undefined {
349
325
  return undefined
350
326
  }
351
327
 
352
- function mismatch(
353
- expected: Schema.Schema.Any,
354
- actual: unknown,
355
- ): ParseResult.ParseError {
328
+ function mismatch(expected: Schema.Schema.Any, actual: unknown): ParseResult.ParseError {
356
329
  return new ParseResult.ParseError({
357
330
  issue: new ParseResult.Type(expected.ast, actual),
358
331
  })
@@ -10,9 +10,9 @@ export type Segment =
10
10
  | { _tag: "LiteralSegment"; value: string }
11
11
  | { _tag: "InvalidSegment"; value: string }
12
12
 
13
- export function segments(pattern: string): Segment[] {
13
+ export function segments(pattern: string): Array<Segment> {
14
14
  const parts = pattern.split("/").filter(Boolean)
15
- const result: Segment[] = []
15
+ const result: Array<Segment> = []
16
16
 
17
17
  for (const part of parts) {
18
18
  if (/^\(\w+\)$/.test(part)) {
@@ -37,7 +37,7 @@ export type ValidationError = {
37
37
  message: string
38
38
  }
39
39
 
40
- export type ValidationResult = Either.Either<Segment[], ValidationError>
40
+ export type ValidationResult = Either.Either<Array<Segment>, ValidationError>
41
41
 
42
42
  export function validate(pattern: string): ValidationResult {
43
43
  const segs = segments(pattern)
@@ -63,7 +63,7 @@ export function validate(pattern: string): ValidationResult {
63
63
  return Either.right(segs)
64
64
  }
65
65
 
66
- export function format(segs: Segment[]): `/${string}` {
66
+ export function format(segs: Array<Segment>): `/${string}` {
67
67
  const parts = segs.map((seg) => {
68
68
  switch (seg._tag) {
69
69
  case "GroupSegment":
@@ -92,7 +92,7 @@ export function toPathPattern(
92
92
  }
93
93
 
94
94
  const segs = result.right
95
- const pathParts: string[] = []
95
+ const pathParts: Array<string> = []
96
96
 
97
97
  for (const seg of segs) {
98
98
  switch (seg._tag) {
package/src/FileRouter.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as FileSystem from "@effect/platform/FileSystem"
1
+ import * as FileSystem from "./FileSystem.ts"
2
2
  import * as Data from "effect/Data"
3
3
  import * as Effect from "effect/Effect"
4
4
  import * as Either from "effect/Either"
@@ -17,10 +17,7 @@ import * as Route from "./Route.ts"
17
17
  import * as RouteTree from "./RouteTree.ts"
18
18
 
19
19
  export class FileRouterError extends Data.TaggedError("FileRouterError")<{
20
- reason:
21
- | "Import"
22
- | "Conflict"
23
- | "FileSystem"
20
+ reason: "Import" | "Conflict" | "FileSystem"
24
21
  cause?: unknown
25
22
  path?: string
26
23
  }> {}
@@ -32,23 +29,18 @@ export type RouteModule = {
32
29
  export type LazyRouteModule = () => Promise<RouteModule>
33
30
 
34
31
  export type FileRoutes = {
35
- [path: PathPattern.PathPattern]: [
36
- LazyRouteModule,
37
- ...LazyRouteModule[],
38
- ]
32
+ [path: PathPattern.PathPattern]: [LazyRouteModule, ...LazyRouteModule[]]
39
33
  }
40
34
 
41
35
  export type Segment = FilePathPattern.Segment
42
36
 
43
37
  export type FileRoute = {
44
- handle:
45
- | "route"
46
- | "layer"
38
+ handle: "route" | "layer"
47
39
  // eg. `/about/route.tsx`, `/users/[userId]/route.tsx`, `/(admin)/users/route.tsx`
48
40
  modulePath: `/${string}`
49
41
  // eg. `/about`, `/users/[userId]`, `/users` (groups stripped)
50
42
  routePath: `/${string}`
51
- segments: Segment[]
43
+ segments: Array<Segment>
52
44
  }
53
45
 
54
46
  /**
@@ -58,19 +50,17 @@ export type FileRoute = {
58
50
  * - users/[userId]/route.tsx
59
51
  * - [[rest]]/route.tsx
60
52
  */
61
- export type OrderedFileRoutes = FileRoute[]
53
+ export type OrderedFileRoutes = Array<FileRoute>
62
54
 
63
55
  const ROUTE_PATH_REGEX = /^\/?(.*\/?)(?:route|layer)\.(jsx?|tsx?)$/
64
56
 
65
- export function parseRoute(
66
- path: string,
67
- ): FileRoute | null {
57
+ export function parseRoute(path: string): FileRoute | null {
68
58
  const segs = FilePathPattern.segments(path)
69
59
 
70
60
  const lastSeg = segs.at(-1)
71
- const handleMatch = lastSeg?._tag === "LiteralSegment"
72
- && lastSeg.value.match(/^(route|layer)\.(tsx?|jsx?)$/)
73
- const handle = handleMatch ? handleMatch[1] as "route" | "layer" : null
61
+ const handleMatch =
62
+ lastSeg?._tag === "LiteralSegment" && lastSeg.value.match(/^(route|layer)\.(tsx?|jsx?)$/)
63
+ const handle = handleMatch ? (handleMatch[1] as "route" | "layer") : null
74
64
 
75
65
  if (!handle) {
76
66
  return null
@@ -78,9 +68,7 @@ export function parseRoute(
78
68
 
79
69
  const pathSegments = segs.slice(0, -1)
80
70
 
81
- const validated = FilePathPattern.validate(
82
- FilePathPattern.format(pathSegments),
83
- )
71
+ const validated = FilePathPattern.validate(FilePathPattern.format(pathSegments))
84
72
  if (Either.isLeft(validated)) {
85
73
  return null
86
74
  }
@@ -90,9 +78,7 @@ export function parseRoute(
90
78
  return null
91
79
  }
92
80
 
93
- const routePathSegments = pathSegments.filter(
94
- (seg) => seg._tag !== "GroupSegment",
95
- )
81
+ const routePathSegments = pathSegments.filter((seg) => seg._tag !== "GroupSegment")
96
82
  const routePath = FilePathPattern.format(routePathSegments)
97
83
 
98
84
  return {
@@ -103,9 +89,7 @@ export function parseRoute(
103
89
  }
104
90
  }
105
91
 
106
- function importModule<T>(
107
- load: () => Promise<T>,
108
- ): Effect.Effect<T, FileRouterError> {
92
+ function importModule<T>(load: () => Promise<T>): Effect.Effect<T, FileRouterError> {
109
93
  return Effect.tryPromise({
110
94
  try: () => load(),
111
95
  catch: (cause) => new FileRouterError({ reason: "Import", cause }),
@@ -127,12 +111,13 @@ export function layer(
127
111
  | (() => Promise<{ default: FileRoutes }>)
128
112
  | { load: () => Promise<{ default: FileRoutes }>; path: string },
129
113
  ) {
130
- const options = typeof loadOrOptions === "function"
131
- ? {
132
- load: loadOrOptions,
133
- path: NPath.join(NodeUtils.getEntrypoint(), "routes"),
134
- }
135
- : loadOrOptions
114
+ const options =
115
+ typeof loadOrOptions === "function"
116
+ ? {
117
+ load: loadOrOptions,
118
+ path: NPath.join(NodeUtils.getEntrypoint(), "routes"),
119
+ }
120
+ : loadOrOptions
136
121
  let treePath = options.path
137
122
  if (treePath.startsWith("file://")) {
138
123
  treePath = NUrl.fileURLToPath(treePath)
@@ -147,7 +132,7 @@ export function layer(
147
132
 
148
133
  return Layer.scoped(
149
134
  Route.Routes,
150
- Effect.gen(function*() {
135
+ Effect.gen(function* () {
151
136
  // Generate routes file before loading
152
137
  yield* FileRouterCodegen.update(routesPath, treeFilename)
153
138
 
@@ -158,12 +143,8 @@ export function layer(
158
143
  // Watch for changes (only when Development service is available)
159
144
  yield* Function.pipe(
160
145
  Development.stream(),
161
- Stream.filter(e =>
162
- e._tag !== "Reload" && e.path.startsWith(relativeRoutesPath)
163
- ),
164
- Stream.runForEach(() =>
165
- FileRouterCodegen.update(routesPath, treeFilename)
166
- ),
146
+ Stream.filter((e) => e._tag !== "Reload" && e.path.startsWith(relativeRoutesPath)),
147
+ Stream.runForEach(() => FileRouterCodegen.update(routesPath, treeFilename)),
167
148
  Effect.fork,
168
149
  )
169
150
 
@@ -172,25 +153,19 @@ export function layer(
172
153
  )
173
154
  }
174
155
 
175
- export function fromFileRoutes(
176
- fileRoutes: FileRoutes,
177
- ): Effect.Effect<RouteTree.RouteTree> {
178
- return Effect.gen(function*() {
156
+ export function fromFileRoutes(fileRoutes: FileRoutes): Effect.Effect<RouteTree.RouteTree> {
157
+ return Effect.gen(function* () {
179
158
  const mounts: RouteTree.InputRouteMap = {}
180
159
 
181
160
  for (const [path, loaders] of Object.entries(fileRoutes)) {
182
- const modules = yield* Effect.forEach(
183
- loaders,
184
- (loader) => Effect.promise(() => loader()),
185
- )
161
+ const modules = yield* Effect.forEach(loaders, (loader) => Effect.promise(() => loader()))
186
162
 
187
- const allRoutes: RouteTree.RouteTuple =
188
- [] as unknown as RouteTree.RouteTuple
163
+ const allRoutes: RouteTree.RouteTuple = [] as unknown as RouteTree.RouteTuple
189
164
 
190
165
  for (const m of modules) {
191
166
  if (Route.isRouteSet(m.default)) {
192
167
  for (const route of m.default) {
193
- ;(allRoutes as any[]).push(route)
168
+ ;(allRoutes as Array<any>).push(route)
194
169
  }
195
170
  }
196
171
  }
@@ -209,7 +184,7 @@ export function walkRoutesDirectory(
209
184
  PlatformError.PlatformError | FileRouterError,
210
185
  FileSystem.FileSystem
211
186
  > {
212
- return Effect.gen(function*() {
187
+ return Effect.gen(function* () {
213
188
  const fs = yield* FileSystem.FileSystem
214
189
  const files = yield* fs.readDirectory(dir, { recursive: true })
215
190
 
@@ -218,13 +193,13 @@ export function walkRoutesDirectory(
218
193
  }
219
194
 
220
195
  export function getFileRoutes(
221
- paths: string[],
196
+ paths: Array<string>,
222
197
  ): Effect.Effect<OrderedFileRoutes, FileRouterError> {
223
- return Effect.gen(function*() {
198
+ return Effect.gen(function* () {
224
199
  const routes = paths
225
- .map(f => f.match(ROUTE_PATH_REGEX))
200
+ .map((f) => f.match(ROUTE_PATH_REGEX))
226
201
  .filter(Boolean)
227
- .map(v => {
202
+ .map((v) => {
228
203
  const path = v![0]
229
204
  try {
230
205
  return parseRoute(path)
@@ -241,16 +216,16 @@ export function getFileRoutes(
241
216
 
242
217
  return (
243
218
  // rest is a dominant factor (routes with rest come last)
244
- (+aHasRest - +bHasRest) * 1000
219
+ (+aHasRest - +bHasRest) * 1000 +
245
220
  // depth is reversed for rest
246
- + (aDepth - bDepth) * (1 - 2 * +aHasRest)
221
+ (aDepth - bDepth) * (1 - 2 * +aHasRest) +
247
222
  // lexicographic comparison as tiebreaker
248
- + a.modulePath.localeCompare(b.modulePath) * 0.001
223
+ a.modulePath.localeCompare(b.modulePath) * 0.001
249
224
  )
250
225
  })
251
226
 
252
227
  // Detect conflicting routes at the same path
253
- const routesByPath = new Map<string, FileRoute[]>()
228
+ const routesByPath = new Map<string, Array<FileRoute>>()
254
229
  for (const route of routes) {
255
230
  const existing = routesByPath.get(route.routePath) || []
256
231
  existing.push(route)
@@ -258,7 +233,7 @@ export function getFileRoutes(
258
233
  }
259
234
 
260
235
  for (const [path, pathRoutes] of routesByPath) {
261
- const routeHandles = pathRoutes.filter(h => h.handle === "route")
236
+ const routeHandles = pathRoutes.filter((h) => h.handle === "route")
262
237
 
263
238
  if (routeHandles.length > 1) {
264
239
  yield* new FileRouterError({ reason: "Conflict", path })