@effect/platform 0.48.27 → 0.48.29

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 (54) hide show
  1. package/README.md +51 -0
  2. package/dist/cjs/Http/App.js +50 -32
  3. package/dist/cjs/Http/App.js.map +1 -1
  4. package/dist/cjs/Http/Headers.js +4 -1
  5. package/dist/cjs/Http/Headers.js.map +1 -1
  6. package/dist/cjs/Http/Router.js.map +1 -1
  7. package/dist/cjs/Http/UrlParams.js +1 -1
  8. package/dist/cjs/Http/UrlParams.js.map +1 -1
  9. package/dist/cjs/Transferable.js +6 -3
  10. package/dist/cjs/Transferable.js.map +1 -1
  11. package/dist/cjs/WorkerError.js +9 -6
  12. package/dist/cjs/WorkerError.js.map +1 -1
  13. package/dist/cjs/internal/http/middleware.js +14 -16
  14. package/dist/cjs/internal/http/middleware.js.map +1 -1
  15. package/dist/cjs/internal/http/multipart.js +2 -2
  16. package/dist/cjs/internal/http/multipart.js.map +1 -1
  17. package/dist/cjs/internal/http/router.js +21 -11
  18. package/dist/cjs/internal/http/router.js.map +1 -1
  19. package/dist/dts/Http/App.d.ts +5 -7
  20. package/dist/dts/Http/App.d.ts.map +1 -1
  21. package/dist/dts/Http/Headers.d.ts.map +1 -1
  22. package/dist/dts/Http/Router.d.ts +57 -20
  23. package/dist/dts/Http/Router.d.ts.map +1 -1
  24. package/dist/dts/Transferable.d.ts.map +1 -1
  25. package/dist/dts/WorkerError.d.ts +2 -2
  26. package/dist/dts/WorkerError.d.ts.map +1 -1
  27. package/dist/dts/internal/http/router.d.ts.map +1 -1
  28. package/dist/esm/Http/App.js +48 -30
  29. package/dist/esm/Http/App.js.map +1 -1
  30. package/dist/esm/Http/Headers.js +4 -1
  31. package/dist/esm/Http/Headers.js.map +1 -1
  32. package/dist/esm/Http/Router.js.map +1 -1
  33. package/dist/esm/Http/UrlParams.js +1 -1
  34. package/dist/esm/Http/UrlParams.js.map +1 -1
  35. package/dist/esm/Transferable.js +6 -3
  36. package/dist/esm/Transferable.js.map +1 -1
  37. package/dist/esm/WorkerError.js +9 -6
  38. package/dist/esm/WorkerError.js.map +1 -1
  39. package/dist/esm/internal/http/middleware.js +14 -16
  40. package/dist/esm/internal/http/middleware.js.map +1 -1
  41. package/dist/esm/internal/http/multipart.js +2 -2
  42. package/dist/esm/internal/http/multipart.js.map +1 -1
  43. package/dist/esm/internal/http/router.js +21 -11
  44. package/dist/esm/internal/http/router.js.map +1 -1
  45. package/package.json +3 -3
  46. package/src/Http/App.ts +70 -46
  47. package/src/Http/Headers.ts +2 -3
  48. package/src/Http/Router.ts +42 -22
  49. package/src/Http/UrlParams.ts +2 -2
  50. package/src/Transferable.ts +3 -4
  51. package/src/WorkerError.ts +11 -9
  52. package/src/internal/http/middleware.ts +7 -7
  53. package/src/internal/http/multipart.ts +2 -2
  54. package/src/internal/http/router.ts +69 -50
@@ -78,18 +78,18 @@ export const logger = make((httpApp) => {
78
78
  })
79
79
 
80
80
  /** @internal */
81
- export const tracer = make((httpApp) => {
82
- const appWithStatus = Effect.tap(
83
- httpApp,
84
- (response) => Effect.annotateCurrentSpan("http.status", response.status)
85
- )
86
- return Effect.withFiberRuntime((fiber) => {
81
+ export const tracer = make((httpApp) =>
82
+ Effect.withFiberRuntime((fiber) => {
87
83
  const context = fiber.getFiberRef(FiberRef.currentContext)
88
84
  const request = Context.unsafeGet(context, ServerRequest.ServerRequest)
89
85
  const disabled = fiber.getFiberRef(currentTracerDisabledWhen)(request)
90
86
  if (disabled) {
91
87
  return httpApp
92
88
  }
89
+ const appWithStatus = Effect.tap(
90
+ httpApp,
91
+ (response) => Effect.annotateCurrentSpan("http.status", response.status)
92
+ )
93
93
  return Effect.withSpan(
94
94
  appWithStatus,
95
95
  `http.server ${request.method}`,
@@ -99,7 +99,7 @@ export const tracer = make((httpApp) => {
99
99
  }
100
100
  )
101
101
  })
102
- })
102
+ )
103
103
 
104
104
  /** @internal */
105
105
  export const xForwardedHeaders = make((httpApp) =>
@@ -105,7 +105,7 @@ const fileSchema: Schema.Schema<Multipart.PersistedFile> = Schema.declare(isPers
105
105
  })
106
106
 
107
107
  /** @internal */
108
- export const filesSchema: Schema.Schema<ReadonlyArray<Multipart.PersistedFile>> = Schema.array(fileSchema)
108
+ export const filesSchema: Schema.Schema<ReadonlyArray<Multipart.PersistedFile>> = Schema.Array(fileSchema)
109
109
 
110
110
  /** @internal */
111
111
  export const schemaPersisted = <R, I extends Partial<Multipart.Persisted>, A>(
@@ -140,7 +140,7 @@ export const schemaJson = <A, I, R>(schema: Schema.Schema<A, I, R>, options?: Pa
140
140
  >(2, (persisted, field) =>
141
141
  Effect.map(
142
142
  Schema.decodeUnknown(
143
- Schema.struct({
143
+ Schema.Struct({
144
144
  [field]: fromJson
145
145
  }),
146
146
  options
@@ -5,6 +5,7 @@ import * as Chunk from "effect/Chunk"
5
5
  import * as Context from "effect/Context"
6
6
  import * as Effect from "effect/Effect"
7
7
  import * as Effectable from "effect/Effectable"
8
+ import * as FiberRef from "effect/FiberRef"
8
9
  import { dual } from "effect/Function"
9
10
  import * as Inspectable from "effect/Inspectable"
10
11
  import * as Option from "effect/Option"
@@ -186,7 +187,8 @@ const toHttpApp = <R, E>(
186
187
  "*",
187
188
  options?.includePrefix ? `${path}/*` as Router.PathInput : "/*",
188
189
  app,
189
- options?.includePrefix ? Option.none() : Option.some(path)
190
+ options?.includePrefix ? Option.none() : Option.some(path),
191
+ false
190
192
  ),
191
193
  {},
192
194
  {}
@@ -202,50 +204,54 @@ const toHttpApp = <R, E>(
202
204
  router.on(route.method, route.path, route)
203
205
  }
204
206
  })
205
- return Effect.flatMap(
206
- ServerRequest.ServerRequest,
207
- (request): App.Default<R, E | Error.RouteNotFound> => {
208
- if (mountsLen > 0) {
209
- for (let i = 0; i < mountsLen; i++) {
210
- const [path, context, options] = mounts[i]
211
- if (request.url.startsWith(path)) {
212
- return Effect.provideService(
213
- Effect.provideService(
214
- context.route.handler as App.Default<R, E>,
215
- RouteContext,
216
- context
217
- ),
218
- ServerRequest.ServerRequest,
219
- options?.includePrefix ?
220
- request :
221
- sliceRequestUrl(request, path)
222
- )
207
+ return Effect.withFiberRuntime<
208
+ ServerResponse.ServerResponse,
209
+ E | Error.RouteNotFound,
210
+ R | ServerRequest.ServerRequest
211
+ >((fiber) => {
212
+ let context = fiber.getFiberRef(FiberRef.currentContext)
213
+ const request = Context.unsafeGet(context, ServerRequest.ServerRequest)
214
+ if (mountsLen > 0) {
215
+ for (let i = 0; i < mountsLen; i++) {
216
+ const [path, routeContext, options] = mounts[i]
217
+ if (request.url.startsWith(path)) {
218
+ context = Context.add(context, RouteContext, routeContext)
219
+ if (options?.includePrefix !== true) {
220
+ context = Context.add(context, ServerRequest.ServerRequest, sliceRequestUrl(request, path))
223
221
  }
222
+ return Effect.locally(
223
+ routeContext.route.handler as App.Default<R, E>,
224
+ FiberRef.currentContext,
225
+ context
226
+ )
224
227
  }
225
228
  }
229
+ }
226
230
 
227
- let result = router.find(request.method, request.url)
228
- if (result === undefined && request.method === "HEAD") {
229
- result = router.find("GET", request.url)
230
- }
231
- if (result === undefined) {
232
- return Effect.fail(new Error.RouteNotFound({ request }))
233
- }
234
- const route = result.handler
235
- if (route.prefix._tag === "Some") {
236
- request = sliceRequestUrl(request, route.prefix.value)
237
- }
238
- return Effect.mapInputContext(
239
- route.handler as Effect.Effect<ServerResponse.ServerResponse, E, Router.Router.ExcludeProvided<R>>,
240
- (context) =>
241
- Context.add(
242
- Context.add(context, ServerRequest.ServerRequest, request),
243
- RouteContext,
244
- new RouteContextImpl(route, result!.params, result!.searchParams)
245
- ) as Context.Context<R>
246
- )
231
+ let result = router.find(request.method, request.url)
232
+ if (result === undefined && request.method === "HEAD") {
233
+ result = router.find("GET", request.url)
247
234
  }
248
- )
235
+ if (result === undefined) {
236
+ return Effect.fail(new Error.RouteNotFound({ request }))
237
+ }
238
+ const route = result.handler
239
+ if (route.prefix._tag === "Some") {
240
+ context = Context.add(context, ServerRequest.ServerRequest, sliceRequestUrl(request, route.prefix.value))
241
+ }
242
+ context = Context.add(context, RouteContext, new RouteContextImpl(route, result.params, result.searchParams))
243
+ return Effect.locally(
244
+ (route.uninterruptible ?
245
+ route.handler :
246
+ Effect.interruptible(route.handler)) as Effect.Effect<
247
+ ServerResponse.ServerResponse,
248
+ E,
249
+ Router.Router.ExcludeProvided<R>
250
+ >,
251
+ FiberRef.currentContext,
252
+ context
253
+ )
254
+ })
249
255
  }
250
256
 
251
257
  function sliceRequestUrl(request: ServerRequest.ServerRequest, prefix: string) {
@@ -259,7 +265,8 @@ class RouteImpl<R, E> extends Inspectable.Class implements Router.Route<R, E> {
259
265
  readonly method: Method.Method | "*",
260
266
  readonly path: Router.PathInput,
261
267
  readonly handler: Router.Route.Handler<R, E>,
262
- readonly prefix = Option.none<string>()
268
+ readonly prefix = Option.none<string>(),
269
+ readonly uninterruptible = false
263
270
  ) {
264
271
  super()
265
272
  this[RouteTypeId] = RouteTypeId
@@ -301,8 +308,10 @@ export const makeRoute = <R, E>(
301
308
  method: Method.Method,
302
309
  path: Router.PathInput,
303
310
  handler: Router.Route.Handler<R, E>,
304
- prefix: Option.Option<string> = Option.none()
305
- ): Router.Route<Router.Router.ExcludeProvided<R>, E> => new RouteImpl(method, path, handler, prefix) as any
311
+ prefix: Option.Option<string> = Option.none(),
312
+ uninterruptible = false
313
+ ): Router.Route<Router.Router.ExcludeProvided<R>, E> =>
314
+ new RouteImpl(method, path, handler, prefix, uninterruptible) as any
306
315
 
307
316
  /** @internal */
308
317
  export const concat = dual<
@@ -331,7 +340,8 @@ export const prefixAll = dual<
331
340
  Option.orElse(
332
341
  Option.map(route.prefix, (_) => prefix + _),
333
342
  () => Option.some(prefix)
334
- )
343
+ ),
344
+ route.uninterruptible
335
345
  )),
336
346
  Chunk.map(self.mounts, ([path, app]) => [path === "/" ? prefix : prefix + path, app])
337
347
  )
@@ -390,14 +400,20 @@ export const mountApp = dual<
390
400
  export const route = (method: Method.Method | "*"): {
391
401
  <R1, E1>(
392
402
  path: Router.PathInput,
393
- handler: Router.Route.Handler<R1, E1>
403
+ handler: Router.Route.Handler<R1, E1>,
404
+ options?: {
405
+ readonly uninterruptible?: boolean | undefined
406
+ } | undefined
394
407
  ): <R, E>(
395
408
  self: Router.Router<R, E>
396
409
  ) => Router.Router<R | Router.Router.ExcludeProvided<R1>, E1 | E>
397
410
  <R, E, R1, E1>(
398
411
  self: Router.Router<R, E>,
399
412
  path: Router.PathInput,
400
- handler: Router.Route.Handler<R1, E1>
413
+ handler: Router.Route.Handler<R1, E1>,
414
+ options?: {
415
+ readonly uninterruptible?: boolean | undefined
416
+ } | undefined
401
417
  ): Router.Router<R | Router.Router.ExcludeProvided<R1>, E1 | E>
402
418
  } =>
403
419
  dual<
@@ -410,11 +426,14 @@ export const route = (method: Method.Method | "*"): {
410
426
  <R, E, R1, E1>(
411
427
  self: Router.Router<R, E>,
412
428
  path: Router.PathInput,
413
- handler: Router.Route.Handler<R1, E1>
429
+ handler: Router.Route.Handler<R1, E1>,
430
+ options?: {
431
+ readonly uninterruptible?: boolean | undefined
432
+ } | undefined
414
433
  ) => Router.Router<R | Router.Router.ExcludeProvided<R1>, E | E1>
415
- >(3, (self, path, handler) =>
434
+ >((args) => Predicate.hasProperty(args[0], TypeId), (self, path, handler, options) =>
416
435
  new RouterImpl<any, any>(
417
- Chunk.append(self.routes, new RouteImpl(method, path, handler)),
436
+ Chunk.append(self.routes, new RouteImpl(method, path, handler, Option.none(), options?.uninterruptible ?? false)),
418
437
  self.mounts
419
438
  ))
420
439
 
@@ -455,7 +474,7 @@ export const use = dual<
455
474
  new RouterImpl<any, any>(
456
475
  Chunk.map(
457
476
  self.routes,
458
- (route) => new RouteImpl(route.method, route.path, f(route.handler) as any, route.prefix)
477
+ (route) => new RouteImpl(route.method, route.path, f(route.handler) as any, route.prefix, route.uninterruptible)
459
478
  ),
460
479
  Chunk.map(
461
480
  self.mounts,