effect-start 0.14.0 → 0.16.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 (87) hide show
  1. package/package.json +8 -9
  2. package/src/Commander.test.ts +507 -245
  3. package/src/ContentNegotiation.test.ts +603 -0
  4. package/src/ContentNegotiation.ts +542 -0
  5. package/src/Entity.test.ts +592 -0
  6. package/src/Entity.ts +362 -0
  7. package/src/FileRouter.ts +16 -12
  8. package/src/{FileRouterCodegen.test.ts → FileRouterCodegen.todo.ts} +384 -219
  9. package/src/FileRouterCodegen.ts +6 -6
  10. package/src/FileRouterPattern.test.ts +93 -62
  11. package/src/FileRouter_files.test.ts +5 -5
  12. package/src/FileRouter_path.test.ts +121 -69
  13. package/src/FileRouter_tree.test.ts +62 -56
  14. package/src/FileSystemExtra.test.ts +46 -30
  15. package/src/Http.test.ts +319 -0
  16. package/src/Http.ts +167 -0
  17. package/src/HttpAppExtra.test.ts +39 -20
  18. package/src/HttpAppExtra.ts +0 -1
  19. package/src/HttpUtils.test.ts +35 -18
  20. package/src/HttpUtils.ts +2 -0
  21. package/src/PathPattern.test.ts +648 -0
  22. package/src/PathPattern.ts +485 -0
  23. package/src/Route.ts +266 -1069
  24. package/src/RouteBody.test.ts +234 -0
  25. package/src/RouteBody.ts +193 -0
  26. package/src/RouteHook.test.ts +40 -0
  27. package/src/RouteHook.ts +106 -0
  28. package/src/RouteHttp.test.ts +2906 -0
  29. package/src/RouteHttp.ts +427 -0
  30. package/src/RouteHttpTracer.ts +92 -0
  31. package/src/RouteMount.test.ts +481 -0
  32. package/src/RouteMount.ts +470 -0
  33. package/src/RouteSchema.test.ts +427 -0
  34. package/src/RouteSchema.ts +423 -0
  35. package/src/RouteTree.test.ts +494 -0
  36. package/src/RouteTree.ts +219 -0
  37. package/src/RouteTrie.test.ts +322 -0
  38. package/src/RouteTrie.ts +224 -0
  39. package/src/RouterPattern.test.ts +569 -548
  40. package/src/RouterPattern.ts +7 -7
  41. package/src/Start.ts +3 -3
  42. package/src/StreamExtra.ts +21 -1
  43. package/src/TuplePathPattern.ts +64 -0
  44. package/src/Values.test.ts +263 -0
  45. package/src/Values.ts +76 -0
  46. package/src/bun/BunBundle.test.ts +36 -42
  47. package/src/bun/BunBundle.ts +2 -2
  48. package/src/bun/BunBundle_imports.test.ts +4 -6
  49. package/src/bun/BunHttpServer.test.ts +183 -6
  50. package/src/bun/BunHttpServer.ts +72 -32
  51. package/src/bun/BunHttpServer_web.ts +18 -6
  52. package/src/bun/BunImportTrackerPlugin.test.ts +3 -3
  53. package/src/bun/BunRoute.test.ts +124 -442
  54. package/src/bun/BunRoute.ts +146 -286
  55. package/src/{BundleHttp.test.ts → bundler/BundleHttp.test.ts} +34 -60
  56. package/src/{BundleHttp.ts → bundler/BundleHttp.ts} +1 -2
  57. package/src/client/index.ts +1 -1
  58. package/src/{Effect_HttpRouter.test.ts → effect/HttpRouter.test.ts} +69 -90
  59. package/src/experimental/EncryptedCookies.test.ts +125 -64
  60. package/src/experimental/SseHttpResponse.ts +0 -1
  61. package/src/hyper/Hyper.ts +89 -0
  62. package/src/{HyperHtml.test.ts → hyper/HyperHtml.test.ts} +13 -13
  63. package/src/{HyperHtml.ts → hyper/HyperHtml.ts} +2 -2
  64. package/src/{jsx.d.ts → hyper/jsx.d.ts} +1 -1
  65. package/src/index.ts +3 -4
  66. package/src/middlewares/BasicAuthMiddleware.test.ts +29 -19
  67. package/src/{NodeFileSystem.ts → node/FileSystem.ts} +6 -2
  68. package/src/testing/TestHttpClient.test.ts +26 -26
  69. package/src/testing/TestLogger.test.ts +27 -14
  70. package/src/testing/TestLogger.ts +15 -9
  71. package/src/x/datastar/Datastar.test.ts +47 -48
  72. package/src/x/datastar/Datastar.ts +1 -1
  73. package/src/x/tailwind/TailwindPlugin.test.ts +56 -58
  74. package/src/x/tailwind/plugin.ts +1 -1
  75. package/src/FileHttpRouter.test.ts +0 -239
  76. package/src/FileHttpRouter.ts +0 -194
  77. package/src/Hyper.ts +0 -194
  78. package/src/Route.test.ts +0 -1370
  79. package/src/RouteRender.ts +0 -40
  80. package/src/Router.test.ts +0 -375
  81. package/src/Router.ts +0 -255
  82. package/src/bun/BunRoute_bundles.test.ts +0 -219
  83. /package/src/{Bundle.ts → bundler/Bundle.ts} +0 -0
  84. /package/src/{BundleFiles.ts → bundler/BundleFiles.ts} +0 -0
  85. /package/src/{HyperNode.ts → hyper/HyperNode.ts} +0 -0
  86. /package/src/{jsx-runtime.ts → hyper/jsx-runtime.ts} +0 -0
  87. /package/src/{NodeUtils.ts → node/Utils.ts} +0 -0
@@ -1,187 +1,169 @@
1
- import * as HttpApp from "@effect/platform/HttpApp"
2
- import * as HttpServerRequest from "@effect/platform/HttpServerRequest"
3
- import * as HttpServerResponse from "@effect/platform/HttpServerResponse"
4
1
  import type * as Bun from "bun"
5
2
  import * as Array from "effect/Array"
3
+ import * as Data from "effect/Data"
6
4
  import * as Effect from "effect/Effect"
7
- import * as Function from "effect/Function"
8
5
  import * as Option from "effect/Option"
9
- import * as Predicate from "effect/Predicate"
10
- import type * as Runtime from "effect/Runtime"
11
- import * as HttpAppExtra from "../HttpAppExtra.ts"
12
- import * as HttpUtils from "../HttpUtils.ts"
13
- import * as HyperHtml from "../HyperHtml.ts"
6
+ import * as Entity from "../Entity.ts"
7
+ import * as Hyper from "../hyper/Hyper.ts"
8
+ import * as HyperHtml from "../hyper/HyperHtml.ts"
14
9
  import * as Random from "../Random.ts"
15
10
  import * as Route from "../Route.ts"
16
- import * as Router from "../Router.ts"
17
- import * as RouteRender from "../RouteRender.ts"
18
11
  import * as RouterPattern from "../RouterPattern.ts"
19
12
  import * as BunHttpServer from "./BunHttpServer.ts"
20
13
 
21
- const TypeId: unique symbol = Symbol.for("effect-start/BunRoute")
22
-
23
14
  const INTERNAL_FETCH_HEADER = "x-effect-start-internal-fetch"
24
15
 
25
- export type BunRoute =
26
- & Route.Route
27
- & {
28
- [TypeId]: typeof TypeId
29
- // Prefix because Bun.serve routes ignore everything after `*` in wildcard patterns.
30
- // A suffix like `/*~internal` would match the same as `/*`, shadowing the internal route.
31
- internalPathPrefix: string
32
- load: () => Promise<Bun.HTMLBundle>
33
- }
34
-
35
- export function html(
36
- load: () => Promise<Bun.HTMLBundle | { default: Bun.HTMLBundle }>,
37
- ): BunRoute {
38
- const internalPathPrefix = `/.BunRoute-${Random.token(6)}`
39
-
40
- const handler: Route.RouteHandler<
41
- HttpServerResponse.HttpServerResponse,
42
- Router.RouterError,
43
- BunHttpServer.BunHttpServer
44
- > = (context) =>
45
- Effect.gen(function*() {
46
- const originalRequest = context.request.source as Request
47
-
48
- if (
49
- originalRequest.headers.get(INTERNAL_FETCH_HEADER) === "true"
50
- ) {
51
- return yield* Effect.fail(
52
- new Router.RouterError({
53
- reason: "ProxyError",
54
- pattern: context.url.pathname,
55
- message:
56
- "Request to internal Bun server was caught by BunRoute handler. This should not happen. Please report a bug.",
57
- }),
58
- )
59
- }
60
-
61
- const bunServer = yield* BunHttpServer.BunHttpServer
62
-
63
- const internalPath = `${internalPathPrefix}${context.url.pathname}`
64
- const internalUrl = new URL(internalPath, bunServer.server.url)
65
-
66
- const headers = new Headers(originalRequest.headers)
67
- headers.set(INTERNAL_FETCH_HEADER, "true")
68
-
69
- const proxyRequest = new Request(internalUrl, {
70
- method: originalRequest.method,
71
- headers,
72
- })
73
-
74
- const response = yield* Effect.tryPromise({
75
- try: () => fetch(proxyRequest),
76
- catch: (error) =>
77
- new Router.RouterError({
78
- reason: "ProxyError",
79
- pattern: internalPath,
80
- message: `Failed to fetch internal HTML bundle: ${String(error)}`,
81
- }),
82
- })
83
-
84
- let html = yield* Effect.tryPromise({
85
- try: () => response.text(),
86
- catch: (error) =>
87
- new Router.RouterError({
88
- reason: "ProxyError",
89
- pattern: internalPath,
90
- message: String(error),
91
- }),
92
- })
93
-
94
- const children = yield* context.next<Router.RouterError, never>()
95
- let childrenHtml = ""
96
- if (children != null) {
97
- if (HttpServerResponse.isServerResponse(children)) {
98
- const webResponse = HttpServerResponse.toWeb(children)
99
- childrenHtml = yield* Effect.promise(() => webResponse.text())
100
- } else if (Route.isGenericJsxObject(children)) {
101
- childrenHtml = HyperHtml.renderToString(children)
102
- } else {
103
- childrenHtml = String(children)
104
- }
105
- }
106
-
107
- html = html.replace(/%yield%/g, childrenHtml)
108
- html = html.replace(/%slots\.(\w+)%/g, (_, name) =>
109
- context.slots[name] ?? "")
110
-
111
- return HttpServerResponse
112
- .html(html)
113
- })
114
-
115
- const route = Route.make({
116
- method: "*",
117
- media: "text/html",
118
- handler,
119
- schemas: {},
120
- })
121
-
122
- const bunRoute: BunRoute = Object.assign(
123
- Object.create(route),
124
- {
125
- [TypeId]: TypeId,
126
- internalPathPrefix,
127
- load: () => load().then(mod => "default" in mod ? mod.default : mod),
128
- set: [],
129
- },
130
- )
16
+ export class BunRouteError extends Data.TaggedError("BunRouteError")<{
17
+ reason: "ProxyError" | "UnsupportedPattern"
18
+ pattern: string
19
+ message: string
20
+ }> {}
131
21
 
132
- bunRoute.set.push(bunRoute)
133
-
134
- return bunRoute
22
+ export type BunDescriptors = {
23
+ bunPrefix: string
24
+ bunLoad: () => Promise<Bun.HTMLBundle>
135
25
  }
136
26
 
137
- export function isBunRoute(input: unknown): input is BunRoute {
138
- return Predicate.hasProperty(input, TypeId)
27
+ export function descriptors(
28
+ route: Route.Route.Route,
29
+ ): BunDescriptors | undefined {
30
+ const descriptor = Route.descriptor(route) as Partial<BunDescriptors>
31
+ if (
32
+ typeof descriptor.bunPrefix === "string"
33
+ && typeof descriptor.bunLoad === "function"
34
+ ) {
35
+ return descriptor as BunDescriptors
36
+ }
37
+ return undefined
139
38
  }
140
39
 
141
- function makeHandler(routes: Route.Route.Default[]) {
142
- return Effect.gen(function*() {
143
- const request = yield* HttpServerRequest.HttpServerRequest
144
- const accept = request.headers.accept ?? ""
145
-
146
- let selectedRoute: Route.Route.Default | undefined
40
+ export function htmlBundle(
41
+ load: () => Promise<Bun.HTMLBundle | { default: Bun.HTMLBundle }>,
42
+ ) {
43
+ const bunPrefix = `/.BunRoute-${Random.token(6)}`
44
+ const bunLoad = () => load().then(mod => "default" in mod ? mod.default : mod)
45
+ const descriptors = { bunPrefix, bunLoad, format: "html" as const }
46
+
47
+ return function<
48
+ D extends Route.RouteDescriptor.Any,
49
+ B extends {},
50
+ I extends Route.Route.Tuple,
51
+ >(
52
+ self: Route.RouteSet.RouteSet<D, B, I>,
53
+ ): Route.RouteSet.RouteSet<
54
+ D,
55
+ B,
56
+ [
57
+ ...I,
58
+ Route.Route.Route<
59
+ BunDescriptors & { format: "html" },
60
+ { request: Request },
61
+ string,
62
+ BunRouteError,
63
+ BunHttpServer.BunHttpServer
64
+ >,
65
+ ]
66
+ > {
67
+ const handler: Route.Route.Handler<
68
+ BunDescriptors & { format: "html" } & { request: Request },
69
+ string,
70
+ BunRouteError,
71
+ BunHttpServer.BunHttpServer
72
+ > = (context, next) =>
73
+ Effect.gen(function*() {
74
+ const originalRequest = context.request
75
+
76
+ if (
77
+ originalRequest.headers.get(INTERNAL_FETCH_HEADER) === "true"
78
+ ) {
79
+ const url = new URL(originalRequest.url)
80
+ return yield* Effect.fail(
81
+ new BunRouteError({
82
+ reason: "ProxyError",
83
+ pattern: url.pathname,
84
+ message:
85
+ "Request to internal Bun server was caught by BunRoute handler. This should not happen. Please report a bug.",
86
+ }),
87
+ )
88
+ }
147
89
 
148
- if (accept.includes("application/json")) {
149
- selectedRoute = routes.find((r) => r.media === "application/json")
150
- }
151
- if (!selectedRoute && accept.includes("text/plain")) {
152
- selectedRoute = routes.find((r) => r.media === "text/plain")
153
- }
154
- if (
155
- !selectedRoute
156
- && (accept.includes("text/html")
157
- || accept.includes("*/*")
158
- || !accept)
159
- ) {
160
- selectedRoute = routes.find((r) => r.media === "text/html")
161
- }
162
- if (!selectedRoute) {
163
- selectedRoute = routes[0]
164
- }
90
+ const bunServer = yield* BunHttpServer.BunHttpServer
91
+ const url = new URL(originalRequest.url)
92
+
93
+ const internalPath = `${bunPrefix}${url.pathname}`
94
+ const internalUrl = new URL(internalPath, bunServer.server.url)
95
+
96
+ const headers = new Headers(originalRequest.headers)
97
+ headers.set(INTERNAL_FETCH_HEADER, "true")
98
+
99
+ const proxyRequest = new Request(internalUrl, {
100
+ method: originalRequest.method,
101
+ headers,
102
+ })
103
+
104
+ const response = yield* Effect.tryPromise({
105
+ try: () => fetch(proxyRequest),
106
+ catch: (error) =>
107
+ new BunRouteError({
108
+ reason: "ProxyError",
109
+ pattern: internalPath,
110
+ message: `Failed to fetch internal HTML bundle: ${String(error)}`,
111
+ }),
112
+ })
113
+
114
+ let html = yield* Effect.tryPromise({
115
+ try: () => response.text(),
116
+ catch: (error) =>
117
+ new BunRouteError({
118
+ reason: "ProxyError",
119
+ pattern: internalPath,
120
+ message: String(error),
121
+ }),
122
+ })
123
+
124
+ const childEntity = yield* Entity.resolve(next(context))
125
+ const children = childEntity?.body ?? childEntity
126
+
127
+ let childrenHtml = ""
128
+ if (children != null) {
129
+ if ((children as unknown) instanceof Response) {
130
+ childrenHtml = yield* Effect.promise(() =>
131
+ (children as unknown as Response).text()
132
+ )
133
+ } else if (Hyper.isGenericJsxObject(children)) {
134
+ childrenHtml = HyperHtml.renderToString(children)
135
+ } else {
136
+ childrenHtml = String(children)
137
+ }
138
+ }
165
139
 
166
- if (!selectedRoute) {
167
- return HttpServerResponse.empty({ status: 406 })
168
- }
140
+ html = html.replace(/%children%/g, childrenHtml)
169
141
 
170
- const context: Route.RouteContext = {
171
- request,
172
- get url() {
173
- return HttpUtils.makeUrlFromRequest(request)
174
- },
175
- slots: {},
176
- next: () => Effect.void,
177
- }
142
+ return Entity.make(html, {
143
+ status: response.status,
144
+ headers: {
145
+ "content-type": response.headers.get("content-type"),
146
+ },
147
+ })
148
+ })
178
149
 
179
- return yield* RouteRender.render(selectedRoute, context).pipe(
180
- Effect.catchAllCause((cause) => HttpAppExtra.renderError(cause, accept)),
150
+ const route = Route.make<
151
+ BunDescriptors & { format: "html" },
152
+ { request: Request },
153
+ string,
154
+ BunRouteError,
155
+ BunHttpServer.BunHttpServer
156
+ >(handler, descriptors)
157
+
158
+ return Route.set(
159
+ [...Route.items(self), route] as any,
160
+ Route.descriptor(self),
181
161
  )
182
- })
162
+ }
183
163
  }
184
164
 
165
+
166
+
185
167
  type BunServerFetchHandler = (
186
168
  request: Request,
187
169
  server: Bun.Server<unknown>,
@@ -194,14 +176,6 @@ type BunServerRouteHandler =
194
176
 
195
177
  export type BunRoutes = Record<string, BunServerRouteHandler>
196
178
 
197
- type MethodHandlers = Partial<
198
- Record<Bun.Serve.HTTPMethod, BunServerFetchHandler>
199
- >
200
-
201
- function isMethodHandlers(value: unknown): value is MethodHandlers {
202
- return typeof value === "object" && value !== null && !("index" in value)
203
- }
204
-
205
179
  /**
206
180
  * Validates that a route pattern can be implemented with Bun.serve routes.
207
181
  *
@@ -223,7 +197,7 @@ function isMethodHandlers(value: unknown): value is MethodHandlers {
223
197
 
224
198
  export function validateBunPattern(
225
199
  pattern: string,
226
- ): Option.Option<Router.RouterError> {
200
+ ): Option.Option<BunRouteError> {
227
201
  const segments = RouterPattern.parse(pattern)
228
202
 
229
203
  const unsupported = Array.findFirst(segments, (seg) => {
@@ -236,7 +210,7 @@ export function validateBunPattern(
236
210
 
237
211
  if (Option.isSome(unsupported)) {
238
212
  return Option.some(
239
- new Router.RouterError({
213
+ new BunRouteError({
240
214
  reason: "UnsupportedPattern",
241
215
  pattern,
242
216
  message:
@@ -249,121 +223,7 @@ export function validateBunPattern(
249
223
  return Option.none()
250
224
  }
251
225
 
252
- /**
253
- * Converts a RouterBuilder into Bun-compatible routes passed to {@link Bun.serve}.
254
- *
255
- * For BunRoutes (HtmlBundle), creates two routes:
256
- * - An internal route at `${path}~BunRoute-${nonce}:${path}` holding the actual HtmlBundle
257
- * - A proxy route at the original path that forwards requests to the internal route
258
- *
259
- * This allows middleware to be attached to the proxy route while Bun handles
260
- * the HtmlBundle natively on the internal route.
261
- */
262
- export function routesFromRouter(
263
- router: Router.Router.Any,
264
- runtime?: Runtime.Runtime<BunHttpServer.BunHttpServer>,
265
- ): Effect.Effect<BunRoutes, Router.RouterError, BunHttpServer.BunHttpServer> {
266
- return Effect.gen(function*() {
267
- const rt = runtime ?? (yield* Effect.runtime<BunHttpServer.BunHttpServer>())
268
- const result: BunRoutes = {}
269
-
270
- for (const entry of router.entries) {
271
- const { path, route: routeSet, layers } = entry
272
-
273
- const validationError = validateBunPattern(path)
274
- if (Option.isSome(validationError)) {
275
- return yield* Effect.fail(validationError.value)
276
- }
277
-
278
- for (const route of routeSet.set) {
279
- if (isBunRoute(route)) {
280
- const bundle = yield* Effect.promise(() => route.load())
281
- const bunPaths = RouterPattern.toBun(path)
282
- for (const bunPath of bunPaths) {
283
- const internalPath = `${route.internalPathPrefix}${bunPath}`
284
- result[internalPath] = bundle
285
- }
286
- }
287
- }
288
-
289
- for (const layer of layers) {
290
- for (const route of layer.set) {
291
- if (isBunRoute(route)) {
292
- const bundle = yield* Effect.promise(() => route.load())
293
- const bunPaths = RouterPattern.toBun(path)
294
- for (const bunPath of bunPaths) {
295
- const internalPath = `${route.internalPathPrefix}${bunPath}`
296
- result[internalPath] = bundle
297
- }
298
- }
299
- }
300
- }
301
- }
302
-
303
- for (const path of Object.keys(router.mounts)) {
304
- const routeSet = router.mounts[path]
305
-
306
- const validationError = validateBunPattern(path)
307
- if (Option.isSome(validationError)) {
308
- continue
309
- }
310
-
311
- const httpPaths = RouterPattern.toBun(path as Route.RoutePattern)
312
-
313
- const byMethod = new Map<Route.RouteMethod, Route.Route.Default[]>()
314
- for (const route of routeSet.set) {
315
- const existing = byMethod.get(route.method) ?? []
316
- existing.push(route)
317
- byMethod.set(route.method, existing)
318
- }
319
-
320
- const entry = router.entries.find((e) => e.path === path)
321
- const allMiddleware = (entry?.layers ?? [])
322
- .map((layer) => layer.httpMiddleware)
323
- .filter((m): m is Route.HttpMiddlewareFunction => m !== undefined)
324
-
325
- for (const [method, routes] of byMethod) {
326
- let httpApp: HttpApp.Default<any, any> = makeHandler(routes)
327
-
328
- for (const middleware of allMiddleware) {
329
- httpApp = middleware(httpApp)
330
- }
331
-
332
- const webHandler = HttpApp.toWebHandlerRuntime(rt)(httpApp)
333
- const handler: BunServerFetchHandler = (request) => {
334
- const url = new URL(request.url)
335
- if (url.pathname.startsWith("/.BunRoute-")) {
336
- return new Response(
337
- "Internal routing error: BunRoute internal path was not matched. "
338
- + "This indicates the HTMLBundle route was not registered. Please report a bug.",
339
- { status: 500 },
340
- )
341
- }
342
- return webHandler(request)
343
- }
344
-
345
- for (const httpPath of httpPaths) {
346
- if (method === "*") {
347
- if (!(httpPath in result)) {
348
- result[httpPath] = handler
349
- }
350
- } else {
351
- const existing = result[httpPath]
352
- if (isMethodHandlers(existing)) {
353
- existing[method] = handler
354
- } else if (!(httpPath in result)) {
355
- result[httpPath] = { [method]: handler }
356
- }
357
- }
358
- }
359
- }
360
- }
361
-
362
- return result
363
- })
364
- }
365
-
366
- export const isHTMLBundle = (handle: any) => {
226
+ export const isHtmlBundle = (handle: any) => {
367
227
  return (
368
228
  typeof handle === "object"
369
229
  && handle !== null
@@ -1,14 +1,14 @@
1
1
  import * as HttpRouter from "@effect/platform/HttpRouter"
2
2
  import * as HttpServerResponse from "@effect/platform/HttpServerResponse"
3
- import * as t from "bun:test"
3
+ import * as test from "bun:test"
4
4
  import * as Effect from "effect/Effect"
5
5
  import * as Layer from "effect/Layer"
6
- import IndexHtml from "../static/react-dashboard.html" with { type: "file" }
7
- import * as BunBundle from "./bun/BunBundle.ts"
6
+ import IndexHtml from "../../static/react-dashboard.html" with { type: "file" }
7
+ import * as BunBundle from "../bun/BunBundle.ts"
8
+ import { effectFn } from "../testing"
9
+ import * as TestHttpClient from "../testing/TestHttpClient.ts"
8
10
  import * as Bundle from "./Bundle.ts"
9
11
  import * as BundleHttp from "./BundleHttp.ts"
10
- import { effectFn } from "./testing"
11
- import * as TestHttpClient from "./testing/TestHttpClient.ts"
12
12
 
13
13
  const effect = effectFn(
14
14
  Layer.effect(
@@ -17,7 +17,7 @@ const effect = effectFn(
17
17
  ),
18
18
  )
19
19
 
20
- t.it("entrypoint with specific uri", () =>
20
+ test.it("entrypoint with specific uri", () =>
21
21
  effect(function*() {
22
22
  const App = HttpRouter.empty.pipe(
23
23
  HttpRouter.get(
@@ -28,19 +28,15 @@ t.it("entrypoint with specific uri", () =>
28
28
  const Client = TestHttpClient.make(App)
29
29
 
30
30
  const dashboardRes = yield* Client.get("/react-dashboard")
31
- t
32
- .expect(
33
- dashboardRes.status,
34
- )
31
+ test
32
+ .expect(dashboardRes.status)
35
33
  .toBe(200)
36
- t
37
- .expect(
38
- yield* dashboardRes.text,
39
- )
34
+ test
35
+ .expect(yield* dashboardRes.text)
40
36
  .toStartWith("<!DOCTYPE html>")
41
37
  }))
42
38
 
43
- t.it("entrypoint without uri parameter", () =>
39
+ test.it("entrypoint without uri parameter", () =>
44
40
  effect(function*() {
45
41
  const App = HttpRouter.empty.pipe(
46
42
  HttpRouter.get(
@@ -68,10 +64,8 @@ t.it("entrypoint without uri parameter", () =>
68
64
  () => HttpServerResponse.empty({ status: 404 }),
69
65
  ),
70
66
  )
71
- t
72
- .expect(
73
- indexRes.status,
74
- )
67
+ test
68
+ .expect(indexRes.status)
75
69
  .toBe(404)
76
70
 
77
71
  const indexPathRes = yield* Client.get("/index").pipe(
@@ -80,22 +74,16 @@ t.it("entrypoint without uri parameter", () =>
80
74
  () => HttpServerResponse.empty({ status: 404 }),
81
75
  ),
82
76
  )
83
- t
84
- .expect(
85
- indexPathRes.status,
86
- )
77
+ test
78
+ .expect(indexPathRes.status)
87
79
  .toBe(404)
88
80
 
89
81
  const dashboardRes = yield* Client.get("/react-dashboard")
90
- t
91
- .expect(
92
- dashboardRes.status,
93
- )
82
+ test
83
+ .expect(dashboardRes.status)
94
84
  .toBe(200)
95
- t
96
- .expect(
97
- yield* dashboardRes.text,
98
- )
85
+ test
86
+ .expect(yield* dashboardRes.text)
99
87
  .toStartWith("<!DOCTYPE html>")
100
88
 
101
89
  const nonexistentRes = yield* Client.get("/nonexistent").pipe(
@@ -104,14 +92,12 @@ t.it("entrypoint without uri parameter", () =>
104
92
  () => HttpServerResponse.empty({ status: 404 }),
105
93
  ),
106
94
  )
107
- t
108
- .expect(
109
- nonexistentRes.status,
110
- )
95
+ test
96
+ .expect(nonexistentRes.status)
111
97
  .toBe(404)
112
98
  }))
113
99
 
114
- t.it("withEntrypoints middleware", () =>
100
+ test.it("withEntrypoints middleware", () =>
115
101
  effect(function*() {
116
102
  const fallbackApp = Effect.succeed(
117
103
  HttpServerResponse.text("Fallback", { status: 404 }),
@@ -121,38 +107,26 @@ t.it("withEntrypoints middleware", () =>
121
107
  const Client = TestHttpClient.make(App)
122
108
 
123
109
  const rootRes = yield* Client.get("/")
124
- t
125
- .expect(
126
- rootRes.status,
127
- )
110
+ test
111
+ .expect(rootRes.status)
128
112
  .toBe(404)
129
- t
130
- .expect(
131
- yield* rootRes.text,
132
- )
113
+ test
114
+ .expect(yield* rootRes.text)
133
115
  .toBe("Fallback")
134
116
 
135
117
  const dashboardRes = yield* Client.get("/react-dashboard")
136
- t
137
- .expect(
138
- dashboardRes.status,
139
- )
118
+ test
119
+ .expect(dashboardRes.status)
140
120
  .toBe(200)
141
- t
142
- .expect(
143
- yield* dashboardRes.text,
144
- )
121
+ test
122
+ .expect(yield* dashboardRes.text)
145
123
  .toStartWith("<!DOCTYPE html>")
146
124
 
147
125
  const nonexistentRes = yield* Client.get("/nonexistent")
148
- t
149
- .expect(
150
- nonexistentRes.status,
151
- )
126
+ test
127
+ .expect(nonexistentRes.status)
152
128
  .toBe(404)
153
- t
154
- .expect(
155
- yield* nonexistentRes.text,
156
- )
129
+ test
130
+ .expect(yield* nonexistentRes.text)
157
131
  .toBe("Fallback")
158
132
  }))
@@ -12,9 +12,8 @@ import * as Scope from "effect/Scope"
12
12
  import * as Stream from "effect/Stream"
13
13
  import * as NPath from "node:path"
14
14
  import * as NUrl from "node:url"
15
+ import * as SseHttpResponse from "../experimental/SseHttpResponse.ts"
15
16
  import * as Bundle from "./Bundle.ts"
16
- import * as SseHttpResponse from "./experimental/SseHttpResponse.ts"
17
-
18
17
 
19
18
  const DefaultBundleEndpoint = "/_bundle"
20
19
 
@@ -10,7 +10,7 @@
10
10
  import type {
11
11
  BundleEvent,
12
12
  BundleManifest,
13
- } from "../Bundle.ts"
13
+ } from "../bundler/Bundle.ts"
14
14
  import { showBuildError } from "./Overlay.ts"
15
15
  import * as ScrollState from "./ScrollState.ts"
16
16