@effect/platform 0.48.26 → 0.48.28

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 (72) 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 +6 -1
  7. package/dist/cjs/Http/Router.js.map +1 -1
  8. package/dist/cjs/Http/UrlParams.js +1 -1
  9. package/dist/cjs/Http/UrlParams.js.map +1 -1
  10. package/dist/cjs/PlatformConfigProvider.js +3 -3
  11. package/dist/cjs/PlatformConfigProvider.js.map +1 -1
  12. package/dist/cjs/Socket.js +5 -3
  13. package/dist/cjs/Socket.js.map +1 -1
  14. package/dist/cjs/Transferable.js +6 -3
  15. package/dist/cjs/Transferable.js.map +1 -1
  16. package/dist/cjs/WorkerError.js +9 -6
  17. package/dist/cjs/WorkerError.js.map +1 -1
  18. package/dist/cjs/internal/http/middleware.js +14 -16
  19. package/dist/cjs/internal/http/middleware.js.map +1 -1
  20. package/dist/cjs/internal/http/multipart.js +2 -2
  21. package/dist/cjs/internal/http/multipart.js.map +1 -1
  22. package/dist/cjs/internal/http/router.js +17 -6
  23. package/dist/cjs/internal/http/router.js.map +1 -1
  24. package/dist/dts/Http/App.d.ts +5 -7
  25. package/dist/dts/Http/App.d.ts.map +1 -1
  26. package/dist/dts/Http/Headers.d.ts.map +1 -1
  27. package/dist/dts/Http/Router.d.ts +5 -0
  28. package/dist/dts/Http/Router.d.ts.map +1 -1
  29. package/dist/dts/Http/ServerRequest.d.ts +1 -1
  30. package/dist/dts/Http/ServerRequest.d.ts.map +1 -1
  31. package/dist/dts/PlatformConfigProvider.d.ts +2 -2
  32. package/dist/dts/Socket.d.ts +6 -5
  33. package/dist/dts/Socket.d.ts.map +1 -1
  34. package/dist/dts/Transferable.d.ts.map +1 -1
  35. package/dist/dts/WorkerError.d.ts +2 -2
  36. package/dist/dts/WorkerError.d.ts.map +1 -1
  37. package/dist/dts/internal/http/router.d.ts.map +1 -1
  38. package/dist/esm/Http/App.js +48 -30
  39. package/dist/esm/Http/App.js.map +1 -1
  40. package/dist/esm/Http/Headers.js +4 -1
  41. package/dist/esm/Http/Headers.js.map +1 -1
  42. package/dist/esm/Http/Router.js +5 -0
  43. package/dist/esm/Http/Router.js.map +1 -1
  44. package/dist/esm/Http/UrlParams.js +1 -1
  45. package/dist/esm/Http/UrlParams.js.map +1 -1
  46. package/dist/esm/PlatformConfigProvider.js +3 -3
  47. package/dist/esm/PlatformConfigProvider.js.map +1 -1
  48. package/dist/esm/Socket.js +5 -3
  49. package/dist/esm/Socket.js.map +1 -1
  50. package/dist/esm/Transferable.js +6 -3
  51. package/dist/esm/Transferable.js.map +1 -1
  52. package/dist/esm/WorkerError.js +9 -6
  53. package/dist/esm/WorkerError.js.map +1 -1
  54. package/dist/esm/internal/http/middleware.js +14 -16
  55. package/dist/esm/internal/http/middleware.js.map +1 -1
  56. package/dist/esm/internal/http/multipart.js +2 -2
  57. package/dist/esm/internal/http/multipart.js.map +1 -1
  58. package/dist/esm/internal/http/router.js +15 -5
  59. package/dist/esm/internal/http/router.js.map +1 -1
  60. package/package.json +3 -3
  61. package/src/Http/App.ts +71 -46
  62. package/src/Http/Headers.ts +2 -3
  63. package/src/Http/Router.ts +7 -0
  64. package/src/Http/ServerRequest.ts +1 -1
  65. package/src/Http/UrlParams.ts +2 -2
  66. package/src/PlatformConfigProvider.ts +3 -3
  67. package/src/Socket.ts +28 -19
  68. package/src/Transferable.ts +3 -4
  69. package/src/WorkerError.ts +11 -9
  70. package/src/internal/http/middleware.ts +7 -7
  71. package/src/internal/http/multipart.ts +2 -2
  72. package/src/internal/http/router.ts +45 -39
package/src/Socket.ts CHANGED
@@ -47,7 +47,10 @@ export interface Socket {
47
47
  readonly run: <R, E, _>(
48
48
  handler: (_: Uint8Array) => Effect.Effect<_, E, R>
49
49
  ) => Effect.Effect<void, SocketError | E, R>
50
- readonly writer: Effect.Effect<(chunk: Uint8Array | CloseEvent) => Effect.Effect<void>, never, Scope.Scope>
50
+ readonly runRaw: <R, E, _>(
51
+ handler: (_: string | Uint8Array) => Effect.Effect<_, E, R>
52
+ ) => Effect.Effect<void, SocketError | E, R>
53
+ readonly writer: Effect.Effect<(chunk: Uint8Array | string | CloseEvent) => Effect.Effect<void>, never, Scope.Scope>
51
54
  }
52
55
 
53
56
  /**
@@ -165,7 +168,7 @@ export const toChannel = <IE>(
165
168
  self: Socket
166
169
  ): Channel.Channel<
167
170
  Chunk.Chunk<Uint8Array>,
168
- Chunk.Chunk<Uint8Array | CloseEvent>,
171
+ Chunk.Chunk<Uint8Array | string | CloseEvent>,
169
172
  SocketError | IE,
170
173
  IE,
171
174
  void,
@@ -177,7 +180,7 @@ export const toChannel = <IE>(
177
180
  const write = yield* _(Scope.extend(self.writer, writeScope))
178
181
  const exitQueue = yield* _(Queue.unbounded<Exit.Exit<Chunk.Chunk<Uint8Array>, SocketError | IE>>())
179
182
 
180
- const input: AsyncProducer.AsyncInputProducer<IE, Chunk.Chunk<Uint8Array | CloseEvent>, unknown> = {
183
+ const input: AsyncProducer.AsyncInputProducer<IE, Chunk.Chunk<Uint8Array | string | CloseEvent>, unknown> = {
181
184
  awaitRead: () => Effect.unit,
182
185
  emit(chunk) {
183
186
  return Effect.catchAllCause(
@@ -227,7 +230,7 @@ export const toChannelWith = <IE = never>() =>
227
230
  self: Socket
228
231
  ): Channel.Channel<
229
232
  Chunk.Chunk<Uint8Array>,
230
- Chunk.Chunk<Uint8Array | CloseEvent>,
233
+ Chunk.Chunk<Uint8Array | string | CloseEvent>,
231
234
  SocketError | IE,
232
235
  IE,
233
236
  void,
@@ -240,7 +243,7 @@ export const toChannelWith = <IE = never>() =>
240
243
  */
241
244
  export const makeChannel = <IE = never>(): Channel.Channel<
242
245
  Chunk.Chunk<Uint8Array>,
243
- Chunk.Chunk<Uint8Array | CloseEvent>,
246
+ Chunk.Chunk<Uint8Array | string | CloseEvent>,
244
247
  SocketError | IE,
245
248
  IE,
246
249
  void,
@@ -303,12 +306,11 @@ export const fromWebSocket = (
303
306
  ): Effect.Effect<Socket> =>
304
307
  Effect.gen(function*(_) {
305
308
  const closeCodeIsError = options?.closeCodeIsError ?? defaultCloseCodeIsError
306
- const sendQueue = yield* _(Queue.unbounded<Uint8Array | CloseEvent>())
309
+ const sendQueue = yield* _(Queue.unbounded<Uint8Array | string | CloseEvent>())
307
310
 
308
- const run = <R, E, _>(handler: (_: Uint8Array) => Effect.Effect<_, E, R>) =>
311
+ const runRaw = <R, E, _>(handler: (_: string | Uint8Array) => Effect.Effect<_, E, R>) =>
309
312
  Effect.gen(function*(_) {
310
313
  const ws = yield* _(acquire)
311
- const encoder = new TextEncoder()
312
314
  const fiberSet = yield* _(FiberSet.make<any, E | SocketError>())
313
315
  const run = yield* _(
314
316
  FiberSet.runtime(fiberSet)<R>(),
@@ -317,15 +319,13 @@ export const fromWebSocket = (
317
319
  let open = false
318
320
 
319
321
  ws.onmessage = (event) => {
320
- run(
321
- handler(
322
- event.data instanceof Uint8Array
323
- ? event.data
324
- : typeof event.data === "string"
325
- ? encoder.encode(event.data)
326
- : new Uint8Array(event.data)
327
- )
328
- )
322
+ run(handler(
323
+ typeof event.data === "string"
324
+ ? event.data
325
+ : event.data instanceof Uint8Array
326
+ ? event.data
327
+ : new Uint8Array(event.data)
328
+ ))
329
329
  }
330
330
  ws.onclose = (event) => {
331
331
  Deferred.unsafeDone(
@@ -396,12 +396,21 @@ export const fromWebSocket = (
396
396
  Effect.interruptible
397
397
  )
398
398
 
399
- const write = (chunk: Uint8Array | CloseEvent) => Queue.offer(sendQueue, chunk)
399
+ const encoder = new TextEncoder()
400
+ const run = <R, E, _>(handler: (_: Uint8Array) => Effect.Effect<_, E, R>) =>
401
+ runRaw((data) =>
402
+ typeof data === "string"
403
+ ? handler(encoder.encode(data))
404
+ : handler(data)
405
+ )
406
+
407
+ const write = (chunk: Uint8Array | string | CloseEvent) => Queue.offer(sendQueue, chunk)
400
408
  const writer = Effect.succeed(write)
401
409
 
402
410
  return Socket.of({
403
411
  [TypeId]: TypeId,
404
412
  run,
413
+ runRaw,
405
414
  writer
406
415
  })
407
416
  })
@@ -417,7 +426,7 @@ export const makeWebSocketChannel = <IE = never>(
417
426
  }
418
427
  ): Channel.Channel<
419
428
  Chunk.Chunk<Uint8Array>,
420
- Chunk.Chunk<Uint8Array | CloseEvent>,
429
+ Chunk.Chunk<Uint8Array | string | CloseEvent>,
421
430
  SocketError | IE,
422
431
  IE,
423
432
  void,
@@ -93,8 +93,7 @@ export const schema: {
93
93
  Schema.transformOrFail(
94
94
  Schema.encodedSchema(self),
95
95
  self,
96
- ParseResult.succeed,
97
- (i) => Effect.as(addAll(f(i)), i)
96
+ { decode: ParseResult.succeed, encode: (i) => Effect.as(addAll(f(i)), i) }
98
97
  ))
99
98
 
100
99
  /**
@@ -102,7 +101,7 @@ export const schema: {
102
101
  * @category schema
103
102
  */
104
103
  export const ImageData: Schema.Schema<ImageData> = schema(
105
- Schema.any,
104
+ Schema.Any,
106
105
  (_) => [(_ as ImageData).data.buffer]
107
106
  )
108
107
 
@@ -111,7 +110,7 @@ export const ImageData: Schema.Schema<ImageData> = schema(
111
110
  * @category schema
112
111
  */
113
112
  export const MessagePort: Schema.Schema<MessagePort> = schema(
114
- Schema.any,
113
+ Schema.Any,
115
114
  (_) => [_ as MessagePort]
116
115
  )
117
116
 
@@ -26,14 +26,16 @@ export type WorkerErrorTypeId = typeof WorkerErrorTypeId
26
26
  export const isWorkerError = (u: unknown): u is WorkerError => Predicate.hasProperty(u, WorkerErrorTypeId)
27
27
 
28
28
  const causeDefectPretty: Schema.Schema<unknown> = Schema.transform(
29
- Schema.unknown,
30
- Schema.unknown,
31
- identity,
32
- (defect) => {
33
- if (Predicate.isObject(defect)) {
34
- return Cause.pretty(Cause.die(defect))
29
+ Schema.Unknown,
30
+ Schema.Unknown,
31
+ {
32
+ decode: identity,
33
+ encode: (defect) => {
34
+ if (Predicate.isObject(defect)) {
35
+ return Cause.pretty(Cause.die(defect))
36
+ }
37
+ return String(defect)
35
38
  }
36
- return String(defect)
37
39
  }
38
40
  )
39
41
 
@@ -42,7 +44,7 @@ const causeDefectPretty: Schema.Schema<unknown> = Schema.transform(
42
44
  * @category errors
43
45
  */
44
46
  export class WorkerError extends Schema.TaggedError<WorkerError>()("WorkerError", {
45
- reason: Schema.literal("spawn", "decode", "send", "unknown", "encode"),
47
+ reason: Schema.Literal("spawn", "decode", "send", "unknown", "encode"),
46
48
  error: causeDefectPretty
47
49
  }) {
48
50
  /**
@@ -56,7 +58,7 @@ export class WorkerError extends Schema.TaggedError<WorkerError>()("WorkerError"
56
58
  static readonly Cause: Schema.Schema<
57
59
  Cause.Cause<WorkerError>,
58
60
  Schema.CauseEncoded<WorkerErrorFrom>
59
- > = Schema.cause({ defect: causeDefectPretty, error: this })
61
+ > = Schema.Cause({ defect: causeDefectPretty, error: this })
60
62
 
61
63
  /**
62
64
  * @since 1.0.0
@@ -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"
@@ -202,50 +203,48 @@ const toHttpApp = <R, E>(
202
203
  router.on(route.method, route.path, route)
203
204
  }
204
205
  })
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
- )
206
+ return Effect.withFiberRuntime<
207
+ ServerResponse.ServerResponse,
208
+ E | Error.RouteNotFound,
209
+ R | ServerRequest.ServerRequest
210
+ >((fiber) => {
211
+ let context = fiber.getFiberRef(FiberRef.currentContext)
212
+ const request = Context.unsafeGet(context, ServerRequest.ServerRequest)
213
+ if (mountsLen > 0) {
214
+ for (let i = 0; i < mountsLen; i++) {
215
+ const [path, routeContext, options] = mounts[i]
216
+ if (request.url.startsWith(path)) {
217
+ context = Context.add(context, RouteContext, routeContext)
218
+ if (options?.includePrefix !== true) {
219
+ context = Context.add(context, ServerRequest.ServerRequest, sliceRequestUrl(request, path))
223
220
  }
221
+ return Effect.locally(
222
+ routeContext.route.handler as App.Default<R, E>,
223
+ FiberRef.currentContext,
224
+ context
225
+ )
224
226
  }
225
227
  }
228
+ }
226
229
 
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
- )
230
+ let result = router.find(request.method, request.url)
231
+ if (result === undefined && request.method === "HEAD") {
232
+ result = router.find("GET", request.url)
247
233
  }
248
- )
234
+ if (result === undefined) {
235
+ return Effect.fail(new Error.RouteNotFound({ request }))
236
+ }
237
+ const route = result.handler
238
+ if (route.prefix._tag === "Some") {
239
+ context = Context.add(context, ServerRequest.ServerRequest, sliceRequestUrl(request, route.prefix.value))
240
+ }
241
+ context = Context.add(context, RouteContext, new RouteContextImpl(route, result.params, result.searchParams))
242
+ return Effect.locally(
243
+ route.handler as Effect.Effect<ServerResponse.ServerResponse, E, Router.Router.ExcludeProvided<R>>,
244
+ FiberRef.currentContext,
245
+ context
246
+ )
247
+ })
249
248
  }
250
249
 
251
250
  function sliceRequestUrl(request: ServerRequest.ServerRequest, prefix: string) {
@@ -600,3 +599,10 @@ export const provideServiceEffect = dual<
600
599
  >,
601
600
  E | E1
602
601
  > => use(self, Effect.provideServiceEffect(tag, effect)) as any)
602
+
603
+ /* @internal */
604
+ export const uninterruptible = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
605
+ Effect.uninterruptible(Effect.flatMap(
606
+ effect,
607
+ Effect.die
608
+ ))