effect-app 3.15.1 → 4.0.0-beta.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 (174) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/Array.js +1 -1
  3. package/dist/Chunk.d.ts +2 -4
  4. package/dist/Chunk.d.ts.map +1 -1
  5. package/dist/Chunk.js +2 -2
  6. package/dist/Config/SecretURL.d.ts +2 -12
  7. package/dist/Config/SecretURL.d.ts.map +1 -1
  8. package/dist/Config/SecretURL.js +2 -4
  9. package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
  10. package/dist/Config/internal/configSecretURL.js +3 -4
  11. package/dist/Effect.d.ts +12 -10
  12. package/dist/Effect.d.ts.map +1 -1
  13. package/dist/Effect.js +6 -15
  14. package/dist/Layer.d.ts +15 -9
  15. package/dist/Layer.d.ts.map +1 -1
  16. package/dist/Layer.js +2 -2
  17. package/dist/Operations.d.ts +37 -47
  18. package/dist/Operations.d.ts.map +1 -1
  19. package/dist/Option.js +3 -3
  20. package/dist/Pure.d.ts +17 -6
  21. package/dist/Pure.d.ts.map +1 -1
  22. package/dist/Pure.js +35 -17
  23. package/dist/Schema/Class.d.ts +13 -16
  24. package/dist/Schema/Class.d.ts.map +1 -1
  25. package/dist/Schema/Class.js +5 -27
  26. package/dist/Schema/brand.d.ts +7 -10
  27. package/dist/Schema/brand.d.ts.map +1 -1
  28. package/dist/Schema/brand.js +3 -2
  29. package/dist/Schema/email.d.ts +1 -1
  30. package/dist/Schema/email.d.ts.map +1 -1
  31. package/dist/Schema/email.js +2 -2
  32. package/dist/Schema/ext.d.ts +42 -45
  33. package/dist/Schema/ext.d.ts.map +1 -1
  34. package/dist/Schema/ext.js +49 -63
  35. package/dist/Schema/moreStrings.d.ts +17 -17
  36. package/dist/Schema/moreStrings.d.ts.map +1 -1
  37. package/dist/Schema/moreStrings.js +10 -10
  38. package/dist/Schema/numbers.d.ts +14 -14
  39. package/dist/Schema/numbers.js +5 -5
  40. package/dist/Schema/phoneNumber.d.ts +1 -1
  41. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  42. package/dist/Schema/phoneNumber.js +2 -2
  43. package/dist/Schema/schema.d.ts +2 -3
  44. package/dist/Schema/schema.d.ts.map +1 -1
  45. package/dist/Schema/schema.js +3 -4
  46. package/dist/Schema/strings.d.ts +4 -4
  47. package/dist/Schema/strings.d.ts.map +1 -1
  48. package/dist/Schema/strings.js +4 -4
  49. package/dist/Schema.d.ts +27 -25
  50. package/dist/Schema.d.ts.map +1 -1
  51. package/dist/Schema.js +22 -21
  52. package/dist/ServiceMap.d.ts +44 -0
  53. package/dist/ServiceMap.d.ts.map +1 -0
  54. package/dist/ServiceMap.js +91 -0
  55. package/dist/Set.d.ts +4 -4
  56. package/dist/Set.d.ts.map +1 -1
  57. package/dist/Set.js +14 -14
  58. package/dist/Struct.d.ts +4 -4
  59. package/dist/Struct.d.ts.map +1 -1
  60. package/dist/_ext/Array.d.ts.map +1 -1
  61. package/dist/_ext/Array.js +4 -4
  62. package/dist/_ext/misc.d.ts +2 -2
  63. package/dist/_ext/misc.js +4 -4
  64. package/dist/_ext/ord.ext.js +2 -2
  65. package/dist/builtin.d.ts +0 -8
  66. package/dist/builtin.d.ts.map +1 -1
  67. package/dist/builtin.js +3 -1
  68. package/dist/client/apiClientFactory.d.ts +14 -16
  69. package/dist/client/apiClientFactory.d.ts.map +1 -1
  70. package/dist/client/apiClientFactory.js +38 -23
  71. package/dist/client/clientFor.d.ts +7 -4
  72. package/dist/client/clientFor.d.ts.map +1 -1
  73. package/dist/client/errors.d.ts +36 -48
  74. package/dist/client/errors.d.ts.map +1 -1
  75. package/dist/client/errors.js +19 -9
  76. package/dist/client/makeClient.d.ts +34 -50
  77. package/dist/client/makeClient.d.ts.map +1 -1
  78. package/dist/client/makeClient.js +28 -18
  79. package/dist/http/Request.d.ts +3 -3
  80. package/dist/http/Request.d.ts.map +1 -1
  81. package/dist/http/Request.js +5 -8
  82. package/dist/http/internal/lib.d.ts +12 -13
  83. package/dist/http/internal/lib.d.ts.map +1 -1
  84. package/dist/http/internal/lib.js +14 -14
  85. package/dist/ids.d.ts +9 -9
  86. package/dist/ids.d.ts.map +1 -1
  87. package/dist/ids.js +1 -1
  88. package/dist/index.d.ts +7 -1
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +8 -2
  91. package/dist/logger.d.ts +1 -1
  92. package/dist/middleware.d.ts +2 -2
  93. package/dist/middleware.d.ts.map +1 -1
  94. package/dist/middleware.js +3 -3
  95. package/dist/rpc/MiddlewareMaker.d.ts +17 -16
  96. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  97. package/dist/rpc/MiddlewareMaker.js +27 -18
  98. package/dist/rpc/RpcContextMap.d.ts +4 -4
  99. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  100. package/dist/rpc/RpcContextMap.js +4 -4
  101. package/dist/rpc/RpcMiddleware.d.ts +24 -40
  102. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  103. package/dist/rpc/RpcMiddleware.js +3 -10
  104. package/dist/utils/effectify.js +2 -2
  105. package/dist/utils/gen.d.ts +4 -5
  106. package/dist/utils/gen.d.ts.map +1 -1
  107. package/dist/utils/logLevel.d.ts +1 -1
  108. package/dist/utils/logLevel.d.ts.map +1 -1
  109. package/dist/utils/logLevel.js +6 -7
  110. package/dist/utils/logger.d.ts +4 -3
  111. package/dist/utils/logger.d.ts.map +1 -1
  112. package/dist/utils/logger.js +10 -9
  113. package/dist/utils.d.ts +4 -5
  114. package/dist/utils.d.ts.map +1 -1
  115. package/dist/utils.js +10 -9
  116. package/package.json +16 -25
  117. package/src/Array.ts +1 -1
  118. package/src/Chunk.ts +2 -2
  119. package/src/Config/SecretURL.ts +3 -18
  120. package/src/Config/internal/configSecretURL.ts +2 -3
  121. package/src/Effect.ts +17 -37
  122. package/src/Layer.ts +16 -11
  123. package/src/Option.ts +2 -2
  124. package/src/Pure.ts +60 -26
  125. package/src/Schema/Class.ts +17 -73
  126. package/src/Schema/brand.ts +11 -12
  127. package/src/Schema/email.ts +2 -2
  128. package/src/Schema/ext.ts +114 -167
  129. package/src/Schema/moreStrings.ts +20 -23
  130. package/src/Schema/numbers.ts +4 -4
  131. package/src/Schema/phoneNumber.ts +2 -2
  132. package/src/Schema/schema.ts +2 -3
  133. package/src/Schema/strings.ts +3 -3
  134. package/src/Schema.ts +49 -47
  135. package/src/ServiceMap.ts +187 -0
  136. package/src/Set.ts +19 -19
  137. package/src/Struct.ts +4 -4
  138. package/src/_ext/Array.ts +4 -5
  139. package/src/_ext/misc.ts +4 -4
  140. package/src/_ext/ord.ext.ts +2 -2
  141. package/src/builtin.ts +2 -8
  142. package/src/client/apiClientFactory.ts +74 -59
  143. package/src/client/clientFor.ts +10 -7
  144. package/src/client/errors.ts +28 -22
  145. package/src/client/makeClient.ts +75 -100
  146. package/src/http/Request.ts +5 -8
  147. package/src/http/internal/lib.ts +13 -13
  148. package/src/ids.ts +1 -1
  149. package/src/index.ts +10 -1
  150. package/src/middleware.ts +2 -2
  151. package/src/rpc/MiddlewareMaker.ts +76 -47
  152. package/src/rpc/RpcContextMap.ts +7 -7
  153. package/src/rpc/RpcMiddleware.ts +28 -54
  154. package/src/utils/effectify.ts +1 -1
  155. package/src/utils/gen.ts +8 -6
  156. package/src/utils/logLevel.ts +6 -6
  157. package/src/utils/logger.ts +15 -20
  158. package/src/utils.ts +12 -12
  159. package/test/dist/rpc.test.d.ts.map +1 -1
  160. package/test/schema.test.ts +8 -8
  161. package/test/utils.test.ts +2 -2
  162. package/tsconfig.json +1 -25
  163. package/dist/Context.d.ts +0 -67
  164. package/dist/Context.d.ts.map +0 -1
  165. package/dist/Context.js +0 -207
  166. package/dist/Tag.d.ts +0 -6
  167. package/dist/Tag.d.ts.map +0 -1
  168. package/dist/Tag.js +0 -9
  169. package/dist/Unify.d.ts +0 -27
  170. package/dist/Unify.d.ts.map +0 -1
  171. package/dist/Unify.js +0 -15
  172. package/src/Context.ts +0 -351
  173. package/src/Tag.ts +0 -11
  174. package/src/Unify.ts +0 -40
@@ -1,6 +1,5 @@
1
- import type { HttpClientResponse } from "@effect/platform/HttpClientResponse"
1
+ import type { HttpClientResponse } from "effect/unstable/http/HttpClientResponse"
2
2
  import * as Effect from "../Effect.js"
3
- import * as Option from "../Option.js"
4
3
  import { HttpClient, HttpClientError, HttpClientRequest, HttpHeaders } from "./internal/lib.js"
5
4
 
6
5
  export interface ResponseWithBody<A> extends Pick<HttpClientResponse, "headers" | "status" | "remoteAddress"> {
@@ -25,18 +24,16 @@ export const demandJson = (client: HttpClient.HttpClient) =>
25
24
  .mapRequest(client, (_) => HttpClientRequest.acceptJson(_))
26
25
  .pipe(HttpClient.transform((r, request) =>
27
26
  Effect.tap(r, (response) =>
28
- Option
29
- .getOrUndefined(HttpHeaders
30
- .get(response.headers, "Content-Type"))
27
+ HttpHeaders
28
+ .get(response.headers, "Content-Type")
31
29
  ?.startsWith("application/json")
32
30
  ? Effect.void
33
31
  : Effect.fail(
34
- new HttpClientError.ResponseError({
32
+ new HttpClientError.DecodeError({
35
33
  request,
36
34
  response,
37
- reason: "Decode",
38
35
  description: "not json response: "
39
- + Option.getOrUndefined(HttpHeaders.get(response.headers, "Content-Type"))
36
+ + HttpHeaders.get(response.headers, "Content-Type")
40
37
  })
41
38
  ))
42
39
  ))
@@ -1,13 +1,13 @@
1
- export * as HttpHeaders from "@effect/platform/Headers"
2
- export * as HttpBody from "@effect/platform/HttpBody"
3
- export * as HttpClient from "@effect/platform/HttpClient"
4
- export * as HttpClientError from "@effect/platform/HttpClientError"
5
- export * as HttpClientRequest from "@effect/platform/HttpClientRequest"
6
- export * as HttpClientResponse from "@effect/platform/HttpClientResponse"
7
- export * as HttpLayerRouter from "@effect/platform/HttpLayerRouter"
8
- export * as HttpMiddleware from "@effect/platform/HttpMiddleware"
9
- export * as HttpRouter from "@effect/platform/HttpRouter"
10
- export * as HttpServer from "@effect/platform/HttpServer"
11
- export * as HttpServerError from "@effect/platform/HttpServerError"
12
- export * as HttpServerRequest from "@effect/platform/HttpServerRequest"
13
- export * as HttpServerResponse from "@effect/platform/HttpServerResponse"
1
+ export * as HttpHeaders from "effect/unstable/http/Headers"
2
+ export * as HttpBody from "effect/unstable/http/HttpBody"
3
+ export * as HttpClient from "effect/unstable/http/HttpClient"
4
+ export * as HttpClientError from "effect/unstable/http/HttpClientError"
5
+ export * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
6
+ export * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
7
+ // HttpLayerRouter removed in v4 — use HttpRouter instead
8
+ export * as HttpMiddleware from "effect/unstable/http/HttpMiddleware"
9
+ export * as HttpRouter from "effect/unstable/http/HttpRouter"
10
+ export * as HttpServer from "effect/unstable/http/HttpServer"
11
+ export * as HttpServerError from "effect/unstable/http/HttpServerError"
12
+ export * as HttpServerRequest from "effect/unstable/http/HttpServerRequest"
13
+ export * as HttpServerResponse from "effect/unstable/http/HttpServerResponse"
package/src/ids.ts CHANGED
@@ -12,7 +12,7 @@ export type RequestId = NonEmptyString255
12
12
  // a request id may be made from a span id, which does not comply with StringId schema.
13
13
  export const RequestId = extendM(
14
14
  Object
15
- .assign(Object.create(NonEmptyString255) as {}, NonEmptyString255 as Schema<NonEmptyString255, string>),
15
+ .assign(Object.create(NonEmptyString255) as {}, NonEmptyString255 as unknown as Schema<NonEmptyString255>),
16
16
  (s) => {
17
17
  const make = StringId.make as () => NonEmptyString255
18
18
  return ({
package/src/index.ts CHANGED
@@ -1,15 +1,24 @@
1
1
  import "./builtin.js"
2
2
 
3
+ import * as ServiceMap from "./ServiceMap.js"
4
+
3
5
  export * as Fnc from "./Function.js"
4
6
  export * as Utils from "./utils.js"
5
7
 
6
8
  export * as Array from "./Array.js"
7
- export * as Context from "./Context.js"
8
9
  export * as Effect from "./Effect.js"
9
10
  export * as Layer from "./Layer.js"
10
11
  export * as NonEmptySet from "./NonEmptySet.js"
12
+ export * as ServiceMap from "./ServiceMap.js"
11
13
  export * as Set from "./Set.js"
12
14
 
15
+ export {
16
+ /**
17
+ * @deprecated use ServiceMap directly instead
18
+ */
19
+ ServiceMap as Context
20
+ }
21
+
13
22
  export { type NonEmptyArray, type NonEmptyReadonlyArray } from "./Array.js"
14
23
 
15
24
  export * from "effect"
package/src/middleware.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Context } from "effect-app"
2
+ import { ServiceMap } from "effect-app"
3
3
  import { RpcX } from "./rpc.js"
4
4
 
5
- export class DevMode extends Context.Reference<DevMode>()("DevMode", { defaultValue: () => false }) {}
5
+ export class DevMode extends ServiceMap.Reference("DevMode", { defaultValue: () => false }) {}
6
6
 
7
7
  export class RequestCacheMiddleware
8
8
  extends RpcX.RpcMiddleware.Tag<RequestCacheMiddleware>()("RequestCacheMiddleware")
@@ -1,9 +1,11 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Rpc, type RpcGroup, type RpcMiddleware, type RpcSchema } from "@effect/rpc"
3
- import { type HandlersFrom } from "@effect/rpc/RpcGroup"
4
- import { Context, Effect, Layer, type Schema, Schema as S, type Scope } from "effect"
2
+ import { Effect, Layer, type Schema, Schema as S, type Scope, ServiceMap } from "effect"
5
3
  import { type NonEmptyArray, type NonEmptyReadonlyArray } from "effect/Array"
6
4
  import { type Simplify } from "effect/Types"
5
+ import { Rpc, type RpcGroup, type RpcSchema } from "effect/unstable/rpc"
6
+ import { type HandlersFrom } from "effect/unstable/rpc/RpcGroup"
7
+ import { type RequestId } from "effect/unstable/rpc/RpcMessage"
8
+ import { type HttpHeaders } from "../http.js"
7
9
  import { PreludeLogger } from "../logger.js"
8
10
  import { type TypeTestId } from "../TypeTest.js"
9
11
  import { typedValuesOf } from "../utils.js"
@@ -11,8 +13,8 @@ import { type GetContextConfig, type RequestContextMapTagAny, type RpcContextMap
11
13
  import { type AddMiddleware, type AnyDynamic, type RpcDynamic, type RpcMiddlewareV4, type TagClassAny } from "./RpcMiddleware.js"
12
14
  import * as RpcMiddlewareX from "./RpcMiddleware.js"
13
15
 
14
- // adapter for effect/rpc v3 middleware provides. (in effect-smol (v4), it's wrap only, and just a Service Identifier, no tags.)
15
- type MakeTags<A> = Context.Tag<A, A>
16
+ // adapter for effect/rpc v3 middleware provides. (in effect-smol (v4), it's just a Service Identifier, no tags.)
17
+ type MakeTags<A> = ServiceMap.Service<A, A>
16
18
 
17
19
  export interface MiddlewareMaker<
18
20
  Self,
@@ -20,11 +22,10 @@ export interface MiddlewareMaker<
20
22
  RequestContextMap extends Record<string, RpcContextMap.Any>,
21
23
  MiddlewareProviders extends ReadonlyArray<MiddlewareMaker.Any>
22
24
  > extends
23
- RpcMiddleware.TagClass<
25
+ RpcMiddlewareX.TagClass<
24
26
  Self,
25
27
  Id,
26
28
  Simplify<
27
- & { readonly wrap: true }
28
29
  & (Exclude<
29
30
  MiddlewareMaker.ManyRequired<MiddlewareProviders>,
30
31
  MiddlewareMaker.ManyProvided<MiddlewareProviders>
@@ -38,20 +39,34 @@ export interface MiddlewareMaker<
38
39
  })
39
40
  & (MiddlewareMaker.ManyErrors<MiddlewareProviders> extends never ? {}
40
41
  : {
41
- readonly failure: S.Schema<MiddlewareMaker.ManyErrors<MiddlewareProviders>>
42
+ readonly error: S.Schema<MiddlewareMaker.ManyErrors<MiddlewareProviders>>
42
43
  })
43
44
  & (MiddlewareMaker.ManyProvided<MiddlewareProviders> extends never ? {}
44
45
  : { readonly provides: MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>> })
45
- >
46
+ >,
47
+ {
48
+ provides: MiddlewareMaker.ManyProvided<MiddlewareProviders> extends never ? never
49
+ : MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>>
50
+ requires: Exclude<
51
+ MiddlewareMaker.ManyRequired<MiddlewareProviders>,
52
+ MiddlewareMaker.ManyProvided<MiddlewareProviders>
53
+ > extends never ? never
54
+ : MakeTags<
55
+ Exclude<
56
+ MiddlewareMaker.ManyRequired<MiddlewareProviders>,
57
+ MiddlewareMaker.ManyProvided<MiddlewareProviders>
58
+ >
59
+ >
60
+ }
46
61
  >
47
62
  {
48
- readonly layer: Layer.Layer<Self, never, Context.Tag.Identifier<MiddlewareProviders[number]>>
63
+ readonly layer: Layer.Layer<Self, never, ServiceMap.Service.Identifier<MiddlewareProviders[number]>>
49
64
  readonly requestContext: RequestContextTag<RequestContextMap>
50
65
  readonly requestContextMap: RequestContextMap
51
66
  }
52
67
 
53
68
  export interface RequestContextTag<RequestContextMap extends Record<string, RpcContextMap.Any>>
54
- extends Context.Tag<"RequestContextConfig", GetContextConfig<RequestContextMap>>
69
+ extends ServiceMap.Service<"RequestContextConfig", GetContextConfig<RequestContextMap>>
55
70
  {}
56
71
 
57
72
  export namespace MiddlewareMaker {
@@ -77,7 +92,7 @@ export namespace MiddlewareMaker {
77
92
  : never
78
93
  : never
79
94
 
80
- export type Errors<T> = T extends TagClassAny ? T extends { failure: S.Schema.Any } ? S.Schema.Type<T["failure"]>
95
+ export type Errors<T> = T extends TagClassAny ? T extends { error: S.Top } ? S.Schema.Type<T["error"]>
81
96
  : never
82
97
  : never
83
98
 
@@ -153,9 +168,9 @@ export interface BuildingMiddleware<
153
168
  > {
154
169
  rpc: <
155
170
  const Tag extends string,
156
- Payload extends Schema.Schema.Any | Schema.Struct.Fields = typeof Schema.Void,
157
- Success extends Schema.Schema.Any = typeof Schema.Void,
158
- Error extends Schema.Schema.All = typeof Schema.Never,
171
+ Payload extends Schema.Top | Schema.Struct.Fields = typeof Schema.Void,
172
+ Success extends Schema.Top = typeof Schema.Void,
173
+ Error extends Schema.Top = typeof Schema.Never,
159
174
  const Stream extends boolean = false,
160
175
  Config extends GetContextConfig<RequestContextMap> = {}
161
176
  >(tag: Tag, options?: {
@@ -164,8 +179,9 @@ export interface BuildingMiddleware<
164
179
  readonly error?: Error
165
180
  readonly stream?: Stream
166
181
  readonly config?: Config
167
- readonly primaryKey?: [Payload] extends [Schema.Struct.Fields]
168
- ? ((payload: Schema.Simplify<Schema.Struct.Type<NoInfer<Payload>>>) => string)
182
+ readonly primaryKey?: [Payload] extends [Schema.Struct.Fields] ? ((
183
+ payload: Payload extends Schema.Struct.Fields ? Simplify<Schema.Struct<Payload>["Type"]> : Payload["Type"]
184
+ ) => string)
169
185
  : never
170
186
  }) =>
171
187
  & Rpc.Rpc<
@@ -258,29 +274,31 @@ const middlewareMaker = <
258
274
  middlewares = middlewares.toReversed() as any
259
275
 
260
276
  return Effect.gen(function*() {
261
- const context = yield* Effect.context()
277
+ const context = yield* Effect.services()
262
278
 
263
279
  // returns a Effect/RpcMiddlewareV4 with Scope.Scope in requirements
280
+ // v4: wrap middleware takes (effect, options) as two params instead of a single options bag
264
281
  return (
265
- _options: Parameters<
266
- RpcMiddleware.RpcMiddlewareWrap<
267
- MiddlewareMaker.ManyProvided<MiddlewareProviders>,
268
- never
269
- >
270
- >[0]
282
+ next: Effect.Effect<any, any, any>,
283
+ options: {
284
+ readonly clientId: number
285
+ readonly requestId: RequestId
286
+ readonly rpc: Rpc.AnyWithProps
287
+ readonly payload: unknown
288
+ readonly headers: HttpHeaders.Headers
289
+ }
271
290
  ) => {
272
- const { next, ...options } = _options
273
291
  // we start with the actual handler
274
292
  let handler = next
275
293
 
276
294
  // inspired from Effect/RpcMiddleware
277
295
  for (const tag of middlewares) {
278
296
  // use the tag to get the middleware from context
279
- const middleware = Context.unsafeGet(context, tag)
297
+ const middleware = ServiceMap.getUnsafe(context, tag)
280
298
 
281
299
  // wrap the current handler, allowing the middleware to run before and after it
282
300
  handler = PreludeLogger.logDebug("Applying middleware wrap " + tag.key).pipe(
283
- Effect.zipRight(middleware(handler, options))
301
+ Effect.andThen(middleware(handler, options))
284
302
  ) as any
285
303
  }
286
304
  return handler
@@ -302,15 +320,17 @@ const makeMiddlewareBasic = <Self>() =>
302
320
  // reverse middlewares and wrap one after the other
303
321
  const middleware = middlewareMaker(make)
304
322
 
305
- const failures = make.map((_) => _.failure).filter(Boolean)
323
+ const failures = make.map((_) => _.error).filter(Boolean)
306
324
  const provides = make.flatMap((_) => !_.provides ? [] : Array.isArray(_.provides) ? _.provides : [_.provides])
307
325
  const requires = make
308
326
  .flatMap((_) => !_.requires ? [] : Array.isArray(_.requires) ? _.requires : [_.requires])
309
327
  .filter((_) => !provides.includes(_))
310
328
 
329
+ const [firstFailure, ...restFailures] = failures
330
+
311
331
  const MiddlewareMaker = RpcMiddlewareX.Tag<Self>()(id, {
312
- failure: (failures.length > 0
313
- ? S.Union(...failures)
332
+ error: (firstFailure
333
+ ? S.Union([firstFailure, ...restFailures])
314
334
  : S.Never) as unknown as MiddlewareMaker.ManyErrors<MiddlewareProviders> extends never ? never
315
335
  : S.Schema<MiddlewareMaker.ManyErrors<MiddlewareProviders>>,
316
336
  requires: (requires.length > 0
@@ -329,17 +349,16 @@ const makeMiddlewareBasic = <Self>() =>
329
349
  provides: (provides.length > 0
330
350
  ? provides
331
351
  : undefined) as unknown as MiddlewareMaker.ManyProvided<MiddlewareProviders> extends never ? never
332
- : MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>>,
333
- wrap: true
352
+ : MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>>
334
353
  })
335
354
 
336
355
  const layer = Layer
337
- .scoped(
356
+ .effect(
338
357
  MiddlewareMaker,
339
358
  middleware as Effect.Effect<
340
- any, // TODO: why ?
341
- Effect.Effect.Error<typeof middleware>,
342
- Effect.Effect.Context<typeof middleware>
359
+ any,
360
+ Effect.Error<typeof middleware>,
361
+ Effect.Services<typeof middleware>
343
362
  >
344
363
  )
345
364
 
@@ -347,7 +366,7 @@ const makeMiddlewareBasic = <Self>() =>
347
366
  return Object.assign(MiddlewareMaker, {
348
367
  layer,
349
368
  // tag to be used to retrieve the RequestContextConfig from Rpc annotations
350
- requestContext: Context.GenericTag<"RequestContextConfig", GetContextConfig<RequestContextMap>>(
369
+ requestContext: ServiceMap.Service<"RequestContextConfig", GetContextConfig<RequestContextMap>>(
351
370
  "RequestContextConfig"
352
371
  ),
353
372
  requestContextMap: rcm
@@ -360,7 +379,7 @@ export const Tag = <Self>() =>
360
379
  RequestContextMap extends RequestContextMapTagAny
361
380
  >(id: Id, rcm: RequestContextMap): MiddlewaresBuilder<Self, Id, RequestContextMap["config"]> => {
362
381
  let allMiddleware: MiddlewareMaker.Any[] = []
363
- const requestContext = Context.GenericTag<"RequestContextConfig", GetContextConfig<RequestContextMap["config"]>>(
382
+ const requestContext = ServiceMap.Service<"RequestContextConfig", GetContextConfig<RequestContextMap["config"]>>(
364
383
  "RequestContextConfig"
365
384
  )
366
385
  const it = {
@@ -368,9 +387,9 @@ export const Tag = <Self>() =>
368
387
  // rpc with config
369
388
  rpc: <
370
389
  const Tag extends string,
371
- Payload extends Schema.Schema.Any | Schema.Struct.Fields = typeof Schema.Void,
372
- Success extends Schema.Schema.Any = typeof Schema.Void,
373
- Error extends Schema.Schema.All = typeof Schema.Never,
390
+ Payload extends Schema.Top | Schema.Struct.Fields = typeof Schema.Void,
391
+ Success extends Schema.Top = typeof Schema.Void,
392
+ Error extends Schema.Top = typeof Schema.Never,
374
393
  const Stream extends boolean = false,
375
394
  Config extends GetContextConfig<RequestContextMap["config"]> = {}
376
395
  >(tag: Tag, options?: {
@@ -379,8 +398,9 @@ export const Tag = <Self>() =>
379
398
  readonly error?: Error
380
399
  readonly stream?: Stream
381
400
  readonly config?: Config
382
- readonly primaryKey?: [Payload] extends [Schema.Struct.Fields]
383
- ? ((payload: Schema.Simplify<Schema.Struct.Type<NoInfer<Payload>>>) => string)
401
+ readonly primaryKey?: [Payload] extends [Schema.Struct.Fields] ? ((
402
+ payload: Payload extends Schema.Struct.Fields ? Simplify<Schema.Struct<Payload>["Type"]> : Payload["Type"]
403
+ ) => string)
384
404
  : never
385
405
  }):
386
406
  & Rpc.Rpc<
@@ -398,9 +418,18 @@ export const Tag = <Self>() =>
398
418
  // TODO: we should only include errors that are relevant based on the middleware config.ks
399
419
  const error = options?.error
400
420
  const errors = typedValuesOf(rcm.config).map((_) => _.error).filter((_) => _ && _ !== S.Never) // TODO: only the errors relevant based on config
401
- const newError = error ? S.Union(error, ...errors) : S.Union(...errors)
402
-
403
- const rpc = Rpc.make(tag, { ...options, error: newError }) as any
421
+ const allErrors = error ? [error, ...errors] : errors
422
+ const [firstError, ...restErrors] = allErrors
423
+ const newError = firstError ? S.Union([firstError, ...restErrors]) : S.Never
424
+
425
+ // @ts-expect-error — TypeScript can't prove Simplify<T> ≡ { [K in keyof T]: T[K] } for unresolved generics (primaryKey)
426
+ const rpc = Rpc.make(tag, {
427
+ ...options?.payload !== undefined ? { payload: options.payload } : {},
428
+ ...options?.success !== undefined ? { success: options.success } : {},
429
+ error: newError,
430
+ ...options?.stream !== undefined ? { stream: options.stream } : {},
431
+ ...options?.primaryKey !== undefined ? { primaryKey: options.primaryKey } : {}
432
+ }) as any
404
433
 
405
434
  return Object.assign(rpc.annotate(requestContext, config), { config })
406
435
  },
@@ -422,7 +451,7 @@ export const Tag = <Self>() =>
422
451
  // alternatively consider group.serverMiddleware? hmmm
423
452
  export const middlewareGroup = <
424
453
  RequestContextMap extends Record<string, RpcContextMap.Any>,
425
- Middleware extends RpcMiddleware.TagClassAny & {
454
+ Middleware extends RpcMiddlewareX.TagClassAny & {
426
455
  readonly requestContext: RequestContextTag<RequestContextMap>
427
456
  readonly requestContextMap: RequestContextMap
428
457
  }
@@ -2,14 +2,14 @@
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-return */
3
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
4
4
 
5
- import { type AnyWithProps } from "@effect/rpc/Rpc"
6
- import { Context, type Schema as S } from "effect"
5
+ import { type Schema as S, ServiceMap } from "effect"
6
+ import { type AnyWithProps } from "effect/unstable/rpc/Rpc"
7
7
  import { type RpcDynamic } from "./RpcMiddleware.js"
8
8
 
9
9
  type Values<T extends Record<any, any>> = T[keyof T]
10
10
 
11
11
  /**
12
- * Middleware is inactivate by default, the Key is optional in route context, and the service is optionally provided as Effect Context.
12
+ * Middleware is inactivate by default, the Key is optional in route context, and the service is optionally provided as Effect ServiceMap.
13
13
  * Unless explicitly configured as `true`.
14
14
  */
15
15
  export type RpcContextMap<Service, E> = {
@@ -22,7 +22,7 @@ export type RpcContextMap<Service, E> = {
22
22
 
23
23
  export declare namespace RpcContextMap {
24
24
  /**
25
- * Middleware is active by default, and provides the Service at Key in route context, and the Service is provided as Effect Context.
25
+ * Middleware is active by default, and provides the Service at Key in route context, and the Service is provided as Effect ServiceMap.
26
26
  * Unless explicitly omitted.
27
27
  */
28
28
  export type Inverted<Service, E> = {
@@ -41,7 +41,7 @@ export declare namespace RpcContextMap {
41
41
 
42
42
  export type Any = {
43
43
  service: any
44
- error: S.Schema.All
44
+ error: S.Top
45
45
  contextActivation: any
46
46
  inverted: boolean
47
47
  }
@@ -97,7 +97,7 @@ export type GetEffectError<RequestContextMap extends Record<string, RpcContextMa
97
97
  }
98
98
  >
99
99
 
100
- const tag = Context.GenericTag("RequestContextConfig")
100
+ const tag = ServiceMap.Service("RequestContextConfig")
101
101
 
102
102
  export const makeMap = <const Config extends Record<string, RpcContextMap.Any>>(config: Config) => {
103
103
  const cls = class {
@@ -109,7 +109,7 @@ export const makeMap = <const Config extends Record<string, RpcContextMap.Any>>(
109
109
  return Object.assign(cls, {
110
110
  config, /** Retrieves RequestContextConfig out of the Rpc annotations */
111
111
  getConfig: (rpc: AnyWithProps): GetContextConfig<Config> => {
112
- return Context.getOrElse(rpc.annotations, tag as any, () => ({}))
112
+ return ServiceMap.getOrElse(rpc.annotations, tag as any, () => ({}))
113
113
  },
114
114
  /** Adapter used when setting the dynamic prop on a middleware implementation */
115
115
  get: <
@@ -1,28 +1,17 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-return */
3
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
4
- import { type Rpc, RpcMiddleware } from "@effect/rpc"
5
- import { type SuccessValue, type TypeId } from "@effect/rpc/RpcMiddleware"
6
- import { type Context, type Effect, type Schema, type Schema as S, type Scope, type Stream, Unify } from "effect"
7
- import { type HttpHeaders } from "effect-app/http"
4
+ import { type Effect, type Schema, type Schema as S, type Scope, type ServiceMap, type Stream } from "effect"
8
5
  import { type NonEmptyReadonlyArray } from "effect/Array"
9
- import { type TagUnify, type TagUnifyIgnore } from "effect/Context"
10
- import { type ReadonlyMailbox } from "effect/Mailbox"
6
+ import { type Rpc, RpcMiddleware } from "effect/unstable/rpc"
7
+ import { type TypeId } from "effect/unstable/rpc/RpcMiddleware"
11
8
  import { type GetEffectContext, type RpcContextMap } from "./RpcContextMap.js"
12
9
 
13
- // updated to support Scope.Scope and follow V4: Provides/Requires as Identifiers instead of Tag, wrap is default
14
- export interface RpcMiddlewareV4<Provides, E, Requires> {
15
- (effect: Effect.Effect<SuccessValue, E, Provides | Scope.Scope | Requires>, options: {
16
- readonly clientId: number
17
- readonly rpc: Rpc.AnyWithProps
18
- readonly payload: unknown
19
- readonly headers: HttpHeaders.Headers
20
- }): Effect.Effect<SuccessValue, E, Scope.Scope | Requires>
21
- }
10
+ export type RpcMiddlewareV4<Provides, E, Requires> = RpcMiddleware.RpcMiddleware<Provides, E, Requires>
22
11
 
23
12
  export type RpcOptionsOriginal = {
24
13
  readonly optional?: boolean
25
- readonly failure?: Schema.Schema.All
14
+ readonly error?: Schema.Top
26
15
  readonly requiredForClient?: boolean
27
16
  }
28
17
 
@@ -44,27 +33,13 @@ export interface RpcOptionsDynamic<Key extends string, A extends RpcContextMap.A
44
33
 
45
34
  export type Dynamic<Options> = Options extends RpcOptionsDynamic<any, any> ? true : false
46
35
 
47
- export interface RpcMiddlewareDynamic<E, R, _Config> {
48
- (effect: Effect.Effect<SuccessValue, E, Scope.Scope | R>, options: {
49
- readonly clientId: number
50
- readonly rpc: Rpc.AnyWithProps
51
- readonly payload: unknown
52
- readonly headers: HttpHeaders.Headers
53
- }): Effect.Effect<
54
- SuccessValue,
55
- E,
56
- Scope.Scope | R
57
- >
58
- }
36
+ export interface RpcMiddlewareDynamic<E, R, _Config> extends RpcMiddleware.RpcMiddleware<never, E, R> {}
59
37
 
60
- export interface TagClassAny extends Context.Tag<any, any> {
61
- readonly [TypeId]: TypeId
38
+ export interface TagClassAny extends RpcMiddleware.AnyService {
62
39
  readonly optional: boolean
63
40
  readonly provides: any
64
41
  readonly requires: any
65
- readonly failure: Schema.Schema.All
66
- readonly requiredForClient: boolean
67
- readonly wrap: true
42
+ readonly error: Schema.Top
68
43
  readonly dynamic?: RpcDynamic<any, any> | undefined
69
44
  readonly dependsOn?: NonEmptyReadonlyArray<AnyDynamic> | undefined
70
45
  }
@@ -74,8 +49,8 @@ export declare namespace TagClass {
74
49
  * @since 1.0.0
75
50
  * @category models
76
51
  */
77
- export type FailureSchema<Options> = Options extends
78
- { readonly failure: Schema.Schema.All; readonly optional?: false } ? Options["failure"]
52
+ export type FailureSchema<Options> = Options extends { readonly error: Schema.Top; readonly optional?: false }
53
+ ? Options["error"]
79
54
  // actually not, the Failure depends on Dynamic Middleware Configuration!
80
55
  // : Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? A["error"]
81
56
  : typeof Schema.Never
@@ -84,8 +59,8 @@ export declare namespace TagClass {
84
59
  * @since 1.0.0
85
60
  * @category models
86
61
  */
87
- export type Failure<Options> = Options extends
88
- { readonly failure: Schema.Schema<infer _A, infer _I, infer _R>; readonly optional?: false } ? _A
62
+ export type Failure<Options> = Options extends { readonly error: Schema.Schema<infer _A>; readonly optional?: false }
63
+ ? _A
89
64
  // actually not, the Failure depends on Dynamic Middleware Configuration!
90
65
  : Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? S.Schema.Type<A["error"]>
91
66
  : never
@@ -94,7 +69,7 @@ export declare namespace TagClass {
94
69
  * @since 1.0.0
95
70
  * @category models
96
71
  */
97
- export type FailureContext<Options> = Schema.Schema.Context<FailureSchema<Options>>
72
+ export type FailureContext<Options> = Schema.Codec.DecodingServices<FailureSchema<Options>>
98
73
 
99
74
  /**
100
75
  * @since 1.0.0
@@ -127,18 +102,18 @@ export declare namespace TagClass {
127
102
  requires?: any
128
103
  provides?: any
129
104
  }
130
- > extends Context.Tag<Self, Service> {
131
- new(_: never): Context.TagClassShape<Name, Service>
105
+ > extends ServiceMap.Service<Self, Service> {
106
+ new(_: never): ServiceMap.ServiceClass.Shape<Name, Service>
132
107
  readonly [TypeId]: TypeId
133
108
  readonly optional: Optional<Options>
134
- readonly failure: FailureSchema<Options>
109
+ readonly error: FailureSchema<Options>
110
+ readonly "~ClientError": Options extends { readonly clientError: infer CE } ? CE : never
135
111
  readonly provides: "provides" extends keyof Config ? Config["provides"] : never
136
112
  readonly requires: "requires" extends keyof Config ? Config["requires"] : never
137
113
  readonly dynamic: Options extends RpcOptionsDynamic<any, any> ? Options["dynamic"]
138
114
  : undefined
139
115
  readonly dependsOn: Options extends DependsOn ? Options["dependsOn"] : undefined
140
116
  readonly requiredForClient: RequiredForClient<Options>
141
- readonly wrap: true
142
117
  }
143
118
  }
144
119
 
@@ -183,18 +158,15 @@ export const Tag = <
183
158
  id: Name,
184
159
  options?: Options
185
160
  ): TagClass<Self, Name, Options, Config> =>
186
- class extends RpcMiddleware.Tag<Self>()(id, options) {
161
+ class extends RpcMiddleware.Service<Self>()(id, options as any) {
187
162
  static readonly requires: "requires" extends keyof Config ? Config["requires"] : never
188
- static override readonly provides: "provides" extends keyof Config ? Config["provides"] : never
163
+ static readonly provides: "provides" extends keyof Config ? Config["provides"] : never
189
164
  static readonly dynamic = options && "dynamic" in options ? options.dynamic : undefined
190
165
  static readonly dependsOn = options && "dependsOn" in options ? options.dependsOn : undefined
191
- static override [Unify.typeSymbol]?: unknown
192
- static override [Unify.unifySymbol]?: TagUnify<typeof this>
193
- static override [Unify.ignoreSymbol]?: TagUnifyIgnore
194
166
  } as any
195
167
 
196
168
  // not needed if there's official support in Rpc.Rpc.
197
- export type AddMiddleware<R extends Rpc.Any, Middleware extends RpcMiddleware.TagClassAny> = R extends Rpc.Rpc<
169
+ export type AddMiddleware<R extends Rpc.Any, Middleware extends RpcMiddleware.AnyServiceWithProps> = R extends Rpc.Rpc<
198
170
  infer _Tag,
199
171
  infer _Payload,
200
172
  infer _Success,
@@ -221,13 +193,13 @@ export type HandlerContext<Rpcs extends Rpc.Any, K extends Rpcs["_tag"], Handler
221
193
  | Stream.Stream<infer _A, infer _E, infer _R>
222
194
  | Rpc.Wrapper<Stream.Stream<infer _A, infer _E, infer _R>>
223
195
  | Effect.Effect<
224
- ReadonlyMailbox<infer _A, infer _E>,
196
+ infer _A,
225
197
  infer _EX,
226
198
  infer _R
227
199
  >
228
200
  | Rpc.Wrapper<
229
201
  Effect.Effect<
230
- ReadonlyMailbox<infer _A, infer _E>,
202
+ infer _A,
231
203
  infer _EX,
232
204
  infer _R
233
205
  >
@@ -241,7 +213,7 @@ export type HandlerContext<Rpcs extends Rpc.Any, K extends Rpcs["_tag"], Handler
241
213
 
242
214
  // new
243
215
  export type ExtractDynamicallyProvides<R extends Rpc.Any, Tag extends string> = R extends
244
- Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware> ? _Middleware extends {
216
+ Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware, infer _Requires> ? _Middleware extends {
245
217
  readonly requestContextMap: infer _RC
246
218
  } ? _RC extends Record<string, RpcContextMap.Any> // ? GetEffectContext<_RC, { allowAnonymous: false }>
247
219
  ? R extends { readonly config: infer _C } ? GetEffectContext<_RC, _C>
@@ -251,9 +223,11 @@ export type ExtractDynamicallyProvides<R extends Rpc.Any, Tag extends string> =
251
223
  : never
252
224
 
253
225
  export type ExtractProvides<R extends Rpc.Any, Tag extends string> = R extends
254
- Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware> ? _Middleware extends {
255
- readonly provides: Context.Tag<infer _I, infer _S>
256
- } ? _I
226
+ Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware, infer _Requires> ? _Middleware extends {
227
+ readonly provides: infer _P
228
+ } ? [_P] extends [never] ? never
229
+ : _P extends ServiceMap.Service<infer _I, infer _S> ? _I
230
+ : never
257
231
  : never
258
232
  : never
259
233
 
@@ -245,7 +245,7 @@ export const effectify: {
245
245
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
246
246
  (<A>(fn: Function, onError?: (e: any, args: any) => any, onSyncError?: (e: any, args: any) => any) =>
247
247
  (...args: Array<any>) =>
248
- Effect.async<A, Error>((resume) => {
248
+ Effect.callback<A, Error>((resume) => {
249
249
  try {
250
250
  fn(...args, (err: Error | null, result: A) => {
251
251
  if (err) {
package/src/utils/gen.ts CHANGED
@@ -1,22 +1,24 @@
1
- import { type Effect } from "effect/Effect"
2
- import { type YieldWrap } from "effect/Utils"
1
+ import { type Effect, type Yieldable } from "effect/Effect"
3
2
 
4
3
  export namespace EffectGenUtils {
5
4
  export type Success<EG> = EG extends Effect<infer A, infer _E, infer _R> ? A
6
5
  // there could be a case where the generator function does not yield anything, so we need to handle that
7
6
  : EG extends (..._: infer _3) => Generator<never, infer A, infer _2> ? A
8
- : EG extends (..._: infer _3) => Generator<YieldWrap<Effect<infer _, infer _E, infer _R>>, infer A, infer _2> ? A
7
+ // v4: generators can yield Yieldable (Effect, Service, etc.), all have asEffect()
8
+ : EG extends (..._: infer _3) => Generator<Yieldable<any, infer _, infer _E, infer _R>, infer A, infer _2> ? A
9
9
  : never
10
10
 
11
11
  export type Error<EG> = EG extends Effect<infer _A, infer E, infer _R> ? E
12
12
  // there could be a case where the generator function does not yield anything, so we need to handle that
13
13
  : EG extends (..._: infer _3) => Generator<never, infer _A, infer _2> ? never
14
- : EG extends (..._: infer _3) => Generator<YieldWrap<Effect<infer _, infer E, infer _R>>, infer _A, infer _2> ? E
14
+ // v4: generators can yield Yieldable (Effect, Service, etc.), all have asEffect()
15
+ : EG extends (..._: infer _3) => Generator<Yieldable<any, infer _, infer E, infer _R>, infer _A, infer _2> ? E
15
16
  : never
16
17
 
17
- export type Context<EG> = EG extends Effect<infer _A, infer _E, infer R> ? R
18
+ export type ServiceMap<EG> = EG extends Effect<infer _A, infer _E, infer R> ? R
18
19
  // there could be a case where the generator function does not yield anything, so we need to handle that
19
20
  : EG extends (..._: infer _3) => Generator<never, infer _A, infer _2> ? never
20
- : EG extends (..._: infer _3) => Generator<YieldWrap<Effect<infer _, infer _E, infer R>>, infer _A, infer _2> ? R
21
+ // v4: generators can yield Yieldable (Effect, Service, etc.), all have asEffect()
22
+ : EG extends (..._: infer _3) => Generator<Yieldable<any, infer _, infer _E, infer R>, infer _A, infer _2> ? R
21
23
  : never
22
24
  }