effect-app 4.0.0-beta.15 → 4.0.0-beta.151

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 (198) hide show
  1. package/CHANGELOG.md +595 -0
  2. package/dist/Array.d.ts +1 -1
  3. package/dist/Chunk.d.ts +1 -1
  4. package/dist/Chunk.d.ts.map +1 -1
  5. package/dist/Config/SecretURL.d.ts +1 -1
  6. package/dist/Config/SecretURL.d.ts.map +1 -1
  7. package/dist/Config/SecretURL.js +2 -2
  8. package/dist/Config/internal/configSecretURL.d.ts +1 -1
  9. package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
  10. package/dist/Config.d.ts +7 -0
  11. package/dist/Config.d.ts.map +1 -0
  12. package/dist/Config.js +6 -0
  13. package/dist/ConfigProvider.d.ts +39 -0
  14. package/dist/ConfigProvider.d.ts.map +1 -0
  15. package/dist/ConfigProvider.js +42 -0
  16. package/dist/Context.d.ts +40 -0
  17. package/dist/Context.d.ts.map +1 -0
  18. package/dist/Context.js +67 -0
  19. package/dist/Effect.d.ts +9 -10
  20. package/dist/Effect.d.ts.map +1 -1
  21. package/dist/Effect.js +3 -6
  22. package/dist/Function.d.ts +1 -1
  23. package/dist/Function.d.ts.map +1 -1
  24. package/dist/Inputify.type.d.ts +1 -1
  25. package/dist/Layer.d.ts +6 -5
  26. package/dist/Layer.d.ts.map +1 -1
  27. package/dist/Layer.js +1 -1
  28. package/dist/NonEmptySet.d.ts +1 -1
  29. package/dist/NonEmptySet.d.ts.map +1 -1
  30. package/dist/Operations.d.ts +372 -50
  31. package/dist/Operations.d.ts.map +1 -1
  32. package/dist/Operations.js +9 -9
  33. package/dist/Option.d.ts +1 -1
  34. package/dist/Option.d.ts.map +1 -1
  35. package/dist/Pure.d.ts +5 -5
  36. package/dist/Pure.d.ts.map +1 -1
  37. package/dist/Pure.js +13 -13
  38. package/dist/Schema/Class.d.ts +69 -20
  39. package/dist/Schema/Class.d.ts.map +1 -1
  40. package/dist/Schema/Class.js +193 -22
  41. package/dist/Schema/FastCheck.d.ts +1 -1
  42. package/dist/Schema/FastCheck.d.ts.map +1 -1
  43. package/dist/Schema/Methods.d.ts +1 -1
  44. package/dist/Schema/SpecialJsonSchema.d.ts +33 -0
  45. package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
  46. package/dist/Schema/SpecialJsonSchema.js +122 -0
  47. package/dist/Schema/SpecialOpenApi.d.ts +32 -0
  48. package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
  49. package/dist/Schema/SpecialOpenApi.js +123 -0
  50. package/dist/Schema/brand.d.ts +7 -2
  51. package/dist/Schema/brand.d.ts.map +1 -1
  52. package/dist/Schema/brand.js +1 -1
  53. package/dist/Schema/email.d.ts +1 -1
  54. package/dist/Schema/email.d.ts.map +1 -1
  55. package/dist/Schema/email.js +7 -4
  56. package/dist/Schema/ext.d.ts +113 -48
  57. package/dist/Schema/ext.d.ts.map +1 -1
  58. package/dist/Schema/ext.js +115 -53
  59. package/dist/Schema/moreStrings.d.ts +111 -11
  60. package/dist/Schema/moreStrings.d.ts.map +1 -1
  61. package/dist/Schema/moreStrings.js +14 -15
  62. package/dist/Schema/numbers.d.ts +127 -15
  63. package/dist/Schema/numbers.d.ts.map +1 -1
  64. package/dist/Schema/numbers.js +10 -12
  65. package/dist/Schema/phoneNumber.d.ts +1 -1
  66. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  67. package/dist/Schema/phoneNumber.js +6 -3
  68. package/dist/Schema/schema.d.ts +1 -1
  69. package/dist/Schema/strings.d.ts +37 -5
  70. package/dist/Schema/strings.d.ts.map +1 -1
  71. package/dist/Schema/strings.js +1 -5
  72. package/dist/Schema.d.ts +88 -53
  73. package/dist/Schema.d.ts.map +1 -1
  74. package/dist/Schema.js +125 -63
  75. package/dist/Set.d.ts +1 -1
  76. package/dist/Set.d.ts.map +1 -1
  77. package/dist/TypeTest.d.ts +1 -1
  78. package/dist/Types.d.ts +1 -1
  79. package/dist/Widen.type.d.ts +1 -1
  80. package/dist/_ext/Array.d.ts +1 -1
  81. package/dist/_ext/Array.d.ts.map +1 -1
  82. package/dist/_ext/date.d.ts +1 -1
  83. package/dist/_ext/misc.d.ts +1 -1
  84. package/dist/_ext/ord.ext.d.ts +1 -1
  85. package/dist/_ext/ord.ext.d.ts.map +1 -1
  86. package/dist/builtin.d.ts +1 -1
  87. package/dist/builtin.d.ts.map +1 -1
  88. package/dist/client/apiClientFactory.d.ts +14 -30
  89. package/dist/client/apiClientFactory.d.ts.map +1 -1
  90. package/dist/client/apiClientFactory.js +18 -19
  91. package/dist/client/clientFor.d.ts +7 -6
  92. package/dist/client/clientFor.d.ts.map +1 -1
  93. package/dist/client/errors.d.ts +44 -19
  94. package/dist/client/errors.d.ts.map +1 -1
  95. package/dist/client/errors.js +35 -10
  96. package/dist/client/makeClient.d.ts +77 -29
  97. package/dist/client/makeClient.d.ts.map +1 -1
  98. package/dist/client/makeClient.js +49 -23
  99. package/dist/client.d.ts +1 -1
  100. package/dist/faker.d.ts +1 -1
  101. package/dist/faker.d.ts.map +1 -1
  102. package/dist/http/Request.d.ts +2 -2
  103. package/dist/http/Request.d.ts.map +1 -1
  104. package/dist/http/Request.js +5 -5
  105. package/dist/http/internal/lib.d.ts +1 -1
  106. package/dist/http.d.ts +1 -1
  107. package/dist/ids.d.ts +3 -3
  108. package/dist/ids.d.ts.map +1 -1
  109. package/dist/ids.js +3 -2
  110. package/dist/index.d.ts +5 -8
  111. package/dist/index.d.ts.map +1 -1
  112. package/dist/index.js +6 -8
  113. package/dist/logger.d.ts +1 -1
  114. package/dist/middleware.d.ts +8 -8
  115. package/dist/middleware.d.ts.map +1 -1
  116. package/dist/middleware.js +8 -8
  117. package/dist/rpc/MiddlewareMaker.d.ts +5 -4
  118. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  119. package/dist/rpc/MiddlewareMaker.js +26 -27
  120. package/dist/rpc/RpcContextMap.d.ts +3 -3
  121. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  122. package/dist/rpc/RpcContextMap.js +4 -4
  123. package/dist/rpc/RpcMiddleware.d.ts +5 -4
  124. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  125. package/dist/rpc/RpcMiddleware.js +1 -1
  126. package/dist/rpc.d.ts +1 -2
  127. package/dist/rpc.d.ts.map +1 -1
  128. package/dist/rpc.js +1 -2
  129. package/dist/transform.d.ts +1 -1
  130. package/dist/transform.d.ts.map +1 -1
  131. package/dist/transform.js +3 -3
  132. package/dist/utils/effectify.d.ts +1 -1
  133. package/dist/utils/extend.d.ts +1 -1
  134. package/dist/utils/extend.d.ts.map +1 -1
  135. package/dist/utils/gen.d.ts +2 -2
  136. package/dist/utils/gen.d.ts.map +1 -1
  137. package/dist/utils/logLevel.d.ts +2 -2
  138. package/dist/utils/logLevel.d.ts.map +1 -1
  139. package/dist/utils/logger.d.ts +3 -3
  140. package/dist/utils/logger.d.ts.map +1 -1
  141. package/dist/utils/logger.js +3 -3
  142. package/dist/utils.d.ts +30 -10
  143. package/dist/utils.d.ts.map +1 -1
  144. package/dist/utils.js +10 -4
  145. package/dist/validation/validators.d.ts +1 -1
  146. package/dist/validation/validators.d.ts.map +1 -1
  147. package/dist/validation.d.ts +1 -1
  148. package/dist/validation.d.ts.map +1 -1
  149. package/eslint.config.mjs +1 -1
  150. package/package.json +35 -19
  151. package/src/Config/SecretURL.ts +2 -1
  152. package/src/Config.ts +14 -0
  153. package/src/ConfigProvider.ts +48 -0
  154. package/src/{ServiceMap.ts → Context.ts} +52 -59
  155. package/src/Effect.ts +12 -14
  156. package/src/Layer.ts +5 -4
  157. package/src/Operations.ts +9 -9
  158. package/src/Pure.ts +17 -18
  159. package/src/Schema/Class.ts +281 -62
  160. package/src/Schema/SpecialJsonSchema.ts +137 -0
  161. package/src/Schema/SpecialOpenApi.ts +130 -0
  162. package/src/Schema/brand.ts +9 -1
  163. package/src/Schema/email.ts +7 -2
  164. package/src/Schema/ext.ts +196 -87
  165. package/src/Schema/moreStrings.ts +22 -20
  166. package/src/Schema/numbers.ts +14 -16
  167. package/src/Schema/phoneNumber.ts +5 -1
  168. package/src/Schema/strings.ts +4 -8
  169. package/src/Schema.ts +256 -98
  170. package/src/client/apiClientFactory.ts +107 -113
  171. package/src/client/clientFor.ts +6 -1
  172. package/src/client/errors.ts +42 -17
  173. package/src/client/makeClient.ts +156 -63
  174. package/src/http/Request.ts +7 -4
  175. package/src/ids.ts +2 -1
  176. package/src/index.ts +5 -10
  177. package/src/middleware.ts +7 -9
  178. package/src/rpc/MiddlewareMaker.ts +36 -47
  179. package/src/rpc/RpcContextMap.ts +6 -5
  180. package/src/rpc/RpcMiddleware.ts +5 -4
  181. package/src/rpc.ts +0 -1
  182. package/src/transform.ts +2 -2
  183. package/src/utils/gen.ts +1 -1
  184. package/src/utils/logger.ts +2 -2
  185. package/src/utils.ts +47 -11
  186. package/test/dist/rpc.test.d.ts.map +1 -1
  187. package/test/dist/secretURL.test.d.ts.map +1 -0
  188. package/test/dist/special.test.d.ts.map +1 -0
  189. package/test/rpc.test.ts +38 -6
  190. package/test/schema.test.ts +594 -4
  191. package/test/secretURL.test.ts +157 -0
  192. package/test/special.test.ts +1005 -0
  193. package/test/utils.test.ts +6 -6
  194. package/tsconfig.base.json +0 -1
  195. package/tsconfig.json +0 -1
  196. package/dist/ServiceMap.d.ts +0 -44
  197. package/dist/ServiceMap.d.ts.map +0 -1
  198. package/dist/ServiceMap.js +0 -91
@@ -1,3 +1,4 @@
1
+ import { SchemaTransformation } from "effect"
1
2
  import { type GetContextConfig, type GetEffectError, type RequestContextMapTagAny } from "../rpc/RpcContextMap.js"
2
3
  import * as S from "../Schema.js"
3
4
  import { AST } from "../Schema.js"
@@ -8,33 +9,46 @@ const merge = (a: any, b: Array<any>) =>
8
9
  /**
9
10
  * Whatever the input, we will only decode or encode to void
10
11
  */
11
- const ForceVoid: S.Codec<void> = S.Void as any
12
+ export const ForceVoid = S
13
+ .declare((_: unknown): _ is unknown => true)
14
+ .pipe(
15
+ S.decodeTo(S.Any, SchemaTransformation.transform<unknown, unknown>({ decode: () => void 0, encode: () => void 0 }))
16
+ )
12
17
 
13
18
  type SchemaOrFields<T> = T extends S.Top ? T : T extends S.Struct.Fields ? S.Struct<T> : S.Void
14
19
 
15
- type TaggedRequestResult<
20
+ type TaggedRequestSchema<Tag extends string, Payload extends S.Struct.Fields> = S.Struct<
21
+ { readonly _tag: S.tag<Tag> } & Payload
22
+ >
23
+
24
+ type TaggedRequestForResult<
25
+ Self,
16
26
  Tag extends string,
17
27
  Payload extends S.Struct.Fields,
18
28
  Success extends S.Top,
19
29
  Error extends S.Top,
20
- Config = Record<string, never>
30
+ Config,
31
+ ModuleName extends string,
32
+ Type extends "command" | "query"
21
33
  > =
22
- & S.TaggedStruct<Tag, Payload>
34
+ & S.EnhancedClass<Self, TaggedRequestSchema<Tag, Payload>, {}>
23
35
  & {
24
- new(...args: any[]): any
25
36
  readonly _tag: Tag
26
- readonly fields: { readonly _tag: S.tag<Tag> } & Payload
27
37
  readonly success: Success
28
38
  readonly error: Error
29
39
  readonly config: Config
30
40
  readonly "~decodingServices": S.Codec.DecodingServices<Success> | S.Codec.DecodingServices<Error>
41
+ readonly "~encodingServices": S.Codec.EncodingServices<Success> | S.Codec.EncodingServices<Error>
42
+ readonly id: `${ModuleName}.${Tag}`
43
+ readonly moduleName: ModuleName
44
+ readonly type: Type
31
45
  }
32
46
 
33
47
  export const makeRpcClient = <
34
48
  RequestContextMap extends RequestContextMapTagAny,
35
49
  GeneralErrors extends S.Top = never
36
50
  >(rcs: RequestContextMap, generalErrors?: GeneralErrors) => {
37
- // Long way around ServiceMap/C extends etc to support actual jsdoc from passed in RequestConfig etc... (??)
51
+ // Long way around Context/C extends etc to support actual jsdoc from passed in RequestConfig etc... (??)
38
52
  type ServiceMap = {
39
53
  success: S.Top | S.Struct.Fields // SchemaOrFields will make a Schema type out of Struct.Fields
40
54
  error: S.Top | S.Struct.Fields // SchemaOrFields will make a Schema type out of Struct.Fields
@@ -47,64 +61,143 @@ export const makeRpcClient = <
47
61
  : [GeneralErrors] extends [never] ? GetEffectError<RequestContextMap["config"], C>
48
62
  : MergeError<GetEffectError<RequestContextMap["config"], C>>
49
63
 
50
- function TaggedRequest<_Self>(): {
51
- <Tag extends string, Payload extends S.Struct.Fields, C extends ServiceMap>(
52
- tag: Tag,
53
- fields: Payload,
54
- config: RequestConfig & C
55
- ): TaggedRequestResult<Tag, Payload, SchemaOrFields<C["success"]>, ErrorResult<C>, Omit<C, "success" | "error">>
56
- <Tag extends string, Payload extends S.Struct.Fields, C extends Pick<ServiceMap, "success">>(
57
- tag: Tag,
58
- fields: Payload,
59
- config: RequestConfig & C
60
- ): TaggedRequestResult<Tag, Payload, SchemaOrFields<C["success"]>, ErrorResult<C>, Omit<C, "success" | "error">>
61
- <Tag extends string, Payload extends S.Struct.Fields, C extends Pick<ServiceMap, "error">>(
62
- tag: Tag,
63
- fields: Payload,
64
- config: RequestConfig & C
65
- ): TaggedRequestResult<Tag, Payload, S.Codec<void>, ErrorResult<C>, Omit<C, "success" | "error">>
66
- <Tag extends string, Payload extends S.Struct.Fields, C extends Record<string, any>>(
67
- tag: Tag,
68
- fields: Payload,
69
- config: C & RequestConfig
70
- ): TaggedRequestResult<Tag, Payload, S.Codec<void>, ErrorResult<C>, Omit<C, "success" | "error">>
71
- <Tag extends string, Payload extends S.Struct.Fields>(
72
- tag: Tag,
73
- fields: Payload
74
- ): TaggedRequestResult<Tag, Payload, S.Codec<void>, ErrorResult<never>, Record<string, never>>
75
- } {
76
- // TODO: filter errors based on config + take care of inversion
77
- const errorSchemas = Object.values(rcs.config).map((_) => _.error)
78
- return (<Tag extends string, Fields extends S.Struct.Fields, C extends ServiceMap>(
79
- tag: Tag,
80
- fields: Fields,
81
- config?: C
82
- ) => {
83
- // TODO: S.TaggedRequest removed in v4 — needs rework to use Rpc.make or Request.TaggedClass
84
- // For now, creating a simple tagged struct class with success/failure properties
85
- const failureSchema = merge(
86
- config?.error ? S.isSchema(config.error) ? config.error : S.Struct(config.error) : undefined,
87
- [...errorSchemas, generalErrors].filter(Boolean)
88
- )
89
- const successSchema = config?.success
90
- ? S.isSchema(config.success)
91
- ? AST.isVoid(config.success.ast) ? ForceVoid : config.success
92
- : S.Struct(config.success)
93
- : ForceVoid
94
-
95
- const RequestClass = S.TaggedClass<any>()(tag, fields)
96
- Object.assign(RequestClass, {
97
- _tag: tag,
98
- success: successSchema,
99
- error: failureSchema,
100
- config
101
- })
102
-
103
- return RequestClass
104
- }) as any
64
+ // TODO: filter errors based on config + take care of inversion
65
+ const errorSchemas = Object.values(rcs.config).map((_) => _.error)
66
+
67
+ function makeRequestClass<Tag extends string, Fields extends S.Struct.Fields, C extends ServiceMap>(
68
+ tag: Tag,
69
+ fields: Fields,
70
+ config?: C
71
+ ) {
72
+ const failureSchema = merge(
73
+ config?.error ? S.isSchema(config.error) ? config.error : S.Struct(config.error) : undefined,
74
+ [...errorSchemas, generalErrors].filter(Boolean)
75
+ )
76
+ const successSchema = config?.success
77
+ ? S.isSchema(config.success)
78
+ ? AST.isVoid(config.success.ast) ? ForceVoid : config.success
79
+ : S.Struct(config.success)
80
+ : ForceVoid
81
+
82
+ const RequestClass = S.TaggedClass<any>()(tag, fields)
83
+ Object.assign(RequestClass, {
84
+ _tag: tag,
85
+ success: successSchema,
86
+ error: failureSchema,
87
+ config
88
+ })
89
+
90
+ return RequestClass
91
+ }
92
+
93
+ function makeTaggedRequestWithMeta<ModuleName extends string, Type extends "command" | "query">(
94
+ moduleName: ModuleName,
95
+ type: Type
96
+ ) {
97
+ function TaggedRequestWithMeta<Self>(): {
98
+ <Tag extends string, Payload extends S.Struct.Fields, C extends ServiceMap>(
99
+ tag: Tag,
100
+ fields: Payload,
101
+ config: RequestConfig & C
102
+ ): TaggedRequestForResult<
103
+ Self,
104
+ Tag,
105
+ Payload,
106
+ SchemaOrFields<C["success"]>,
107
+ ErrorResult<C>,
108
+ Omit<C, "success" | "error">,
109
+ ModuleName,
110
+ Type
111
+ >
112
+ <Tag extends string, Payload extends S.Struct.Fields, C extends Pick<ServiceMap, "success">>(
113
+ tag: Tag,
114
+ fields: Payload,
115
+ config: RequestConfig & C
116
+ ): TaggedRequestForResult<
117
+ Self,
118
+ Tag,
119
+ Payload,
120
+ SchemaOrFields<C["success"]>,
121
+ ErrorResult<C>,
122
+ Omit<C, "success" | "error">,
123
+ ModuleName,
124
+ Type
125
+ >
126
+ <Tag extends string, Payload extends S.Struct.Fields, C extends Pick<ServiceMap, "error">>(
127
+ tag: Tag,
128
+ fields: Payload,
129
+ config: RequestConfig & C
130
+ ): TaggedRequestForResult<
131
+ Self,
132
+ Tag,
133
+ Payload,
134
+ typeof ForceVoid,
135
+ ErrorResult<C>,
136
+ Omit<C, "success" | "error">,
137
+ ModuleName,
138
+ Type
139
+ >
140
+ <Tag extends string, Payload extends S.Struct.Fields, C extends Record<string, any>>(
141
+ tag: Tag,
142
+ fields: Payload,
143
+ config: C & RequestConfig
144
+ ): TaggedRequestForResult<
145
+ Self,
146
+ Tag,
147
+ Payload,
148
+ typeof ForceVoid,
149
+ ErrorResult<C>,
150
+ Omit<C, "success" | "error">,
151
+ ModuleName,
152
+ Type
153
+ >
154
+ <Tag extends string, Payload extends S.Struct.Fields>(
155
+ tag: Tag,
156
+ fields: Payload
157
+ ): TaggedRequestForResult<
158
+ Self,
159
+ Tag,
160
+ Payload,
161
+ typeof ForceVoid,
162
+ ErrorResult<{}>,
163
+ Record<string, never>,
164
+ ModuleName,
165
+ Type
166
+ >
167
+ } {
168
+ return (<Tag extends string, Fields extends S.Struct.Fields, C extends ServiceMap>(
169
+ tag: Tag,
170
+ fields: Fields,
171
+ config?: C
172
+ ) => {
173
+ const cls = makeRequestClass(tag, fields, config)
174
+ Object.assign(cls, { id: `${moduleName}.${tag}`, moduleName, type })
175
+ return cls
176
+ }) as any
177
+ }
178
+ return Object.assign(TaggedRequestWithMeta, { moduleName, type } as const)
179
+ }
180
+
181
+ function TaggedRequestFor<ModuleName extends string>(moduleName: ModuleName) {
182
+ const Query = makeTaggedRequestWithMeta(moduleName, "query")
183
+ const Command = makeTaggedRequestWithMeta(moduleName, "command")
184
+
185
+ return {
186
+ moduleName,
187
+ /**
188
+ * Create query request classes for this module.
189
+ * Queries read state and should not mutate server state.
190
+ */
191
+ Query,
192
+ /**
193
+ * Create command request classes for this module.
194
+ * Commands mutate state and should avoid returning complex read models.
195
+ */
196
+ Command
197
+ } as const
105
198
  }
106
199
 
107
200
  return {
108
- TaggedRequest
201
+ TaggedRequestFor
109
202
  }
110
203
  }
@@ -1,3 +1,4 @@
1
+ import { Option } from "effect"
1
2
  import type { HttpClientResponse } from "effect/unstable/http/HttpClientResponse"
2
3
  import * as Effect from "../Effect.js"
3
4
  import { HttpClient, HttpClientError, HttpClientRequest, HttpHeaders } from "./internal/lib.js"
@@ -24,16 +25,18 @@ export const demandJson = (client: HttpClient.HttpClient) =>
24
25
  .mapRequest(client, (_) => HttpClientRequest.acceptJson(_))
25
26
  .pipe(HttpClient.transform((r, request) =>
26
27
  Effect.tap(r, (response) =>
27
- HttpHeaders
28
- .get(response.headers, "Content-Type")
29
- ?.startsWith("application/json")
28
+ Option
29
+ .exists(
30
+ HttpHeaders.get(response.headers, "Content-Type"),
31
+ (_) => _.startsWith("application/json")
32
+ )
30
33
  ? Effect.void
31
34
  : Effect.fail(
32
35
  new HttpClientError.DecodeError({
33
36
  request,
34
37
  response,
35
38
  description: "not json response: "
36
- + HttpHeaders.get(response.headers, "Content-Type")
39
+ + Option.getOrElse(HttpHeaders.get(response.headers, "Content-Type"), () => "<missing>")
37
40
  })
38
41
  ))
39
42
  ))
package/src/ids.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Effect } from "effect"
1
2
  import { brandedStringId, type Codec, NonEmptyString255, StringId, type StringIdBrand, withDefaultMake } from "effect-app/Schema"
2
3
  import type { B } from "effect-app/Schema/schema"
3
4
  import type { Simplify } from "effect/Types"
@@ -17,7 +18,7 @@ export const RequestId = extendM(
17
18
  const make = StringId.make as () => NonEmptyString255
18
19
  return ({
19
20
  make,
20
- withDefault: s.pipe(S.withDefaultConstructor(make))
21
+ withDefault: S.withConstructorDefault(Effect.sync(make))(s as typeof s & S.WithoutConstructorDefault)
21
22
  })
22
23
  }
23
24
  )
package/src/index.ts CHANGED
@@ -1,24 +1,18 @@
1
+ // eslint-disable-next-line import/no-unassigned-import
1
2
  import "./builtin.js"
2
3
 
3
- import * as ServiceMap from "./ServiceMap.js"
4
-
5
4
  export * as Fnc from "./Function.js"
6
5
  export * as Utils from "./utils.js"
7
6
 
8
7
  export * as Array from "./Array.js"
8
+ export * as Config from "./Config.js"
9
+ export * as ConfigProvider from "./ConfigProvider.js"
10
+ export * as Context from "./Context.js"
9
11
  export * as Effect from "./Effect.js"
10
12
  export * as Layer from "./Layer.js"
11
13
  export * as NonEmptySet from "./NonEmptySet.js"
12
- export * as ServiceMap from "./ServiceMap.js"
13
14
  export * as Set from "./Set.js"
14
15
 
15
- export {
16
- /**
17
- * @deprecated use ServiceMap directly instead
18
- */
19
- ServiceMap as Context
20
- }
21
-
22
16
  export { type NonEmptyArray, type NonEmptyReadonlyArray } from "./Array.js"
23
17
 
24
18
  export * from "effect"
@@ -26,5 +20,6 @@ export * from "effect"
26
20
  export type * as Types from "./Types.js"
27
21
 
28
22
  export * as SecretURL from "./Config/SecretURL.js"
23
+ export * as RpcX from "./rpc.js"
29
24
  export * as S from "./Schema.js"
30
25
  export { copy } from "./utils.js"
package/src/middleware.ts CHANGED
@@ -1,20 +1,18 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { ServiceMap } from "effect-app"
3
- import { RpcX } from "./rpc.js"
2
+ import { Context } from "effect-app"
3
+ import { RpcMiddleware } from "./rpc.js"
4
4
 
5
- export class DevMode extends ServiceMap.Reference("DevMode", { defaultValue: () => false }) {}
5
+ export class DevMode extends Context.Reference("DevMode", { defaultValue: () => false }) {}
6
6
 
7
- export class RequestCacheMiddleware
8
- extends RpcX.RpcMiddleware.Tag<RequestCacheMiddleware>()("RequestCacheMiddleware")
9
- {}
7
+ export class RequestCacheMiddleware extends RpcMiddleware.Tag<RequestCacheMiddleware>()("RequestCacheMiddleware") {}
10
8
 
11
9
  export class ConfigureInterruptibilityMiddleware
12
- extends RpcX.RpcMiddleware.Tag<ConfigureInterruptibilityMiddleware>()("ConfigureInterruptibilityMiddleware")
10
+ extends RpcMiddleware.Tag<ConfigureInterruptibilityMiddleware>()("ConfigureInterruptibilityMiddleware")
13
11
  {}
14
12
 
15
- export class LoggerMiddleware extends RpcX.RpcMiddleware.Tag<LoggerMiddleware>()("LoggerMiddleware") {}
13
+ export class LoggerMiddleware extends RpcMiddleware.Tag<LoggerMiddleware>()("LoggerMiddleware") {}
16
14
 
17
- export class DevModeMiddleware extends RpcX.RpcMiddleware.Tag<DevModeMiddleware>()("DevModeMiddleware") {}
15
+ export class DevModeMiddleware extends RpcMiddleware.Tag<DevModeMiddleware>()("DevModeMiddleware") {}
18
16
 
19
17
  export const DefaultGenericMiddlewares = [
20
18
  RequestCacheMiddleware,
@@ -1,11 +1,10 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { Effect, Layer, type Schema, Schema as S, type Scope, ServiceMap } from "effect"
2
+ import { Effect, Layer, type Schema, Schema as S, type Scope } from "effect"
3
3
  import { type NonEmptyArray, type NonEmptyReadonlyArray } from "effect/Array"
4
4
  import { type Simplify } from "effect/Types"
5
5
  import { Rpc, type RpcGroup, type RpcSchema } from "effect/unstable/rpc"
6
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
+ import * as Context from "../Context.js"
9
8
  import { PreludeLogger } from "../logger.js"
10
9
  import { type TypeTestId } from "../TypeTest.js"
11
10
  import { typedValuesOf } from "../utils.js"
@@ -61,13 +60,13 @@ export interface MiddlewareMaker<
61
60
  }
62
61
  >
63
62
  {
64
- readonly layer: Layer.Layer<Self, never, ServiceMap.Service.Identifier<MiddlewareProviders[number]>>
63
+ readonly layer: Layer.Layer<Self, never, Context.Service.Identifier<MiddlewareProviders[number]>>
65
64
  readonly requestContext: RequestContextTag<RequestContextMap>
66
65
  readonly requestContextMap: RequestContextMap
67
66
  }
68
67
 
69
68
  export interface RequestContextTag<RequestContextMap extends Record<string, RpcContextMap.Any>>
70
- extends ServiceMap.Service<"RequestContextConfig", GetContextConfig<RequestContextMap>>
69
+ extends Context.Service<"RequestContextConfig", GetContextConfig<RequestContextMap>>
71
70
  {}
72
71
 
73
72
  export namespace MiddlewareMaker {
@@ -258,10 +257,10 @@ export type MiddlewaresBuilder<
258
257
  : { new(_: never): {} }
259
258
  : { new(_: never): {} })
260
259
 
261
- const middlewareMaker = <
260
+ const middlewareMaker = Effect.fnUntraced(function*<
262
261
  MiddlewareProviders extends ReadonlyArray<MiddlewareMaker.Any>
263
- >(middlewares: MiddlewareProviders): Effect.Effect<
264
- RpcMiddlewareV4<
262
+ >(middlewares: MiddlewareProviders) {
263
+ type Middleware = RpcMiddlewareV4<
265
264
  MiddlewareMaker.ManyProvided<MiddlewareProviders>,
266
265
  MiddlewareMaker.ManyErrors<MiddlewareProviders>,
267
266
  Exclude<
@@ -270,42 +269,32 @@ const middlewareMaker = <
270
269
  > extends never ? never
271
270
  : Exclude<MiddlewareMaker.ManyRequired<MiddlewareProviders>, MiddlewareMaker.ManyProvided<MiddlewareProviders>>
272
271
  >
273
- > => {
272
+ type Next = Parameters<Middleware>[0]
273
+ type Options = Parameters<Middleware>[1]
274
+
274
275
  // we want to run them in reverse order because latter middlewares will provide context to former ones
275
- middlewares = middlewares.toReversed() as any
276
-
277
- return Effect.gen(function*() {
278
- const context = yield* Effect.services()
279
-
280
- // returns a Effect/RpcMiddlewareV4 with Scope.Scope in requirements
281
- // v4: wrap middleware takes (effect, options) as two params instead of a single options bag
282
- return (
283
- next: Effect.Effect<any, any, any>,
284
- options: {
285
- readonly clientId: number
286
- readonly requestId: RequestId
287
- readonly rpc: Rpc.AnyWithProps
288
- readonly payload: unknown
289
- readonly headers: HttpHeaders.Headers
290
- }
291
- ) => {
292
- // we start with the actual handler
293
- let handler = next
294
-
295
- // inspired from Effect/RpcMiddleware
296
- for (const tag of middlewares) {
297
- // use the tag to get the middleware from context
298
- const middleware = ServiceMap.getUnsafe(context, tag)
299
-
300
- // wrap the current handler, allowing the middleware to run before and after it
301
- handler = PreludeLogger.logDebug("Applying middleware wrap " + tag.key).pipe(
302
- Effect.andThen(middleware(handler, options))
303
- ) as any
304
- }
305
- return handler
276
+ const reversed = middlewares.toReversed()
277
+ const context = yield* Effect.context()
278
+
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
281
+ return (next: Next, options: Options) => {
282
+ // we start with the actual handler
283
+ let handler = next
284
+
285
+ // inspired from Effect/RpcMiddleware
286
+ for (const tag of reversed) {
287
+ // use the tag to get the middleware from context
288
+ const middleware = Context.getUnsafe(context, tag)
289
+
290
+ // wrap the current handler, allowing the middleware to run before and after it
291
+ handler = PreludeLogger.logDebug("Applying middleware wrap " + tag.key).pipe(
292
+ Effect.andThen(middleware(handler, options))
293
+ ) as any
306
294
  }
307
- }) as any
308
- }
295
+ return handler
296
+ }
297
+ })
309
298
 
310
299
  const makeMiddlewareBasic = <Self>() =>
311
300
  // by setting RequestContextMap beforehand, execute contextual typing does not fuck up itself to anys
@@ -321,7 +310,7 @@ const makeMiddlewareBasic = <Self>() =>
321
310
  // reverse middlewares and wrap one after the other
322
311
  const middleware = middlewareMaker(make)
323
312
 
324
- const failures = make.map((_) => _.error).filter(Boolean)
313
+ const failures = make.flatMap((_) => _.error ? [_.error] : [])
325
314
  const provides = make.flatMap((_) => !_.provides ? [] : Array.isArray(_.provides) ? _.provides : [_.provides])
326
315
  const requires = make
327
316
  .flatMap((_) => !_.requires ? [] : Array.isArray(_.requires) ? _.requires : [_.requires])
@@ -367,7 +356,7 @@ const makeMiddlewareBasic = <Self>() =>
367
356
  return Object.assign(MiddlewareMaker, {
368
357
  layer,
369
358
  // tag to be used to retrieve the RequestContextConfig from Rpc annotations
370
- requestContext: ServiceMap.Service<"RequestContextConfig", GetContextConfig<RequestContextMap>>(
359
+ requestContext: Context.Service<"RequestContextConfig", GetContextConfig<RequestContextMap>>(
371
360
  "RequestContextConfig"
372
361
  ),
373
362
  requestContextMap: rcm
@@ -379,8 +368,8 @@ export const Tag = <Self>() =>
379
368
  const Id extends string,
380
369
  RequestContextMap extends RequestContextMapTagAny
381
370
  >(id: Id, rcm: RequestContextMap): MiddlewaresBuilder<Self, Id, RequestContextMap["config"]> => {
382
- let allMiddleware: MiddlewareMaker.Any[] = []
383
- const requestContext = ServiceMap.Service<"RequestContextConfig", GetContextConfig<RequestContextMap["config"]>>(
371
+ const allMiddleware: MiddlewareMaker.Any[] = []
372
+ const requestContext = Context.Service<"RequestContextConfig", GetContextConfig<RequestContextMap["config"]>>(
384
373
  "RequestContextConfig"
385
374
  )
386
375
  const it = {
@@ -437,7 +426,7 @@ export const Tag = <Self>() =>
437
426
  middleware: (...middlewares: any[]) => {
438
427
  for (const mw of middlewares) {
439
428
  // recall that we run middlewares in reverse order
440
- allMiddleware = [mw, ...allMiddleware]
429
+ allMiddleware.unshift(mw)
441
430
  }
442
431
  return allMiddleware.filter((m) => !!m.dynamic).length !== Object.keys(rcm.config).length
443
432
  // for sure, until all the dynamic middlewares are provided it's non sensical to call makeMiddlewareBasic
@@ -2,14 +2,15 @@
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-return */
3
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
4
4
 
5
- import { type Schema as S, ServiceMap } from "effect"
5
+ import { type Schema as S } from "effect"
6
6
  import { type AnyWithProps } from "effect/unstable/rpc/Rpc"
7
+ import * as Context from "../Context.js"
7
8
  import { type RpcDynamic } from "./RpcMiddleware.js"
8
9
 
9
10
  type Values<T extends Record<any, any>> = T[keyof T]
10
11
 
11
12
  /**
12
- * Middleware is inactivate by default, the Key is optional in route context, and the service is optionally provided as Effect ServiceMap.
13
+ * Middleware is inactivate by default, the Key is optional in route context, and the service is optionally provided as Effect Context.
13
14
  * Unless explicitly configured as `true`.
14
15
  */
15
16
  export type RpcContextMap<Service, E> = {
@@ -22,7 +23,7 @@ export type RpcContextMap<Service, E> = {
22
23
 
23
24
  export declare namespace RpcContextMap {
24
25
  /**
25
- * Middleware is active by default, and provides the Service at Key in route context, and the Service is provided as Effect ServiceMap.
26
+ * Middleware is active by default, and provides the Service at Key in route context, and the Service is provided as Effect Context.
26
27
  * Unless explicitly omitted.
27
28
  */
28
29
  export type Inverted<Service, E> = {
@@ -97,7 +98,7 @@ export type GetEffectError<RequestContextMap extends Record<string, RpcContextMa
97
98
  }
98
99
  >
99
100
 
100
- const tag = ServiceMap.Service("RequestContextConfig")
101
+ const tag = Context.Service("RequestContextConfig")
101
102
 
102
103
  export const makeMap = <const Config extends Record<string, RpcContextMap.Any>>(config: Config) => {
103
104
  const cls = class {
@@ -109,7 +110,7 @@ export const makeMap = <const Config extends Record<string, RpcContextMap.Any>>(
109
110
  return Object.assign(cls, {
110
111
  config, /** Retrieves RequestContextConfig out of the Rpc annotations */
111
112
  getConfig: (rpc: AnyWithProps): GetContextConfig<Config> => {
112
- return ServiceMap.getOrElse(rpc.annotations, tag as any, () => ({}))
113
+ return Context.getOrElse(rpc.annotations, tag as any, () => ({}))
113
114
  },
114
115
  /** Adapter used when setting the dynamic prop on a middleware implementation */
115
116
  get: <
@@ -1,10 +1,11 @@
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 Effect, type Schema, type Schema as S, type Scope, type ServiceMap, type Stream } from "effect"
4
+ import { type Effect, type Schema, type Schema as S, type Scope, type Stream } from "effect"
5
5
  import { type NonEmptyReadonlyArray } from "effect/Array"
6
6
  import { type Rpc, RpcMiddleware } from "effect/unstable/rpc"
7
7
  import { type TypeId } from "effect/unstable/rpc/RpcMiddleware"
8
+ import type * as Context from "../Context.js"
8
9
  import { type GetEffectContext, type RpcContextMap } from "./RpcContextMap.js"
9
10
 
10
11
  export type RpcMiddlewareV4<Provides, E, Requires> = RpcMiddleware.RpcMiddleware<Provides, E, Requires>
@@ -102,8 +103,8 @@ export declare namespace TagClass {
102
103
  requires?: any
103
104
  provides?: any
104
105
  }
105
- > extends ServiceMap.Service<Self, Service> {
106
- new(_: never): ServiceMap.ServiceClass.Shape<Name, Service>
106
+ > extends Context.Service<Self, Service> {
107
+ new(_: never): Context.ServiceClass.Shape<Name, Service>
107
108
  readonly [TypeId]: TypeId
108
109
  readonly optional: Optional<Options>
109
110
  readonly error: FailureSchema<Options>
@@ -226,7 +227,7 @@ export type ExtractProvides<R extends Rpc.Any, Tag extends string> = R extends
226
227
  Rpc.Rpc<Tag, infer _Payload, infer _Success, infer _Error, infer _Middleware, infer _Requires> ? _Middleware extends {
227
228
  readonly provides: infer _P
228
229
  } ? [_P] extends [never] ? never
229
- : _P /*_P extends ServiceMap.Service<infer _I, infer _S> ? _I
230
+ : _P /*_P extends Context.Service<infer _I, infer _S> ? _I
230
231
  : never */
231
232
  : never
232
233
  : never
package/src/rpc.ts CHANGED
@@ -1,4 +1,3 @@
1
- export * as RpcX from "./rpc.js"
2
1
  export * as MiddlewareMaker from "./rpc/MiddlewareMaker.js"
3
2
  export * as RpcContextMap from "./rpc/RpcContextMap.js"
4
3
  export * as RpcMiddleware from "./rpc/RpcMiddleware.js"
package/src/transform.ts CHANGED
@@ -51,8 +51,8 @@ const encodeOptsAsNullable_ = (value: any, cacheMap: Map<any, any>): any => {
51
51
 
52
52
  if (
53
53
  value instanceof Date
54
- || value instanceof Function
55
- || value instanceof Promise
54
+ || typeof value === "function"
55
+ || (typeof value === "object" && value !== null && "then" in value && typeof value.then === "function")
56
56
  ) {
57
57
  return value
58
58
  }
package/src/utils/gen.ts CHANGED
@@ -15,7 +15,7 @@ export namespace EffectGenUtils {
15
15
  : EG extends (..._: infer _3) => Generator<Yieldable<any, infer _, infer E, infer _R>, infer _A, infer _2> ? E
16
16
  : never
17
17
 
18
- export type ServiceMap<EG> = EG extends Effect<infer _A, infer _E, infer R> ? R
18
+ export type Context<EG> = EG extends Effect<infer _A, infer _E, infer R> ? R
19
19
  // there could be a case where the generator function does not yield anything, so we need to handle that
20
20
  : EG extends (..._: infer _3) => Generator<never, infer _A, infer _2> ? never
21
21
  // v4: generators can yield Yieldable (Effect, Service, etc.), all have asEffect()
@@ -2,11 +2,11 @@
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
 
4
4
  import { Effect, type LogLevel } from "effect"
5
- import * as ServiceMap from "../ServiceMap.js"
5
+ import * as Context from "../Context.js"
6
6
 
7
7
  type Levels = "info" | "debug" | "warn" | "error"
8
8
 
9
- export class LogLevels extends ServiceMap.Reference("LogLevels", {
9
+ export class LogLevels extends Context.Reference("LogLevels", {
10
10
  defaultValue: () => new Map<string, Levels>()
11
11
  }) {}
12
12